delete_after_append = FALSE;
generic_format = FALSE;
- remove_temporary_at_error = FALSE;
recover_archive_when_interrupt = FALSE;
remove_extracting_file_when_interrupt = FALSE;
get_filename_from_stdin = FALSE;
exclude_files = NULL;
verify_mode = FALSE;
- noconvertcase = FALSE;
+ convertcase = FALSE;
extract_directory = NULL;
temporary_fd = -1;
#else
backup_old_archive = FALSE;
#endif
+
+ extract_broken_archive = FALSE;
+ decode_macbinary_contents = FALSE;
+ sort_contents = TRUE;
+ recursive_archiving = TRUE;
+ dump_lzss = FALSE;
}
/* ------------------------------------------------------------------------ */
static void
print_tiny_usage()
{
- fprintf(stderr, "\
+ fprintf(stdout, "\
usage: lha [-]<commands>[<options>] [-<options> ...] archive_file [file...]\n\
commands: [axelvudmcpt]\n\
- options: [q[012]vnfto[567]dizg012e[w=<dir>|x=<pattern>]]\n");
+ options: [q[012]vnfto[567]dizg012%s%s[w=<dir>|x=<pattern>]]\n\
+ long options: --system-kanji-code={euc,sjis,utf8,cap}\n\
+ --archive-kanji-code={euc,sjis,utf8,cap}\n\
+ --extract-broken-archive\n\
+ --convert-filename-case\n\
+ --ignore-mac-files\n\
+ --traditional\n\
+ --help\n\
+ --version\n"
+#ifdef EUC
+ ,"e"
+#else
+ ,""
+#endif
+#if HAVE_LIBAPPLEFILE
+ ,"b" /* decode_macbinary_contents */
+#else
+ ,""
+#endif
+ );
}
static void
print_usage()
{
- fprintf(stderr, "\
+ fprintf(stdout, "\
LHarc for UNIX V 1.02 Copyright(C) 1989 Y.Tagawa\n\
LHx for MSDOS V C2.01 Copyright(C) 1990 H.Yoshizaki\n\
LHx(arc) for OSK V 2.01 Modified 1990 Momozou\n\
LHa for UNIX V 1.00 Copyright(C) 1992 Masaru Oki\n\
LHa for UNIX V 1.14 Modified 1995 Nobutaka Watazaki\n\
LHa for UNIX V 1.14i Modified 2000 Tsugio Okamoto\n\
- Autoconfiscated 2001-2003 Koji Arai\n\
+LHA-PMA for UNIX V 2 PMA added 2000 Maarten ter Huurne\n\
+ Autoconfiscated 2001-2008 Koji Arai\n\
");
print_tiny_usage();
- fprintf(stderr, "\
+ fprintf(stdout, "\
commands: options:\n\
a Add(or replace) to archive q{num} quiet (num:quiet mode)\n\
x,e EXtract from archive v verbose\n\
u Update newer files to archive f force (over write at extract)\n\
d Delete from archive t FILES are TEXT file\n");
#ifdef SUPPORT_LH7
- fprintf(stderr, "\
+ fprintf(stdout, "\
m Move to archive (means 'ad') o[567] compression method (a/u/c)\n\
");
#endif
#ifndef SUPPORT_LH7
- fprintf(stderr, "\
+ fprintf(stdout, "\
m Move to archive (means 'ad') o use LHarc compatible method (a/u/c)\n\
");
#endif
- fprintf(stderr, "\
+ fprintf(stdout, "\
c re-Construct new archive d delete FILES after (a/u/c)\n\
p Print to STDOUT from archive i ignore directory path (x/e)\n\
t Test file CRC in archive z files not compress (a/u/c)\n\
g Generic format (for compatibility)\n\
- or not convert case when extracting\n\
0/1/2 header level (a/u/c)\n\
");
#ifdef EUC
- fprintf(stderr, "\
+ fprintf(stdout, "\
e TEXT code convert from/to EUC\n\
");
#endif
- fprintf(stderr, "\
+#if HAVE_LIBAPPLEFILE
+ fprintf(stdout, "\
+ b decode MacBinary (x/e)\n\
+");
+#endif
+ fprintf(stdout, "\
w=<dir> specify extract directory (x/e)\n\
x=<pattern> eXclude files (a/u/c)\n\
");
-#if IGNORE_DOT_FILES /* experimental feature */
- fprintf(stderr, "\
- X ignore dot files (a/u/c)\n\
-");
-#endif
}
+#include "getopt_long.h"
+
+/*
+ Parse LHA options
+*/
static int
-parse_option(int argc, char **argv)
+parse_suboption(int argc, char **argv)
{
- char *opt;
+ enum {
+ HELP_OPTION = 256,
+ VERSION_OPTION,
+ SYSTEM_KANJI_CODE_OPTION,
+ ARCHIVE_KANJI_CODE_OPTION,
+ TRADITIONAL_BEHAVIOR,
+ IGNORE_MAC_FILES,
+ DEBUG_OPTION,
+ };
+
+ struct option long_options[] = {
+ /* These options set a flag. */
+ {"help", no_argument, 0, HELP_OPTION},
+ {"version", no_argument, 0, VERSION_OPTION},
+
+ {"system-kanji-code", required_argument, 0, SYSTEM_KANJI_CODE_OPTION},
+ {"archive-kanji-code", required_argument, 0, ARCHIVE_KANJI_CODE_OPTION},
+ {"extract-broken-archive", no_argument, &extract_broken_archive, 1},
+ {"convert-filename-case", no_argument, &convertcase, TRUE},
+ {"traditional", no_argument, 0, TRADITIONAL_BEHAVIOR},
+ {"ignore-mac-files", no_argument, 0, IGNORE_MAC_FILES},
+ {"debug", required_argument, 0, DEBUG_OPTION},
+ {0, 0, 0, 0}
+ };
int i;
- argv++; argc--; /* exclude command name */
+ char short_options[256] = "q[012]vnfto[567]dizg012ew:x:";
+ /* "[...]" means optional 1 byte argument (original extention) */
- if (argc < 1) {
- print_usage();
- exit(0);
+#if HAVE_LIBAPPLEFILE
+ strncat(short_options, "b", sizeof(short_options)-strlen(short_options)-1);
+#endif
+
+ /* parse option */
+ while (1) {
+ int option_index = 0;
+ int c = getopt_long(argc, argv,
+ short_options, long_options,
+ &option_index);
+
+ if (c == -1) break; /* end of options */
+
+ switch (c) {
+ case 0:
+ /* Already set a flag variable by the definition of the
+ long_options. */
+ break;
+ case '?':
+ /* Invalid option */
+ print_tiny_usage();
+ exit(2);
+ case HELP_OPTION:
+ print_usage();
+ exit(0);
+ case VERSION_OPTION:
+ print_version();
+ exit(0);
+ case 'q':
+ if (!optarg) {
+ /* In quiet mode, no confirm to overwrite */
+ force = TRUE;
+ quiet = TRUE;
+ break;
+ }
+
+ switch (*optarg) {
+ case '0': /* no quiet */
+ case '1': /* no use the incremental indicator */
+ quiet_mode = *optarg - '0';
+ break;
+ case '2': /* no output */
+ /* fall through */
+ default:
+ force = TRUE;
+ quiet = TRUE;
+ break;
+ }
+ break;
+ case 'f':
+ force = TRUE;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 't':
+ text_mode = TRUE;
+ break;
+#ifdef EUC
+ case 'e':
+ text_mode = TRUE;
+ euc_mode = TRUE;
+ break;
+#endif
+#if HAVE_LIBAPPLEFILE
+ case 'b':
+ decode_macbinary_contents = TRUE;
+ break;
+#endif
+ case 'n':
+ noexec = TRUE;
+ break;
+ case 'g':
+ generic_format = TRUE;
+ header_level = 0;
+ break;
+ case 'd':
+ delete_after_append = TRUE;
+ break;
+ case 'o':
+ if (!optarg) {
+ compress_method = LZHUFF1_METHOD_NUM;
+ header_level = 0;
+ break;
+ }
+ switch (*optarg) {
+ case '5':
+ compress_method = LZHUFF5_METHOD_NUM;
+ break;
+#ifdef SUPPORT_LH7
+ case '6':
+ compress_method = LZHUFF6_METHOD_NUM;
+ break;
+ case '7':
+ compress_method = LZHUFF7_METHOD_NUM;
+ break;
+#endif
+ default:
+ error("invalid compression method 'o%c'", *optarg);
+ return -1;
+ }
+ break;
+ case 'z':
+ compress_method = LZHUFF0_METHOD_NUM; /* Changed N.Watazaki */
+ break;
+ case 'i':
+ ignore_directory = TRUE;
+ break;
+ case 'x':
+ if (!optarg) {
+ error("exclude files does not specified for `-x'");
+ exit(2);
+ }
+
+ for (i = 0; exclude_files && exclude_files[i]; i++)
+ ;
+ exclude_files = (char**)xrealloc(exclude_files,
+ sizeof(char*) * (i+2));
+
+ if (*optarg == '=')
+ optarg++;
+ exclude_files[i] = optarg;
+ exclude_files[i+1] = 0;
+
+ break;
+ case 'w':
+ if (!optarg) {
+ error("working directory does not specified for `-w'");
+ exit(2);
+ }
+ if (*optarg == '=')
+ optarg++;
+
+ extract_directory = optarg;
+ break;
+ case '0':
+ header_level = 0;
+ break;
+ case '1':
+ header_level = 1;
+ break;
+ case '2':
+ header_level = 2;
+ break;
+ case SYSTEM_KANJI_CODE_OPTION:
+ if (!optarg) {
+ error("kanji code not specified for --%s",
+ long_options[option_index].name);
+ return -1;
+ }
+ if (strcmp(optarg, "euc") == 0) {
+ optional_system_kanji_code = CODE_EUC;
+ }
+ else if (strcmp(optarg, "sjis") == 0) {
+ optional_system_kanji_code = CODE_SJIS;
+ }
+ else if (strcmp(optarg, "utf8") == 0) {
+ optional_system_kanji_code = CODE_UTF8;
+ }
+ else if (strcmp(optarg, "cap") == 0) {
+ optional_system_kanji_code = CODE_CAP;
+ }
+ else {
+ error("unknown kanji code \"%s\"", optarg);
+ return -1;
+ }
+ break;
+
+ case ARCHIVE_KANJI_CODE_OPTION:
+ if (!optarg) {
+ error("kanji code not specified for --%s",
+ long_options[option_index].name);
+ return -1;
+ }
+ if (strcmp(optarg, "euc") == 0) {
+ optional_archive_kanji_code = CODE_EUC;
+ }
+ else if (strcmp(optarg, "sjis") == 0) {
+ optional_archive_kanji_code = CODE_SJIS;
+ }
+ else if (strcmp(optarg, "utf8") == 0) {
+ optional_archive_kanji_code = CODE_UTF8;
+ }
+ else if (strcmp(optarg, "cap") == 0) {
+ optional_archive_kanji_code = CODE_CAP;
+ }
+ else {
+ error("unknown kanji code \"%s\"", optarg);
+ return -1;
+ }
+ break;
+
+ case TRADITIONAL_BEHAVIOR:
+ convertcase = TRUE;
+ break;
+
+ case IGNORE_MAC_FILES:
+ /* ignore Mac specific files (._*, .DS_Store and Icon\r)
+ when archiving */
+ for (i = 0; exclude_files && exclude_files[i]; i++)
+ ;
+ exclude_files = (char**)xrealloc(exclude_files,
+ sizeof(char*) * (i+4));
+
+ exclude_files[i] = xstrdup("._*");
+ exclude_files[i+1] = xstrdup(".DS_Store");
+ exclude_files[i+2] = xstrdup("Icon\r");
+ exclude_files[i+3] = 0;
+ break;
+
+ case DEBUG_OPTION:
+ if (!optarg) {
+ error("debugging item is not specified for --%s",
+ long_options[option_index].name);
+ return -1;
+ }
+ if (strcmp(optarg, "nosort") == 0) {
+ sort_contents = FALSE;
+ }
+ else if (strcmp(optarg, "norecursion") == 0) {
+ recursive_archiving = FALSE;
+ }
+ else if (strcmp(optarg, "dumplzss") == 0) {
+ dump_lzss = TRUE;
+ quiet = TRUE;
+ }
+ else {
+ error("unknown debugging item \"%s\" for --%s",
+ optarg, long_options[option_index].name);
+ return -1;
+ }
+ break;
+
+ default:
+ error("unknown option `-%c'.", c);
+ return -1;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (!archive_name) {
+ archive_name = *argv++;
+ argc--;
}
- if (strcmp(*argv, "--help") == 0) {
+ cmd_filec = argc;
+ cmd_filev = argv;
+
+ return 0;
+}
+
+/*
+ Parse LHA command and options.
+*/
+static int
+parse_option(int argc, char **argv)
+{
+ char *cmd_char;
+
+ if (argv[1] == NULL || strcmp(argv[1], "--help") == 0) {
print_usage();
exit(0);
}
- if (strcmp(*argv, "--version") == 0) {
+
+ if (strcmp(argv[1], "--version") == 0) {
print_version();
exit(0);
}
- if (argc == 1 && **argv != '-') {
- archive_name = *argv++; argc--;
+ if (argc == 2 && *argv[1] != '-') {
+ archive_name = argv[1];
cmd = CMD_LIST;
- cmd_filec = argc;
- cmd_filev = argv;
+ cmd_filec = 0;
+ cmd_filev = 0;
return 0;
}
- opt = *argv++; argc--;
+ cmd_char = argv[1];
- if (opt[0] == '-')
- opt++;
+ if (cmd_char[0] == '-')
+ cmd_char++;
- /* commands */
- switch (*opt) {
+ /* parse commands */
+ switch (*cmd_char) {
case 'x':
case 'e':
cmd = CMD_EXTRACT;
break;
default:
- error("unknown command `-%c'", *opt);
+ error("unknown command `-%c'", *cmd_char);
return -1;
}
- /* options */
- for (;;) {
- char *p = opt+1;
-
- while ( *p != 0 ) {
- switch ((*p++)) {
- case 'q':
- switch (*p) {
- case '0': /* no quiet */
- case '1': /* no use the incremental indicator */
- quiet_mode = *p - '0';
- ++p;
- break;
- case '2': /* no output */
- ++p;
- /* fall through */
- default:
- /* In quiet mode, no confirm to overwrite */
- force = TRUE;
- quiet = TRUE;
- break;
- }
- break;
- case 'f':
- force = TRUE;
- break;
- case 'v':
- verbose++;
- break;
- case 't':
- text_mode = TRUE;
- break;
-#ifdef EUC
- case 'e':
- text_mode = TRUE;
- euc_mode = TRUE;
- break;
-#endif
- case 'n':
- noexec = TRUE;
- break;
- case 'g':
- generic_format = TRUE;
- noconvertcase = TRUE;
- header_level = 0;
- break;
- case 'd':
- delete_after_append = TRUE;
- break;
- case 'o':
- switch (*p) {
- case 0:
- compress_method = LZHUFF1_METHOD_NUM;
- header_level = 0;
- break;
- case '5':
- compress_method = LZHUFF5_METHOD_NUM;
- p++;
- break;
-#ifdef SUPPORT_LH7
- case '6':
- compress_method = LZHUFF6_METHOD_NUM;
- p++;
- break;
- case '7':
- compress_method = LZHUFF7_METHOD_NUM;
- p++;
- break;
-#endif
- default:
- error("invalid compression method 'o%c'", *p);
- return -1;
- }
- break;
- case 'z':
- compress_method = LZHUFF0_METHOD_NUM; /* Changed N.Watazaki */
- break;
- case 'i':
- ignore_directory = TRUE;
- break;
- case 'x':
- if (*p == '=')
- p++;
-
- for (i = 0; exclude_files && exclude_files[i]; i++)
- ;
- exclude_files = (char**)xrealloc(exclude_files,
- sizeof(char*) * (i+2));
-
- if (*p == 0) {
- if (*argv == 0) {
- error("exclude files does not specified for `-x'");
- return -1;
- }
- exclude_files[i] = *argv++; argc--;
- exclude_files[i+1] = 0;
- goto next;
- }
- else {
- exclude_files[i] = p;
- exclude_files[i+1] = 0;
- p += strlen(p);
- }
- break;
-#if IGNORE_DOT_FILES /* experimental feature */
- case 'X':
- for (i = 0; exclude_files && exclude_files[i]; i++)
- ;
- exclude_files = (char**)xrealloc(exclude_files,
- sizeof(char*) * (i+2));
-
- exclude_files[i] = xstrdup(".*");
- exclude_files[i+1] = 0;
- break;
-#endif
- case 'w':
- if (*p == '=')
- p++;
- if (*p == 0) {
- if (*argv == 0) {
- error("working directory does not specified for `-w'");
- return -1;
- }
- extract_directory = *argv++; argc--;
- goto next;
- }
- else {
- extract_directory = p;
- p += strlen(p);
- }
- break;
- case '0':
- header_level = 0;
- break;
- case '1':
- header_level = 1;
- break;
- case '2':
- header_level = 2;
- break;
- default:
- error("unknown option `-%c'.", p[-1]);
- return -1;
- }
- }
-
- next:
- opt = *argv;
- if (!opt || opt[0] != '-')
- break;
-
- /* special archive name */
- if (strcmp(opt, "-") == 0)
- break;
-
- /* GNU style long options */
- if (opt[0] == '-' && opt[1] == '-') {
- opt += 2;
-
- if (strncmp(opt, "system-kanji-code=",
- sizeof("system-kanji-code=")-1) == 0) {
- opt += sizeof("system-kanji-code=")-1;
- if (strcmp(opt, "euc") == 0) {
- optional_system_kanji_code = CODE_EUC;
- }
- else if (strcmp(opt, "sjis") == 0) {
- optional_system_kanji_code = CODE_SJIS;
- }
- else if (strcmp(opt, "utf8") == 0) {
- optional_system_kanji_code = CODE_UTF8;
- }
- else if (strcmp(opt, "cap") == 0) {
- optional_system_kanji_code = CODE_CAP;
- }
- else {
- error("unknown kanji code \"%s\"", opt);
- return -1;
- }
- }
- else if (strncmp(opt, "archive-kanji-code=",
- sizeof("archive-kanji-code=")-1) == 0) {
- opt += sizeof("archive-kanji-code=")-1;
- if (strcmp(opt, "euc") == 0) {
- optional_archive_kanji_code = CODE_EUC;
- }
- else if (strcmp(opt, "sjis") == 0) {
- optional_archive_kanji_code = CODE_SJIS;
- }
- else if (strcmp(opt, "utf8") == 0) {
- optional_archive_kanji_code = CODE_UTF8;
- }
- else if (strcmp(opt, "cap") == 0) {
- optional_archive_kanji_code = CODE_CAP;
- }
- else {
- error("unknown kanji code \"%s\"", opt);
- return -1;
- }
- }
- else {
- error("unknown long option \"--%s\"", opt);
- return -1;
- }
- argv++; argc--;
- goto next;
- }
-
- argv++; argc--;
+ if (cmd_char[1] == '\0') {
+ /* argv[1] is command name */
+ argv[1] = argv[0];
+ argv++;
+ argc--;
}
-
- if (!archive_name) {
- archive_name = *argv++; argc--;
+ else {
+ /* Eliminate command character
+ e.g.) lha cv foo.lzh -> lha -v foo.lzh
+ lha -cv foo.lzh -> lha -v foo.lzh
+ */
+ cmd_char[0] = '-';
+ argv[1] = cmd_char;
}
- cmd_filec = argc;
- cmd_filev = argv;
-
- return 0;
+ return parse_suboption(argc, argv);
}
/* ------------------------------------------------------------------------ */
defined in config.h by configure script */
fprintf(stderr, "%s version %s (%s)\n",
PACKAGE_NAME, PACKAGE_VERSION, PLATFORM);
+ fprintf(stderr, " configure options: %s\n", LHA_CONFIGURE_OPTIONS);
}
void
else
fputs("\n", stderr);
- if (remove_temporary_at_error) {
- if (temporary_fd != -1)
- close(temporary_fd);
+ exit(1);
+}
+
+void
+cleanup()
+{
+ if (temporary_fd != -1) {
+ close(temporary_fd);
+ temporary_fd = -1;
unlink(temporary_name);
}
- exit(1);
+ if (recover_archive_when_interrupt) {
+ rename(backup_archive_name, archive_name);
+ recover_archive_when_interrupt = FALSE;
+ }
+ if (remove_extracting_file_when_interrupt) {
+ message("Removing: %s", writing_filename);
+ unlink(writing_filename);
+ remove_extracting_file_when_interrupt = FALSE;
+ }
}
-/* ------------------------------------------------------------------------ */
RETSIGTYPE
interrupt(signo)
int signo;
{
message("Interrupted");
- if (temporary_fd != -1)
- close(temporary_fd);
- unlink(temporary_name);
- if (recover_archive_when_interrupt)
- rename(backup_archive_name, archive_name);
- if (remove_extracting_file_when_interrupt) {
- message("Removing: %s", writing_filename);
- unlink(writing_filename);
- }
+ cleanup();
+
signal(SIGINT, SIG_DFL);
#ifdef SIGHUP
signal(SIGHUP, SIG_DFL);
static void
sort_files()
{
- if (cmd_filec > 1)
+ if (cmd_filec > 1 && sort_contents)
qsort(cmd_filev, cmd_filec, sizeof(char *), sort_by_ascii);
}
{
int len = strlen(str);
char *p = (char *)xmalloc(len + 1);
- strcpy(p, str);
+ strcpy(p, str); /* ok */
return p;
}
struct stat tmp_stbuf, arc_stbuf, fil_stbuf;
int exist_tmp = 1, exist_arc = 1;
- strcpy(newname, name);
- len = strlen(name);
+ len = str_safe_copy(newname, name, sizeof(newname));
if (len > 0 && newname[len - 1] != '/') {
- newname[len++] = '/';
- newname[len] = 0;
+ if (len < sizeof(newname)-1)
+ strcpy(&newname[len++], "/"); /* ok */
+ else
+ warning("the length of pathname \"%s\" is too long.", name);
}
dirp = opendir(name);
}
closedir(dirp);
finish_sp(&sp, v_filec, v_filev);
- if (*v_filec > 1)
+ if (*v_filec > 1 && sort_contents)
qsort(*v_filev, *v_filec, sizeof(char *), sort_by_ascii);
cleaning_files(v_filec, v_filev);
#ifdef TMP_FILENAME_TEMPLATE
/* "/tmp/lhXXXXXX" etc. */
if (extract_directory == NULL) {
- strcpy(temporary_name, TMP_FILENAME_TEMPLATE);
+ str_safe_copy(temporary_name, TMP_FILENAME_TEMPLATE,
+ sizeof(temporary_name));
}
else {
xsnprintf(temporary_name, sizeof(temporary_name),
"%s/lhXXXXXX", extract_directory);
}
#else
- char *p, *s;
-
- strcpy(temporary_name, archive_name);
- for (p = temporary_name, s = (char *) 0; *p; p++)
- if (*p == '/')
- s = p;
- strcpy((s ? s + 1 : temporary_name), "lhXXXXXX");
+ char *s;
+
+ str_safe_copy(temporary_name, archive_name, sizeof(temporary_name));
+ s = strrchr(temporary_name, '/');
+ if (s) {
+ int len;
+ len = s - temporary_name;
+ if (len + strlen("lhXXXXXX") < sizeof(temporary_name))
+ /* use directory at archive file */
+ strcpy(s, "lhXXXXXX"); /* ok */
+ else
+ /* use current directory */
+ str_safe_copy(temporary_name, "lhXXXXXX", sizeof(temporary_name));
+ }
+ else
+ /* use current directory */
+ str_safe_copy(temporary_name, "lhXXXXXX", sizeof(temporary_name));
#endif
#ifdef HAVE_MKSTEMP
{
/* ------------------------------------------------------------------------ */
static void
-modify_filename_extention(buffer, ext)
+modify_filename_extention(buffer, ext, size)
char *buffer;
char *ext;
+ size_t size;
{
register char *p, *dot;
if (dot)
p = dot;
- strcpy(p, ext);
+ str_safe_copy(p, ext, size - (p - buffer));
}
/* ------------------------------------------------------------------------ */
/* build backup file name */
void
-build_backup_name(buffer, original)
+build_backup_name(buffer, original, size)
char *buffer;
char *original;
+ size_t size;
{
- strcpy(buffer, original);
- modify_filename_extention(buffer, BACKUPNAME_EXTENTION); /* ".bak" */
+ str_safe_copy(buffer, original, size);
+ modify_filename_extention(buffer, BACKUPNAME_EXTENTION, size); /* ".bak" */
}
/* ------------------------------------------------------------------------ */
void
-build_standard_archive_name(buffer, orginal)
+build_standard_archive_name(buffer, original, size)
char *buffer;
- char *orginal;
+ char *original;
+ size_t size;
{
- strcpy(buffer, orginal);
- modify_filename_extention(buffer, ARCHIVENAME_EXTENTION); /* ".lzh" */
+ str_safe_copy(buffer, original, size);
+ modify_filename_extention(buffer, ARCHIVENAME_EXTENTION, size); /* ".lzh" */
}
/* ------------------------------------------------------------------------ */
FILE *
open_old_archive()
{
- FILE *fp;
- char *p;
+ FILE *fp = NULL;
+ char *p = NULL, *ext, *ext2;
static char expanded_archive_name[FILENAME_LENGTH];
if (!strcmp(archive_name, "-")) {
if (cmd == CMD_EXTRACT || cmd == CMD_LIST) {
-#if __MINGW32__
+#if defined(__MINGW32__) || defined(__DJGPP__)
setmode(fileno(stdin), O_BINARY);
#endif
return stdin;
else
return NULL;
}
- p = strrchr(archive_name, '.');
- if (p) {
- if (strcasecmp(".LZH", p) == 0
- || strcasecmp(".LZS", p) == 0
- || strcasecmp(".COM", p) == 0 /* DOS SFX */
- || strcasecmp(".EXE", p) == 0
- || strcasecmp(".X", p) == 0 /* HUMAN SFX */
- || strcasecmp(".BAK", p) == 0) { /* for BackUp */
- open_old_archive_1(archive_name, &fp);
- return fp;
+
+ ext2 = strrchr(archive_name, '.');
+ if (ext2) {
+ ext2++;
+
+ /* .com: DOS SFX
+ .exe: DOS SFX
+ .x: HUMAN SFX
+ .bak: Backup file
+ .lha: Amiga(?) */
+ p = xstrdup("lzh," ADDITIONAL_SUFFIXES);
+ for (ext = strtok(p, ",");
+ ext;
+ ext = strtok(NULL, ",")) {
+
+ if (*ext == 0) continue;
+
+ if (strcasecmp(ext, ext2)) {
+ /* Try to open file just specified filename
+ with usual suffixes.
+ Return NULL if the file is not exist. */
+
+ open_old_archive_1(archive_name, &fp);
+ goto ret; /* found or not */
+ }
}
+ free(p);
+ p = NULL;
}
+ /* Try to open file just specified filename */
if (open_old_archive_1(archive_name, &fp))
- return fp;
- xsnprintf(expanded_archive_name, sizeof(expanded_archive_name),
- "%s.lzh", archive_name);
- if (open_old_archive_1(expanded_archive_name, &fp)) {
- archive_name = expanded_archive_name;
- return fp;
- }
- /*
- * if ( (errno&0xffff)!=E_PNNF ) { archive_name =
- * expanded_archive_name; return NULL; }
- */
- xsnprintf(expanded_archive_name, sizeof(expanded_archive_name),
- "%s.lzs", archive_name);
- if (open_old_archive_1(expanded_archive_name, &fp)) {
- archive_name = expanded_archive_name;
- return fp;
+ goto ret; /* found */
+
+ /* Try to open file with implicit suffixes */
+ p = xstrdup("lzh," ADDITIONAL_SUFFIXES);
+ for (ext = strtok(p, ",");
+ ext;
+ ext = strtok(NULL, ",")) {
+
+ if (*ext == 0) continue;
+
+ xsnprintf(expanded_archive_name, sizeof(expanded_archive_name),
+ "%s.%s", archive_name, ext);
+
+ if (open_old_archive_1(expanded_archive_name, &fp)) {
+ archive_name = expanded_archive_name;
+ goto ret; /* found */
+ }
}
- /*
- * if ( (errno&0xffff)!=E_PNNF ) { archive_name =
- * expanded_archive_name; return NULL; }
- */
- /*
- * sprintf( expanded_archive_name , "%s.lzh",archive_name);
- * archive_name = expanded_archive_name;
- */
- return NULL;
+
+ret:
+ if (p) free(p);
+ return fp;
}
/* ------------------------------------------------------------------------ */
copyfile(oafp, nafp, hdr->header_size + hdr->packed_size, 0, 0);
}
}
+
+#undef exit
+
+void
+lha_exit(status)
+ int status;
+{
+ cleanup();
+ exit(status);
+}