]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/cnid.c
Don't log failed lstat
[netatalk.git] / libatalk / util / cnid.c
index 375309071d57bce7f5fd5317a69231069d343d52..6e431c1b8d16dfca39d0a02bfc03e0ac1fdf5284 100644 (file)
@@ -35,7 +35,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/stat.h>
-
+#include <arpa/inet.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
@@ -48,7 +48,6 @@
 
 #include <atalk/util.h>
 #include <atalk/cnid.h>
-#include <atalk/volinfo.h>
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/logger.h>
@@ -135,3 +134,69 @@ EC_CLEANUP:
         return NULL;
     return fpath;
 }
+
+/*!
+ * Resolves CNID of a given path
+ *
+ * path might be:
+ * (a) relative:
+ *     "dir/subdir" with cwd: "/afp_volume/topdir"
+ * (b) absolute:
+ *     "/afp_volume/dir/subdir"
+ *
+ * path MUST be pointing inside vol, this is usually the case as vol has been build from
+ * path using loadvolinfo and friends.
+ *
+ * @param cdb     (r) CNID db handle
+ * @param volpath (r) UNIX path of volume
+ * @param path    (r) path, see above
+ * @param did     (w) parent CNID of returned CNID
+ *
+ * @returns CNID of path
+ */
+cnid_t cnid_for_path(struct _cnid_db *cdb,
+                     const char *volpath,
+                     const char *path,
+                     cnid_t *did)
+{
+    EC_INIT;
+
+    cnid_t cnid;
+    bstring rpath = NULL;
+    bstring statpath = NULL;
+    struct bstrList *l = NULL;
+    struct stat st;
+
+    cnid = htonl(2);
+
+    EC_NULL(rpath = rel_path_in_vol(path, volpath));
+    EC_NULL(statpath = bfromcstr(volpath));
+    EC_ZERO(bcatcstr(statpath, "/"));
+
+    l = bsplit(rpath, '/');
+    for (int i = 0; i < l->qty ; i++) {
+        *did = cnid;
+
+        EC_ZERO( bconcat(statpath, l->entry[i]) );
+        EC_ZERO( lstat(cfrombstr(statpath), &st) );
+
+        if ((cnid = cnid_add(cdb,
+                             &st,
+                             *did,
+                             cfrombstr(l->entry[i]),
+                             blength(l->entry[i]),
+                             0)) == CNID_INVALID) {
+            EC_FAIL;
+        }
+        EC_ZERO(bcatcstr(statpath, "/"));
+    }
+
+EC_CLEANUP:
+    bdestroy(rpath);
+    bstrListDestroy(l);
+    bdestroy(statpath);
+    if (ret != 0)
+        return CNID_INVALID;
+
+    return cnid;
+}