wc: Added wc
[mutos-utils.git] / mv.c
blob07a6a0dbe104061d38abe74ab59e148890e78942
1 /*
2 Copyright © 2013 Alastair Stuart
4 This program is open source software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
15 #include <errno.h>
16 #include <stdbool.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
21 #include <getopt.h>
22 #include <sys/stat.h>
24 #define VERSION "0.01"
26 void usage(char* program)
28 printf("Usage: %s [options] [source ...] [dest]\n", program);
29 printf("Moves files.\n"
30 "\n"
31 " --help Print this message.\n"
32 " --version Show version info.\n");
35 int main(int argc, char* argv[])
37 static struct option long_options[] = {
38 {"help", no_argument, NULL, 1},
39 {"version", no_argument, NULL, 2},
40 {NULL, 0, NULL, 0}
43 int c = 0;
44 while ((c = getopt_long(argc, argv, "",
45 long_options, NULL)) != -1)
47 switch (c)
49 case 1:
50 usage(argv[0]);
51 return 0;
52 case 2:
53 printf("mv (mutos) v"VERSION"\n");
54 return 0;
55 default:
56 fprintf(stderr,"Run '%s --help' for usage.\n",
57 argv[0]);
58 return 1;
62 if ((argc - optind) == 0) {
63 fprintf(stderr, "%s: Missing operands\n"
64 "Run '%s --help' for usage.\n",
65 argv[0], argv[0]);
66 return 1;
67 } else if ((argc - optind) == 1) {
69 fprintf(stderr, "%s: Missing destination operand\n"
70 "Run '%s --help' for usage.\n",
71 argv[0], argv[0]);
72 return 1;
75 bool errors = false;
77 char* dest_path = argv[argc - 1];
78 bool dest_dir = false;
80 struct stat dest;
81 int rc = stat(dest_path, &dest);
82 if (rc == 0) {
83 // if destination is a directory
84 if (dest.st_mode & S_IFDIR) {
85 dest_dir = true;
86 } else {
87 // if multiple source files are specified
88 // and dest isn't a directory
89 if ((argc - 1) > 2) {
90 fprintf(stderr, "%s: Destination is not a directory: %s\n",
91 argv[0], dest_path);
92 return 1;
97 for (int i = 1; i < argc - 1; i++)
99 if (dest_dir) {
100 // concat dest path and filename
101 size_t dest_len = strlen(dest_path) + 1 + strlen(argv[i]) + 1;
102 char* dest = calloc(1, dest_len);
103 if (!dest) {
104 fprintf(stderr, "%s: %s: %s",
105 argv[0], strerror(errno), argv[i]);
106 errors = true;
109 strncat(dest, dest_path, dest_len - strlen(dest) - 1);
110 strncat(dest, "/", dest_len - strlen(dest) - 1);
111 strncat(dest, argv[i], dest_len - strlen(dest) - 1);
112 dest[dest_len - 1] = '\0';
114 rc = rename(argv[i], dest);
115 if (rc != 0) {
116 fprintf(stderr, "%s: %s: %s\n",
117 argv[0], strerror(errno), argv[i]);
118 errors = true;
121 free(dest);
122 } else {
123 rc = rename(argv[i], dest_path);
124 if (rc != 0) {
125 fprintf(stderr, "%s: %s: %s\n",
126 argv[0], strerror(errno), argv[i]);
127 return 1;
132 if (errors) {
133 return 1;
136 return 0;