]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
New MySQL CNID backend
[netatalk.git] / etc / afpd / file.c
index 307f6204f02d7155c2c6aa4dfe8293522f53cda1..cb8a968af09ddf491721b18b6b691f0fa97b62ce 100644 (file)
@@ -252,7 +252,7 @@ restart:
                     }
                     LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
                         vol->v_path);
-                    vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL);
+                    vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL, NULL, NULL);
                     if (vol->v_cdb) {
                         if (!(vol->v_flags & AFPVOL_TM)) {
                             vol->v_flags |= AFPVOL_RO;
@@ -378,6 +378,7 @@ int getmetadata(const AFPObj *obj,
                 ashort = htons(ATTRBIT_INVISIBLE);
             } else
                 ashort = 0;
+            ashort &= ~htons(vol->v_ignattr);
 #if 0
             /* FIXME do we want a visual clue if the file is read only
              */
@@ -460,18 +461,23 @@ int getmetadata(const AFPObj *obj,
             data += sizeof( aint );
             break;
 
-        case FILPBIT_RFLEN :
-            if ( adp ) {
+        case FILPBIT_RFLEN: {
+            off_t rlen;
+            if (adp) {
                 if (adp->ad_rlen > 0xffffffff)
                     aint = 0xffffffff;
                 else
                     aint = htonl( adp->ad_rlen);
             } else {
-                aint = 0;
+                rlen = ad_reso_size(path->u_name, 0, NULL);
+                if (rlen > 0xffffffff)
+                    rlen = 0xffffffff;
+                aint = htonl(rlen);
             }
             memcpy(data, &aint, sizeof( aint ));
             data += sizeof( aint );
             break;
+        }
 
             /* Current client needs ProDOS info block for this file.
                Use simple heuristic and let the Mac "type" string tell
@@ -539,15 +545,18 @@ int getmetadata(const AFPObj *obj,
             data += sizeof( aint );
             break;
         case FILPBIT_EXTRFLEN:
-            aint = 0;
-            if (adp) 
+            if (adp) {
                 aint = htonl(adp->ad_rlen >> 32);
-            memcpy(data, &aint, sizeof( aint ));
-            data += sizeof( aint );
-            if (adp) 
+                memcpy(data, &aint, sizeof( aint ));
+                data += sizeof( aint );
                 aint = htonl(adp->ad_rlen);
-            memcpy(data, &aint, sizeof( aint ));
-            data += sizeof( aint );
+                memcpy(data, &aint, sizeof( aint ));
+                data += sizeof( aint );
+            } else {
+                int64_t rlen = hton64(ad_reso_size(path->u_name, 0, NULL));
+                memcpy(data, &rlen, sizeof(rlen));
+                data += sizeof(rlen);
+            }
             break;
         case FILPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
@@ -1015,6 +1024,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol,
             ad_getattr(adp, &bshort);
             oshort = bshort;
             if ( ntohs( ashort ) & ATTRBIT_SETCLR ) {
+                ashort &= ~htons(vol->v_ignattr);
                 bshort |= htons( ntohs( ashort ) & ~ATTRBIT_SETCLR );
             } else {
                 bshort &= ~ashort;
@@ -1519,7 +1529,7 @@ done:
    WRITE lock on read only file.
 */
 
-static int check_attrib(struct adouble *adp)
+static int check_attrib(const struct vol *vol, struct adouble *adp)
 {
 uint16_t   bshort = 0;
 
@@ -1527,10 +1537,10 @@ uint16_t   bshort = 0;
     /*
      * Does kFPDeleteInhibitBit (bit 8) set?
      */
-       if ((bshort & htons(ATTRBIT_NODELETE))) {
+       if (!(vol->v_ignattr & ATTRBIT_NODELETE) && (bshort & htons(ATTRBIT_NODELETE))) {
                return AFPERR_OLOCK;
        }
-    if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) {
+     if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) {
        return AFPERR_BUSY;
        }
        return 0;
@@ -1555,7 +1565,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib)
          * ad_open would create a 0 byte resource fork
         */
         if ( ad_metadataat(dirfd, file, ADFLAGS_CHECK_OF, &ad) == 0 ) {
-            if ((err = check_attrib(&ad))) {
+            if ((err = check_attrib(vol, &ad))) {
                 ad_close(&ad, ADFLAGS_HF | ADFLAGS_CHECK_OF);
                return err;
             }
@@ -2199,6 +2209,42 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
         }
         goto err_temp_to_dest;
     }
+
+    if (AD_META_OPEN(adsp) || AD_META_OPEN(addp)) {
+        struct adouble adtmp;
+        bool opened_ads, opened_add;
+
+        ad_init(&adtmp, vol);
+        ad_init_offsets(&adtmp);
+
+        if (!AD_META_OPEN(adsp)) {
+            if (ad_open(adsp, p, ADFLAGS_HF) != 0)
+                return -1;
+            opened_ads = true;
+        }
+
+        if (!AD_META_OPEN(addp)) {
+            if (ad_open(addp, upath, ADFLAGS_HF) != 0)
+                return -1;
+            opened_add = true;
+        }
+
+        if (ad_copy_header(&adtmp, adsp) != 0)
+            goto err_temp_to_dest;
+        if (ad_copy_header(adsp, addp) != 0)
+            goto err_temp_to_dest;
+        if (ad_copy_header(addp, &adtmp) != 0)
+            goto err_temp_to_dest;
+        ad_flush(adsp);
+        ad_flush(addp);
+
+        if (opened_ads)
+            ad_close(adsp, ADFLAGS_HF);
+        if (opened_add)
+            ad_close(addp, ADFLAGS_HF);
+    }
+
+    /* FIXME: we should switch ressource fork too */
     
     /* here we need to reopen if crossdev */
     if (sid && ad_setid(addp, destst.st_dev, destst.st_ino,  sid, sdir->d_did, vol->v_stamp))