From: franklahm Date: Wed, 18 Nov 2009 10:51:59 +0000 (+0000) Subject: New convert_charset option CONV_ALLOW_COLON. X-Git-Tag: branch-symlink-start~125 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=562098d91208d5b5c8a6a8be72076ff93db832a1 New convert_charset option CONV_ALLOW_COLON. Used in conjunction with CONV_ESCAPEHEX to allow and escape ':'. Needed for storing Extended Attributes in files in adouble dirs. --- diff --git a/bin/misc/netacnv.c b/bin/misc/netacnv.c index 6e3107c6..03e0fa67 100644 --- a/bin/misc/netacnv.c +++ b/bin/misc/netacnv.c @@ -8,7 +8,7 @@ #define MACCHARSET "MAC_ROMAN" -#define flag(x) x, #x +#define flag(x) {x, #x} struct flag_map { int flag; @@ -17,6 +17,7 @@ struct flag_map { struct flag_map flag_map[] = { flag(CONV_ESCAPEHEX), + flag(CONV_ALLOW_COLON), flag(CONV_UNESCAPEHEX), flag(CONV_ESCAPEDOTS), flag(CONV_IGNORE), @@ -85,7 +86,7 @@ int main(int argc, char **argv) string, strlen(string), buffer, MAXPATHLEN, &flags)) ) { - fprintf( stderr, "Conversion error"); + perror("Conversion error"); return 1; } diff --git a/include/atalk/unicode.h b/include/atalk/unicode.h index cda2bbf6..21ef32f0 100644 --- a/include/atalk/unicode.h +++ b/include/atalk/unicode.h @@ -46,7 +46,9 @@ typedef struct { /* conversion flags */ #define CONV_IGNORE (1<<0) /* return the first convertable characters. */ -#define CONV_ESCAPEHEX (1<<1) /* escape unconvertable chars with :[UCS2HEX] */ +#define CONV_ESCAPEHEX (1<<1) /* escape unconvertable chars with :[UCS2HEX], */ + /* also escape '/'. Escape ':' if also CONV_ALLOW_COLON, */ + /* else ':' raises EILSEQ */ #define CONV_ESCAPEDOTS (1<<2) /* escape leading dots with :2600 */ #define CONV_UNESCAPEHEX (1<<3) #define CONV_TOUPPER (1<<4) /* convert to UPPERcase */ @@ -55,6 +57,7 @@ typedef struct { #define CONV_DECOMPOSE (1<<7) /* precompose */ #define CONV_FORCE (1<<8) /* force convertion */ #define CONV__EILSEQ (1<<9) /* ignore EILSEQ, replace with IGNORE_CHAR (try USC2) */ +#define CONV_ALLOW_COLON (1<<10) /* Allow ':' in name. Needed for Extended Attributes */ /* conversion return flags */ #define CONV_REQMANGLE (1<<14) /* mangling of returned name is required */ @@ -68,7 +71,7 @@ typedef enum {CH_UCS2=0, CH_UTF8=1, CH_MAC=2, CH_UNIX=3, CH_UTF8_MAC=4} charset_ /* * for each charset we have a function that pulls from that charset to * a ucs2 buffer, and a function that pushes to a ucs2 buffer - * */ + */ struct charset_functions { const char *name; diff --git a/libatalk/unicode/charcnv.c b/libatalk/unicode/charcnv.c index 6deaeb8c..4cad3e9c 100644 --- a/libatalk/unicode/charcnv.c +++ b/libatalk/unicode/charcnv.c @@ -889,6 +889,7 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src char* outbuf = (char*)dest; atalk_iconv_t descriptor; atalk_iconv_t descriptor_cap; + char escch; descriptor = conv_handles[CH_UCS2][to_set]; descriptor_cap = conv_handles[CH_UCS2][cap_set]; @@ -920,13 +921,21 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src if ((option & CONV_ESCAPEHEX)) { for (i = 0; i < i_len; i += 2) { ucs2_t c = SVAL(inbuf, i); - if (c == 0x002f) { /* 0x002f = / */ + 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; - } else if (c == 0x003a) { /* 0x003a = : */ - errno = EILSEQ; - goto end; } } } @@ -985,9 +994,27 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src errno = E2BIG; goto end; } - *outbuf++ = ':'; - *outbuf++ = '2'; - *outbuf++ = 'f'; + 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; diff --git a/libatalk/vfs/ea.c b/libatalk/vfs/ea.c index 35048a3c..8d3c1ae8 100644 --- a/libatalk/vfs/ea.c +++ b/libatalk/vfs/ea.c @@ -1,5 +1,5 @@ /* - $Id: ea.c,v 1.15 2009-11-18 08:02:33 didg Exp $ + $Id: ea.c,v 1.16 2009-11-18 10:52:00 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -78,7 +78,7 @@ static char *mtoupath(const struct vol *vol, const char *mpath) char *u; size_t inplen; size_t outlen; - uint16_t flags = CONV_ESCAPEHEX | CONV_FORCE; + uint16_t flags = CONV_ESCAPEHEX | CONV_ALLOW_COLON; if (!mpath) return NULL;