]> arthur.barton.de Git - netatalk.git/commitdiff
New convert_charset option CONV_ALLOW_COLON.
authorfranklahm <franklahm>
Wed, 18 Nov 2009 10:51:59 +0000 (10:51 +0000)
committerfranklahm <franklahm>
Wed, 18 Nov 2009 10:51:59 +0000 (10:51 +0000)
Used in conjunction with CONV_ESCAPEHEX to allow and escape ':'.
Needed for storing Extended Attributes in files in adouble dirs.

bin/misc/netacnv.c
include/atalk/unicode.h
libatalk/unicode/charcnv.c
libatalk/vfs/ea.c

index 6e3107c6b01842a6402adc510e73f7a7694282ea..03e0fa670375c8ae3588ae53ee550beac617f292 100644 (file)
@@ -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;
     }
 
index cda2bbf65a1bb77f034530d1de8309a404610ec9..21ef32f020ff658ad0ad2a858678eb583427a768 100644 (file)
@@ -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;
index 6deaeb8c6b60bb68c6b6ff26ba1c15d0fcd42af2..4cad3e9c60f815ba18e8759fb82a0a4442d55d60 100644 (file)
@@ -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;
index 35048a3cc5cfa8dd43e2989aa103ded410508e83..8d3c1ae8ab9964956a2393b31bf6dee0f3128f44 100644 (file)
@@ -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 <franklahm@gmail.com>
 
   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;