]> arthur.barton.de Git - netatalk.git/commitdiff
Fixes
authorFrank Lahm <franklahm@googlemail.com>
Wed, 4 Jan 2012 12:33:58 +0000 (13:33 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 4 Jan 2012 12:33:58 +0000 (13:33 +0100)
etc/afpd/fork.c
etc/afpd/fork.h
etc/afpd/ofork.c
libatalk/adouble/ad_flush.c
libatalk/adouble/ad_lock.c
libatalk/adouble/ad_open.c

index 8092fd398d8b423723f785402748258ec98b2f3b..560f766b5e41e29cc21611b08c3b9db13bc37ae4 100644 (file)
@@ -227,6 +227,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     struct stat     *st;
     uint16_t        bshort;
     struct path     *s_path;
+    struct stat xxx;
 
     ibuf++;
     fork = *ibuf++;
@@ -328,7 +329,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
                 ret = AFPERR_VLOCK;
             case EACCES:
                 goto openfork_err;
-                break;
             case ENOENT:
                 if (fork == OPENFORK_DATA) {
                     /* try to open only the data fork */
@@ -343,28 +343,25 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
                     if (ad_open(ofork->of_ad, upath,
                                 adflags | ADFLAGS_RDWR | ADFLAGS_SETSHRMD | ADFLAGS_CREATE, 0666) < 0)
                         goto openfork_err;
-                    ofork->of_flags |= AFPFORK_OPEN;
+                    ofork->of_flags |= AFPFORK_META;
                 }
                 break;
             case EMFILE :
             case ENFILE :
                 ret = AFPERR_NFILE;
                 goto openfork_err;
-                break;
             case EISDIR :
                 ret = AFPERR_BADTYPE;
                 goto openfork_err;
-                break;
             default:
                 LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
                 ret = AFPERR_PARAM;
                 goto openfork_err;
-                break;
             }
         }
         else {
             /* the ressource fork is open too */
-            ofork->of_flags |= AFPFORK_OPEN;
+            ofork->of_flags |= AFPFORK_META;
         }
     } else {
         /* try opening in read-only mode */
@@ -385,8 +382,8 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
                     }
                     adflags = ADFLAGS_DF;
                 }
-                /* else we don't set AFPFORK_OPEN because there's no ressource fork file
-                 * We need to check AFPFORK_OPEN in afp_closefork(). eg fork open read-only
+                /* else we don't set AFPFORK_META because there's no ressource fork file
+                 * We need to check AFPFORK_META in afp_closefork(). eg fork open read-only
                  * then create in open read-write.
                  * FIXME , it doesn't play well with byte locking example:
                  * ressource fork open read only
@@ -398,21 +395,16 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
             case ENFILE :
                 ret = AFPERR_NFILE;
                 goto openfork_err;
-                break;
             case EISDIR :
                 ret = AFPERR_BADTYPE;
                 goto openfork_err;
-                break;
             default:
                 LOG(log_error, logtype_afpd, "afp_openfork(\"%s\"): %s",
                     fullpathname(s_path->m_name), strerror(errno) );
                 goto openfork_err;
-                break;
             }
-        }
-        else {
-            /* the ressource fork is open too */
-            ofork->of_flags |= AFPFORK_OPEN;
+        } else {
+            ofork->of_flags |= AFPFORK_META;
         }
     }
 
index 9355c5e545d3a3bf3ede322c4af737dcdfed1b40..37605e4a07a90b05ba7b24711e179b2792d4e129 100644 (file)
@@ -38,9 +38,9 @@ struct ofork {
 #define OPENACC_DWR (1<<5)
 
 /* ofork.of_flags bits */
-#define AFPFORK_OPEN    (1<<0)
-#define AFPFORK_RSRC    (1<<1)
-#define AFPFORK_DATA    (1<<2)
+#define AFPFORK_DATA    (1<<0)  /* open datafork */
+#define AFPFORK_RSRC    (1<<1)  /* open rsrcfork */
+#define AFPFORK_META    (1<<2)  /* open metadata */
 #define AFPFORK_DIRTY   (1<<3)
 #define AFPFORK_ACCRD   (1<<4)
 #define AFPFORK_ACCWR   (1<<5)
index 2a8c5443705375d3a763929788bbf6d5afc8a88d..326acd0b0ba565dde9905650b45304120092e981 100644 (file)
@@ -393,27 +393,21 @@ void of_dealloc( struct ofork *of)
 int of_closefork(struct ofork *ofork)
 {
     struct timeval      tv;
-    int         adflags, doflush = 0;
+    int         adflags = 0;
     int                 ret;
 
     adflags = 0;
-    if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) {
+    if (ofork->of_flags & AFPFORK_DATA)
         adflags |= ADFLAGS_DF;
-    }
-    if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) {
+    if (ofork->of_flags & AFPFORK_META)
         adflags |= ADFLAGS_HF;
-        /*
-         * Only set the rfork's length if we're closing the rfork.
-         */
-        if ((ofork->of_flags & AFPFORK_RSRC)) {
-            ad_refresh( ofork->of_ad );
-            if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) {
-                ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec);
-                doflush++;
-            }
-            if ( doflush ) {
-                ad_flush( ofork->of_ad );
-            }
+    if (ofork->of_flags & AFPFORK_RSRC) {
+        adflags |= ADFLAGS_RF;
+        /* Only set the rfork's length if we're closing the rfork. */
+        ad_refresh( ofork->of_ad );
+        if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) {
+            ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec);
+            ad_flush( ofork->of_ad );
         }
     }
 
index f41b10826d730e2e2bffe775d5fba53848c3508c..abc697bdeff14aa48fcb0fea70b84658868b3e37 100644 (file)
@@ -248,5 +248,28 @@ int ad_close(struct adouble *ad, int adflags)
         }
     }
 
+    if ((adflags & ADFLAGS_RF)) {
+        switch (ad->ad_flags) {
+        case AD_VERSION2:
+            /* Do nothing as ADFLAGS_RF == ADFLAGS_HF */
+            break;
+
+        case AD_VERSION_EA:
+            if ((ad_data_fileno(ad) >= 0 || ad_data_fileno(ad) == -2) /* -2 means symlink */ 
+                && !(--ad->ad_data_fork.adf_refcount)) {
+                if (close( ad_data_fileno(ad) ) < 0)
+                    err = -1;
+                ad_data_fileno(ad) = -1;
+                adf_lock_free(&ad->ad_data_fork);
+            }
+            break;
+
+        default:
+            LOG(log_error, logtype_default, "ad_close: unknown AD version");
+            errno = EIO;
+            return -1;
+        }
+    }
+
     return err;
 }
index 5d6e4b1a234f1e61e629e81f70d539f75d9ed271..b78e22dea7ae96332eb0a93114bed4bccf41a224 100644 (file)
@@ -427,7 +427,7 @@ static int ad_testlock_ea(struct adouble *ad, int eid, const off_t off)
     off_t      lock_offset;
 
     if (eid == ADEID_DFORK) {
-        lock_offset = df2off(off);
+        lock_offset = off;
     } else { /* rfork */
         lock_offset = rf2off(off);
     }
index 84fee0dad392251943ebb37d1846dc87da76ea53..1c8cb294b52539fd4688503c2a2b5b31d0fac7c1 100644 (file)
@@ -888,12 +888,31 @@ static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *a
 static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *ad)
 {
     int ret = 0;
+    int oflags;
 
     if (ad->ad_flags != AD_VERSION_EA)
         return 0;
 
-    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)",
-        path, mode);
+    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)", path, mode);
+
+    oflags |= ad2openflags(adflags) & ~(O_CREAT | O_TRUNC);
+
+    if (ad_data_fileno(ad) != -1) {
+        /* the file is already open, but we want write access: */
+        if ((adflags & ADFLAGS_RDWR) &&
+            /* and it was already denied: */
+            (ad->ad_data_fork.adf_flags & O_RDONLY)) {
+            LOG(log_error, logtype_default, "ad_open_rf(%s): rw request for ro file: %s",
+                fullpathname(path), strerror(errno));
+            errno = EACCES;
+            return -1;
+        }
+    } else {
+        if ((ad_data_fileno(ad) = open(path, oflags)) == -1)
+            goto exit;
+        ad->ad_data_fork.adf_flags = oflags;
+        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) {
@@ -925,9 +944,12 @@ static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *a
         }       
     }
 
+    ad->ad_data_fork.adf_refcount++;
+
 exit:
     if (ret != 0) {
-        free(ad->ad_resforkbuf);
+        if (ad->ad_resforkbuf)
+            free(ad->ad_resforkbuf);
         ad->ad_resforkbuf = NULL;
         ad->ad_rlen = 0;
         ad->ad_resforkbufsize = 0;