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 #ifdef MULTIBYTE_FILENAME
26 int default_system_kanji_code = MULTIBYTE_FILENAME;
28 int default_system_kanji_code = NONE;
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 memset(hdr, 0, 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 (level %d)", hdr->header_level);
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 memcpy(hdr->method, data + I_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 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 memcpy(hdr->method, LZHUFF5_METHOD, METHOD_TYPE_STRAGE);
831 else if (compress_method)
832 memcpy(hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE);
834 memcpy(hdr->method, LZHUFF0_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 memcpy(hdr->method, LZHDIRS_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)) {
890 char lkname[256]; /* FIXME: no enough space */
892 memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
893 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
894 hdr->original_size = 0;
895 len = readlink(name, lkname, sizeof(lkname));
896 if (xsnprintf(hdr->name, sizeof(hdr->name),
897 "%s|%.*s", hdr->name, len, lkname) == -1)
898 error("file name is too long (%s -> %.*s)", hdr->name, len, lkname);
902 if (generic_format) {
903 filename_case = TO_UPPER;
904 archive_delim = "\\";
907 filename_conv(hdr->name, len, sizeof(hdr->name),
909 system_kanji_code, /* no change code */
910 system_delim, archive_delim, filename_case);
913 /* ------------------------------------------------------------------------ */
914 /* Write unix extended header or generic header. */
916 write_header(nafp, hdr)
922 char data[LZHEADER_STRAGE];
925 int archive_kanji_code = CODE_SJIS;
926 int system_kanji_code = default_system_kanji_code;
928 if (optional_archive_kanji_code)
929 archive_kanji_code = optional_archive_kanji_code;
930 if (optional_system_kanji_code)
931 system_kanji_code = optional_system_kanji_code;
933 memset(data, 0, LZHEADER_STRAGE);
934 memcpy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
935 setup_put(data + I_PACKED_SIZE);
936 put_longword(hdr->packed_size);
937 put_longword(hdr->original_size);
939 if (hdr->header_level == HEADER_LEVEL2)
940 put_longword((long) hdr->unix_last_modified_stamp);
942 put_longword(hdr->last_modified_stamp);
944 switch (hdr->header_level) {
946 put_byte(hdr->attribute);
954 put_byte(hdr->header_level);
956 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
958 archive_kanji_code, /* no change code */
959 "\xff\\/", "\xff\xff\xff", NONE);
961 if (hdr->header_level != HEADER_LEVEL2) {
962 if (p = (char *) strrchr(hdr->name, DELIM2))
963 name_length = strlen(++p);
965 name_length = strlen(hdr->name);
966 put_byte(name_length);
967 memcpy(data + I_NAME, p ? p : hdr->name, name_length);
968 setup_put(data + I_NAME + name_length);
972 if (header_level == HEADER_LEVEL0) {
973 if (generic_format) {
974 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
975 data[I_HEADER_SIZE] = header_size;
976 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
978 /* write old-style extend header */
979 put_byte(EXTEND_UNIX);
980 put_byte(CURRENT_UNIX_MINOR_VERSION);
981 put_longword((long) hdr->unix_last_modified_stamp);
982 put_word(hdr->unix_mode);
983 put_word(hdr->unix_uid);
984 put_word(hdr->unix_gid);
985 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
986 data[I_HEADER_SIZE] = header_size;
987 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
990 /* write extend header. */
996 put_byte(EXTEND_UNIX);
999 if (hdr->header_level == HEADER_LEVEL2) {
1000 /* write common header */
1003 headercrc_ptr = put_ptr;
1007 if (generic_format) {
1008 header_size = put_ptr - data; /* +2 for last 0x0000 */
1011 if (hdr->header_level == HEADER_LEVEL1)
1012 header_size = put_ptr - data - 2;
1013 put_byte(0x50); /* permission */
1014 put_word(hdr->unix_mode);
1016 put_byte(0x51); /* gid and uid */
1017 put_word(hdr->unix_gid);
1018 put_word(hdr->unix_uid);
1021 int i, len = strlen(hdr->group);
1023 put_byte(0x52); /* group name */
1024 for (i = 0; i < len; i++)
1025 put_byte(hdr->group[i]);
1027 len = strlen(hdr->user);
1029 put_byte(0x53); /* user name */
1030 for (i = 0; i < len; i++)
1031 put_byte(hdr->user[i]);
1034 if (p = (char *) strrchr(hdr->name, DELIM2)) {
1037 name_length = p - hdr->name + 1;
1038 put_word(name_length + 3);
1039 put_byte(2); /* dirname */
1040 for (i = 0; i < name_length; i++)
1041 put_byte(hdr->name[i]);
1043 } /* if generic .. */
1045 if (header_level != HEADER_LEVEL2) {
1046 if (!generic_format) {
1048 put_byte(0x54); /* time stamp */
1049 put_longword(hdr->unix_last_modified_stamp);
1051 hdr->packed_size += put_ptr - ptr;
1053 setup_put(data + I_PACKED_SIZE);
1054 put_longword(hdr->packed_size);
1056 data[I_HEADER_SIZE] = header_size;
1057 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1058 } else { /* header level 2 */
1060 if (p = (char *) strrchr(hdr->name, DELIM2))
1061 name_length = strlen(++p);
1064 name_length = strlen(hdr->name);
1066 put_word(name_length + 3);
1067 put_byte(1); /* filename */
1068 for (i = 0; i < name_length; i++)
1070 } /* if he.. != HEAD_LV2 */
1071 header_size = put_ptr - data;
1074 if (header_level == HEADER_LEVEL2) {
1075 unsigned short hcrc;
1076 setup_put(data + I_HEADER_SIZE);
1077 put_word(header_size + 2);
1079 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1080 setup_put(headercrc_ptr);
1084 if (fwrite(data, header_size + 2, 1, nafp) == 0)
1085 fatal_error("Cannot write to temporary file");
1087 filename_conv(hdr->name, strlen(hdr->name), sizeof(hdr->name),
1090 "\xff\\/", "///", NONE);
1094 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1095 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1096 * ¤è¤êÈ´¿è(by Koji Arai)
1099 euc2sjis(int *p1, int *p2)
1101 unsigned char c1 = *p1 & 0x7f;
1102 unsigned char c2 = *p2 & 0x7f;
1103 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1104 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1105 *p1 = ((c1 + 1) >> 1) + rowoff;
1106 *p2 += celoff - 0x80;
1110 sjis2euc(int *p1, int *p2)
1112 unsigned char c1 = *p1;
1113 unsigned char c2 = *p2;
1114 int adjust = c2 < 0x9f;
1115 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1116 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1117 *p1 = ((c1 - rowoff) << 1) - adjust;
1124 /* Local Variables: */
1127 /* compile-command:"gcc -c header.c" */
1129 /* vi: set tabstop=4: */