ar.c -- main file
***********************************************************/
+static char *version = "0.01";
+
static char *usage =
"ar -- compression archiver -- written by Haruhiko Okumura\n"
" PC-VAN:SCIENCE CompuServe:74050,1022\n"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <utime.h>
+#include <unistd.h>
#include "ar.h"
-struct lzh_header {
- char filename[1024];
- int xnamelen;
- char method[5];
- int compsize;
- int origsize;
- int ftime;
- int file_crc;
- char os_id;
+struct lha_method methods[] = {
+ /* id, dicbit, pbit, maxmatch */
+ /* note: dicbit == 0 means no compress */
+ /* (1U << pbit) > np(dicbit+1) */
+ {"-lh0-", 0, 0, 0}, /* 0: no compress */
+ {"-lh1-", 12, 0, 60}, /* 1: 2^12 = 4KB dynamic huffman (LHarc) */
+ {"-lh2-", 13, 0,256}, /* 2: 2^13 = 8KB dynamic huffman */
+ {"-lh3-", 13, 0,256}, /* 3: 2^13 = 8KB static huffman */
+ {"-lh4-", 12, 4,256}, /* 4: 2^12 = 4KB static huffman (pos and len)*/
+ {"-lh5-", 13, 4,256}, /* 5: 2^13 = 8KB static huffman (pos and len)*/
+ {"-lh6-", 15, 5,256}, /* 6: 2^15 = 32KB static huffman (pos and len)*/
+ {"-lh7-", 16, 5,256}, /* 7: 2^16 = 64KB static huffman (pos and len)*/
+ {"-lzs-", 11, 0, 17}, /* 8: 2^11 = 2KB (LArc) */
+ {"-lz5-", 12, 0, 17}, /* 9: 2^12 = 4KB (LArc) */
+ {"-lz4-", 0, 0, 0}, /*10: no compress (LArc) */
+ {"-lhd-", 0, 0, 0}, /*11: directory */
};
-#define FNAME_MAX (255 - 25) /* max strlen(filename) */
+struct lha_opts opts;
-int unpackable; /* global, set in io.c */
-ulong compsize, origsize; /* global */
+struct lha_method *
+which_method(char *id)
+{
+ int i;
-static uchar headersize;
-static char *temp_name;
+ for (i = 0; i < sizeof(methods)/sizeof(methods[0]); i++) {
+ if (strncmp(id, methods[i].id, sizeof(methods[0].id)) == 0) {
+ return &methods[i];
+ }
+ }
+ return NULL;
+}
static void
print_usage()
{
- puts("usage: ...");
+ printf("%s", usage);
+ exit(0);
+}
+
+static void
+print_version()
+{
+ printf("version %s\n", version);
exit(0);
}
-static uint
+uint
ratio(ulong a, ulong b)
{ /* [(1000a + [b/2]) / b] */
int i;
return (uint) ((a + (b >> 1)) / b);
}
-static void
-put_to_header(char *buf, int i, int n, ulong x)
-{
- while (--n >= 0) {
- buf[i++] = (uchar) ((uint) x & 0xFF);
- x >>= 8;
- }
-}
-
-static ulong
-get_from_header(char *buf, int i, int n)
-{
- ulong s;
-
- s = 0;
- while (--n >= 0)
- s = (s << 8) + buf[i + n]; /* little endian */
- return s;
-}
-
-static uint
-calc_headersum(char *buf, int size)
-{
- int i;
- uint s;
-
- s = 0;
- for (i = 0; i < size; i++)
- s += buf[i];
- return s & 0xFF;
-}
-
-int
-get_byte(char *buf)
-{
- return *(unsigned char*)buf;
-}
-
-uint16_t
-get_word(char *buf)
-{
- return get_byte(buf) | (get_byte(buf+1) << 8);
-}
-
-uint32_t
-get_dword(char *buf)
-{
- return get_byte(buf) |
- (get_byte(buf+1) << 8) |
- (get_byte(buf+2) << 16) |
- (get_byte(buf+3) << 24);
-}
-
void
-get_char(char *buf, char *p, size_t size)
-{
- memcpy(p, buf, size);
-}
-
-void
-put_byte(char *buf, int c)
-{
- *buf = (unsigned char)(c & 0xff);
-}
-
-void
-put_word(char *buf, uint16_t c)
-{
- put_byte(buf, c);
- put_byte(buf+1, c>>8);
-}
-
-void
-put_dword(char *buf, uint32_t c)
-{
- put_byte(buf, c);
- put_byte(buf+1, c>>8);
- put_byte(buf+2, c>>16);
- put_byte(buf+3, c>>24);
-}
-
-void
-put_char(char *buf, char *p, size_t size)
-{
- memcpy(buf, p, size);
-}
-
-static int
-read_header(FILE *fp, struct lzh_header *h, uchar *headersize)
-{
- int headersum;
- char buf[4096];
- int ext_headersize;
-
- *headersize = (uchar) fgetc(fp);
- if (*headersize == 0)
- return 0; /* end of archive */
- headersum = (uchar) fgetc(fp);
- fread_crc(buf, *headersize, fp); /* CRC not used */
- if (calc_headersum(buf, *headersize) != headersum)
- error("Header sum error");
-
- get_char(&buf[0], h->method, 5);
- h->compsize = get_dword(&buf[5]);
- h->origsize = get_dword(&buf[9]);
- h->ftime = get_dword(&buf[13]);
- /* attrib = get_byte(&buf[17]); */
- /* level = get_byte(&buf[18]); */ /* level */
- h->xnamelen = get_byte(&buf[19]);
- get_char(&buf[20], h->filename, h->xnamelen);
- h->file_crc = get_word(&buf[20+h->xnamelen]);
- h->os_id = get_byte(&buf[20+h->xnamelen+2]);
-
- ext_headersize = get_word(&buf[20+h->xnamelen+3]);
-
- while (ext_headersize != 0) {
- fprintf(stderr, "There's an extended header of size %u.\n",
- ext_headersize);
- h->compsize -= ext_headersize;
-
- /* skip ext header */
- if (fseek(arcfile, ext_headersize - 2, SEEK_CUR))
- error("Can't read");
- ext_headersize = fgetc(arcfile);
- ext_headersize += (uint) fgetc(arcfile) << 8;
- }
-
- return 1; /* success */
-}
-
-
-void
-write_header(FILE *fp, int headersize, struct lzh_header *h)
-{
- char buf[4096], *p = buf;
- int sum;
-
- put_byte(&buf[0], headersize);
- put_byte(&buf[1], 0); /* dummy */
- put_char(&buf[2], "-lh5-", 5);
- put_dword(&buf[7], h->compsize); /* packed size */
- put_dword(&buf[11], h->origsize); /* original size */
- put_dword(&buf[15], h->ftime); /* ftime */
- put_byte(&buf[19], 0x20); /* attribute */
- put_byte(&buf[20], 1); /* level */
- put_byte(&buf[21], h->xnamelen); /* length of pathname */
- put_char(&buf[22], h->filename, h->xnamelen);
- put_word(&buf[22+h->xnamelen], h->file_crc);
- put_byte(&buf[22+h->xnamelen+2], 'M');
- put_word(&buf[22+h->xnamelen+3], 0x0000); /* next header size */
-
- sum = calc_headersum(buf+2, headersize);
- put_byte(&buf[1], sum);
-
- fwrite_crc(buf, headersize+2, fp);
-}
-
-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
copy(FILE *arcfile, FILE *outfile, struct lzh_header *h)
{
uint n;
- uchar buffer[DICSIZ];
+ uchar buffer[MAXDICSIZ];
- write_header(outfile, headersize, h);
+ write_header(outfile, h);
while (h->compsize != 0) {
- n = (uint) ((h->compsize > DICSIZ) ? DICSIZ : h->compsize);
+ n = (uint) ((h->compsize > sizeof(buffer)) ? sizeof(buffer) : h->compsize);
if (fread((char *) buffer, 1, n, arcfile) != n)
error("Can't read");
if (fwrite((char *) buffer, 1, n, outfile) != n)
}
}
-static void
-store(void)
-{
- uint n;
- uchar buffer[DICSIZ];
-
- origsize = 0;
- crc = INIT_CRC;
- while ((n = fread((char *) buffer, 1, DICSIZ, infile)) != 0) {
- fwrite_crc(buffer, n, outfile);
- origsize += n;
- }
- compsize = origsize;
-}
-
-static int
-add(int replace_flag, char *filename)
-{
- long headerpos, arcpos;
- uint r;
- struct lzh_header h;
-
- if ((infile = fopen(filename, "rb")) == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- return 0; /* failure */
- }
- if (replace_flag) {
- printf("Replacing %s ", filename);
- skip(arcfile, &h);
- }
- else
- printf("Adding %s ", filename);
-
- strcpy(h.filename, filename);
- h.xnamelen = strlen(filename);
-
- headersize = 25 + h.xnamelen;
- memcpy(h.method, "-lh5-", 5); /* compress */
-
- headerpos = ftell(outfile);
- write_header(outfile, headersize, &h);
- arcpos = ftell(outfile);
-
- origsize = compsize = 0;
- unpackable = 0;
- crc = INIT_CRC;
- encode();
- if (unpackable) {
- h.method[3] = '0'; /* store */
- rewind(infile);
- fseek(outfile, arcpos, SEEK_SET);
- store();
- }
- h.file_crc = crc ^ INIT_CRC;
- fclose(infile);
-
- h.compsize = compsize;
- h.origsize = origsize;
-
- fseek(outfile, headerpos, SEEK_SET);
- write_header(outfile, headersize, &h);
- fseek(outfile, 0L, SEEK_END);
- r = ratio(compsize, origsize);
- printf(" %d.%d%%\n", r / 10, r % 10);
- return 1; /* success */
-}
-
int
get_line(char *s, int n)
{
return i;
}
-static void
-extract(int to_file, struct lzh_header *h)
-{
- int n, method;
- uint ext_headersize;
- uchar buffer[DICSIZ];
-
- if (to_file) {
- 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) {
- fprintf(stderr, "Not extracted\n");
- skip(arcfile, h);
- return;
- }
- h->xnamelen = strlen(h->filename);
- }
- printf("Extracting %s ", h->filename);
- }
- else {
- outfile = stdout;
- printf("===== %s =====\n", h->filename);
- }
- crc = INIT_CRC;
- method = h->method[3]; /* -lh*5*- */
- h->method[3] = ' ';
- if (!strchr("045", method) || memcmp("-lh -", h->method, 5)) {
- fprintf(stderr, "Unknown method: %u\n", method);
- skip(arcfile, h);
- }
- else {
- crc = INIT_CRC;
- if (method != '0')
- decode_start();
- while (h->origsize != 0) {
- n = (uint) ((h->origsize > DICSIZ) ? DICSIZ : h->origsize);
- if (method != '0')
- decode(n, buffer);
- else if (fread((char *) buffer, 1, n, arcfile) != n)
- error("Can't read");
- fwrite_crc(buffer, n, outfile);
- if (outfile != stdout)
- putc('.', stderr);
- h->origsize -= n;
- }
- }
- if (to_file)
- fclose(outfile);
- else
- outfile = NULL;
- printf("\n");
- if ((crc ^ INIT_CRC) != h->file_crc)
- fprintf(stderr, "CRC error\n");
-}
-
-static void
-list_start(void)
-{
- printf("Filename Original Compressed Ratio CRC Method\n");
-}
-
-static void
-list(struct lzh_header *h)
-{
- uint r;
-
- printf("%-14s", h->filename);
- if (h->xnamelen > 14)
- printf("\n ");
- r = ratio(h->compsize, h->origsize);
- printf(" %10lu %10lu %u.%03u %04X %5.5s\n",
- h->origsize, h->compsize, r / 1000, r % 1000, h->file_crc, h->method);
-}
-
static int
match(char *s1, char *s2)
{
int i;
if (argc == 0)
- return 1;
+ return -1;
for (i = 0; i < argc; i++)
- if (match(h->filename, argv[i]))
- return 1;
+ if (argv[i] && match(h->filename, argv[i]))
+ return i+1;
return 0;
}
-static void
-exitfunc(void)
-{
- fclose(outfile);
- remove(temp_name);
-}
-
#include "getopt_long.h"
-int
+void
parse_args(int argc, char **argv)
{
int c;
for (;;) {
- int this_option_optind = optind ? optind : 1;
+ /* int this_option_optind = optind ? optind : 1; */
int option_index = 0;
enum {
LHA_OPT_HELP = 128,
+ LHA_OPT_VERSION,
};
static struct option long_options[] = {
non-NULL: getopt_long() return 0, and *flag set val.
*/
{"help", no_argument, NULL, LHA_OPT_HELP},
+ {"version", no_argument, NULL, LHA_OPT_VERSION},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "a", long_options, &option_index);
+ c = getopt_long(argc, argv, "012fgo[567]q[012]vw:z",
+ long_options, &option_index);
- if (c == -1) break;
+ if (c == -1) break; /* end of parsing options */
switch (c) {
- case 0: /* set vallue by long option */
+ case '?':
+ print_usage();
+ break;
+ case 0:
+ /* set value by long option */
+ break;
+ case '0': case '1': case '2':
+ /* header level */
+ opts.header_level = c - '0';
+ break;
+ case 'f':
+ opts.force_extract = 1;
+ break;
+ case 'g':
+ opts.generic = 1;
+ opts.header_level = 0;
+ break;
+ case 'o':
+ /* compress method */
+ {
+ int idx = 1; /* -o means -lh1- method */
+
+ if (optarg)
+ idx = *optarg - '0'; /* -lh[567]- method */
+
+ opts.method = &methods[idx];
+ }
+ break;
+ case 'q':
+ /* quiet mode */
+ opts.quiet = 2; /* -q is equivalent to -q2 */
+ if (optarg)
+ opts.quiet = *optarg - '0';
+ break;
+ case 'v':
+ /* verbose mode */
+ opts.verbose = 1;
+ break;
+
+ case 'w':
+ /* extract directory */
+ if (!optarg)
+ error("extract directory does not specified for `-w'");
+ if (*optarg == '=')
+ optarg++;
+
+ opts.outdir = optarg;
+ break;
+ case 'z': /* no compress */
+ opts.nocompress = 1;
break;
case LHA_OPT_HELP:
print_usage();
break;
+ case LHA_OPT_VERSION:
+ print_version();
+ break;
default:
break;
}
}
}
+FILE *
+open_tempfile()
+{
+ FILE *outfile;
+
+ outfile = tmpfile();
+ if (outfile == NULL)
+ error("Can't open temporary file");
+
+ return outfile;
+}
+
+static void
+op_add(int cmd, char *archive_file, int argc, char **argv)
+{
+ int i, count, found, done;
+ struct lzh_header h;
+ struct lzh_ostream w, *wp;
+ FILE *arcfile = NULL;
+ FILE *outfile = NULL;
+
+ wp = &w;
+
+ count = done = 0;
+
+ outfile = open_tempfile();
+ wp->fp = outfile;
+ wp->buf = 0;
+ if (*argv == 0)
+ error("archived files are not specified.");
+
+ arcfile = fopen(archive_file, "rb");
+ if (arcfile == NULL)
+ error("Can't open archive '%s'", archive_file);
+
+ while (!done && read_header(arcfile, &h)) {
+
+ found = search(argc, argv, &h);
+ 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);
+ continue;
+ }
+ }
+
+ if (add(wp, 1, h.filename, h.namelen)) {
+ skip(arcfile, &h);
+ count++;
+ }
+ else
+ copy(arcfile, outfile, &h);
+ }
+ else
+ copy(arcfile, outfile, &h);
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (argv[i]) {
+ count++;
+ add(wp, 0, argv[i], strlen(argv[i]));
+ }
+ }
+
+ 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);
+ }
+}
+
+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++) {
+ 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, found, done;
+ struct lzh_header h;
+ int arc_count;
+ struct lzh_ostream w, *wp;
+ FILE *arcfile = NULL;
+ FILE *outfile = NULL;
+
+ wp = &w;
+
+ count = done = 0;
+
+ if (argc == 0) {
+ message("No files given in argument, do nothing.");
+ return;
+ }
+ 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);
+ if (found) {
+ count++;
+ message("'%s' deleted", h.filename);
+ skip(arcfile, &h);
+ }
+ else
+ copy(arcfile, outfile, &h);
+ }
+
+ 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 (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);
+ }
+ }
+}
+
+static void
+op_extract(int cmd, char *archive_file, int argc, char **argv)
+{
+ int count, nfiles, found, done;
+ struct lzh_header h;
+ 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);
+
+ /* 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);
+ }
+ }
+
+ while (!done && read_header(arcfile, &h)) {
+
+ found = search(argc, argv, &h);
+ if (found != 0) {
+ rp->fp = arcfile;
+ rp->compsize = h.compsize;
+ extract(rp, cmd == 'x', &h);
+ if (++count == nfiles)
+ done = 1;
+ }
+ else
+ skip(arcfile, &h);
+ }
+
+ 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;
+ 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);
+
+ while (!done && read_header(arcfile, &h)) {
+
+ 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 i, j, cmd, count, nfiles, found, done;
+ int cmd;
char *archive_file;
- struct lzh_header h;
+
+ INITIALIZE_OPTS(opts);
if (argv[1] == 0)
print_usage();
+ /*take a command character */
{
- char *str;
+ char *arg1;
- str = argv[1];
- if (str[0] == '-')
- str++;
- if (str[0] == 0)
+ arg1 = argv[1];
+ if (arg1[0] == '-')
+ arg1++;
+ if (arg1[0] == 0)
print_usage();
- cmd = *str;
- if (str[1] == 0) {
+ cmd = *arg1;
+ if (arg1[1] == 0) {
+ /* -<cmd> -<opts> ... */
argv++;
argc--;
}
else {
/* -<cmd><opts> => -<opts> */
- *str = '-';
+ *arg1 = '-';
}
}
archive_file = argv[0];
- /* Open archive. */
- arcfile = fopen(archive_file, "rb");
-
- if (arcfile == NULL && cmd != 'a')
- error("Can't open archive '%s'", argv[2]);
+ if (strcmp(archive_file, "-") == 0)
+ opts.archive_to_stdio = 1;
+ if (opts.archive_to_stdio)
+ opts.quiet = 2;
argv++;
argc--;
- /* Open temporary file. */
- if (strchr("ard", cmd)) {
- temp_name = tmpnam(NULL);
- outfile = fopen(temp_name, "wb");
- if (outfile == NULL)
- error("Can't open temporary file");
- atexit(exitfunc);
- }
- else
- temp_name = NULL;
-
make_crctable();
- count = done = 0;
switch (cmd) {
case 'a':
- if (*argv == 0)
- error("archived files are not specified.");
- for (i = 0; i < argc; i++) {
- add(0, argv[i]);
+ case 'u':
+ if (opts.archive_to_stdio || !file_exists(archive_file)) {
+ op_create(cmd, archive_file, argc, argv);
}
+ else {
+ op_add(cmd, archive_file, argc, argv);
+ }
+ break;
- fputc(0, outfile); /* end of archive */
- if (ferror(outfile) || fclose(outfile) == EOF)
- error("Can't write");
- remove(archive_file);
- fclose(arcfile);
- if (rename(temp_name, archive_file) == -1)
- error("fail to rename()");
+ case 'c':
+ op_create(cmd, archive_file, argc, argv);
+ break;
- exit(0);
+ case 'd':
+ op_delete(cmd, archive_file, argc, argv);
break;
+
case 'x':
- case 'r':
- case 'd':
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;
}
-
- while (!done && read_header(arcfile, &h, &headersize)) {
-
- compsize = h.compsize;
- origsize = h.origsize;
-
- found = search(argc, argv, &h);
- switch (cmd) {
- case 'r':
- if (found) {
- if (add(1, *argv))
- count++;
- else
- copy(arcfile, outfile, &h);
- }
- else
- copy(arcfile, outfile, &h);
- break;
- case 'a':
- case 'd':
- if (found) {
- count += (cmd == 'D');
- skip(arcfile, &h);
- }
- else
- copy(arcfile, outfile, &h);
- break;
- case 'x':
- case 'p':
- if (found) {
- extract(cmd == 'x', &h);
- if (++count == nfiles)
- done = 1;
- }
- else
- skip(arcfile, &h);
- break;
- case 'l':
- if (found) {
- if (count == 0)
- list_start();
- list(&h);
- if (++count == nfiles)
- done = 1;
- }
- skip(arcfile, &h);
- break;
- }
- }
-
- if (temp_name != NULL && count != 0) {
- }
-
- printf(" %d files\n", count);
return EXIT_SUCCESS;
}