]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
*** empty log message ***
[netatalk.git] / etc / afpd / file.c
index 52b56a0a8c2771c9cac7e16de82c593c93f9dd8c..42dfea89fe6c3985e8ec88f2acdf10c3329083de 100644 (file)
@@ -1,18 +1,24 @@
 /*
+ * $Id: file.c,v 1.23 2001-07-10 13:38:13 rufustfirefly Exp $
+ *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
 
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif /* HAVE_UNISTD_H */
 #include <string.h>
 #include <utime.h>
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
 #include <dirent.h>
 #include <sys/mman.h>
 #include <errno.h>
 #include "filedir.h"
 #include "globals.h"
 
+/* check for mtab DID code */
+#ifdef DID_MTAB
+#include "parse_mtab.h"
+#endif /* DID_MTAB */
+
 #ifdef FORCE_UIDGID
+#warning UIDGID
 #include "uid.h"
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
 /* the format for the finderinfo fields (from IM: Toolbox Essentials):
  * field         bytes        subfield    bytes
@@ -76,7 +88,11 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
     char       *buf;
     int                *buflen;
 {
+#ifndef USE_LASTDID
     struct stat                hst, lst, *lstp;
+#else /* USE_LASTDID */
+    struct stat                hst;
+#endif /* USE_LASTDID */
     struct adouble     ad, *adp;
     struct ofork        *of;
     struct extmap      *em;
@@ -87,7 +103,7 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin getfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     upath = mtoupath(vol, path);
     if ((of = of_findname(vol, curdir, path))) {
@@ -194,7 +210,7 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
 
            if (!(aint = cnid_add(vol->v_db, st, dir->d_did, upath, 
                                  strlen(upath), aint))) {
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
            /*
             * What a fucking mess.  First thing:  DID and FNUMs are
             * in the same space for purposes of enumerate (and several
@@ -221,11 +237,20 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
             *
             * it should be okay to use lstat to deal with symlinks.
             */
-             lstp = (lstat(upath, &lst) < 0) ? st : &lst;
+#ifdef USE_LASTDID
+             aint = htonl(( st->st_dev << 16 ) | (st->st_ino & 0x0000ffff));
+#else /* USE_LASTDID */
+             lstp = lstat(upath, &lst) < 0 ? st : &lst;
+#ifdef DID_MTAB
+             aint = htonl( afpd_st_cnid ( lstp ) );
+#else /* DID_MTAB */
              aint = htonl(CNID(lstp, 1));
+#endif /* DID_MTAB */
+#endif /* USE_LASTDID */
+
 #if AD_VERSION > AD_VERSION1
            }
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
            memcpy(data, &aint, sizeof( aint ));
            data += sizeof( aint );
            break;
@@ -319,7 +344,7 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end getfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return( AFP_OK );
 }
@@ -339,11 +364,11 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     u_int16_t          vid;
 #ifdef FORCE_UIDGID
        uidgidset               *uidgid;
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_createfile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     *rbuflen = 0;
     ibuf++;
@@ -405,7 +430,7 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
        /* perform all switching of users */
        set_uidgid ( vol );
 
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
     if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF,
                  openf, 0666, adp) < 0 ) {
@@ -414,13 +439,13 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
 #ifdef FORCE_UIDGID
                /* bring everything back to old euid, egid */
                restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
            return( AFPERR_EXIST );
        case EACCES :
 #ifdef FORCE_UIDGID
                /* bring everything back to old euid, egid */
                restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
            return( AFPERR_ACCESS );
         case ENOENT:
            /* on noadouble volumes, just creating the data fork is ok */
@@ -431,7 +456,7 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
 #ifdef FORCE_UIDGID
                /* bring everything back to old euid, egid */
                restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
            return( AFPERR_PARAM );
        }
     }
@@ -445,19 +470,21 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
 createfile_done:
 
 #ifdef DROPKLUDGE
-    retvalue=matchfile2dirperms(upath, vol, did);
-#endif DROPKLUDGE
+    if (vol->v_flags & AFPVOL_DROPBOX) {
+         retvalue = matchfile2dirperms(upath, vol, did);
+    }
+#endif /* DROPKLUDGE */
 
     setvoltime(obj, vol );
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end afp_createfile");
-#endif DEBUG
+#endif /* DEBUG */
 
 #ifdef FORCE_UIDGID
        /* bring everything back to old euid, egid */
        restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
     return (retvalue);
 }
@@ -475,7 +502,7 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_setfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     *rbuflen = 0;
     ibuf += 2;
@@ -513,7 +540,7 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end afp_setfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return( rc );
 }
@@ -536,11 +563,13 @@ int setfilparams(vol, path, bitmap, buf )
 
 #ifdef FORCE_UIDGID
        uidgidset               *uidgid;
-#endif FORCE_UIDGID
+
+       uidgid = malloc(sizeof(uidgidset));
+#endif /* FORCE_UIDGID */
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin setfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     upath = mtoupath(vol, path);
     if ((of = of_findname(vol, curdir, path))) {
@@ -553,7 +582,7 @@ int setfilparams(vol, path, bitmap, buf )
 #ifdef FORCE_UIDGID
        save_uidgid ( uidgid );
        set_uidgid ( vol );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
     if (ad_open( upath, vol_noadouble(vol) | ADFLAGS_HF, 
                 O_RDWR|O_CREAT, 0666, adp) < 0) {
@@ -561,7 +590,7 @@ int setfilparams(vol, path, bitmap, buf )
       if (bitmap & ~(1<<FILPBIT_MDATE)) {
 #ifdef FORCE_UIDGID
        restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
        return vol_noadouble(vol) ? AFP_OK : AFPERR_ACCESS;
       }
       isad = 0;
@@ -682,13 +711,13 @@ setfilparam_done:
 
 #ifdef FORCE_UIDGID
        restore_uidgid ( uidgid );
-#endif FORCE_UIDGID
+#endif /* FORCE_UIDGID */
 
     }
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end setfilparams:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return err;
 }
@@ -718,7 +747,7 @@ int renamefile(src, dst, newname, noadouble )
 
 #ifdef DEBUG
     syslog (LOG_INFO, "begin renamefile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     if ( rename( src, dst ) < 0 ) {
        switch ( errno ) {
@@ -789,7 +818,7 @@ rename_retry:
 
 #ifdef DEBUG
     syslog (LOG_INFO, "end renamefile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return( AFP_OK );
 }
@@ -803,12 +832,12 @@ int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     struct dir *dir;
     char       *newname, *path, *p;
     u_int32_t  sdid, ddid;
-    int                plen, err, did, retvalue = AFP_OK;
+    int                plen, err, retvalue = AFP_OK;
     u_int16_t  svid, dvid;
 
 #ifdef DEBUG
     syslog (LOG_INFO, "begin afp_copyfile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     *rbuflen = 0;
     ibuf += 2;
@@ -885,12 +914,14 @@ int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     setvoltime(obj, vol );
 
 #ifdef DROPKLUDGE
-    retvalue=matchfile2dirperms(newname, vol, sdid);
-#endif DROPKLUDGE
+    if (vol->v_flags & AFPVOL_DROPBOX) {
+         retvalue=matchfile2dirperms(newname, vol, sdid);
+    }
+#endif /* DROPKLUDGE */
 
 #ifdef DEBUG
     syslog (LOG_INFO, "end afp_copyfile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return( retvalue );
 }
@@ -903,7 +934,7 @@ static __inline__ int copy_all(const int dfd, const void *buf,
 
 #ifdef DEBUG
   syslog(LOG_INFO, "begin copy_all:");
-#endif DEBUG
+#endif /* DEBUG */
 
   while (buflen > 0) {
     if ((cc = write(dfd, buf, buflen)) < 0) {
@@ -925,7 +956,7 @@ static __inline__ int copy_all(const int dfd, const void *buf,
 
 #ifdef DEBUG
   syslog(LOG_INFO, "end copy_all:");
-#endif DEBUG
+#endif /* DEBUG */
 
   return AFP_OK;
 }
@@ -944,7 +975,7 @@ int copyfile(src, dst, newname, noadouble )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin copyfile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     if (newname) { 
       if ((sfd = open( ad_path( src, ADFLAGS_HF ), O_RDONLY, 0 )) < 0 ) {
@@ -991,7 +1022,7 @@ int copyfile(src, dst, newname, noadouble )
          }
          goto copyheader_done;
        }
-#endif
+#endif /* SENDFILE_FLAVOR_LINUX */
        while (1) {
          if ((cc = read(sfd, filebuf, sizeof(filebuf))) < 0) {
            if (errno == EINTR) 
@@ -1055,7 +1086,7 @@ copyheader_done:
       }
       goto copydata_done;
     }
-#endif
+#endif /* SENDFILE_FLAVOR_LINUX */
 
     while (1) {
       if ((cc = read( sfd, filebuf, sizeof( filebuf ))) < 0) {
@@ -1105,7 +1136,7 @@ copydata_done:
     
 #ifdef DEBUG
     syslog(LOG_INFO, "end copyfile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return( AFP_OK );
 }
@@ -1116,48 +1147,71 @@ int deletefile( file )
 {
     struct adouble     ad;
     int                        adflags, err = AFP_OK;
+    int                        locktype = ADLOCK_WR;
+    int                        openmode = O_RDWR;
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin deletefile:");
-#endif DEBUG
-
-    /* try to open both at once */
-    adflags = ADFLAGS_DF|ADFLAGS_HF;
-    memset(&ad, 0, sizeof(ad));
-    if ( ad_open( file, adflags, O_RDWR, 0, &ad ) < 0 ) {
-         switch (errno) {
-         case ENOENT:
-           adflags = ADFLAGS_DF;
-           /* that failed. now try to open just the data fork */
-           memset(&ad, 0, sizeof(ad));
-           if ( ad_open( file, adflags, O_RDWR, 0, &ad ) < 0 ) {
+#endif /* DEBUG */
+
+    while(1) {
+       /*
+        * If can't open read/write then try again read-only.  If it's open
+        * read-only, we must do a read lock instead of a write lock.
+        */
+       /* try to open both at once */
+       adflags = ADFLAGS_DF|ADFLAGS_HF;
+       memset(&ad, 0, sizeof(ad));
+       if ( ad_open( file, adflags, openmode, 0, &ad ) < 0 ) {
              switch (errno) {
              case ENOENT:
-               return AFPERR_NOOBJ;
+               adflags = ADFLAGS_DF;
+               /* that failed. now try to open just the data fork */
+               memset(&ad, 0, sizeof(ad));
+               if ( ad_open( file, adflags, openmode, 0, &ad ) < 0 ) {
+                 switch (errno) {
+                 case ENOENT:
+                   return AFPERR_NOOBJ;
+                 case EACCES:
+                   if(openmode == O_RDWR) {
+                       openmode = O_RDONLY;
+                       locktype = ADLOCK_RD;
+                       continue;
+                   } else {
+                       return AFPERR_ACCESS;
+                   }
+                 case EROFS:
+                   return AFPERR_VLOCK;
+                 default:
+                   return AFPERR_PARAM;
+                 }
+               }
+               break;
+
              case EACCES:
-               return AFPERR_ACCESS;
+               if(openmode == O_RDWR) {
+                   openmode = O_RDONLY;
+                   locktype = ADLOCK_RD;
+                   continue;
+               } else {
+                   return AFPERR_ACCESS;
+               }
+             case EROFS:
+               return AFPERR_VLOCK;
              default:
-               return AFPERR_PARAM;
+               return( AFPERR_PARAM );
              }
-           }
-           break;
-
-         case EACCES:
-           return( AFPERR_ACCESS );
-         case EROFS:
-           return AFPERR_VLOCK;
-         default:
-           return( AFPERR_PARAM );
-         }
+       }
+       break;  /* from the while */
     }
 
     if ((adflags & ADFLAGS_HF) &&
-       (ad_tmplock(&ad, ADEID_RFORK, ADLOCK_WR, 0, 0) < 0 )) {
+       (ad_tmplock(&ad, ADEID_RFORK, locktype, 0, 0) < 0 )) {
       ad_close( &ad, adflags );
       return( AFPERR_BUSY );
     }
 
-    if (ad_tmplock( &ad, ADEID_DFORK, ADLOCK_WR, 0, 0 ) < 0) {
+    if (ad_tmplock( &ad, ADEID_DFORK, locktype, 0, 0 ) < 0) {
       err = AFPERR_BUSY;
       goto delete_unlock;
     }
@@ -1204,7 +1258,7 @@ delete_unlock:
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end deletefile:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return err;
 }
@@ -1228,7 +1282,7 @@ int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_createid:");
-#endif DEBUG
+#endif /* DEBUG */
     
     *rbuflen = 0;
     ibuf += 2;
@@ -1282,7 +1336,7 @@ int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
       id = 0;
     else {
       memcpy(&id, ad_entry(&ad, ADEID_DID), sizeof(id));
-      ad_close(upath, ADFLAGS_HF);
+      ad_close(&ad, ADFLAGS_HF);
     }
 
     if (id = cnid_add(vol->v_db, &st, did, upath, len, id)) {
@@ -1293,7 +1347,7 @@ int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "ending afp_createid...:");
-#endif DEBUG
+#endif /* DEBUG */
 
     switch (errno) {
     case EROFS:
@@ -1325,7 +1379,7 @@ int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_resolveid:");
-#endif DEBUG
+#endif /* DEBUG */
     
     *rbuflen = 0;
     ibuf += 2;
@@ -1376,7 +1430,7 @@ int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end afp_resolveid:");
-#endif DEBUG
+#endif /* DEBUG */
     
     return AFP_OK;
 }
@@ -1396,7 +1450,7 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_deleteid:");
-#endif DEBUG
+#endif /* DEBUG */
 
     *rbuflen = 0;
     ibuf += 2;
@@ -1455,13 +1509,14 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
 #ifdef DEBUG
     syslog(LOG_INFO, "end afp_deleteid:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return err;
 }
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
 
 #define APPLETEMP ".AppleTempXXXXXX"
+
 int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
     AFPObj      *obj;
     char       *ibuf, *rbuf;
@@ -1475,13 +1530,13 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                 err;
 #if AD_VERSION > AD_VERSION1
     int                 slen, dlen;
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
     cnid_t             sid, did;
     u_int16_t          vid;
 
 #ifdef DEBUG
     syslog(LOG_INFO, "begin afp_exchangefiles:");
-#endif DEBUG
+#endif /* DEBUG */
 
     *rbuflen = 0;
     ibuf += 2;
@@ -1541,7 +1596,7 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
 #if AD_VERSION > AD_VERSION1
     sid = cnid_lookup(vol->v_db, &srcst, sdir->d_did, supath, 
                      slen = strlen(supath));
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
 
     if (( dir = dirsearch( vol, did )) == NULL ) {
        return( AFPERR_PARAM );
@@ -1577,7 +1632,7 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
     /* look for destination id. */
     did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath, 
                      dlen = strlen(upath));
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
 
     /* construct a temp name. 
      * NOTE: the temp file will be in the dest file's directory. it
@@ -1629,11 +1684,11 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
        cnid_update(vol->v_db, sid, &srcst, sdir->d_did, supath, slen);
       goto err_temp_to_dest;
     }
-#endif
+#endif /* AD_VERSION > AD_VERSION1 */
 
 #ifdef DEBUG
     syslog(LOG_INFO, "ending afp_exchangefiles:");
-#endif DEBUG
+#endif /* DEBUG */
 
     return AFP_OK;