static char hexdig[] = "0123456789abcdef";
#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
-static char* read_charsets_from_env(charset_t ch)
-{
- char *name;
-
- switch (ch) {
- case CH_MAC:
- if (( name = getenv( "ATALK_MAC_CHARSET" )) != NULL )
- return name;
- else
- return "MAC_ROMAN";
- break;
- case CH_UNIX:
- if (( name = getenv( "ATALK_UNIX_CHARSET" )) != NULL )
- return name;
- else
- return "LOCALE";
- break;
- default:
- break;
- }
- return "ASCII";
-}
-
/**
* Return the name of a charset to give to iconv().
else if (ch == CH_UTF8_MAC) ret = "UTF8-MAC";
else if (ch == CH_UNIX) {
if (unixname[0] == '\0') {
- ret = read_charsets_from_env(CH_UNIX);
+ ret = "LOCALE";
strlcpy(unixname, ret, sizeof(unixname));
}
else
}
else if (ch == CH_MAC) {
if (macname[0] == '\0') {
- ret = read_charsets_from_env(CH_MAC);
+ ret = "MAC_ROMAN";
strlcpy(macname, ret, sizeof(macname));
}
else
if (ln) {
/* Check whether the charset name is supported
by iconv */
+ LOG(log_debug, logtype_default, "Locale charset is '%s'", ln);
atalk_iconv_t handle = atalk_iconv_open(ln, "UCS-2");
if (handle == (atalk_iconv_t) -1) {
- LOG(log_debug, logtype_default, "Locale charset '%s' unsupported, using ASCII instead", ln);
+ LOG(log_warning, logtype_default, "Locale charset '%s' unsupported, using ASCII instead", ln);
ln = "ASCII";
} else {
atalk_iconv_close(handle);
ret = ln;
}
#else /* system doesn't have LOCALE support */
+ LOG(log_warning, logtype_default, "system doesn't have LOCALE support");
if (ch == CH_UNIX) ret = NULL;
#endif
o_len=destlen;
while (i_len > 0) {
- if ((option & CONV_UNESCAPEHEX)) {
- for (j = 0; j < i_len; ++j) {
- if (inbuf[j] == ':') break;
- }
- j = i_len - j;
- i_len -= j;
- }
+ for (j = 0; j < i_len; ++j)
+ if (inbuf[j] == ':')
+ break;
+ j = i_len - j;
+ i_len -= j;
if (i_len > 0 &&
atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len) == (size_t)-1) {
}
if (j) {
- /* we're at the start on an hex encoded ucs2 char */
- char h[MAXPATHLEN];
- size_t hlen = 0;
-
+ /* we have a ':' */
i_len = j, j = 0;
- while (i_len >= 3 && inbuf[0] == ':' &&
- isxdigit(inbuf[1]) && isxdigit(inbuf[2])) {
- h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]);
- inbuf += 3;
- i_len -= 3;
- }
- if (hlen) {
- const char *h_buf = h;
- if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) {
- i_len += hlen * 3;
- inbuf -= hlen * 3;
- if (errno == EILSEQ && (option & CONV_IGNORE)) {
+
+ if ((option & CONV_UNESCAPEHEX)) {
+ /* treat it as a CAP hex encoded char */
+ char h[MAXPATHLEN];
+ size_t hlen = 0;
+
+ while (i_len >= 3 && inbuf[0] == ':' &&
+ isxdigit(inbuf[1]) && isxdigit(inbuf[2])) {
+ h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]);
+ inbuf += 3;
+ i_len -= 3;
+ }
+ if (hlen) {
+ const char *h_buf = h;
+ if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) {
+ i_len += hlen * 3;
+ inbuf -= hlen * 3;
+ if (errno == EILSEQ && (option & CONV_IGNORE)) {
+ *flags |= CONV_REQMANGLE;
+ return destlen - o_len;
+ }
+ goto end;
+ }
+ } else {
+ /* We have an invalid :xx sequence */
+ errno = EILSEQ;
+ if ((option & CONV_IGNORE)) {
*flags |= CONV_REQMANGLE;
return destlen - o_len;
}
goto end;
}
} else {
- /* We have an invalid :xx sequence */
- errno = EILSEQ;
- if ((option & CONV_IGNORE)) {
- *flags |= CONV_REQMANGLE;
- return destlen - o_len;
- }
- goto end;
+ /* a ':' that we just convert to a '/' */
+ ucs2_t slash = 0x002f;
+ memcpy(outbuf, &slash, sizeof(ucs2_t));
+ outbuf += 2;
+ o_len -= 2;
+ inbuf++;
+ i_len--;
}
}
}
}
while (i_len >= 2) {
- if ((option & CONV_ESCAPEHEX)) {
- for (i = 0; i < i_len; i += 2) {
- ucs2_t c = SVAL(inbuf, i);
- switch (c) {
- case 0x003a: /* 0x003a = ':' */
- if ( ! (option & CONV_ALLOW_COLON)) {
- errno = EILSEQ;
- goto end;
- }
- escch = c;
- j = i_len - i;
- i_len = i;
- break;
- case 0x002f: /* 0x002f = '/' */
- escch = c;
- j = i_len - i;
- i_len = i;
- break;
+ for (i = 0; i < i_len; i += 2) {
+ ucs2_t c = SVAL(inbuf, i);
+ switch (c) {
+ case 0x003a: /* 0x003a = ':' */
+ if ( ! (option & CONV_ALLOW_COLON)) {
+ errno = EILSEQ;
+ goto end;
}
+ escch = c;
+ j = i_len - i;
+ i_len = i;
+ break;
+ case 0x002f: /* 0x002f = '/' */
+ escch = c;
+ j = i_len - i;
+ i_len = i;
+ break;
}
}
while (i_len > 0 &&
}
if (j) {
+ /* we have a ':' or '/' */
i_len = j, j = 0;
- if (o_len < 3) {
- errno = E2BIG;
- goto end;
- }
- switch (escch) {
- case '/':
- *outbuf++ = ':';
- *outbuf++ = '2';
- *outbuf++ = 'f';
- break;
- case ':':
- *outbuf++ = ':';
- *outbuf++ = '3';
- *outbuf++ = 'a';
- break;
- default:
- /*
- * THIS SHOULD NEVER BE REACHED !!!
- * As a safety net I put in a ' ' here
- */
- *outbuf++ = ':';
- *outbuf++ = '2';
- *outbuf++ = '0';
- break;
+
+ if ((option & CONV_ESCAPEHEX)) {
+ /* CAP hex encode it */
+ if (o_len < 3) {
+ errno = E2BIG;
+ goto end;
+ }
+ switch (escch) {
+ case '/':
+ *outbuf++ = ':';
+ *outbuf++ = '2';
+ *outbuf++ = 'f';
+ break;
+ case ':':
+ *outbuf++ = ':';
+ *outbuf++ = '3';
+ *outbuf++ = 'a';
+ break;
+ default:
+ /*
+ * THIS SHOULD NEVER BE REACHED !!!
+ * As a safety net I put in a ' ' here
+ */
+ *outbuf++ = ':';
+ *outbuf++ = '2';
+ *outbuf++ = '0';
+ break;
+ }
+ o_len -= 3;
+ inbuf += 2;
+ i_len -= 2;
+ } else {
+ switch (escch) {
+ case '/':
+ case ':':
+ *outbuf++ = ':';
+ break;
+ default: /* should never be reached */
+ *outbuf++ = ' ';
+ break;
+ }
+ o_len--;
+ inbuf += 2;
+ i_len -= 2;
}
- o_len -= 3;
- inbuf += 2;
- i_len -= 2;
}
}
if (i_len > 0) errno = EINVAL;