]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
OSX return AFPERR_NOOBJ rather than AFPERR_PARAM
[netatalk.git] / etc / afpd / file.c
index 41195251c086e1da8fd3049f50b5d2b2440404c2..47555f3c241396d4ed55f39fb9122054cabaf954 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.132 2010-02-04 10:52:29 franklahm Exp $
+ * $Id: file.c,v 1.139 2010-02-18 08:08:01 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -89,7 +89,7 @@ static int default_type(void *finder)
 }
 
 /* FIXME path : unix or mac name ? (for now it's unix name ) */
-void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data)
+void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink)
 {
     struct extmap      *em;
     void                *ad_finder = NULL;
@@ -114,6 +114,17 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a
             memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
         }
     }
+
+    if (islink){
+        u_int16_t linkflag;
+        memcpy(&linkflag, (char *)data + FINDERINFO_FRFLAGOFF, 2);
+        linkflag |= htons(FINDERINFO_ISALIAS);
+        memcpy((char *)data + FINDERINFO_FRFLAGOFF, &linkflag, 2);
+        memcpy((char *)data + FINDERINFO_FRTYPEOFF,"slnk",4); 
+        memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4); 
+        chk_ext = 0;
+    }
+
     /** Only enter if no appledouble information and no finder information found. */
     if (chk_ext && (em = getextmap( upath ))) {
         memcpy(data, em->em_type, sizeof( em->em_type ));
@@ -332,7 +343,7 @@ int getmetadata(struct vol *vol,
             break;
 
         case FILPBIT_FINFO :
-           get_finderinfo(vol, upath, adp, (char *)data);
+               get_finderinfo(vol, upath, adp, (char *)data,S_ISLNK(st->st_mode));
             data += ADEDLEN_FINDERI;
             break;
 
@@ -596,7 +607,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
     }
 
     upath = s_path->u_name;
-
+    
     /* if upath is deleted we already in trouble anyway */
     if ((of = of_findname(s_path))) {
         adp = of->of_ad;
@@ -667,18 +678,6 @@ createfile_done:
 
     setvoltime(obj, vol );
 
-    /* Check if this is the magic debugfile  */
-    if (retvalue == AFP_OK
-        && curdir->d_did == htonl(2)
-        && vol->v_debugfile
-        && strcmp(upath, vol->v_debugfile) == 0) {
-        char *path = absupath(vol, curdir, upath);
-        char *logstring = malloc(strlen("default log_maxdebug ") + strlen(path) + 1);
-        sprintf(logstring, "default log_maxdebug %s", path);
-        setuplog(logstring);
-        free(logstring);
-    }
-
     return (retvalue);
 }
 
@@ -807,6 +806,28 @@ int setfilparams(struct vol *vol,
         case FILPBIT_FINFO :
             change_mdate = 1;
             memcpy(finder_buf, buf, 32 );
+            if (memcmp(buf,"slnkrhap",8)==0 && !S_ISLNK(path->st.st_mode)){
+            // SLFINFO
+                int fp;
+                ssize_t len;
+                int erc=1;
+                char buf[PATH_MAX+1];
+                if ((fp=open(path->u_name,O_RDONLY))>=0){
+                    if ((len=read(fp,buf,PATH_MAX+1))){
+                        if (unlink(path->u_name)==0){
+                            buf[len]=0;
+                            erc = symlink(buf, path->u_name);
+                            if (!erc)
+                                of_stat(path);
+                        }
+                    }
+                    close(fp);
+                }
+                if (erc!=0){
+                    err=AFPERR_BITMAP;
+                    goto setfilparam_done;
+                }
+            }
             buf += 32;
             break;
         case FILPBIT_UNIXPR :
@@ -876,9 +897,9 @@ int setfilparams(struct vol *vol,
          * - change of modification date
          * - UNIX privs (Bug-ID #2863424)
          */
-        if ( (f_bitmap & ~(1<<FILPBIT_MDATE | 1<<FILPBIT_UNIXPR))) {
+        if (!vol_noadouble(vol) && (f_bitmap & ~(1<<FILPBIT_MDATE | 1<<FILPBIT_UNIXPR))) {
             LOG(log_debug, logtype_afpd, "setfilparams: need adouble access");
-            return vol_noadouble(vol) ? AFP_OK : AFPERR_ACCESS;
+            return AFPERR_ACCESS;
         }
         LOG(log_debug, logtype_afpd, "setfilparams: no adouble perms, but only FILPBIT_MDATE and/or FILPBIT_UNIXPR");
         isad = 0;
@@ -1186,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;
@@ -1196,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++;
 
@@ -1243,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 );
 }
 
@@ -1367,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;
@@ -1390,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 );
@@ -1666,7 +1703,7 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data)
     cnid_t        did  = param->did;
     cnid_t       aint;
     
-    if ( stat(de->d_name, &path.st)<0 )
+    if ( lstat(de->d_name, &path.st)<0 )
         return 0;
     
     /* update or add to cnid */
@@ -1711,7 +1748,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir)
     }
     
     /* FIXME use of_statdir ? */
-    if (stat(name, &st)) {
+    if (lstat(name, &st)) {
        return -1;
     }
 
@@ -1881,7 +1918,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
     }
 
     err = AFP_OK;
-    if ((movecwd(vol, dir) < 0) || (stat(upath, &st) < 0)) {
+    if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) {
         switch (errno) {
         case EACCES:
         case EPERM:
@@ -2126,10 +2163,10 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     if (did) {
        cnid_delete(vol->v_cdb, did);
     }
-    if ((did && ( (crossdev && stat( upath, &srcst) < 0) || 
+    if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || 
                 cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0))
        ||
-       (sid && ( (crossdev && stat(p, &destst) < 0) ||
+       (sid && ( (crossdev && lstat(p, &destst) < 0) ||
                 cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0))
     ) {
         switch (errno) {