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 #if !STRCHR_8BIT_CLEAN
22 /* should use 8 bit clean version */
25 #define strchr xstrchr
26 #define strrchr xstrrchr
29 /* ------------------------------------------------------------------------ */
32 int optional_archive_kanji_code = NONE;
33 int optional_system_kanji_code = NONE;
34 char *optional_archive_delim = NULL;
35 char *optional_system_delim = NULL;
36 int optional_filename_case = NONE;
38 #ifdef MULTIBYTE_FILENAME
39 int default_system_kanji_code = MULTIBYTE_FILENAME;
41 int default_system_kanji_code = NONE;
44 /* ------------------------------------------------------------------------ */
52 for (sum = 0; len; len--)
58 /* ------------------------------------------------------------------------ */
66 return (b1 << 8) + b0;
69 /* ------------------------------------------------------------------------ */
78 /* ------------------------------------------------------------------------ */
88 return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
91 /* ------------------------------------------------------------------------ */
102 /* ------------------------------------------------------------------------ */
104 msdos_to_unix_filename(name, len)
110 #ifdef MULTIBYTE_FILENAME
111 for (i = 0; i < len; i++) {
112 if (MULTIBYTE_FIRST_P(name[i]) &&
113 MULTIBYTE_SECOND_P(name[i + 1]))
115 else if (name[i] == '\\')
117 else if (!noconvertcase && isupper(name[i]))
118 name[i] = tolower(name[i]);
121 for (i = 0; i < len; i++) {
124 else if (!noconvertcase && isupper(name[i]))
125 name[i] = tolower(name[i]);
130 /* ------------------------------------------------------------------------ */
132 generic_to_unix_filename(name, len)
137 boolean lower_case_used = FALSE;
139 #ifdef MULTIBYTE_FILENAME
140 for (i = 0; i < len; i++) {
141 if (MULTIBYTE_FIRST_P(name[i]) &&
142 MULTIBYTE_SECOND_P(name[i + 1]))
144 else if (islower(name[i])) {
145 lower_case_used = TRUE;
149 for (i = 0; i < len; i++) {
150 if (MULTIBYTE_FIRST_P(name[i]) &&
151 MULTIBYTE_SECOND_P(name[i + 1]))
153 else if (name[i] == '\\')
155 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
156 name[i] = tolower(name[i]);
159 for (i = 0; i < len; i++)
160 if (islower(name[i])) {
161 lower_case_used = TRUE;
164 for (i = 0; i < len; i++) {
167 else if (!noconvertcase && !lower_case_used && isupper(name[i]))
168 name[i] = tolower(name[i]);
173 /* ------------------------------------------------------------------------ */
175 macos_to_unix_filename(name, len)
181 for (i = 0; i < len; i++) {
184 else if (name[i] == '/')
189 /* ------------------------------------------------------------------------ */
191 unix_to_generic_filename(name, len)
197 for (i = 0; i < len; i++) {
200 else if (islower(name[i]))
201 name[i] = toupper(name[i]);
205 /* added by Koji Arai */
207 convert_filename(name, len, size,
209 from_delim, to_delim,
214 int from_code, to_code, case_to;
215 char *from_delim, *to_delim;
219 #ifdef MULTIBYTE_FILENAME
220 char tmp[256]; /* 256 is sizeof(LzHeader.name) */
222 if (from_code == CODE_SJIS && to_code == CODE_UTF8) {
223 for (i = 0; i < len; i++)
224 if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
225 sjis_to_utf8(tmp, name, sizeof(tmp));
226 strncpy(name, tmp, size);
229 for (i = 0; i < len; i++)
230 if (name[i] == '/') name[i] = LHA_PATHSEP;
231 from_code = CODE_UTF8;
233 else if (from_code == CODE_UTF8 && to_code == CODE_SJIS) {
234 for (i = 0; i < len; i++)
235 if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
236 utf8_to_sjis(tmp, name, sizeof(tmp));
237 strncpy(name, tmp, size);
240 for (i = 0; i < len; i++)
241 if (name[i] == '/') name[i] = LHA_PATHSEP;
242 from_code = CODE_SJIS;
246 for (i = 0; i < len; i ++) {
247 #ifdef MULTIBYTE_FILENAME
248 if (from_code == CODE_EUC &&
249 (unsigned char)name[i] == 0x8e) {
250 if (to_code != CODE_SJIS) {
256 memmove(name + i, name + i + 1, len - i);
260 if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
261 if (to_code != CODE_EUC) {
265 if (len == size - 1) /* check overflow */
267 memmove(name+i+1, name+i, len-i);
273 if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
275 if (to_code != CODE_SJIS) {
280 c1 = (unsigned char)name[i];
281 c2 = (unsigned char)name[i+1];
288 if (from_code == CODE_SJIS &&
289 SJC_FIRST_P(name[i]) &&
290 SJC_SECOND_P(name[i+1])) {
293 if (to_code != CODE_EUC) {
298 c1 = (unsigned char)name[i];
299 c2 = (unsigned char)name[i+1];
306 #endif /* MULTIBYTE_FILENAME */
310 /* transpose from_delim to to_delim */
312 if ((ptr = strchr(from_delim, name[i])) != NULL) {
313 name[i] = to_delim[ptr - from_delim];
318 if (case_to == TO_UPPER && islower(name[i])) {
319 name[i] = toupper(name[i]);
322 if (case_to == TO_LOWER && isupper(name[i])) {
323 name[i] = tolower(name[i]);
329 /* ------------------------------------------------------------------------ */
331 /* Generic stamp format: */
333 /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
334 /* |<-------- year ------->|<- month ->|<-- day -->| */
336 /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
337 /* |<--- hour --->|<---- minute --->|<- second*2 ->| */
339 /* ------------------------------------------------------------------------ */
342 * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
343 * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
347 #if defined(HAVE_MKTIME)
348 #ifdef HAVE_TIMELOCAL
349 #undef HAVE_TIMELOCAL
351 #endif /* defined(HAVE_MKTIME) */
353 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
357 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
359 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET)
365 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) || defined(HAVE_TZSET) || defined(HAVE_FTIME)
366 #ifdef HAVE_GETTIMEOFDAY
367 #undef HAVE_GETTIMEOFDAY
370 #ifndef HAVE_GETTIMEOFDAY
371 #define HAVE_GETTIMEOFDAY /* use gettimeofday() */
376 #include <sys/timeb.h>
380 * You may define as : #define TIMEZONE_HOOK \ extern long
381 * timezone ; \ extern void tzset();
385 /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
388 #if defined(HAVE_TZSET) && defined(_MINIX)
389 extern long timezone; /* not defined in time.h */
392 /* ------------------------------------------------------------------------ */
393 #if defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) || defined(HAVE_TZSET)
403 /* ------------------------------------------------------------------------ */
404 #if !defined(HAVE_TZSET) && defined(HAVE_FTIME)
409 return buf.timezone * 60L;
413 /* ------------------------------------------------------------------------ */
414 #if !defined(HAVE_TZSET) && !defined(HAVE_FTIME) /* maybe defined(HAVE_GETTIMEOFDAY) */
416 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
420 return -localtime(&tt)->tm_gmtoff;
421 #else /* HAVE_STRUCT_TM_TM_GMTOFF */
424 gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
426 * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
429 return (tzp.tz_minuteswest * 60L);
430 #endif /* HAVE_STRUCT_TM_TM_GMTOFF */
433 #endif /* defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) ||
434 * defined(HAVE_TZSET) */
436 /* ------------------------------------------------------------------------ */
439 msdos_to_unix_stamp_tm(a)
444 t.tm_sec = (a & 0x1f) * 2;
445 t.tm_min = (a >> 5) & 0x3f;
446 t.tm_hour = (a >> 11) & 0x1f;
447 t.tm_mday = (a >> 16) & 0x1f;
448 t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
449 t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
454 /* ------------------------------------------------------------------------ */
456 generic_to_unix_stamp(t)
458 #if defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL)
463 * special case: if MSDOS format date and time were zero, then we
464 * set time to be zero here too.
469 dostm.tm_sec = (t & 0x1f) * 2;
470 dostm.tm_min = t >> 5 & 0x3f;
471 dostm.tm_hour = t >> 11 & 0x1f;
472 dostm.tm_mday = t >> 16 & 0x1f;
473 dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1; /* 0..11 */
474 dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
476 dostm.tm_isdst = 0; /* correct? */
478 dostm.tm_isdst = -1; /* correct? */
480 return (time_t) mktime(&dostm);
481 #else /* maybe defined(HAVE_TIMELOCAL) */
482 return (time_t) timelocal(&dostm);
486 #else /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
488 int year, month, day, hour, min, sec;
490 static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
491 181, 212, 243, 273, 304, 334};
495 * special case: if MSDOS format date and time were zero, then we
496 * set time to be zero here too.
501 year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
502 month = (int) (t >> 16 + 5) & 0x0f; /* 1..12 means Jan..Dec */
503 day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
505 hour = ((int) t >> 11) & 0x1f;
506 min = ((int) t >> 5) & 0x3f;
507 sec = ((int) t & 0x1f) * 2;
509 /* Calculate days since 1970.01.01 */
510 days = (365 * (year - 1970) + /* days due to whole years */
511 (year - 1970 + 1) / 4 + /* days due to leap years */
512 dsboy[month - 1] + /* days since beginning of this year */
513 day - 1); /* days since beginning of month */
515 if ((year % 4 == 0) &&
516 (year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
517 (month >= 3)) /* if this is a leap year and month */
518 days++; /* is March or later, add a day */
520 /* Knowing the days, we can find seconds */
521 longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
522 longtime += gettz(); /* adjust for timezone */
524 /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
525 return (time_t) longtime;
527 #endif /* defined(HAVE_MKTIME) || defined(HAVE_TIMELOCAL) */
529 /* ------------------------------------------------------------------------ */
531 unix_to_generic_stamp(t)
534 struct tm *tm = localtime(&t);
536 return ((((long) (tm->tm_year - 80)) << 25) +
537 (((long) (tm->tm_mon + 1)) << 21) +
538 (((long) tm->tm_mday) << 16) +
539 (long) ((tm->tm_hour << 11) +
544 /* ------------------------------------------------------------------------ */
545 /* build header functions */
546 /* ------------------------------------------------------------------------ */
550 register LzHeader *hdr;
554 char data[LZHEADER_STRAGE];
555 char dirname[FILENAME_LENGTH];
563 int archive_kanji_code = CODE_SJIS;
564 int system_kanji_code = default_system_kanji_code;
565 char *archive_delim = "";
566 char *system_delim = "";
567 int filename_case = NONE;
569 memset(hdr, 0, sizeof(LzHeader));
571 if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
572 return FALSE; /* finish */
575 if (fread(data + I_HEADER_CHECKSUM,
576 sizeof(char), header_size - 1, fp) < header_size - 1) {
577 fatal_error("Invalid header (LHarc file ?)");
578 return FALSE; /* finish */
580 setup_get(data + I_HEADER_LEVEL);
581 hdr->header_level = get_byte();
582 if (hdr->header_level != 2 &&
583 fread(data + header_size, sizeof(char), 2, fp) < 2) {
584 fatal_error("Invalid header (LHarc file ?)");
585 return FALSE; /* finish */
588 if (hdr->header_level >= 3) {
589 fatal_error("Unknown level header (level %d)", hdr->header_level);
593 setup_get(data + I_HEADER_CHECKSUM);
594 checksum = get_byte();
596 if (hdr->header_level == 2) {
597 hdr->header_size = header_size + checksum*256;
599 hdr->header_size = header_size;
601 memcpy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
602 setup_get(data + I_PACKED_SIZE);
603 hdr->packed_size = get_longword();
604 hdr->original_size = get_longword();
605 hdr->last_modified_stamp = get_longword();
606 hdr->attribute = get_byte();
608 if ((hdr->header_level = get_byte()) != 2) {
609 if (calc_sum(data + I_METHOD, header_size) != checksum)
610 warning("Checksum error (LHarc file?)");
611 name_length = get_byte();
612 for (i = 0; i < name_length; i++)
613 hdr->name[i] = (char) get_byte();
614 hdr->name[name_length] = '\0';
617 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
621 /* defaults for other type */
622 hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
626 if (hdr->header_level == 0) {
627 extend_size = header_size - name_length -22;
628 if (extend_size < 0) {
629 if (extend_size == -2) {
630 hdr->extend_type = EXTEND_GENERIC;
631 hdr->has_crc = FALSE;
633 error("Unkonwn header (lha file?)");
638 hdr->crc = get_word();
641 if (extend_size >= 1) {
642 hdr->extend_type = get_byte();
645 if (hdr->extend_type == EXTEND_UNIX) {
646 if (extend_size >= 11) {
647 hdr->minor_version = get_byte();
648 hdr->unix_last_modified_stamp = (time_t) get_longword();
649 hdr->unix_mode = get_word();
650 hdr->unix_uid = get_word();
651 hdr->unix_gid = get_word();
654 hdr->extend_type = EXTEND_GENERIC;
657 while (extend_size-- > 0)
659 if (hdr->extend_type == EXTEND_UNIX)
661 } else if (hdr->header_level == 1) {
663 extend_size = header_size - name_length-25;
664 hdr->crc = get_word();
665 hdr->extend_type = get_byte();
666 while (extend_size-- > 0)
668 } else { /* level 2 */
670 hdr->crc = get_word();
671 hdr->extend_type = get_byte();
674 if (hdr->header_level > 0) {
676 if (hdr->header_level != 2)
677 setup_get(data + hdr->header_size);
679 while ((header_size = get_word()) != 0) {
680 if (hdr->header_level != 2 &&
681 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
682 fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
683 fatal_error("Invalid header (LHa file ?)");
686 switch (get_byte()) {
691 setup_get(get_ptr + header_size - 3);
697 for (i = 0; i < header_size - 3; i++)
698 hdr->name[i] = (char) get_byte();
699 hdr->name[header_size - 3] = '\0';
700 name_length = header_size - 3;
706 for (i = 0; i < header_size - 3; i++)
707 dirname[i] = (char) get_byte();
708 dirname[header_size - 3] = '\0';
709 dir_length = header_size - 3;
715 if (hdr->extend_type == EXTEND_MSDOS ||
716 hdr->extend_type == EXTEND_HUMAN ||
717 hdr->extend_type == EXTEND_GENERIC)
718 hdr->attribute = get_word();
724 if (hdr->extend_type == EXTEND_UNIX)
725 hdr->unix_mode = get_word();
731 if (hdr->extend_type == EXTEND_UNIX) {
732 hdr->unix_gid = get_word();
733 hdr->unix_uid = get_word();
740 for (i = 0; i < header_size - 3; i++)
741 hdr->group[i] = get_byte();
742 hdr->group[i] = '\0';
748 for (i = 0; i < header_size - 3; i++)
749 hdr->user[i] = get_byte();
754 * UNIX last modified time
756 if (hdr->extend_type == EXTEND_UNIX)
757 hdr->unix_last_modified_stamp = (time_t) get_longword();
763 setup_get(get_ptr + header_size - 3);
767 if (hdr->header_level != 2 && get_ptr - ptr != 2) {
768 hdr->packed_size -= get_ptr - ptr - 2;
769 hdr->header_size += get_ptr - ptr - 2;
773 switch (hdr->extend_type) {
775 archive_delim = "\xff\\";
777 filename_case = noconvertcase ? NONE : TO_LOWER;
781 if (hdr->header_level == 2)
782 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
784 hdr->unix_last_modified_stamp =
785 generic_to_unix_stamp(hdr->last_modified_stamp);
793 archive_delim = "\xff";
795 filename_case = NONE;
800 archive_delim = "\xff/:";
801 system_delim = "/:/";
802 filename_case = NONE;
804 hdr->unix_last_modified_stamp =
805 generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
809 archive_delim = "\xff\\";
811 filename_case = noconvertcase ? NONE : TO_LOWER;
812 /* FIXME: if small letter is included in filename,
813 the generic_to_unix_filename() do not case conversion,
814 but this code does not consider it. */
816 if (hdr->header_level == 2)
817 hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
819 hdr->unix_last_modified_stamp =
820 generic_to_unix_stamp(hdr->last_modified_stamp);
823 /* filename kanji code and delimiter conversion */
824 if (optional_archive_kanji_code)
825 archive_kanji_code = optional_archive_kanji_code;
826 if (optional_system_kanji_code)
827 system_kanji_code = optional_system_kanji_code;
828 if (optional_archive_delim)
829 archive_delim = optional_archive_delim;
830 if (optional_system_delim)
831 system_delim = optional_system_delim;
832 if (optional_filename_case)
833 filename_case = optional_filename_case;
836 strcat(dirname, hdr->name);
837 strcpy(hdr->name, dirname);
838 name_length += dir_length;
841 convert_filename(hdr->name, name_length, sizeof(hdr->name),
844 archive_delim, system_delim, filename_case);
849 /* ------------------------------------------------------------------------ */
851 init_header(name, v_stat, hdr)
858 int system_kanji_code = default_system_kanji_code;
859 char *archive_delim = "";
860 char *system_delim = "";
861 int filename_case = NONE;
863 memset(hdr, 0, sizeof(LzHeader));
865 if (optional_system_kanji_code)
866 system_kanji_code = optional_system_kanji_code;
868 if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
869 memcpy(hdr->method, LZHUFF5_METHOD, METHOD_TYPE_STRAGE);
870 else if (compress_method)
871 memcpy(hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE);
873 memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE);
875 hdr->packed_size = 0;
876 hdr->original_size = v_stat->st_size;
877 hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
878 hdr->attribute = GENERIC_ATTRIBUTE;
879 hdr->header_level = header_level;
880 strcpy(hdr->name, name);
883 hdr->extend_type = EXTEND_UNIX;
884 hdr->unix_last_modified_stamp = v_stat->st_mtime;
885 /* since 00:00:00 JAN.1.1970 */
886 #ifdef NOT_COMPATIBLE_MODE
887 /* Please need your modification in this space. */
889 hdr->unix_mode = v_stat->st_mode;
892 hdr->unix_uid = v_stat->st_uid;
893 hdr->unix_gid = v_stat->st_gid;
895 #if INCLUDE_OWNER_NAME_IN_HEADER
898 struct passwd *ent = getpwuid(hdr->unix_uid);
901 strncpy(hdr->user, ent->pw_name, sizeof(hdr->user));
902 if (hdr->user[sizeof(hdr->user)-1])
903 hdr->user[sizeof(hdr->user)-1] = 0;
909 struct group *ent = getgrgid(hdr->unix_gid);
912 strncpy(hdr->group, ent->gr_name, sizeof(hdr->group));
913 if (hdr->group[sizeof(hdr->group)-1])
914 hdr->group[sizeof(hdr->group)-1] = 0;
918 #endif /* INCLUDE_OWNER_NAME_IN_HEADER */
919 if (is_directory(v_stat)) {
920 memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
921 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
922 hdr->original_size = 0;
923 if (len > 0 && hdr->name[len - 1] != '/')
924 strcpy(&hdr->name[len++], "/");
928 if (is_symlink(v_stat)) {
929 char lkname[256]; /* FIXME: no enough space */
931 memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
932 hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
933 hdr->original_size = 0;
934 len = readlink(name, lkname, sizeof(lkname));
935 if (xsnprintf(hdr->name, sizeof(hdr->name),
936 "%s|%.*s", hdr->name, len, lkname) == -1)
937 error("file name is too long (%s -> %.*s)", hdr->name, len, lkname);
941 if (generic_format) {
942 filename_case = TO_UPPER;
943 archive_delim = "\\";
946 convert_filename(hdr->name, len, sizeof(hdr->name),
948 system_kanji_code, /* no change code */
949 system_delim, archive_delim, filename_case);
952 /* ------------------------------------------------------------------------ */
953 /* Write unix extended header or generic header. */
955 write_header(nafp, hdr)
961 char data[LZHEADER_STRAGE];
964 int archive_kanji_code = CODE_SJIS;
965 int system_kanji_code = default_system_kanji_code;
968 if (optional_archive_kanji_code)
969 archive_kanji_code = optional_archive_kanji_code;
970 if (optional_system_kanji_code)
971 system_kanji_code = optional_system_kanji_code;
973 memset(data, 0, LZHEADER_STRAGE);
974 memcpy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
975 setup_put(data + I_PACKED_SIZE);
976 put_longword(hdr->packed_size);
977 put_longword(hdr->original_size);
979 if (hdr->header_level == HEADER_LEVEL2)
980 put_longword((long) hdr->unix_last_modified_stamp);
982 put_longword(hdr->last_modified_stamp);
984 switch (hdr->header_level) {
986 put_byte(hdr->attribute);
994 put_byte(hdr->header_level);
996 strncpy(lzname, hdr->name, sizeof(lzname));
997 convert_filename(lzname, strlen(lzname), sizeof(lzname),
1000 "\xff\\/", "\xff\xff\xff", NONE);
1002 if (hdr->header_level != HEADER_LEVEL2) {
1003 if (p = (char *) strrchr(lzname, LHA_PATHSEP))
1004 name_length = strlen(++p);
1006 name_length = strlen(lzname);
1007 put_byte(name_length);
1008 memcpy(data + I_NAME, p ? p : lzname, name_length);
1009 setup_put(data + I_NAME + name_length);
1013 if (header_level == HEADER_LEVEL0) {
1014 if (generic_format) {
1015 header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
1016 data[I_HEADER_SIZE] = header_size;
1017 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1019 /* write old-style extend header */
1020 put_byte(EXTEND_UNIX);
1021 put_byte(CURRENT_UNIX_MINOR_VERSION);
1022 put_longword((long) hdr->unix_last_modified_stamp);
1023 put_word(hdr->unix_mode);
1024 put_word(hdr->unix_uid);
1025 put_word(hdr->unix_gid);
1026 header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
1027 data[I_HEADER_SIZE] = header_size;
1028 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1031 /* write extend header. */
1037 put_byte(EXTEND_UNIX);
1040 if (hdr->header_level == HEADER_LEVEL2) {
1041 /* write common header */
1044 headercrc_ptr = put_ptr;
1048 if (generic_format) {
1049 header_size = put_ptr - data; /* +2 for last 0x0000 */
1052 if (hdr->header_level == HEADER_LEVEL1)
1053 header_size = put_ptr - data - 2;
1054 put_byte(0x50); /* permission */
1055 put_word(hdr->unix_mode);
1057 put_byte(0x51); /* gid and uid */
1058 put_word(hdr->unix_gid);
1059 put_word(hdr->unix_uid);
1062 int i, len = strlen(hdr->group);
1064 put_byte(0x52); /* group name */
1065 for (i = 0; i < len; i++)
1066 put_byte(hdr->group[i]);
1068 len = strlen(hdr->user);
1070 put_byte(0x53); /* user name */
1071 for (i = 0; i < len; i++)
1072 put_byte(hdr->user[i]);
1075 if (p = (char *) strrchr(lzname, LHA_PATHSEP)) {
1078 name_length = p - lzname + 1;
1079 put_word(name_length + 3);
1080 put_byte(2); /* dirname */
1081 for (i = 0; i < name_length; i++)
1082 put_byte(lzname[i]);
1084 } /* if generic .. */
1086 if (header_level != HEADER_LEVEL2) {
1087 if (!generic_format) {
1089 put_byte(0x54); /* time stamp */
1090 put_longword(hdr->unix_last_modified_stamp);
1092 hdr->packed_size += put_ptr - ptr;
1094 setup_put(data + I_PACKED_SIZE);
1095 put_longword(hdr->packed_size);
1097 data[I_HEADER_SIZE] = header_size;
1098 data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
1099 } else { /* header level 2 */
1101 if (p = (char *) strrchr(lzname, LHA_PATHSEP))
1102 name_length = strlen(++p);
1105 name_length = strlen(lzname);
1107 put_word(name_length + 3);
1108 put_byte(1); /* filename */
1109 for (i = 0; i < name_length; i++)
1111 } /* if he.. != HEAD_LV2 */
1112 header_size = put_ptr - data;
1115 if (header_level == HEADER_LEVEL2) {
1116 unsigned short hcrc;
1117 setup_put(data + I_HEADER_SIZE);
1118 put_word(header_size + 2);
1120 hcrc = calc_header_crc(data, (unsigned int) header_size + 2);
1121 setup_put(headercrc_ptr);
1125 if (fwrite(data, header_size + 2, 1, nafp) == 0)
1126 fatal_error("Cannot write to temporary file");
1130 /* this is not need for Mac OS X v 10.2 later */
1132 kCFStringEncodingAllowLossyConversion = 1,
1133 kCFStringEncodingBasicDirectionLeftToRight = (1 << 1),
1134 kCFStringEncodingBasicDirectionRightToLeft = (1 << 2),
1135 kCFStringEncodingSubstituteCombinings = (1 << 3),
1136 kCFStringEncodingComposeCombinings = (1 << 4),
1137 kCFStringEncodingIgnoreCombinings = (1 << 5),
1138 kCFStringEncodingUseCanonical = (1 << 6),
1139 kCFStringEncodingUseHFSPlusCanonical = (1 << 7),
1140 kCFStringEncodingPrependBOM = (1 << 8),
1141 kCFStringEncodingDisableCorporateArea = (1 << 9),
1142 kCFStringEncodingASCIICompatibleConversion = (1 << 10),
1146 ConvertEncodingToUTF8(const char* inCStr,
1147 char* outUTF8Buffer,
1148 int outUTF8BufferLength,
1149 unsigned long scriptEncoding,
1150 unsigned long flags)
1152 unsigned long unicodeChars;
1153 unsigned long srcCharsUsed;
1154 unsigned long usedByteLen = 0;
1155 UniChar uniStr[512];
1156 unsigned long cfResult;
1158 cfResult = CFStringEncodingBytesToUnicode(scriptEncoding,
1166 if (cfResult == 0) {
1167 cfResult = CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8,
1172 (char*)outUTF8Buffer,
1173 outUTF8BufferLength - 1,
1175 outUTF8Buffer[usedByteLen] = '\0';
1182 ConvertUTF8ToEncoding(const char* inUTF8Buf,
1183 int inUTF8BufLength,
1184 char* outCStrBuffer,
1185 int outCStrBufferLength,
1186 unsigned long scriptEncoding,
1187 unsigned long flags)
1189 unsigned long unicodeChars;
1190 unsigned long srcCharsUsed;
1191 unsigned long usedByteLen = 0;
1192 UniChar uniStr[256];
1193 unsigned long cfResult;
1195 cfResult = CFStringEncodingBytesToUnicode(kCFStringEncodingUTF8,
1203 if (cfResult == 0) {
1204 cfResult = CFStringEncodingUnicodeToBytes(scriptEncoding,
1209 (char*)outCStrBuffer,
1210 outCStrBufferLength - 1,
1212 outCStrBuffer[usedByteLen] = '\0';
1217 #endif /* __APPLE__ */
1220 sjis_to_utf8(char *dst, const char *src, size_t dstsize)
1224 ConvertEncodingToUTF8(src, dst, dstsize,
1225 kCFStringEncodingDOSJapanese,
1226 kCFStringEncodingUseHFSPlusCanonical);
1235 utf8_to_sjis(char *dst, const char *src, size_t dstsize)
1241 srclen = strlen(src);
1242 ConvertUTF8ToEncoding(src, srclen, dst, dstsize,
1243 kCFStringEncodingDOSJapanese,
1244 kCFStringEncodingUseHFSPlusCanonical);
1252 * SJIS <-> EUC ÊÑ´¹´Ø¿ô
1253 * ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
1254 * ¤è¤êÈ´¿è(by Koji Arai)
1257 euc2sjis(int *p1, int *p2)
1259 unsigned char c1 = *p1 & 0x7f;
1260 unsigned char c2 = *p2 & 0x7f;
1261 int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
1262 int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
1263 *p1 = ((c1 + 1) >> 1) + rowoff;
1264 *p2 += celoff - 0x80;
1268 sjis2euc(int *p1, int *p2)
1270 unsigned char c1 = *p1;
1271 unsigned char c2 = *p2;
1272 int adjust = c2 < 0x9f;
1273 int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
1274 int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
1275 *p1 = ((c1 - rowoff) << 1) - adjust;
1282 /* Local Variables: */
1285 /* compile-command:"gcc -c header.c" */
1287 /* vi: set tabstop=4: */