]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/volume.c
AC_HEADER_STDC autoconf change
[netatalk.git] / etc / afpd / volume.c
index 6c286851d959aadcccf64206858acfb7a4634e46..3f9a0a37fb0dad8a8ce07b188c8657b44f8d14d4 100644 (file)
@@ -1,30 +1,54 @@
 /*
+ * $Id: volume.c,v 1.13 2001-09-06 20:00:59 rufustfirefly Exp $
+ *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
 
 #include <sys/time.h>
 #include <sys/syslog.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <netatalk/endian.h>
 #include <atalk/asp.h>
 #include <atalk/dsi.h>
 #include <atalk/adouble.h>
 #include <atalk/afp.h>
 #include <atalk/util.h>
+#ifdef CNID_DB
 #include <atalk/cnid.h>
+#endif /* CNID_DB*/
 #include <dirent.h>
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+
+/* STDC check */
+#if STDC_HEADERS
 #include <string.h>
+#else /* STDC_HEADERS */
+#ifndef HAVE_STRCHR
+#define strchr index
+#define strrchr index
+#endif /* HAVE_STRCHR */
+char *strchr (), *strrchr ();
+#ifndef HAVE_MEMCPY
+#define memcpy(d,s,n) bcopy ((s), (d), (n))
+#define memmove(d,s,n) bcopy ((s), (d), (n))
+#endif /* ! HAVE_MEMCPY */
+#endif /* STDC_HEADERS */
+
 #include <pwd.h>
 #include <grp.h>
 #include <utime.h>
 
 #ifndef MIN
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
+#endif /* ! MIN */
 
 #ifndef NO_LARGE_VOL_SUPPORT
 #if BYTE_ORDER == BIG_ENDIAN
 #define hton64(x)       (x)
 #define ntoh64(x)       (x)
-#else
+#else /* BYTE_ORDER == BIG_ENDIAN */
 #define hton64(x)       ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \
                          (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32))
 #define ntoh64(x)       (hton64(x))
-#endif
-#endif
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+#endif /* ! NO_LARGE_VOL_SUPPORT */
 
 static struct vol *volumes = NULL;
 static int             lastvid = 0;
-#if AD_VERSION == AD_VERSION1
+#ifndef CNID_DB
 static char            *Trash = "\02\024Network Trash Folder";
-#endif
+#endif /* CNID_DB */
 static struct extmap   *extmap = NULL, *defextmap = NULL;
 
 #define VOLOPT_ALLOW      0  /* user allow list */
@@ -77,13 +101,16 @@ static struct extmap       *extmap = NULL, *defextmap = NULL;
                                ~u  -> make u illegal only as the first
                                       part of a double-byte character.
                             */
+#define VOLOPT_VETO      10  /* list of veto filespec */
 
 #ifdef FORCE_UIDGID
-#define VOLOPT_FORCEUID  10  /* force uid for username x */
-#define VOLOPT_FORCEGID  11  /* force gid for group x */
-#endif FORCE_UIDGID
+#define VOLOPT_FORCEUID  11  /* force uid for username x */
+#define VOLOPT_FORCEGID  12  /* force gid for group x */
+#define VOLOPT_MAX       12
+#else /* normally, there are only 9 possible options */
+#define VOLOPT_MAX       10
+#endif /* FORCE_UIDGID */
 
-#define VOLOPT_MAX        11
 #define VOLOPT_NUM        (VOLOPT_MAX + 1)
 
 #define VOLPASSLEN  8
@@ -163,7 +190,7 @@ static void volxlate(AFPObj *obj, char *dest, int destlen,
        destlen -= len;
       }
     } else if (is_var(p, "$f")) {
-      if (q = strchr(pwd->pw_gecos, ','))
+      if ((q = strchr(pwd->pw_gecos, ',')))
        *q = '\0';
       q = pwd->pw_gecos;
     } else if (is_var(p, "$g")) {
@@ -290,6 +317,11 @@ static void volset(struct vol_option *options, char *volname, int vlen,
       free(options[VOLOPT_CODEPAGE].c_value);
     options[VOLOPT_CODEPAGE].c_value = get_codepage_path(nlspath, val + 1);
 
+  } else if (optionok(tmp, "veto:", val)) {
+    if (options[VOLOPT_VETO].c_value)
+      free(options[VOLOPT_VETO].c_value);
+    options[VOLOPT_VETO].c_value = strdup(val + 1);
+
   } else if (optionok(tmp, "casefold:", val)) {
     if (strcasecmp(val + 1, "tolower") == 0)
       options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMLOWER;
@@ -327,17 +359,22 @@ static void volset(struct vol_option *options, char *volname, int vlen,
        options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS;
       else if (strcasecmp(p, "limitsize") == 0)
        options[VOLOPT_FLAGS].i_value |= AFPVOL_LIMITSIZE;
+      /* support for either "dropbox" or "dropkludge" */
+      else if (strcasecmp(p, "dropbox") == 0)
+       options[VOLOPT_FLAGS].i_value |= AFPVOL_DROPBOX;
+      else if (strcasecmp(p, "dropkludge") == 0)
+       options[VOLOPT_FLAGS].i_value |= AFPVOL_DROPBOX;
 
       p = strtok(NULL, ",");
     }
 
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
   } else if (optionok(tmp, "dbpath:", val)) {
     if (options[VOLOPT_DBPATH].c_value)
       free(options[VOLOPT_DBPATH].c_value);
-    
+
     options[VOLOPT_DBPATH].c_value = strdup(val + 1);
-#endif
+#endif /* CNID_DB */
   } else if (optionok(tmp, "mapchars:",val)) {
     if (options[VOLOPT_MAPCHARS].c_value)
       free(options[VOLOPT_MAPCHARS].c_value);
@@ -360,7 +397,7 @@ static void volset(struct vol_option *options, char *volname, int vlen,
       free(options[VOLOPT_FORCEGID].c_value);
     options[VOLOPT_FORCEGID].c_value = strdup(val + 1);
 
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
   } else if (val) {
     /* ignore unknown options */
@@ -368,7 +405,7 @@ static void volset(struct vol_option *options, char *volname, int vlen,
 
   } else {
     /* we'll assume it's a volume name. */
-    strncpy(volname, tmp, vlen); 
+    strncpy(volname, tmp, vlen);
   }
 }
 
@@ -401,18 +438,18 @@ static int creatvol(const char *path, char *name, struct vol_option *options)
 
     if (( volume =
            (struct vol *)calloc(1, sizeof( struct vol ))) == NULL ) {
-       syslog( LOG_ERR, "creatvol: malloc: %m" );
+       syslog( LOG_ERR, "creatvol: malloc: %s", strerror(errno) );
        return -1;
     }
     if (( volume->v_name =
            (char *)malloc( vlen + 1 )) == NULL ) {
-       syslog( LOG_ERR, "creatvol: malloc: %m" );
+       syslog( LOG_ERR, "creatvol: malloc: %s", strerror(errno) );
        free(volume);
        return -1;
     }
     if (( volume->v_path =
            (char *)malloc( strlen( path ) + 1 )) == NULL ) {
-       syslog( LOG_ERR, "creatvol: malloc: %m" );
+       syslog( LOG_ERR, "creatvol: malloc: %s", strerror(errno) );
        free(volume->v_name);
        free(volume);
        return -1;
@@ -423,7 +460,7 @@ static int creatvol(const char *path, char *name, struct vol_option *options)
 
 #ifdef __svr4__
     volume->v_qfd = -1;
-#endif
+#endif /* __svr4__ */
     volume->v_vid = lastvid++;
     volume->v_lastdid = 3;
 
@@ -442,10 +479,13 @@ static int creatvol(const char *path, char *name, struct vol_option *options)
       if (options[VOLOPT_PASSWORD].c_value) 
        volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
 
-#if AD_VERSION > AD_VERSION1
+      if (options[VOLOPT_VETO].c_value) 
+       volume->v_veto = strdup(options[VOLOPT_VETO].c_value);
+
+#ifdef CNID_DB
       if (options[VOLOPT_DBPATH].c_value)
        volume->v_dbpath = strdup(options[VOLOPT_DBPATH].c_value);
-#endif
+#endif /* CNID_DB */
 
 #ifdef FORCE_UIDGID
 
@@ -461,7 +501,7 @@ static int creatvol(const char *path, char *name, struct vol_option *options)
        volume->v_forcegid = NULL; /* set as null so as to return 0 later on */
          }
 
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
     }
 
@@ -549,7 +589,7 @@ static void setextmap( ext, type, creator, user)
     if ( em == NULL ) {
        if (( em =
                (struct extmap *)malloc( sizeof( struct extmap ))) == NULL ) {
-           syslog( LOG_ERR, "setextmap: malloc: %m" );
+           syslog( LOG_ERR, "setextmap: malloc: %s", strerror(errno) );
            return;
        }
        em->em_next = extmap;
@@ -629,10 +669,10 @@ static int readvolfile(obj, p1, p2, user, pwent)
          if (strncmp(path, VOLOPT_DEFAULT, VOLOPT_DEFAULT_LEN) == 0) {
            *tmp = '\0';
            for (i = 0; i < VOLOPT_NUM; i++) {
-             if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1, 
+             if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1,
                             path + VOLOPT_DEFAULT_LEN) < 0)
                break;
-             volset(save_options, tmp, sizeof(tmp) - 1, 
+             volset(save_options, tmp, sizeof(tmp) - 1,
                     obj->options.nlspath, path + VOLOPT_DEFAULT_LEN);
            }
          }
@@ -707,7 +747,7 @@ static int readvolfile(obj, p1, p2, user, pwent)
              if (((options[VOLOPT_FLAGS].i_value & AFPVOL_RO) == 0) && 
                  ((accessvol(options[VOLOPT_ROLIST].c_value, 
                              obj->username) == 1) ||
-                  !accessvol(options[VOLOPT_RWLIST].c_value, 
+                  !accessvol(options[VOLOPT_RWLIST].c_value,
                              obj->username))) 
                options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
 
@@ -730,7 +770,7 @@ static int readvolfile(obj, p1, p2, user, pwent)
     }
     volfree(save_options, NULL);
     if ( fclose( fp ) != 0 ) {
-       syslog( LOG_ERR, "readvolfile: fclose: %m" );
+       syslog( LOG_ERR, "readvolfile: fclose: %s", strerror(errno) );
     }
     return( 0 );
 }
@@ -749,7 +789,7 @@ static void load_volumes(AFPObj *obj)
   } else if (pwent) {
         /*
         * Read user's AppleVolumes or .AppleVolumes file
-        * If neither are readable, read the default volumes file. if 
+        * If neither are readable, read the default volumes file. if
         * that doesn't work, create a user share.
         */
     if ( readvolfile(obj, pwent->pw_dir, "AppleVolumes", 1, pwent) < 0 &&
@@ -775,7 +815,7 @@ static int getvolspace( vol, bfree, btotal, xbfree, xbtotal, bsize )
     u_int32_t   maxsize;
 #ifndef NO_QUOTA_SUPPORT
     VolSpace   qfree, qtotal;
-#endif
+#endif /* ! NO_QUOTA_SUPPORT */
 
     spaceflag = AFPVOL_GVSMASK & vol->v_flags;
     /* report up to 2GB if afp version is < 2.2 (4GB if not) */
@@ -790,7 +830,7 @@ static int getvolspace( vol, bfree, btotal, xbfree, xbtotal, bsize )
            goto getvolspace_done;
        }
     }
-#endif AFS
+#endif /* AFS */
 
     if (( rc = ustatfs_getvolspace( vol, xbfree, xbtotal,
                                    bsize)) != AFP_OK ) {
@@ -807,7 +847,7 @@ static int getvolspace( vol, bfree, btotal, xbfree, xbtotal, bsize )
            goto getvolspace_done;
        }
     }
-#endif
+#endif /* ! NO_QUOTA_SUPPORT */
     vol->v_flags = ( ~AFPVOL_GVSMASK & vol->v_flags ) | AFPVOL_USTATFS;
 
 getvolspace_done:
@@ -824,7 +864,8 @@ static int getvolparams( bitmap, vol, st, buf, buflen )
     int                *buflen;
 {
     struct adouble     ad;
-    int                        bit = 0, aint, isad = 1;
+    int                        bit = 0, isad = 1;
+    u_int32_t          aint;
     u_short            ashort;
     u_int32_t          bfree, btotal, bsize;
     VolSpace            xbfree, xbtotal; /* extended bytes */
@@ -836,7 +877,7 @@ static int getvolparams( bitmap, vol, st, buf, buflen )
      * .Parent file here if it doesn't exist. */
     
     memset(&ad, 0, sizeof(ad));
-    if ( ad_open( vol->v_path, vol_noadouble(vol) | 
+    if ( ad_open( vol->v_path, vol_noadouble(vol) |
                  ADFLAGS_HF|ADFLAGS_DIR, O_RDWR | O_CREAT, 
                  0666, &ad) < 0 ) {
          isad = 0;
@@ -875,11 +916,11 @@ static int getvolparams( bitmap, vol, st, buf, buflen )
 
        switch ( bit ) {
        case VOLPBIT_ATTR :
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
            ashort = VOLPBIT_ATTR_FILEID;
-#else
+#else /* CNID_DB */
            ashort = 0;
-#endif
+#endif /* CNID_DB */
            /* check for read-only.
             * NOTE: we don't actually set the read-only flag unless
             *       it's passed in that way as it's possible to mount
@@ -945,9 +986,9 @@ static int getvolparams( bitmap, vol, st, buf, buflen )
            xbfree = hton64( xbfree );
 #if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
            bcopy(&xbfree, data, sizeof(xbfree));
-#else
+#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
            memcpy(data, &xbfree, sizeof( xbfree ));
-#endif
+#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
            data += sizeof( xbfree );
            break;
 
@@ -955,12 +996,12 @@ static int getvolparams( bitmap, vol, st, buf, buflen )
            xbtotal = hton64( xbtotal );
 #if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
            bcopy(&xbtotal, data, sizeof(xbtotal));
-#else
+#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
            memcpy(data, &xbtotal, sizeof( xbtotal ));
-#endif
+#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
            data += sizeof( xbfree );
            break;
-#endif
+#endif /* ! NO_LARGE_VOL_SUPPORT */
 
        case VOLPBIT_NAME :
            nameoff = data;
@@ -1017,8 +1058,8 @@ int afp_getsrvrparms(obj, ibuf, ibuflen, rbuf, rbuflen )
     data = rbuf + 5;
     for ( vcnt = 0, volume = volumes; volume; volume = volume->v_next ) {
        if ( stat( volume->v_path, &st ) < 0 ) {
-           syslog( LOG_INFO, "afp_getsrvrparms: stat %s: %m", 
-                   volume->v_path );
+           syslog( LOG_INFO, "afp_getsrvrparms: stat %s: %s",
+                   volume->v_path, strerror(errno) );
            continue;           /* can't access directory */
        }
        if (!S_ISDIR(st.st_mode)) {
@@ -1045,7 +1086,7 @@ int afp_getsrvrparms(obj, ibuf, ibuflen, rbuf, rbuflen )
     *rbuflen = data - rbuf;
     data = rbuf;
     if ( gettimeofday( &tv, 0 ) < 0 ) {
-       syslog( LOG_ERR, "afp_getsrvrparms: gettimeofday: %m" );
+       syslog( LOG_ERR, "afp_getsrvrparms: gettimeofday: %s", strerror(errno) );
        *rbuflen = 0;
        return AFPERR_PARAM;
     }
@@ -1063,9 +1104,9 @@ int afp_openvol(obj, ibuf, ibuflen, rbuf, rbuflen )
 {
     struct stat        st;
     char       *volname;
-#if AD_VERSION == AD_VERSION1
+#ifndef CNID_DB
     char *p;
-#endif
+#endif /* CNID_DB */
     struct vol *volume;
     struct dir *dir;
     int                len, ret, buflen;
@@ -1111,7 +1152,7 @@ int afp_openvol(obj, ibuf, ibuflen, rbuf, rbuflen )
 
     if (( volume->v_flags & AFPVOL_OPEN  ) == 0 ) {
         if ((dir = dirnew(strlen(volume->v_name) + 1)) == NULL) {
-           syslog( LOG_ERR, "afp_openvol: malloc: %m" );
+           syslog( LOG_ERR, "afp_openvol: malloc: %s", strerror(errno) );
            ret = AFPERR_MISC;
            goto openvol_err;
        }
@@ -1141,7 +1182,15 @@ int afp_openvol(obj, ibuf, ibuflen, rbuf, rbuflen )
         ret = AFPERR_PARAM;
        goto openvol_err;
     }
-#if AD_VERSION == AD_VERSION1
+
+#ifdef CNID_DB
+       if (volume->v_dbpath)
+               volume->v_db = cnid_open (volume->v_dbpath);
+       if (volume->v_db == 0)
+               volume->v_db = cnid_open (volume->v_path);
+#endif /* CNID_DB */
+
+#ifndef CNID_DB
     /*
      * 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
@@ -1151,7 +1200,7 @@ int afp_openvol(obj, ibuf, ibuflen, rbuf, rbuflen )
      */
     p = Trash;
     cname( volume, volume->v_dir, &p );
-#endif
+#endif /* CNID_DB */
 
     return( AFP_OK );
 
@@ -1190,10 +1239,10 @@ int afp_closevol(obj, ibuf, ibuflen, rbuf, rbuflen )
 
     dirfree( vol->v_root );
     vol->v_dir = NULL;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
     cnid_close(vol->v_db);
     vol->v_db = NULL;
-#endif
+#endif /* CNID_DB */
     return( AFP_OK );
 }
 
@@ -1247,7 +1296,7 @@ void setvoltime(obj, vol )
      * [RS] */
 
     if ( gettimeofday( &tv, 0 ) < 0 ) {
-       syslog( LOG_ERR, "setvoltime: gettimeofday: %m" );
+       syslog( LOG_ERR, "setvoltime: gettimeofday: %s", strerror(errno) );
        return;
     }
     if( utime( vol->v_path, NULL ) < 0 ) {
@@ -1255,7 +1304,7 @@ void setvoltime(obj, vol )
          * where no other users can interfere, so there's no issue here
          */
     }
-    
+
     /* a little granularity */
     if (vol->v_time < tv.tv_sec) {
       vol->v_time = tv.tv_sec;