OSDN Git Service

added modeline for vi(m).
[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_STYCKYBIT) ? 't' :
167                         ((mode & UNIX_OTHER_EXEC_PERM) ? 'x' : '-');
168                 modebits[10] = 0;
169
170                 printf("%s %5d/%-5d ", modebits,
171                        hdr->unix_uid, hdr->unix_gid);
172                 break;
173         case EXTEND_OS68K:
174          /**/ case EXTEND_XOSK:/**/
175                 mode = hdr->unix_mode;
176                 printf("%c%c%c%c%c%c%c%c %5d/%-5d",
177                        ((mode & OSK_DIRECTORY_PERM) ? 'd' : '-'),
178                        ((mode & OSK_SHARED_PERM) ? 's' : '-'),
179                        ((mode & OSK_OTHER_EXEC_PERM) ? 'e' : '-'),
180                        ((mode & OSK_OTHER_WRITE_PERM) ? 'w' : '-'),
181                        ((mode & OSK_OTHER_READ_PERM) ? 'r' : '-'),
182                        ((mode & OSK_OWNER_EXEC_PERM) ? 'e' : '-'),
183                        ((mode & OSK_OWNER_WRITE_PERM) ? 'w' : '-'),
184                        ((mode & OSK_OWNER_READ_PERM) ? 'r' : '-'),
185                        hdr->unix_uid, hdr->unix_gid);
186                 break;
187         default:
188                 switch (hdr->extend_type) {     /* max 18 characters */
189                 case EXTEND_GENERIC:
190                         p = "[generic]";
191                         break;
192                 case EXTEND_CPM:
193                         p = "[CP/M]";
194                         break;
195                 case EXTEND_FLEX:
196                         p = "[FLEX]";
197                         break;
198                 case EXTEND_OS9:
199                         p = "[OS-9]";
200                         break;
201                 case EXTEND_OS68K:
202                         p = "[OS-9/68K]";
203                         break;
204                 case EXTEND_MSDOS:
205                         p = "[MS-DOS]";
206                         break;
207                 case EXTEND_MACOS:
208                         p = "[Mac OS]";
209                         break;
210                 case EXTEND_OS2:
211                         p = "[OS/2]";
212                         break;
213                 case EXTEND_HUMAN:
214                         p = "[Human68K]";
215                         break;
216                 case EXTEND_OS386:
217                         p = "[OS-386]";
218                         break;
219                 case EXTEND_RUNSER:
220                         p = "[Runser]";
221                         break;
222 #ifdef EXTEND_TOWNSOS
223                         /* This ID isn't fixed */
224                 case EXTEND_TOWNSOS:
225                         p = "[TownsOS]";
226                         break;
227 #endif
228                         /* Ouch!  Please customize it's ID.  */
229                 default:
230                         p = "[unknown]";
231                         break;
232                 }
233                 printf("%-23.23s", p);
234                 break;
235         }
236
237         print_size(hdr->packed_size, hdr->original_size);
238
239         if (verbose_listing)
240                 if (hdr->has_crc)
241                         printf(" %s %04x", method, hdr->crc);
242                 else
243                         printf(" %s ****", method);
244
245         printf(" ");
246         print_stamp(hdr->unix_last_modified_stamp);
247
248         if (!verbose)
249                 if ((mode & UNIX_FILE_SYMLINK) != UNIX_FILE_SYMLINK)
250                         printf(" %s", hdr->name);
251                 else {
252                         char            buf[256], *b1, *b2;
253                         strcpy(buf, hdr->name);
254                         b1 = strtok(buf, "|");
255                         b2 = strtok(NULL, "|");
256                         printf(" %s -> %s", b1, b2);
257                 }
258
259         if (verbose)
260                 printf(" [%d]", hdr->header_level);
261         printf("\n");
262
263 }
264
265 /* ------------------------------------------------------------------------ */
266 static void
267 list_tailer()
268 {
269         struct stat     stbuf;
270
271         print_bar();
272
273         printf(" Total %9d file%c ",
274                list_files, (list_files == 1) ? ' ' : 's');
275         print_size(packed_size_total, original_size_total);
276         printf(" ");
277
278         if (verbose_listing)
279                 printf("           ");
280
281         if (stat(archive_name, &stbuf) < 0)
282                 print_stamp((time_t) 0);
283         else
284                 print_stamp(stbuf.st_mtime);
285
286         printf("\n");
287 }
288
289 /* ------------------------------------------------------------------------ */
290 /* LIST COMMAND MAIN                                                                                                            */
291 /* ------------------------------------------------------------------------ */
292 void
293 cmd_list()
294 {
295         FILE           *afp;
296         LzHeader        hdr;
297         int             i;
298
299         /* initialize total count */
300         packed_size_total = 0L;
301         original_size_total = 0L;
302         list_files = 0;
303
304         /* open archive file */
305         if ((afp = open_old_archive()) == NULL) {
306                 error(archive_name, "");
307                 exit(1);
308         }
309         if (archive_is_msdos_sfx1(archive_name))
310                 skip_msdos_sfx1_code(afp);
311
312         /* print header message */
313         if (!quiet)
314                 list_header();
315
316         /* print each file information */
317         while (get_header(afp, &hdr)) {
318                 if (need_file(hdr.name)) {
319                         list_one(&hdr);
320                         list_files++;
321                         packed_size_total += hdr.packed_size;
322                         original_size_total += hdr.original_size;
323                 }
324
325                 if (afp != stdin)
326                         fseek(afp, hdr.packed_size, SEEK_CUR);
327                 else {
328                         i = hdr.packed_size;
329                         while (i--)
330                                 fgetc(afp);
331                 }
332         }
333
334         /* close archive file */
335         fclose(afp);
336
337         /* print tailer message */
338         if (!quiet)
339                 list_tailer();
340
341         return;
342 }
343
344 /* Local Variables: */
345 /* mode:c */
346 /* tab-width:4 */
347 /* compile-command:"gcc -c lhlist.c" */
348 /* End: */
349 /* vi: set tabstop=4: */