+2008-03-08 Koji Arai <arai@users.sourceforge.jp>
+
+ * src/lhext.c (add_dirinfo): no longer suppose that contents of the LZH archive is sorted by pathname.
+
+ * tests/lha-test18: added tests for above.
+
+ * src/lharc.c (parse_suboption): added debugging option `--debug=nosort' and `--debug=norecursion'
+ for above tests.
+
+ * src/lha.h: added two global variables for above options: sort_contents, recursive_archiving;
+
+ * src/lharc.c (init_variable): ditto.
+ (sort_files): no sort arguments with --debug=nosort.
+ (find_files): no sort directory entries with --debug=nosort.
+
+ * src/lhadd.c (append_it): non-sorted and non-recursive archiving with --debug=nosort and --debug=norecursion.
+
+ * src/lhadd.c (remove_one): should use the message() instead of printf().
+
2008-03-07 Koji Arai <arai@users.sourceforge.jp>
* man/lha.1: correct the description about the -m command.
EXTERN int quiet_mode;
EXTERN boolean backup_old_archive;
-EXTERN boolean extract_broken_archive;
+EXTERN boolean extract_broken_archive;
EXTERN boolean decode_macbinary_contents;
+/* for debugging */
+EXTERN boolean sort_contents;
+EXTERN boolean recursive_archiving;
+
+
/* ------------------------------------------------------------------------ */
/* Globale Variable */
/* ------------------------------------------------------------------------ */
break;
}
+ if (!sort_contents) {
+ if (!noexec) {
+ fseeko(oafp, old_header, SEEK_SET);
+ copy_old_one(oafp, nafp, &ahdr);
+ }
+ else
+ fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+ cmp = -1; /* to be -1 always */
+ continue;
+ }
+
cmp = strcmp(ahdr.name, hdr.name);
if (cmp < 0) { /* SKIP */
/* copy old to new */
if (fp) fclose(fp);
- if (directory) { /* recursive call */
+ if (directory && recursive_archiving) { /* recursive call */
if (find_files(name, &filec, &filev)) {
for (i = 0; i < filec; i++)
oafp = append_it(filev[i], oafp, nafp);
#ifdef S_IFLNK
else if (is_symlink(&stbuf)) {
if (noexec)
- printf("REMOVE SYMBOLIC LINK %s.\n", name);
+ message("REMOVE SYMBOLIC LINK %s.", name);
else if (unlink(name) < 0)
warning("Cannot remove", name);
else if (verbose)
extract_broken_archive = FALSE;
decode_macbinary_contents = FALSE;
+ sort_contents = TRUE;
+ recursive_archiving = TRUE;
}
/* ------------------------------------------------------------------------ */
ARCHIVE_KANJI_CODE_OPTION,
TRADITIONAL_BEHAVIOR,
IGNORE_MAC_FILES,
+ DEBUG_OPTION,
};
struct option long_options[] = {
{"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;
exclude_files[i+3] = 0;
break;
+ case DEBUG_OPTION:
+ if (!optarg) {
+ error("debugging item is not specified for --%s=item",
+ 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 {
+ error("unknown debugging item \"%s\" for --%s=item",
+ optarg, long_options[option_index].name);
+ return -1;
+ }
+ break;
+
default:
error("unknown option `-%c'.", c);
return -1;
static void
sort_files()
{
- if (cmd_filec > 1)
+ if (cmd_filec > 1 && sort_contents)
qsort(cmd_filev, cmd_filec, sizeof(char *), sort_by_ascii);
}
}
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);
static void add_dirinfo(char *name, LzHeader *hdr)
{
- LzHeaderList *p;
+ LzHeaderList *p, *tmp, top;
if (memcmp(hdr->method, LZHDIRS_METHOD, 5) != 0)
return;
strncpy(p->hdr.name, name, sizeof(p->hdr.name));
p->hdr.name[sizeof(p->hdr.name)-1] = 0;
+#if 0
+ /* push front */
{
- LzHeaderList *tmp = dirinfo;
+ tmp = dirinfo;
dirinfo = p;
dirinfo->next = tmp;
}
+#else
+
+ /*
+ reverse sorted by pathname order
+
+ p->hdr.name = "a"
+
+ dirinfo->hdr.name = "a/b/d"
+ dirinfo->next->hdr.name = "a/b/c"
+ dirinfo->next->next->hdr.name = "a/b"
+
+ result:
+
+ dirinfo->hdr.name = "a/b/d"
+ dirinfo->next->hdr.name = "a/b/c"
+ dirinfo->next->next->hdr.name = "a/b"
+ dirinfo->next->next->next->hdr.name = "a"
+ */
+
+ top.next = dirinfo;
+
+ for (tmp = ⊤ tmp->next; tmp = tmp->next) {
+ if (strcmp(p->hdr.name, tmp->next->hdr.name) > 0) {
+ p->next = tmp->next;
+ tmp->next = p;
+ break;
+ }
+ }
+ if (tmp->next == NULL) {
+ p->next = NULL;
+ tmp->next = p;
+ }
+
+ dirinfo = top.next;
+#endif
}
static void adjust_dirinfo()
{
while (dirinfo) {
+ /* message("adjusting [%s]", dirinfo->hdr.name); */
adjust_info(dirinfo->hdr.name, &dirinfo->hdr);
{
$lha c test-tmp1.lzh test-tmp1
check $? $LINENO
+$lha v test-tmp1.lzh
+ check $? $LINENO
+$lha xw=test-tmp1x test-tmp1.lzh
+ check $? $LINENO
+
+diff -r test-tmp1x/test-tmp1 test-tmp1
+ check $? $LINENO
+
+ls -ld test-tmp1x/test-tmp1 | grep '^dr-xr--r--' &&
+ls -ld test-tmp1x/test-tmp1/test1 | grep '^drwxr--r--' &&
+ls -ld test-tmp1x/test-tmp1/test1/test2 | grep '^drwxrw-rw-' &&
+ls -ld test-tmp1x/test-tmp1/test1/test2/test-1 | grep '^dr-xr--r--'
+ check $? $LINENO
+echo -------------------------------------------------------------------
+
+mkdir -p test-tmp2/test1/test2 &&
+cp -r test-1 test-tmp2/test1/test2 &&
+chmod 766 test-tmp2/test1/test2 &&
+chmod 744 test-tmp2/test1 &&
+chmod 544 test-tmp2
+ check $? $LINENO
+
+
+change_timestamp 01020304.05 test-tmp2
+ check $? $LINENO
+
+$lha c test-tmp3.lzh ./test-tmp2/test1/test2 \
+ ./test-tmp2/test1 \
+ ./test-tmp2
+ check $? $LINENO
+
+$lha c test-tmp2.lzh ./test-tmp2/test1/test2
+ check $? $LINENO
+$lha a --debug=norecursion --debug=nosort test-tmp2.lzh \
+ ./test-tmp2/test1/
+ check $? $LINENO
+
+chmod 444 test-tmp2
+ check $? $LINENO
+$lha a --debug=norecursion --debug=nosort test-tmp2.lzh \
+ ./test-tmp2/
+ check $? $LINENO
+
+# PERMISSION UID GID PACKED SIZE RATIO METHOD CRC STAMP NAME
+# ---------- ----------- ------- ------- ------ ---------- ------------ ----------
+# drwxrw-rw- 1010/513 0 0 ****** -lhd- 0000 Mar 8 20:27 test-tmp2/test1/test2/
+# drwxr-xr-x 1010/513 0 0 ****** -lhd- 0000 Mar 8 20:27 test-tmp2/test1/test2/test-1/
+# -rw-r--r-- 1010/513 16 400 4.0% -lh5- 6e5b Mar 8 20:27 test-tmp2/test1/test2/test-1/test-a
+# -rw-r--r-- 1010/513 17 400 4.2% -lh5- 8fe6 Mar 8 20:27 test-tmp2/test1/test2/test-1/test-b
+# -rw-r--r-- 1010/513 17 400 4.2% -lh5- 0861 Mar 8 20:27 test-tmp2/test1/test2/test-1/test-c
+# drwxr--r-- 1010/513 0 0 ****** -lhd- 0000 Mar 8 20:27 test-tmp2/test1/
+# dr--r--r-- 1010/513 0 0 ****** -lhd- 0000 Jan 2 03:04 test-tmp2/
+$lha v test-tmp2.lzh
+ check $? $LINENO
-$lha xw=test-tmp2 test-tmp1.lzh
+$lha v test-tmp3.lzh
check $? $LINENO
-diff -r test-tmp2/test-tmp1 test-tmp1
+$lha xqw=test-tmp2x test-tmp2.lzh
+ check $? $LINENO
+
+$lha xqw=test-tmp3x test-tmp3.lzh
+ check $? $LINENO
+
+ls -ld test-tmp2x/test-tmp2 | grep '^dr--r--r--'
+ check $? $LINENO
+chmod 544 test-tmp2x/test-tmp2
+ check $? $LINENO
+
+find test-tmp2x | xargs ls -ld
+# drwxr-xr-x+ 3 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x
+# dr-xr--r--+ 3 arai \82È\82µ 0 Jan 2 03:04 test-tmp2x/test-tmp2
+# drwxr--r--+ 3 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x/test-tmp2/test1
+# drwxrw-rw-+ 3 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2
+# drwxr-xr-x+ 2 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2/test-1
+# -rw-r--r-- 1 arai \82È\82µ 400 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2/test-1/test-a
+# -rw-r--r-- 1 arai \82È\82µ 400 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2/test-1/test-b
+# -rw-r--r-- 1 arai \82È\82µ 400 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2/test-1/test-c
+# dr-xr--r--+ 3 arai \82È\82µ 0 Jan 2 03:04 test-tmp2x/test-tmp2
+# drwxr--r--+ 3 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x/test-tmp2/test1
+# drwxrw-rw-+ 3 arai \82È\82µ 0 Mar 8 20:30 test-tmp2x/test-tmp2/test1/test2
+
+diff -r test-tmp2x test-tmp3x
check $? $LINENO
-ls -ld test-tmp2/test-tmp1 | grep '^dr-xr--r--' &&
-ls -ld test-tmp2/test-tmp1/test1 | grep '^drwxr--r--' &&
-ls -ld test-tmp2/test-tmp1/test1/test2 | grep '^drwxrw-rw-' &&
-ls -ld test-tmp2/test-tmp1/test1/test2/test-1 | grep '^dr-xr--r--'
+ls -ld test-tmp2x/test-tmp2 | grep '^dr-xr--r--' &&
+ls -ld test-tmp2x/test-tmp2/test1 | grep '^drwxr--r--' &&
+ls -ld test-tmp2x/test-tmp2/test1/test2 | grep '^drwxrw-rw-'
check $? $LINENO