add_dirinfo() no longer suppose that contents of the LZH archive is sorted by pathname.
* 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().
@@ -1,3 +1,22 @@ | ||
1 | +2008-03-08 Koji Arai <arai@users.sourceforge.jp> | |
2 | + | |
3 | + * src/lhext.c (add_dirinfo): no longer suppose that contents of the LZH archive is sorted by pathname. | |
4 | + | |
5 | + * tests/lha-test18: added tests for above. | |
6 | + | |
7 | + * src/lharc.c (parse_suboption): added debugging option `--debug=nosort' and `--debug=norecursion' | |
8 | + for above tests. | |
9 | + | |
10 | + * src/lha.h: added two global variables for above options: sort_contents, recursive_archiving; | |
11 | + | |
12 | + * src/lharc.c (init_variable): ditto. | |
13 | + (sort_files): no sort arguments with --debug=nosort. | |
14 | + (find_files): no sort directory entries with --debug=nosort. | |
15 | + | |
16 | + * src/lhadd.c (append_it): non-sorted and non-recursive archiving with --debug=nosort and --debug=norecursion. | |
17 | + | |
18 | + * src/lhadd.c (remove_one): should use the message() instead of printf(). | |
19 | + | |
1 | 20 | 2008-03-07 Koji Arai <arai@users.sourceforge.jp> |
2 | 21 | |
3 | 22 | * man/lha.1: correct the description about the -m command. |
@@ -329,9 +329,14 @@ | ||
329 | 329 | EXTERN int quiet_mode; |
330 | 330 | |
331 | 331 | EXTERN boolean backup_old_archive; |
332 | -EXTERN boolean extract_broken_archive; | |
332 | +EXTERN boolean extract_broken_archive; | |
333 | 333 | EXTERN boolean decode_macbinary_contents; |
334 | 334 | |
335 | +/* for debugging */ | |
336 | +EXTERN boolean sort_contents; | |
337 | +EXTERN boolean recursive_archiving; | |
338 | + | |
339 | + | |
335 | 340 | /* ------------------------------------------------------------------------ */ |
336 | 341 | /* Globale Variable */ |
337 | 342 | /* ------------------------------------------------------------------------ */ |
@@ -122,6 +122,17 @@ | ||
122 | 122 | break; |
123 | 123 | } |
124 | 124 | |
125 | + if (!sort_contents) { | |
126 | + if (!noexec) { | |
127 | + fseeko(oafp, old_header, SEEK_SET); | |
128 | + copy_old_one(oafp, nafp, &ahdr); | |
129 | + } | |
130 | + else | |
131 | + fseeko(oafp, ahdr.packed_size, SEEK_CUR); | |
132 | + cmp = -1; /* to be -1 always */ | |
133 | + continue; | |
134 | + } | |
135 | + | |
125 | 136 | cmp = strcmp(ahdr.name, hdr.name); |
126 | 137 | if (cmp < 0) { /* SKIP */ |
127 | 138 | /* copy old to new */ |
@@ -166,7 +177,7 @@ | ||
166 | 177 | |
167 | 178 | if (fp) fclose(fp); |
168 | 179 | |
169 | - if (directory) { /* recursive call */ | |
180 | + if (directory && recursive_archiving) { /* recursive call */ | |
170 | 181 | if (find_files(name, &filec, &filev)) { |
171 | 182 | for (i = 0; i < filec; i++) |
172 | 183 | oafp = append_it(filev[i], oafp, nafp); |
@@ -400,7 +411,7 @@ | ||
400 | 411 | #ifdef S_IFLNK |
401 | 412 | else if (is_symlink(&stbuf)) { |
402 | 413 | if (noexec) |
403 | - printf("REMOVE SYMBOLIC LINK %s.\n", name); | |
414 | + message("REMOVE SYMBOLIC LINK %s.", name); | |
404 | 415 | else if (unlink(name) < 0) |
405 | 416 | warning("Cannot remove", name); |
406 | 417 | else if (verbose) |
@@ -106,6 +106,8 @@ | ||
106 | 106 | |
107 | 107 | extract_broken_archive = FALSE; |
108 | 108 | decode_macbinary_contents = FALSE; |
109 | + sort_contents = TRUE; | |
110 | + recursive_archiving = TRUE; | |
109 | 111 | } |
110 | 112 | |
111 | 113 | /* ------------------------------------------------------------------------ */ |
@@ -214,6 +216,7 @@ | ||
214 | 216 | ARCHIVE_KANJI_CODE_OPTION, |
215 | 217 | TRADITIONAL_BEHAVIOR, |
216 | 218 | IGNORE_MAC_FILES, |
219 | + DEBUG_OPTION, | |
217 | 220 | }; |
218 | 221 | |
219 | 222 | struct option long_options[] = { |
@@ -227,6 +230,7 @@ | ||
227 | 230 | {"convert-filename-case", no_argument, &convertcase, TRUE}, |
228 | 231 | {"traditional", no_argument, 0, TRADITIONAL_BEHAVIOR}, |
229 | 232 | {"ignore-mac-files", no_argument, 0, IGNORE_MAC_FILES}, |
233 | + {"debug", required_argument, 0, DEBUG_OPTION}, | |
230 | 234 | {0, 0, 0, 0} |
231 | 235 | }; |
232 | 236 | int i; |
@@ -444,6 +448,25 @@ | ||
444 | 448 | exclude_files[i+3] = 0; |
445 | 449 | break; |
446 | 450 | |
451 | + case DEBUG_OPTION: | |
452 | + if (!optarg) { | |
453 | + error("debugging item is not specified for --%s=item", | |
454 | + long_options[option_index].name); | |
455 | + return -1; | |
456 | + } | |
457 | + if (strcmp(optarg, "nosort") == 0) { | |
458 | + sort_contents = FALSE; | |
459 | + } | |
460 | + else if (strcmp(optarg, "norecursion") == 0) { | |
461 | + recursive_archiving = FALSE; | |
462 | + } | |
463 | + else { | |
464 | + error("unknown debugging item \"%s\" for --%s=item", | |
465 | + optarg, long_options[option_index].name); | |
466 | + return -1; | |
467 | + } | |
468 | + break; | |
469 | + | |
447 | 470 | default: |
448 | 471 | error("unknown option `-%c'.", c); |
449 | 472 | return -1; |
@@ -845,7 +868,7 @@ | ||
845 | 868 | static void |
846 | 869 | sort_files() |
847 | 870 | { |
848 | - if (cmd_filec > 1) | |
871 | + if (cmd_filec > 1 && sort_contents) | |
849 | 872 | qsort(cmd_filev, cmd_filec, sizeof(char *), sort_by_ascii); |
850 | 873 | } |
851 | 874 |
@@ -1139,7 +1162,7 @@ | ||
1139 | 1162 | } |
1140 | 1163 | closedir(dirp); |
1141 | 1164 | finish_sp(&sp, v_filec, v_filev); |
1142 | - if (*v_filec > 1) | |
1165 | + if (*v_filec > 1 && sort_contents) | |
1143 | 1166 | qsort(*v_filev, *v_filec, sizeof(char *), sort_by_ascii); |
1144 | 1167 | cleaning_files(v_filec, v_filev); |
1145 | 1168 |
@@ -600,7 +600,7 @@ | ||
600 | 600 | |
601 | 601 | static void add_dirinfo(char *name, LzHeader *hdr) |
602 | 602 | { |
603 | - LzHeaderList *p; | |
603 | + LzHeaderList *p, *tmp, top; | |
604 | 604 | |
605 | 605 | if (memcmp(hdr->method, LZHDIRS_METHOD, 5) != 0) |
606 | 606 | return; |
@@ -611,16 +611,54 @@ | ||
611 | 611 | strncpy(p->hdr.name, name, sizeof(p->hdr.name)); |
612 | 612 | p->hdr.name[sizeof(p->hdr.name)-1] = 0; |
613 | 613 | |
614 | +#if 0 | |
615 | + /* push front */ | |
614 | 616 | { |
615 | - LzHeaderList *tmp = dirinfo; | |
617 | + tmp = dirinfo; | |
616 | 618 | dirinfo = p; |
617 | 619 | dirinfo->next = tmp; |
618 | 620 | } |
621 | +#else | |
622 | + | |
623 | + /* | |
624 | + reverse sorted by pathname order | |
625 | + | |
626 | + p->hdr.name = "a" | |
627 | + | |
628 | + dirinfo->hdr.name = "a/b/d" | |
629 | + dirinfo->next->hdr.name = "a/b/c" | |
630 | + dirinfo->next->next->hdr.name = "a/b" | |
631 | + | |
632 | + result: | |
633 | + | |
634 | + dirinfo->hdr.name = "a/b/d" | |
635 | + dirinfo->next->hdr.name = "a/b/c" | |
636 | + dirinfo->next->next->hdr.name = "a/b" | |
637 | + dirinfo->next->next->next->hdr.name = "a" | |
638 | + */ | |
639 | + | |
640 | + top.next = dirinfo; | |
641 | + | |
642 | + for (tmp = ⊤ tmp->next; tmp = tmp->next) { | |
643 | + if (strcmp(p->hdr.name, tmp->next->hdr.name) > 0) { | |
644 | + p->next = tmp->next; | |
645 | + tmp->next = p; | |
646 | + break; | |
647 | + } | |
648 | + } | |
649 | + if (tmp->next == NULL) { | |
650 | + p->next = NULL; | |
651 | + tmp->next = p; | |
652 | + } | |
653 | + | |
654 | + dirinfo = top.next; | |
655 | +#endif | |
619 | 656 | } |
620 | 657 | |
621 | 658 | static void adjust_dirinfo() |
622 | 659 | { |
623 | 660 | while (dirinfo) { |
661 | + /* message("adjusting [%s]", dirinfo->hdr.name); */ | |
624 | 662 | adjust_info(dirinfo->hdr.name, &dirinfo->hdr); |
625 | 663 | |
626 | 664 | { |