OSDN Git Service

* src/lharc.c (message): use variable argument list with stdarg.
[lha/lha.git] / src / lhlist.c
1 /* ------------------------------------------------------------------------ */
2 /* LHa for UNIX                                                                                                                         */
3 /*                              lhlist.c -- LHarc list                                                                          */
4 /*                                                                                                                                                      */
5 /*              Copyright (C) MCMLXXXIX Yooichi.Tagawa                                                          */
6 /*              Modified                        Nobutaka Watazaki                                                       */
7 /*                                                                                                                                                      */
8 /*  Ver. 0.00   Original                                                1988.05.23  Y.Tagawa            */
9 /*  Ver. 1.00   Fixed                                                   1989.09.22  Y.Tagawa            */
10 /*  Ver. 1.01   Bug Fix for month name                  1989.12.25  Y.Tagawa            */
11 /*  Ver. 1.10   Changed list format                             1993.10.01      N.Watazaki              */
12 /*      Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
13 /*      Ver. 1.14e      Bug Fix for many problems               1999.05.25  T.Okamoto       */
14 /* ------------------------------------------------------------------------ */
15 #include "lha.h"
16
17 /* ------------------------------------------------------------------------ */
18 static long     packed_size_total;
19 static long     original_size_total;
20 static int      list_files;
21
22 /* ------------------------------------------------------------------------ */
23 /* Print Stuff                                                                                                                          */
24 /* ------------------------------------------------------------------------ */
25 /* need 14 or 22 (when verbose_listing is TRUE) column spaces */
26 static void
27 print_size(packed_size, original_size)
28         long            packed_size, original_size;
29 {
30         if (verbose_listing)
31                 printf("%7d ", packed_size);
32
33         printf("%7d ", original_size);
34
35         if (original_size == 0L)
36                 printf("******");
37         else    /* Changed N.Watazaki */
38                 printf("%5.1f%%", packed_size * 100.0 / original_size);
39 }
40
41 /* ------------------------------------------------------------------------ */
42 /* need 12 or 17 (when verbose_listing is TRUE) column spaces */
43 static void
44 print_stamp(t)
45         time_t          t;
46 {
47         static boolean  got_now = FALSE;
48         static time_t   now;
49         static unsigned int threshold;
50         static char     t_month[12 * 3 + 1] = "JanFebMarAprMayJunJulAugSepOctNovDec";
51         struct tm      *p;
52
53         if (t == 0) {
54                 printf("            "); /* 12 spaces */
55                 return;
56         }
57
58         if (!got_now) {
59                 now = time((time_t *) 0);
60                 p = localtime(&now);
61                 threshold = p->tm_year * 12 + p->tm_mon - 6;
62                 got_now = TRUE;
63         }
64
65         p = localtime(&t);
66
67         if (p->tm_year * 12 + p->tm_mon > threshold)
68                 printf("%.3s %2d %02d:%02d",
69                 &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min);
70         else
71                 printf("%.3s %2d  %04d",
72                     &t_month[p->tm_mon * 3], p->tm_mday, p->tm_year + 1900);
73 }
74
75 /* ------------------------------------------------------------------------ */
76 static void
77 print_bar()
78 {
79         char           *p, *q;
80         /* 17+1+(0 or 7+1)+7+1+6+1+(0 or 1+4)+(12 or 17)+1+20 */
81         /* 12345678901234567_  1234567_123456  _123456789012   1234 */
82
83         if (verbose_listing) {
84                 p = "- ------ ---------- ";
85                 q = " -------------";
86         }
87         else {
88                 p = " ";
89                 q = " --------------------";
90         }
91
92         if (verbose)
93                 q = "";
94
95         printf("---------- ----------- ------- ------%s------------%s\n", p, q);
96 }
97
98 /* ------------------------------------------------------------------------ */
99 /*                                                                                                                                                      */
100 /* ------------------------------------------------------------------------ */
101 static void
102 list_header()
103 {
104         char           *p, *q;
105
106         if (verbose_listing) {
107                 p = "PACKED    SIZE  RATIO METHOD CRC";
108                 q = "          NAME";
109         }
110         else {
111                 p = "  SIZE  RATIO";
112                 q = "           NAME";
113         }
114
115         if (verbose)
116                 q = "";
117
118         printf(" PERMSSN    UID  GID    %s     STAMP%s\n", p, q);
119 #if 0
120         printf(" PERMSSN  UID GID %s   SIZE  RATIO%s %s    STAMP%s%s\n",
121                verbose_listing ? " PACKED " : "",       /* 8,0 */
122                verbose_listing ? "  CRC" : "",  /* 5,0 */
123                verbose_listing ? "  " : "",     /* 2,0 */
124                verbose_listing ? "      " : "   ",      /* 6,3 */
125                verbose ? "" : " NAME");
126 #endif
127         print_bar();
128 }
129
130 /* ------------------------------------------------------------------------ */
131 static void
132 list_one(hdr)
133         register LzHeader *hdr;
134 {
135         register int    mode;
136         register char  *p;
137         char            method[6];
138         char modebits[11];
139
140         if (verbose)
141                 printf("%s\n", hdr->name);
142
143         strncpy(method, hdr->method, 5);
144         method[5] = '\0';
145
146         switch (mode = hdr->extend_type) {
147         case EXTEND_UNIX:
148                 mode = hdr->unix_mode;
149
150                 if (mode & UNIX_FILE_DIRECTORY)
151                         modebits[0] = 'd';
152                 else if ((mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK)
153                         modebits[0] = 'l';
154                 else
155                         modebits[0] = '-';
156                 modebits[1] = ((mode & UNIX_OWNER_READ_PERM) ? 'r' : '-');
157                 modebits[2] = ((mode & UNIX_OWNER_WRITE_PERM) ? 'w' : '-');
158                 modebits[3] = (mode & UNIX_SETUID) ? 's' :
159                         ((mode & UNIX_OWNER_EXEC_PERM) ? 'x' : '-');
160                 modebits[4] = ((mode & UNIX_GROUP_READ_PERM) ? 'r' : '-');
161                 modebits[5] = ((mode & UNIX_GROUP_WRITE_PERM) ? 'w' : '-');
162                 modebits[6] = (mode & UNIX_SETGID) ? 's' :
163                         ((mode & UNIX_GROUP_EXEC_PERM) ? 'x' : '-');
164                 modebits[7] = ((mode & UNIX_OTHER_READ_PERM) ? 'r' : '-');
165                 modebits[8] = ((mode & UNIX_OTHER_WRITE_PERM) ? 'w' : '-');
166                 modebits[9] = (mode & UNIX_STICKYBIT) ? 't' :
167                         ((mode & UNIX_OTHER_EXEC_PERM) ? 'x' : '-');
168                 modebits[10] = 0;
169
170         printf("%s ", modebits);
171                 break;
172         case EXTEND_OS68K:
173          /**/ case EXTEND_XOSK:/**/
174                 mode = hdr->unix_mode;
175                 printf("%c%c%c%c%c%c%c%c   ",
176                        ((mode & OSK_DIRECTORY_PERM) ? 'd' : '-'),
177                        ((mode & OSK_SHARED_PERM) ? 's' : '-'),
178                        ((mode & OSK_OTHER_EXEC_PERM) ? 'e' : '-'),
179                        ((mode & OSK_OTHER_WRITE_PERM) ? 'w' : '-'),
180                        ((mode & OSK_OTHER_READ_PERM) ? 'r' : '-'),
181                        ((mode & OSK_OWNER_EXEC_PERM) ? 'e' : '-'),
182                        ((mode & OSK_OWNER_WRITE_PERM) ? 'w' : '-'),
183                        ((mode & OSK_OWNER_READ_PERM) ? 'r' : '-'));
184
185                 break;
186         default:
187                 switch (hdr->extend_type) {     /* max 18 characters */
188                 case EXTEND_GENERIC:
189                         p = "[generic]";
190                         break;
191                 case EXTEND_CPM:
192                         p = "[CP/M]";
193                         break;
194                 case EXTEND_FLEX:
195                         p = "[FLEX]";
196                         break;
197                 case EXTEND_OS9:
198                         p = "[OS-9]";
199                         break;
200                 case EXTEND_OS68K:
201                         p = "[OS-9/68K]";
202                         break;
203                 case EXTEND_MSDOS:
204                         p = "[MS-DOS]";
205                         break;
206                 case EXTEND_MACOS:
207                         p = "[Mac OS]";
208                         break;
209                 case EXTEND_OS2:
210                         p = "[OS/2]";
211                         break;
212                 case EXTEND_HUMAN:
213                         p = "[Human68K]";
214                         break;
215                 case EXTEND_OS386:
216                         p = "[OS-386]";
217                         break;
218                 case EXTEND_RUNSER:
219                         p = "[Runser]";
220                         break;
221 #ifdef EXTEND_TOWNSOS
222                         /* This ID isn't fixed */
223                 case EXTEND_TOWNSOS:
224                         p = "[TownsOS]";
225                         break;
226 #endif
227                         /* Ouch!  Please customize it's ID.  */
228                 default:
229                         p = "[unknown]";
230                         break;
231                 }
232                 printf("%-11.11s", p);
233                 break;
234         }
235
236     switch (mode = hdr->extend_type) {
237     case EXTEND_UNIX:
238     case EXTEND_OS68K:
239     case EXTEND_XOSK:
240         if (hdr->user[0])
241             printf("%5.5s/", hdr->user);
242         else
243             printf("%5d/", hdr->unix_uid);
244
245         if (hdr->group[0])
246             printf("%-5.5s ", hdr->group);
247         else
248             printf("%-5d ", hdr->unix_gid);
249         break;
250     default:
251         printf("%12s", "");
252         break;
253     }
254
255         print_size(hdr->packed_size, hdr->original_size);
256
257         if (verbose_listing)
258                 if (hdr->has_crc)
259                         printf(" %s %04x", method, hdr->crc);
260                 else
261                         printf(" %s ****", method);
262
263         printf(" ");
264         print_stamp(hdr->unix_last_modified_stamp);
265
266         if (!verbose)
267                 if ((mode & UNIX_FILE_SYMLINK) != UNIX_FILE_SYMLINK)
268                         printf(" %s", hdr->name);
269                 else {
270                         char            buf[256], *b1, *b2;
271                         strcpy(buf, hdr->name);
272                         b1 = strtok(buf, "|");
273                         b2 = strtok(NULL, "|");
274                         printf(" %s -> %s", b1, b2);
275                 }
276
277         if (verbose)
278                 printf(" [%d]", hdr->header_level);
279         printf("\n");
280
281 }
282
283 /* ------------------------------------------------------------------------ */
284 static void
285 list_tailer()
286 {
287         struct stat     stbuf;
288
289         print_bar();
290
291         printf(" Total %9d file%c ",
292                list_files, (list_files == 1) ? ' ' : 's');
293         print_size(packed_size_total, original_size_total);
294         printf(" ");
295
296         if (verbose_listing)
297                 printf("           ");
298
299         if (stat(archive_name, &stbuf) < 0)
300                 print_stamp((time_t) 0);
301         else
302                 print_stamp(stbuf.st_mtime);
303
304         printf("\n");
305 }
306
307 /* ------------------------------------------------------------------------ */
308 /* LIST COMMAND MAIN                                                                                                            */
309 /* ------------------------------------------------------------------------ */
310 void
311 cmd_list()
312 {
313         FILE           *afp;
314         LzHeader        hdr;
315         int             i;
316
317         /* initialize total count */
318         packed_size_total = 0L;
319         original_size_total = 0L;
320         list_files = 0;
321
322         /* open archive file */
323         if ((afp = open_old_archive()) == NULL) {
324                 error("Cannot open archive \"%s\"", archive_name);
325                 exit(1);
326         }
327         if (archive_is_msdos_sfx1(archive_name))
328                 skip_msdos_sfx1_code(afp);
329
330         /* print header message */
331         if (!quiet)
332                 list_header();
333
334         /* print each file information */
335         while (get_header(afp, &hdr)) {
336                 if (need_file(hdr.name)) {
337                         list_one(&hdr);
338                         list_files++;
339                         packed_size_total += hdr.packed_size;
340                         original_size_total += hdr.original_size;
341                 }
342
343                 if (afp != stdin)
344                         fseek(afp, hdr.packed_size, SEEK_CUR);
345                 else {
346                         i = hdr.packed_size;
347                         while (i--)
348                                 fgetc(afp);
349                 }
350         }
351
352         /* close archive file */
353         fclose(afp);
354
355         /* print tailer message */
356         if (!quiet)
357                 list_tailer();
358
359         return;
360 }
361
362 /* Local Variables: */
363 /* mode:c */
364 /* tab-width:4 */
365 /* compile-command:"gcc -c lhlist.c" */
366 /* End: */
367 /* vi: set tabstop=4: */