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 /* ------------------------------------------------------------------------ */
17 static int ConvertEncodingToUTF8(const char* inCStr, char* outUTF8Buffer, int outUTF8BufferLength, unsigned long scriptEncoding, unsigned long flags);
18 static int ConvertUTF8ToEncoding(const char* inUTF8Buf, int inUTF8BufLength, char* outCStrBuffer, int outCStrBufferLength, unsigned long scriptEncoding, unsigned long flags);
19 #endif /* __APPLE__ */
21 /* ------------------------------------------------------------------------ */
24 int optional_archive_kanji_code = NONE;
25 int optional_system_kanji_code = NONE;
26 char *optional_archive_delim = NULL;
27 char *optional_system_delim = NULL;
28 int optional_filename_case = NONE;
30 #ifdef MULTIBYTE_FILENAME
31 int default_system_kanji_code = MULTIBYTE_FILENAME;
33 int default_system_kanji_code = NONE;
36 /* ------------------------------------------------------------------------ */
44 for (sum = 0; len; len--)
50 /* ------------------------------------------------------------------------ */
58 return (b1 << 8) + b0;
61 /* ------------------------------------------------------------------------ */
70 /* ------------------------------------------------------------------------ */
80 return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
83 /* ------------------------------------------------------------------------ */
94 /* ------------------------------------------------------------------------ */
96 msdos_to_unix_filename(name, len)
102 #ifdef MULTIBYTE_FILENAME
103 for (i = 0; i < len; i++) {
104 if (MULTIBYTE_FIRST_P(name[i]) &&
105 MULTIBYTE_SECOND_P(name[i + 1]))
107 else if (name[i] == '\\')
109 else if (!noconvertcase && isupper(name[i]))
110 name[i] = tolower(name[i]);
113 for (i = 0; i < len; i++) {
116 else if (!noconvertcase && isupper(name[i]))
117 name[i] = tolower(name[i]);
122 /* ------------------------------------------------------------------------ */
124 generic_to_unix_filename(name, len)
129 boolean lower_case_used = FALSE;
131 #ifdef MULTIBYTE_FILENAME
132 for (i = 0; i < len; i++) {
133 if (MULTIBYTE_FIRST_P(name[i]) &&
134 MULTIBYTE_SECOND_P(name[i + 1]))
136 else if (islower(name[i])) {
137 lower_case_used = TRUE;
141 for (i = 0; i < len; i++) {
142 if (MULTIBYTE_FIRST_P(name[i]) &&
143 MULTIBYTE_SECOND_P(name[i + 1]))
145 else if (name[i] == '\\')
147 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
148 name[i] = tolower(name[i]);
151 for (i = 0; i < len; i++)
152 if (islower(name[i])) {
153 lower_case_used = TRUE;
156 for (i = 0; i < len; i++) {
159 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
160 name[i] = tolower(name[i]);
165 /* ------------------------------------------------------------------------ */
167 macos_to_unix_filename(name, len)
173 for (i = 0; i < len; i++) {
176 else if (name[i] == '/')
181 /* ------------------------------------------------------------------------ */
183 unix_to_generic_filename(name, len)
189 for (i = 0; i < len; i++) {
192 else if (islower(name[i]))
193 name[i] = toupper(name[i]);
197 /* added by Koji Arai */
199 convert_filename(name, len, size,
201 from_delim, to_delim,
206 int from_code, to_code, case_to;
207 char *from_delim, *to_delim;
211 #ifdef MULTIBYTE_FILENAME
212 char tmp[256]; /* 256 is sizeof(LzHeader.name) */
214 if (from_code == CODE_SJIS && to_code == CODE_UTF8) {
215 for (i = 0; i < len; i++)
216 if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
217 sjis_to_utf8(tmp, name, sizeof(tmp));
218 strncpy(name, tmp, size);
221 for (i = 0; i < len; i++)
222 if (name[i] == '/') name[i] = LHA_PATHSEP;
223 from_code = CODE_UTF8;
225 else if (from_code == CODE_UTF8 && to_code == CODE_SJIS) {
226 for (i = 0; i < len; i++)
227 if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
228 utf8_to_sjis(tmp, name, sizeof(tmp));
229 strncpy(name, tmp, size);
232 for (i = 0; i < len; i++)
233 if (name[i] == '/') name[i] = LHA_PATHSEP;
234 from_code = CODE_SJIS;
238 for (i = 0; i < len; i ++) {
239 #ifdef MULTIBYTE_FILENAME
240 if (from_code == CODE_EUC &&
241 (unsigned char)name[i] == 0x8e) {
242 if (to_code != CODE_SJIS) {
248 memmove(name + i, name + i + 1, len - i);
252 if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
253 if (to_code != CODE_EUC) {
257 if (len == size - 1) /* check overflow */
259 memmove(name+i+1, name+i, len-i);
265 if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
267 if (to_code != CODE_SJIS) {
272 c1 = (unsigned char)name[i];
273 c2 = (unsigned char)name[i+1];
280 if (from_code == CODE_SJIS &&
281 SJC_FIRST_P(name[i]) &&
282 SJC_SECOND_P(name[i+1])) {
285 if (to_code != CODE_EUC) {
290 c1 = (unsigned char)name[i];
291 c2 = (unsigned char)name[i+1];
298 #endif /* MULTIBYTE_FILENAME */
302 /* transpose from_delim to to_delim */
304 if ((ptr = strchr(from_delim, name[i])) != NULL) {
305 name[i] = to_delim[ptr - from_delim];
310 if (case_to == TO_UPPER && islower(name[i])) {
311 name[i] = toupper(name[i]);
314 if (case_to == TO_LOWER && isupper(name[i])) {
315 name[i] = tolower(name[i]);
321 /* ------------------------------------------------------------------------ */
323 /* Generic stamp format: */
325 /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
326 /* |<-------- year ------->|<- month ->|<-- day -->| */
328 /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
329 /* |<--- hour --->|<---- minute --->|<- second*2 ->| */
331 /* ------------------------------------------------------------------------ */
334 * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
335 * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
339 #if defined(HAVE_MKTIME)
340 #ifdef HAVE_TIMELOCAL
341 #undef HAVE_TIMELOCAL
343 #endif /* defined(HAVE_MKTIME) */
345 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
349 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
351 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET)
357 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET) || defined(HAVE_FTIME)
358 #ifdef HAVE_GETTIMEOFDAY
359 #undef HAVE_GETTIMEOFDAY
362 #ifndef HAVE_GETTIMEOFDAY
363 #define HAVE_GETTIMEOFDAY /* use gettimeofday() */
368 #include <sys/timeb.h>
372 * You may define as : #define TIMEZONE_HOOK \ extern long
373 * timezone ; \ extern void tzset();
377 /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
380 #if defined(HAVE_TZSET) && defined(_MINIX)
381 extern long timezone; /* not defined in time.h */
384 /* ------------------------------------------------------------------------ */
385 #if defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) || defined(HAVE_TZSET)
395 /* ------------------------------------------------------------------------ */
396 #if !defined(HAVE_TZSET) && defined(HAVE_FTIME)
401 return buf.timezone * 60L;
405 /* ------------------------------------------------------------------------ */
406 #if !defined(HAVE_TZSET) && !defined(HAVE_FTIME) /* maybe defined(HAVE_GETTIMEOFDAY) */
408 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
412 return -localtime(&tt)->tm_gmtoff;
413 #else /* HAVE_STRUCT_TM_TM_GMTOFF */
416 gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
418 * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
421 return (tzp.tz_minuteswest * 60L);
422 #endif /* HAVE_STRUCT_TM_TM_GMTOFF */
425 #endif /* defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) ||
426 * defined(HAVE_TZSET) */
428 /* ------------------------------------------------------------------------ */
431 msdos_to_unix_stamp_tm(a)
436 t.tm_sec = (a & 0x1f) * 2;
437 t.tm_min = (a >> 5) & 0x3f;
438 t.tm_hour = (a >> 11) & 0x1f;
439 t.tm_mday = (a >> 16) & 0x1f;
440 t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
441 t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
446 /* ------------------------------------------------------------------------ */
448 generic_to_unix_stamp(t)
450 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
455 * special case: if MSDOS format date and time were zero, then we
456 * set time to be zero here too.
461 dostm.tm_sec = (t & 0x1f) * 2;
462 dostm.tm_min = t >> 5 & 0x3f;
463 dostm.tm_hour = t >> 11 & 0x1f;
464 dostm.tm_mday = t >> 16 & 0x1f;
465 dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1; /* 0..11 */
466 dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
468 dostm.tm_isdst = 0; /* correct? */
470 dostm.tm_isdst = -1; /* correct? */
472 return (time_t) mktime(&dostm);
473 #else /* maybe defined(HAVE_TIMELOCAL) */
474 return (time_t) timelocal(&dostm);
478 #else /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
480 int year, month, day, hour, min, sec;
482 static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
483 181, 212, 243, 273, 304, 334};
487 * special case: if MSDOS format date and time were zero, then we
488 * set time to be zero here too.
493 year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
494 month = (int) (t >> 16 + 5) & 0x0f; /* 1..12 means Jan..Dec */
495 day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
497 hour = ((int) t >> 11) & 0x1f;
498 min = ((int) t >> 5) & 0x3f;
499 sec = ((int) t & 0x1f) * 2;
501 /* Calculate days since 1970.01.01 */
502 days = (365 * (year - 1970) + /* days due to whole years */
503 (year - 1970 + 1) / 4 + /* days due to leap years */
504 dsboy[month - 1] + /* days since beginning of this year */
505 day - 1); /* days since beginning of month */
507 if ((year % 4 == 0) &&
508 (year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
509 (month >= 3)) /* if this is a leap year and month */
510 days++; /* is March or later, add a day */
512 /* Knowing the days, we can find seconds */
513 longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
514 longtime += gettz(); /* adjust for timezone */
516 /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
517 return (time_t) longtime;
519 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
521 /* ------------------------------------------------------------------------ */
523 unix_to_generic_stamp(t)
526 struct tm *tm = localtime(&t);
528 return ((((long) (tm->tm_year - 80)) << 25) +
529 (((long) (tm->tm_mon + 1)) << 21) +
530 (((long) tm->tm_mday) << 16) +
531 (long) ((tm->tm_hour << 11) +
536 /* ------------------------------------------------------------------------ */
537 /* build header functions */
538 /* ------------------------------------------------------------------------ */
542 register LzHeader *hdr;
546 char data[LZHEADER_STRAGE];
547 char dirname[FILENAME_LENGTH];
555 int archive_kanji_code = CODE_SJIS;
556 int system_kanji_code = default_system_kanji_code;
557 char *archive_delim = "";
558 char *system_delim = "";
559 int filename_case = NONE;
561 memset(hdr, 0, sizeof(LzHeader));
563 if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
564 return FALSE; /* finish */
567 if (fread(data + I_HEADER_CHECKSUM,
568 sizeof(char), header_size - 1, fp) < header_size - 1) {
569 fatal_error("Invalid header (LHarc file ?)");
570 return FALSE; /* finish */
572 setup_get(data + I_HEADER_LEVEL);
573 hdr->header_level = get_byte();
574 if (hdr->header_level != 2 &&
575 fread(data + header_size, sizeof(char), 2, fp) < 2) {
576 fatal_error("Invalid header (LHarc file ?)");
577 return FALSE; /* finish */
580 if (hdr->header_level >= 3) {
581 fatal_error("Unknown level header (level %d)", hdr->header_level);
585 setup_get(data + I_HEADER_CHECKSUM);
586 checksum = get_byte();
588 if (hdr->header_level == 2) {
589 hdr->header_size = header_size + checksum*256;
591 hdr->header_size = header_size;
593 memcpy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
594 setup_get(data + I_PACKED_SIZE);
595 hdr->packed_size = get_longword();
596 hdr->original_size = get_longword();
597 hdr->last_modified_stamp = get_longword();
598 hdr->attribute = get_byte();
600 if ((hdr->header_level = get_byte()) != 2) {
601 if (calc_sum(data + I_METHOD, header_size) != checksum)
602 warning("Checksum error (LHarc file?)");
603 name_length = get_byte();
604 for (i = 0; i < name_length; i++)
605 hdr->name[i] = (char) get_byte();
606 hdr->name[name_length] = '\0';
609 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
613 /* defaults for other type */
614 hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
618 if (hdr->header_level == 0) {
619 extend_size = header_size - name_length -22;
620 if (extend_size < 0) {
621 if (extend_size == -2) {
622 hdr->extend_type = EXTEND_GENERIC;
623 hdr->has_crc = FALSE;
625 error("Unkonwn header (lha file?)");
630 hdr->crc = get_word();
633 if (extend_size >= 1) {
634 hdr->extend_type = get_byte();
637 if (hdr->extend_type == EXTEND_UNIX) {
638 if (extend_size >= 11) {
639 hdr->minor_version = get_byte();
640 hdr->unix_last_modified_stamp = (time_t) get_longword();
641 hdr->unix_mode = get_word();
642 hdr->unix_uid = get_word();
643 hdr->unix_gid = get_word();
646 hdr->extend_type = EXTEND_GENERIC;
649 while (extend_size-- > 0)
651 if (hdr->extend_type == EXTEND_UNIX)
653 } else if (hdr->header_level == 1) {
655 extend_size = header_size - name_length-25;
656 hdr->crc = get_word();
657 hdr->extend_type = get_byte();
658 while (extend_size-- > 0)
660 } else { /* level 2 */
662 hdr->crc = get_word();
663 hdr->extend_type = get_byte();
666 if (hdr->header_level > 0) {
668 if (hdr->header_level != 2)
669 setup_get(data + hdr->header_size);
671 while ((header_size = get_word()) != 0) {
672 if (hdr->header_level != 2 &&
673 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
674 fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
675 fatal_error("Invalid header (LHa file ?)");
678 switch (get_byte()) {
683 setup_get(get_ptr + header_size - 3);
689 for (i = 0; i < header_size - 3; i++)
690 hdr->name[i] = (char) get_byte();
691 hdr->name[header_size - 3] = '\0';
692 name_length = header_size - 3;
698 for (i = 0; i < header_size - 3; i++)
699 dirname[i] = (char) get_byte();
700 dirname[header_size - 3] = '\0';
701 dir_length = header_size - 3;
707 if (hdr->extend_type == EXTEND_MSDOS ||
708 hdr->extend_type == EXTEND_HUMAN ||
709 hdr->extend_type == EXTEND_GENERIC)
710 hdr->attribute = get_word();
716 if (hdr->extend_type == EXTEND_UNIX)
717 hdr->unix_mode = get_word();
723 if (hdr->extend_type == EXTEND_UNIX) {
724 hdr->unix_gid = get_word();
725 hdr->unix_uid = get_word();
732 for (i = 0; i < header_size - 3; i++)
733 hdr->group[i] = get_byte();
734 hdr->group[i] = '\0';
740 for (i = 0; i < header_size - 3; i++)
741 hdr->user[i] = get_byte();
746 * UNIX last modified time
748 if (hdr->extend_type == EXTEND_UNIX)
749 hdr->unix_last_modified_stamp = (time_t) get_longword();
755 setup_get(get_ptr + header_size - 3);
759 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
760 hdr->packed_size -= get_ptr - ptr - 2;
761 hdr->header_size += get_ptr - ptr - 2;
765 switch (hdr->extend_type) {
767 archive_delim = "\xff\\";
769 filename_case = noconvertcase ? NONE : TO_LOWER;
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);
785 archive_delim = "\xff";
787 filename_case = NONE;
792 archive_delim = "\xff/:";
793 system_delim = "/:/";
794 filename_case = NONE;
796 hdr->unix_last_modified_stamp =
797 generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
801 archive_delim = "\xff\\";
803 filename_case = noconvertcase ? NONE : TO_LOWER;
804 /* FIXME: if small letter is included in filename,
805 the generic_to_unix_filename() do not case conversion,
806 but this code does not consider it. */
808 if (hdr->header_level == 2)
809 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
811 hdr->unix_last_modified_stamp =
812 generic_to_unix_stamp(hdr->last_modified_stamp);
815 /* filename kanji code and delimiter conversion */
816 if (optional_archive_kanji_code)
817 archive_kanji_code = optional_archive_kanji_code;
818 if (optional_system_kanji_code)
819 system_kanji_code = optional_system_kanji_code;
820 if (optional_archive_delim)
821 archive_delim = optional_archive_delim;
822 if (optional_system_delim)
823 system_delim = optional_system_delim;
824 if (optional_filename_case)
825 filename_case = optional_filename_case;
828 strcat(dirname, hdr->name);
829 strcpy(hdr->name, dirname);
830 name_length += dir_length;
833 convert_filename(hdr->name, name_length, sizeof(hdr->name),
836 archive_delim, system_delim, filename_case);
841 /* ------------------------------------------------------------------------ */
843 init_header(name, v_stat, hdr)
850 int system_kanji_code = default_system_kanji_code;
851 char *archive_delim = "";
852 char *system_delim = "";
853 int filename_case = NONE;
855 memset(hdr, 0, sizeof(LzHeader));
857 if (optional_system_kanji_code)
858 system_kanji_code = optional_system_kanji_code;
860 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
861 memcpy(hdr->method, LZHUFF5_METHOD, METHOD_TYPE_STRAGE);
862 else if (compress_method)
863 memcpy(hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE);
865 memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE);
867 hdr->packed_size = 0;
868 hdr->original_size = v_stat->st_size;
869 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
870 hdr->attribute = GENERIC_ATTRIBUTE;
871 hdr->header_level = header_level;
872 strcpy(hdr->name, name);
875 hdr->extend_type = EXTEND_UNIX;
876 hdr->unix_last_modified_stamp = v_stat->st_mtime;
877 /* since 00:00:00 JAN.1.1970 */
878 #ifdef NOT_COMPATIBLE_MODE
879 /* Please need your modification in this space. */
881 hdr->unix_mode = v_stat->st_mode;
884 hdr->unix_uid = v_stat->st_uid;
885 hdr->unix_gid = v_stat->st_gid;
887 #if INCLUDE_OWNER_NAME_IN_HEADER
890 struct passwd *ent = getpwuid(hdr->unix_uid);
893 strncpy(hdr->user, ent->pw_name, sizeof(hdr->user));
894 if (hdr->user[sizeof(hdr->user)-1])
895 hdr->user[sizeof(hdr->user)-1] = 0;
901 struct group *ent = getgrgid(hdr->unix_gid);
904 strncpy(hdr->group, ent->gr_name, sizeof(hdr->group));
905 if (hdr->group[sizeof(hdr->group)-1])
906 hdr->group[sizeof(hdr->group)-1] = 0;
910 #endif /* INCLUDE_OWNER_NAME_IN_HEADER */
911 if (is_directory(v_stat)) {
912 memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
913 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
914 hdr->original_size = 0;
915 if (len > 0 && hdr->name[len - 1] != '/')
916 strcpy(&hdr->name[len++], "/");
920 if (is_symlink(v_stat)) {
921 char lkname[256]; /* FIXME: no enough space */
923 memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
924 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
925 hdr->original_size = 0;
926 len = readlink(name, lkname, sizeof(lkname));
927 if (xsnprintf(hdr->name, sizeof(hdr->name),
928 "%s|%.*s", hdr->name, len, lkname) == -1)
929 error("file name is too long (%s -> %.*s)", hdr->name, len, lkname);
933 if (generic_format) {
934 filename_case = TO_UPPER;
935 archive_delim = "\\";
938 convert_filename(hdr->name, len, sizeof(hdr->name),
940 system_kanji_code, /* no change code */
941 system_delim, archive_delim, filename_case);
944 /* ------------------------------------------------------------------------ */
945 /* Write unix extended header or generic header. */
947 write_header(nafp, hdr)
953 char data[LZHEADER_STRAGE];
956 int archive_kanji_code = CODE_SJIS;
957 int system_kanji_code = default_system_kanji_code;
960 if (optional_archive_kanji_code)
961 archive_kanji_code = optional_archive_kanji_code;
962 if (optional_system_kanji_code)
963 system_kanji_code = optional_system_kanji_code;
965 memset(data, 0, LZHEADER_STRAGE);
966 memcpy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
967 setup_put(data + I_PACKED_SIZE);
968 put_longword(hdr->packed_size);
969 put_longword(hdr->original_size);
971 if (hdr->header_level == HEADER_LEVEL2)
972 put_longword((long) hdr->unix_last_modified_stamp);
974 put_longword(hdr->last_modified_stamp);
976 switch (hdr->header_level) {
978 put_byte(hdr->attribute);
986 put_byte(hdr->header_level);
988 strncpy(lzname, hdr->name, sizeof(lzname));
989 convert_filename(lzname, strlen(lzname), sizeof(lzname),
992 "\xff\\/", "\xff\xff\xff", NONE);
994 if (hdr->header_level != HEADER_LEVEL2) {
995 if (p = (char *) strrchr(lzname, LHA_PATHSEP))
996 name_length = strlen(++p);
998 name_length = strlen(lzname);
999 put_byte(name_length);
1000 memcpy(data + I_NAME, p ? p : lzname, name_length);
1001 setup_put(data + I_NAME + name_length);
1005 if (header_level == HEADER_LEVEL0) {
1006 if (generic_format) {
1007 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
1008 data[I_HEADER_SIZE] = header_size;
1009 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1011 /* write old-style extend header */
1012 put_byte(EXTEND_UNIX);
1013 put_byte(CURRENT_UNIX_MINOR_VERSION);
1014 put_longword((long) hdr->unix_last_modified_stamp);
1015 put_word(hdr->unix_mode);
1016 put_word(hdr->unix_uid);
1017 put_word(hdr->unix_gid);
1018 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
1019 data[I_HEADER_SIZE] = header_size;
1020 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1023 /* write extend header. */
1029 put_byte(EXTEND_UNIX);
1032 if (hdr->header_level == HEADER_LEVEL2) {
1033 /* write common header */
1036 headercrc_ptr = put_ptr;
1040 if (generic_format) {
1041 header_size = put_ptr - data; /* +2 for last 0x0000 */
1044 if (hdr->header_level == HEADER_LEVEL1)
1045 header_size = put_ptr - data - 2;
1046 put_byte(0x50); /* permission */
1047 put_word(hdr->unix_mode);
1049 put_byte(0x51); /* gid and uid */
1050 put_word(hdr->unix_gid);
1051 put_word(hdr->unix_uid);
1054 int i, len = strlen(hdr->group);
1056 put_byte(0x52); /* group name */
1057 for (i = 0; i < len; i++)
1058 put_byte(hdr->group[i]);
1060 len = strlen(hdr->user);
1062 put_byte(0x53); /* user name */
1063 for (i = 0; i < len; i++)
1064 put_byte(hdr->user[i]);
1067 if (p = (char *) strrchr(lzname, LHA_PATHSEP)) {
1070 name_length = p - lzname + 1;
1071 put_word(name_length + 3);
1072 put_byte(2); /* dirname */
1073 for (i = 0; i < name_length; i++)
1074 put_byte(lzname[i]);
1076 } /* if generic .. */
1078 if (header_level != HEADER_LEVEL2) {
1079 if (!generic_format) {
1081 put_byte(0x54); /* time stamp */
1082 put_longword(hdr->unix_last_modified_stamp);
1084 hdr->packed_size += put_ptr - ptr;
1086 setup_put(data + I_PACKED_SIZE);
1087 put_longword(hdr->packed_size);
1089 data[I_HEADER_SIZE] = header_size;
1090 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1091 } else { /* header level 2 */
1093 if (p = (char *) strrchr(lzname, LHA_PATHSEP))
1094 name_length = strlen(++p);
1097 name_length = strlen(lzname);
1099 put_word(name_length + 3);
1100 put_byte(1); /* filename */
1101 for (i = 0; i < name_length; i++)
1103 } /* if he.. != HEAD_LV2 */
1104 header_size = put_ptr - data;
1107 if (header_level == HEADER_LEVEL2) {
1108 unsigned short hcrc;
1109 setup_put(data + I_HEADER_SIZE);
1110 put_word(header_size + 2);
1112 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1113 setup_put(headercrc_ptr);
1117 if (fwrite(data, header_size + 2, 1, nafp) == 0)
1118 fatal_error("Cannot write to temporary file");
1122 /* this is not need for Mac OS X v 10.2 later */
1124 kCFStringEncodingAllowLossyConversion = 1,
1125 kCFStringEncodingBasicDirectionLeftToRight = (1 << 1),
1126 kCFStringEncodingBasicDirectionRightToLeft = (1 << 2),
1127 kCFStringEncodingSubstituteCombinings = (1 << 3),
1128 kCFStringEncodingComposeCombinings = (1 << 4),
1129 kCFStringEncodingIgnoreCombinings = (1 << 5),
1130 kCFStringEncodingUseCanonical = (1 << 6),
1131 kCFStringEncodingUseHFSPlusCanonical = (1 << 7),
1132 kCFStringEncodingPrependBOM = (1 << 8),
1133 kCFStringEncodingDisableCorporateArea = (1 << 9),
1134 kCFStringEncodingASCIICompatibleConversion = (1 << 10),
1138 ConvertEncodingToUTF8(const char* inCStr,
1139 char* outUTF8Buffer,
1140 int outUTF8BufferLength,
1141 unsigned long scriptEncoding,
1142 unsigned long flags)
1144 unsigned long unicodeChars;
1145 unsigned long srcCharsUsed;
1146 unsigned long usedByteLen = 0;
1147 UniChar uniStr[512];
1148 unsigned long cfResult;
1150 cfResult = CFStringEncodingBytesToUnicode(scriptEncoding,
1158 if (cfResult == 0) {
1159 cfResult = CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8,
1164 (char*)outUTF8Buffer,
1165 outUTF8BufferLength - 1,
1167 outUTF8Buffer[usedByteLen] = '\0';
1174 ConvertUTF8ToEncoding(const char* inUTF8Buf,
1175 int inUTF8BufLength,
1176 char* outCStrBuffer,
1177 int outCStrBufferLength,
1178 unsigned long scriptEncoding,
1179 unsigned long flags)
1181 unsigned long unicodeChars;
1182 unsigned long srcCharsUsed;
1183 unsigned long usedByteLen = 0;
1184 UniChar uniStr[256];
1185 unsigned long cfResult;
1187 cfResult = CFStringEncodingBytesToUnicode(kCFStringEncodingUTF8,
1195 if (cfResult == 0) {
1196 cfResult = CFStringEncodingUnicodeToBytes(scriptEncoding,
1201 (char*)outCStrBuffer,
1202 outCStrBufferLength - 1,
1204 outCStrBuffer[usedByteLen] = '\0';
1209 #endif /* __APPLE__ */
1212 sjis_to_utf8(char *dst, const char *src, size_t dstsize)
1216 ConvertEncodingToUTF8(src, dst, dstsize,
1217 kCFStringEncodingDOSJapanese,
1218 kCFStringEncodingUseHFSPlusCanonical);
1227 utf8_to_sjis(char *dst, const char *src, size_t dstsize)
1233 srclen = strlen(src);
1234 ConvertUTF8ToEncoding(src, srclen, dst, dstsize,
1235 kCFStringEncodingDOSJapanese,
1236 kCFStringEncodingUseHFSPlusCanonical);
1244 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1245 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1246 * ¤è¤êÈ´¿è(by Koji Arai)
1249 euc2sjis(int *p1, int *p2)
1251 unsigned char c1 = *p1 & 0x7f;
1252 unsigned char c2 = *p2 & 0x7f;
1253 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1254 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1255 *p1 = ((c1 + 1) >> 1) + rowoff;
1256 *p2 += celoff - 0x80;
1260 sjis2euc(int *p1, int *p2)
1262 unsigned char c1 = *p1;
1263 unsigned char c2 = *p2;
1264 int adjust = c2 < 0x9f;
1265 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1266 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1267 *p1 = ((c1 - rowoff) << 1) - adjust;
1274 /* Local Variables: */
1277 /* compile-command:"gcc -c header.c" */
1279 /* vi: set tabstop=4: */