"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "lha-114i/src/header.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 /* header.c -- header manipulate functions */
4 /* */
5 /* Modified Nobutaka Watazaki */
6 /* */
7 /* Original Y.Tagawa */
8 /* modified 1991.12.16 M.Oki */
9 /* Ver. 1.10 Symbolic Link added 1993.10.01 N.Watazaki */
10 /* Ver. 1.13b Symbolic Link Bug Fix 1994.08.22 N.Watazaki */
11 /* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
12 /* Ver. 1.14i bug fixed 2000.10.06 t.okamoto */
13 /* ------------------------------------------------------------------------ */
14 #include "lha.h"
15
16 /* ------------------------------------------------------------------------ */
17 static char *get_ptr;
18 /* ------------------------------------------------------------------------ */
19 int
20 calc_sum(p, len)
21 register char *p;
22 register int len;
23 {
24 register int sum;
25
26 for (sum = 0; len; len--)
27 sum += *p++;
28
29 return sum & 0xff;
30 }
31
32 /* ------------------------------------------------------------------------ */
33 static unsigned short
34 get_word()
35 {
36 int b0, b1;
37
38 b0 = get_byte();
39 b1 = get_byte();
40 return (b1 << 8) + b0;
41 }
42
43 /* ------------------------------------------------------------------------ */
44 static void
45 put_word(v)
46 unsigned int v;
47 {
48 put_byte(v);
49 put_byte(v >> 8);
50 }
51
52 /* ------------------------------------------------------------------------ */
53 static long
54 get_longword()
55 {
56 long b0, b1, b2, b3;
57
58 b0 = get_byte();
59 b1 = get_byte();
60 b2 = get_byte();
61 b3 = get_byte();
62 return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
63 }
64
65 /* ------------------------------------------------------------------------ */
66 static void
67 put_longword(v)
68 long v;
69 {
70 put_byte(v);
71 put_byte(v >> 8);
72 put_byte(v >> 16);
73 put_byte(v >> 24);
74 }
75
76 /* ------------------------------------------------------------------------ */
77 static void
78 msdos_to_unix_filename(name, len)
79 register char *name;
80 register int len;
81 {
82 register int i;
83
84 #ifdef MULTIBYTE_CHAR
85 for (i = 0; i < len; i++) {
86 if (MULTIBYTE_FIRST_P(name[i]) &&
87 MULTIBYTE_SECOND_P(name[i + 1]))
88 i++;
89 else if (name[i] == '\\')
90 name[i] = '/';
91 else if (!noconvertcase && isupper(name[i]))
92 name[i] = tolower(name[i]);
93 }
94 #else
95 for (i = 0; i < len; i++) {
96 if (name[i] == '\\')
97 name[i] = '/';
98 else if (!noconvertcase && isupper(name[i]))
99 name[i] = tolower(name[i]);
100 }
101 #endif
102 }
103
104 /* ------------------------------------------------------------------------ */
105 static void
106 generic_to_unix_filename(name, len)
107 register char *name;
108 register int len;
109 {
110 register int i;
111 boolean lower_case_used = FALSE;
112
113 #ifdef MULTIBYTE_CHAR
114 for (i = 0; i < len; i++) {
115 if (MULTIBYTE_FIRST_P(name[i]) &&
116 MULTIBYTE_SECOND_P(name[i + 1]))
117 i++;
118 else if (islower(name[i])) {
119 lower_case_used = TRUE;
120 break;
121 }
122 }
123 for (i = 0; i < len; i++) {
124 if (MULTIBYTE_FIRST_P(name[i]) &&
125 MULTIBYTE_SECOND_P(name[i + 1]))
126 i++;
127 else if (name[i] == '\\')
128 name[i] = '/';
129 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
130 name[i] = tolower(name[i]);
131 }
132 #else
133 for (i = 0; i < len; i++)
134 if (islower(name[i])) {
135 lower_case_used = TRUE;
136 break;
137 }
138 for (i = 0; i < len; i++) {
139 if (name[i] == '\\')
140 name[i] = '/';
141 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
142 name[i] = tolower(name[i]);
143 }
144 #endif
145 }
146
147 /* ------------------------------------------------------------------------ */
148 static void
149 macos_to_unix_filename(name, len)
150 register char *name;
151 register int len;
152 {
153 register int i;
154
155 for (i = 0; i < len; i++) {
156 if (name[i] == ':')
157 name[i] = '/';
158 else if (name[i] == '/')
159 name[i] = ':';
160 }
161 }
162
163 /* ------------------------------------------------------------------------ */
164 static void
165 unix_to_generic_filename(name, len)
166 register char *name;
167 register int len;
168 {
169 register int i;
170
171 for (i = 0; i < len; i++) {
172 if (name[i] == '/')
173 name[i] = '\\';
174 else if (islower(name[i]))
175 name[i] = toupper(name[i]);
176 }
177 }
178
179 /* ------------------------------------------------------------------------ */
180 /* */
181 /* Generic stamp format: */
182 /* */
183 /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
184 /* |<-------- year ------->|<- month ->|<-- day -->| */
185 /* */
186 /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
187 /* |<--- hour --->|<---- minute --->|<- second*2 ->| */
188 /* */
189 /* ------------------------------------------------------------------------ */
190
191 /*
192 * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
193 * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
194 */
195
196 /* choose one */
197 #if defined(MKTIME)
198 #ifdef TIMELOCAL
199 #undef TIMELOCAL
200 #endif
201 #endif /* defined(MKTIME) */
202
203 #if defined(MKTIME) || defined(TIMELOCAL)
204 #ifdef TZSET
205 #undef TZSET
206 #endif
207 #endif /* defined(MKTIME) || defined(TIMELOCAL) */
208
209 #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET)
210 #ifdef FTIME
211 #undef FTIME
212 #endif
213 #endif
214
215 #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) || defined(FTIME)
216 #ifdef GETTIMEOFDAY
217 #undef GETTIMEOFDAY
218 #endif
219 #else
220 #ifndef GETTIMEOFDAY
221 #define GETTIMEOFDAY /* use gettimeofday() */
222 #endif
223 #endif
224
225 #ifdef FTIME
226 #include <sys/timeb.h>
227 #endif
228
229 /*
230 * You may define as : #define TIMEZONE_HOOK \ extern long
231 * timezone ; \ extern void tzset();
232 */
233 #ifdef TIMEZONE_HOOK
234 TIMEZONE_HOOK
235 /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
236 #endif
237
238 #if defined(TZSET) && defined(_MINIX)
239 extern long timezone; /* not defined in time.h */
240 #endif
241
242 /* ------------------------------------------------------------------------ */
243 #if defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET)
244 static long
245 gettz()
246 #ifdef TZSET
247 {
248 tzset();
249 return timezone;
250 }
251 #endif
252
253 /* ------------------------------------------------------------------------ */
254 #if !defined(TZSET) && defined(FTIME)
255 {
256 struct timeb buf;
257
258 ftime(&buf);
259 return buf.timezone * 60L;
260 }
261 #endif
262
263 /* ------------------------------------------------------------------------ */
264 #if !defined(TZSET) && !defined(FTIME) /* maybe defined(GETTIMEOFDAY) */
265 {
266 #ifdef HAVE_TM_ZONE
267 time_t tt;
268
269 time(&tt);
270 return -localtime(&tt)->tm_gmtoff;
271 #else /* HAVE_TM_ZONE */
272 struct timeval tp;
273 struct timezone tzp;
274 gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
275 /*
276 * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
277 * 60L : 0));
278 */
279 return (tzp.tz_minuteswest * 60L);
280 #endif /* HAVE_TM_ZONE */
281 }
282 #endif
283 #endif /* defined(FTIME) || defined(GETTIMEOFDAY) ||
284 * defined(TZSET) */
285
286 /* ------------------------------------------------------------------------ */
287 #ifdef NOT_USED
288 static struct tm *
289 msdos_to_unix_stamp_tm(a)
290 long a;
291 {
292 static struct tm t;
293
294 t.tm_sec = (a & 0x1f) * 2;
295 t.tm_min = (a >> 5) & 0x3f;
296 t.tm_hour = (a >> 11) & 0x1f;
297 t.tm_mday = (a >> 16) & 0x1f;
298 t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
299 t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
300 return &t;
301 }
302 #endif
303
304 /* ------------------------------------------------------------------------ */
305 static time_t
306 generic_to_unix_stamp(t)
307 long t;
308 #if defined(MKTIME) || defined(TIMELOCAL)
309 {
310 struct tm dostm;
311
312 /*
313 * special case: if MSDOS format date and time were zero, then we
314 * set time to be zero here too.
315 */
316 if (t == 0)
317 return (time_t) 0;
318
319 dostm.tm_sec = (t & 0x1f) * 2;
320 dostm.tm_min = t >> 5 & 0x3f;
321 dostm.tm_hour = t >> 11 & 0x1f;
322 dostm.tm_mday = t >> 16 & 0x1f;
323 dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1; /* 0..11 */
324 dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
325 #if 0
326 dostm.tm_isdst = 0; /* correct? */
327 #endif
328 dostm.tm_isdst = -1; /* correct? */
329 #ifdef MKTIME
330 return (time_t) mktime(&dostm);
331 #else /* maybe defined(TIMELOCAL) */
332 return (time_t) timelocal(&dostm);
333 #endif
334 }
335
336 #else /* defined(MKTIME) || defined(TIMELOCAL) */
337 {
338 int year, month, day, hour, min, sec;
339 long longtime;
340 static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
341 181, 212, 243, 273, 304, 334};
342 unsigned int days;
343
344 /*
345 * special case: if MSDOS format date and time were zero, then we
346 * set time to be zero here too.
347 */
348 if (t == 0)
349 return (time_t) 0;
350
351 year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
352 month = (int) (t >> 16 + 5) & 0x0f; /* 1..12 means Jan..Dec */
353 day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
354
355 hour = ((int) t >> 11) & 0x1f;
356 min = ((int) t >> 5) & 0x3f;
357 sec = ((int) t & 0x1f) * 2;
358
359 /* Calculate days since 1970.01.01 */
360 days = (365 * (year - 1970) + /* days due to whole years */
361 (year - 1970 + 1) / 4 + /* days due to leap years */
362 dsboy[month - 1] + /* days since beginning of this year */
363 day - 1); /* days since beginning of month */
364
365 if ((year % 4 == 0) &&
366 (year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
367 (month >= 3)) /* if this is a leap year and month */
368 days++; /* is March or later, add a day */
369
370 /* Knowing the days, we can find seconds */
371 longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
372 longtime += gettz(); /* adjust for timezone */
373
374 /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
375 return (time_t) longtime;
376 }
377 #endif /* defined(MKTIME) || defined(TIMELOCAL) */
378
379 /* ------------------------------------------------------------------------ */
380 static long
381 unix_to_generic_stamp(t)
382 time_t t;
383 {
384 struct tm *tm = localtime(&t);
385
386 return ((((long) (tm->tm_year - 80)) << 25) +
387 (((long) (tm->tm_mon + 1)) << 21) +
388 (((long) tm->tm_mday) << 16) +
389 (long) ((tm->tm_hour << 11) +
390 (tm->tm_min << 5) +
391 (tm->tm_sec / 2)));
392 }
393
394 /* ------------------------------------------------------------------------ */
395 /* build header functions */
396 /* ------------------------------------------------------------------------ */
397 boolean
398 get_header(fp, hdr)
399 FILE *fp;
400 register LzHeader *hdr;
401 {
402 int header_size;
403 int name_length;
404 char data[LZHEADER_STRAGE];
405 char dirname[FILENAME_LENGTH];
406 int dir_length = 0;
407 int checksum;
408 int i;
409 char *ptr;
410 int extend_size;
411 int dmy;
412
413 bzero(hdr, sizeof(LzHeader));
414
415 if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
416 return FALSE; /* finish */
417 }
418
419 if (fread(data + I_HEADER_CHECKSUM,
420 sizeof(char), header_size - 1, fp) < header_size - 1) {
421 fatal_error("Invalid header (LHarc file ?)");
422 return FALSE; /* finish */
423 }
424 setup_get(data + I_HEADER_LEVEL);
425 hdr->header_level = get_byte();
426 if (hdr->header_level != 2 &&
427 fread(data + header_size, sizeof(char), 2, fp) < 2) {
428 fatal_error("Invalid header (LHarc file ?)");
429 return FALSE; /* finish */
430 }
431
432 if (hdr->header_level >= 3) {
433 fatal_error("Unknown level header");
434 return FALSE;
435 }
436
437 setup_get(data + I_HEADER_CHECKSUM);
438 checksum = get_byte();
439
440 if (hdr->header_level == 2) {
441 hdr->header_size = header_size + checksum*256;
442 } else {
443 hdr->header_size = header_size;
444 }
445 bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
446 setup_get(data + I_PACKED_SIZE);
447 hdr->packed_size = get_longword();
448 hdr->original_size = get_longword();
449 hdr->last_modified_stamp = get_longword();
450 hdr->attribute = get_byte();
451
452 if ((hdr->header_level = get_byte()) != 2) {
453 if (calc_sum(data + I_METHOD, header_size) != checksum)
454 warning("Checksum error (LHarc file?)", "");
455 name_length = get_byte();
456 for (i = 0; i < name_length; i++)
457 hdr->name[i] = (char) get_byte();
458 hdr->name[name_length] = '\0';
459 }
460 else {
461 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
462 name_length = 0;
463 }
464
465 /* defaults for other type */
466 hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
467 hdr->unix_gid = 0;
468 hdr->unix_uid = 0;
469
470 if (hdr->header_level == 0) {
471 extend_size = header_size - name_length -22;
472 if (extend_size < 0) {
473 if (extend_size == -2) {
474 hdr->extend_type = EXTEND_GENERIC;
475 hdr->has_crc = FALSE;
476 } else {
477 fatal_error("Unkonwn header (lha file?)");
478 return FALSE;
479 }
480 } else {
481 hdr->has_crc = TRUE;
482 hdr->crc = get_word();
483 }
484
485 if (extend_size >= 1) {
486 hdr->extend_type = get_byte();
487 extend_size--;
488 }
489 if (hdr->extend_type == EXTEND_UNIX) {
490 if (extend_size >= 11) {
491 hdr->minor_version = get_byte();
492 hdr->unix_last_modified_stamp = (time_t) get_longword();
493 hdr->unix_mode = get_word();
494 hdr->unix_uid = get_word();
495 hdr->unix_gid = get_word();
496 extend_size -= 11;
497 } else {
498 hdr->extend_type = EXTEND_GENERIC;
499 }
500 }
501 while (extend_size-- > 0)
502 dmy = get_byte();
503 if (hdr->extend_type == EXTEND_UNIX)
504 return TRUE;
505 } else if (hdr->header_level == 1) {
506 hdr->has_crc = TRUE;
507 extend_size = header_size - name_length-25;
508 hdr->crc = get_word();
509 hdr->extend_type = get_byte();
510 while (extend_size-- > 0)
511 dmy = get_byte();
512 } else { /* level 2 */
513 hdr->has_crc = TRUE;
514 hdr->crc = get_word();
515 hdr->extend_type = get_byte();
516 }
517
518 if (hdr->header_level > 0) {
519 /* Extend Header */
520 if (hdr->header_level != 2)
521 setup_get(data + hdr->header_size);
522 ptr = get_ptr;
523 while ((header_size = get_word()) != 0) {
524 if (hdr->header_level != 2 &&
525 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
526 fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
527 fatal_error("Invalid header (LHa file ?)");
528 return FALSE;
529 }
530 switch (get_byte()) {
531 case 0:
532 /*
533 * header crc
534 */
535 setup_get(get_ptr + header_size - 3);
536 break;
537 case 1:
538 /*
539 * filename
540 */
541 for (i = 0; i < header_size - 3; i++)
542 hdr->name[i] = (char) get_byte();
543 hdr->name[header_size - 3] = '\0';
544 name_length = header_size - 3;
545 break;
546 case 2:
547 /*
548 * directory
549 */
550 for (i = 0; i < header_size - 3; i++)
551 dirname[i] = (char) get_byte();
552 dirname[header_size - 3] = '\0';
553 convdelim(dirname, DELIM);
554 dir_length = header_size - 3;
555 break;
556 case 0x40:
557 /*
558 * MS-DOS attribute
559 */
560 if (hdr->extend_type == EXTEND_MSDOS ||
561 hdr->extend_type == EXTEND_HUMAN ||
562 hdr->extend_type == EXTEND_GENERIC)
563 hdr->attribute = get_word();
564 break;
565 case 0x50:
566 /*
567 * UNIX permission
568 */
569 if (hdr->extend_type == EXTEND_UNIX)
570 hdr->unix_mode = get_word();
571 break;
572 case 0x51:
573 /*
574 * UNIX gid and uid
575 */
576 if (hdr->extend_type == EXTEND_UNIX) {
577 hdr->unix_gid = get_word();
578 hdr->unix_uid = get_word();
579 }
580 break;
581 case 0x52:
582 /*
583 * UNIX group name
584 */
585 setup_get(get_ptr + header_size - 3);
586 break;
587 case 0x53:
588 /*
589 * UNIX user name
590 */
591 setup_get(get_ptr + header_size - 3);
592 break;
593 case 0x54:
594 /*
595 * UNIX last modified time
596 */
597 if (hdr->extend_type == EXTEND_UNIX)
598 hdr->unix_last_modified_stamp = (time_t) get_longword();
599 break;
600 default:
601 /*
602 * other headers
603 */
604 setup_get(get_ptr + header_size - 3);
605 break;
606 }
607 }
608 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
609 hdr->packed_size -= get_ptr - ptr - 2;
610 hdr->header_size += get_ptr - ptr - 2;
611 }
612 }
613
614 switch (hdr->extend_type) {
615 case EXTEND_MSDOS:
616 msdos_to_unix_filename(hdr->name, name_length);
617 msdos_to_unix_filename(dirname, dir_length);
618 case EXTEND_HUMAN:
619 if (hdr->header_level == 2)
620 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
621 else
622 hdr->unix_last_modified_stamp =
623 generic_to_unix_stamp(hdr->last_modified_stamp);
624 break;
625
626 #ifdef OSK
627 case EXTEND_OS68K:
628 case EXTEND_XOSK:
629 #endif
630 case EXTEND_UNIX:
631 break;
632
633 case EXTEND_MACOS:
634 macos_to_unix_filename(hdr->name, name_length);
635 /* macos_to_unix_filename(dirname, dir_length); */
636 hdr->unix_last_modified_stamp =
637 generic_to_unix_stamp(hdr->last_modified_stamp);
638 break;
639
640 default:
641 generic_to_unix_filename(hdr->name, name_length);
642 generic_to_unix_filename(dirname, dir_length);
643 if (hdr->header_level == 2)
644 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
645 else
646 hdr->unix_last_modified_stamp =
647 generic_to_unix_stamp(hdr->last_modified_stamp);
648 }
649
650 if (dir_length) {
651 strcat(dirname, hdr->name);
652 strcpy(hdr->name, dirname);
653 name_length += dir_length;
654 }
655
656 return TRUE;
657 }
658
659 /* ------------------------------------------------------------------------ */
660 void
661 init_header(name, v_stat, hdr)
662 char *name;
663 struct stat *v_stat;
664 LzHeader *hdr;
665 {
666 int len;
667
668 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
669 bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
670 else if (compress_method)
671 bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
672 else
673 bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
674
675 hdr->packed_size = 0;
676 hdr->original_size = v_stat->st_size;
677 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
678 hdr->attribute = GENERIC_ATTRIBUTE;
679 hdr->header_level = header_level;
680 strcpy(hdr->name, name);
681 len = strlen(name);
682 hdr->crc = 0x0000;
683 hdr->extend_type = EXTEND_UNIX;
684 hdr->unix_last_modified_stamp = v_stat->st_mtime;
685 /* since 00:00:00 JAN.1.1970 */
686 #ifdef NOT_COMPATIBLE_MODE
687 /* Please need your modification in this space. */
688 #else
689 hdr->unix_mode = v_stat->st_mode;
690 #endif
691
692 hdr->unix_uid = v_stat->st_uid;
693 hdr->unix_gid = v_stat->st_gid;
694
695 if (is_directory(v_stat)) {
696 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
697 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
698 hdr->original_size = 0;
699 if (len > 0 && hdr->name[len - 1] != '/')
700 strcpy(&hdr->name[len++], "/");
701 }
702
703 #ifdef S_IFLNK
704 if (is_symlink(v_stat)) {
705 char lkname[257];
706 int len;
707 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
708 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
709 hdr->original_size = 0;
710 len = readlink(name, lkname, 256);
711 lkname[len] = (char)'\0';
712 sprintf(hdr->name, "%s|%s", hdr->name, lkname);
713 }
714 #endif
715 if (generic_format)
716 unix_to_generic_filename(hdr->name, len);
717 }
718
719 /* ------------------------------------------------------------------------ */
720 /* Write unix extended header or generic header. */
721 void
722 write_header(nafp, hdr)
723 FILE *nafp;
724 LzHeader *hdr;
725 {
726 int header_size;
727 int name_length;
728 char data[LZHEADER_STRAGE];
729 char *p;
730 char *headercrc_ptr;
731
732 bzero(data, LZHEADER_STRAGE);
733 bcopy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
734 setup_put(data + I_PACKED_SIZE);
735 put_longword(hdr->packed_size);
736 put_longword(hdr->original_size);
737
738 if (hdr->header_level == HEADER_LEVEL2)
739 put_longword((long) hdr->unix_last_modified_stamp);
740 else
741 put_longword(hdr->last_modified_stamp);
742
743 switch (hdr->header_level) {
744 case HEADER_LEVEL0:
745 put_byte(hdr->attribute);
746 break;
747 case HEADER_LEVEL1:
748 case HEADER_LEVEL2:
749 put_byte(0x20);
750 break;
751 }
752
753 put_byte(hdr->header_level);
754
755 convdelim(hdr->name, DELIM2);
756 if (hdr->header_level != HEADER_LEVEL2) {
757 if (p = (char *) rindex(hdr->name, DELIM2))
758 name_length = strlen(++p);
759 else
760 name_length = strlen(hdr->name);
761 put_byte(name_length);
762 bcopy(p ? p : hdr->name, data + I_NAME, name_length);
763 setup_put(data + I_NAME + name_length);
764 }
765
766 put_word(hdr->crc);
767 if (header_level == HEADER_LEVEL0) {
768 if (generic_format) {
769 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
770 data[I_HEADER_SIZE] = header_size;
771 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
772 } else {
773 /* write old-style extend header */
774 put_byte(EXTEND_UNIX);
775 put_byte(CURRENT_UNIX_MINOR_VERSION);
776 put_longword((long) hdr->unix_last_modified_stamp);
777 put_word(hdr->unix_mode);
778 put_word(hdr->unix_uid);
779 put_word(hdr->unix_gid);
780 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
781 data[I_HEADER_SIZE] = header_size;
782 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
783 }
784 } else {
785 /* write extend header. */
786 char *ptr;
787
788 if (generic_format)
789 put_byte(0x00);
790 else
791 put_byte(EXTEND_UNIX);
792
793 ptr = put_ptr;
794 if (hdr->header_level == HEADER_LEVEL2) {
795 /* write common header */
796 put_word(5);
797 put_byte(0x00);
798 headercrc_ptr = put_ptr;
799 put_word(0x0000);
800 }
801
802 if (generic_format) {
803 header_size = put_ptr - data; /* +2 for last 0x0000 */
804 } else {
805 put_word(5);
806 if (hdr->header_level == HEADER_LEVEL1)
807 header_size = put_ptr - data - 2;
808 put_byte(0x50); /* permission */
809 put_word(hdr->unix_mode);
810 put_word(7);
811 put_byte(0x51); /* gid and uid */
812 put_word(hdr->unix_gid);
813 put_word(hdr->unix_uid);
814
815 if (p = (char *) rindex(hdr->name, DELIM2)) {
816 int i;
817
818 name_length = p - hdr->name + 1;
819 put_word(name_length + 3);
820 put_byte(2); /* dirname */
821 for (i = 0; i < name_length; i++)
822 put_byte(hdr->name[i]);
823 }
824 } /* if generic .. */
825
826 if (header_level != HEADER_LEVEL2) {
827 if (!generic_format) {
828 put_word(7);
829 put_byte(0x54); /* time stamp */
830 put_longword(hdr->unix_last_modified_stamp);
831 }
832 hdr->packed_size += put_ptr - ptr;
833 ptr = put_ptr;
834 setup_put(data + I_PACKED_SIZE);
835 put_longword(hdr->packed_size);
836 put_ptr = ptr;
837 data[I_HEADER_SIZE] = header_size;
838 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
839 } else { /* header level 2 */
840 int i;
841 if (p = (char *) rindex(hdr->name, DELIM2))
842 name_length = strlen(++p);
843 else {
844 p = hdr->name;
845 name_length = strlen(hdr->name);
846 }
847 put_word(name_length + 3);
848 put_byte(1); /* filename */
849 for (i = 0; i < name_length; i++)
850 put_byte(*p++);
851 } /* if he.. != HEAD_LV2 */
852 header_size = put_ptr - data;
853 }
854
855 if (header_level == HEADER_LEVEL2) {
856 unsigned short hcrc;
857 setup_put(data + I_HEADER_SIZE);
858 put_word(header_size + 2);
859 /* common header */
860 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
861 setup_put(headercrc_ptr);
862 put_word(hcrc);
863 }
864
865 if (fwrite(data, sizeof(char), header_size + 2, nafp) == 0)
866 fatal_error("Cannot write to temporary file");
867
868 convdelim(hdr->name, DELIM);
869 }
870
871 /* Local Variables: */
872 /* mode:c */
873 /* tab-width:4 */
874 /* compile-command:"gcc -c header.c" */
875 /* End: */