]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/adouble/ad_open.c
Fix ad_reso_size once more...
[netatalk.git] / libatalk / adouble / ad_open.c
index bafade2a6d939f02273ae1d1fe9c0559b096a5d7..72250de8034caca1cacf9422870e0ad2ee0f87a6 100644 (file)
 #define ADEDOFF_RFORK_V2     (ADEDOFF_PRIVID + ADEDLEN_PRIVID)
 
 /* ad:ea */
-#define ADEDOFF_FINDERI_EA   (AD_HEADER_LEN + ADEID_NUM_EA * AD_ENTRY_LEN)
-#define ADEDOFF_COMMENT_EA   (ADEDOFF_FINDERI_EA + ADEDLEN_FINDERI)
+#define ADEDOFF_FINDERI_EA    (AD_HEADER_LEN + ADEID_NUM_EA * AD_ENTRY_LEN)
+#define ADEDOFF_COMMENT_EA    (ADEDOFF_FINDERI_EA + ADEDLEN_FINDERI)
 #define ADEDOFF_FILEDATESI_EA (ADEDOFF_COMMENT_EA + ADEDLEN_COMMENT)
-#define ADEDOFF_AFPFILEI_EA  (ADEDOFF_FILEDATESI_EA + ADEDLEN_FILEDATESI)
+#define ADEDOFF_AFPFILEI_EA   (ADEDOFF_FILEDATESI_EA + ADEDLEN_FILEDATESI)
+#define ADEDOFF_PRIVID_EA     (ADEDOFF_AFPFILEI_EA + ADEDLEN_AFPFILEI)
 
 /* this is to prevent changing timezones from causing problems with
    localtime volumes. the screw-up is 30 years. we use a delta of 5 years */
@@ -162,7 +163,7 @@ static const struct entry entry_order_ea[ADEID_NUM_EA + 1] = {
     {ADEID_COMMENT,    ADEDOFF_COMMENT_EA,    ADEDLEN_INIT},
     {ADEID_FILEDATESI, ADEDOFF_FILEDATESI_EA, ADEDLEN_FILEDATESI},
     {ADEID_AFPFILEI,   ADEDOFF_AFPFILEI_EA,   ADEDLEN_AFPFILEI},
-    {ADEID_PRIVID,     ADEDOFF_PRIVID,        ADEDLEN_INIT},
+    {ADEID_PRIVID,     ADEDOFF_PRIVID_EA,     ADEDLEN_INIT},
     {0, 0, 0}
 };
 
@@ -937,6 +938,10 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
 
     oflags = O_NOFOLLOW | (ad2openflags(adflags) & ~(O_CREAT | O_TRUNC));
 
+    if (ad_meta_fileno(ad) == -2)
+        /* symlink */
+        EC_EXIT;
+
     if (ad_meta_fileno(ad) != -1) {
         /* the file is already open, but we want write access: */
         if ((oflags & O_RDWR) &&
@@ -956,7 +961,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
                 /* For directories we open the directory RDONYL so we can later fchdir()  */
                 oflags = (oflags & ~O_RDWR) | O_RDONLY;
             LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path);
-            EC_NEG1(ad_meta_fileno(ad) = open(path, oflags));
+            EC_NEG1_LOG(ad_meta_fileno(ad) = open(path, oflags));
             opened = 1;
             ad->ad_mdp->adf_flags = oflags;
         }
@@ -964,9 +969,8 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
 
     /* Read the adouble header in and parse it.*/
     if (ad->ad_ops->ad_header_read(path, ad, NULL) != 0) {
-        LOG(log_error, logtype_default, "ad_open_hf_ea: no EA adouble");
-
         if (!(adflags & ADFLAGS_CREATE)) {
+            LOG(log_error, logtype_default, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path);
             errno = ENOENT;
             EC_FAIL;
         }
@@ -1041,14 +1045,18 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad)
     LOG(log_debug, logtype_default, "ad_reso_size(\"%s\")", path);
 
 #ifdef HAVE_EAFD
-    int opened = 0;
-    int eafd = ad_reso_fileno(ad);
-    if (eafd == -1) {
-        EC_NEG1( eafd = sys_getxattrfd(path, O_RDONLY) );
-        opened = 1;
+    ssize_t easz;
+
+    if (ad_reso_fileno(ad) != -1) {
+        EC_NEG1( fstat(ad_reso_fileno(ad), &st) );
+        ad->ad_rlen = st.st_size;
+    } else if (ad_meta_fileno(ad) != -1) {
+        EC_NEG1( easz = sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, NULL, 0) );
+        ad->ad_rlen = easz;
+    } else {
+        EC_FAIL;
     }
-    EC_NEG1( rlen = fstat(eafd, &st) );
-    ad->ad_rlen = st.st_size;
+
 #else
     const char *rfpath;
     EC_NULL_LOG( rfpath = ad->ad_ops->ad_path(path, adflags));
@@ -1062,10 +1070,6 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad)
     LOG(log_debug, logtype_default, "ad_reso_size(\"%s\"): size: %zd", path, ad->ad_rlen);
 
 EC_CLEANUP:
-#ifdef HAVE_EAFD
-    if (opened)
-        close(eafd);
-#endif
     if (ret != 0)
         ad->ad_rlen = 0;
     EC_EXIT;
@@ -1110,11 +1114,16 @@ static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *a
         goto EC_CLEANUP;
     }
 #ifdef HAVE_EAFD
-    if ((ad_reso_fileno(ad) = sys_getxattrfd(path, oflags)) == -1) {
-        if (!(adflags & ADFLAGS_CREATE))
+    if (ad_meta_fileno(ad) == -1)
+        EC_FAIL;
+    if ((ad_reso_fileno(ad) = sys_getxattrfd(ad_meta_fileno(ad), AD_EA_RESO, oflags)) == -1) {
+        if (!(adflags & ADFLAGS_CREATE)) {
+            errno = ENOENT;
             EC_FAIL;
+        }
         oflags |= O_CREAT;
-        EC_NEG1_LOG( ad_reso_fileno(ad) = sys_getxattrfd(path, oflags, 0666) ); 
+        EC_NEG1_LOG( ad_reso_fileno(ad) = sys_getxattrfd(ad_meta_fileno(ad),
+                                                         AD_EA_RESO, oflags, 0666) ); 
     }
 #else
     EC_NULL_LOG( rfpath = ad->ad_ops->ad_path(path, adflags) );
@@ -1599,10 +1608,10 @@ int ad_refresh(const char *path, struct adouble *ad)
         if (AD_RSRC_OPEN(ad)) {
             if (ad_reso_fileno(ad) == -1)
                 return -1;
-            ssize_t len;
-            if ((len = fstat(ad_reso_fileno(ad))) == -1)
+            struct stat st;
+            if (fstat(ad_reso_fileno(ad), &st) == -1)
                 return -1;
-            ad->ad_rlen = len;
+            ad->ad_rlen = st.st_size;
         }
 #else
         if (AD_META_OPEN(ad)) {