return NULL;
}
-init_opts()
-{
- opts.nocompress = 0;
- opts.outdir = NULL;
- opts.quiet = 0;
- opts.header_level = 2;
- opts.generic = 0;
- opts.verbose = 0;
-
- /* default is the -lh5- method */
- opts.method = &methods[5];
-}
-
#define FNAME_MAX (255 - 25) /* max strlen(filename) */
int unpackable; /* global, set in io.c */
static void
skip(FILE *fp, struct lzh_header *h)
{
- fseek(fp, h->compsize, SEEK_CUR);
+ int i;
+ if (opts.archive_to_stdio)
+ for (i = 0; i < h->compsize; i++)
+ fgetc(fp);
+ else
+ fseek(fp, h->compsize, SEEK_CUR);
}
static void
}
else {
/* regular file */
+ if (file_exists(h->filename)) {
+ if (!opts.force_extract) {
+ message("'%s' has been already exist. skip", h->filename);
+ skip(arcfile, h);
+ return;
+ }
+ }
while ((outfile = fopen(h->filename, "wb")) == NULL) {
fprintf(stderr, "Can't open %s\nNew filename: ", h->filename);
if (get_line(h->filename, FNAME_MAX) == 0) {
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "012go[567]q[012]vw:z",
+ c = getopt_long(argc, argv, "012fgo[567]q[012]vw:z",
long_options, &option_index);
if (c == -1) break; /* end of parsing options */
/* header level */
opts.header_level = c - '0';
break;
+ case 'f':
+ opts.force_extract = 1;
+ break;
case 'g':
opts.generic = 1;
break;
struct lzh_header h;
int arc_count;
- init_opts();
+ INITIALIZE_OPTS(opts);
if (argv[1] == 0)
print_usage();
archive_file = argv[0];
+ if (strcmp(archive_file, "-") == 0)
+ opts.archive_to_stdio = 1;
+
argv++;
argc--;
switch (cmd) {
case 'a':
case 'c':
+ if (opts.archive_to_stdio)
+ opts.quiet = 2;
outfile = open_tempfile();
if (*argv == 0)
error("archived files are not specified.");
fputc(0, outfile); /* end of archive */
if (ferror(outfile))
error("Can't write");
- remove(archive_file);
fclose(outfile);
- if (xrename(temp_name, archive_file) == -1)
- error("fail to rename(): %s -> %s",temp_name,archive_file);
-
+ if (opts.archive_to_stdio) {
+ if (move_file_to_stream(temp_name, stdout) == -1)
+ error("fail to move_file_to_stream(): %s -> %s",temp_name,"stdout");
+ }
+ else {
+ unlink(archive_file);
+ if (xrename(temp_name, archive_file) == -1)
+ error("fail to rename(): %s -> %s",temp_name,archive_file);
+ }
exit(0);
break;
case 'r':
case 'l':
case 'v':
/* Open archive. */
- arcfile = fopen(archive_file, "rb");
+ if (opts.archive_to_stdio) {
+ arcfile = stdin;
+ }
+ else {
+ arcfile = fopen(archive_file, "rb");
+ }
if (arcfile == NULL)
error("Can't open archive '%s'", archive_file);
fputc(0, outfile); /* end of archive */
if (ferror(outfile))
error("Can't write");
- remove(archive_file);
+ if (!opts.archive_to_stdio)
+ unlink(archive_file);
fclose(outfile);
if (arc_count > count) {
if (xrename(temp_name, archive_file) == -1)
error("fail to rename(): %s -> %s",temp_name,archive_file);
}
- else {
- unlink(archive_file);
+ else
message("The archive file \"%s\" was removed because it would be empty.", archive_file);
- }
+
exit(0);
}
return EXIT_SUCCESS;
#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+int
+file_exists(char *file)
+{
+ struct stat stbuf;
+ int ret;
+
+ ret = stat(file, &stbuf);
+ if (ret == 0)
+ return 1;
+ else if (ret == -1 && errno == ENOENT)
+ return 0;
+ else
+ error("failed to stat() for '%s'", file);
+}
int
copy_stream(FILE *from, FILE *to)
}
int
+move_file_to_stream(char *from, FILE *to)
+{
+ FILE *ffp = NULL, *tfp = NULL;
+
+ if ((ffp = fopen(from, "r")) == NULL)
+ goto err;
+
+ copy_stream(ffp, to);
+
+ if (ffp) fclose(ffp);
+
+ unlink(from);
+
+ return 0;
+err:
+ if (ffp) fclose(ffp);
+
+ return -1;
+}
+
+int
xrename(char *from, char *to)
{
FILE *ffp = NULL, *tfp = NULL;