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)
97 #ifdef MULTIBYTE_FILENAME
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_FILENAME
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_FILENAME
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_FILENAME */
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_STRUCT_TM_TM_GMTOFF
381 return -localtime(&tt)->tm_gmtoff;
382 #else /* HAVE_STRUCT_TM_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_STRUCT_TM_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;
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 for (i = 0; i < header_size - 3; i++)
702 hdr->group[i] = get_byte();
703 hdr->group[i] = '\0';
709 for (i = 0; i < header_size - 3; i++)
710 hdr->user[i] = get_byte();
715 * UNIX last modified time
717 if (hdr->extend_type == EXTEND_UNIX)
718 hdr->unix_last_modified_stamp = (time_t) get_longword();
724 setup_get(get_ptr + header_size - 3);
728 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
729 hdr->packed_size -= get_ptr - ptr - 2;
730 hdr->header_size += get_ptr - ptr - 2;
734 switch (hdr->extend_type) {
736 archive_delim = "\xff\\";
738 filename_case = noconvertcase ? NONE : TO_LOWER;
742 if (hdr->header_level == 2)
743 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
745 hdr->unix_last_modified_stamp =
746 generic_to_unix_stamp(hdr->last_modified_stamp);
754 archive_delim = "\xff";
756 filename_case = NONE;
761 archive_delim = "\xff/:";
762 system_delim = "/:/";
763 filename_case = NONE;
765 hdr->unix_last_modified_stamp =
766 generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
770 archive_delim = "\xff\\";
772 filename_case = noconvertcase ? NONE : TO_LOWER;
773 /* pending: if small letter is included in filename,
774 the generic_to_unix_filename() do not case conversion,
775 but this code does not consider it. */
777 if (hdr->header_level == 2)
778 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
780 hdr->unix_last_modified_stamp =
781 generic_to_unix_stamp(hdr->last_modified_stamp);
784 /* filename kanji code and delimiter conversion */
785 if (optional_archive_kanji_code)
786 archive_kanji_code = optional_archive_kanji_code;
787 if (optional_system_kanji_code)
788 system_kanji_code = optional_system_kanji_code;
789 if (optional_archive_delim)
790 archive_delim = optional_archive_delim;
791 if (optional_system_delim)
792 system_delim = optional_system_delim;
793 if (optional_filename_case)
794 filename_case = optional_filename_case;
797 strcat(dirname, hdr->name);
798 strcpy(hdr->name, dirname);
799 name_length += dir_length;
802 filename_conv(hdr->name, name_length, sizeof(hdr->name),
805 archive_delim, system_delim, filename_case);
810 /* ------------------------------------------------------------------------ */
812 init_header(name, v_stat, hdr)
819 int system_kanji_code = default_system_kanji_code;
820 char *archive_delim = "";
821 char *system_delim = "";
822 int filename_case = NONE;
824 memset(hdr, 0, sizeof(LzHeader));
826 if (optional_system_kanji_code)
827 system_kanji_code = optional_system_kanji_code;
829 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
830 bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
831 else if (compress_method)
832 bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
834 bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
836 hdr->packed_size = 0;
837 hdr->original_size = v_stat->st_size;
838 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
839 hdr->attribute = GENERIC_ATTRIBUTE;
840 hdr->header_level = header_level;
841 strcpy(hdr->name, name);
844 hdr->extend_type = EXTEND_UNIX;
845 hdr->unix_last_modified_stamp = v_stat->st_mtime;
846 /* since 00:00:00 JAN.1.1970 */
847 #ifdef NOT_COMPATIBLE_MODE
848 /* Please need your modification in this space. */
850 hdr->unix_mode = v_stat->st_mode;
853 hdr->unix_uid = v_stat->st_uid;
854 hdr->unix_gid = v_stat->st_gid;
856 #if INCLUDE_OWNER_NAME_IN_HEADER
859 struct passwd *ent = getpwuid(hdr->unix_uid);
862 strncpy(hdr->user, ent->pw_name, sizeof(hdr->user));
863 if (hdr->user[sizeof(hdr->user)-1])
864 hdr->user[sizeof(hdr->user)-1] = 0;
870 struct group *ent = getgrgid(hdr->unix_gid);
873 strncpy(hdr->group, ent->gr_name, sizeof(hdr->group));
874 if (hdr->group[sizeof(hdr->group)-1])
875 hdr->group[sizeof(hdr->group)-1] = 0;
879 #endif /* INCLUDE_OWNER_NAME_IN_HEADER */
880 if (is_directory(v_stat)) {
881 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
882 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
883 hdr->original_size = 0;
884 if (len > 0 && hdr->name[len - 1] != '/')
885 strcpy(&hdr->name[len++], "/");
889 if (is_symlink(v_stat)) {
892 bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
893 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
894 hdr->original_size = 0;
895 len = readlink(name, lkname, 256);
896 lkname[len] = (char)'\0';
897 sprintf(hdr->name, "%s|%s", hdr->name, lkname);
901 if (generic_format) {
902 filename_case = TO_UPPER;
903 archive_delim = "\\";
906 filename_conv(hdr->name, len, sizeof(hdr->name),
908 system_kanji_code, /* no change code */
909 system_delim, archive_delim, filename_case);
912 /* ------------------------------------------------------------------------ */
913 /* Write unix extended header or generic header. */
915 write_header(nafp, hdr)
921 char data[LZHEADER_STRAGE];
924 int archive_kanji_code = CODE_SJIS;
925 int system_kanji_code = default_system_kanji_code;
927 if (optional_archive_kanji_code)
928 archive_kanji_code = optional_archive_kanji_code;
929 if (optional_system_kanji_code)
930 system_kanji_code = optional_system_kanji_code;
932 bzero(data, LZHEADER_STRAGE);
933 bcopy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
934 setup_put(data + I_PACKED_SIZE);
935 put_longword(hdr->packed_size);
936 put_longword(hdr->original_size);
938 if (hdr->header_level == HEADER_LEVEL2)
939 put_longword((long) hdr->unix_last_modified_stamp);
941 put_longword(hdr->last_modified_stamp);
943 switch (hdr->header_level) {
945 put_byte(hdr->attribute);
953 put_byte(hdr->header_level);
955 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
957 archive_kanji_code, /* no change code */
958 "\xff\\/", "\xff\xff\xff", NONE);
960 if (hdr->header_level != HEADER_LEVEL2) {
961 if (p = (char *) strrchr(hdr->name, DELIM2))
962 name_length = strlen(++p);
964 name_length = strlen(hdr->name);
965 put_byte(name_length);
966 bcopy(p ? p : hdr->name, data + I_NAME, name_length);
967 setup_put(data + I_NAME + name_length);
971 if (header_level == HEADER_LEVEL0) {
972 if (generic_format) {
973 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
974 data[I_HEADER_SIZE] = header_size;
975 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
977 /* write old-style extend header */
978 put_byte(EXTEND_UNIX);
979 put_byte(CURRENT_UNIX_MINOR_VERSION);
980 put_longword((long) hdr->unix_last_modified_stamp);
981 put_word(hdr->unix_mode);
982 put_word(hdr->unix_uid);
983 put_word(hdr->unix_gid);
984 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
985 data[I_HEADER_SIZE] = header_size;
986 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
989 /* write extend header. */
995 put_byte(EXTEND_UNIX);
998 if (hdr->header_level == HEADER_LEVEL2) {
999 /* write common header */
1002 headercrc_ptr = put_ptr;
1006 if (generic_format) {
1007 header_size = put_ptr - data; /* +2 for last 0x0000 */
1010 if (hdr->header_level == HEADER_LEVEL1)
1011 header_size = put_ptr - data - 2;
1012 put_byte(0x50); /* permission */
1013 put_word(hdr->unix_mode);
1015 put_byte(0x51); /* gid and uid */
1016 put_word(hdr->unix_gid);
1017 put_word(hdr->unix_uid);
1020 int i, len = strlen(hdr->group);
1022 put_byte(0x52); /* group name */
1023 for (i = 0; i < len; i++)
1024 put_byte(hdr->group[i]);
1026 len = strlen(hdr->user);
1028 put_byte(0x53); /* user name */
1029 for (i = 0; i < len; i++)
1030 put_byte(hdr->user[i]);
1033 if (p = (char *) strrchr(hdr->name, DELIM2)) {
1036 name_length = p - hdr->name + 1;
1037 put_word(name_length + 3);
1038 put_byte(2); /* dirname */
1039 for (i = 0; i < name_length; i++)
1040 put_byte(hdr->name[i]);
1042 } /* if generic .. */
1044 if (header_level != HEADER_LEVEL2) {
1045 if (!generic_format) {
1047 put_byte(0x54); /* time stamp */
1048 put_longword(hdr->unix_last_modified_stamp);
1050 hdr->packed_size += put_ptr - ptr;
1052 setup_put(data + I_PACKED_SIZE);
1053 put_longword(hdr->packed_size);
1055 data[I_HEADER_SIZE] = header_size;
1056 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1057 } else { /* header level 2 */
1059 if (p = (char *) strrchr(hdr->name, DELIM2))
1060 name_length = strlen(++p);
1063 name_length = strlen(hdr->name);
1065 put_word(name_length + 3);
1066 put_byte(1); /* filename */
1067 for (i = 0; i < name_length; i++)
1069 } /* if he.. != HEAD_LV2 */
1070 header_size = put_ptr - data;
1073 if (header_level == HEADER_LEVEL2) {
1074 unsigned short hcrc;
1075 setup_put(data + I_HEADER_SIZE);
1076 put_word(header_size + 2);
1078 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1079 setup_put(headercrc_ptr);
1083 if (fwrite(data, sizeof(char), header_size + 2, nafp) == 0)
1084 fatal_error("Cannot write to temporary file");
1086 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
1089 "\xff\\/", "///", NONE);
1093 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1094 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1095 * ¤è¤êÈ´¿è(by Koji Arai)
1098 euc2sjis(int *p1, int *p2)
1100 unsigned char c1 = *p1 & 0x7f;
1101 unsigned char c2 = *p2 & 0x7f;
1102 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1103 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1104 *p1 = ((c1 + 1) >> 1) + rowoff;
1105 *p2 += celoff - 0x80;
1109 sjis2euc(int *p1, int *p2)
1111 unsigned char c1 = *p1;
1112 unsigned char c2 = *p2;
1113 int adjust = c2 < 0x9f;
1114 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1115 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1116 *p1 = ((c1 - rowoff) << 1) - adjust;
1123 /* Local Variables: */
1126 /* compile-command:"gcc -c header.c" */
1128 /* vi: set tabstop=4: */