return outfile;
}
-int
-main(int argc, char *argv[])
+static void
+op_add(int cmd, char *archive_file, int argc, char **argv)
{
- int i, cmd, count, nfiles, found, done;
- char *archive_file;
+ int i, count, nfiles, found, done;
struct lzh_header h;
int arc_count;
- struct lzh_istream r, *rp;
struct lzh_ostream w, *wp;
FILE *arcfile = NULL;
FILE *outfile = NULL;
- rp = &r;
wp = &w;
- INITIALIZE_OPTS(opts);
-
- if (argv[1] == 0)
- print_usage();
+ count = done = nfiles = 0;
- /*take a command character */
{
- char *arg1;
+ outfile = open_tempfile();
+ wp->fp = outfile;
+ wp->buf = 0;
+ if (*argv == 0)
+ error("archived files are not specified.");
- arg1 = argv[1];
- if (arg1[0] == '-')
- arg1++;
- if (arg1[0] == 0)
- print_usage();
+ if (!opts.archive_to_stdio && (cmd == 'a' || cmd == 'u')) {
+ if (file_exists(archive_file)) {
+ arcfile = fopen(archive_file, "rb");
+ if (arcfile == NULL)
+ error("Can't open archive '%s'", archive_file);
- cmd = *arg1;
- if (arg1[1] == 0) {
- /* -<cmd> -<opts> ... */
- argv++;
- argc--;
+ goto xxx;
+ }
+ }
+ for (i = 0; i < argc; i++) {
+ add(wp, 0, argv[i], strlen(argv[i]));
+ }
+
+ fputc(0, outfile); /* end of archive */
+ if (ferror(outfile))
+ error("Can't write");
+ rewind(outfile);
+ if (opts.archive_to_stdio) {
+ if (copy_stream(outfile, stdout) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s","stdout");
}
else {
- /* -<cmd><opts> => -<opts> */
- *arg1 = '-';
+ if (copy_stream_to_file(outfile, archive_file) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s",archive_file);
}
+
+ return;
}
- parse_args(argc, argv);
- argv += optind;
- argc -= optind;
+xxx:
+ arc_count = 0;
- archive_file = argv[0];
+ while (!done && read_header(arcfile, &h)) {
- if (strcmp(archive_file, "-") == 0)
- opts.archive_to_stdio = 1;
- if (opts.archive_to_stdio)
- opts.quiet = 2;
+ arc_count++;
- argv++;
- argc--;
+ found = search(argc, argv, &h);
+ switch (cmd) {
+ case 'a':
+ case 'u':
+ if (found>0) {
+ argv[found-1] = 0;
+
+ if (cmd == 'u') {
+ time_t mtime;
+
+ if (file_mtime(h.filename, &mtime) == -1 || h.mtime > mtime) {
+ copy(arcfile, outfile, &h);
+ break;
+ }
+ }
+
+ if (add(wp, 1, h.filename, h.namelen)) {
+ skip(arcfile, &h);
+ count++;
+ }
+ else
+ copy(arcfile, outfile, &h);
+ }
+ else
+ copy(arcfile, outfile, &h);
+ break;
+ case 'd':
+ if (found) {
+ count++;
+ message("'%s' deleted", h.filename);
+ skip(arcfile, &h);
+ }
+ else
+ copy(arcfile, outfile, &h);
+ break;
+ }
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (argv[i]) {
+ count++;
+ add(wp, 0, argv[i], strlen(argv[i]));
+ }
+ }
+
+ if (cmd != 'p') {
+ if (opts.quiet < 2)
+ printf(" %d files\n", count);
+ }
+
+ if (count > 0) {
+ fputc(0, outfile); /* end of archive */
+ if (ferror(outfile))
+ error("Can't write");
+ if (!opts.archive_to_stdio)
+ unlink(archive_file);
+
+ fclose(arcfile);
+ rewind(outfile);
+ if (copy_stream_to_file(outfile, archive_file) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s",archive_file);
+ exit(0);
+ }
+}
+
+static void
+op_update(int cmd, char *archive_file, int argc, char **argv)
+{
+ int i, count, nfiles, found, done;
+ struct lzh_header h;
+ int arc_count;
+ struct lzh_ostream w, *wp;
+ FILE *arcfile = NULL;
+ FILE *outfile = NULL;
+
+ wp = &w;
- make_crctable();
count = done = nfiles = 0;
- switch (cmd) {
- case 'a':
- case 'u':
- case 'c':
+ {
outfile = open_tempfile();
wp->fp = outfile;
wp->buf = 0;
if (arcfile == NULL)
error("Can't open archive '%s'", archive_file);
- break;
+ goto xxx;
}
}
for (i = 0; i < argc; i++) {
if (copy_stream_to_file(outfile, archive_file) == -1)
error("fail to copy_stream_to_file(): temp -> %s",archive_file);
}
- exit(0);
- break;
- case 'r':
- case 'd':
- if (argc == 0) {
- message("No files given in argument, do nothing.");
- exit(0);
- }
- outfile = open_tempfile();
- case 'x':
- case 'p':
- case 'l':
- case 'v':
- /* Open archive. */
- if (opts.archive_to_stdio) {
- arcfile = stdin;
- }
- else {
- arcfile = fopen(archive_file, "rb");
- }
- if (arcfile == NULL)
- error("Can't open archive '%s'", archive_file);
- break;
- default:
- print_usage();
- break;
- }
-
- /* change directory to extract dir */
- if (cmd == 'x') {
- if (opts.outdir) {
- if (mkdir(opts.outdir, 0777) == -1) {
- if (errno != EEXIST)
- error("cannot make directory \"%s\"", opts.outdir);
- }
-
- if (chdir(opts.outdir) == -1)
- error("cannot change directory \"%s\"", opts.outdir);
- }
+ return;
}
+xxx:
arc_count = 0;
while (!done && read_header(arcfile, &h)) {
else
copy(arcfile, outfile, &h);
break;
- case 'x':
- case 'p':
- if (found != 0) {
- rp->fp = arcfile;
- rp->compsize = h.compsize;
- extract(rp, cmd == 'x', &h);
- if (++count == nfiles)
- done = 1;
- }
- else
- skip(arcfile, &h);
- break;
- case 'l':
- case 'v':
- if (found != 0) {
- if (count == 0)
- list_start();
- list(&h);
- if (++count == nfiles)
- done = 1;
- }
- skip(arcfile, &h);
- break;
}
}
- if (cmd == 'a' || cmd == 'u') {
+ for (i = 0; i < argc; i++) {
+ if (argv[i]) {
+ count++;
+ add(wp, 0, argv[i], strlen(argv[i]));
+ }
+ }
+
+ if (cmd != 'p') {
+ if (opts.quiet < 2)
+ printf(" %d files\n", count);
+ }
+
+ if (count > 0) {
+ fputc(0, outfile); /* end of archive */
+ if (ferror(outfile))
+ error("Can't write");
+ if (!opts.archive_to_stdio)
+ unlink(archive_file);
+
+ fclose(arcfile);
+ rewind(outfile);
+ if (copy_stream_to_file(outfile, archive_file) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s",archive_file);
+ exit(0);
+ }
+}
+
+static void
+op_create(int cmd, char *archive_file, int argc, char **argv)
+{
+ int i;
+ struct lzh_ostream w, *wp;
+ FILE *outfile = NULL;
+
+ wp = &w;
+
+ {
+ outfile = open_tempfile();
+ wp->fp = outfile;
+ wp->buf = 0;
+ if (*argv == 0)
+ error("archived files are not specified.");
+
for (i = 0; i < argc; i++) {
- if (argv[i]) {
+ add(wp, 0, argv[i], strlen(argv[i]));
+ }
+
+ fputc(0, outfile); /* end of archive */
+ if (ferror(outfile))
+ error("Can't write");
+ rewind(outfile);
+ if (opts.archive_to_stdio) {
+ if (copy_stream(outfile, stdout) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s","stdout");
+ }
+ else {
+ if (copy_stream_to_file(outfile, archive_file) == -1)
+ error("fail to copy_stream_to_file(): temp -> %s",archive_file);
+ }
+
+ return;
+ }
+}
+
+static void
+op_delete(int cmd, char *archive_file, int argc, char **argv)
+{
+ int count, nfiles, found, done;
+ struct lzh_header h;
+ int arc_count;
+ struct lzh_ostream w, *wp;
+ FILE *arcfile = NULL;
+ FILE *outfile = NULL;
+
+ wp = &w;
+
+ count = done = nfiles = 0;
+
+ {
+ if (argc == 0) {
+ message("No files given in argument, do nothing.");
+ exit(0);
+ }
+ outfile = open_tempfile();
+
+ /* Open archive. */
+ if (opts.archive_to_stdio) {
+ arcfile = stdin;
+ }
+ else {
+ arcfile = fopen(archive_file, "rb");
+ }
+ if (arcfile == NULL)
+ error("Can't open archive '%s'", archive_file);
+ }
+
+ arc_count = 0;
+
+ while (!done && read_header(arcfile, &h)) {
+
+ arc_count++;
+
+ found = search(argc, argv, &h);
+ switch (cmd) {
+ case 'd':
+ if (found) {
count++;
- add(wp, 0, argv[i], strlen(argv[i]));
+ message("'%s' deleted", h.filename);
+ skip(arcfile, &h);
}
+ else
+ copy(arcfile, outfile, &h);
+ break;
}
}
printf(" %d files\n", count);
}
- if (count > 0 && (cmd == 'd' || cmd == 'a' || cmd == 'u')) {
+ if (count > 0) {
fputc(0, outfile); /* end of archive */
if (ferror(outfile))
error("Can't write");
fclose(arcfile);
rewind(outfile);
- if (cmd == 'd') {
+
if (arc_count > count) {
if (copy_stream_to_file(outfile, archive_file) == -1)
error("fail to copy_stream_to_file(): temp -> %s",archive_file);
else {
message("The archive file \"%s\" was removed because it would be empty.", archive_file);
}
+
+ exit(0);
+ }
+}
+
+static void
+op_extract(int cmd, char *archive_file, int argc, char **argv)
+{
+ int count, nfiles, found, done;
+ struct lzh_header h;
+ int arc_count;
+ struct lzh_istream r, *rp;
+ FILE *arcfile = NULL;
+
+ rp = &r;
+
+ count = done = nfiles = 0;
+
+ switch (cmd) {
+ case 'x':
+ case 'p':
+ /* Open archive. */
+ if (opts.archive_to_stdio) {
+ arcfile = stdin;
}
else {
- if (copy_stream_to_file(outfile, archive_file) == -1)
- error("fail to copy_stream_to_file(): temp -> %s",archive_file);
+ arcfile = fopen(archive_file, "rb");
}
- exit(0);
+ if (arcfile == NULL)
+ error("Can't open archive '%s'", archive_file);
+
+ break;
+ }
+
+ /* change directory to extract dir */
+ if (cmd == 'x') {
+ if (opts.outdir) {
+ if (mkdir(opts.outdir, 0777) == -1) {
+ if (errno != EEXIST)
+ error("cannot make directory \"%s\"", opts.outdir);
+ }
+
+ if (chdir(opts.outdir) == -1)
+ error("cannot change directory \"%s\"", opts.outdir);
+ }
+ }
+
+ arc_count = 0;
+
+ while (!done && read_header(arcfile, &h)) {
+
+ arc_count++;
+
+ found = search(argc, argv, &h);
+ switch (cmd) {
+ case 'x':
+ case 'p':
+ if (found != 0) {
+ rp->fp = arcfile;
+ rp->compsize = h.compsize;
+ extract(rp, cmd == 'x', &h);
+ if (++count == nfiles)
+ done = 1;
+ }
+ else
+ skip(arcfile, &h);
+ break;
+ }
+ }
+
+ if (cmd != 'p') {
+ if (opts.quiet < 2)
+ printf(" %d files\n", count);
+ }
+}
+
+static void
+op_list(int cmd, char *archive_file, int argc, char **argv)
+{
+ int count, nfiles, found, done;
+ struct lzh_header h;
+ int arc_count;
+ struct lzh_istream r, *rp;
+ FILE *arcfile = NULL;
+
+ rp = &r;
+
+ count = done = nfiles = 0;
+
+ /* Open archive. */
+ if (opts.archive_to_stdio) {
+ arcfile = stdin;
+ }
+ else {
+ arcfile = fopen(archive_file, "rb");
+ }
+ if (arcfile == NULL)
+ error("Can't open archive '%s'", archive_file);
+
+ arc_count = 0;
+
+ while (!done && read_header(arcfile, &h)) {
+
+ arc_count++;
+
+ found = search(argc, argv, &h);
+
+ if (found != 0) {
+ if (count == 0)
+ list_start();
+ list(&h);
+ if (++count == nfiles)
+ done = 1;
+ }
+ skip(arcfile, &h);
+ }
+
+ if (opts.quiet < 2)
+ printf(" %d files\n", count);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int cmd;
+ char *archive_file;
+
+ INITIALIZE_OPTS(opts);
+
+ if (argv[1] == 0)
+ print_usage();
+
+ /*take a command character */
+ {
+ char *arg1;
+
+ arg1 = argv[1];
+ if (arg1[0] == '-')
+ arg1++;
+ if (arg1[0] == 0)
+ print_usage();
+
+ cmd = *arg1;
+ if (arg1[1] == 0) {
+ /* -<cmd> -<opts> ... */
+ argv++;
+ argc--;
+ }
+ else {
+ /* -<cmd><opts> => -<opts> */
+ *arg1 = '-';
+ }
+ }
+
+ parse_args(argc, argv);
+ argv += optind;
+ argc -= optind;
+
+ archive_file = argv[0];
+
+ if (strcmp(archive_file, "-") == 0)
+ opts.archive_to_stdio = 1;
+ if (opts.archive_to_stdio)
+ opts.quiet = 2;
+
+ argv++;
+ argc--;
+
+ make_crctable();
+
+ switch (cmd) {
+ case 'a':
+ op_add(cmd, archive_file, argc, argv);
+ break;
+
+ case 'u':
+ op_update(cmd, archive_file, argc, argv);
+ break;
+
+ case 'c':
+ op_create(cmd, archive_file, argc, argv);
+ break;
+
+ case 'd':
+ op_delete(cmd, archive_file, argc, argv);
+ break;
+
+ case 'x':
+ case 'p':
+ op_extract(cmd, archive_file, argc, argv);
+ break;
+
+ case 'l':
+ case 'v':
+ op_list(cmd, archive_file, argc, argv);
+ break;
+
+ default:
+ print_usage();
+ break;
}
return EXIT_SUCCESS;
}