]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/volume.c
Remove incomplete mapchars option
[netatalk.git] / etc / afpd / volume.c
index 7f86f04db838bc34bc31cd770e6b88364f4dcf40..d68cb7ba15ebf2c3bf0d0fe5a96b51175a574074 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.112 2009-12-18 19:18:40 franklahm Exp $
+ * $Id: volume.c,v 1.123 2010-04-04 15:04:45 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -92,45 +92,37 @@ static void             free_extmap(void);
 #define VOLOPT_CASEFOLD   5  /* character case mangling */
 #define VOLOPT_FLAGS      6  /* various flags */
 #define VOLOPT_DBPATH     7  /* path to database */
-#define VOLOPT_MAPCHARS   8  /* does mtou and utom mappings. syntax:
-                                m and u can be double-byte hex
-                                strings if necessary.
-                                m=u -> map both ways
-                                m>u -> map m to u
-                                m<u -> map u to m
-                                !u  -> make u illegal always
-                                ~u  -> make u illegal only as the first
-                                part of a double-byte character.
-                             */
+/* Usable slots: 8 and 9 */
 #define VOLOPT_VETO          10  /* list of veto filespec */
 #define VOLOPT_PREEXEC       11  /* preexec command */
 #define VOLOPT_ROOTPREEXEC   12  /* root preexec command */
-
 #define VOLOPT_POSTEXEC      13  /* postexec command */
 #define VOLOPT_ROOTPOSTEXEC  14  /* root postexec command */
-
 #define VOLOPT_ENCODING      15  /* mac encoding (pre OSX)*/
 #define VOLOPT_MACCHARSET    16
 #define VOLOPT_CNIDSCHEME    17
 #define VOLOPT_ADOUBLE       18  /* adouble version */
+
 #ifdef FORCE_UIDGID
 #warning UIDGID
 #include "uid.h"
 
-#define VOLOPT_FORCEUID  19  /* force uid for username x */
-#define VOLOPT_FORCEGID  20  /* force gid for group x */
+#define VOLOPT_FORCEUID      19  /* force uid for username x */
+#define VOLOPT_FORCEGID      20  /* force gid for group x */
 #endif /* FORCE_UIDGID */
 
-#define VOLOPT_UMASK     21
+#define VOLOPT_UMASK         21
 #define VOLOPT_ALLOWED_HOSTS 22
 #define VOLOPT_DENIED_HOSTS  23
-#define VOLOPT_DPERM     24  /* dperm default directories perms */
-#define VOLOPT_FPERM     25  /* fperm default files perms */
-#define VOLOPT_DFLTPERM  26  /* perm */
-#define VOLOPT_EA_VFS    27  /* Extended Attributes vfs indirection */
+#define VOLOPT_DPERM         24  /* dperm default directories perms */
+#define VOLOPT_FPERM         25  /* fperm default files perms */
+#define VOLOPT_DFLTPERM      26  /* perm */
+#define VOLOPT_EA_VFS        27  /* Extended Attributes vfs indirection */
+#define VOLOPT_CNIDSERVER    28  /* CNID Server ip address*/
+#define VOLOPT_CNIDPORT      30  /* CNID server tcp port */
 
-#define VOLOPT_MAX       28  /* <== IMPORTANT !!!!!! */
-#define VOLOPT_NUM       (VOLOPT_MAX + 1)
+#define VOLOPT_MAX           31  /* <== IMPORTANT !!!!!! */
+#define VOLOPT_NUM           (VOLOPT_MAX + 1)
 
 #define VOLPASSLEN  8
 #define VOLOPT_DEFAULT     ":DEFAULT:"
@@ -470,6 +462,18 @@ static void volset(struct vol_option *options, struct vol_option *save,
             p = strtok(NULL, ",");
         }
 
+    } else if (optionok(tmp, "cnidserver:", val)) {
+        setoption(options, save, VOLOPT_CNIDSERVER, val);
+
+        char *p = strrchr(val + 1, ':');
+        if (p) {
+            *p = 0;
+            setoption(options, save, VOLOPT_CNIDPORT, p);
+        }
+
+        LOG(log_debug, logtype_afpd, "CNID Server for volume '%s': %s:%s",
+            volname, val + 1, p ? p + 1 : Cnid_port);
+
     } else if (optionok(tmp, "dbpath:", val)) {
         setoption(options, save, VOLOPT_DBPATH, val);
 
@@ -481,9 +485,6 @@ static void volset(struct vol_option *options, struct vol_option *save,
         options[VOLOPT_FPERM].i_value = (int)strtol(val+1, NULL, 8);
     } else if (optionok(tmp, "perm:", val)) {
         options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8);
-    } else if (optionok(tmp, "mapchars:",val)) {
-        setoption(options, save, VOLOPT_MAPCHARS, val);
-
     } else if (optionok(tmp, "password:", val)) {
         setoption(options, save, VOLOPT_PASSWORD, val);
 
@@ -696,6 +697,8 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
             volume->v_ad_options |= ADVOL_UNIXPRIV;
         if ((volume->v_flags & AFPVOL_INV_DOTS))
             volume->v_ad_options |= ADVOL_INVDOTS;
+        if ((volume->v_flags & AFPVOL_NOADOUBLE))
+            volume->v_ad_options |= ADVOL_NOADOUBLE;
 
         if (options[VOLOPT_PASSWORD].c_value)
             volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
@@ -715,6 +718,12 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
         if (options[VOLOPT_CNIDSCHEME].c_value)
             volume->v_cnidscheme = strdup(options[VOLOPT_CNIDSCHEME].c_value);
 
+        if (options[VOLOPT_CNIDSERVER].c_value)
+            volume->v_cnidserver = strdup(options[VOLOPT_CNIDSERVER].c_value);
+
+        if (options[VOLOPT_CNIDPORT].c_value)
+            volume->v_cnidport = strdup(options[VOLOPT_CNIDPORT].c_value);
+
         if (options[VOLOPT_UMASK].i_value)
             volume->v_umask = (mode_t)options[VOLOPT_UMASK].i_value;
 
@@ -980,12 +989,12 @@ static void setextmap(char *ext, char *type, char *creator, int user)
     }
 
     if ( *type == '\0' ) {
-        memcpy(em->em_type, "????", sizeof( em->em_type ));
+        memcpy(em->em_type, "\0\0\0\0", sizeof( em->em_type ));
     } else {
         memcpy(em->em_type, type, sizeof( em->em_type ));
     }
     if ( *creator == '\0' ) {
-        memcpy(em->em_creator, "UNIX", sizeof( em->em_creator ));
+        memcpy(em->em_creator, "\0\0\0\0", sizeof( em->em_creator ));
     } else {
         memcpy(em->em_creator, creator, sizeof( em->em_creator ));
     }
@@ -1408,7 +1417,7 @@ static int getvolparams( u_int16_t bitmap, struct vol *vol, struct stat *st, cha
      * .Parent file here if it doesn't exist. */
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if ( ad_open_metadata( vol->v_path, vol_noadouble(vol) | ADFLAGS_DIR, O_CREAT, &ad) < 0 ) {
+    if ( ad_open_metadata( vol->v_path, ADFLAGS_DIR, O_CREAT, &ad) < 0 ) {
         isad = 0;
         vol->v_ctime = AD_DATE_FROM_UNIX(st->st_mtime);
 
@@ -1816,15 +1825,20 @@ static int volume_openDB(struct vol *volume)
         volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME);
         LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.", volume->v_path, volume->v_cnidscheme);
     }
-    if (volume->v_dbpath)
-        volume->v_cdb = cnid_open (volume->v_dbpath, volume->v_umask, volume->v_cnidscheme, flags);
-    else
-        volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, volume->v_cnidscheme, flags);
+
+    LOG(log_info, logtype_afpd, "%s:%s", volume->v_cnidserver, volume->v_cnidport);
+    
+    volume->v_cdb = cnid_open(volume->v_dbpath ? volume->v_dbpath : volume->v_path,
+                              volume->v_umask,
+                              volume->v_cnidscheme,
+                              flags,
+                              volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+                              volume->v_cnidport ? volume->v_cnidport : Cnid_port);
 
     if (!volume->v_cdb) {
         flags |= CNID_FLAG_MEMORY;
         LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.", volume->v_path);
-        volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags);
+        volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags, NULL, NULL);
 #ifdef SERVERTEXT
         /* kill ourself with SIGUSR2 aka msg pending */
         if (volume->v_cdb) {
@@ -1991,6 +2005,27 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         return AFPERR_MISC;
     }
 
+    /* Normalize volume path */
+#ifdef REALPATH_TAKES_NULL
+    if ((volume->v_path = realpath(path, NULL)) == NULL)
+        return AFPERR_MISC;
+#else
+    if ((volume->v_path = malloc(MAXPATHLEN+1)) == NULL)
+        return AFPERR_MISC;
+    if (realpath(path, volume->v_path) == NULL) {
+        free(volume->v_path);
+        return AFPERR_MISC;
+    }
+    /* Safe some memory */
+    char *tmp;
+    if ((tmp = strdup(volume->v_path)) == NULL) {
+        free(volume->v_path);
+        return AFPERR_MISC;
+    } 
+    free(volume->v_path);
+    volume->v_path = tmp;
+#endif
+
     if (volume_codepage(obj, volume) < 0) {
         ret = AFPERR_MISC;
         goto openvol_err;
@@ -2055,7 +2090,9 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
 
         if (!(volume->v_flags & AFPVOL_RO)) {
             handle_special_folders( volume );
-            savevolinfo(volume, Cnid_srv, Cnid_port);
+            savevolinfo(volume,
+                        volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+                        volume->v_cnidport   ? volume->v_cnidport   : Cnid_port);
         }
 
         /*
@@ -2297,9 +2334,9 @@ void setvoltime(AFPObj *obj, struct vol *vol)
     if (vol->v_mtime < tv.tv_sec) {
         vol->v_mtime = tv.tv_sec;
         /* or finder doesn't update free space
-         * XXX is it still true with newer OSX?
+         * AFP 3.2 and above clients seem to be ok without so many notification
          */
-        if (afp_version > 21 && obj->options.server_notif) {
+        if (afp_version < 32 && obj->options.server_notif) {
             obj->attention(obj->handle, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
         }
     }
@@ -2450,19 +2487,13 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
     if ( !ret && folder->hide) {
         /* Hide it */
         ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-        if (ad_open( p, vol_noadouble(vol) | ADFLAGS_HF|ADFLAGS_DIR,
-                     O_RDWR|O_CREAT, 0666, &ad) < 0) {
+        if (ad_open_metadata( p, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
             free (p);
             free(q);
             return (-1);
         }
-        if ((ad_get_HF_flags( &ad ) & O_CREAT) ) {
-            if (ad_getentryoff(&ad, ADEID_NAME)) {
-                ad_setentrylen( &ad, ADEID_NAME, strlen(folder->name));
-                memcpy(ad_entry( &ad, ADEID_NAME ), folder->name,
-                       ad_getentrylen( &ad, ADEID_NAME ));
-            }
-        }
+        
+        ad_setname(&ad, folder->name);
 
         ad_getattr(&ad, &attr);
         attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE );
@@ -2476,7 +2507,7 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
         }
 
         ad_flush( &ad );
-        ad_close( &ad, ADFLAGS_HF );
+        ad_close_metadata( &ad);
     }
     free(p);
     free(q);