]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/unix.c
Merge from branch-2-1
[netatalk.git] / libatalk / util / unix.c
index 9fd11e615d5e9e798d9302a4e93eca492ff47dd3..1c131ad507c9712a4de3a18f8648795b89c950ef 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: unix.c,v 1.5 2010-02-28 17:02:49 didg Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
@@ -36,7 +35,6 @@
 #include <atalk/ea.h>
 #include <atalk/afp.h>
 #include <atalk/logger.h>
-#include <atalk/volume.h>
 #include <atalk/vfs.h>
 #include <atalk/util.h>
 #include <atalk/unix.h>
@@ -57,6 +55,26 @@ const char *getcwdpath(void)
         return strerror(errno);
 }
 
+/*!
+ * Takes a buffer with a path, strips slashs, returns basename
+ *
+ * @param p (rw) path
+ *        path may be
+ *          "[/][dir/[...]]file"
+ *        or
+ *          "[/][dir/[...]]dir/[/]"
+ *        Result is "file" or "dir" 
+ *
+ * @returns pointer to basename in path buffer, buffer is possibly modified
+ */
+char *stripped_slashes_basename(char *p)
+{
+    int i = strlen(p) - 1;
+    while (i > 0 && p[i] == '/')
+        p[i--] = 0;
+    return (strrchr(p, '/') ? strrchr(p, '/') + 1 : p);
+}
+
 /*!
  * @brief symlink safe chdir replacement
  *
@@ -64,10 +82,22 @@ const char *getcwdpath(void)
  *
  * @returns 1 if a path element is a symlink, 0 otherwise, -1 on syserror
  */
-int lchdir(struct vol *vol, const char *dir)
+int lchdir(const char *dir)
 {
     char buf[MAXPATHLEN+1];
+    char cwd[MAXPATHLEN+1];
+    char *test;
+    int  i;
 
+    /*
+     dir is a canonical path (without "../" "./" "//" )
+     but may end with a / 
+    */
+    *cwd = 0;
+    if (*dir != '/') {
+        if (getcwd(cwd, MAXPATHLEN) == NULL)
+            return -1;
+    }
     if (chdir(dir) != 0)
         return -1;
 
@@ -83,11 +113,38 @@ int lchdir(struct vol *vol, const char *dir)
     if (getcwd(buf, MAXPATHLEN) == NULL)
         return 1;
 
-    for (int i = 0; vol->v_path[i]; i++) {
-        if (buf[i] != vol->v_path[i]) {
+    i = 0;
+    if (*cwd) {
+        /* relative path requested, 
+         * Same directory?
+        */
+        for (; cwd[i]; i++) {
+            if (buf[i] != cwd[i])
+                return 1;
+        }
+        if (buf[i]) {
+            if (buf[i] != '/')
+                return 1;
+            i++;
+        }                    
+    }
+
+    test = &buf[i];    
+    for (i = 0; test[i]; i++) {
+        if (test[i] != dir[i]) {
             return 1;
         }
     }
-        
+    /* trailing '/' ? */
+    if (!dir[i])
+        return 0;
+
+    if (dir[i] != '/')
+        return 1;
+
+    i++;
+    if (dir[i])
+        return 1;
+
     return 0;
 }