aboutsummaryrefslogtreecommitdiff
path: root/coreutils/condmv.c
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
committerBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
commit02013228914a1d17e8df15d4e2b7950469395a5c (patch)
tree48d2fbe2f5a5adb60cbeabc26fadaec8e0fa82ed /coreutils/condmv.c
parent9b3dbb454e8f8a463d5fe4541ee2001585527bc6 (diff)
ripe-atlas-fw: imported version 45204520
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'coreutils/condmv.c')
-rw-r--r--coreutils/condmv.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/coreutils/condmv.c b/coreutils/condmv.c
new file mode 100644
index 0000000..0139779
--- /dev/null
+++ b/coreutils/condmv.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * condmv.c -- move a file only if the destination doesn't exist
+ */
+
+#include "libbb.h"
+
+#define SAFE_PREFIX_FROM ATLAS_DATA_NEW
+#define SAFE_PREFIX_TO ATLAS_DATA_OUT
+
+#define A_FLAG (1 << 0)
+#define F_FLAG (1 << 1)
+
+int condmv_main(int argc, char *argv[])
+{
+ char *opt_add, *from, *to;
+ uint32_t opt;
+ struct stat sb;
+ FILE *file;
+ time_t mytime;
+
+ opt_add= NULL;
+ opt_complementary= NULL; /* For when we are called by crond */
+ opt= getopt32(argv, "!A:f", &opt_add);
+
+ if (opt == (uint32_t)-1)
+ {
+ fprintf(stderr, "condmv: bad options\n");
+ return 1;
+ }
+
+ if (argc != optind + 2)
+ {
+ fprintf(stderr, "condmv: two arguments expected\n");
+ return 1;
+ }
+
+ from= argv[optind];
+ to= argv[optind+1];
+
+ if (!validate_filename(from, SAFE_PREFIX_FROM))
+ {
+ fprintf(stderr, "insecure from file '%s'\n", from);
+ return 1;
+ }
+ if (!validate_filename(to, SAFE_PREFIX_TO) &&
+ !validate_filename(to, SAFE_PREFIX_FROM))
+ {
+ fprintf(stderr, "insecure to file '%s'\n", to);
+ return 1;
+ }
+
+ if (stat(to, &sb) == 0 && !(opt & F_FLAG))
+ {
+ /* Destination exists */
+ fprintf(stderr, "condmv: not moving, destination '%s' exists\n",
+ to);
+ return 1;
+ }
+
+ if (opt_add)
+ {
+ mytime = time(NULL);
+ /* We have to add something to the existing file before moving
+ * to.
+ */
+ file= fopen(from, "a");
+ if (file == NULL)
+ {
+ fprintf(stderr,
+ "condmv: unable to append to '%s': %s\n",
+ from, strerror(errno));
+ return 1;
+ }
+ if (fprintf(file, "%s %lu %s\n", opt_add, mytime, from) < 0)
+ {
+ fprintf(stderr,
+ "condmv: unable to append to '%s': %s\n",
+ from, strerror(errno));
+ fclose(file);
+ return 1;
+ }
+ if (fclose(file) != 0)
+ {
+ fprintf(stderr,
+ "condmv: unable to close '%s': %s\n",
+ from, strerror(errno));
+ return 1;
+ }
+ }
+ if (rename(from, to) != 0)
+ {
+ fprintf(stderr, "condmv: unable to rename '%s' to '%s': %s\n",
+ from, to, strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}