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 */
return NULL;
}
-int unpackable; /* global, set in io.c */
-ulong compsize, origsize; /* global */
-
-static char *temp_name = NULL;
-
static void
print_usage()
{
return 0;
}
-static void
-exitfunc(void)
-{
- if (temp_name)
- remove(temp_name);
-}
-
#include "getopt_long.h"
void
{
FILE *outfile;
- temp_name = tmpnam(NULL);
- outfile = fopen(temp_name, "wb");
+ outfile = tmpfile();
if (outfile == NULL)
error("Can't open temporary file");
- atexit(exitfunc);
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, 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_istream r, *rp;
struct lzh_ostream w, *wp;
FILE *arcfile = NULL;
FILE *outfile = NULL;
- rp = &r;
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 cmd;
+ char *archive_file;
+
INITIALIZE_OPTS(opts);
if (argv[1] == 0)
if (strcmp(archive_file, "-") == 0)
opts.archive_to_stdio = 1;
+ if (opts.archive_to_stdio)
+ opts.quiet = 2;
argv++;
argc--;
make_crctable();
- count = done = nfiles = 0;
switch (cmd) {
case 'a':
case 'u':
- case 'c':
- if (opts.archive_to_stdio)
- opts.quiet = 2;
-
- outfile = open_tempfile();
- wp->fp = outfile;
- if (*argv == 0)
- error("archived files are not specified.");
-
- 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);
-
- break;
- }
- }
- 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");
- fclose(outfile);
- 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");
+ if (opts.archive_to_stdio || !file_exists(archive_file)) {
+ op_create(cmd, archive_file, argc, argv);
}
else {
- unlink(archive_file);
- if (xrename(temp_name, archive_file) == -1)
- error("fail to rename(): %s -> %s",temp_name,archive_file);
+ op_add(cmd, archive_file, argc, argv);
}
- exit(0);
break;
- case 'r':
+
+ case 'c':
+ op_create(cmd, archive_file, argc, argv);
+ break;
+
case 'd':
- if (argc == 0) {
- message("No files given in argument, do nothing.");
- exit(0);
- }
- outfile = open_tempfile();
+ op_delete(cmd, archive_file, argc, argv);
+ break;
+
case 'x':
case 'p':
+ op_extract(cmd, archive_file, argc, argv);
+ break;
+
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);
-
+ op_list(cmd, archive_file, argc, argv);
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);
- }
- }
-
- arc_count = 0;
-
- while (!done && read_header(arcfile, &h)) {
-
- arc_count++;
-
- compsize = h.compsize;
- origsize = h.origsize;
-
- 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;
- case 'x':
- case 'p':
- if (found != 0) {
- rp->fp = arcfile;
- 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 && (cmd == 'd' || cmd == 'a' || cmd == 'u')) {
- fputc(0, outfile); /* end of archive */
- if (ferror(outfile))
- error("Can't write");
- if (!opts.archive_to_stdio)
- unlink(archive_file);
- fclose(outfile);
- fclose(arcfile);
- if (cmd == 'd') {
- if (arc_count > count) {
- if (xrename(temp_name, archive_file) == -1)
- error("fail to rename(): %s -> %s",temp_name,archive_file);
- }
- else {
- message("The archive file \"%s\" was removed because it would be empty.", archive_file);
- }
- }
- else {
- if (xrename(temp_name, archive_file) == -1)
- error("fail to rename(): %s -> %s",temp_name,archive_file);
- }
- exit(0);
- }
return EXIT_SUCCESS;
}