]> arthur.barton.de Git - netatalk.git/commitdiff
/tmp/log
authordidg <didg>
Thu, 16 Jan 2003 20:06:33 +0000 (20:06 +0000)
committerdidg <didg>
Thu, 16 Jan 2003 20:06:33 +0000 (20:06 +0000)
etc/afpd/file.c
etc/afpd/fork.c
etc/afpd/fork.h
include/atalk/adouble.h
libatalk/adouble/ad_lock.c
libatalk/adouble/ad_write.c

index 4529f37043ac278f68712cf16c92b79534146eac..691ec0cafdf05ec318a89871a7fe5a68f2f381e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.72 2003-01-12 14:39:59 didg Exp $
+ * $Id: file.c,v 1.73 2003-01-16 20:06:33 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -1048,7 +1048,7 @@ int               ibuflen, *rbuflen;
     memcpy(&ddid, ibuf, sizeof( ddid ));
     ibuf += sizeof( ddid );
 
-    if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
+    if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
         return afp_errno;
     }
     if ( *s_path->m_name == '\0' ) {
@@ -1071,14 +1071,14 @@ int             ibuflen, *rbuflen;
 #ifdef FORCE_UIDGID
     /* FIXME svid != dvid && dvid's user can't read svid */
 #endif
-    if (( vol = getvolbyvid( dvid )) == NULL ) {
+    if (NULL == ( vol = getvolbyvid( dvid )) ) {
         return( AFPERR_PARAM );
     }
 
     if (vol->v_flags & AFPVOL_RO)
         return AFPERR_VLOCK;
 
-    if (( dir = dirlookup( vol, ddid )) == NULL ) {
+    if (NULL == ( dir = dirlookup( vol, ddid )) ) {
         return afp_errno;
     }
 
@@ -1428,13 +1428,13 @@ int         checkAttrib;
          *
          * FIXME it doesn't for RFORK open read only and fork open without deny mode
          */
-        if (ad_tmplock(&ad, ADEID_RFORK, locktype |ADLOCK_FILELOCK, 0, 0) < 0 ) {
+        if (ad_tmplock(&ad, ADEID_RFORK, locktype |ADLOCK_FILELOCK, 0, 0, 0) < 0 ) {
             ad_close( &ad, adflags );
             return( AFPERR_BUSY );
         }
     }
 
-    if (ad_tmplock( &ad, ADEID_DFORK, locktype, 0, 0 ) < 0) {
+    if (ad_tmplock( &ad, ADEID_DFORK, locktype, 0, 0, 0 ) < 0) {
         err = AFPERR_BUSY;
         goto delete_unlock;
     }
@@ -1475,8 +1475,8 @@ int         checkAttrib;
 
 delete_unlock:
     if (adflags & ADFLAGS_HF)
-        ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR |ADLOCK_FILELOCK, 0, 0);
-    ad_tmplock(&ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
+        ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR |ADLOCK_FILELOCK, 0, 0, 0);
+    ad_tmplock(&ad, ADEID_DFORK, ADLOCK_CLR, 0, 0, 0);
     ad_close( &ad, adflags );
 
 #ifdef DEBUG
index 32008c1db55d02f16a899e7a4c224be9a82077f1..543c769c5fc20de9433d1fe3ef094423ff4b6496 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.43 2003-01-12 14:40:01 didg Exp $
+ * $Id: fork.c,v 1.44 2003-01-16 20:06:33 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -47,9 +47,6 @@
 #include "desktop.h"
 #include "volume.h"
 
-#define BYTELOCK_MAX 0x7FFFFFFFU
-#define BYTELOCK_MAXL 0x7FFFFFFFFFFFFFFFULL
-
 struct ofork           *writtenfork;
 extern int getmetadata(struct vol *vol,
                  u_int16_t bitmap,
@@ -107,24 +104,75 @@ const u_int16_t     attrbits;
     return getmetadata(vol, bitmap, ofork->of_name, dir, &st, buf, buflen, adp, attrbits );    
 }
 
+/* ---------------------------- */
+static off_t get_off_t(ibuf, is64)
+char   **ibuf;
+int     is64;
+{
+    u_int32_t             temp;
+    off_t                 ret;
+
+    ret = 0;
+    memcpy(&temp, *ibuf, sizeof( temp ));
+    ret = ntohl(temp); /* ntohl is unsigned */
+    *ibuf += sizeof(temp);
+
+    if (is64) {
+        memcpy(&temp, *ibuf, sizeof( temp ));
+        *ibuf += sizeof(temp);
+        ret = ntohl(temp)| (ret << 32);
+    }
+    else {
+       ret = (int)ret; /* sign extend */
+    }
+    return ret;
+}
+
+/* ---------------------- */
+static int set_off_t(offset, rbuf, is64)
+off_t   offset;
+char   *rbuf;
+int     is64;
+{
+    u_int32_t  temp;
+    int        ret;
+
+    ret = 0;
+    if (is64) {
+        temp = htonl(offset >> 32);
+        memcpy(rbuf, &temp, sizeof( temp ));
+        rbuf += sizeof(temp);
+        ret = sizeof( temp );
+        offset &= 0xffffffff;
+    }
+    temp = htonl(offset);
+    memcpy(rbuf, &temp, sizeof( temp ));
+    ret += sizeof( temp );
+
+    return ret;
+}
+
+/* ------------------------ 
+*/
+static int is_neg(int is64, off_t val)
+{
+    if (val < 0 || (sizeof(off_t) == 8 && !is64 && (val & 0x80000000U)))
+       return 1;
+    return 0;
+}
+
+static __inline__ int sum_neg(int is64, off_t offset, off_t reqcount) 
+{
+    if (is_neg(is64, offset +reqcount) ) 
+       return 1;
+    return 0;
+}
+
 /* -------------------------
 */
-#define SHARE 0
-#define EXCL  1
-static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what, int mode)
+static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what)
 {
-    int lockmode;
-    int lockop;
-    
-    /* NOTE: we can't write lock a read-only file. on those, we just
-     * make sure that we have a read lock set. that way, we at least prevent
-     * someone else from really setting a deny read/write on the file. 
-     */
-    lockmode = (ad_getoflags(adp, eid) & O_RDWR) ?ADLOCK_WR : ADLOCK_RD;
-    lockop = (mode == EXCL)?lockmode:ADLOCK_RD;
-    
-    return ad_lock(adp, eid, lockop | ADLOCK_FILELOCK | ADLOCK_UPGRADE,
-                        what, 1, ofrefnum);
+    return ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, what, 1, ofrefnum);
 }
 
 /* -------------------------
@@ -146,7 +194,7 @@ static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
     int mode;    
 
     if (! (access & (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD))) {
-        return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE, SHARE);
+        return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE);
     }
 
     if ((access & (OPENACC_RD | OPENACC_DRD))) {
@@ -166,14 +214,13 @@ static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
         /* boolean logic is not enough, because getforkmode is not always telling the
          * true 
          */
-        mode = ((access & OPENACC_DRD))?EXCL: SHARE;
         if ((access & OPENACC_RD)) {
-            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD, mode);
+            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD);
             if (ret)
                 return ret;
         }
         if ((access & OPENACC_DRD)) {
-            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD, SHARE);
+            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD);
             if (ret)
                 return ret;
         }
@@ -193,14 +240,13 @@ static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
             errno = EACCES;
             return -1;
         }   
-        mode = ((access & OPENACC_DWR))?EXCL: SHARE;
         if ((access & OPENACC_WR)) {
-            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR, mode);
+            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR);
             if (ret)
                 return ret;
         }
         if ((access & OPENACC_DWR)) {
-            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR, SHARE);
+            ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR);
             if (ret)
                 return ret;
         }
@@ -481,21 +527,24 @@ char      *ibuf, *rbuf;
 int            ibuflen, *rbuflen;
 {
     struct ofork       *ofork;
-    int32_t            size;
+    off_t              size;
     u_int16_t          ofrefnum, bitmap;
     int                 err;
-
+    int                 is64;
+    int                 eid;
+    off_t              st_size;
+    
     ibuf += 2;
+
     memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
     ibuf += sizeof( ofrefnum );
+
     memcpy(&bitmap, ibuf, sizeof(bitmap));
     bitmap = ntohs(bitmap);
     ibuf += sizeof( bitmap );
-    memcpy(&size, ibuf, sizeof( size ));
-    size = ntohl( size );
 
     *rbuflen = 0;
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_setforkparams: of_find could not locate open fork refnum: %u", ofrefnum );
         return( AFPERR_PARAM );
     }
@@ -506,24 +555,69 @@ int               ibuflen, *rbuflen;
     if ((ofork->of_flags & AFPFORK_ACCWR) == 0)
         return AFPERR_ACCESS;
 
-    if (size < 0)
+    if ( ofork->of_flags & AFPFORK_DATA) {
+        eid = ADEID_DFORK;
+    } else if (ofork->of_flags & AFPFORK_RSRC) {
+        eid = ADEID_RFORK;
+    } else
         return AFPERR_PARAM;
 
-    if ((bitmap == (1<<FILPBIT_DFLEN)) && (ofork->of_flags & AFPFORK_DATA)) {
+    if ( ( (bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) )) 
+                  && eid == ADEID_RFORK 
+         ) ||
+         ( (bitmap & ( (1<<FILPBIT_RFLEN) | (1<<FILPBIT_EXTRFLEN) )) 
+                  && eid == ADEID_DFORK)) {
+        return AFPERR_BITMAP;
+    }
+    
+    is64 = 0;
+    if ((bitmap & ( (1<<FILPBIT_EXTDFLEN) | (1<<FILPBIT_EXTRFLEN) ))) {
+        if (afp_version >= 30) {
+            is64 = 4;
+        }
+        else 
+           return AFPERR_BITMAP;
+    }
+
+    if (ibuflen < 2+ sizeof(ofrefnum) + sizeof(bitmap) + is64 +4)
+        return AFPERR_PARAM ;
+    
+    size = get_off_t(&ibuf, is64);
+
+    if (size < 0)
+        return AFPERR_PARAM; /* Some MacOS don't return an error they just don't change the size! */
+
+
+    if (bitmap == (1<<FILPBIT_DFLEN) || bitmap == (1<<FILPBIT_EXTDFLEN)) {
+       st_size = ad_size(ofork->of_ad, eid);
+       err = -2;
+       if (st_size > size && 
+             ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, size, st_size -size, ofork->of_refnum) < 0) 
+            goto afp_setfork_err;
+
         err = ad_dtruncate( ofork->of_ad, size );
+        if (st_size > size)
+           ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum);  
         if (err < 0)
             goto afp_setfork_err;
-    } else if ((bitmap == (1<<FILPBIT_RFLEN)) &&
-               (ofork->of_flags & AFPFORK_RSRC)) {
+    } else if (bitmap == (1<<FILPBIT_RFLEN) || bitmap == (1<<FILPBIT_EXTRFLEN)) {
         ad_refresh( ofork->of_ad );
+
+       st_size = ad_size(ofork->of_ad, eid);
+       err = -2;
+       if (st_size > size && 
+              ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, size, st_size -size, ofork->of_refnum) < 0) {
+            goto afp_setfork_err;
+       }
         err = ad_rtruncate(ofork->of_ad, size);
+        if (st_size > size)
+           ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum);  
         if (err < 0)
             goto afp_setfork_err;
 
         if (ad_flush( ofork->of_ad, ADFLAGS_HF ) < 0) {
-            LOG(log_error, logtype_afpd, "afp_setforkparams: ad_flush: %s",
-                strerror(errno) );
-            return( AFPERR_PARAM );
+            LOG(log_error, logtype_afpd, "afp_setforkparams: ad_flush: %s",strerror(errno) );
+            return AFPERR_PARAM;
         }
     } else
         return AFPERR_BITMAP;
@@ -565,48 +659,6 @@ afp_setfork_err:
 #define ENDBIT(a)  ((a) & 0x80)
 #define UNLOCKBIT(a) ((a) & 0x01)
 
-static off_t get_off_t(ibuf, is64)
-char   **ibuf;
-int     is64;
-{
-    u_int32_t             temp;
-    off_t                 ret;
-
-    memcpy(&temp, *ibuf, sizeof( temp ));
-    ret = ntohl(temp); /* ntohl is unsigned */
-    *ibuf += sizeof(temp);
-
-    if (is64) {
-        memcpy(&temp, *ibuf, sizeof( temp ));
-        *ibuf += sizeof(temp);
-        ret = ntohl(temp)| (ret << 32);
-    }
-    return ret;
-}
-
-/* ---------------------- */
-static int set_off_t(offset, rbuf, is64)
-off_t   offset;
-char   *rbuf;
-int     is64;
-{
-    u_int32_t  temp;
-    int        ret;
-
-    ret = 0;
-    if (is64) {
-        temp = htonl(offset >> 32);
-        memcpy(rbuf, &temp, sizeof( temp ));
-        rbuf += sizeof(temp);
-        ret = sizeof( temp );
-        offset &= 0xffffffff;
-    }
-    temp = htonl(offset);
-    memcpy(rbuf, &temp, sizeof( temp ));
-    ret += sizeof( temp );
-
-    return ret;
-}
 
 /* ---------------------- */
 static int byte_lock(obj, ibuf, ibuflen, rbuf, rbuflen, is64 )
@@ -620,7 +672,8 @@ int     is64;
     int                 eid;
     u_int16_t          ofrefnum;
     u_int8_t            flags;
-
+    int                 lockop;
+    
     *rbuflen = 0;
 
     /* figure out parameters */
@@ -630,7 +683,7 @@ int     is64;
     memcpy(&ofrefnum, ibuf, sizeof(ofrefnum));
     ibuf += sizeof(ofrefnum);
 
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_bytelock: of_find");
         return( AFPERR_PARAM );
     }
@@ -645,39 +698,29 @@ int     is64;
     offset = get_off_t(&ibuf, is64);
     length = get_off_t(&ibuf, is64);
 
-    if (is64) {
-        if (length == -1)
-            length = BYTELOCK_MAXL;
-        else if (length <= 0) {
-            return AFPERR_PARAM;
-        } else if ((length >= AD_FILELOCK_BASE) &&
-                   (ad_hfileno(ofork->of_ad) == -1)) {
-            return AFPERR_LOCK;
-        }
-    }
-    else {
-        if (length == 0xFFFFFFFF)
-            length = BYTELOCK_MAX;
-        else if (!length || (length & (1 << 31))) {
-            return AFPERR_PARAM;
-        } else if ((length >= AD_FILELOCK_BASE) &&
-                   (ad_hfileno(ofork->of_ad) == -1)) {
-            return AFPERR_LOCK;
-        }
+    /* FIXME AD_FILELOCK test is surely wrong */
+    if (length == -1)
+        length = BYTELOCK_MAX;
+     else if (!length || is_neg(is64, length)) {
+       return AFPERR_PARAM;
+     } else if ((length >= AD_FILELOCK_BASE) && -1 == (ad_hfileno(ofork->of_ad))) {
+        return AFPERR_LOCK;
     }
-    
-    if (ENDBIT(flags))
-        offset += ad_size(ofork->of_ad, eid);
 
+    if (ENDBIT(flags)) {
+        offset += ad_size(ofork->of_ad, eid);
+        /* FIXME what do we do if file size > 2 GB and 
+           it's not byte_lock_ext?
+        */
+    }
     if (offset < 0)    /* error if we have a negative offset */
         return AFPERR_PARAM;
 
     /* if the file is a read-only file, we use read locks instead of
      * write locks. that way, we can prevent anyone from initiating
      * a write lock. */
-    if (ad_lock(ofork->of_ad, eid, UNLOCKBIT(flags) ? ADLOCK_CLR :
-                ((ad_getoflags(ofork->of_ad, eid) & O_RDWR) ?
-                 ADLOCK_WR : ADLOCK_RD), offset, length,
+    lockop = UNLOCKBIT(flags) ? ADLOCK_CLR : ADLOCK_WR;
+    if (ad_lock(ofork->of_ad, eid, lockop, offset, length,
                 ofork->of_refnum) < 0) {
         switch (errno) {
         case EACCES:
@@ -747,7 +790,7 @@ struct ofork        *of;
 
 
 static __inline__ ssize_t read_file(struct ofork *ofork, int eid,
-                                    int offset, u_char nlmask,
+                                    off_t offset, u_char nlmask,
                                     u_char nlchar, char *rbuf,
                                     int *rbuflen, const int xlate)
 {
@@ -885,7 +928,7 @@ int is64;
 
     savereqcount = reqcount;
     saveoff = offset;
-    if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount) < 0) {
+    if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
         err = AFPERR_LOCK;
         goto afp_read_err;
     }
@@ -968,12 +1011,12 @@ afp_read_loop:
 afp_read_exit:
         LOG(log_error, logtype_afpd, "afp_read: %s", strerror(errno));
         dsi_readdone(dsi);
-        ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
+        ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
         obj->exit(1);
     }
 
 afp_read_done:
-    ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
+    ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
     return err;
 
 afp_read_err:
@@ -1032,7 +1075,7 @@ int               ibuflen, *rbuflen;
     ibuf += 2;
     memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
 
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_flushfork: of_find");
         return( AFPERR_PARAM );
     }
@@ -1101,7 +1144,7 @@ int               ibuflen, *rbuflen;
     ibuf += 2;
     memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
 
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_closefork: of_find");
         return( AFPERR_PARAM );
     }
@@ -1175,6 +1218,7 @@ static __inline__ ssize_t write_file(struct ofork *ofork, int eid,
     return cc;
 }
 
+
 /* FPWrite. NOTE: on an error, we always use afp_write_err as
  * the client may have sent us a bunch of data that's not reflected 
  * in reqcount et al. */
@@ -1200,7 +1244,7 @@ int                 is64;
     offset   = get_off_t(&ibuf, is64);
     reqcount = get_off_t(&ibuf, is64);
 
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_write: of_find");
         err = AFPERR_PARAM;
         goto afp_write_err;
@@ -1236,7 +1280,7 @@ int                 is64;
 
     /* offset can overflow on 64-bit capable filesystems.
      * report disk full if that's going to happen. */
-    if (offset + reqcount < 0) {
+     if (sum_neg(is64, offset, reqcount)) {
         err = AFPERR_DFULL;
         goto afp_write_err;
     }
@@ -1249,7 +1293,7 @@ int                 is64;
 
     saveoff = offset;
     if (ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, saveoff,
-                   reqcount) < 0) {
+                   reqcount, ofork->of_refnum) < 0) {
         err = AFPERR_LOCK;
         goto afp_write_err;
     }
@@ -1272,7 +1316,7 @@ int                 is64;
         if ((cc = write_file(ofork, eid, offset, rbuf, *rbuflen,
                              xlate)) < 0) {
             *rbuflen = 0;
-            ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+            ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
             return cc;
         }
         offset += cc;
@@ -1289,7 +1333,7 @@ int                 is64;
                     (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
                 dsi_writeflush(dsi);
                 *rbuflen = 0;
-                ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+                ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
                 return cc;
             }
             offset += cc;
@@ -1311,7 +1355,7 @@ int                 is64;
                     dsi_writeflush(dsi);
                     *rbuflen = 0;
                     ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff,
-                               reqcount);
+                               reqcount,  ofork->of_refnum);
                     return cc;
                 }
 
@@ -1332,7 +1376,7 @@ int                 is64;
                     dsi_writeflush(dsi);
                     *rbuflen = 0;
                     ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff,
-                               reqcount);
+                               reqcount,  ofork->of_refnum);
                     return cc;
                 }
                 offset += cc;
@@ -1341,7 +1385,7 @@ int                 is64;
         break;
     }
 
-    ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+    ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount,  ofork->of_refnum);
     if ( ad_hfileno( ofork->of_ad ) != -1 )
         ofork->of_flags |= AFPFORK_DIRTY;
 
@@ -1397,7 +1441,7 @@ int               ibuflen, *rbuflen;
     ibuf += sizeof( bitmap );
 
     *rbuflen = 0;
-    if (( ofork = of_find( ofrefnum )) == NULL ) {
+    if (NULL == ( ofork = of_find( ofrefnum )) ) {
         LOG(log_error, logtype_afpd, "afp_getforkparams: of_find");
         return( AFPERR_PARAM );
     }
index 5140312b0c7ac312d6378707a487ec2ef19cf315..512f5f2c254c4107720009ccccbc4a18ac4fa101 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.h,v 1.6 2002-10-11 14:18:34 didg Exp $
+ * $Id: fork.h,v 1.7 2003-01-16 20:06:33 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -44,6 +44,7 @@ struct ofork {
 #define OPENACC_DRD    (1<<4)
 #define OPENACC_DWR    (1<<5)
 
+/* ofork.of_flags bits */
 #define AFPFORK_OPEN   (1<<0)
 #define AFPFORK_RSRC   (1<<1)
 #define AFPFORK_DATA   (1<<2)
index 542503fc6509df2ffef6fc1b64feedf1052ac25b..f1820381ee0c31702523508e8d3b564267022421 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: adouble.h,v 1.12 2002-11-14 17:15:22 srittau Exp $
+ * $Id: adouble.h,v 1.13 2003-01-16 20:06:33 didg Exp $
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -261,8 +261,18 @@ struct adouble {
 /* synchronization locks */
 #define AD_FILELOCK_BASE (0x80000000)
 #else
-#define AD_FILELOCK_BASE (0x7FFFFFFF -4)
+#define AD_FILELOCK_BASE (0x7FFFFFFF -9)
 #endif
+
+/* FIXME:
+ * AD_FILELOCK_BASE case 
+ */
+#if _FILE_OFFSET_BITS == 64   
+#define BYTELOCK_MAX (0x7FFFFFFFFFFFFFFFULL)
+#else
+#define BYTELOCK_MAX (0x7FFFFFFFU)
+#endif
+
 #define AD_FILELOCK_OPEN_WR        (AD_FILELOCK_BASE + 0)
 #define AD_FILELOCK_OPEN_RD       (AD_FILELOCK_BASE + 1)
 #define AD_FILELOCK_DENY_WR       (AD_FILELOCK_BASE + 2)
@@ -308,12 +318,12 @@ extern int ad_close           __P((struct adouble *, int));
 /* ad_lock.c */
 extern int ad_fcntl_lock __P((struct adouble *, const u_int32_t /*eid*/,
                              const int /*type*/, const off_t /*offset*/,
-                             const size_t /*len*/, const int /*user*/));
+                             const off_t /*len*/, const int /*user*/));
 extern void ad_fcntl_unlock __P((struct adouble *, const int /*user*/));
 
 extern int ad_fcntl_tmplock __P((struct adouble *, const u_int32_t /*eid*/,
                                 const int /*type*/, const off_t /*offset*/,
-                                const size_t /*len*/));
+                                const off_t /*len*/, const int /*user*/));
 
 #define ad_lock ad_fcntl_lock
 #define ad_tmplock ad_fcntl_tmplock
@@ -365,8 +375,8 @@ extern ssize_t ad_write __P((struct adouble *, const u_int32_t, off_t,
 extern ssize_t adf_pread  __P((struct ad_fd *, void *, size_t, off_t));
 extern ssize_t adf_pwrite __P((struct ad_fd *, const void *, size_t, off_t));
 
-extern int ad_dtruncate __P((struct adouble *, const size_t));
-extern int ad_rtruncate __P((struct adouble *, const size_t));
+extern int ad_dtruncate __P((struct adouble *, const off_t));
+extern int ad_rtruncate __P((struct adouble *, const off_t));
 
 /* ad_size.c */
 extern off_t ad_size __P((const struct adouble *, const u_int32_t ));
index 22ceef504c9a2fc20fe453e8459ccd282076929d..0331bb3c3d239aab3347075c14ea2ebba59d5736 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * $Id: ad_lock.c,v 1.6 2002-11-14 17:15:22 srittau Exp $
+ * $Id: ad_lock.c,v 1.7 2003-01-16 20:06:33 didg Exp $
  *
  * Copyright (c) 1998,1999 Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT for more information.
 ((type) == ADLOCK_WR ? LOCK_EX : \
  ((type) == ADLOCK_CLR ? LOCK_UN : -1)))
 
-#define XLATE_FCNTL_LOCK(type) ((type) == ADLOCK_RD ? F_RDLCK : \
-((type) == ADLOCK_WR ? F_WRLCK : \
- ((type) == ADLOCK_CLR ? F_UNLCK : -1))) 
-     
-#define OVERLAP(a,alen,b,blen) ((!(alen) && (a) <= (b)) || \
-                               (!(blen) && (b) <= (a)) || \
-                               ((((a) + (alen)) > (b)) && \
-                               (((b) + (blen)) > (a))))
+/* ----------------------- */
+static int XLATE_FCNTL_LOCK(int type) 
+{
+    switch(type) {
+    case ADLOCK_RD:
+        return F_RDLCK;
+    case ADLOCK_WR:
+         return F_WRLCK;
+    case ADLOCK_CLR:
+         return F_UNLCK;
+    }
+    return -1;
+}
+
+/* ----------------------- */
+
+static int OVERLAP(off_t a, off_t alen, off_t b, off_t blen) 
+{
+ return (!alen && a <= b) || 
+       (!blen && b <= a) || 
+       ( (a + alen > b) && (b + blen > a) );
+}
 
 
 /* allocation for lock regions. we allocate aggressively and shrink
@@ -116,7 +130,7 @@ static __inline__ void adf_unlock(struct ad_fd *ad, int fd, const int user)
 /* relock any byte lock that overlaps off/len. unlock everything
  * else. */
 static __inline__ void adf_relockrange(struct ad_fd *ad, int fd,
-                                      const off_t off, const size_t len)
+                                      const off_t off, const off_t len)
 {
     adf_lock_t *lock = ad->adf_lock;
     int i;
@@ -132,7 +146,7 @@ static __inline__ void adf_relockrange(struct ad_fd *ad, int fd,
 static __inline__ int adf_findlock(struct ad_fd *ad,
                                   const int user, const int type,
                                   const off_t off,
-                                  const size_t len)
+                                  const off_t len)
 {
   adf_lock_t *lock = ad->adf_lock;
   int i;
@@ -154,7 +168,7 @@ static __inline__ int adf_findlock(struct ad_fd *ad,
 static __inline__  int adf_findxlock(struct ad_fd *ad, 
                                     const int user, const int type,
                                     const off_t off,
-                                    const size_t len)
+                                    const off_t len)
 {
   adf_lock_t *lock = ad->adf_lock;
   int i;
@@ -234,20 +248,23 @@ int start = off;
        return start;
 }
 
-int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int type,
-                 const off_t off, const size_t len, const int user)
+/* ------------------ */
+int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype,
+                 const off_t off, const off_t len, const int user)
 {
   struct flock lock;
   struct ad_fd *adf;
   adf_lock_t *adflock, *oldlock;
   int i;
-  
+  int type;  
+
   lock.l_start = off;
+  type = locktype;
   if (eid == ADEID_DFORK) {
     adf = &ad->ad_df;
     if ((type & ADLOCK_FILELOCK)) {
         if (ad_hfileno(ad) != -1) {
-               lock.l_start = df2off(off);
+            lock.l_start = df2off(off);
             adf = &ad->ad_hf;
         }
     }
@@ -258,8 +275,22 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int type,
     else
       lock.l_start += ad_getentryoff(ad, eid);
   }
-
+  /* NOTE: we can't write lock a read-only file. on those, we just
+    * make sure that we have a read lock set. that way, we at least prevent
+    * someone else from really setting a deny read/write on the file. 
+    */
+  if (!(adf->adf_flags & O_RDWR) && (type & ADLOCK_WR)) {
+      type = (type & ~ADLOCK_WR) | ADLOCK_RD;
+  }
+  
   lock.l_type = XLATE_FCNTL_LOCK(type & ADLOCK_MASK);
+  lock.l_whence = SEEK_SET;
+  lock.l_len = len;
+
+  /* byte_lock(len=-1) lock whole file */
+  if (len == BYTELOCK_MAX) {
+      lock.l_len -= lock.l_start; /* otherwise  EOVERFLOW error */
+  }
 
   /* see if it's locked by another user. 
    * NOTE: this guarantees that any existing locks must be at most
@@ -267,13 +298,13 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int type,
    * guaranteed to be ORable. */
   if (adf_findxlock(adf, user, ADLOCK_WR | 
                    ((type & ADLOCK_WR) ? ADLOCK_RD : 0), 
-                   lock.l_start, len) > -1) {
+                   lock.l_start, lock.l_len) > -1) {
     errno = EACCES;
     return -1;
   }
   
   /* look for any existing lock that we may have */
-  i = adf_findlock(adf, user, ADLOCK_RD | ADLOCK_WR, lock.l_start, len);
+  i = adf_findlock(adf, user, ADLOCK_RD | ADLOCK_WR, lock.l_start, lock.l_len);
   adflock = (i < 0) ? NULL : adf->adf_lock + i;
 
   /* here's what we check for:
@@ -283,13 +314,11 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int type,
   if ((!adflock && (lock.l_type == F_UNLCK)) ||
       (adflock && !(type & ADLOCK_UPGRADE) && 
        ((lock.l_type != F_UNLCK) || (adflock->lock.l_start != lock.l_start) ||
-       (adflock->lock.l_len != len)))) {
+       (adflock->lock.l_len != lock.l_len)))) {
     errno = EINVAL;
     return -1;
   }
 
-  lock.l_whence = SEEK_SET;
-  lock.l_len = len;
 
   /* now, update our list of locks */
   /* clear the lock */
@@ -310,8 +339,8 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int type,
 
   /* it wasn't an upgrade */
   oldlock = NULL;
-  if ((lock.l_type = F_RDLCK) &&
-      ((i = adf_findxlock(adf, user, ADLOCK_RD, lock.l_start, len)) > -1)) {
+  if ((lock.l_type == F_RDLCK) &&
+      ((i = adf_findxlock(adf, user, ADLOCK_RD, lock.l_start, lock.l_len)) > -1)) {
     oldlock = adf->adf_lock + i;
   } 
     
@@ -384,7 +413,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
   /* Does another process have a lock? 
      FIXME F_GETLK ?
   */
-  lock.l_type = (ad_getoflags(ad, eid) & O_RDWR) ?F_WRLCK : F_RDLCK;                                           
+  lock.l_type = (adf->adf_flags & O_RDWR) ?F_WRLCK : F_RDLCK;                                           
 
   if (fcntl(adf->adf_fd, F_SETLK, &lock) < 0) {
     return (errno == EACCES || errno == EAGAIN)?1:-1;
@@ -396,11 +425,8 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
 
 /* -------------------------
 */
-/* with temp locks, we don't need to distinguish within the same
- * process as everything is single-threaded. in addition, if
- * multi-threading gets added, it will only be in a few areas. */
 int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int type,
-                    const off_t off, const size_t len)
+                    const off_t off, const off_t len, const int user)
 {
   struct flock lock;
   struct ad_fd *adf;
@@ -424,6 +450,14 @@ int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int type,
   lock.l_whence = SEEK_SET;
   lock.l_len = len;
 
+  /* see if it's locked by another user. */
+  if (user && adf_findxlock(adf, user, ADLOCK_WR | 
+                   ((type & ADLOCK_WR) ? ADLOCK_RD : 0), 
+                   lock.l_start, lock.l_len) > -1) {
+    errno = EACCES;
+    return -1;
+  }
+
   /* okay, we might have ranges byte-locked. we need to make sure that
    * we restore the appropriate ranges once we're done. so, we check
    * for overlap on an unlock and relock. 
index 52b33ea4ffa3db7fb2128d2c658061714a2117c3..1faf1799603a1a1e46362a63e239c72968180305 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_write.c,v 1.4 2002-10-11 14:18:39 didg Exp $
+ * $Id: ad_write.c,v 1.5 2003-01-16 20:06:33 didg Exp $
  *
  * Copyright (c) 1990,1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -46,7 +46,7 @@ ssize_t adf_pwrite(struct ad_fd *ad_fd, const void *buf, size_t count, off_t off
     return cc;
 }
 
-
+/* end is always 0 */
 ssize_t ad_write( ad, eid, off, end, buf, buflen )
     struct adouble     *ad;
     const u_int32_t    eid;
@@ -92,57 +92,30 @@ ssize_t ad_write( ad, eid, off, end, buf, buflen )
     return( cc );
 }
 
-/* set locks here */
+/* 
+ * the caller set the locks
+ * we need tocopy and paste from samba code source/smbd/vfs_wrap.c
+ * ftruncate is undefined when the file length is smaller than 'size'
+ */
 int ad_rtruncate( ad, size )
     struct adouble     *ad;
-    const size_t       size;
+    const off_t        size;
 {
-    int err;
-
-    if (ad_tmplock(ad, ADEID_RFORK, ADLOCK_WR, 0, 0) < 0)
-      return -2;
-
     if ( ftruncate( ad->ad_hf.adf_fd,
            size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 ) {
-        err = errno;
-        ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
-       errno = err;
        return( -1 );
     }
     ad->ad_rlen = size;    
 
-#if 0
-    ad->ad_eid[ ADEID_RFORK ].ade_len = size;
-    if ( lseek( ad->ad_hf.adf_fd, ad->ad_eid[ADEID_RFORK].ade_off, 
-               SEEK_SET ) < 0 ) {
-        err = errno;
-        ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
-       errno = err;
-       return( -1 );
-    }
-
-    ad->ad_hf.adf_off = ad->ad_eid[ADEID_RFORK].ade_off;
-#endif
-    ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
     return( 0 );
 }
 
 int ad_dtruncate(ad, size)
     struct adouble     *ad;
-    const size_t       size;
+    const off_t        size;
 {
-    int err;
-
-    if (ad_tmplock(ad, ADEID_DFORK, ADLOCK_WR, 0, 0) < 0)
-      return -2;
-
     if (ftruncate(ad->ad_df.adf_fd, size) < 0) {
-      err = errno;
-      ad_tmplock(ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
-      errno = err;
       return -1;
-    } else 
-      ad_tmplock(ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
-
+    }
     return 0;
 }