]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/adouble/ad_open.c
Merge symlink branch
[netatalk.git] / libatalk / adouble / ad_open.c
index b0eb42350553b2924d2e42e9cbc31a1abcf26691..2785cbf17848f8b790f13d5c0d23cc033781b415 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_open.c,v 1.68 2010-01-06 14:05:15 franklahm Exp $
+ * $Id: ad_open.c,v 1.69 2010-02-10 14:05:37 franklahm Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
@@ -1014,8 +1014,8 @@ int ad_stat(const char *path, struct stat *stbuf)
     if (!p) {
         return -1;
     }
-
-    return stat( p, stbuf );
+//FIXME!
+    return lstat( p, stbuf );
 }
 
 /* ----------------
@@ -1037,7 +1037,7 @@ static int ad_chown(const char *path, struct stat *stbuf)
     if (default_uid != (uid_t)-1) {
         /* we are root (admin) */
         id = (default_uid)?default_uid:stbuf->st_uid;
-        ret = chown( path, id, stbuf->st_gid );
+        ret = lchown( path, id, stbuf->st_gid );
     }
 #endif
     return ret;
@@ -1265,6 +1265,7 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble
         ad->ad_adflags = adflags;
         ad->ad_resource_fork.adf_refcount = 0;
         ad->ad_data_fork.adf_refcount = 0;
+        ad->ad_data_fork.adf_syml=0;
     }
     else {
         ad->ad_open_forks = ((ad->ad_data_fork.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
@@ -1283,13 +1284,33 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble
                     admode = mode;
                 }
             }
-            ad->ad_data_fork.adf_fd =open( path, hoflags, admode );
+                
+            ad->ad_data_fork.adf_fd =open( path, hoflags | O_NOFOLLOW, admode );
+            
             if (ad->ad_data_fork.adf_fd < 0 ) {
                 if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
                     hoflags = oflags;
-                    ad->ad_data_fork.adf_fd = open( path, hoflags, admode );
+                    ad->ad_data_fork.adf_fd = open( path, hoflags | O_NOFOLLOW, admode );
+                }
+                if (ad->ad_data_fork.adf_fd < 0 && errno == ELOOP) {
+                    int lsz;
+
+                    if (oflags != O_RDONLY)
+                         return -1;
+
+                    ad->ad_data_fork.adf_syml = malloc(PATH_MAX+1);
+                    lsz = readlink(path, ad->ad_data_fork.adf_syml, PATH_MAX);
+                    if (lsz <= 0) {
+                        free(ad->ad_data_fork.adf_syml);
+                        return -1;
+                    }
+                    ad->ad_data_fork.adf_syml[lsz]=0;
+                    ad->ad_data_fork.adf_syml = realloc(ad->ad_data_fork.adf_syml,lsz+1);
+                    // XX
+                    ad->ad_data_fork.adf_fd = 0;
                 }
             }
+
             if ( ad->ad_data_fork.adf_fd < 0)
                 return -1;
 
@@ -1349,11 +1370,11 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble
     if (!(adflags & ADFLAGS_RDONLY)) {
         hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
     }
-    ad->ad_md->adf_fd = open( ad_p, hoflags, 0 );
+    ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 );
     if (ad->ad_md->adf_fd < 0 ) {
         if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
             hoflags = oflags & ~(O_CREAT | O_EXCL);
-            ad->ad_md->adf_fd = open( ad_p, hoflags, 0 );
+            ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 );
         }
     }
 
@@ -1618,7 +1639,7 @@ static int new_rfork(const char *path, struct adouble *ad, int adflags)
         memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
     }
 
-    if (stat(path, &st) < 0) {
+    if (lstat(path, &st) < 0) {
         return -1;
     }