"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "lha-114i/src/lharc.c" of archive lha-114i.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* ------------------------------------------------------------------------ */
2 /* LHa for UNIX */
3 /* lharc.c -- append to archive */
4 /* */
5 /* Copyright (C) MCMLXXXIX Yooichi.Tagawa */
6 /* Modified Nobutaka Watazaki */
7 /* Thanks to H.Yoshizaki. (MS-DOS LHarc) */
8 /* */
9 /* Ver. 0.00 Original 1988.05.23 Y.Tagawa */
10 /* Ver. 0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */
11 /* Ver. 0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */
12 /* Ver. 0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */
13 /* Ver. 0.03a Debug 1989.07.03 Y.Tagawa */
14 /* Ver. 0.03b Modified 1989.07.13 Y.Tagawa */
15 /* Ver. 0.03c Debug (Thanks to void@rena.dit.junet) */
16 /* 1989.08.09 Y.Tagawa */
17 /* Ver. 0.03d Modified (quiet and verbose) 1989.09.14 Y.Tagawa */
18 /* V1.00 Fixed 1989.09.22 Y.Tagawa */
19 /* V1.01 Bug Fixed 1989.12.25 Y.Tagawa */
20 /* */
21 /* DOS-Version Original LHx V C2.01 (C) H.Yohizaki */
22 /* */
23 /* V2.00 UNIX Lharc + DOS LHx -> OSK LHx 1990.11.01 Momozou */
24 /* V2.01 Minor Modified 1990.11.24 Momozou */
25 /* */
26 /* Ver. 0.02 LHx for UNIX 1991.11.18 M.Oki */
27 /* Ver. 0.03 LHa for UNIX 1991.12.17 M.Oki */
28 /* Ver. 0.04 LHa for UNIX beta version 1992.01.20 M.Oki */
29 /* Ver. 1.00 LHa for UNIX Fixed 1992.03.19 M.Oki */
30 /* */
31 /* Ver. 1.10 for Symblic Link 1993.06.25 N.Watazaki */
32 /* Ver. 1.11 for Symblic Link Bug Fixed 1993.08.18 N.Watazaki */
33 /* Ver. 1.12 for File Date Check 1993.10.28 N.Watazaki */
34 /* Ver. 1.13 Bug Fixed (Idicator calcurate) 1994.02.21 N.Watazaki */
35 /* Ver. 1.13a Bug Fixed (Sym. Link delete) 1994.03.11 N.Watazaki */
36 /* Ver. 1.13b Bug Fixed (Sym. Link delete) 1994.07.29 N.Watazaki */
37 /* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
38 /* Ver. 1.14b,c Bug Fixed 1996.03.07 t.okamoto */
39 /* Ver. 1.14d Version up 1997.01.12 t.okamoto */
40 /* Ver. 1.14g Bug Fixed 2000.05.06 t.okamoto */
41 /* Ver. 1.14i Modified 2000.10.06 t.okamoto */
42 /* ------------------------------------------------------------------------ */
43 #define LHA_MAIN_SRC
44
45 #include "lha.h"
46
47 /* ------------------------------------------------------------------------ */
48 /* PROGRAM */
49 /* ------------------------------------------------------------------------ */
50 static int cmd = CMD_UNKNOWN;
51
52 /* 1996.8.13 t.okamoto */
53 #if 0
54 char **cmd_filev;
55 int cmd_filec;
56
57 char *archive_name;
58 char expanded_archive_name[FILENAME_LENGTH];
59 char temporary_name[FILENAME_LENGTH];
60 char backup_archive_name[FILENAME_LENGTH];
61 #endif
62
63 /* static functions */
64 static void sort_files();
65 static void print_version();
66
67 char *extract_directory = NULL;
68 char **xfilev;
69 int xfilec = 257;
70
71 /* 1996.8.13 t.okamoto */
72 #if 0
73 char *writting_filename;
74 char *reading_filename;
75
76 int archive_file_mode;
77 int archive_file_gid;
78 #endif
79 /* ------------------------------------------------------------------------ */
80 static void
81 init_variable() /* Added N.Watazaki */
82 {
83 /* options */
84 quiet = FALSE;
85 text_mode = FALSE;
86 verbose = FALSE;
87 noexec = FALSE; /* debugging option */
88 force = FALSE;
89 prof = FALSE;
90 #ifndef SUPPORT_LH7
91 compress_method = LZHUFF5_METHOD_NUM;
92 #endif
93 #ifdef SUPPORT_LH7
94 compress_method = LZHUFF7_METHOD_NUM;
95 #endif
96
97 header_level = HEADER_LEVEL1;
98 quiet_mode = 0;
99
100 #ifdef EUC
101 euc_mode = FALSE;
102 #endif
103
104 /* view command flags */
105 verbose_listing = FALSE;
106
107 /* extract command flags */
108 output_to_stdout = FALSE;
109
110 /* append command flags */
111 new_archive = FALSE;
112 update_if_newer = FALSE;
113 delete_after_append = FALSE;
114 generic_format = FALSE;
115
116 remove_temporary_at_error = FALSE;
117 recover_archive_when_interrupt = FALSE;
118 remove_extracting_file_when_interrupt = FALSE;
119 get_filename_from_stdin = FALSE;
120 ignore_directory = FALSE;
121 verify_mode = FALSE;
122
123 noconvertcase = FALSE;
124
125 extract_directory = NULL;
126 xfilec = 257;
127 }
128
129 /* ------------------------------------------------------------------------ */
130 /* NOTES : Text File Format */
131 /* GENERATOR NewLine */
132 /* [generic] 0D 0A */
133 /* [MS-DOS] 0D 0A */
134 /* [OS9][MacOS] 0D */
135 /* [UNIX] 0A */
136 /* ------------------------------------------------------------------------ */
137 static void
138 print_tiny_usage_and_exit()
139 {
140 fprintf(stderr, "\
141 LHarc for UNIX V 1.02 Copyright(C) 1989 Y.Tagawa\n\
142 LHx for MSDOS V C2.01 Copyright(C) 1990 H.Yoshizaki\n\
143 LHx(arc) for OSK V 2.01 Modified 1990 Momozou\n\
144 LHa for UNIX V 1.00 Copyright(C) 1992 Masaru Oki\n\
145 LHa for UNIX V 1.14 Modified 1995 Nobutaka Watazaki\n\
146 LHa for UNIX V 1.14i Modified 2000 Tsugio Okamoto\n\
147 ");
148 fprintf(stderr, "\
149 usage: lha [-]{axelvudmcp[q[num]][vnfodizg012]}[w=<dir>] archive_file [file...]\n\
150 commands: options:\n\
151 a Add(or replace) to archive q{num} quiet (num:quiet mode)\n\
152 x,e EXtract from archive v verbose\n\
153 l,v List / Verbose List n not execute\n\
154 u Update newer files to archive f force (over write at extract)\n\
155 d Delete from archive t FILES are TEXT file\n");
156 #ifdef SUPPORT_LH7
157 fprintf(stderr, "\
158 m Move to archive (means 'ad') o[567] compression method (a/u)\n\
159 ");
160 #endif
161 #ifndef SUPPORT_LH7
162 fprintf(stderr, "\
163 m Move to archive (means 'ad') o use LHarc compatible method (a/u)\n\
164 ");
165 #endif
166 fprintf(stderr, "\
167 c re-Construct new archive w=<dir> specify extract directory (a/u/m/x/e)\n\
168 p Print to STDOUT from archive d delete FILES after (a/u/c)\n\
169 t Test file CRC in archive i ignore directory path (x/e)\n\
170 z files not compress (a/u)\n\
171 g Generic format (for compatibility)\n\
172 or not convert case when extracting\n\
173 0/1/2 header level (a/u)\n\
174 ");
175 #ifdef EUC
176 fprintf(stderr, "\
177 e TEXT code convert from/to EUC\n\
178 ");
179 #endif
180 exit(1);
181 }
182
183 /* ------------------------------------------------------------------------ */
184 int
185 main(argc, argv)
186 int argc;
187 char *argv[];
188 {
189 char *p, inpbuf[256];
190
191 int i;
192 int ac;
193 char **av, *m;
194
195 init_variable(); /* Added N.Watazaki */
196
197 ac = argc;
198 av = (char **)malloc( sizeof(char*)*argc );
199 if (av == NULL) fatal_error("not enough memory\n");
200 for (i=0; i<argc; i++) {
201 if ((av[i] = strdup( argv[i] )) == NULL)
202 fatal_error("not enough memory\n");
203 }
204
205 if (ac < 2)
206 print_tiny_usage_and_exit();
207
208 if (strcmp(av[1], "--version") == 0) {
209 print_version();
210 exit(1);
211 }
212
213 if (ac < 3) {
214 cmd = CMD_LIST;
215 av--; /* argv--; */ /* 1999.7.18 */
216 ac++; /* argc++; */
217 goto work;
218 }
219
220 m = av[1];
221
222 if (m[0] == '-')
223 m++;
224 /* commands */
225 switch (*m) {
226 case 'x':
227 case 'e':
228 cmd = CMD_EXTRACT;
229 break;
230
231 case 'p':
232 output_to_stdout = TRUE;
233 cmd = CMD_EXTRACT;
234 break;
235
236 case 'c':
237 new_archive = TRUE;
238 cmd = CMD_ADD;
239 break;
240
241 case 'a':
242 cmd = CMD_ADD;
243 break;
244
245 case 'd':
246 cmd = CMD_DELETE;
247 break;
248
249 case 'u':
250 update_if_newer = TRUE;
251 cmd = CMD_ADD;
252 break;
253
254 case 'm':
255 delete_after_append = TRUE;
256 cmd = CMD_ADD;
257 break;
258
259 case 'v':
260 verbose_listing = TRUE;
261 cmd = CMD_LIST;
262 break;
263
264 case 'l':
265 cmd = CMD_LIST;
266 break;
267
268 case 't':
269 cmd = CMD_EXTRACT;
270 verify_mode = TRUE;
271 break;
272
273 default:
274 print_tiny_usage_and_exit();
275
276 }
277
278 /* options */
279 /* p = &argv[1][1]; */
280 p = m+1;
281 while ( *p != 0 ) {
282 switch ((*p++)) {
283 case 'q':
284 switch (*p) {
285 case '0':
286 case '1':
287 quiet_mode = *p - '0';
288 ++p;
289 break;
290 case '2':
291 default:
292 quiet = TRUE;
293 break;
294 }
295 case 'f':
296 force = TRUE;
297 break;
298 case 'p':
299 prof = TRUE;
300 break;
301 case 'v':
302 verbose = TRUE;
303 break;
304 case 't':
305 text_mode = TRUE;
306 break;
307 #ifdef EUC
308 case 'e':
309 text_mode = TRUE;
310 euc_mode = TRUE;
311 break;
312 #endif
313 case 'n':
314 noexec = TRUE;
315 break;
316 case 'g':
317 generic_format = TRUE;
318 noconvertcase = TRUE;
319 header_level = 0;
320 break;
321 case 'd':
322 delete_after_append = TRUE;
323 break;
324 case 'o':
325 switch (*p) {
326 case 0:
327 compress_method = LZHUFF1_METHOD_NUM;
328 header_level = 0;
329 break;
330 case '5':
331 compress_method = LZHUFF5_METHOD_NUM;
332 p++;
333 break;
334 #ifdef SUPPORT_LH7
335 case '6':
336 compress_method = LZHUFF6_METHOD_NUM;
337 p++;
338 break;
339 case '7':
340 compress_method = LZHUFF7_METHOD_NUM;
341 p++;
342 break;
343 #endif
344 default:
345 fprintf(stderr, "LHa: error option o%c\n", p[-1]);
346 exit(1);
347 }
348 break;
349 case 'z':
350 compress_method = LZHUFF0_METHOD_NUM; /* Changed N.Watazaki */
351 break;
352 case 'i':
353 ignore_directory = TRUE;
354 break;
355 case 'w':
356 if (*p == '=')
357 p++;
358 extract_directory = p;
359 while (*p)
360 p++;
361 break;
362 case '0':
363 header_level = HEADER_LEVEL0;
364 break;
365 case '1':
366 header_level = HEADER_LEVEL1;
367 break;
368 case '2':
369 header_level = HEADER_LEVEL2;
370 break;
371 default:
372 fprintf(stderr, "LHa: Unknown option '%c'.\n", p[-1]);
373 exit(1);
374 }
375 }
376
377 work:
378 /* archive file name */
379 archive_name = av[2];
380
381 if (!strcmp(archive_name, "-")) {
382 if (!isatty(1) && cmd == CMD_ADD)
383 quiet = TRUE;
384 }
385 else {
386 if (ac == 3 && !isatty(0)) { /* 1999.7.18 */
387 get_filename_from_stdin = TRUE;
388 }
389 }
390
391 /* target file name */
392 if (get_filename_from_stdin) {
393 cmd_filec = 0;
394 if ((xfilev = (char **) malloc(sizeof(char *) * xfilec)) == NULL)
395 fatal_error("Virtual memory exhausted\n");
396 while (fgets(inpbuf, sizeof(inpbuf), stdin)) {
397 /* delete \n if it exist */
398 i=0; p=inpbuf;
399 while (i < sizeof(inpbuf) && p != 0) {
400 if (*p == '\n') {
401 *p = 0;
402 break;
403 }
404 p++; i++;
405 }
406
407 if (cmd_filec >= xfilec) {
408 xfilec += 256;
409 cmd_filev = (char **) realloc(xfilev,
410 sizeof(char *) * xfilec);
411 if (cmd_filev == NULL)
412 fatal_error("Virtual memory exhausted\n");
413 xfilev = cmd_filev;
414 }
415 if (strlen(inpbuf) < 1)
416 continue;
417 if ((xfilev[cmd_filec++] = (char *) strdup(inpbuf)) == NULL)
418 fatal_error("Virtual memory exhausted\n");
419 }
420 xfilev[cmd_filec] = NULL;
421 cmd_filev = xfilev;
422 } else {
423 cmd_filec = ac - 3;
424 cmd_filev = av + 3;
425 }
426 sort_files();
427
428 /* make crc table */
429 make_crctable();
430
431 switch (cmd) {
432 case CMD_EXTRACT:
433 cmd_extract();
434 break;
435 case CMD_ADD:
436 cmd_add();
437 break;
438 case CMD_LIST:
439 cmd_list();
440 break;
441 case CMD_DELETE:
442 cmd_delete();
443 break;
444 }
445
446 #ifdef USE_PROF
447 if (!prof)
448 exit(0);
449 #endif
450
451 return 0;
452 }
453
454
455 /* ------------------------------------------------------------------------ */
456 /* */
457 /* ------------------------------------------------------------------------ */
458
459 /* ------------------------------------------------------------------------ */
460 static void
461 print_version()
462 {
463 fprintf(stderr, "%s\n", LHA_VERSION);
464 }
465
466 /* ------------------------------------------------------------------------ */
467 static void
468 message_1(title, subject, name)
469 char *title, *subject, *name;
470 {
471 fprintf(stderr, "LHa: %s%s ", title, subject);
472 fflush(stderr);
473
474 if (errno == 0)
475 fprintf(stderr, "%s\n", name);
476 else
477 perror(name);
478 }
479
480 /* ------------------------------------------------------------------------ */
481 void
482 message(subject, name)
483 char *subject, *name;
484 {
485 message_1("", subject, name);
486 }
487
488 /* ------------------------------------------------------------------------ */
489 void
490 warning(subject, name)
491 char *subject, *name;
492 {
493 message_1("Warning: ", subject, name);
494 }
495
496 /* ------------------------------------------------------------------------ */
497 void
498 error(subject, msg)
499 char *subject, *msg;
500 {
501 message_1("Error: ", subject, msg);
502 }
503
504 /* ------------------------------------------------------------------------ */
505 void
506 fatal_error(msg)
507 char *msg;
508 {
509 message_1("Fatal error:", "", msg);
510
511 if (remove_temporary_at_error)
512 unlink(temporary_name);
513
514 exit(1);
515 }
516
517 /* ------------------------------------------------------------------------ */
518 void
519 write_error()
520 {
521 fatal_error(writting_filename);
522 }
523
524 /* ------------------------------------------------------------------------ */
525 void
526 read_error()
527 {
528 fatal_error(reading_filename);
529 }
530
531 /* ------------------------------------------------------------------------ */
532 void
533 interrupt(signo)
534 int signo;
535 {
536 errno = 0;
537 message("Interrupted\n", "");
538
539 if (temporary_fp)
540 fclose(temporary_fp);
541 unlink(temporary_name);
542 if (recover_archive_when_interrupt)
543 rename(backup_archive_name, archive_name);
544 if (remove_extracting_file_when_interrupt) {
545 errno = 0;
546 message("Removing", writting_filename);
547 unlink(writting_filename);
548 }
549 signal(SIGINT, SIG_DFL);
550 signal(SIGHUP, SIG_DFL);
551 kill(getpid(), signo);
552 }
553
554 /* ------------------------------------------------------------------------ */
555 /* */
556 /* ------------------------------------------------------------------------ */
557 static int
558 sort_by_ascii(a, b)
559 char **a, **b;
560 {
561 register char *p, *q;
562 register int c1, c2;
563
564 p = *a, q = *b;
565 if (generic_format) {
566 do {
567 c1 = *(unsigned char *) p++;
568 c2 = *(unsigned char *) q++;
569 if (!c1 || !c2)
570 break;
571 if (islower(c1))
572 c1 = toupper(c1);
573 if (islower(c2))
574 c2 = toupper(c2);
575 }
576 while (c1 == c2);
577 return c1 - c2;
578 }
579 else {
580 while (*p == *q && *p != '\0')
581 p++, q++;
582 return *(unsigned char *) p - *(unsigned char *) q;
583 }
584 }
585
586 /* ------------------------------------------------------------------------ */
587 static void
588 sort_files()
589 {
590 if (cmd_filec > 1)
591 qsort(cmd_filev, cmd_filec, sizeof(char *), sort_by_ascii);
592 }
593
594 /* ------------------------------------------------------------------------ */
595 char *
596 xmalloc(size)
597 int size;
598 {
599 char *p = (char *) malloc(size);
600 if (!p)
601 fatal_error("Not enough memory");
602 return p;
603 }
604
605 /* ------------------------------------------------------------------------ */
606 char *
607 xrealloc(old, size)
608 char *old;
609 int size;
610 {
611 char *p = (char *) realloc(old, size);
612 if (!p)
613 fatal_error("Not enough memory");
614 return p;
615 }
616
617 /* ------------------------------------------------------------------------ */
618 /* STRING POOL */
619 /* ------------------------------------------------------------------------ */
620 /*
621 string pool :
622 +-------------+-------------+------+-------------+----------+
623 | N A M E 1 \0| N A M E 2 \0| .... | N A M E n \0| |
624 +-------------+-------------+------+-------------+----------+
625 ^ ^ ^ buffer+0 buffer+used buffer+size
626
627 vector :
628 +---------------+---------------+------------- -----------------+
629 | pointer to | pointer to | pointer to ... pointer to |
630 | stringpool | N A M E 1 | N A M E 2 ... N A M E n |
631 +---------------+---------------+------------- -------------+
632 ^ malloc base returned
633 */
634
635 /* ------------------------------------------------------------------------ */
636 void
637 init_sp(sp)
638 struct string_pool *sp;
639 {
640 sp->size = 1024 - 8; /* any ( >=0 ) */
641 sp->used = 0;
642 sp->n = 0;
643 sp->buffer = (char *) xmalloc(sp->size * sizeof(char));
644 }
645
646 /* ------------------------------------------------------------------------ */
647 void
648 add_sp(sp, name, len)
649 struct string_pool *sp;
650 char *name; /* stored '\0' at tail */
651 int len; /* include '\0' */
652 {
653 while (sp->used + len > sp->size) {
654 sp->size *= 2;
655 sp->buffer = (char *) xrealloc(sp->buffer, sp->size * sizeof(char));
656 }
657 bcopy(name, sp->buffer + sp->used, len);
658 sp->used += len;
659 sp->n++;
660 }
661
662 /* ------------------------------------------------------------------------ */
663 void
664 finish_sp(sp, v_count, v_vector)
665 register struct string_pool *sp;
666 int *v_count;
667 char ***v_vector;
668 {
669 int i;
670 register char *p;
671 char **v;
672
673 v = (char **) xmalloc((sp->n + 1) * sizeof(char *));
674 *v++ = sp->buffer;
675 *v_vector = v;
676 *v_count = sp->n;
677 p = sp->buffer;
678 for (i = sp->n; i; i--) {
679 *v++ = p;
680 if (i - 1)
681 p += strlen(p) + 1;
682 }
683 }
684
685 /* ------------------------------------------------------------------------ */
686 void
687 free_sp(vector)
688 char **vector;
689 {
690 vector--;
691 free(*vector); /* free string pool */
692 free(vector);
693 }
694
695
696 /* ------------------------------------------------------------------------ */
697 /* READ DIRECTORY FILES */
698 /* ------------------------------------------------------------------------ */
699 static boolean
700 include_path_p(path, name)
701 char *path, *name;
702 {
703 char *n = name;
704 while (*path)
705 if (*path++ != *n++)
706 return (path[-1] == '/' && *n == '\0');
707 return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/'));
708 }
709
710 /* ------------------------------------------------------------------------ */
711 void
712 cleaning_files(v_filec, v_filev)
713 int *v_filec;
714 char ***v_filev;
715 {
716 char *flags;
717 struct stat stbuf;
718
719 register char **filev = *v_filev;
720 register int filec = *v_filec;
721 register char *p;
722 register int i, j;
723
724 if (filec == 0)
725 return;
726
727 flags = xmalloc(filec * sizeof(char));
728
729 /* flags & 0x01 : 1: ignore */
730 /* flags & 0x02 : 1: directory, 0 : regular file */
731 /* flags & 0x04 : 1: need delete */
732
733
734 for (i = 0; i < filec; i++)
735 if (GETSTAT(filev[i], &stbuf) < 0) {
736 flags[i] = 0x04;
737 fprintf(stderr,
738 "LHa: Cannot access \"%s\", ignored.\n", filev[i]);
739 }
740 else {
741 if (is_regularfile(&stbuf))
742 flags[i] = 0x00;
743 else if (is_directory(&stbuf))
744 flags[i] = 0x02;
745 #ifdef S_IFLNK
746 else if (is_symlink(&stbuf)) /* t.okamoto */
747 flags[i] = 0x00;
748 #endif
749 else {
750 flags[i] = 0x04;
751 fprintf(stderr,
752 "LHa: Cannot archive \"%s\", ignored.\n", filev[i]);
753 }
754 }
755 errno = 0;
756
757 for (i = 0; i < filec; i++) {
758 p = filev[i];
759 if ((flags[i] & 0x07) == 0x00) { /* regular file, not
760 * deleted/ignored */
761 for (j = i + 1; j < filec; j++) {
762 if ((flags[j] & 0x07) == 0x00) { /* regular file, not
763 * deleted/ignored */
764 if (STREQU(p, filev[j]))
765 flags[j] = 0x04; /* delete */
766 }
767 }
768 }
769 else if ((flags[i] & 0x07) == 0x02) { /* directory, not
770 * deleted/ignored */
771 for (j = i + 1; j < filec; j++) {
772 if ((flags[j] & 0x07) == 0x00) { /* regular file, not
773 * deleted/ignored */
774 if (include_path_p(p, filev[j]))
775 flags[j] = 0x04; /* delete */
776 }
777 else if ((flags[j] & 0x07) == 0x02) { /* directory, not
778 * deleted/ignored */
779 if (include_path_p(p, filev[j]))
780 flags[j] = 0x04; /* delete */
781 }
782 }
783 }
784 }
785
786 for (i = j = 0; i < filec; i++) {
787 if ((flags[i] & 0x04) == 0) {
788 if (i != j)
789 filev[j] = filev[i];
790 j++;
791 }
792 }
793 *v_filec = j;
794
795 free(flags);
796 }
797
798 /* ------------------------------------------------------------------------ */
799 #ifdef NODIRECTORY
800 /* please need your imprementation */
801 boolean
802 find_files(name, v_filec, v_filev)
803 char *name;
804 int *v_filec;
805 char ***v_filev;
806 {
807 return FALSE; /* DUMMY */
808 }
809
810 /* ------------------------------------------------------------------------ */
811 void
812 free_files(filec, filev)
813 int filec;
814 char **filev;
815 {
816 /* do nothing */
817 }
818 /* ------------------------------------------------------------------------ */
819 #else
820 boolean
821 find_files(name, v_filec, v_filev)
822 char *name;
823 int *v_filec;
824 char ***v_filev;
825 {
826 struct string_pool sp;
827 char newname[FILENAME_LENGTH];
828 int len, n;
829 DIR *dirp;
830 DIRENTRY *dp;
831 struct stat tmp_stbuf, arc_stbuf, fil_stbuf;
832
833 strcpy(newname, name);
834 len = strlen(name);
835 if (len > 0 && newname[len - 1] != '/')
836 newname[len++] = '/';
837
838 dirp = opendir(name);
839 if (!dirp)
840 return FALSE;
841
842 init_sp(&sp);
843
844 GETSTAT(temporary_name, &tmp_stbuf);
845 GETSTAT(archive_name, &arc_stbuf);
846
847 for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
848 n = NAMLEN(dp);
849 strncpy(newname + len, dp->d_name, n);
850 newname[len + n] = '\0';
851 if (GETSTAT(newname, &fil_stbuf) < 0)
852 continue;
853 #ifdef NO_INODE
854 if ( dp->d_name[0] != '.' ||
855 (n != 1 &&
856 (dp->d_name[1] != '.' ||
857 n != 2)) ) {
858 add_sp(&sp, newname, len+n+1);
859 }
860 #else
861 if ((dp->d_ino != 0) &&
862 /* exclude '.' and '..' */
863 ((dp->d_name[0] != '.') ||
864 ((n != 1) &&
865 ((dp->d_name[1] != '.') ||
866 (n != 2)))) &&
867 ((tmp_stbuf.st_dev != fil_stbuf.st_dev ||
868 tmp_stbuf.st_ino != fil_stbuf.st_ino) &&
869 (arc_stbuf.st_dev != fil_stbuf.st_dev ||
870 arc_stbuf.st_ino != fil_stbuf.st_ino))) {
871 add_sp(&sp, newname, len + n + 1);
872 }
873 #endif
874 }
875 closedir(dirp);
876 finish_sp(&sp, v_filec, v_filev);
877 if (*v_filec > 1)
878 qsort(*v_filev, *v_filec, sizeof(char *), sort_by_ascii);
879 cleaning_files(v_filec, v_filev);
880
881 return TRUE;
882 }
883
884 /* ------------------------------------------------------------------------ */
885 void
886 free_files(filec, filev)
887 int filec;
888 char **filev;
889 {
890 free_sp(filev);
891 }
892 #endif
893 /* ------------------------------------------------------------------------ */
894 /* */
895 /* ------------------------------------------------------------------------ */
896 /* Build temporary file name and store to TEMPORARY_NAME */
897 void
898 build_temporary_name()
899 {
900 #ifdef TMP_FILENAME_TEMPLATE
901 /* "/tmp/lhXXXXXX" etc. */
902 if (extract_directory == NULL) {
903 strcpy(temporary_name, TMP_FILENAME_TEMPLATE);
904 }
905 else {
906 sprintf(temporary_name, "%s/lhXXXXXX", extract_directory);
907 }
908 #ifdef MKSTEMP
909 mkstemp(temporary_name);
910 #else
911 mktemp(temporary_name);
912 #endif
913 #else
914 char *p, *s;
915
916 strcpy(temporary_name, archive_name);
917 for (p = temporary_name, s = (char *) 0; *p; p++)
918 if (*p == '/')
919 s = p;
920 strcpy((s ? s + 1 : temporary_name), "lhXXXXXX");
921 #ifdef MKSTEMP
922 mkstemp(temporary_name);
923 #else
924 mktemp(temporary_name);
925 #endif
926 #endif
927 }
928
929 /* ------------------------------------------------------------------------ */
930 static void
931 modify_filename_extention(buffer, ext)
932 char *buffer;
933 char *ext;
934 {
935 register char *p, *dot;
936
937 for (p = buffer, dot = (char *) 0; *p; p++) {
938 if (*p == '.')
939 dot = p;
940 else if (*p == '/')
941 dot = (char *) 0;
942 }
943
944 if (dot)
945 p = dot;
946
947 strcpy(p, ext);
948 }
949
950 /* ------------------------------------------------------------------------ */
951 /* build backup file name */
952 void
953 build_backup_name(buffer, original)
954 char *buffer;
955 char *original;
956 {
957 strcpy(buffer, original);
958 modify_filename_extention(buffer, BACKUPNAME_EXTENTION); /* ".bak" */
959 }
960
961 /* ------------------------------------------------------------------------ */
962 void
963 build_standard_archive_name(buffer, orginal)
964 char *buffer;
965 char *orginal;
966 {
967 strcpy(buffer, orginal);
968 modify_filename_extention(buffer, ARCHIVENAME_EXTENTION); /* ".lzh" */
969 }
970
971 /* ------------------------------------------------------------------------ */
972 /* */
973 /* ------------------------------------------------------------------------ */
974 boolean
975 need_file(name)
976 char *name;
977 {
978 int i;
979
980 if (cmd_filec == 0)
981 return TRUE;
982
983 for (i = 0; i < cmd_filec; i++) {
984 if (patmatch(cmd_filev[i], name, 0))
985 return TRUE;
986 }
987
988 return FALSE;
989 }
990
991 FILE *
992 xfopen(name, mode)
993 char *name, *mode;
994 {
995 FILE *fp;
996
997 if ((fp = fopen(name, mode)) == NULL)
998 fatal_error(name);
999
1000 return fp;
1001 }
1002
1003 /* ------------------------------------------------------------------------ */
1004 /* */
1005 /* ------------------------------------------------------------------------ */
1006