diff --git a/GNUmakefile.in b/GNUmakefile.in index 96b367e6..a99b03b9 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -1,6 +1,6 @@ OBJ=crawler.o rdup.o gfunc.o getdelim.o signal.o usage.o sha1.o regexp.o abspath.o link.o reverse.o OBJ_TR=rdup-tr.o signal.o getdelim.o usage-tr.o child.o entry.o link.o -OBJ_UP=rdup-up.o entry.o usage-up.o signal.o link.o getdelim.o abspath.o rm.o fs-up.o strippath.o +OBJ_UP=rdup-up.o entry.o usage-up.o signal.o link.o getdelim.o abspath.o rm.o fs-up.o strippath.o mkpath.o HDR=rdup.h rdup-tr.h rdup-up.h io.h CMD=rdup rdup-tr rdup-up # installs to /usr/lib/rdup diff --git a/mkpath.c b/mkpath.c new file mode 100644 index 00000000..ec530f53 --- /dev/null +++ b/mkpath.c @@ -0,0 +1,45 @@ +/* Function with behaviour like `mkdir -p' */ +/* From: http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/ + * with some tweaks + * libglib'i'fied by Miek Gieben + */ + +#include "rdup-up.h" + +int +mkpath(const char *s, mode_t mode) +{ + char *q, *r = NULL, *path = NULL, *up = NULL; + int rv; + + rv = -1; + if (strcmp(s, ".") == 0 || strcmp(s, "/") == 0) + return 0; + + if ((path = g_strdup(s)) == NULL) + return -1; + + if ((q = g_strdup(s)) == NULL) + return -1; + + if ((r = dirname(q)) == NULL) + goto out; + + if ((up = g_strdup(r)) == NULL) + return -1; + + if ((mkpath(up, mode) == -1) && (errno != EEXIST)) + goto out; + + if ((mkdir(path, mode) == -1) && (errno != EEXIST)) + rv = -1; + else + rv = 0; + +out: + if (up != NULL) + free(up); + free(q); + free(path); + return (rv); +} diff --git a/rdup-up.c b/rdup-up.c index f9bf8806..bbe2bf0c 100644 --- a/rdup-up.c +++ b/rdup-up.c @@ -13,7 +13,7 @@ gint opt_verbose = 0; /* be more verbose */ gint opt_output = O_RDUP; /* set these 2 so we can use parse_entry */ gint opt_input = I_RDUP; gboolean opt_dry = FALSE; /* don't touch the filesystem */ -gboolean opt_top = FALSE; /* create top dir is it does not exist */ +gboolean opt_top = FALSE; /* create top dir if it does not exist */ sig_atomic_t sig = 0; GSList *hlink = NULL; /* save hardlink for post processing */ /* signal.c */ @@ -175,15 +175,16 @@ main(int argc, char **argv) else path = abspath(argv[0]); - if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { - if (!opt_top) { + + if (opt_top) { + if (mkpath(path, 00777) == -1) { + msg("Failed to create directory `%s\': %s", path, strerror(errno)); + exit(EXIT_FAILURE); + } + } else { + if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { msg("No such directory: `%s\'", path); exit(EXIT_FAILURE); - } else { - if (mkdir(path, 00777) == -1) { - msg("Failed to create directory `%s\': %s", path, strerror(errno)); - exit(EXIT_FAILURE); - } } } diff --git a/rdup-up.h.in b/rdup-up.h.in index d735c8a2..ddf18172 100644 --- a/rdup-up.h.in +++ b/rdup-up.h.in @@ -86,4 +86,6 @@ gboolean mk_obj(FILE *in, char *p, struct r_entry *e, guint strip); /* strippath.c */ char * strippath(char *path, guint n); +/* mkpath.c */ +int mkpath(const char *path, mode_t mode); #endif /* _RDUP_UP_H */ diff --git a/sh/rdup-simple.sh b/sh/rdup-simple.sh index 24a907ae..0b054b5a 100755 --- a/sh/rdup-simple.sh +++ b/sh/rdup-simple.sh @@ -3,7 +3,7 @@ # updates a hardlinked backup # licensed under the GPL version 3 # Copyright Miek Gieben, 2007 - 2009 -# rewritten for rdup-up + rdup-tr +# rewritten for rdup-up and rdup-tr #{exec_prefix} XXX todo? echo2() { @@ -160,9 +160,9 @@ LIST=$etc/list.${HOSTNAME}.${dest//\//_} # create our command line if [[ -z $ssh ]]; then - pipe="rdup-tr$trans | rdup-up$OPT $BACKUPDIR/$NOW" + pipe="rdup-tr$trans | rdup-up$OPT -t $BACKUPDIR/$NOW" else - pipe="rdup-tr$trans | $ssh rdup-up$OPT $BACKUPDIR/$NOW" + pipe="rdup-tr$trans | $ssh rdup-up$OPT -t $BACKUPDIR/$NOW" fi cmd="rdup$E$x$l -N $STAMP $LIST $DIRS | $pipe"