From 83b9983e8fb0a9cd0038c1106cb4e7338a278a44 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 8 Oct 2010 16:50:46 +0200 Subject: [PATCH] CNID for new dirs works with ad cp -R --- bin/ad/ad.c | 2 +- bin/ad/ad_cp.c | 5 +- bin/ad/ad_util.c | 105 ++++++++++++++++++++++++++++++++-------- include/atalk/bstradd.h | 5 +- 4 files changed, 90 insertions(+), 27 deletions(-) diff --git a/bin/ad/ad.c b/bin/ad/ad.c index e272f5b9..381b05bf 100644 --- a/bin/ad/ad.c +++ b/bin/ad/ad.c @@ -41,7 +41,7 @@ static void usage_main(void) int main(int argc, char **argv) { - setuplog("default log_note /dev/tty"); + setuplog("default log_debug /dev/tty"); if (argc < 2) { usage_main(); diff --git a/bin/ad/ad_cp.c b/bin/ad/ad_cp.c index 25a36542..6a717bba 100644 --- a/bin/ad/ad_cp.c +++ b/bin/ad/ad_cp.c @@ -299,7 +299,7 @@ int ad_cp(int argc, char *argv[]) if ((dvolinfo.v_flags & AFPVOL_NODEV)) flags |= CNID_FLAG_NODEV; - if ((dvolume.v_cdb = cnid_open(dvolinfo.v_path, + if ((dvolume.v_cdb = cnid_open(dvolinfo.v_dbpath, 0000, "dbd", flags, @@ -329,7 +329,7 @@ int ad_cp(int argc, char *argv[]) if ((svolinfo.v_flags & AFPVOL_NODEV)) flags |= CNID_FLAG_NODEV; - if ((svolume.v_cdb = cnid_open(svolinfo.v_path, + if ((svolume.v_cdb = cnid_open(svolinfo.v_dbpath, 0000, "dbd", flags, @@ -496,6 +496,7 @@ static int copy(const char *path, /* Get CNID of Parent and add new childir to CNID database */ did = cnid_for_path(&dvolinfo, &dvolume, to.p_path); + SLOG("got CNID: %u for path: %s", ntohl(did), to.p_path); } if (pflag) { diff --git a/bin/ad/ad_util.c b/bin/ad/ad_util.c index 9f862a4d..25a980b8 100644 --- a/bin/ad/ad_util.c +++ b/bin/ad/ad_util.c @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include "ad.h" #define cp_pct(x, y)((y == 0) ? 0 : (int)(100.0 * (x) / (y))) @@ -159,33 +161,55 @@ char *utompath(const struct volinfo *volinfo, char *upath) return(m); } -/* +/*! + * Build path relativ to volume root + * * path might be: * (a) relative: * "dir/subdir" with cwd: "/afp_volume/topdir" * (b) absolute: * "/afp_volume/dir/subdir" + * + * @param path (r) path relative to cwd() or absolute + * @param volpath (r) volume path that path is a subdir of (has been computed in volinfo funcs) + * + * @returns relative path in new bstring, caller must bdestroy it */ -static const char *relative_path_for_volume(const char *path, const char *volpath) +static bstring rel_path_in_vol(const char *path, const char *volpath) { - static char buf[MAXPATHLEN+1]; - bstring fpath; + EC_INIT; + + if (path == NULL || volpath == NULL) + return NULL; + + bstring fpath = NULL; /* Make path absolute by concetanating for case (a) */ if (path[0] != '/') { - fpath = bfromcstr(getcwdpath()); - if (fpath->data[fpath->slen - 1] != '/') - bcatcstr(fpath, "/"); - bcatcstr(fpath, path); - if (fpath->data[fpath->slen - 1] == '/') - bdelete(fpath, fpath->slen - 1, 1); + EC_NULL(fpath = bfromcstr(getcwdpath())); + if (bchar(fpath, blength(fpath) - 1) != '/') + EC_ZERO(bcatcstr(fpath, "/")); + EC_ZERO(bcatcstr(fpath, path)); + BSTRING_STRIP_SLASH(fpath); + SLOG("Built path: %s", cfrombstr(fpath)); } else { - fpath = bfromcstr(path); - if (fpath->data[fpath->slen - 1] == '/') - bdelete(fpath, fpath->slen - 1, 1); - + EC_NULL(fpath = bfromcstr(path)); + BSTRING_STRIP_SLASH(fpath); + SLOG("Built path: %s", cfrombstr(fpath)); } + /* + * Now we have eg: + * fpath: /Volume/netatalk/dir/bla + * volpath: /Volume/netatalk/ + * we want: "dir/bla" + */ + EC_ZERO(bdelete(fpath, 0, strlen(volpath))); + SLOG("rel path: %s", cfrombstr(fpath)); + return fpath; + +EC_CLEANUP: + bdestroy(fpath); return NULL; } @@ -198,12 +222,10 @@ static const char *relative_path_for_volume(const char *path, const char *volpat * (b) absolute: * "/afp_volume/dir/subdir" * - * 1) in case a) concatenate both paths - * 3) strip volume root - * 4) start recursive CNID search with - * a) DID:2, "topdir" - * b) DID:2, "dir" - * 5) ...until we have the CNID for + * 1) start recursive CNID search with + * a) DID:2 / "topdir" + * b) DID:2 / "dir" + * 2) ...until we have the CNID for * a) "/afp_volume/topdir/dir" * b) "/afp_volume/dir" (no recursion required) */ @@ -211,8 +233,49 @@ cnid_t cnid_for_path(const struct volinfo *vi, const struct vol *vol, const char *path) { + EC_INIT; + + cnid_t did; + cnid_t cnid; + bstring rpath = NULL; + bstring statpath = NULL; + struct bstrList *l = NULL; + struct stat st; + + EC_NULL(rpath = rel_path_in_vol(path, vi->v_path)); + SLOG("vol:%s, path: %s, rpath: %s", vi->v_path, path, bdata(rpath)); + + cnid = htonl(2); + + EC_NULL(statpath = bfromcstr(vi->v_path)); + + l = bsplit(rpath, '/'); + SLOG("elem: %s, qty: %u", cfrombstr(l->entry[0]), l->qty); + for(int i = 0; i < l->qty ; i++) { + did = cnid; + EC_ZERO(bconcat(statpath, l->entry[i])); + SLOG("statpath: %s", cfrombstr(statpath)); + EC_ZERO_LOG(stat(cfrombstr(statpath), &st)); + SLOG("db query: did: %u, name: %s, dev: %08x, ino: %08x", + ntohl(did), cfrombstr(l->entry[i]), st.st_dev, st.st_ino); + cnid = cnid_add(vol->v_cdb, + &st, + did, + cfrombstr(l->entry[i]), + blength(l->entry[i]), + 0); + + EC_ZERO(bcatcstr(statpath, "/")); + } - return 0; +EC_CLEANUP: + bdestroy(rpath); + bstrListDestroy(l); + bdestroy(statpath); + if (ret != 0) + return CNID_INVALID; + + return cnid; } int ftw_copy_file(const struct FTW *entp, diff --git a/include/atalk/bstradd.h b/include/atalk/bstradd.h index df8262ca..2f0693cf 100644 --- a/include/atalk/bstradd.h +++ b/include/atalk/bstradd.h @@ -1,5 +1,4 @@ /* - $Id: bstradd.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -32,8 +31,8 @@ /* strip slashes from end of a bstring */ #define BSTRING_STRIP_SLASH(a) \ do { \ - while ((a)->data[(a)->slen - 1] == '/') \ - bdelete((a), (a)->slen - 1, 1); \ + while (bchar((a), blength(a) - 1) == '/') \ + bdelete((a), blength(a) - 1, 1); \ } while (0); typedef struct tagbstring static_bstring; -- 2.39.2