OSDN Git Service

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