]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/adouble/ad_read.c
Fix ressource fork refcounting
[netatalk.git] / libatalk / adouble / ad_read.c
index 7b8841bb619b01cdf05e22ff0a305572f0f2d01f..852a6e963b94f964e3b47d1ea8b67df6cac0717e 100644 (file)
@@ -62,8 +62,7 @@ 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;
+    off_t r_off = 0;
 
     /* We're either reading the data fork (and thus the data file)
      * or we're reading anything else (and thus the header file). */
@@ -83,69 +82,18 @@ ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, c
             /* resource fork is not open ( cf etc/afp/fork.c) */
             return 0;
 
-        switch (ad->ad_vers) {
-        case AD_VERSION2:
+        if (ad->ad_vers == AD_VERSION_EA) {
+#ifdef HAVE_EAFD
+            r_off = off;
+#else
+            r_off = off + ADEDOFF_RFORK_OSX;
+#endif
+        } else {
             r_off = ad_getentryoff(ad, eid) + off;
-            if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
-                return( -1 );
-            /*
-             * We've just read in bytes from the disk that we read earlier
-             * into ad_data. If we're going to write this buffer out later,
-             * we need to update ad_data.
-             * FIXME : always false?
-             */
-            if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
-                if ( ad->ad_resource_fork.adf_flags & O_RDWR ) {
-                    memcpy(buf, ad->ad_data + r_off,
-                           MIN(sizeof( ad->ad_data ) - r_off, cc));
-                } else {
-                    memcpy(ad->ad_data + r_off, buf,
-                           MIN(sizeof( ad->ad_data ) - r_off, cc));
-                }
-            }
-            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_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) */
+        if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
+            return( -1 );
     }
 
     return( cc );