/* Ver. 1.10 Symbolic Link added 1993.10.01 N.Watazaki */
/* Ver. 1.13b Symbolic Link Bug Fix 1994.08.22 N.Watazaki */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
-/* Ver. 1.14e bug fixed 1999.05.27 T.Okamoto */
+/* Ver. 1.14i bug fixed 2000.10.06 t.okamoto */
/* ------------------------------------------------------------------------ */
#include "lha.h"
+#if !STRCHR_8BIT_CLEAN
+/* should use 8 bit clean version */
+#undef strchr
+#undef strrchr
+#define strchr xstrchr
+#define strrchr xstrrchr
+#endif
+
/* ------------------------------------------------------------------------ */
static char *get_ptr;
+
+int optional_archive_kanji_code = NONE;
+int optional_system_kanji_code = NONE;
+char *optional_archive_delim = NULL;
+char *optional_system_delim = NULL;
+int optional_filename_case = NONE;
+
+#ifdef MULTIBYTE_FILENAME
+int default_system_kanji_code = MULTIBYTE_FILENAME;
+#else
+int default_system_kanji_code = NONE;
+#endif
+
/* ------------------------------------------------------------------------ */
int
calc_sum(p, len)
put_byte(v >> 24);
}
+#if 0 /* no use */
/* ------------------------------------------------------------------------ */
static void
msdos_to_unix_filename(name, len)
{
register int i;
-#define X0201_KANA_P(c)\
- (0xa0 < (unsigned char)(c) && (unsigned char)(c) < 0xe0)
-
-#ifdef MULTIBYTE_CHAR
-#ifdef SUPPORT_X0201
- for (i = 0; i < len; i++) {
- /* modified by Koji Arai */
- if (X0201_KANA_P(name[i])) {
- int j;
- for (j = len; j >= i; j--) {
- name[j+1] = name[j]; /* no check over */
- }
- name[i] = 0x8e;
- i++;
- len++;
- } else
- if (MULTIBYTE_FIRST_P(name[i]) &&
- MULTIBYTE_SECOND_P(name[i + 1])) {
- int c1, c2;
- c1 = name[i]; c2 = name[i+1];
- sjis2euc(&c1, &c2);
- name[i] = c1; name[i+1] = c2;
- i++;
- }
- else if (name[i] == '\\')
- name[i] = '/';
- else if (isupper(name[i]))
- name[i] = tolower(name[i]);
- }
-#else
+#ifdef MULTIBYTE_FILENAME
for (i = 0; i < len; i++) {
if (MULTIBYTE_FIRST_P(name[i]) &&
MULTIBYTE_SECOND_P(name[i + 1]))
i++;
else if (name[i] == '\\')
name[i] = '/';
- else if (isupper(name[i]))
+ else if (!noconvertcase && isupper(name[i]))
name[i] = tolower(name[i]);
}
-#endif /* SUPPORT_X0201 */
#else
for (i = 0; i < len; i++) {
if (name[i] == '\\')
name[i] = '/';
- else if (isupper(name[i]))
+ else if (!noconvertcase && isupper(name[i]))
name[i] = tolower(name[i]);
}
#endif
register int i;
boolean lower_case_used = FALSE;
-#ifdef MULTIBYTE_CHAR
-#ifdef SUPPORT_X0201
- for (i = 0; i < len; i++) {
- /* modified by Koji Arai */
- if (X0201_KANA_P(name[i])) {
- int j;
- for (j = len; j >= i; j--) {
- name[j+1] = name[j]; /* no check over */
- }
- name[i] = 0x8e;
- i++;
- len++;
- } else
-
- if (MULTIBYTE_FIRST_P(name[i]) &&
- MULTIBYTE_SECOND_P(name[i + 1]))
- i++;
- else if (islower(name[i])) {
- lower_case_used = TRUE;
- break;
- }
- }
-#else
+#ifdef MULTIBYTE_FILENAME
for (i = 0; i < len; i++) {
if (MULTIBYTE_FIRST_P(name[i]) &&
MULTIBYTE_SECOND_P(name[i + 1]))
break;
}
}
-#endif /* SUPPORT_X0201 */
for (i = 0; i < len; i++) {
if (MULTIBYTE_FIRST_P(name[i]) &&
MULTIBYTE_SECOND_P(name[i + 1]))
i++;
else if (name[i] == '\\')
name[i] = '/';
- else if (!lower_case_used && isupper(name[i]))
+ else if (!noconvertcase && !lower_case_used && isupper(name[i]))
name[i] = tolower(name[i]);
}
#else
for (i = 0; i < len; i++) {
if (name[i] == '\\')
name[i] = '/';
- else if (!lower_case_used && isupper(name[i]))
+ else if (!noconvertcase && !lower_case_used && isupper(name[i]))
name[i] = tolower(name[i]);
}
#endif
{
register int i;
-/* modified by Koji Arai */
-#ifdef SUPPORT_X0201
- for (i = 0; i < len; i ++) {
- /* modified by Koji Arai */
- if (X0201_KANA_P(name[i])) {
- int j;
- for (j = len; j >= i; j--) {
- name[j+1] = name[j]; /* no check over */
- }
- name[i] = 0x8e;
- i++;
- len++;
- } else
-
- if (MULTIBYTE_FIRST_P (name[i]) &&
- MULTIBYTE_SECOND_P (name[i+1])) {
- int c1, c2;
- c1 = name[i]; c2 = name[i+1];
- sjis2euc(&c1, &c2);
- name[i] = c1; name[i+1] = c2;
- i ++;
- }
- else if (name[i] == ':')
- name[i] = '/';
- else if (name[i] == '/')
- name[i] = ':';
-/*
- else if (isupper (name[i]))
- name[i] = tolower (name[i]);
-*/
- }
-#else
for (i = 0; i < len; i++) {
if (name[i] == ':')
name[i] = '/';
else if (name[i] == '/')
name[i] = ':';
}
-#endif /* SUPPORT_X0201 */
}
/* ------------------------------------------------------------------------ */
name[i] = toupper(name[i]);
}
}
+#endif /* 0 */
+
+/* added by Koji Arai */
+static void
+convert_filename(name, len, size,
+ from_code, to_code,
+ from_delim, to_delim,
+ case_to)
+ register char *name;
+ register int len;
+ register int size;
+ int from_code, to_code, case_to;
+ char *from_delim, *to_delim;
+
+{
+ register int i;
+#ifdef MULTIBYTE_FILENAME
+ char tmp[256]; /* 256 is sizeof(LzHeader.name) */
+
+ if (from_code == CODE_SJIS && to_code == CODE_UTF8) {
+ for (i = 0; i < len; i++)
+ if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
+ sjis_to_utf8(tmp, name, sizeof(tmp));
+ strncpy(name, tmp, size);
+ name[size-1] = 0;
+ len = strlen(name);
+ for (i = 0; i < len; i++)
+ if (name[i] == '/') name[i] = LHA_PATHSEP;
+ from_code = CODE_UTF8;
+ }
+ else if (from_code == CODE_UTF8 && to_code == CODE_SJIS) {
+ for (i = 0; i < len; i++)
+ if ((unsigned char)name[i] == LHA_PATHSEP) name[i] = '/';
+ utf8_to_sjis(tmp, name, sizeof(tmp));
+ strncpy(name, tmp, size);
+ name[size-1] = 0;
+ len = strlen(name);
+ for (i = 0; i < len; i++)
+ if (name[i] == '/') name[i] = LHA_PATHSEP;
+ from_code = CODE_SJIS;
+ }
+#endif
+
+ for (i = 0; i < len; i ++) {
+#ifdef MULTIBYTE_FILENAME
+ if (from_code == CODE_EUC &&
+ (unsigned char)name[i] == 0x8e) {
+ if (to_code != CODE_SJIS) {
+ i++;
+ continue;
+ }
+
+ /* X0201 KANA */
+ memmove(name + i, name + i + 1, len - i);
+ len--;
+ continue;
+ }
+ if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
+ if (to_code != CODE_EUC) {
+ continue;
+ }
+
+ if (len == size - 1) /* check overflow */
+ len--;
+ memmove(name+i+1, name+i, len-i);
+ name[i] = 0x8e;
+ i++;
+ len++;
+ continue;
+ }
+ if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
+ int c1, c2;
+ if (to_code != CODE_SJIS) {
+ i++;
+ continue;
+ }
+
+ c1 = (unsigned char)name[i];
+ c2 = (unsigned char)name[i+1];
+ euc2sjis(&c1, &c2);
+ name[i] = c1;
+ name[i+1] = c2;
+ i++;
+ continue;
+ }
+ if (from_code == CODE_SJIS &&
+ SJC_FIRST_P(name[i]) &&
+ SJC_SECOND_P(name[i+1])) {
+ int c1, c2;
+
+ if (to_code != CODE_EUC) {
+ i++;
+ continue;
+ }
+
+ c1 = (unsigned char)name[i];
+ c2 = (unsigned char)name[i+1];
+ sjis2euc(&c1, &c2);
+ name[i] = c1;
+ name[i+1] = c2;
+ i++;
+ continue;
+ }
+#endif /* MULTIBYTE_FILENAME */
+ {
+ char *ptr;
+
+ /* transpose from_delim to to_delim */
+
+ if ((ptr = strchr(from_delim, name[i])) != NULL) {
+ name[i] = to_delim[ptr - from_delim];
+ continue;
+ }
+ }
+
+ if (case_to == TO_UPPER && islower(name[i])) {
+ name[i] = toupper(name[i]);
+ continue;
+ }
+ if (case_to == TO_LOWER && isupper(name[i])) {
+ name[i] = tolower(name[i]);
+ continue;
+ }
+ }
+}
/* ------------------------------------------------------------------------ */
/* */
/* ------------------------------------------------------------------------ */
#if !defined(HAVE_TZSET) && !defined(HAVE_FTIME) /* maybe defined(HAVE_GETTIMEOFDAY) */
{
-#ifdef HAVE_TM_GMTOFF
- time_t tt;
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+ time_t tt;
- time(&tt);
- return -localtime(&tt)->tm_gmtoff;
-#else /* HAVE_TM_GMTOFF */
+ time(&tt);
+ return -localtime(&tt)->tm_gmtoff;
+#else /* HAVE_STRUCT_TM_TM_GMTOFF */
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
* 60L : 0));
*/
return (tzp.tz_minuteswest * 60L);
-#endif /* HAVE_TM_GMTOFF */
+#endif /* HAVE_STRUCT_TM_TM_GMTOFF */
}
#endif
#endif /* defined(HAVE_FTIME) || defined(HAVE_GETTIMEOFDAY) ||
- * defined(HAVE_TZSET) */
+ * defined(HAVE_TZSET) */
/* ------------------------------------------------------------------------ */
#ifdef NOT_USED
int extend_size;
int dmy;
- bzero(hdr, sizeof(LzHeader));
+ int archive_kanji_code = CODE_SJIS;
+ int system_kanji_code = default_system_kanji_code;
+ char *archive_delim = "";
+ char *system_delim = "";
+ int filename_case = NONE;
+
+ memset(hdr, 0, sizeof(LzHeader));
if (((header_size = getc(fp)) == EOF) || (header_size == 0)) {
return FALSE; /* finish */
}
if (hdr->header_level >= 3) {
- fatal_error("Unknown level header");
+ fatal_error("Unknown level header (level %d)", hdr->header_level);
return FALSE;
}
setup_get(data + I_HEADER_CHECKSUM);
checksum = get_byte();
- hdr->header_size = header_size;
- bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ if (hdr->header_level == 2) {
+ hdr->header_size = header_size + checksum*256;
+ } else {
+ hdr->header_size = header_size;
+ }
+ memcpy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
setup_get(data + I_PACKED_SIZE);
hdr->packed_size = get_longword();
hdr->original_size = get_longword();
if ((hdr->header_level = get_byte()) != 2) {
if (calc_sum(data + I_METHOD, header_size) != checksum)
- warning("Checksum error (LHarc file?)", "");
+ warning("Checksum error (LHarc file?)");
name_length = get_byte();
for (i = 0; i < name_length; i++)
hdr->name[i] = (char) get_byte();
hdr->unix_gid = 0;
hdr->unix_uid = 0;
-
if (hdr->header_level == 0) {
extend_size = header_size - name_length -22;
if (extend_size < 0) {
hdr->extend_type = EXTEND_GENERIC;
hdr->has_crc = FALSE;
} else {
- fatal_error("Unkonwn header (lha file?)");
- return FALSE;
+ error("Unkonwn header (lha file?)");
+ exit(1);
}
} else {
hdr->has_crc = TRUE;
}
while (extend_size-- > 0)
dmy = get_byte();
- if (hdr->extend_type == EXTEND_UNIX)
- return TRUE;
} else if (hdr->header_level == 1) {
hdr->has_crc = TRUE;
extend_size = header_size - name_length-25;
for (i = 0; i < header_size - 3; i++)
hdr->name[i] = (char) get_byte();
hdr->name[header_size - 3] = '\0';
- name_length = header_size - 3; /* modified by Koji Arai */
+ name_length = header_size - 3;
break;
case 2:
/*
for (i = 0; i < header_size - 3; i++)
dirname[i] = (char) get_byte();
dirname[header_size - 3] = '\0';
- convdelim(dirname, DELIM);
dir_length = header_size - 3;
break;
case 0x40:
/*
* UNIX group name
*/
- setup_get(get_ptr + header_size - 3);
+ for (i = 0; i < header_size - 3; i++)
+ hdr->group[i] = get_byte();
+ hdr->group[i] = '\0';
break;
case 0x53:
/*
* UNIX user name
*/
- setup_get(get_ptr + header_size - 3);
+ for (i = 0; i < header_size - 3; i++)
+ hdr->user[i] = get_byte();
+ hdr->user[i] = '\0';
break;
case 0x54:
/*
hdr->header_size += get_ptr - ptr - 2;
}
}
- if (dir_length) {
- strcat(dirname, hdr->name);
- strcpy(hdr->name, dirname);
- name_length += dir_length;
- }
switch (hdr->extend_type) {
case EXTEND_MSDOS:
- msdos_to_unix_filename(hdr->name, name_length);
+ archive_delim = "\377\\";
+ /* `\' is for level 0 header and broken archive. */
+ system_delim = "//";
+ filename_case = noconvertcase ? NONE : TO_LOWER;
+
+ /* fall through */
case EXTEND_HUMAN:
if (hdr->header_level == 2)
hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
case EXTEND_XOSK:
#endif
case EXTEND_UNIX:
+ archive_delim = "\377\\";
+ /* `\' is for level 0 header and broken archive. */
+ system_delim = "//";
+ filename_case = NONE;
+
break;
case EXTEND_MACOS:
- macos_to_unix_filename(hdr->name, name_length);
+ archive_delim = "\377/:\\";
+ /* `\' is for level 0 header and broken archive. */
+ system_delim = "/://";
+ filename_case = NONE;
+
hdr->unix_last_modified_stamp =
- generic_to_unix_stamp(hdr->last_modified_stamp);
+ generic_to_unix_stamp(hdr->last_modified_stamp, sizeof(hdr->name));
break;
default:
- generic_to_unix_filename(hdr->name, name_length);
+ archive_delim = "\377\\";
+ /* `\' is for level 0 header and broken archive. */
+ system_delim = "//";
+ filename_case = noconvertcase ? NONE : TO_LOWER;
+ /* FIXME: if small letter is included in filename,
+ the generic_to_unix_filename() do not case conversion,
+ but this code does not consider it. */
+
if (hdr->header_level == 2)
hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
else
generic_to_unix_stamp(hdr->last_modified_stamp);
}
-#if 0
- printf("header level=%d\n", hdr->header_level); fflush(stdout);
-#endif
+ /* filename kanji code and delimiter conversion */
+ if (optional_archive_kanji_code)
+ archive_kanji_code = optional_archive_kanji_code;
+ if (optional_system_kanji_code)
+ system_kanji_code = optional_system_kanji_code;
+ if (optional_archive_delim)
+ archive_delim = optional_archive_delim;
+ if (optional_system_delim)
+ system_delim = optional_system_delim;
+ if (optional_filename_case)
+ filename_case = optional_filename_case;
+
+ if (dir_length) {
+ strcat(dirname, hdr->name);
+ strcpy(hdr->name, dirname);
+ name_length += dir_length;
+ }
+
+ convert_filename(hdr->name, name_length, sizeof(hdr->name),
+ archive_kanji_code,
+ system_kanji_code,
+ archive_delim, system_delim, filename_case);
return TRUE;
}
{
int len;
+ memset(hdr, 0, sizeof(LzHeader));
+
if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
- bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ memcpy(hdr->method, LZHUFF5_METHOD, METHOD_TYPE_STRAGE);
else if (compress_method)
- bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ memcpy(hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE);
else
- bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE);
hdr->packed_size = 0;
hdr->original_size = v_stat->st_size;
hdr->unix_uid = v_stat->st_uid;
hdr->unix_gid = v_stat->st_gid;
+#if INCLUDE_OWNER_NAME_IN_HEADER
+#if HAVE_GETPWUID
+ {
+ struct passwd *ent = getpwuid(hdr->unix_uid);
+
+ if (ent) {
+ strncpy(hdr->user, ent->pw_name, sizeof(hdr->user));
+ if (hdr->user[sizeof(hdr->user)-1])
+ hdr->user[sizeof(hdr->user)-1] = 0;
+ }
+ }
+#endif
+#if HAVE_GETGRGID
+ {
+ struct group *ent = getgrgid(hdr->unix_gid);
+
+ if (ent) {
+ strncpy(hdr->group, ent->gr_name, sizeof(hdr->group));
+ if (hdr->group[sizeof(hdr->group)-1])
+ hdr->group[sizeof(hdr->group)-1] = 0;
+ }
+ }
+#endif
+#endif /* INCLUDE_OWNER_NAME_IN_HEADER */
if (is_directory(v_stat)) {
- bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
hdr->original_size = 0;
if (len > 0 && hdr->name[len - 1] != '/')
#ifdef S_IFLNK
if (is_symlink(v_stat)) {
- char lkname[257];
+ char lkname[256]; /* FIXME: no enough space */
int len;
- bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+ memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STRAGE);
hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
hdr->original_size = 0;
- len = readlink(name, lkname, 256);
- lkname[len] = (char)'\0';
- sprintf(hdr->name, "%s|%s", hdr->name, lkname);
+ len = readlink(name, lkname, sizeof(lkname));
+ if (xsnprintf(hdr->name, sizeof(hdr->name),
+ "%s|%.*s", hdr->name, len, lkname) == -1)
+ error("file name is too long (%s -> %.*s)", hdr->name, len, lkname);
}
#endif
- if (generic_format)
- unix_to_generic_filename(hdr->name, len);
}
/* ------------------------------------------------------------------------ */
char *p;
char *headercrc_ptr;
- bzero(data, LZHEADER_STRAGE);
- bcopy(hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
+ int archive_kanji_code = CODE_SJIS;
+ int system_kanji_code = default_system_kanji_code;
+ char *archive_delim = "\377";
+ char *system_delim = "/";
+ int filename_case = NONE;
+ char lzname[256];
+
+ if (optional_archive_kanji_code)
+ archive_kanji_code = optional_archive_kanji_code;
+ if (optional_system_kanji_code)
+ system_kanji_code = optional_system_kanji_code;
+
+ memset(data, 0, LZHEADER_STRAGE);
+ memcpy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
setup_put(data + I_PACKED_SIZE);
put_longword(hdr->packed_size);
put_longword(hdr->original_size);
put_byte(hdr->header_level);
- convdelim(hdr->name, DELIM2);
+ if (generic_format)
+ filename_case = TO_UPPER;
+
+ if (hdr->header_level == HEADER_LEVEL0) {
+ archive_delim = "\\";
+ }
+
+ strncpy(lzname, hdr->name, sizeof(lzname));
+ convert_filename(lzname, strlen(lzname), sizeof(lzname),
+ system_kanji_code,
+ archive_kanji_code,
+ system_delim, archive_delim, filename_case);
+
if (hdr->header_level != HEADER_LEVEL2) {
- if (p = (char *) strrchr(hdr->name, DELIM2))
- name_length = strlen(++p);
- else
- name_length = strlen(hdr->name);
+ if (hdr->header_level == HEADER_LEVEL0 ||
+ (p = strchr(lzname, LHA_PATHSEP)) == 0)
+ p = lzname;
+ else
+ ++p;
+ /* level 0 header: write pathname (contain the directory part) */
+ /* level 1 header: write filename (basename only) */
+ name_length = strlen(p);
put_byte(name_length);
- bcopy(p ? p : hdr->name, data + I_NAME, name_length);
+ memcpy(data + I_NAME, p, name_length);
setup_put(data + I_NAME + name_length);
}
put_word(hdr->unix_gid);
put_word(hdr->unix_uid);
- if (p = (char *) strrchr(hdr->name, DELIM2)) {
+ {
+ int i, len = strlen(hdr->group);
+ put_word(len + 3);
+ put_byte(0x52); /* group name */
+ for (i = 0; i < len; i++)
+ put_byte(hdr->group[i]);
+
+ len = strlen(hdr->user);
+ put_word(len + 3);
+ put_byte(0x53); /* user name */
+ for (i = 0; i < len; i++)
+ put_byte(hdr->user[i]);
+ }
+
+ if (p = strrchr(lzname, LHA_PATHSEP)) {
int i;
- name_length = p - hdr->name + 1;
+ name_length = p - lzname + 1;
put_word(name_length + 3);
put_byte(2); /* dirname */
for (i = 0; i < name_length; i++)
- put_byte(hdr->name[i]);
+ put_byte(lzname[i]);
}
} /* if generic .. */
data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
} else { /* header level 2 */
int i;
- if (p = (char *) strrchr(hdr->name, DELIM2))
+ if (p = strrchr(lzname, LHA_PATHSEP))
name_length = strlen(++p);
else {
- p = hdr->name;
- name_length = strlen(hdr->name);
+ p = lzname;
+ name_length = strlen(lzname);
}
put_word(name_length + 3);
put_byte(1); /* filename */
put_word(hcrc);
}
- if (fwrite(data, sizeof(char), header_size + 2, nafp) == 0)
+ if (fwrite(data, header_size + 2, 1, nafp) == 0)
fatal_error("Cannot write to temporary file");
+}
+
+#if MULTIBYTE_FILENAME
+
+#if defined(__APPLE__)
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFStringEncodingExt.h>
+
+/* this is not need for Mac OS X v 10.2 later */
+enum {
+ kCFStringEncodingAllowLossyConversion = 1,
+ kCFStringEncodingBasicDirectionLeftToRight = (1 << 1),
+ kCFStringEncodingBasicDirectionRightToLeft = (1 << 2),
+ kCFStringEncodingSubstituteCombinings = (1 << 3),
+ kCFStringEncodingComposeCombinings = (1 << 4),
+ kCFStringEncodingIgnoreCombinings = (1 << 5),
+ kCFStringEncodingUseCanonical = (1 << 6),
+ kCFStringEncodingUseHFSPlusCanonical = (1 << 7),
+ kCFStringEncodingPrependBOM = (1 << 8),
+ kCFStringEncodingDisableCorporateArea = (1 << 9),
+ kCFStringEncodingASCIICompatibleConversion = (1 << 10),
+};
+
+static int
+ConvertEncodingToUTF8(const char* inCStr,
+ char* outUTF8Buffer,
+ int outUTF8BufferLength,
+ unsigned long scriptEncoding,
+ unsigned long flags)
+{
+ unsigned long unicodeChars;
+ unsigned long srcCharsUsed;
+ unsigned long usedByteLen = 0;
+ UniChar uniStr[512];
+ unsigned long cfResult;
+
+ cfResult = CFStringEncodingBytesToUnicode(scriptEncoding,
+ flags,
+ (char *)inCStr,
+ strlen(inCStr),
+ &srcCharsUsed,
+ uniStr,
+ 512,
+ &unicodeChars);
+ if (cfResult == 0) {
+ cfResult = CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8,
+ flags,
+ uniStr,
+ unicodeChars,
+ &srcCharsUsed,
+ (char*)outUTF8Buffer,
+ outUTF8BufferLength - 1,
+ &usedByteLen);
+ outUTF8Buffer[usedByteLen] = '\0';
+ }
+
+ return cfResult;
+}
+
+static int
+ConvertUTF8ToEncoding(const char* inUTF8Buf,
+ int inUTF8BufLength,
+ char* outCStrBuffer,
+ int outCStrBufferLength,
+ unsigned long scriptEncoding,
+ unsigned long flags)
+{
+ unsigned long unicodeChars;
+ unsigned long srcCharsUsed;
+ unsigned long usedByteLen = 0;
+ UniChar uniStr[256];
+ unsigned long cfResult;
+
+ cfResult = CFStringEncodingBytesToUnicode(kCFStringEncodingUTF8,
+ flags,
+ (char*)inUTF8Buf,
+ inUTF8BufLength,
+ &srcCharsUsed,
+ uniStr,
+ 255,
+ &unicodeChars);
+ if (cfResult == 0) {
+ cfResult = CFStringEncodingUnicodeToBytes(scriptEncoding,
+ flags,
+ uniStr,
+ unicodeChars,
+ &srcCharsUsed,
+ (char*)outCStrBuffer,
+ outCStrBufferLength - 1,
+ &usedByteLen);
+ outCStrBuffer[usedByteLen] = '\0';
+ }
+
+ return cfResult;
+}
+
+#elif HAVE_ICONV
+#include <iconv.h>
+
+static int
+ConvertEncodingByIconv(const char *src, char *dst, int dstsize,
+ const char *srcEnc, const char *dstEnc)
+{
+ iconv_t ic;
+ static char szTmpBuf[2048];
+ char *src_p;
+ char *dst_p;
+ size_t sLen;
+ size_t iLen;
+
+ dst_p = &szTmpBuf[0];
+ iLen = (size_t)sizeof(szTmpBuf)-1;
+ src_p = (char *)src;
+ sLen = (size_t)strlen(src);
+ memset(szTmpBuf, 0, sizeof(szTmpBuf));
+ memset(dst, 0, dstsize);
+
+ ic = iconv_open(dstEnc, srcEnc);
+ if (ic == (iconv_t)-1) {
+ error("iconv_open() failure");
+ return -1;
+ }
+
+ if (iconv(ic, &src_p, &sLen, &dst_p, &iLen) == (size_t)-1) {
+ error("iconv() failure");
+ iconv_close(ic);
+ return -1;
+ }
+
+ strncpy(dst, szTmpBuf, dstsize);
+
+ iconv_close(ic);
+
+ return 0;
+}
+#endif /* defined(__APPLE__) */
+
+char *
+sjis_to_utf8(char *dst, const char *src, size_t dstsize)
+{
+#if defined(__APPLE__)
+ dst[0] = '\0';
+ if (ConvertEncodingToUTF8(src, dst, dstsize,
+ kCFStringEncodingDOSJapanese,
+ kCFStringEncodingUseHFSPlusCanonical) == 0)
+ return dst;
+#elif HAVE_ICONV
+ if (ConvertEncodingByIconv(src, dst, dstsize, "SJIS", "UTF-8") != -1)
+ return dst;
+#else
+ error("not support utf-8 conversion");
+#endif
+
+ /* not supported */
+ if (dstsize < 1) return dst;
+ dst[dstsize-1] = 0;
+ return strncpy(dst, src, dstsize-1);
+}
+
+char *
+utf8_to_sjis(char *dst, const char *src, size_t dstsize)
+{
+#if defined(__APPLE__)
+ int srclen;
+
+ dst[0] = '\0';
+ srclen = strlen(src);
+ if (ConvertUTF8ToEncoding(src, srclen, dst, dstsize,
+ kCFStringEncodingDOSJapanese,
+ kCFStringEncodingUseHFSPlusCanonical) == 0)
+ return dst;
+#elif HAVE_ICONV
+ if (ConvertEncodingByIconv(src, dst, dstsize, "UTF-8", "SJIS") != -1)
+ return dst;
+#else
+ error("not support utf-8 conversion");
+#endif
- convdelim(hdr->name, DELIM);
+ /* not supported */
+ if (dstsize < 1) return dst;
+ dst[dstsize-1] = 0;
+ return strncpy(dst, src, dstsize-1);
}
-#ifdef SUPPORT_X0201
/*
* SJIS <-> EUC ÊÑ´¹´Ø¿ô
* ¡ÖÆüËܸì¾ðÊó½èÍý¡× ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
*p1 |= 0x80;
*p2 |= 0x80;
}
-#endif /* SUPPORT_X0201 */
+#endif /* MULTIBYTE_FILENAME */
/* Local Variables: */
-/* tab-width : 4 */
+/* mode:c */
+/* tab-width:4 */
+/* compile-command:"gcc -c header.c" */
/* End: */
+/* vi: set tabstop=4: */