]> arthur.barton.de Git - netatalk.git/commitdiff
Fixes
authorFrank Lahm <franklahm@googlemail.com>
Wed, 4 Jan 2012 15:48:56 +0000 (16:48 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 4 Jan 2012 15:48:56 +0000 (16:48 +0100)
etc/afpd/fork.c
include/atalk/adouble.h
libatalk/adouble/ad_attr.c
libatalk/adouble/ad_flush.c
libatalk/adouble/ad_lock.c
libatalk/adouble/ad_open.c
libatalk/adouble/ad_read.c
libatalk/adouble/ad_write.c
libatalk/vfs/extattr.c

index 4b5a9a265eb70bc239c0c42bbee6fe11d48cc22b..40ae7cdad88b56e6aa63ad821bf419f4207ab79f 100644 (file)
@@ -54,7 +54,7 @@ static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t
         return( AFPERR_BITMAP );
     }
 
-    if ( ad_reso_fileno( ofork->of_ad ) == -1 ) { /* META ? */
+    if (! AD_META_OPEN(ofork->of_ad)) {
         adp = NULL;
     } else {
         adp = ofork->of_ad;
@@ -1353,7 +1353,7 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu
         return( AFPERR_PARAM );
     }
 
-    if (AD_META_OPEN(ofork->of_ad))) {
+    if (AD_META_OPEN(ofork->of_ad)) {
         if ( ad_refresh( ofork->of_ad ) < 0 ) {
             LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) );
             return( AFPERR_PARAM );
index d3466518f84a0507c3d876f03ea1bbbc63a4f8ed..4539bed828672fc5c6ca54d523ba7a378f0266f7 100644 (file)
@@ -374,8 +374,8 @@ extern uid_t ad_getfuid   (void );
 extern char *ad_dir       (const char *);
 extern const char *ad_path      (const char *, int);
 extern const char *ad_path_ea   (const char *, int);
-extern int ad_mode        (const char *, int);
-extern int ad_mkdir       (const char *, int);
+extern int ad_mode        (const char *, mode_t);
+extern int ad_mkdir       (const char *, mode_t);
 struct vol;
 extern void ad_init       (struct adouble *, const struct vol * restrict);
 extern void ad_init_old   (struct adouble *ad, int flags, int options);
index e005577f026dd1fc661ef0ded2ef1aedc49bfdbf..47e6f37c515904a4d88241b2c57f519a2e29f6df 100644 (file)
@@ -92,7 +92,7 @@ int ad_setattr(const struct adouble *ad, const uint16_t attribute)
  */
 int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint32_t id, const cnid_t did, const void *stamp)
 {
-    if ((adp->ad_flags == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) {
+    if ((adp->ad_vers == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) {
 
         /* ad_getid depends on this to detect presence of ALL entries */
         ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
index abc697bdeff14aa48fcb0fea70b84658868b3e37..0685646667d2d2fab3eaf11b8cdf2f047d5a60a8 100644 (file)
@@ -93,7 +93,7 @@ int  ad_rebuild_adouble_header(struct adouble *ad)
     nent = htons( nent );
     memcpy(nentp, &nent, sizeof( nent ));
 
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         len = ad_getentryoff(ad, ADEID_RFORK);
         break;
@@ -149,7 +149,7 @@ int ad_flush(struct adouble *ad)
     int len;
     struct ad_fd *adf;
 
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         adf = ad->ad_mdp;
         break;
@@ -170,7 +170,7 @@ int ad_flush(struct adouble *ad)
         }
         len = ad->ad_ops->ad_rebuild_header(ad);
 
-        switch (ad->ad_flags) {
+        switch (ad->ad_vers) {
         case AD_VERSION2:
             if (adf_pwrite(ad->ad_mdp, ad->ad_data, len, 0) != len) {
                 if (errno == 0)
@@ -221,7 +221,7 @@ int ad_close(struct adouble *ad, int adflags)
     }
 
     if ((adflags & ADFLAGS_HF)) {
-        switch (ad->ad_flags) {
+        switch (ad->ad_vers) {
         case AD_VERSION2:
             if ((ad_meta_fileno(ad) != -1) && !(--ad->ad_mdp->adf_refcount)) {
                 if (close( ad_meta_fileno(ad) ) < 0)
@@ -249,7 +249,7 @@ int ad_close(struct adouble *ad, int adflags)
     }
 
     if ((adflags & ADFLAGS_RF)) {
-        switch (ad->ad_flags) {
+        switch (ad->ad_vers) {
         case AD_VERSION2:
             /* Do nothing as ADFLAGS_RF == ADFLAGS_HF */
             break;
index b78e22dea7ae96332eb0a93114bed4bccf41a224..6961930d4e3925babc3d8e4c26e0d78dd8506e9b 100644 (file)
@@ -462,7 +462,7 @@ int ad_lock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len
             }
         }
     } else { /* rfork */
-        switch (ad->ad_flags) {
+        switch (ad->ad_vers) {
         case AD_VERSION2:
             if (ad_meta_fileno(ad) == -1 || ad_reso_fileno(ad) == -1) {
                 /* there's no meta data. return a lock error 
@@ -682,7 +682,7 @@ void ad_unlock(struct adouble *ad, const int fork)
  */
 int ad_testlock(struct adouble *ad, int eid, const off_t off)
 {
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         return ad_testlock_v2(ad, eid, off);
     case AD_VERSION_EA:
@@ -706,7 +706,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
  */
 uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
 {
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         return ad_openforks_v2(ad, attrbits);
     case AD_VERSION_EA:
index c906e07b5535e8a1cb7fcc1d5e379c28d406709b..2223029b293ca905ed6f7ccfb6827a90983da4aa 100644 (file)
@@ -253,7 +253,7 @@ static int new_ad_header(const char *path, struct adouble *ad, int adflags)
     struct stat         st;
 
     ad->ad_magic = AD_MAGIC;
-    ad->ad_version = ad->ad_flags & 0x0f0000;
+    ad->ad_version = ad->ad_vers & 0x0f0000;
     if (!ad->ad_version) {
         ad->ad_version = AD_VERSION;
     }
@@ -261,9 +261,9 @@ static int new_ad_header(const char *path, struct adouble *ad, int adflags)
 
     memset(ad->ad_data, 0, sizeof(ad->ad_data));
 
-    if (ad->ad_flags == AD_VERSION2)
+    if (ad->ad_vers == AD_VERSION2)
         eid = entry_order2;
-    else if (ad->ad_flags == AD_VERSION_EA)
+    else if (ad->ad_vers == AD_VERSION_EA)
         eid = entry_order_ea;
     else {
         return -1;
@@ -465,6 +465,27 @@ static int ad_header_read_ea(struct adouble *ad, struct stat *hst _U_)
 
     /* Now parse entries */
     parse_entries(ad, buf + AD_HEADER_LEN, nentries);
+
+    return 0;
+}
+
+static int ad_rsrc_len_ea(struct adouble *ad)
+{
+    ssize_t rlen;
+
+    if ((rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
+        switch (errno) {
+        case ENOATTR:
+        case ENOENT:
+            ad->ad_rlen = 0;
+            break;
+        default:
+            LOG(log_error, logtype_default, "ad_refresh_rsrc_len_ea: %s", strerror(errno));
+            ad->ad_rlen = 0;
+            return -1;
+        }
+    }
+    ad->ad_rlen = rlen;
     return 0;
 }
 
@@ -522,7 +543,7 @@ static int ad_chown(const char *path, struct stat *stbuf)
 /* ----------------
    return access right and inode of path parent directory
 */
-static int ad_mode_st(const char *path, int *mode, struct stat *stbuf)
+static int ad_mode_st(const char *path, mode_t *mode, struct stat *stbuf)
 {
     if (*mode == 0) {
         return -1;
@@ -558,11 +579,11 @@ static int ad_header_upgrade_ea(struct adouble *ad _U_, const char *name _U_)
 static int ad_error(struct adouble *ad, int adflags)
 {
     int err = errno;
-    if ((adflags & ADFLAGS_NOHF)) { /* 1 */
+    if (adflags & ADFLAGS_NOHF) { /* 1 */
         ad->ad_adflags &= ~ADFLAGS_HF;
         return 0;
     }
-    if ((adflags & ADFLAGS_DF) { /* 2 */
+    if (adflags & ADFLAGS_DF) { /* 2 */
         ad_close( ad, ADFLAGS_DF );
         err = errno;
     }
@@ -864,7 +885,7 @@ static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *a
     memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
     ad->ad_rlen = 0;
 
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         ret = ad_open_hf_v2(path, adflags, mode, ad);
         break;
@@ -879,6 +900,7 @@ static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *a
     return ret;
 }
 
+
 /*!
  * Open ressource fork
  *
@@ -889,8 +911,9 @@ static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *a
 {
     int ret = 0;
     int oflags;
+    ssize_t rlen;
 
-    if (ad->ad_flags != AD_VERSION_EA)
+    if (ad->ad_vers != AD_VERSION_EA)
         return 0;
 
     LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)", path, mode);
@@ -914,47 +937,12 @@ static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *a
         adf_lock_init(&ad->ad_data_fork);
     }
 
-    if ((ad->ad_rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
-        switch (errno) {
-        case ENOATTR:
-            ad->ad_rlen = 0;
-            break;
-        default:
-            LOG(log_warning, logtype_default, "ad_open_rf(\"%s\"): %s",
-                fullpathname(path), strerror(errno));
-            ret = -1;
-            goto exit;
-        }
-    }
-
-    /* Round up and allocate buffer */
-    size_t roundup = ((ad->ad_rlen / RFORK_EA_ALLOCSIZE) + 1) * RFORK_EA_ALLOCSIZE;
-    if ((ad->ad_resforkbuf = malloc(roundup)) == NULL) {
-        ret = -1;
+    if ((ret = ad_rsrc_len_ea(ad)) != 0)
         goto exit;
-    }
-
-    ad->ad_resforkbufsize = roundup;
-
-    /* Read the EA into the buffer */
-    if (ad->ad_rlen > 0) {
-        if (sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
-            ret = -1;
-            goto exit;
-        }       
-    }
 
     ad->ad_data_fork.adf_refcount++;
 
 exit:
-    if (ret != 0) {
-        if (ad->ad_resforkbuf)
-            free(ad->ad_resforkbuf);
-        ad->ad_resforkbuf = NULL;
-        ad->ad_rlen = 0;
-        ad->ad_resforkbufsize = 0;
-    }
-
     return ret;
 }
 
@@ -1088,7 +1076,7 @@ int ad_stat(const char *path, struct stat *stbuf)
 /* ----------------
    return access right of path parent directory
 */
-int ad_mode( const char *path, int mode)
+int ad_mode( const char *path, mode_t mode)
 {
     struct stat     stbuf;
     ad_mode_st(path, &mode, &stbuf);
@@ -1098,7 +1086,7 @@ int ad_mode( const char *path, int mode)
 /*
  * Use mkdir() with mode bits taken from ad_mode().
  */
-int ad_mkdir( const char *path, int mode)
+int ad_mkdir( const char *path, mode_t mode)
 {
     int ret;
     int st_invalid;
@@ -1118,7 +1106,7 @@ int ad_mkdir( const char *path, int mode)
 
 static void ad_init_func(struct adouble *ad)
 {
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         ad->ad_ops = &ad_adouble;
         ad->ad_rfp = &ad->ad_resource_fork;
@@ -1150,14 +1138,14 @@ static void ad_init_func(struct adouble *ad)
 
 void ad_init_old(struct adouble *ad, int flags, int options)
 {
-    ad->ad_flags = flags;
+    ad->ad_vers = flags;
     ad->ad_options = options;
     ad_init_func(ad);
 }
 
 void ad_init(struct adouble *ad, const struct vol * restrict vol)
 {
-    ad->ad_flags = vol->v_adouble;
+    ad->ad_vers = vol->v_adouble;
     ad->ad_options = vol->v_ad_options;
     ad->ad_maxeafssize = 3500;  /* FIXME: option from vol */
     ad_init_func(ad);
@@ -1316,8 +1304,7 @@ exit:
 
 int ad_refresh(struct adouble *ad)
 {
-
-    switch (ad->ad_flags) {
+    switch (ad->ad_vers) {
     case AD_VERSION2:
         if (ad_meta_fileno(ad) == -1)
             return -1;
@@ -1326,6 +1313,8 @@ int ad_refresh(struct adouble *ad)
     case AD_VERSION_EA:
         if (ad_data_fileno(ad) == -1)
             return -1;
+        if (ad_rsrc_len_ea(ad) != 0)
+            return -1;
         return ad->ad_ops->ad_header_read(ad, NULL);
         break;
     default:
index 224c72d9fb381fe12470a27117a2aab52117545a..7b8841bb619b01cdf05e22ff0a305572f0f2d01f 100644 (file)
 #include <string.h>
 #include <sys/param.h>
 #include <errno.h>
+#include <stdlib.h>
 
 #include <atalk/adouble.h>
 #include <atalk/ea.h>
-
-#ifndef MIN
-#define MIN(a,b)    ((a)<(b)?(a):(b))
-#endif /* ! MIN */
+#include <atalk/logger.h>
+#include <atalk/util.h>
 
 ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
 {
@@ -63,6 +62,8 @@ ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
 ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, const size_t buflen)
 {
     ssize_t     cc;
+    ssize_t     rlen;
+    off_t r_off;
 
     /* We're either reading the data fork (and thus the data file)
      * or we're reading anything else (and thus the header file). */
@@ -78,11 +79,12 @@ ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, c
             cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
         }
     } else {
-        if (ad->ad_flags != AD_VERSION_EA) {
-            off_t r_off;
-            if ( ad_reso_fileno( ad ) == -1 )
-                /* resource fork is not open ( cf etc/afp/fork.c) */
-                return 0;
+        if (! AD_RSRC_OPEN(ad))
+            /* resource fork is not open ( cf etc/afp/fork.c) */
+            return 0;
+
+        switch (ad->ad_vers) {
+        case AD_VERSION2:
             r_off = ad_getentryoff(ad, eid) + off;
             if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
                 return( -1 );
@@ -101,17 +103,49 @@ ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, c
                            MIN(sizeof( ad->ad_data ) - r_off, cc));
                 }
             }
-        } else { /* AD_VERSION_EA */
+            break;
+
+        case AD_VERSION_EA:
+            if ((rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
+                switch (errno) {
+                case ENOATTR:
+                case ENOENT:
+                    cc = ad->ad_rlen = 0;
+                    break;
+                default:
+                    LOG(log_error, logtype_default, "ad_read: %s", strerror(errno));
+                    return -1;
+                }
+            }
+            ad->ad_rlen = rlen;
+
             if (off > ad->ad_rlen) {
                 errno = ERANGE;
                 return -1;
             }
-            if (ad->ad_rlen == 0)
-                return 0;
+
+            if (ad->ad_resforkbuf == NULL) {
+                if ((ad->ad_resforkbuf = malloc(ad->ad_rlen)) == NULL) {
+                    ad->ad_rlen = 0;
+                    return -1;
+                }
+            } else {
+                if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, ad->ad_rlen)) == NULL) {
+                    ad->ad_rlen = 0;
+                    return -1;
+                } 
+            }
+
+            if (sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
+                ad->ad_rlen = 0;
+                return -1;
+            }       
+
             if ((off + buflen) > ad->ad_rlen)
                 cc = ad->ad_rlen;
             memcpy(buf, ad->ad_resforkbuf + off, cc);
-        }
+            break;
+        } /* switch (ad->ad_vers) */
     }
 
     return( cc );
index dd66796c829a0345e1420d88a206df87b640b9c5..5762d18f9b971fc44500e878748a86a93231a6ff 100644 (file)
@@ -112,7 +112,7 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
         }
         cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
     } else if ( eid == ADEID_RFORK ) {
-        switch (ad->ad_flags) {
+        switch (ad->ad_vers) {
         case AD_VERSION2:
 
             if ( end ) {
@@ -131,15 +131,19 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
             break;
 
         case AD_VERSION_EA:
-            if ((off + buflen) > ad->ad_resforkbufsize) {
-                roundup = (((off + buflen) / RFORK_EA_ALLOCSIZE) + 1) * RFORK_EA_ALLOCSIZE;
-                if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, roundup)) == NULL)
+            if (ad->ad_resforkbuf == NULL) {
+                ad->ad_rlen = off + buflen;
+                if ((ad->ad_resforkbuf = malloc(ad->ad_rlen)) == NULL) {
+                    ad->ad_rlen = 0;
                     return -1;
-                ad->ad_resforkbufsize = roundup;
+                }
             }
-            memcpy(ad->ad_resforkbuf + off, buf, buflen);
-            if ((off + buflen) > ad->ad_rlen)
+            if ((off + buflen) > ad->ad_rlen) {                
+                if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, off + buflen)) == NULL)
+                    return -1;
                 ad->ad_rlen = off + buflen;
+            }
+            memcpy(ad->ad_resforkbuf + off, buf, buflen);
             
             if (fsetrsrcea(ad, ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen, 0) == -1)
                 return -1;
@@ -217,7 +221,7 @@ char            c = 0;
 /* ------------------------ */
 int ad_rtruncate( struct adouble *ad, const off_t size)
 {
-    if (ad->ad_flags != AD_VERSION_EA)
+    if (ad->ad_vers != AD_VERSION_EA)
         if (sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 )
             return -1;
 
index bdae873e6c05ef3682a9db708167addd890ddf0c..853b7f2ffe3c3fd7691f097599dcd3066a75014b 100644 (file)
@@ -855,8 +855,10 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
 {
        int filedes = openat(fildes, path, oflag, mode);
        if (filedes == -1) {
-               LOG(log_error, logtype_default, "openat(\"%s\"): %s",
-            path, strerror(errno));
+        if (errno != ENOENT)
+            LOG(log_error, logtype_default, "openat(\"%s\"): %s",
+                path, strerror(errno));
+        errno = ENOATTR;
        }
        return filedes;
 }