]> arthur.barton.de Git - netatalk.git/commitdiff
Merge remote branch 'origin/develop' into nohex
authorFrank Lahm <franklahm@googlemail.com>
Thu, 29 Mar 2012 17:19:47 +0000 (19:19 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 29 Mar 2012 17:19:47 +0000 (19:19 +0200)
13 files changed:
bin/ad/ad_util.c
etc/afpd/enumerate.c
etc/afpd/filedir.c
etc/afpd/volume.c
etc/cnid_dbd/cmd_dbd_scanvol.c
include/atalk/adouble.h
include/atalk/volume.h
libatalk/adouble/Makefile.am
libatalk/adouble/ad_conv.c [new file with mode: 0644]
libatalk/adouble/ad_open.c
libatalk/unicode/charcnv.c
libatalk/util/netatalk_conf.c
libatalk/vfs/vfs.c

index d994f74f56afa666fe8376d142c882fcf6a83aaa..682bc57c98190191bccdc5f6721315395b62d6d3 100644 (file)
@@ -216,15 +216,6 @@ int convert_dots_encoding(const afpvol_t *svol, const afpvol_t *dvol, char *path
         from = svol->vol->v_volcharset;
     }
 
-    if ( (svol->vol->v_path)
-         && ! (svol->vol->v_flags & AFPVOL_USEDOTS)
-         && (dvol->vol->v_flags & AFPVOL_USEDOTS)) {
-        /* source is without dots, destination is with */
-        flags |= CONV_UNESCAPEHEX;
-    } else if (! (dvol->vol->v_flags & AFPVOL_USEDOTS)) {
-        flags |= CONV_ESCAPEDOTS;
-    }
-
     int len = convert_charset(from,
                               dvol->vol->v_volcharset,
                               dvol->vol->v_maccharset,
index 80759a439cf61bfed6f088b0641bf5e4c48a907a..f77d34a522a91ce702ff80599540791684586548 100644 (file)
@@ -347,13 +347,15 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
             continue;
         }
         memset(&s_path, 0, sizeof(s_path));
+
+        /* conversions on the fly */
+        const char *convname;
         s_path.u_name = sd.sd_last;
-        if (of_stat( &s_path) < 0 ) {
-            /*
-             * Somebody else plays with the dir, well it can be us with 
-            * "Empty Trash..."
-            */
+        if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0 && convname) {
+            s_path.u_name = (char *)convname;
+        }
 
+        if (of_stat( &s_path) < 0 ) {
             /* so the next time it won't try to stat it again
              * another solution would be to invalidate the cache with 
              * sd.sd_did = 0 but if it's not ENOENT error it will start again
@@ -364,12 +366,18 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
             continue;
         }
 
+        /* Fixup CNID db if ad_convert resulted in a rename (then convname != NULL) */
+        if (convname) {
+            s_path.id = cnid_lookup(vol->v_cdb, &s_path.st, curdir->d_did, sd.sd_last, strlen(sd.sd_last));
+            if (s_path.id != CNID_INVALID) {
+                if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, convname, strlen(convname)) != 0)
+                    LOG(log_error, logtype_afpd, "enumerate: error updating CNID of \"%s\"", fullpathname(convname));
+            }
+        }
+
         sd.sd_last += len + 1;
         s_path.m_name = NULL;
 
-        /* Convert adouble:v2 to adouble:ea on the fly */
-        (void)ad_convert(s_path.u_name, &s_path.st, vol);
-
         /*
          * If a fil/dir is not a dir, it's a file. This is slightly
          * inaccurate, since that means /dev/null is a file, /dev/printer
index a04776fae35148b85735549221f22f0f2e479722..17473d19e7788adc542e8c95f8d66ed4b0e28e08 100644 (file)
@@ -203,9 +203,6 @@ int afp_setfildirparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf
 */
 int check_name(const struct vol *vol, char *name)
 {
-    if ((vol->v_flags & AFPVOL_NOHEX) && strchr(name, '/'))
-        return AFPERR_PARAM;
-
     if (!vol->vfs->vfs_validupath(vol, name)) {
         LOG(log_error, logtype_afpd, "check_name: illegal name: '%s'", name);
         return AFPERR_EXIST;
index 1d4081e29212e9dcd851e8e39efbaccfc7fe3273..61d744ca70cdc980d21b98734a06b25682e3e1d9 100644 (file)
@@ -321,7 +321,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str
      * .Parent file here if it doesn't exist. */
 
     /* Convert adouble:v2 to adouble:ea on the fly */
-    (void)ad_convert(vol->v_path, st, vol);
+    (void)ad_convert(vol->v_path, st, vol, NULL);
 
     ad_init(&ad, vol);
     if (ad_open(&ad, vol->v_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0 ) {
index 9685c3d219c341a81aa48de436abd2e3f3bb4ca0..6b486dc68c6da7127e3093df156d2095447669f9 100644 (file)
@@ -124,11 +124,6 @@ static char *mtoupath(char *mpath)
     }
 
     /* set conversion flags */
-    if (!(myvol->v_flags & AFPVOL_NOHEX))
-        flags |= CONV_ESCAPEHEX;
-    if (!(myvol->v_flags & AFPVOL_USEDOTS))
-        flags |= CONV_ESCAPEDOTS;
-
     if ((myvol->v_casefold & AFPVOL_MTOUUPPER))
         flags |= CONV_TOUPPER;
     else if ((myvol->v_casefold & AFPVOL_MTOULOWER))
@@ -221,7 +216,7 @@ static int check_adfile(const char *fname, const struct stat *st)
     if (myvol->v_adouble == AD_VERSION_EA) {
         if (!(dbd_flags & DBD_FLAGS_V2TOEA))
             return 0;
-        if (ad_convert(fname, st, myvol) != 0) {
+        if (ad_convert(fname, st, myvol, NULL) != 0) {
             switch (errno) {
             case ENOENT:
                 break;
@@ -1002,7 +997,7 @@ static int scanvol(struct vol *vol, dbd_flags_t flags)
     if ((myvol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) {
         if (lstat(".", &st) != 0)
             return -1;
-        if (ad_convert(".", &st, vol) != 0) {
+        if (ad_convert(".", &st, vol, NULL) != 0) {
             switch (errno) {
             case ENOENT:
                 break;
index 5b276a5a27a2e8255266eb5bbf810e3c0b19c2b8..f95279d7aa7779ada385ea7642799aad682b832e 100644 (file)
@@ -403,8 +403,11 @@ extern int ad_stat        (const char *, struct stat *);
 extern int ad_metadata    (const char *, int, struct adouble *);
 extern int ad_metadataat  (int, const char *, int, struct adouble *);
 extern mode_t ad_hf_mode(mode_t mode);
-extern int ad_convert(const char *path, const struct stat *sp, const struct vol *vol);
 extern int ad_valid_header_osx(const char *path);
+
+/* ad_conv.c */
+extern int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, const char **newpath);
+
 /* ad_read.c/ad_write.c */
 extern int     sys_ftruncate(int fd, off_t length);
 extern ssize_t ad_read(struct adouble *, uint32_t, off_t, char *, size_t);
index d8948500e8eb86d57df8fc95236d7790016fd0f0..f5e995d28319c2be8665d2896f422c70eab35342 100644 (file)
@@ -114,8 +114,6 @@ struct vol {
 #define AFPVOL_NOV2TOEACONV (1 << 5) /* no adouble:v2 to adouble:ea conversion */
 #define AFPVOL_UNIX_CTXT (1 << 6)   /* volume created by getvolbypath ie UNIX access, not afpd AFP user session */
 #define AFPVOL_RO        (1 << 8)   /* read-only volume */
-#define AFPVOL_NOHEX     (1 << 10)  /* don't do :hex translation */
-#define AFPVOL_USEDOTS   (1 << 11)  /* use real dots */
 #define AFPVOL_NOSTAT    (1 << 16)  /* advertise the volume even if we can't stat() it
                                      * maybe because it will be mounted later in preexec */
 #define AFPVOL_UNIX_PRIV (1 << 17)  /* support unix privileges */
index 6602926b6328986453cb395bbb9c476bdf582aca..49144a2aa62831042f33efff428316378d724b60 100644 (file)
@@ -2,7 +2,17 @@
 
 noinst_LTLIBRARIES = libadouble.la
 
-libadouble_la_SOURCES = ad_open.c ad_flush.c ad_read.c ad_write.c ad_size.c \
-       ad_mmap.c ad_lock.c ad_date.c ad_attr.c ad_sendfile.c
+libadouble_la_SOURCES = \
+       ad_attr.c \
+       ad_conv.c \
+       ad_date.c \
+       ad_flush.c \
+       ad_lock.c \
+       ad_mmap.c \
+       ad_open.c \
+       ad_read.c \
+       ad_sendfile.c \
+       ad_size.c \
+       ad_write.c
 
 noinst_HEADERS = ad_lock.h
diff --git a/libatalk/adouble/ad_conv.c b/libatalk/adouble/ad_conv.c
new file mode 100644 (file)
index 0000000..10284db
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2012 Frank Lahm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*!
+ * @file
+ * Part of Netatalk's AppleDouble implementatation
+ * @sa include/atalk/adouble.h
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <errno.h>
+#include <sys/param.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <arpa/inet.h>
+
+#include <atalk/logger.h>
+#include <atalk/adouble.h>
+#include <atalk/util.h>
+#include <atalk/unix.h>
+#include <atalk/ea.h>
+#include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
+#include <atalk/compat.h>
+#include <atalk/errchk.h>
+#include <atalk/volume.h>
+
+#include "ad_lock.h"
+
+static char emptyfilad[32] = {0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0};
+
+static char emptydirad[32] = {0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,1,0,
+                              0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0};
+
+static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struct vol *vol)
+{
+    EC_INIT;
+    struct adouble adv2;
+    struct adouble adea;
+    const char *adpath;
+    int adflags;
+    uint32_t ctime, mtime, afpinfo = 0;
+    char *emptyad;
+
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path));
+
+    ad_init(&adea, vol);
+    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
+    adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
+
+    /* Open and lock adouble:v2 file */
+    EC_ZERO( ad_open(&adv2, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR) );
+
+    EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );
+    EC_NEG1_LOG( adv2.ad_ops->ad_header_read(path, &adv2, sp) );
+
+    /* Check if it's a non-empty header */
+    if (S_ISREG(sp->st_mode))
+        emptyad = &emptyfilad[0];
+    else
+        emptyad = &emptydirad[0];
+
+    if (ad_getentrylen(&adv2, ADEID_COMMENT) != 0)
+        goto copy;
+    if (ad_getentryoff(&adv2, ADEID_FINDERI)
+        && (ad_getentrylen(&adv2, ADEID_FINDERI) == ADEDLEN_FINDERI)
+        && (memcmp(ad_entry(&adv2, ADEID_FINDERI), emptyad, ADEDLEN_FINDERI) != 0))
+        goto copy;
+    if (ad_getentryoff(&adv2, ADEID_FILEDATESI)) {
+        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_CREATE | AD_DATE_UNIX, &ctime) );
+        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_MODIFY | AD_DATE_UNIX, &mtime) );
+        if ((ctime != mtime) || (mtime != sp->st_mtime))
+            goto copy;
+    }
+    if (ad_getentryoff(&adv2, ADEID_AFPFILEI)) {
+        if (memcmp(ad_entry(&adv2, ADEID_AFPFILEI), &afpinfo, ADEDLEN_AFPFILEI) != 0)
+            goto copy;
+    }
+
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret);
+    goto EC_CLEANUP;
+
+copy:
+    /* Create a adouble:ea meta EA */
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret);
+    EC_ZERO_LOG( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE) );
+    EC_ZERO_LOG( ad_copy_header(&adea, &adv2) );
+    ad_flush(&adea);
+
+EC_CLEANUP:
+    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
+    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret);
+    EC_EXIT;
+}
+
+static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struct vol *vol)
+{
+    EC_INIT;
+    struct adouble adv2;
+    struct adouble adea;
+
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path));
+
+    if (S_ISDIR(sp->st_mode))
+        return 0;
+
+    ad_init(&adea, vol);
+    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
+
+    /* Open and lock adouble:v2 file */
+    EC_ZERO( ad_open(&adv2, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR) );
+
+    if (adv2.ad_rlen > 0) {
+        EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );
+
+        /* Create a adouble:ea resource fork */
+        EC_ZERO_LOG( ad_open(&adea, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) );
+
+        EC_ZERO_LOG( copy_fork(ADEID_RFORK, &adea, &adv2) );
+        adea.ad_rlen = adv2.ad_rlen;
+        ad_flush(&adea);
+    }
+
+EC_CLEANUP:
+    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_RF) );
+    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_RF) );
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret);
+    EC_EXIT;
+}
+
+static int ad_conv_v22ea(const char *path, const struct stat *sp, const struct vol *vol)
+{
+    EC_INIT;
+    const char *adpath;
+    int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
+
+    EC_ZERO( ad_conv_v22ea_hf(path, sp, vol) );
+    EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) );
+
+    EC_NULL( adpath = ad_path(path, adflags) );
+    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"",
+        path, fullpathname(adpath));
+
+    become_root();
+    EC_ZERO_LOG( unlink(adpath) );
+    unbecome_root();
+
+EC_CLEANUP:
+    if (errno == ENOENT)
+        EC_STATUS(0);
+    EC_EXIT;
+}
+
+/*!
+ * Remove hexencoded dots and slashes (":2e" and ":2f")
+ */
+static int ad_conv_dehex(const char *path, const struct stat *sp, const struct vol *vol, const char **newpathp)
+{
+    EC_INIT;
+    static char buf[MAXPATHLEN];
+    const char *adpath, *p;
+    int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
+    bstring newpath = NULL;
+
+    LOG(log_debug, logtype_default,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path));
+
+    *newpathp = NULL;
+
+    if ((p = strchr(path, ':')) == NULL)
+        goto EC_CLEANUP;
+
+    EC_NULL( newpath = bfromcstr(path) );
+
+    EC_ZERO( bfindreplace(newpath, bfromcstr(":2e"), bfromcstr("."), 0) );
+    EC_ZERO( bfindreplace(newpath, bfromcstr(":2f"), bfromcstr(":"), 0) );
+    
+    become_root();
+    if (adflags != ADFLAGS_DIR)
+        rename(vol->ad_path(path, 0), vol->ad_path(bdata(newpath), 0));
+    rename(path, bdata(newpath));
+    unbecome_root();
+
+    strlcpy(buf, bdata(newpath), sizeof(buf));
+    *newpathp = buf;
+
+EC_CLEANUP:
+    if (newpath)
+        bdestroy(newpath);
+    EC_EXIT;
+}
+
+/*!
+ * AppleDouble and encoding conversion on the fly
+ *
+ * @param path      (r) path to file or directory
+ * @param sp        (r) stat(path)
+ * @param vol       (r) volume handle
+ * @param newpath   (w) if encoding changed, new name. Can be NULL.
+ *
+ * @returns         -1 on internal error, otherwise 0. newpath is NULL if no character conversion was done,
+ *                  otherwise newpath points to a static string with the converted name
+ */
+int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, const char **newpath)
+{
+    EC_INIT;
+    const char *p;
+
+    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): BEGIN", fullpathname(path));
+
+    if (newpath)
+        *newpath = NULL;
+
+    if ((vol->v_adouble == AD_VERSION_EA) && !(vol->v_flags & AFPVOL_NOV2TOEACONV))
+        EC_ZERO( ad_conv_v22ea(path, sp, vol) );
+
+    if (vol->v_adouble == AD_VERSION_EA) {
+        EC_ZERO( ad_conv_dehex(path, sp, vol, &p) );
+        if (p && newpath)
+            *newpath = p;
+    }
+
+EC_CLEANUP:
+    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret);
+    EC_EXIT;
+}
+
index 196053ee31ab288601b4c365f56da42600c00263..79016b5feac43e1d6fed2110e2d5e320610470e9 100644 (file)
@@ -809,111 +809,6 @@ static int ad2openflags(const struct adouble *ad, int adfile, int adflags)
     return oflags;
 }
 
-static char emptyfilad[32] = {0,0,0,0,0,0,0,0,
-                              0,0,0,0,0,0,0,0,
-                              0,0,0,0,0,0,0,0,
-                              0,0,0,0,0,0,0,0};
-
-static char emptydirad[32] = {0,0,0,0,0,0,0,0,
-                              0,0,0,0,0,0,1,0,
-                              0,0,0,0,0,0,0,0,
-                              0,0,0,0,0,0,0,0};
-
-static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struct vol *vol)
-{
-    EC_INIT;
-    struct adouble adv2;
-    struct adouble adea;
-    const char *adpath;
-    int adflags;
-    uint32_t ctime, mtime, afpinfo = 0;
-    char *emptyad;
-
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path));
-
-    ad_init(&adea, vol);
-    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
-    adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
-
-    /* Open and lock adouble:v2 file */
-    EC_ZERO( ad_open(&adv2, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR) );
-    EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );
-    EC_NEG1_LOG( adv2.ad_ops->ad_header_read(path, &adv2, sp) );
-
-    /* Check if it's a non-empty header */
-    if (S_ISREG(sp->st_mode))
-        emptyad = &emptyfilad[0];
-    else
-        emptyad = &emptydirad[0];
-
-    if (ad_getentrylen(&adv2, ADEID_COMMENT) != 0)
-        goto copy;
-    if (ad_getentryoff(&adv2, ADEID_FINDERI)
-        && (ad_getentrylen(&adv2, ADEID_FINDERI) == ADEDLEN_FINDERI)
-        && (memcmp(ad_entry(&adv2, ADEID_FINDERI), emptyad, ADEDLEN_FINDERI) != 0))
-        goto copy;
-    if (ad_getentryoff(&adv2, ADEID_FILEDATESI)) {
-        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_CREATE | AD_DATE_UNIX, &ctime) );
-        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_MODIFY | AD_DATE_UNIX, &mtime) );
-        if ((ctime != mtime) || (mtime != sp->st_mtime))
-            goto copy;
-    }
-    if (ad_getentryoff(&adv2, ADEID_AFPFILEI)) {
-        if (memcmp(ad_entry(&adv2, ADEID_AFPFILEI), &afpinfo, ADEDLEN_AFPFILEI) != 0)
-            goto copy;
-    }
-
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret);
-    goto EC_CLEANUP;
-
-copy:
-    /* Create a adouble:ea meta EA */
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret);
-    EC_ZERO_LOG( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE) );
-    EC_ZERO_LOG( ad_copy_header(&adea, &adv2) );
-    ad_flush(&adea);
-
-EC_CLEANUP:
-    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
-    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret);
-    EC_EXIT;
-}
-
-static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struct vol *vol)
-{
-    EC_INIT;
-    struct adouble adv2;
-    struct adouble adea;
-
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path));
-
-    if (S_ISDIR(sp->st_mode))
-        return 0;
-
-    ad_init(&adea, vol);
-    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
-
-    /* Open and lock adouble:v2 file */
-    EC_ZERO( ad_open(&adv2, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR) );
-    if (adv2.ad_rlen > 0) {
-        EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );
-
-        /* Create a adouble:ea resource fork */
-        EC_ZERO_LOG( ad_open(&adea, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) );
-
-        EC_ZERO_LOG( copy_fork(ADEID_RFORK, &adea, &adv2) );
-        adea.ad_rlen = adv2.ad_rlen;
-        ad_flush(&adea);
-    }
-
-EC_CLEANUP:
-    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_RF) );
-    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_RF) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret);
-    EC_EXIT;
-}
-
 static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble *ad)
 {
     EC_INIT;
@@ -1929,33 +1824,6 @@ EC_CLEANUP:
     return ret;
 }
 
-int ad_convert(const char *path, const struct stat *sp, const struct vol *vol)
-{
-    EC_INIT;
-    const char *adpath;
-    int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
-
-    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): BEGIN", fullpathname(path));
-
-    if (!(vol->v_adouble == AD_VERSION_EA) || (vol->v_flags & AFPVOL_NOV2TOEACONV))
-        goto EC_CLEANUP;
-
-    EC_ZERO( ad_conv_v22ea_hf(path, sp, vol) );
-    EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) );
-
-    EC_NULL( adpath = ad_path(path, adflags) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"",
-        path, fullpathname(adpath));
-
-    become_root();
-    EC_ZERO_LOG( unlink(adpath) );
-    unbecome_root();
-
-EC_CLEANUP:
-    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret);
-    EC_EXIT;
-}
-
 /* build a resource fork mode from the data fork mode:
  * remove X mode and extend header to RW if R or W (W if R for locking),
  */
index fe33a21784f3eeb0125c33c99d0282c4f43f3665..455a72622ef9fb0f2aa7543aec6bfe6feb651c57 100644 (file)
@@ -772,13 +772,11 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c
     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) {
@@ -806,36 +804,48 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c
         }
 
         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--;
             }
         }
     }
@@ -897,25 +907,23 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src
     }
 
     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 &&
@@ -968,35 +976,53 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src
         }
 
         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;
index af5a21ae8625c02407f93d9d9566748b63c30b18..d06be264051bdd9de82934deddfa753bd4ec32ea 100644 (file)
@@ -719,10 +719,6 @@ static struct vol *creatvol(AFPObj *obj,
 
     if (getoption_bool(obj->iniconfig, section, "read only", preset, 0))
         volume->v_flags |= AFPVOL_RO;
-    if (!getoption_bool(obj->iniconfig, section, "hex encoding", preset, 1))
-        volume->v_flags |= AFPVOL_NOHEX;
-    if (getoption_bool(obj->iniconfig, section, "use dots", preset, 1))
-        volume->v_flags |= AFPVOL_USEDOTS;
     if (getoption_bool(obj->iniconfig, section, "invisible dots", preset, 0))
         volume->v_flags |= AFPVOL_INV_DOTS;
     if (!getoption_bool(obj->iniconfig, section, "stat vol", preset, 1))
@@ -771,10 +767,6 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_ad_options |= ADVOL_INVDOTS;
 
     /* Mac to Unix conversion flags*/
-    if (!(volume->v_flags & AFPVOL_NOHEX))
-        volume->v_mtou_flags |= CONV_ESCAPEHEX;
-    if (!(volume->v_flags & AFPVOL_USEDOTS))
-        volume->v_mtou_flags |= CONV_ESCAPEDOTS;
     if ((volume->v_flags & AFPVOL_EILSEQ))
         volume->v_mtou_flags |= CONV__EILSEQ;
 
@@ -784,7 +776,7 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_mtou_flags |= CONV_TOLOWER;
 
     /* Unix to Mac conversion flags*/
-    volume->v_utom_flags = CONV_IGNORE | CONV_UNESCAPEHEX;
+    volume->v_utom_flags = CONV_IGNORE;
     if ((volume->v_casefold & AFPVOL_UTOMUPPER))
         volume->v_utom_flags |= CONV_TOUPPER;
     else if ((volume->v_casefold & AFPVOL_UTOMLOWER))
index 738e3b837851abc278296f05ebe6d038559dcbc6..8495d8c22fba19dd88789b82c6822bfb4a4fb3d6 100644 (file)
@@ -103,9 +103,6 @@ static int validupath_adouble(VFS_FUNC_ARGS_VALIDUPATH)
     if (name[0] != '.')
         return 1;
     
-    if (!(vol->v_flags & AFPVOL_USEDOTS))
-        return 0;
-        
     return netatalk_name(name) && strcmp(name,".AppleDouble") && strcasecmp(name,".Parent");
 }                                           
 
@@ -467,9 +464,6 @@ static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH)
     if (name[0] != '.')
         return 1;
     
-    if (!(vol->v_flags & AFPVOL_USEDOTS))
-        return 0;
-
 #ifndef HAVE_EAFD
     if (name[1] == '_')
         return ad_valid_header_osx(name);