]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/volume.c
Whitespace and exclamation mark fixes
[netatalk.git] / etc / afpd / volume.c
index a8b0754dd0cd799eb7c9a8c914ee3f6fa9b381e4..da57a30a822491746f603ba6112516b3ac325dac 100644 (file)
@@ -26,7 +26,6 @@
 #include <atalk/adouble.h>
 #include <atalk/afp.h>
 #include <atalk/util.h>
-#include <atalk/volinfo.h>
 #include <atalk/logger.h>
 #include <atalk/vfs.h>
 #include <atalk/uuid.h>
 
 extern int afprun(int root, char *cmd, int *outfd);
 
-typedef struct _special_folder {
-    const char *name;
-    int precreate;
-    mode_t mode;
-    int hide;
-} _special_folder;
-
-static const _special_folder special_folders[] = {
-    {".AppleDesktop",            1,  0777,  0},
-    {NULL, 0, 0, 0}};
-
-/* Forward declarations */
-static void handle_special_folders (const struct vol *);
-
-static void showvol(const ucs2_t *name)
-{
-    struct vol  *volume = getvolumes();
-
-    for ( ; volume; volume = volume->v_next ) {
-        if (volume->v_hide && !strcasecmp_w( volume->v_name, name ) ) {
-            volume->v_hide = 0;
-            return;
-        }
-    }
-}
-
-static void closevol(struct vol *vol)
-{
-    if (!vol)
-        return;
-
-    vol->v_flags &= ~AFPVOL_OPEN;
-
-    of_closevol(vol);
-
-    dir_free( vol->v_root );
-    vol->v_root = NULL;
-    if (vol->v_cdb != NULL) {
-        cnid_close(vol->v_cdb);
-        vol->v_cdb = NULL;
-    }
-
-    if (vol->v_postexec) {
-        afprun(0, vol->v_postexec, NULL);
-    }
-    if (vol->v_root_postexec) {
-        afprun(1, vol->v_root_postexec, NULL);
-    }
-
-    if (vol->v_deleted) {
-        showvol(vol->v_name);
-        volume_free(vol);
-        volume_unlink(vol);
-        free(vol);
-    }
-}
-
 /*!
  * Read band-size info from Info.plist XML file of an TM sparsebundle
  *
@@ -277,7 +219,7 @@ static int getvolspace(const AFPObj *obj, struct vol *vol,
 
     spaceflag = AFPVOL_GVSMASK & vol->v_flags;
     /* report up to 2GB if afp version is < 2.2 (4GB if not) */
-    maxsize = (afp_version < 22) ? 0x7fffffffL : 0xffffffffL;
+    maxsize = (obj->afp_version < 22) ? 0x7fffffffL : 0xffffffffL;
 
 #ifdef AFS
     if ( spaceflag == AFPVOL_NONE || spaceflag == AFPVOL_AFSGVS ) {
@@ -379,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 ) {
@@ -438,12 +380,12 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str
                 ashort |= VOLPBIT_ATTR_RO;
             }
             /* prior 2.1 only VOLPBIT_ATTR_RO is defined */
-            if (afp_version > 20) {
+            if (obj->afp_version > 20) {
                 if (vol->v_cdb != NULL && (vol->v_cdb->flags & CNID_FLAG_PERSISTENT))
                     ashort |= VOLPBIT_ATTR_FILEID;
                 ashort |= VOLPBIT_ATTR_CATSEARCH;
 
-                if (afp_version >= 30) {
+                if (obj->afp_version >= 30) {
                     ashort |= VOLPBIT_ATTR_UTF8;
                     if (vol->v_flags & AFPVOL_UNIX_PRIV)
                         ashort |= VOLPBIT_ATTR_UNIXPRIV;
@@ -451,7 +393,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str
                         ashort |= VOLPBIT_ATTR_TM;
                     if (vol->v_flags & AFPVOL_NONETIDS)
                         ashort |= VOLPBIT_ATTR_NONETIDS;
-                    if (afp_version >= 32) {
+                    if (obj->afp_version >= 32) {
                         if (vol->v_vfs_ea)
                             ashort |= VOLPBIT_ATTR_EXT_ATTRS;
                         if (vol->v_flags & AFPVOL_ACLS)
@@ -601,7 +543,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
     int         vcnt;
     size_t      len;
 
-    load_volumes(obj, of_closevol);
+    load_volumes(obj, closevol);
 
     data = rbuf + 5;
     for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
@@ -621,11 +563,8 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
                 continue;   /* no r-x access */
             }
         }
-        if (volume->v_hide) {
-            continue;       /* config file changed but the volume was mounted */
-        }
 
-        if (utf8_encoding()) {
+        if (utf8_encoding(obj)) {
             len = ucs2_to_charset_allocate(CH_UTF8_MAC, &namebuf, volume->v_u8mname);
         } else {
             len = ucs2_to_charset_allocate(obj->options.maccharset, &namebuf, volume->v_macname);
@@ -674,7 +613,7 @@ static int volume_codepage(AFPObj *obj, struct vol *volume)
     }
 
     if ( NULL == (charset = find_charset_functions(volume->v_volcodepage)) || charset->flags & CHARSET_ICONV ) {
-        LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems !!!!", volume->v_volcodepage);
+        LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems!", volume->v_volcodepage);
     }
 
     if (!volume->v_maccodepage)
@@ -702,22 +641,14 @@ static int volume_openDB(const AFPObj *obj, struct vol *volume)
         flags |= CNID_FLAG_NODEV;
     }
 
-    if (volume->v_cnidscheme == NULL) {
-        volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME);
-        LOG(log_info, logtype_afpd, "Volume %s use CNID scheme %s.",
-            volume->v_path, volume->v_cnidscheme);
-    }
-
-    LOG(log_info, logtype_afpd, "CNID server: %s:%s",
-        volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
-        volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port);
+    LOG(log_debug, logtype_afpd, "CNID server: %s:%s", volume->v_cnidserver, volume->v_cnidport);
 
     volume->v_cdb = cnid_open(volume->v_path,
                               volume->v_umask,
                               volume->v_cnidscheme,
                               flags,
-                              volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
-                              volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port);
+                              volume->v_cnidserver,
+                              volume->v_cnidport);
 
     if ( ! volume->v_cdb && ! (flags & CNID_FLAG_MEMORY)) {
         /* The first attempt failed and it wasn't yet an attempt to open in-memory */
@@ -776,7 +707,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     if ((volname_tmp = strchr(volname,'+')) != NULL)
         volname = volname_tmp+1;
 
-    if (utf8_encoding()) {
+    if (utf8_encoding(obj)) {
         namelen = convert_string(CH_UTF8_MAC, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp));
     } else {
         namelen = convert_string(obj->options.maccharset, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp));
@@ -790,7 +721,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     if ((len + 1) & 1) /* pad to an even boundary */
         ibuf++;
 
-    load_volumes(obj, of_closevol);
+    load_volumes(obj, closevol);
 
     for ( volume = getvolumes(); volume; volume = volume->v_next ) {
         if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) {
@@ -869,7 +800,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     /* initialize volume variables
      * FIXME file size
      */
-    if (utf8_encoding()) {
+    if (utf8_encoding(obj)) {
         volume->max_filename = UTF8FILELEN_EARLY;
     }
     else {
@@ -879,7 +810,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     volume->v_flags |= AFPVOL_OPEN;
     volume->v_cdb = NULL;
 
-    if (utf8_encoding()) {
+    if (utf8_encoding(obj)) {
         len = convert_string_allocate(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, namelen, &vol_mname);
     } else {
         len = convert_string_allocate(CH_UCS2, obj->options.maccharset, volume->v_macname, namelen, &vol_mname);
@@ -921,12 +852,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     ret  = stat_vol(obj, bitmap, volume, rbuf, rbuflen);
 
     if (ret == AFP_OK) {
-        handle_special_folders(volume);
-        savevolinfo(volume,
-                    volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
-                    volume->v_cnidport   ? volume->v_cnidport   : obj->options.Cnid_port);
-
-
         /*
          * If you mount a volume twice, the second time the trash appears on
          * the desk-top.  That's because the Mac remembers the DID for the
@@ -946,6 +871,11 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
                 goto openvol_err;
             }
         }
+
+        const char *msg;
+        if ((msg = iniparser_getstring(obj->iniconfig, volume->v_configname, "login message",  NULL)) != NULL)
+            setmessage(msg);
+
         return( AFP_OK );
     }
 
@@ -964,21 +894,45 @@ openvol_err:
     return ret;
 }
 
+void closevol(const AFPObj *obj, struct vol *vol)
+{
+    if (!vol)
+        return;
+
+    vol->v_flags &= ~AFPVOL_OPEN;
+
+    of_closevol(obj, vol);
+
+    dir_free( vol->v_root );
+    vol->v_root = NULL;
+    if (vol->v_cdb != NULL) {
+        cnid_close(vol->v_cdb);
+        vol->v_cdb = NULL;
+    }
+
+    if (vol->v_postexec) {
+        afprun(0, vol->v_postexec, NULL);
+    }
+    if (vol->v_root_postexec) {
+        afprun(1, vol->v_root_postexec, NULL);
+    }
+}
+
 /* ------------------------- */
-void close_all_vol(void)
+void close_all_vol(const AFPObj *obj)
 {
     struct vol  *ovol;
     curdir = NULL;
     for ( ovol = getvolumes(); ovol; ovol = ovol->v_next ) {
         if ( (ovol->v_flags & AFPVOL_OPEN) ) {
             ovol->v_flags &= ~AFPVOL_OPEN;
-            closevol(ovol);
+            closevol(obj, ovol);
         }
     }
 }
 
 /* ------------------------- */
-int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
+int afp_closevol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct vol  *vol;
     uint16_t   vid;
@@ -991,7 +945,8 @@ int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
     }
 
     (void)chdir("/");
-    closevol(vol);
+    curdir = NULL;
+    closevol(obj, vol);
 
     return( AFP_OK );
 }
@@ -1015,7 +970,7 @@ int  pollvoltime(AFPObj *obj)
     struct timeval   tv;
     struct stat      st;
 
-    if (!(afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF))
+    if (!(obj->afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF))
         return 0;
 
     if ( gettimeofday( &tv, NULL ) < 0 )
@@ -1055,7 +1010,7 @@ void setvoltime(AFPObj *obj, struct vol *vol)
         /* or finder doesn't update free space
          * AFP 3.2 and above clients seem to be ok without so many notification
          */
-        if (afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) {
+        if (obj->afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) {
             obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
         }
     }
@@ -1123,97 +1078,3 @@ int afp_setvolparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf
     ad_close(&ad, ADFLAGS_HF);
     return( AFP_OK );
 }
-
-/*
- * precreate a folder
- * this is only intended for folders in the volume root
- * It will *not* work if the folder name contains extended characters
- */
-static int create_special_folder (const struct vol *vol, const struct _special_folder *folder)
-{
-    char        *p,*q,*r;
-    struct adouble  ad;
-    uint16_t   attr;
-    struct stat st;
-    int     ret;
-
-
-    p = (char *) malloc ( strlen(vol->v_path)+strlen(folder->name)+2);
-    if ( p == NULL) {
-        LOG(log_error, logtype_afpd,"malloc failed");
-        exit (EXITERR_SYS);
-    }
-
-    q=strdup(folder->name);
-    if ( q == NULL) {
-        LOG(log_error, logtype_afpd,"malloc failed");
-        exit (EXITERR_SYS);
-    }
-
-    strcpy(p, vol->v_path);
-    strcat(p, "/");
-
-    r=q;
-    while (*r) {
-        if ((vol->v_casefold & AFPVOL_MTOUUPPER))
-            *r=toupper(*r);
-        else if ((vol->v_casefold & AFPVOL_MTOULOWER))
-            *r=tolower(*r);
-        r++;
-    }
-    strcat(p, q);
-
-    if ( (ret = stat( p, &st )) < 0 ) {
-        if (folder->precreate) {
-            if (ad_mkdir(p, folder->mode)) {
-                LOG(log_debug, logtype_afpd,"Creating '%s' failed in %s: %s", p, vol->v_path, strerror(errno));
-                free(p);
-                free(q);
-                return -1;
-            }
-            ret = 0;
-        }
-    }
-
-    if ( !ret && folder->hide) {
-        /* Hide it */
-        ad_init(&ad, vol);
-        if (ad_open(&ad, p, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
-            free(p);
-            free(q);
-            return (-1);
-        }
-
-        ad_setname(&ad, folder->name);
-
-        ad_getattr(&ad, &attr);
-        attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE );
-        ad_setattr(&ad, attr);
-
-        /* do the same with the finder info */
-        if (ad_entry(&ad, ADEID_FINDERI)) {
-            memcpy(&attr, ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, sizeof(attr));
-            attr   |= htons(FINDERINFO_INVISIBLE);
-            memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr));
-        }
-
-        ad_flush(&ad);
-        ad_close(&ad, ADFLAGS_HF);
-    }
-    free(p);
-    free(q);
-    return 0;
-}
-
-static void handle_special_folders (const struct vol * vol)
-{
-    const _special_folder *p = &special_folders[0];
-
-    become_root();
-
-    for (; p->name != NULL; p++) {
-        create_special_folder (vol, p);
-    }
-
-    unbecome_root();
-}