/*
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)
/* 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 {
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
/* 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;
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);
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;
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);
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));
}
/*
* we want: "dir/bla"
*/
EC_ZERO(bdelete(fpath, 0, strlen(volpath)));
- SLOG("rel path: %s", cfrombstr(fpath));
return fpath;
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:
/*
- * $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
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;
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
{
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;
}