1 /* ------------------------------------------------------------------------ */
3 /* header.c -- header manipulate functions */
5 /* Modified Nobutaka Watazaki */
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.14e bug fixed 1999.05.27 T.Okamoto */
13 /* ------------------------------------------------------------------------ */
16 void euc2sjis(int *p1, int *p2);
17 void sjis2euc(int *p1, int *p2);
19 /* ------------------------------------------------------------------------ */
22 int specific_archive_kanji_code = NONE;
23 int specific_system_kanji_code = NONE;
24 char *specific_archive_delim = NULL;
25 char *specific_system_delim = NULL;
26 int specific_filename_case = NONE;
28 int default_system_kanji_code = CODE_EUC;
29 /* ------------------------------------------------------------------------ */
37 for (sum = 0; len; len--)
43 /* ------------------------------------------------------------------------ */
51 return (b1 << 8) + b0;
54 /* ------------------------------------------------------------------------ */
63 /* ------------------------------------------------------------------------ */
73 return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
76 /* ------------------------------------------------------------------------ */
87 /* ------------------------------------------------------------------------ */
89 msdos_to_unix_filename(name, len)
97 for (i = 0; i < len; i++) {
98 /* modified by Koji Arai */
99 if (X0201_KANA_P(name[i])) {
101 for (j = len; j >= i; j--) {
102 name[j+1] = name[j]; /* no check over */
108 if (MULTIBYTE_FIRST_P(name[i]) &&
109 MULTIBYTE_SECOND_P(name[i + 1])) {
111 c1 = name[i]; c2 = name[i+1];
113 name[i] = c1; name[i+1] = c2;
116 else if (name[i] == '\\')
118 else if (isupper(name[i]))
119 name[i] = tolower(name[i]);
122 for (i = 0; i < len; i++) {
123 if (MULTIBYTE_FIRST_P(name[i]) &&
124 MULTIBYTE_SECOND_P(name[i + 1]))
126 else if (name[i] == '\\')
128 else if (isupper(name[i]))
129 name[i] = tolower(name[i]);
131 #endif /* SUPPORT_X0201 */
133 for (i = 0; i < len; i++) {
136 else if (isupper(name[i]))
137 name[i] = tolower(name[i]);
142 /* ------------------------------------------------------------------------ */
144 generic_to_unix_filename(name, len)
149 boolean lower_case_used = FALSE;
151 #ifdef MULTIBYTE_CHAR
153 for (i = 0; i < len; i++) {
154 /* modified by Koji Arai */
155 if (X0201_KANA_P(name[i])) {
157 for (j = len; j >= i; j--) {
158 name[j+1] = name[j]; /* no check over */
165 if (MULTIBYTE_FIRST_P(name[i]) &&
166 MULTIBYTE_SECOND_P(name[i + 1]))
168 else if (islower(name[i])) {
169 lower_case_used = TRUE;
174 for (i = 0; i < len; i++) {
175 if (MULTIBYTE_FIRST_P(name[i]) &&
176 MULTIBYTE_SECOND_P(name[i + 1]))
178 else if (islower(name[i])) {
179 lower_case_used = TRUE;
183 #endif /* SUPPORT_X0201 */
184 for (i = 0; i < len; i++) {
185 if (MULTIBYTE_FIRST_P(name[i]) &&
186 MULTIBYTE_SECOND_P(name[i + 1]))
188 else if (name[i] == '\\')
190 else if (!lower_case_used && isupper(name[i]))
191 name[i] = tolower(name[i]);
194 for (i = 0; i < len; i++)
195 if (islower(name[i])) {
196 lower_case_used = TRUE;
199 for (i = 0; i < len; i++) {
202 else if (!lower_case_used && isupper(name[i]))
203 name[i] = tolower(name[i]);
208 /* ------------------------------------------------------------------------ */
210 macos_to_unix_filename(name, len)
216 /* modified by Koji Arai */
218 for (i = 0; i < len; i ++) {
219 /* modified by Koji Arai */
220 if (X0201_KANA_P(name[i])) {
222 for (j = len; j >= i; j--) {
223 name[j+1] = name[j]; /* no check over */
230 if (MULTIBYTE_FIRST_P (name[i]) &&
231 MULTIBYTE_SECOND_P (name[i+1])) {
233 c1 = name[i]; c2 = name[i+1];
235 name[i] = c1; name[i+1] = c2;
238 else if (name[i] == ':')
240 else if (name[i] == '/')
243 else if (isupper (name[i]))
244 name[i] = tolower (name[i]);
248 for (i = 0; i < len; i++) {
251 else if (name[i] == '/')
254 #endif /* SUPPORT_X0201 */
257 /* ------------------------------------------------------------------------ */
259 unix_to_generic_filename(name, len)
265 for (i = 0; i < len; i++) {
268 else if (islower(name[i]))
269 name[i] = toupper(name[i]);
273 /* added by Koji Arai */
275 filename_conv(name, len, size,
277 from_delim, to_delim,
282 int from_code, to_code, case_to;
283 char *from_delim, *to_delim;
288 for (i = 0; i < len; i ++) {
289 if (from_code == CODE_EUC &&
290 (unsigned char)name[i] == 0x8e) {
291 if (to_code != CODE_SJIS) {
297 memmove(name + i, name + i + 1, len - i);
301 if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
302 if (to_code != CODE_EUC) {
306 if (len == size - 1) /* check overflow */
308 memmove(name + i + 1, name, len - i);
314 if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
316 if (to_code != CODE_SJIS) {
321 c1 = (unsigned char)name[i];
322 c2 = (unsigned char)name[i+1];
329 if (from_code == CODE_SJIS &&
330 SJC_FIRST_P(name[i]) &&
331 SJC_SECOND_P(name[i + 1])) {
334 if (to_code != CODE_EUC) {
339 c1 = (unsigned char)name[i];
340 c2 = (unsigned char)name[i+1];
342 name[i] = c1; name[i+1] = c2;
350 /* transpose from_delim to to_delim */
352 if ((ptr = strchr(from_delim, name[i])) != NULL) {
353 name[i] = to_delim[ptr - from_delim];
358 if (case_to == TO_UPPER && islower(name[i])) {
359 name[i] = toupper(name[i]);
362 if (case_to == TO_LOWER && islower(name[i])) {
363 name[i] = toupper(name[i]);
369 /* ------------------------------------------------------------------------ */
371 /* Generic stamp format: */
373 /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
374 /* |<-------- year ------->|<- month ->|<-- day -->| */
376 /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
377 /* |<--- hour --->|<---- minute --->|<- second*2 ->| */
379 /* ------------------------------------------------------------------------ */
382 * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
383 * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
387 #if defined(HAVE_MKTIME)
388 #ifdef HAVE_TIMELOCAL
389 #undef HAVE_TIMELOCAL
391 #endif /* defined(HAVE_MKTIME) */
393 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
397 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
399 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET)
405 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET) || defined(HAVE_FTIME)
406 #ifdef HAVE_GETTIMEOFDAY
407 #undef HAVE_GETTIMEOFDAY
410 #ifndef HAVE_GETTIMEOFDAY
411 #define HAVE_GETTIMEOFDAY /* use gettimeofday() */
416 #include <sys/timeb.h>
420 * You may define as : #define TIMEZONE_HOOK \ extern long
421 * timezone ; \ extern void tzset();
425 /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
428 #if defined(HAVE_TZSET) && defined(_MINIX)
429 extern long timezone; /* not defined in time.h */
432 /* ------------------------------------------------------------------------ */
433 #if defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) || defined(HAVE_TZSET)
443 /* ------------------------------------------------------------------------ */
444 #if !defined(HAVE_TZSET) && defined(HAVE_FTIME)
449 return buf.timezone * 60L;
453 /* ------------------------------------------------------------------------ */
454 #if !defined(HAVE_TZSET) && !defined(HAVE_FTIME) /* maybe defined(HAVE_GETTIMEOFDAY) */
456 #ifdef HAVE_TM_GMTOFF
460 return -localtime(&tt)->tm_gmtoff;
461 #else /* HAVE_TM_GMTOFF */
464 gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
466 * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
469 return (tzp.tz_minuteswest * 60L);
470 #endif /* HAVE_TM_GMTOFF */
473 #endif /* defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) ||
474 * defined(HAVE_TZSET) */
476 /* ------------------------------------------------------------------------ */
479 msdos_to_unix_stamp_tm(a)
484 t.tm_sec = (a & 0x1f) * 2;
485 t.tm_min = (a >> 5) & 0x3f;
486 t.tm_hour = (a >> 11) & 0x1f;
487 t.tm_mday = (a >> 16) & 0x1f;
488 t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
489 t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
494 /* ------------------------------------------------------------------------ */
496 generic_to_unix_stamp(t)
498 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
503 * special case: if MSDOS format date and time were zero, then we
504 * set time to be zero here too.
509 dostm.tm_sec = (t & 0x1f) * 2;
510 dostm.tm_min = t >> 5 & 0x3f;
511 dostm.tm_hour = t >> 11 & 0x1f;
512 dostm.tm_mday = t >> 16 & 0x1f;
513 dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1; /* 0..11 */
514 dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
516 dostm.tm_isdst = 0; /* correct? */
518 dostm.tm_isdst = -1; /* correct? */
520 return (time_t) mktime(&dostm);
521 #else /* maybe defined(HAVE_TIMELOCAL) */
522 return (time_t) timelocal(&dostm);
526 #else /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
528 int year, month, day, hour, min, sec;
530 static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
531 181, 212, 243, 273, 304, 334};
535 * special case: if MSDOS format date and time were zero, then we
536 * set time to be zero here too.
541 year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
542 month = (int) (t >> 16 + 5) & 0x0f; /* 1..12 means Jan..Dec */
543 day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
545 hour = ((int) t >> 11) & 0x1f;
546 min = ((int) t >> 5) & 0x3f;
547 sec = ((int) t & 0x1f) * 2;
549 /* Calculate days since 1970.01.01 */
550 days = (365 * (year - 1970) + /* days due to whole years */
551 (year - 1970 + 1) / 4 + /* days due to leap years */
552 dsboy[month - 1] + /* days since beginning of this year */
553 day - 1); /* days since beginning of month */
555 if ((year % 4 == 0) &&
556 (year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
557 (month >= 3)) /* if this is a leap year and month */
558 days++; /* is March or later, add a day */
560 /* Knowing the days, we can find seconds */
561 longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
562 longtime += gettz(); /* adjust for timezone */
564 /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
565 return (time_t) longtime;
567 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
569 /* ------------------------------------------------------------------------ */
571 unix_to_generic_stamp(t)
574 struct tm *tm = localtime(&t);
576 return ((((long) (tm->tm_year - 80)) << 25) +
577 (((long) (tm->tm_mon + 1)) << 21) +
578 (((long) tm->tm_mday) << 16) +
579 (long) ((tm->tm_hour << 11) +
584 /* ------------------------------------------------------------------------ */
585 /* build header functions */
586 /* ------------------------------------------------------------------------ */
590 register LzHeader *hdr;
594 char data[LZHEADER_STRAGE];
595 char dirname[FILENAME_LENGTH];
603 int archive_kanji_code = NONE;
604 int system_kanji_code = NONE;
605 char *archive_delim = "";
606 char *system_delim = "";
607 int filename_case = NONE;
609 bzero(hdr, sizeof(LzHeader));
611 if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
612 return FALSE; /* finish */
615 if (fread(data + I_HEADER_CHECKSUM,
616 sizeof(char), header_size - 1, fp) < header_size - 1) {
617 fatal_error("Invalid header (LHarc file ?)");
618 return FALSE; /* finish */
620 setup_get(data + I_HEADER_LEVEL);
621 hdr->header_level = get_byte();
622 if (hdr->header_level != 2 &&
623 fread(data + header_size, sizeof(char), 2, fp) < 2) {
624 fatal_error("Invalid header (LHarc file ?)");
625 return FALSE; /* finish */
628 if (hdr->header_level >= 3) {
629 fatal_error("Unknown level header");
633 setup_get(data + I_HEADER_CHECKSUM);
634 checksum = get_byte();
636 hdr->header_size = header_size;
637 bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
638 setup_get(data + I_PACKED_SIZE);
639 hdr->packed_size = get_longword();
640 hdr->original_size = get_longword();
641 hdr->last_modified_stamp = get_longword();
642 hdr->attribute = get_byte();
644 if ((hdr->header_level = get_byte()) != 2) {
645 if (calc_sum(data + I_METHOD, header_size) != checksum)
646 warning("Checksum error (LHarc file?)", "");
647 name_length = get_byte();
648 for (i = 0; i < name_length; i++)
649 hdr->name[i] = (char) get_byte();
650 hdr->name[name_length] = '\0';
653 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
657 /* defaults for other type */
658 hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
663 if (hdr->header_level == 0) {
664 extend_size = header_size - name_length -22;
665 if (extend_size < 0) {
666 if (extend_size == -2) {
667 hdr->extend_type = EXTEND_GENERIC;
668 hdr->has_crc = FALSE;
670 fatal_error("Unkonwn header (lha file?)");
675 hdr->crc = get_word();
678 if (extend_size >= 1) {
679 hdr->extend_type = get_byte();
682 if (hdr->extend_type == EXTEND_UNIX) {
683 if (extend_size >= 11) {
684 hdr->minor_version = get_byte();
685 hdr->unix_last_modified_stamp = (time_t) get_longword();
686 hdr->unix_mode = get_word();
687 hdr->unix_uid = get_word();
688 hdr->unix_gid = get_word();
691 hdr->extend_type = EXTEND_GENERIC;
694 while (extend_size-- > 0)
696 if (hdr->extend_type == EXTEND_UNIX)
698 } else if (hdr->header_level == 1) {
700 extend_size = header_size - name_length-25;
701 hdr->crc = get_word();
702 hdr->extend_type = get_byte();
703 while (extend_size-- > 0)
705 } else { /* level 2 */
707 hdr->crc = get_word();
708 hdr->extend_type = get_byte();
711 if (hdr->header_level > 0) {
713 if (hdr->header_level != 2)
714 setup_get(data + hdr->header_size);
716 while ((header_size = get_word()) != 0) {
717 if (hdr->header_level != 2 &&
718 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
719 fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
720 fatal_error("Invalid header (LHa file ?)");
723 switch (get_byte()) {
728 setup_get(get_ptr + header_size - 3);
734 for (i = 0; i < header_size - 3; i++)
735 hdr->name[i] = (char) get_byte();
736 hdr->name[header_size - 3] = '\0';
737 name_length = header_size - 3; /* modified by Koji Arai */
743 for (i = 0; i < header_size - 3; i++)
744 dirname[i] = (char) get_byte();
745 dirname[header_size - 3] = '\0';
746 /* convdelim(dirname, DELIM); is it needed ?
747 comment it by Koji Arai*/
748 dir_length = header_size - 3;
754 if (hdr->extend_type == EXTEND_MSDOS ||
755 hdr->extend_type == EXTEND_HUMAN ||
756 hdr->extend_type == EXTEND_GENERIC)
757 hdr->attribute = get_word();
763 if (hdr->extend_type == EXTEND_UNIX)
764 hdr->unix_mode = get_word();
770 if (hdr->extend_type == EXTEND_UNIX) {
771 hdr->unix_gid = get_word();
772 hdr->unix_uid = get_word();
779 setup_get(get_ptr + header_size - 3);
785 setup_get(get_ptr + header_size - 3);
789 * UNIX last modified time
791 if (hdr->extend_type == EXTEND_UNIX)
792 hdr->unix_last_modified_stamp = (time_t) get_longword();
798 setup_get(get_ptr + header_size - 3);
802 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
803 hdr->packed_size -= get_ptr - ptr - 2;
804 hdr->header_size += get_ptr - ptr - 2;
808 strcat(dirname, hdr->name);
809 strcpy(hdr->name, dirname);
810 name_length += dir_length;
813 switch (hdr->extend_type) {
815 archive_kanji_code = CODE_SJIS;
816 system_kanji_code = default_system_kanji_code;
817 archive_delim = "\\";
819 filename_case = TO_LOWER;
823 if (hdr->header_level == 2)
824 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
826 hdr->unix_last_modified_stamp =
827 generic_to_unix_stamp(hdr->last_modified_stamp);
835 archive_kanji_code = CODE_EUC;
836 system_kanji_code = default_system_kanji_code;
839 filename_case = NONE;
844 archive_kanji_code = CODE_SJIS;
845 system_kanji_code = default_system_kanji_code;
846 archive_delim = "/:";
848 filename_case = NONE;
850 hdr->unix_last_modified_stamp =
851 generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
855 archive_kanji_code = NONE;
856 system_kanji_code = NONE;
857 archive_delim = "\\";
859 filename_case = TO_LOWER;
861 if (hdr->header_level == 2)
862 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
864 hdr->unix_last_modified_stamp =
865 generic_to_unix_stamp(hdr->last_modified_stamp);
868 /* filename code and delimiter conversion */
869 if (specific_archive_kanji_code)
870 archive_kanji_code = specific_archive_kanji_code;
871 if (specific_system_kanji_code)
872 system_kanji_code = specific_system_kanji_code;
873 if (specific_archive_delim)
874 archive_delim = specific_archive_delim;
875 if (specific_system_delim)
876 system_delim = specific_system_delim;
877 if (specific_filename_case)
878 filename_case = specific_filename_case;
880 filename_conv(hdr->name, name_length, sizeof(hdr->name),
883 archive_delim, system_delim, filename_case);
886 printf("header level=%d\n", hdr->header_level); fflush(stdout);
892 /* ------------------------------------------------------------------------ */
894 init_header(name, v_stat, hdr)
901 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
902 bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
903 else if (compress_method)
904 bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
906 bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
908 hdr->packed_size = 0;
909 hdr->original_size = v_stat->st_size;
910 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
911 hdr->attribute = GENERIC_ATTRIBUTE;
912 hdr->header_level = header_level;
913 strcpy(hdr->name, name);
916 hdr->extend_type = EXTEND_UNIX;
917 hdr->unix_last_modified_stamp = v_stat->st_mtime;
918 /* since 00:00:00 JAN.1.1970 */
919 #ifdef NOT_COMPATIBLE_MODE
920 /* Please need your modification in this space. */
922 hdr->unix_mode = v_stat->st_mode;
925 hdr->unix_uid = v_stat->st_uid;
926 hdr->unix_gid = v_stat->st_gid;
928 if (is_directory(v_stat)) {
929 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
930 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
931 hdr->original_size = 0;
932 if (len > 0 && hdr->name[len - 1] != '/')
933 strcpy(&hdr->name[len++], "/");
937 if (is_symlink(v_stat)) {
940 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
941 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
942 hdr->original_size = 0;
943 len = readlink(name, lkname, 256);
944 lkname[len] = (char)'\0';
945 sprintf(hdr->name, "%s|%s", hdr->name, lkname);
948 if (generic_format) {
949 filename_conv(hdr->name, len, sizeof(hdr->name),
950 default_system_kanji_code,
951 default_system_kanji_code,
952 "/", "\\", TO_UPPER);
956 /* ------------------------------------------------------------------------ */
957 /* Write unix extended header or generic header. */
959 write_header(nafp, hdr)
965 char data[LZHEADER_STRAGE];
969 bzero(data, LZHEADER_STRAGE);
970 bcopy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
971 setup_put(data + I_PACKED_SIZE);
972 put_longword(hdr->packed_size);
973 put_longword(hdr->original_size);
975 if (hdr->header_level == HEADER_LEVEL2)
976 put_longword((long) hdr->unix_last_modified_stamp);
978 put_longword(hdr->last_modified_stamp);
980 switch (hdr->header_level) {
982 put_byte(hdr->attribute);
990 put_byte(hdr->header_level);
992 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
993 default_system_kanji_code,
994 default_system_kanji_code, /* no change code */
995 "\xff\\/", "\xff\xff\xff", NONE);
997 if (hdr->header_level != HEADER_LEVEL2) {
998 if (p = (char *) strrchr(hdr->name, DELIM2))
999 name_length = strlen(++p);
1001 name_length = strlen(hdr->name);
1002 put_byte(name_length);
1003 bcopy(p ? p : hdr->name, data + I_NAME, name_length);
1004 setup_put(data + I_NAME + name_length);
1008 if (header_level == HEADER_LEVEL0) {
1009 if (generic_format) {
1010 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
1011 data[I_HEADER_SIZE] = header_size;
1012 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1014 /* write old-style extend header */
1015 put_byte(EXTEND_UNIX);
1016 put_byte(CURRENT_UNIX_MINOR_VERSION);
1017 put_longword((long) hdr->unix_last_modified_stamp);
1018 put_word(hdr->unix_mode);
1019 put_word(hdr->unix_uid);
1020 put_word(hdr->unix_gid);
1021 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
1022 data[I_HEADER_SIZE] = header_size;
1023 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1026 /* write extend header. */
1032 put_byte(EXTEND_UNIX);
1035 if (hdr->header_level == HEADER_LEVEL2) {
1036 /* write common header */
1039 headercrc_ptr = put_ptr;
1043 if (generic_format) {
1044 header_size = put_ptr - data; /* +2 for last 0x0000 */
1047 if (hdr->header_level == HEADER_LEVEL1)
1048 header_size = put_ptr - data - 2;
1049 put_byte(0x50); /* permission */
1050 put_word(hdr->unix_mode);
1052 put_byte(0x51); /* gid and uid */
1053 put_word(hdr->unix_gid);
1054 put_word(hdr->unix_uid);
1056 if (p = (char *) strrchr(hdr->name, DELIM2)) {
1059 name_length = p - hdr->name + 1;
1060 put_word(name_length + 3);
1061 put_byte(2); /* dirname */
1062 for (i = 0; i < name_length; i++)
1063 put_byte(hdr->name[i]);
1065 } /* if generic .. */
1067 if (header_level != HEADER_LEVEL2) {
1068 if (!generic_format) {
1070 put_byte(0x54); /* time stamp */
1071 put_longword(hdr->unix_last_modified_stamp);
1073 hdr->packed_size += put_ptr - ptr;
1075 setup_put(data + I_PACKED_SIZE);
1076 put_longword(hdr->packed_size);
1078 data[I_HEADER_SIZE] = header_size;
1079 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1080 } else { /* header level 2 */
1082 if (p = (char *) strrchr(hdr->name, DELIM2))
1083 name_length = strlen(++p);
1086 name_length = strlen(hdr->name);
1088 put_word(name_length + 3);
1089 put_byte(1); /* filename */
1090 for (i = 0; i < name_length; i++)
1092 } /* if he.. != HEAD_LV2 */
1093 header_size = put_ptr - data;
1096 if (header_level == HEADER_LEVEL2) {
1097 unsigned short hcrc;
1098 setup_put(data + I_HEADER_SIZE);
1099 put_word(header_size + 2);
1101 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1102 setup_put(headercrc_ptr);
1106 if (fwrite(data, sizeof(char), header_size + 2, nafp) == 0)
1107 fatal_error("Cannot write to temporary file");
1109 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
1110 default_system_kanji_code,
1111 default_system_kanji_code, /* no change code */
1112 "\xff\\/", "///", NONE);
1116 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1117 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1118 * ¤è¤êÈ´¿è(by Koji Arai)
1121 euc2sjis(int *p1, int *p2)
1123 unsigned char c1 = *p1 & 0x7f;
1124 unsigned char c2 = *p2 & 0x7f;
1125 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1126 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1127 *p1 = ((c1 + 1) >> 1) + rowoff;
1128 *p2 += celoff - 0x80;
1132 sjis2euc(int *p1, int *p2)
1134 unsigned char c1 = *p1;
1135 unsigned char c2 = *p2;
1136 int adjust = c2 < 0x9f;
1137 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1138 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1139 *p1 = ((c1 - rowoff) << 1) - adjust;
1146 /* Local Variables: */