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
print_size(packed_size,original_size)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
print_stamp(t)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
print_bar()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
list_header()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
list_one(hdr)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
list_tailer(list_files,packed_size_total,original_size_total)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
cmd_list()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 }
358