]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
Initialize AFPobj for AFP over AT too
[netatalk.git] / etc / afpd / file.c
index 4259dbd4ff32c86b01aa1d6c16ca6aa4425d6f7f..94b4f91ab055a687cb6d870deb1825b258c3675c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.137 2010-02-17 01:41:58 didg Exp $
+ * $Id: file.c,v 1.140 2010-03-02 12:45:31 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -1207,9 +1207,10 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si
     }
     denyreadset = (getforkmode(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 || 
                   getforkmode(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 );
-    ad_close( adp, ADFLAGS_DF |ADFLAGS_HF );
+
     if (denyreadset) {
-        return AFPERR_DENYCONF;
+        retvalue = AFPERR_DENYCONF;
+        goto copy_exit;
     }
 
     newname = obj->newtmp;
@@ -1217,42 +1218,54 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si
 
     p = ctoupath( s_vol, curdir, newname );
     if (!p) {
-        return AFPERR_PARAM;
-    
+        retvalue = AFPERR_PARAM;
+        goto copy_exit;
     }
+
 #ifdef FORCE_UIDGID
     /* FIXME svid != dvid && dvid's user can't read svid */
 #endif
     if (NULL == ( d_vol = getvolbyvid( dvid )) ) {
-        return( AFPERR_PARAM );
+        retvalue = AFPERR_PARAM;
+        goto copy_exit;
     }
 
-    if (d_vol->v_flags & AFPVOL_RO)
-        return AFPERR_VLOCK;
+    if (d_vol->v_flags & AFPVOL_RO) {
+        retvalue = AFPERR_VLOCK;
+        goto copy_exit;
+    }
 
     if (NULL == ( dir = dirlookup( d_vol, ddid )) ) {
-        return afp_errno;
+        retvalue = afp_errno;
+        goto copy_exit;
     }
 
     if (( s_path = cname( d_vol, dir, &ibuf )) == NULL ) {
-        return get_afp_errno(AFPERR_NOOBJ); 
+        retvalue = get_afp_errno(AFPERR_NOOBJ);
+        goto copy_exit;
     }
+    
     if ( *s_path->m_name != '\0' ) {
-       path_error(s_path, AFPERR_PARAM);
+       retvalue =path_error(s_path, AFPERR_NOOBJ);
+        goto copy_exit;
     }
 
     /* one of the handful of places that knows about the path type */
     if (copy_path_name(d_vol, newname, ibuf) < 0) {
-        return( AFPERR_PARAM );
+        retvalue = AFPERR_PARAM;
+        goto copy_exit;
     }
     /* newname is always only a filename so curdir *is* its
      * parent folder
     */
     if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) {
-        return( AFPERR_PARAM );
+        retvalue =AFPERR_PARAM;
+        goto copy_exit;
     }
+
     if ( (err = copyfile(s_vol, d_vol, p, upath , newname, adp)) < 0 ) {
-        return err;
+        retvalue = err;
+        goto copy_exit;
     }
     curdir->offcnt++;
 
@@ -1264,6 +1277,8 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si
 
     setvoltime(obj, d_vol );
 
+copy_exit:
+    ad_close( adp, ADFLAGS_DF |ADFLAGS_HF );
     return( retvalue );
 }
 
@@ -1388,7 +1403,7 @@ int copyfile(const struct vol *s_vol, const struct vol*d_vol,
         ad_init(&ads, s_vol->v_adouble, s_vol->v_ad_options); 
         adp = &ads;
     }
-    ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
+
     adflags = ADFLAGS_DF;
     if (newname) {
         adflags |= ADFLAGS_HF;
@@ -1411,6 +1426,7 @@ int copyfile(const struct vol *s_vol, const struct vol*d_vol,
       st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
     }
 
+    ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
     if (ad_open(dst , adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
         ret_err = errno;
         ad_close( adp, adflags );
@@ -1515,55 +1531,53 @@ u_int16_t   bshort = 0;
 int deletefile(const struct vol *vol, char *file, int checkAttrib)
 {
     struct adouble     ad;
-    struct adouble      *adp = &ad;
+    struct adouble      *adp = NULL;
     int                        adflags, err = AFP_OK;
+    int                        meta = 0;
 
 #ifdef DEBUG
     LOG(log_debug9, logtype_afpd, "begin deletefile:");
 #endif /* DEBUG */
 
-    /* try to open both forks at once */
-    adflags = ADFLAGS_DF|ADFLAGS_HF;
+    ad_init(&ad, vol->v_adouble, vol->v_ad_options);
     if (checkAttrib) {
         /* was EACCESS error try to get only metadata */
-        ad_init(&ad, vol->v_adouble, vol->v_ad_options);
         /* we never want to create a resource fork here, we are going to delete it 
          * moreover sometimes deletefile is called with a no existent file and 
          * ad_open would create a 0 byte resource fork
         */
         if ( ad_metadata( file, ADFLAGS_OPENFORKS, &ad) == 0 ) {
-            ad_close( &ad, adflags );
             if ((err = check_attrib(&ad))) {
+               ad_close_metadata(&ad);
                return err;
             }
+            meta = 1;
         }
     }
  
-    while(1) {
-       ad_init(&ad, vol->v_adouble, vol->v_ad_options);  /* OK */
-        if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
-            switch (errno) {
-            case ENOENT:
-                if (adflags == ADFLAGS_DF)
-                    return AFPERR_NOOBJ;
-                   
-                /* that failed. now try to open just the data fork */
-                adflags = ADFLAGS_DF;
-                continue;
-
-            case EACCES:
-                adp = NULL; /* maybe it's a file with no write mode for us */
-                break;      /* was return AFPERR_ACCESS;*/
-            case EROFS:
-                return AFPERR_VLOCK;
-            default:
-                return( AFPERR_PARAM );
-            }
+    /* try to open both forks at once */
+    adflags = ADFLAGS_DF;
+    if ( ad_open( file, adflags |ADFLAGS_HF|ADFLAGS_NOHF, O_RDONLY, 0, &ad ) < 0 ) {
+        switch (errno) {
+        case ENOENT:
+            err = AFPERR_NOOBJ;
+            goto end;
+        case EACCES: /* maybe it's a file with no write mode for us */
+            break;   /* was return AFPERR_ACCESS;*/
+        case EROFS:
+            err = AFPERR_VLOCK;
+            goto end;
+        default:
+            err = AFPERR_PARAM;
+            goto end;
         }
-        break; /* from the while */
+    }
+    else {
+        adp = &ad;
     }
 
-    if (adp && (adflags & ADFLAGS_HF) ) {
+    if ( adp && ad_reso_fileno( adp ) != -1 ) { /* there's a resource fork */
+        adflags |= ADFLAGS_HF;
         /* FIXME we have a pb here because we want to know if a file is open 
          * there's a 'priority inversion' if you can't open the ressource fork RW
          * you can delete it if it's open because you can't get a write lock.
@@ -1574,8 +1588,8 @@ int deletefile(const struct vol *vol, char *file, int checkAttrib)
          * FIXME it doesn't work for RFORK open read only and fork open without deny mode
          */
         if (ad_tmplock(&ad, ADEID_RFORK, ADLOCK_WR |ADLOCK_FILELOCK, 0, 0, 0) < 0 ) {
-            ad_close( &ad, adflags );
-            return( AFPERR_BUSY );
+            err = AFPERR_BUSY;
+            goto end;
         }
     }
 
@@ -1589,9 +1603,15 @@ int deletefile(const struct vol *vol, char *file, int checkAttrib)
             cnid_delete(vol->v_cdb, id);
         }
     }
+
+end:
+    if (meta)
+        ad_close_metadata(&ad);
+
     if (adp)
         ad_close( &ad, adflags );  /* ad_close removes locks if any */
 
+
 #ifdef DEBUG
     LOG(log_debug9, logtype_afpd, "end deletefile:");
 #endif /* DEBUG */