summaryrefslogtreecommitdiffstats
path: root/exchange.c
diff options
context:
space:
mode:
authorTobias Wiese <tobias@tobiaswiese.com>2020-08-07 17:40:14 +0200
committerTobias Wiese <tobias@tobiaswiese.com>2020-08-07 17:40:14 +0200
commite1cfd1c7d296cd691d2194187575f3302f66ef92 (patch)
tree7f871b9ad5e64f4067b5cd5662e2194f18924324 /exchange.c
parentfc513db3e8bca6be022e95a75723143cb6eca36e (diff)
reorganize directory structure.
move the content of the src/ directory up into the root. There is no real need for putting those files inside an extra directory. Signed-off-by: Tobias Wiese <tobias@tobiaswiese.com>
Diffstat (limited to 'exchange.c')
-rw-r--r--exchange.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/exchange.c b/exchange.c
new file mode 100644
index 0000000..c818606
--- /dev/null
+++ b/exchange.c
@@ -0,0 +1,105 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#ifndef SMALL
+#include <getopt.h>
+#include <unistd.h>
+#endif
+
+#ifndef DEFAULT_PROGRAM_NAME
+# define DEFAULT_PROGRAM_NAME "exchange"
+#endif
+
+#ifndef VERSION
+# define VERSION ""
+#endif
+
+#ifndef SMALL
+static char *program_name = DEFAULT_PROGRAM_NAME;
+static struct option const long_options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0 },
+};
+
+void usage(FILE *fd) {
+ fprintf(fd, "\
+Usage: %s [OPTION]... <PATH 1> <PATH 2>\n\
+Exchange PATH 1 and PATH 2.\n",
+ program_name);
+ fputs("\n", fd);
+ fputs("\
+Available Options:\n\
+ -h, --help display this help and exit\n\
+ -v, --version output version information and exit\n", fd);
+}
+
+void version() {
+ printf("%s %s\n", program_name, VERSION);
+#ifdef BUILD_DATE
+ printf("Build on %s.\n", BUILD_DATE);
+#endif
+}
+#endif // !SMALL
+
+int main(int argc, char *argv[]) {
+ char *path1, *path2;
+#ifndef SMALL
+ if (argc > 0)
+ program_name = argv[0];
+
+ int c;
+ while ((c = getopt_long(argc, argv, "hvt", long_options, NULL))
+ != -1)
+ {
+ switch (c) {
+ case 't':
+ break;
+ case 'h': // help
+ usage(stdout);
+ return EXIT_SUCCESS;
+ case 'v': // version
+ version();
+ return EXIT_SUCCESS;
+ default:
+ usage(stderr);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (argc - optind != 2) {
+ fprintf(stderr, "%s: invalid number of arguments. Expected 2.\n", program_name);
+ usage(stderr);
+ return EXIT_FAILURE;
+ }
+
+#else
+ // We currently don't accept any options
+ // when compiling with SMALL
+ // Define optind manually, because we don't use optparse.
+ const int optind = 1;
+#endif // !SMALL
+
+ if (argc - optind != 2) {
+#ifndef SMALL
+ fprintf(stderr, "%s: invalid number of arguments. Expected 2.\n", program_name);
+ usage(stderr);
+#endif
+ return EXIT_FAILURE;
+ }
+ path1 = argv[optind];
+ path2 = argv[optind + 1];
+
+ // Do the magic
+ if (renameat2(AT_FDCWD, path1, AT_FDCWD, path2, RENAME_EXCHANGE) != 0) {
+ int errsv = errno;
+#ifndef SMALL
+ perror(program_name);
+#endif
+ return -errsv;
+ }
+ return EXIT_SUCCESS;
+}