]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
small clean up, use of_ad when we can
[netatalk.git] / etc / afpd / file.c
index e091ba0fdadd258a5a0d08a2c698184b354ccc73..fac35b7fa71a1e282d92dcb28a30f1b2f75e3f5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.103 2006-09-29 09:39:16 didg Exp $
+ * $Id: file.c,v 1.120 2009-11-02 14:35:27 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -28,18 +28,18 @@ char *strchr (), *strrchr ();
 #endif /* ! HAVE_MEMCPY */
 #endif /* STDC_HEADERS */
 
-#include <atalk/adouble.h>
 #include <utime.h>
-#include <dirent.h>
 #include <errno.h>
-
-#include <atalk/logger.h>
 #include <sys/param.h>
 
-
+#include <atalk/adouble.h>
+#include <atalk/vfs.h>
+#include <atalk/logger.h>
 #include <atalk/afp.h>
 #include <atalk/util.h>
 #include <atalk/cnid.h>
+#include <atalk/unix.h>
+
 #include "directory.h"
 #include "desktop.h"
 #include "volume.h"
@@ -111,7 +111,7 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a
             u_int16_t ashort;
             
             ashort = htons(FINDERINFO_INVISIBLE);
-            memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
+            memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
         }
     }
     /** Only enter if no appledouble information and no finder information found. */
@@ -239,7 +239,7 @@ u_int32_t aint = 0;
 int getmetadata(struct vol *vol,
                  u_int16_t bitmap,
                  struct path *path, struct dir *dir, 
-                 char *buf, int *buflen, struct adouble *adp)
+                 char *buf, size_t *buflen, struct adouble *adp)
 {
     char               *data, *l_nameoff = NULL, *upath;
     char                *utf_nameoff = NULL;
@@ -253,7 +253,7 @@ int getmetadata(struct vol *vol,
     struct maccess     ma;
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin getmetadata:");
+    LOG(log_debug9, logtype_afpd, "begin getmetadata:");
 #endif /* DEBUG */
 
     upath = path->u_name;
@@ -511,30 +511,25 @@ int getmetadata(struct vol *vol,
 int getfilparams(struct vol *vol,
                  u_int16_t bitmap,
                  struct path *path, struct dir *dir, 
-                 char *buf, int *buflen )
+                 char *buf, size_t *buflen )
 {
     struct adouble     ad, *adp;
-    struct ofork        *of;
-    char                   *upath;
     int                 opened = 0;
     int rc;    
 
 #ifdef DEBUG
-    LOG(log_info, logtype_default, "begin getfilparams:");
+    LOG(log_debug9, logtype_default, "begin getfilparams:");
 #endif /* DEBUG */
 
     opened = PARAM_NEED_ADP(bitmap);
     adp = NULL;
 
     if (opened) {
-        int flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0;
+        char *upath;
+        int  flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0;
+
+        adp = of_ad(vol, path, &ad);
         upath = path->u_name;
-        if ((of = of_findname(path))) {
-            adp = of->of_ad;
-        } else {
-            ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-            adp = &ad;
-        }
 
         if ( ad_metadata( upath, flags, adp) < 0 ) {
             switch (errno) {
@@ -557,17 +552,14 @@ int getfilparams(struct vol *vol,
         ad_close_metadata( adp);
     }
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end getfilparams:");
+    LOG(log_debug9, logtype_afpd, "end getfilparams:");
 #endif /* DEBUG */
 
     return( rc );
 }
 
 /* ----------------------------- */
-int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj;
-char   *ibuf, *rbuf _U_;
-int    ibuflen _U_, *rbuflen;
+int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct adouble     ad, *adp;
     struct vol         *vol;
@@ -576,13 +568,8 @@ int        ibuflen _U_, *rbuflen;
     char               *path, *upath;
     int                        creatf, did, openf, retvalue = AFP_OK;
     u_int16_t          vid;
-    int                 ret;
     struct path                *s_path;
     
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_createfile:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf++;
     creatf = (unsigned char) *ibuf++;
@@ -613,8 +600,6 @@ int ibuflen _U_, *rbuflen;
     }
 
     upath = s_path->u_name;
-    if (0 != (ret = check_name(vol, upath))) 
-       return  ret;
     
     /* if upath is deleted we already in trouble anyway */
     if ((of = of_findname(s_path))) {
@@ -638,7 +623,7 @@ int ibuflen _U_, *rbuflen;
         openf = O_RDWR|O_CREAT|O_EXCL;
     }
 
-    if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF,
+    if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF|ADFLAGS_CREATE,
                   openf, 0666, adp) < 0 ) {
         switch ( errno ) {
         case EROFS:
@@ -686,17 +671,10 @@ createfile_done:
 
     setvoltime(obj, vol );
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end afp_createfile");
-#endif /* DEBUG */
-
     return (retvalue);
 }
 
-int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj;
-char   *ibuf, *rbuf _U_;
-int    ibuflen _U_, *rbuflen;
+int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct vol *vol;
     struct dir *dir;
@@ -704,10 +682,6 @@ int        ibuflen _U_, *rbuflen;
     int                did, rc;
     u_int16_t  vid, bitmap;
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_setfilparams:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf += 2;
 
@@ -750,10 +724,6 @@ int        ibuflen _U_, *rbuflen;
         setvoltime(obj, vol );
     }
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end afp_setfilparams:");
-#endif /* DEBUG */
-
     return( rc );
 }
 
@@ -789,12 +759,11 @@ int setfilparams(struct vol *vol,
     u_char              finder_buf[32];
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin setfilparams:");
+    LOG(log_debug9, logtype_afpd, "begin setfilparams:");
 #endif /* DEBUG */
 
-    upath = path->u_name;
     adp = of_ad(vol, path, &ad);
-    
+    upath = path->u_name;
 
     if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
@@ -893,10 +862,17 @@ int setfilparams(struct vol *vol,
     /* second try with adouble open 
     */
     if ( ad_open_metadata( upath, vol_noadouble(vol), O_CREAT, adp) < 0) {
-        /* for some things, we don't need an adouble header */
-        if (f_bitmap & ~(1<<FILPBIT_MDATE)) {
+        LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error");
+        /*
+         * For some things, we don't need an adouble header:
+         * - change of modification date
+         * - UNIX privs (Bug-ID #2863424)
+         */
+        if ( (f_bitmap & ~(1<<FILPBIT_MDATE | 1<<FILPBIT_UNIXPR))) {
+            LOG(log_debug, logtype_afpd, "setfilparams: need adouble access");
             return vol_noadouble(vol) ? AFP_OK : AFPERR_ACCESS;
         }
+        LOG(log_debug, logtype_afpd, "setfilparams: no adouble perms, but only FILPBIT_MDATE and/or FILPBIT_UNIXPR");
         isad = 0;
     } else if ((ad_get_HF_flags( adp ) & O_CREAT) ) {
         ad_setname(adp, path->m_name);
@@ -989,7 +965,7 @@ setfilparam_done:
     }
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end setfilparams:");
+    LOG(log_debug9, logtype_afpd, "end setfilparams:");
 #endif /* DEBUG */
     return err;
 }
@@ -1004,15 +980,12 @@ setfilparam_done:
  * adp         adouble struct of src file, if open, or & zeroed one
  *
  */
-int renamefile(vol, src, dst, newname, adp )
-const struct vol *vol;
-char   *src, *dst, *newname;
-struct adouble    *adp;
+int renamefile(const struct vol *vol, char *src, char *dst, char *newname, struct adouble *adp)
 {
     int                rc;
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin renamefile:");
+    LOG(log_debug9, logtype_afpd, "begin renamefile:");
 #endif /* DEBUG */
 
     if ( unix_rename( src, dst ) < 0 ) {
@@ -1043,7 +1016,7 @@ struct adouble    *adp;
         }
     }
 
-    if (vol->vfs->rf_renamefile(vol, src, dst) < 0 ) {
+    if (vol->vfs->vfs_renamefile(vol, src, dst) < 0 ) {
         int err;
         
         err = errno;        
@@ -1075,7 +1048,7 @@ struct adouble    *adp;
         ad_close( adp, ADFLAGS_HF );
     }
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end renamefile:");
+    LOG(log_debug9, logtype_afpd, "end renamefile:");
 #endif /* DEBUG */
 
     return( AFP_OK );
@@ -1152,10 +1125,7 @@ u_int32_t   hint;
 
 /* -----------------------------------
 */
-int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj;
-char   *ibuf, *rbuf _U_;
-int    ibuflen _U_, *rbuflen;
+int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct vol *s_vol, *d_vol;
     struct dir *dir;
@@ -1168,10 +1138,6 @@ int      ibuflen _U_, *rbuflen;
     struct adouble ad, *adp;
     int denyreadset;
     
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_copyfile:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1269,21 +1235,17 @@ int     ibuflen _U_, *rbuflen;
 
     setvoltime(obj, d_vol );
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end afp_copyfile:");
-#endif /* DEBUG */
-
     return( retvalue );
 }
 
 /* ----------------------- */
-static __inline__ int copy_all(const int dfd, const void *buf,
+static int copy_all(const int dfd, const void *buf,
                                size_t buflen)
 {
     ssize_t cc;
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin copy_all:");
+    LOG(log_debug9, logtype_afpd, "begin copy_all:");
 #endif /* DEBUG */
 
     while (buflen > 0) {
@@ -1299,7 +1261,7 @@ static __inline__ int copy_all(const int dfd, const void *buf,
     }
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end copy_all:");
+    LOG(log_debug9, logtype_afpd, "end copy_all:");
 #endif /* DEBUG */
 
     return 0;
@@ -1379,21 +1341,18 @@ static int copy_fork(int eid, struct adouble *add, struct adouble *ads)
  * because we are doing it elsewhere.
  * currently if newname is NULL then adp is NULL. 
  */
-int copyfile(s_vol, d_vol, src, dst, newname, adp )
-const struct vol *s_vol, *d_vol;
-char   *src, *dst, *newname;
-struct adouble *adp;
+int copyfile(const struct vol *s_vol, const struct vol*d_vol, 
+    char *src, char *dst, char *newname, struct adouble *adp)
 {
     struct adouble     ads, add;
     int                        err = 0;
     int                 ret_err = 0;
     int                 adflags;
-    int                 noadouble = vol_noadouble(d_vol);
     int                 stat_result;
     struct stat         st;
     
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin copyfile:");
+    LOG(log_debug9, logtype_afpd, "begin copyfile:");
 #endif /* DEBUG */
 
     if (adp == NULL) {
@@ -1423,7 +1382,7 @@ struct adouble *adp;
       st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
     }
 
-    if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
+    if (ad_open(dst , adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
         ret_err = errno;
         ad_close( adp, adflags );
         if (EEXIST != ret_err) {
@@ -1432,11 +1391,15 @@ struct adouble *adp;
         }
         return AFPERR_EXIST;
     }
-    /* XXX if the source and the dest don't use the same resource type it's broken
-    */
+    
+    /*
+     * XXX if the source and the dest don't use the same resource type it's broken
+     */
     if (ad_reso_fileno(adp) == -1 || 0 == (err = copy_fork(ADEID_RFORK, &add, adp))){
         /* copy the data fork */
-       err = copy_fork(ADEID_DFORK, &add, adp);
+        if ((err = copy_fork(ADEID_DFORK, &add, adp)) == 0) {
+            err = d_vol->vfs->vfs_copyfile(d_vol, src, dst);
+        }
     }
 
     if (err < 0) {
@@ -1470,7 +1433,7 @@ struct adouble *adp;
     }
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end copyfile:");
+    LOG(log_debug9, logtype_afpd, "end copyfile:");
 #endif /* DEBUG */
 
 done:
@@ -1520,17 +1483,14 @@ u_int16_t   bshort = 0;
        return 0;
 }
 
-int deletefile( vol, file, checkAttrib )
-const struct vol      *vol;
-char           *file;
-int         checkAttrib;
+int deletefile(const struct vol *vol, char *file, int checkAttrib)
 {
     struct adouble     ad;
     struct adouble      *adp = &ad;
     int                        adflags, err = AFP_OK;
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin deletefile:");
+    LOG(log_debug9, logtype_afpd, "begin deletefile:");
 #endif /* DEBUG */
 
     /* try to open both forks at once */
@@ -1589,7 +1549,7 @@ int         checkAttrib;
     if (adp && ad_tmplock( &ad, ADEID_DFORK, ADLOCK_WR, 0, 0, 0 ) < 0) {
         err = AFPERR_BUSY;
     }
-    else if (!(err = vol->vfs->rf_deletefile(vol, file)) && !(err = netatalk_unlink( file )) ) {
+    else if (!(err = vol->vfs->vfs_deletefile(vol, file)) && !(err = netatalk_unlink( file )) ) {
         cnid_t id;
         if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) 
         {
@@ -1600,7 +1560,7 @@ int         checkAttrib;
         ad_close( &ad, adflags );  /* ad_close removes locks if any */
 
 #ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end deletefile:");
+    LOG(log_debug9, logtype_afpd, "end deletefile:");
 #endif /* DEBUG */
 
     return err;
@@ -1608,10 +1568,7 @@ int         checkAttrib;
 
 /* ------------------------------------ */
 /* return a file id */
-int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj _U_;
-char   *ibuf, *rbuf;
-int    ibuflen _U_, *rbuflen;
+int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
     struct stat         *st;
     struct vol         *vol;
@@ -1622,10 +1579,6 @@ int      ibuflen _U_, *rbuflen;
     u_short            vid;
     struct path         *s_path;
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_createid:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
 
     ibuf += 2;
@@ -1684,9 +1637,6 @@ int       ibuflen _U_, *rbuflen;
         return AFP_OK;
     }
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "ending afp_createid...:");
-#endif /* DEBUG */
     return afp_errno;
 }
 
@@ -1704,8 +1654,6 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data)
     cnid_t        did  = param->did;
     cnid_t       aint;
     
-    memset(&path, 0, sizeof(path));
-
     if ( stat(de->d_name, &path.st)<0 )
         return 0;
     
@@ -1772,26 +1720,20 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir)
 
 /* ------------------------------
    resolve a file id */
-int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj _U_;
-char   *ibuf, *rbuf;
-int    ibuflen _U_, *rbuflen;
+int afp_resolveid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
     struct vol         *vol;
     struct dir         *dir;
     char               *upath;
     struct path         path;
-    int                 err, buflen, retry=0;
+    int                 err, retry=0;
+    size_t             buflen;
     cnid_t             id, cnid;
     u_int16_t          vid, bitmap;
 
     static char buffer[12 + MAXPATHLEN + 1];
     int len = 12 + MAXPATHLEN + 1;
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_resolveid:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1815,7 +1757,6 @@ int       ibuflen _U_, *rbuflen;
         return AFPERR_NOID;
     }
 retry:
-    memset(&path, 0, sizeof(path));
     if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
         return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */
     }
@@ -1823,7 +1764,6 @@ retry:
     if (NULL == ( dir = dirlookup( vol, id )) ) {
         return AFPERR_NOID; /* idem AFPERR_PARAM */
     }
-    path.u_name = upath;
     if (movecwd(vol, dir) < 0) {
         switch (errno) {
         case EACCES:
@@ -1836,6 +1776,8 @@ retry:
         }
     }
 
+    memset(&path, 0, sizeof(path));
+    path.u_name = upath;
     if ( of_stat(&path) < 0 ) {
 #ifdef ESTALE
         /* with nfs and our working directory is deleted */
@@ -1862,8 +1804,10 @@ retry:
     }
 
     /* directories are bad */
-    if (S_ISDIR(path.st.st_mode))
-        return AFPERR_BADTYPE;
+    if (S_ISDIR(path.st.st_mode)) {
+        /* OS9 and OSX don't return the same error code  */
+        return (afp_version >=30)?AFPERR_NOID:AFPERR_BADTYPE;
+    }
 
     memcpy(&bitmap, ibuf, sizeof(bitmap));
     bitmap = ntohs( bitmap );
@@ -1878,18 +1822,11 @@ retry:
     *rbuflen = buflen + sizeof(bitmap);
     memcpy(rbuf, ibuf, sizeof(bitmap));
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end afp_resolveid:");
-#endif /* DEBUG */
-
     return AFP_OK;
 }
 
 /* ------------------------------ */
-int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj _U_;
-char   *ibuf, *rbuf _U_;
-int    ibuflen _U_, *rbuflen;
+int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct stat         st;
     struct vol         *vol;
@@ -1902,10 +1839,6 @@ int      ibuflen _U_, *rbuflen;
     static char buffer[12 + MAXPATHLEN + 1];
     int len = 12 + MAXPATHLEN + 1;
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_deleteid:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1967,10 +1900,6 @@ int      ibuflen _U_, *rbuflen;
         }
     }
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "end afp_deleteid:");
-#endif /* DEBUG */
-
     return err;
 }
 
@@ -2023,10 +1952,7 @@ static struct adouble *find_adouble(struct path *path, struct ofork **of, struct
 
 #define APPLETEMP ".AppleTempXXXXXX"
 
-int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj  *obj;
-char   *ibuf, *rbuf _U_ ;
-int    ibuflen _U_, *rbuflen;
+int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct stat         srcst, destst;
     struct vol         *vol;
@@ -2050,10 +1976,6 @@ int      ibuflen _U_, *rbuflen;
     uid_t              uid;
     gid_t              gid;
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "begin afp_exchangefiles:");
-#endif /* DEBUG */
-
     *rbuflen = 0;
     ibuf += 2;
 
@@ -2257,10 +2179,6 @@ int      ibuflen _U_, *rbuflen;
         exit(EXITERR_SYS);
     }
 
-#ifdef DEBUG
-    LOG(log_info, logtype_afpd, "ending afp_exchangefiles:");
-#endif /* DEBUG */
-
     err = AFP_OK;
     goto err_exchangefile;