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.14i bug fixed 2000.10.06 t.okamoto */
13 /* ------------------------------------------------------------------------ */
16 /* ------------------------------------------------------------------------ */
19 int optional_archive_kanji_code = NONE;
20 int optional_system_kanji_code = NONE;
21 char *optional_archive_delim = NULL;
22 char *optional_system_delim = NULL;
23 int optional_filename_case = NONE;
25 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__hpux)
26 /* Cygwin, HP-UX and other UNIX are able to use SJIS as native code. */
27 int default_system_kanji_code = CODE_SJIS;
29 int default_system_kanji_code = CODE_EUC;
31 /* ------------------------------------------------------------------------ */
39 for (sum = 0; len; len--)
45 /* ------------------------------------------------------------------------ */
53 return (b1 << 8) + b0;
56 /* ------------------------------------------------------------------------ */
65 /* ------------------------------------------------------------------------ */
75 return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
78 /* ------------------------------------------------------------------------ */
89 /* ------------------------------------------------------------------------ */
91 msdos_to_unix_filename(name, len)
98 for (i = 0; i < len; i++) {
99 if (MULTIBYTE_FIRST_P(name[i]) &&
100 MULTIBYTE_SECOND_P(name[i + 1]))
102 else if (name[i] == '\\')
104 else if (!noconvertcase && isupper(name[i]))
105 name[i] = tolower(name[i]);
108 for (i = 0; i < len; i++) {
111 else if (!noconvertcase && isupper(name[i]))
112 name[i] = tolower(name[i]);
117 /* ------------------------------------------------------------------------ */
119 generic_to_unix_filename(name, len)
124 boolean lower_case_used = FALSE;
126 #ifdef MULTIBYTE_CHAR
127 for (i = 0; i < len; i++) {
128 if (MULTIBYTE_FIRST_P(name[i]) &&
129 MULTIBYTE_SECOND_P(name[i + 1]))
131 else if (islower(name[i])) {
132 lower_case_used = TRUE;
136 for (i = 0; i < len; i++) {
137 if (MULTIBYTE_FIRST_P(name[i]) &&
138 MULTIBYTE_SECOND_P(name[i + 1]))
140 else if (name[i] == '\\')
142 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
143 name[i] = tolower(name[i]);
146 for (i = 0; i < len; i++)
147 if (islower(name[i])) {
148 lower_case_used = TRUE;
151 for (i = 0; i < len; i++) {
154 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
155 name[i] = tolower(name[i]);
160 /* ------------------------------------------------------------------------ */
162 macos_to_unix_filename(name, len)
168 for (i = 0; i < len; i++) {
171 else if (name[i] == '/')
176 /* ------------------------------------------------------------------------ */
178 unix_to_generic_filename(name, len)
184 for (i = 0; i < len; i++) {
187 else if (islower(name[i]))
188 name[i] = toupper(name[i]);
192 /* added by Koji Arai */
194 filename_conv(name, len, size,
196 from_delim, to_delim,
201 int from_code, to_code, case_to;
202 char *from_delim, *to_delim;
207 for (i = 0; i < len; i ++) {
208 #ifdef MULTIBYTE_CHAR
209 if (from_code == CODE_EUC &&
210 (unsigned char)name[i] == 0x8e) {
211 if (to_code != CODE_SJIS) {
217 memmove(name + i, name + i + 1, len - i);
221 if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
222 if (to_code != CODE_EUC) {
226 if (len == size - 1) /* check overflow */
228 memmove(name+i+1, name+i, len-i);
234 if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
236 if (to_code != CODE_SJIS) {
241 c1 = (unsigned char)name[i];
242 c2 = (unsigned char)name[i+1];
249 if (from_code == CODE_SJIS &&
250 SJC_FIRST_P(name[i]) &&
251 SJC_SECOND_P(name[i+1])) {
254 if (to_code != CODE_EUC) {
259 c1 = (unsigned char)name[i];
260 c2 = (unsigned char)name[i+1];
267 #endif /* MULTIBYTE_CHAR */
271 /* transpose from_delim to to_delim */
273 if ((ptr = strchr(from_delim, name[i])) != NULL) {
274 name[i] = to_delim[ptr - from_delim];
279 if (case_to == TO_UPPER && islower(name[i])) {
280 name[i] = toupper(name[i]);
283 if (case_to == TO_LOWER && isupper(name[i])) {
284 name[i] = tolower(name[i]);
290 /* ------------------------------------------------------------------------ */
292 /* Generic stamp format: */
294 /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
295 /* |<-------- year ------->|<- month ->|<-- day -->| */
297 /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
298 /* |<--- hour --->|<---- minute --->|<- second*2 ->| */
300 /* ------------------------------------------------------------------------ */
303 * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
304 * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
308 #if defined(HAVE_MKTIME)
309 #ifdef HAVE_TIMELOCAL
310 #undef HAVE_TIMELOCAL
312 #endif /* defined(HAVE_MKTIME) */
314 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
318 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
320 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET)
326 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET) || defined(HAVE_FTIME)
327 #ifdef HAVE_GETTIMEOFDAY
328 #undef HAVE_GETTIMEOFDAY
331 #ifndef HAVE_GETTIMEOFDAY
332 #define HAVE_GETTIMEOFDAY /* use gettimeofday() */
337 #include <sys/timeb.h>
341 * You may define as : #define TIMEZONE_HOOK \ extern long
342 * timezone ; \ extern void tzset();
346 /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
349 #if defined(HAVE_TZSET) && defined(_MINIX)
350 extern long timezone; /* not defined in time.h */
353 /* ------------------------------------------------------------------------ */
354 #if defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) || defined(HAVE_TZSET)
364 /* ------------------------------------------------------------------------ */
365 #if !defined(HAVE_TZSET) && defined(HAVE_FTIME)
370 return buf.timezone * 60L;
374 /* ------------------------------------------------------------------------ */
375 #if !defined(HAVE_TZSET) && !defined(HAVE_FTIME) /* maybe defined(HAVE_GETTIMEOFDAY) */
377 #ifdef HAVE_TM_GMTOFF
381 return -localtime(&tt)->tm_gmtoff;
382 #else /* HAVE_TM_GMTOFF */
385 gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
387 * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
390 return (tzp.tz_minuteswest * 60L);
391 #endif /* HAVE_TM_GMTOFF */
394 #endif /* defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) ||
395 * defined(HAVE_TZSET) */
397 /* ------------------------------------------------------------------------ */
400 msdos_to_unix_stamp_tm(a)
405 t.tm_sec = (a & 0x1f) * 2;
406 t.tm_min = (a >> 5) & 0x3f;
407 t.tm_hour = (a >> 11) & 0x1f;
408 t.tm_mday = (a >> 16) & 0x1f;
409 t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
410 t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
415 /* ------------------------------------------------------------------------ */
417 generic_to_unix_stamp(t)
419 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
424 * special case: if MSDOS format date and time were zero, then we
425 * set time to be zero here too.
430 dostm.tm_sec = (t & 0x1f) * 2;
431 dostm.tm_min = t >> 5 & 0x3f;
432 dostm.tm_hour = t >> 11 & 0x1f;
433 dostm.tm_mday = t >> 16 & 0x1f;
434 dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1; /* 0..11 */
435 dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
437 dostm.tm_isdst = 0; /* correct? */
439 dostm.tm_isdst = -1; /* correct? */
441 return (time_t) mktime(&dostm);
442 #else /* maybe defined(HAVE_TIMELOCAL) */
443 return (time_t) timelocal(&dostm);
447 #else /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
449 int year, month, day, hour, min, sec;
451 static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
452 181, 212, 243, 273, 304, 334};
456 * special case: if MSDOS format date and time were zero, then we
457 * set time to be zero here too.
462 year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
463 month = (int) (t >> 16 + 5) & 0x0f; /* 1..12 means Jan..Dec */
464 day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
466 hour = ((int) t >> 11) & 0x1f;
467 min = ((int) t >> 5) & 0x3f;
468 sec = ((int) t & 0x1f) * 2;
470 /* Calculate days since 1970.01.01 */
471 days = (365 * (year - 1970) + /* days due to whole years */
472 (year - 1970 + 1) / 4 + /* days due to leap years */
473 dsboy[month - 1] + /* days since beginning of this year */
474 day - 1); /* days since beginning of month */
476 if ((year % 4 == 0) &&
477 (year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
478 (month >= 3)) /* if this is a leap year and month */
479 days++; /* is March or later, add a day */
481 /* Knowing the days, we can find seconds */
482 longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
483 longtime += gettz(); /* adjust for timezone */
485 /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
486 return (time_t) longtime;
488 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
490 /* ------------------------------------------------------------------------ */
492 unix_to_generic_stamp(t)
495 struct tm *tm = localtime(&t);
497 return ((((long) (tm->tm_year - 80)) << 25) +
498 (((long) (tm->tm_mon + 1)) << 21) +
499 (((long) tm->tm_mday) << 16) +
500 (long) ((tm->tm_hour << 11) +
505 /* ------------------------------------------------------------------------ */
506 /* build header functions */
507 /* ------------------------------------------------------------------------ */
511 register LzHeader *hdr;
515 char data[LZHEADER_STRAGE];
516 char dirname[FILENAME_LENGTH];
524 int archive_kanji_code = CODE_SJIS;
525 int system_kanji_code = default_system_kanji_code;
526 char *archive_delim = "";
527 char *system_delim = "";
528 int filename_case = NONE;
530 bzero(hdr, sizeof(LzHeader));
532 if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
533 return FALSE; /* finish */
536 if (fread(data + I_HEADER_CHECKSUM,
537 sizeof(char), header_size - 1, fp) < header_size - 1) {
538 fatal_error("Invalid header (LHarc file ?)");
539 return FALSE; /* finish */
541 setup_get(data + I_HEADER_LEVEL);
542 hdr->header_level = get_byte();
543 if (hdr->header_level != 2 &&
544 fread(data + header_size, sizeof(char), 2, fp) < 2) {
545 fatal_error("Invalid header (LHarc file ?)");
546 return FALSE; /* finish */
549 if (hdr->header_level >= 3) {
550 fatal_error("Unknown level header");
554 setup_get(data + I_HEADER_CHECKSUM);
555 checksum = get_byte();
557 if (hdr->header_level == 2) {
558 hdr->header_size = header_size + checksum*256;
560 hdr->header_size = header_size;
562 bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
563 setup_get(data + I_PACKED_SIZE);
564 hdr->packed_size = get_longword();
565 hdr->original_size = get_longword();
566 hdr->last_modified_stamp = get_longword();
567 hdr->attribute = get_byte();
569 if ((hdr->header_level = get_byte()) != 2) {
570 if (calc_sum(data + I_METHOD, header_size) != checksum)
571 warning("Checksum error (LHarc file?)", "");
572 name_length = get_byte();
573 for (i = 0; i < name_length; i++)
574 hdr->name[i] = (char) get_byte();
575 hdr->name[name_length] = '\0';
578 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
582 /* defaults for other type */
583 hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
587 if (hdr->header_level == 0) {
588 extend_size = header_size - name_length -22;
589 if (extend_size < 0) {
590 if (extend_size == -2) {
591 hdr->extend_type = EXTEND_GENERIC;
592 hdr->has_crc = FALSE;
594 fatal_error("Unkonwn header (lha file?)");
599 hdr->crc = get_word();
602 if (extend_size >= 1) {
603 hdr->extend_type = get_byte();
606 if (hdr->extend_type == EXTEND_UNIX) {
607 if (extend_size >= 11) {
608 hdr->minor_version = get_byte();
609 hdr->unix_last_modified_stamp = (time_t) get_longword();
610 hdr->unix_mode = get_word();
611 hdr->unix_uid = get_word();
612 hdr->unix_gid = get_word();
615 hdr->extend_type = EXTEND_GENERIC;
618 while (extend_size-- > 0)
620 if (hdr->extend_type == EXTEND_UNIX)
622 } else if (hdr->header_level == 1) {
624 extend_size = header_size - name_length-25;
625 hdr->crc = get_word();
626 hdr->extend_type = get_byte();
627 while (extend_size-- > 0)
629 } else { /* level 2 */
631 hdr->crc = get_word();
632 hdr->extend_type = get_byte();
635 if (hdr->header_level > 0) {
637 if (hdr->header_level != 2)
638 setup_get(data + hdr->header_size);
640 while ((header_size = get_word()) != 0) {
641 if (hdr->header_level != 2 &&
642 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
643 fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
644 fatal_error("Invalid header (LHa file ?)");
647 switch (get_byte()) {
652 setup_get(get_ptr + header_size - 3);
658 for (i = 0; i < header_size - 3; i++)
659 hdr->name[i] = (char) get_byte();
660 hdr->name[header_size - 3] = '\0';
661 name_length = header_size - 3; /* modified by Koji Arai */
667 for (i = 0; i < header_size - 3; i++)
668 dirname[i] = (char) get_byte();
669 dirname[header_size - 3] = '\0';
670 dir_length = header_size - 3;
676 if (hdr->extend_type == EXTEND_MSDOS ||
677 hdr->extend_type == EXTEND_HUMAN ||
678 hdr->extend_type == EXTEND_GENERIC)
679 hdr->attribute = get_word();
685 if (hdr->extend_type == EXTEND_UNIX)
686 hdr->unix_mode = get_word();
692 if (hdr->extend_type == EXTEND_UNIX) {
693 hdr->unix_gid = get_word();
694 hdr->unix_uid = get_word();
701 setup_get(get_ptr + header_size - 3);
707 setup_get(get_ptr + header_size - 3);
711 * UNIX last modified time
713 if (hdr->extend_type == EXTEND_UNIX)
714 hdr->unix_last_modified_stamp = (time_t) get_longword();
720 setup_get(get_ptr + header_size - 3);
724 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
725 hdr->packed_size -= get_ptr - ptr - 2;
726 hdr->header_size += get_ptr - ptr - 2;
730 switch (hdr->extend_type) {
732 archive_delim = "\xff\\";
734 filename_case = noconvertcase ? NONE : TO_LOWER;
738 if (hdr->header_level == 2)
739 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
741 hdr->unix_last_modified_stamp =
742 generic_to_unix_stamp(hdr->last_modified_stamp);
750 archive_delim = "\xff";
752 filename_case = NONE;
757 archive_delim = "\xff/:";
758 system_delim = "/:/";
759 filename_case = NONE;
761 hdr->unix_last_modified_stamp =
762 generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
766 archive_delim = "\xff\\";
768 filename_case = noconvertcase ? NONE : TO_LOWER;
769 /* pending: if small letter is included in filename,
770 the generic_to_unix_filename() do not case conversion,
771 but this code does not consider it. */
773 if (hdr->header_level == 2)
774 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
776 hdr->unix_last_modified_stamp =
777 generic_to_unix_stamp(hdr->last_modified_stamp);
780 /* filename kanji code and delimiter conversion */
781 if (optional_archive_kanji_code)
782 archive_kanji_code = optional_archive_kanji_code;
783 if (optional_system_kanji_code)
784 system_kanji_code = optional_system_kanji_code;
785 if (optional_archive_delim)
786 archive_delim = optional_archive_delim;
787 if (optional_system_delim)
788 system_delim = optional_system_delim;
789 if (optional_filename_case)
790 filename_case = optional_filename_case;
793 strcat(dirname, hdr->name);
794 strcpy(hdr->name, dirname);
795 name_length += dir_length;
798 filename_conv(hdr->name, name_length, sizeof(hdr->name),
801 archive_delim, system_delim, filename_case);
806 /* ------------------------------------------------------------------------ */
808 init_header(name, v_stat, hdr)
815 int system_kanji_code = default_system_kanji_code;
816 char *archive_delim = "";
817 char *system_delim = "";
818 int filename_case = NONE;
820 if (optional_system_kanji_code)
821 system_kanji_code = optional_system_kanji_code;
823 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
824 bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
825 else if (compress_method)
826 bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
828 bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
830 hdr->packed_size = 0;
831 hdr->original_size = v_stat->st_size;
832 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
833 hdr->attribute = GENERIC_ATTRIBUTE;
834 hdr->header_level = header_level;
835 strcpy(hdr->name, name);
838 hdr->extend_type = EXTEND_UNIX;
839 hdr->unix_last_modified_stamp = v_stat->st_mtime;
840 /* since 00:00:00 JAN.1.1970 */
841 #ifdef NOT_COMPATIBLE_MODE
842 /* Please need your modification in this space. */
844 hdr->unix_mode = v_stat->st_mode;
847 hdr->unix_uid = v_stat->st_uid;
848 hdr->unix_gid = v_stat->st_gid;
850 if (is_directory(v_stat)) {
851 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
852 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
853 hdr->original_size = 0;
854 if (len > 0 && hdr->name[len - 1] != '/')
855 strcpy(&hdr->name[len++], "/");
859 if (is_symlink(v_stat)) {
862 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
863 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
864 hdr->original_size = 0;
865 len = readlink(name, lkname, 256);
866 lkname[len] = (char)'\0';
867 sprintf(hdr->name, "%s|%s", hdr->name, lkname);
871 if (generic_format) {
872 filename_case = TO_UPPER;
873 archive_delim = "\\";
876 filename_conv(hdr->name, len, sizeof(hdr->name),
878 system_kanji_code, /* no change code */
879 system_delim, archive_delim, filename_case);
882 /* ------------------------------------------------------------------------ */
883 /* Write unix extended header or generic header. */
885 write_header(nafp, hdr)
891 char data[LZHEADER_STRAGE];
894 int archive_kanji_code = CODE_SJIS;
895 int system_kanji_code = default_system_kanji_code;
897 if (optional_archive_kanji_code)
898 archive_kanji_code = optional_archive_kanji_code;
899 if (optional_system_kanji_code)
900 system_kanji_code = optional_system_kanji_code;
902 bzero(data, LZHEADER_STRAGE);
903 bcopy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
904 setup_put(data + I_PACKED_SIZE);
905 put_longword(hdr->packed_size);
906 put_longword(hdr->original_size);
908 if (hdr->header_level == HEADER_LEVEL2)
909 put_longword((long) hdr->unix_last_modified_stamp);
911 put_longword(hdr->last_modified_stamp);
913 switch (hdr->header_level) {
915 put_byte(hdr->attribute);
923 put_byte(hdr->header_level);
925 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
927 archive_kanji_code, /* no change code */
928 "\xff\\/", "\xff\xff\xff", NONE);
930 if (hdr->header_level != HEADER_LEVEL2) {
931 if (p = (char *) strrchr(hdr->name, DELIM2))
932 name_length = strlen(++p);
934 name_length = strlen(hdr->name);
935 put_byte(name_length);
936 bcopy(p ? p : hdr->name, data + I_NAME, name_length);
937 setup_put(data + I_NAME + name_length);
941 if (header_level == HEADER_LEVEL0) {
942 if (generic_format) {
943 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
944 data[I_HEADER_SIZE] = header_size;
945 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
947 /* write old-style extend header */
948 put_byte(EXTEND_UNIX);
949 put_byte(CURRENT_UNIX_MINOR_VERSION);
950 put_longword((long) hdr->unix_last_modified_stamp);
951 put_word(hdr->unix_mode);
952 put_word(hdr->unix_uid);
953 put_word(hdr->unix_gid);
954 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
955 data[I_HEADER_SIZE] = header_size;
956 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
959 /* write extend header. */
965 put_byte(EXTEND_UNIX);
968 if (hdr->header_level == HEADER_LEVEL2) {
969 /* write common header */
972 headercrc_ptr = put_ptr;
976 if (generic_format) {
977 header_size = put_ptr - data; /* +2 for last 0x0000 */
980 if (hdr->header_level == HEADER_LEVEL1)
981 header_size = put_ptr - data - 2;
982 put_byte(0x50); /* permission */
983 put_word(hdr->unix_mode);
985 put_byte(0x51); /* gid and uid */
986 put_word(hdr->unix_gid);
987 put_word(hdr->unix_uid);
989 if (p = (char *) strrchr(hdr->name, DELIM2)) {
992 name_length = p - hdr->name + 1;
993 put_word(name_length + 3);
994 put_byte(2); /* dirname */
995 for (i = 0; i < name_length; i++)
996 put_byte(hdr->name[i]);
998 } /* if generic .. */
1000 if (header_level != HEADER_LEVEL2) {
1001 if (!generic_format) {
1003 put_byte(0x54); /* time stamp */
1004 put_longword(hdr->unix_last_modified_stamp);
1006 hdr->packed_size += put_ptr - ptr;
1008 setup_put(data + I_PACKED_SIZE);
1009 put_longword(hdr->packed_size);
1011 data[I_HEADER_SIZE] = header_size;
1012 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1013 } else { /* header level 2 */
1015 if (p = (char *) strrchr(hdr->name, DELIM2))
1016 name_length = strlen(++p);
1019 name_length = strlen(hdr->name);
1021 put_word(name_length + 3);
1022 put_byte(1); /* filename */
1023 for (i = 0; i < name_length; i++)
1025 } /* if he.. != HEAD_LV2 */
1026 header_size = put_ptr - data;
1029 if (header_level == HEADER_LEVEL2) {
1030 unsigned short hcrc;
1031 setup_put(data + I_HEADER_SIZE);
1032 put_word(header_size + 2);
1034 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1035 setup_put(headercrc_ptr);
1039 if (fwrite(data, sizeof(char), header_size + 2, nafp) == 0)
1040 fatal_error("Cannot write to temporary file");
1042 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
1045 "\xff\\/", "///", NONE);
1049 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1050 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1051 * ¤è¤êÈ´¿è(by Koji Arai)
1054 euc2sjis(int *p1, int *p2)
1056 unsigned char c1 = *p1 & 0x7f;
1057 unsigned char c2 = *p2 & 0x7f;
1058 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1059 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1060 *p1 = ((c1 + 1) >> 1) + rowoff;
1061 *p2 += celoff - 0x80;
1065 sjis2euc(int *p1, int *p2)
1067 unsigned char c1 = *p1;
1068 unsigned char c2 = *p2;
1069 int adjust = c2 < 0x9f;
1070 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1071 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1072 *p1 = ((c1 - rowoff) << 1) - adjust;
1079 /* Local Variables: */
1082 /* compile-command:"gcc -c header.c" */
1084 /* vi: set tabstop=4: */