From 869777e486e0cf24c3cef64b57765a18c0c227de Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sun, 10 Oct 2010 09:21:15 +0200 Subject: [PATCH] ad cp nearly done --- bin/ad/ad.c | 2 +- bin/ad/ad.h | 5 +++- bin/ad/ad_cp.c | 44 ++++++++++++++++------------- bin/ad/ad_util.c | 30 ++++++++++---------- libatalk/vfs/unix.c | 5 +--- libatalk/vfs/vfs.c | 68 +++++++++++++++++++++++++++++---------------- 6 files changed, 90 insertions(+), 64 deletions(-) diff --git a/bin/ad/ad.c b/bin/ad/ad.c index 381b05bf..c18268e6 100644 --- a/bin/ad/ad.c +++ b/bin/ad/ad.c @@ -36,7 +36,7 @@ static void usage_main(void) /* printf("Usage: ad ls|rm|cp|mv|set [file|dir, ...]\n"); */ - printf("Usage: ad ls [file|dir, ...]\n"); + printf("Usage: ad ls|cp [file|dir, ...]\n"); } int main(int argc, char **argv) diff --git a/bin/ad/ad.h b/bin/ad/ad.h index 4cc7c43c..964f3164 100644 --- a/bin/ad/ad.h +++ b/bin/ad/ad.h @@ -56,7 +56,10 @@ extern int ad_cp(int argc, char **argv); /* ad_util.c */ extern int openvol(const char *path, afpvol_t *vol); extern void closevol(afpvol_t *vol); -extern cnid_t cnid_for_path(const struct volinfo *vi, const struct vol *vol, const char *path); +extern cnid_t cnid_for_path(const struct volinfo *vi, + const struct vol *vol, + const char *path, + cnid_t *did); extern char *utompath(const struct volinfo *volinfo, const char *upath); struct FTWELEM { diff --git a/bin/ad/ad_cp.c b/bin/ad/ad_cp.c index 3593602a..dfb2b736 100644 --- a/bin/ad/ad_cp.c +++ b/bin/ad/ad_cp.c @@ -319,10 +319,8 @@ static int copy(const char *path, dir = path; else dir++; - if (check_netatalk_dirs(dir) != NULL) { - SLOG("Skipping Netatalk dir %s", path); + if (check_netatalk_dirs(dir) != NULL) return FTW_SKIP_SUBTREE; - } /* * If we are in case (2) above, we need to append the @@ -428,31 +426,27 @@ static int copy(const char *path, /* Create ad dir and copy ".Parent" */ if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) { + /* Create ".AppleDouble" dir */ mode_t omask = umask(0); bstring addir = bfromcstr(to.p_path); bcatcstr(addir, "/.AppleDouble"); mkdir(cfrombstr(addir), 02777); + bdestroy(addir); if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) { /* copy ".Parent" file */ - bcatcstr(addir, "/.Parent"); - bstring sdir = bfromcstr(path); - bcatcstr(sdir, "/.AppleDouble/.Parent"); - if (copy_file(-1, cfrombstr(sdir), cfrombstr(addir), 0666) != 0) { - SLOG("Error copying %s -> %s", cfrombstr(sdir), cfrombstr(addir)); + SLOG("Copying adouble for %s -> %s", path, to.p_path); + if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) { + SLOG("Error copying adouble for %s -> %s", path, to.p_path); badcp = rval = 1; break; } - bdestroy(sdir); } - bdestroy(addir); /* Get CNID of Parent and add new childir to CNID database */ ppdid = pdid; - pdid = did; - did = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path); - SLOG("got CNID: %u for path: %s", ntohl(did), to.p_path); + did = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path, &pdid); struct adouble ad; struct stat st; @@ -464,8 +458,13 @@ static int copy(const char *path, if (ad_open_metadata(to.p_path, ADFLAGS_DIR, O_RDWR | O_CREAT, &ad) != 0) { ERROR("Error opening adouble for: %s", to.p_path); } + SLOG("Setting CNID %u for %s", ntohl(did), to.p_path); ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp); - ad_setname(&ad, utompath(&dvolume.volinfo, path + ftw->base)); + ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path))); + ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START); ad_flush(&ad); ad_close_metadata(&ad); @@ -498,17 +497,19 @@ static int copy(const char *path, if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) { - SLOG("ad for file: %s", to.p_path); mode_t omask = umask(0); if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) { /* copy ad-file */ - if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) + if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) { + SLOG("Error copying adouble for %s -> %s", path, to.p_path); badcp = rval = 1; + break; + } } /* Get CNID of Parent and add new childir to CNID database */ - cnid_t cnid = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path); - SLOG("got CNID: %u for path: %s", ntohl(cnid), to.p_path); + pdid = did; + cnid_t cnid = cnid_for_path(&dvolume.volinfo, &dvolume.volume, to.p_path, &did); struct adouble ad; struct stat st; @@ -520,8 +521,13 @@ static int copy(const char *path, if (ad_open_metadata(to.p_path, 0, O_RDWR | O_CREAT, &ad) != 0) { ERROR("Error opening adouble for: %s", to.p_path); } + SLOG("setid: DID: %u, CNID: %u, %s", ntohl(did), ntohl(cnid), to.p_path); ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp); - ad_setname(&ad, utompath(&dvolume.volinfo, path + ftw->base)); + ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path))); + ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime); + ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START); ad_flush(&ad); ad_close_metadata(&ad); umask(omask); diff --git a/bin/ad/ad_util.c b/bin/ad/ad_util.c index 8366546a..ac05fc0a 100644 --- a/bin/ad/ad_util.c +++ b/bin/ad/ad_util.c @@ -204,11 +204,9 @@ static bstring rel_path_in_vol(const char *path, const char *volpath) EC_ZERO(bcatcstr(fpath, "/")); EC_ZERO(bcatcstr(fpath, path)); BSTRING_STRIP_SLASH(fpath); - SLOG("Built path: %s", cfrombstr(fpath)); } else { EC_NULL(fpath = bfromcstr(path)); BSTRING_STRIP_SLASH(fpath); - SLOG("Built path: %s", cfrombstr(fpath)); } /* @@ -218,7 +216,6 @@ static bstring rel_path_in_vol(const char *path, const char *volpath) * we want: "dir/bla" */ EC_ZERO(bdelete(fpath, 0, strlen(volpath))); - SLOG("rel path: %s", cfrombstr(fpath)); return fpath; EC_CLEANUP: @@ -241,44 +238,47 @@ EC_CLEANUP: * 2) ...until we have the CNID for * a) "/afp_volume/topdir/dir" * b) "/afp_volume/dir" (no recursion required) + * + * @param vi (r) pointer to volinfo struct + * @param vol (r) pointer to vol struct + * @param path (r) path, see above + * @param did (rw) parent CNID of returned CNID + * + * @returns CNID of path */ cnid_t cnid_for_path(const struct volinfo *vi, const struct vol *vol, - const char *path) + const char *path, + cnid_t *did) { 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); + cnid = *did = htonl(2); + EC_NULL(rpath = rel_path_in_vol(path, vi->v_path)); 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; + *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, + *did, cfrombstr(l->entry[i]), blength(l->entry[i]), 0); EC_ZERO(bcatcstr(statpath, "/")); + } EC_CLEANUP: diff --git a/libatalk/vfs/unix.c b/libatalk/vfs/unix.c index 4812e964..e1eb6a1a 100644 --- a/libatalk/vfs/unix.c +++ b/libatalk/vfs/unix.c @@ -1,9 +1,6 @@ /* - * $Id: unix.c,v 1.11 2010-04-18 16:14:51 hat001 Exp $ - * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. - * */ #ifdef HAVE_CONFIG_H @@ -214,7 +211,7 @@ int copy_file(int dirfd, const char *src, const char *dst, mode_t mode) return -1; } - if ((dfd = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) { + if ((dfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { LOG(log_error, logtype_afpd, "copy_file('%s'/'%s'): open '%s' error: %s", src, dst, dst, strerror(errno)); ret = -1; diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 959a9a55..8213dbe2 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -21,6 +21,9 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#include +#include +#include #include #include #include @@ -329,36 +332,53 @@ static int RF_copyfile_adouble(VFS_FUNC_ARGS_COPYFILE) { EC_INIT; bstring s = NULL, d = NULL; - const char *name; - char *dir = NULL; - - /* get basename */ - EC_NULL(name = strrchr(src, '/')); - name++; - - /* build src path to AppleDouble file*/ - EC_NULL(dir = dirname(strdup(src))); - EC_NULL(s = bfromcstr(dir)); - EC_ZERO(bcatcstr(s, "/.AppleDouble/")); - EC_ZERO(bcatcstr(s, name)); - free(dir); - dir = NULL; - - /* build dst path to AppleDouble file*/ - EC_NULL(dir = dirname(strdup(dst))); - EC_NULL(d = bfromcstr(dir)); - EC_ZERO(bcatcstr(d, "/.AppleDouble/")); - EC_ZERO(bcatcstr(d, name)); - - free(dir); - dir = NULL; + char *dup1 = NULL; + char *dup2 = NULL; + char *dup3 = NULL; + const char *name = NULL; + const char *dir = NULL; + + struct stat st; + EC_ZERO(stat(dst, &st)); + + if (S_ISDIR(st.st_mode)) { + /* build src path to AppleDouble file*/ + EC_NULL(s = bfromcstr(src)); + EC_ZERO(bcatcstr(s, "/.AppleDouble/.Parent")); + + /* build dst path to AppleDouble file*/ + EC_NULL(d = bfromcstr(dst)); + EC_ZERO(bcatcstr(d, "/.AppleDouble/.Parent")); + } else { + /* get basename */ + EC_NULL(dup1 = strdup(dst)); + EC_NULL(name = basename(strdup(dup1))); + + /* build src path to AppleDouble file*/ + EC_NULL(dup2 = strdup(src)); + EC_NULL(dir = dirname(dup2)); + EC_NULL(s = bfromcstr(dir)); + + /* build dst path to AppleDouble file*/ + EC_NULL(dup3 = strdup(dst)); + EC_NULL(dir = dirname(dup3)); + EC_NULL(d = bfromcstr(dir)); + + EC_ZERO(bcatcstr(s, "/.AppleDouble/")); + EC_ZERO(bcatcstr(d, "/.AppleDouble/")); + EC_ZERO(bcatcstr(s, name)); + EC_ZERO(bcatcstr(d, name)); + } EC_ZERO(copy_file(sfd, cfrombstr(s), cfrombstr(d), 0666)); EC_CLEANUP: bdestroy(s); bdestroy(d); - if (dir) free(dir); + if (dup1) free(dup1); + if (dup2) free(dup2); + if (dup3) free(dup3); + EC_EXIT; } -- 2.39.2