]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/mangle.c
Merge master
[netatalk.git] / etc / afpd / mangle.c
index eb1f39eff254279c1388d18b84f1616eb143d691..e4cbd311d9022094e6f74a109cbc91e509a55e73 100644 (file)
@@ -1,6 +1,4 @@
 /* 
- * $Id: mangle.c,v 1.17 2005-04-28 20:49:44 bfernhomberg Exp $ 
- *
  * Copyright (c) 2002. Joe Marcus Clarke (marcus@marcuscom.com)
  * All Rights Reserved.  See COPYRIGHT.
  *
 
 #include <stdio.h>
 #include <ctype.h>
+
+#include <atalk/util.h>
+#include <atalk/bstradd.h>
+
 #include "mangle.h"
 #include "desktop.h"
-#include <atalk/util.h>  
+
 
 #define hextoint( c )   ( isdigit( c ) ? c - '0' : c + 10 - 'A' )
 #define isuxdigit(x)    (isdigit(x) || (isupper(x) && isxdigit(x)))
@@ -28,7 +30,7 @@ static size_t mangle_extension(const struct vol *vol, const char* uname,
   char *p = strrchr(uname, '.');
 
   if (p && p != uname) {
-    u_int16_t flags = CONV_FORCE | CONV_UNESCAPEHEX;
+    uint16_t flags = CONV_FORCE | CONV_UNESCAPEHEX;
     size_t len = convert_charset(vol->v_volcharset, charset,
                                 vol->v_maccharset, p, strlen(p),
                                 extension, MAX_EXT_LENGTH, &flags);
@@ -38,28 +40,28 @@ static size_t mangle_extension(const struct vol *vol, const char* uname,
   return 0;
 }
 
-static char *demangle_checks ( const struct vol *vol, char* uname, char * mfilename, size_t prefix, char * ext)
+static char *demangle_checks(const struct vol *vol, char* uname, char * mfilename, size_t prefix, char * ext)
 {
-    u_int16_t flags;
-    static char buffer[MAXPATHLEN +1];
+    uint16_t flags;
+    static char buffer[MAXPATHLEN +2];  /* for convert_charset dest_len parameter +2 */
     size_t len;
     size_t mfilenamelen;
 
     /* We need to check, whether we really need to demangle the filename       */
     /* i.e. it's not just a file with a valid #HEX in the name ...             */
     /* but we don't want to miss valid demangle as well.                       */
-
     /* check whether file extensions match */
-    {
-      char buf[MAX_EXT_LENGTH + 1];
-      size_t ext_len = mangle_extension(vol, uname, buf, CH_UTF8_MAC);
-
-      if (ext_len) {
-       buf[ext_len] = '\0';
-       if (strcmp(ext, buf)) return mfilename;
-      } else {
-       if (*ext) return mfilename;
-      }
+
+    char buf[MAX_EXT_LENGTH + 2];  /* for convert_charset dest_len parameter +2 */
+    size_t ext_len = mangle_extension(vol, uname, buf, CH_UTF8_MAC);
+
+    if (ext_len) {
+        buf[ext_len] = '\0';
+        if (strcmp(ext, buf))
+            return mfilename;
+    } else {
+        if (*ext)
+            return mfilename;
     }
 
     /* First we convert the unix name to our volume maccharset         */
@@ -134,7 +136,7 @@ private_demangle(const struct vol *vol, char *mfilename, cnid_t did, cnid_t *osx
 {
     char *t;
     char *u_name;
-    u_int32_t id, file_id;
+    uint32_t id, file_id;
     static char buffer[12 + MAXPATHLEN + 1];
     int len = 12 + MAXPATHLEN + 1;
     struct dir *dir;
@@ -169,8 +171,8 @@ private_demangle(const struct vol *vol, char *mfilename, cnid_t did, cnid_t *osx
     }
 
     /* is it a dir?, there's a conflict with pre OSX 'trash #2'  */
-    if ((dir = dirsearch(vol, id))) {
-        if (dir->d_parent && dir->d_parent->d_did != did) {
+    if ((dir = dirlookup(vol, id))) {
+        if (dir->d_pdid != did) {
             /* not in the same folder, there's a race with outdate cache
              * but we have to live with it, hopefully client will recover
             */
@@ -178,13 +180,12 @@ private_demangle(const struct vol *vol, char *mfilename, cnid_t did, cnid_t *osx
         }
         if (!osx) {
             /* it's not from cname so mfilename and dir must be the same */
-            if (!strcmp(dir->d_m_name, mfilename)) {
-                return dir->d_u_name;
+            if (strcmp(cfrombstr(dir->d_m_name), mfilename) == 0) {
+                return cfrombstr(dir->d_u_name);
             }
-        } 
-        else {
-           return demangle_checks (vol, dir->d_u_name, mfilename, prefix, t);
-       }
+        } else {
+            return demangle_checks(vol, cfrombstr(dir->d_u_name), mfilename, prefix, t);
+        }
     }
     else if (NULL != (u_name = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
         if (id != did) {
@@ -222,25 +223,34 @@ demangle_osx(const struct vol *vol, char *mfilename, cnid_t did, cnid_t *fileid)
     return private_demangle(vol, mfilename, did, fileid);
 }
 
+/* -------------------------------------------------------
+   FIXME !!!
+
+   Early Mac OS X (10.0-10.4.?) had the limitation up to 255 Byte.
+   Current implementation is:
+      volcharset -> UTF16-MAC -> truncated 255 UTF8-MAC
+
+   Recent Mac OS X (10.4.?-) don't have this limitation.
+   Desirable implementation is:
+      volcharset -> truncated 510 UTF16-MAC -> UTF8-MAC
 
-/* -----------------------
+   ------------------------
    with utf8 filename not always round trip
    filename   mac filename too long or first chars if unmatchable chars.
    uname      unix filename 
    id         file/folder ID or 0
-   
 */
 char *
 mangle(const struct vol *vol, char *filename, size_t filenamelen, char *uname, cnid_t id, int flags) {
     char *m = NULL;
-    static char mfilename[MAXPATHLEN + 1];
+    static char mfilename[MAXPATHLEN]; /* way > maxlen */
     char mangle_suffix[MANGLE_LENGTH + 1];
-    char ext[MAX_EXT_LENGTH];
+    char ext[MAX_EXT_LENGTH +2];  /* for convert_charset dest_len parameter +2 */
     size_t ext_len;
     size_t maxlen;
     int k;
     
-    maxlen = (flags & 2)?255:MACFILELEN; /* was vol->max_filename */
+    maxlen = (flags & 2)?UTF8FILELEN_EARLY:MACFILELEN; /* was vol->max_filename */
     /* Do we really need to mangle this filename? */
     if (!(flags & 1) && filenamelen <= maxlen) {
        return filename;
@@ -256,7 +266,7 @@ mangle(const struct vol *vol, char *filename, size_t filenamelen, char *uname, c
     k = sprintf(mangle_suffix, "%c%X", MANGLE_CHAR, ntohl(id));
 
     if (filenamelen + k + ext_len > maxlen) {
-      u_int16_t opt = CONV_FORCE | CONV_UNESCAPEHEX;
+      uint16_t opt = CONV_FORCE | CONV_UNESCAPEHEX;
       size_t n = convert_charset(vol->v_volcharset,
                                 (flags & 2) ? CH_UTF8_MAC : vol->v_maccharset,
                                 vol->v_maccharset, uname, strlen(uname),