Blame


1 66390331 2022-09-30 src #include <errno.h>
2 b79428b4 2022-07-13 src #include <stdarg.h>
3 c1ec7947 2022-10-20 src #include <stdint.h>
4 b79428b4 2022-07-13 src #include <stdio.h>
5 b79428b4 2022-07-13 src #include <stdlib.h>
6 b79428b4 2022-07-13 src #include <string.h>
7 b79428b4 2022-07-13 src #include <unistd.h>
8 b79428b4 2022-07-13 src
9 66390331 2022-09-30 src #define O_INTERACTIVE 1
10 66390331 2022-09-30 src #define O_NOACT (1<<1)
11 66390331 2022-09-30 src #define O_NOOVERRIDE (1<<2)
12 66390331 2022-09-30 src #define O_REPLACEALL (1<<3)
13 66390331 2022-09-30 src #define O_REPLACELAST (1<<4)
14 66390331 2022-09-30 src #define O_VERBOSE (1<<5)
15 b79428b4 2022-07-13 src
16 1111d9d2 2022-10-06 src #define MAX_FILENAME 4096
17 1111d9d2 2022-10-06 src
18 66390331 2022-09-30 src uint8_t opts;
19 1111d9d2 2022-10-06 src char new[MAX_FILENAME], *newe = new + MAX_FILENAME-1;
20 b79428b4 2022-07-13 src
21 b79428b4 2022-07-13 src void
22 66390331 2022-09-30 src warn(const char *fmt, ...)
23 b79428b4 2022-07-13 src {
24 66390331 2022-09-30 src char *w = strerror(errno);
25 66390331 2022-09-30 src fputs("rene: ", stderr);
26 b79428b4 2022-07-13 src if (fmt != NULL) {
27 b79428b4 2022-07-13 src va_list argp;
28 b79428b4 2022-07-13 src va_start(argp, fmt);
29 b79428b4 2022-07-13 src vfprintf(stderr, fmt, argp);
30 b79428b4 2022-07-13 src va_end(argp);
31 b79428b4 2022-07-13 src }
32 66390331 2022-09-30 src fprintf(stderr, ": %s\n", w);
33 b79428b4 2022-07-13 src }
34 b79428b4 2022-07-13 src
35 1e12e95d 2022-09-30 src void
36 1e12e95d 2022-09-30 src err(int eval, const char *fmt, ...)
37 1e12e95d 2022-09-30 src {
38 1e12e95d 2022-09-30 src char *w = strerror(errno);
39 1e12e95d 2022-09-30 src fputs("rene: ", stderr);
40 1e12e95d 2022-09-30 src if (fmt != NULL) {
41 1e12e95d 2022-09-30 src va_list argp;
42 1e12e95d 2022-09-30 src va_start(argp, fmt);
43 1e12e95d 2022-09-30 src vfprintf(stderr, fmt, argp);
44 1e12e95d 2022-09-30 src va_end(argp);
45 1e12e95d 2022-09-30 src }
46 1e12e95d 2022-09-30 src fprintf(stderr, ": %s\n", w);
47 1e12e95d 2022-09-30 src exit(eval);
48 1e12e95d 2022-09-30 src }
49 1e12e95d 2022-09-30 src
50 1111d9d2 2022-10-06 src void
51 1111d9d2 2022-10-06 src errx(int eval, const char *fmt, ...)
52 1111d9d2 2022-10-06 src {
53 1111d9d2 2022-10-06 src fputs("rene: ", stderr);
54 1111d9d2 2022-10-06 src if (fmt != NULL) {
55 1111d9d2 2022-10-06 src va_list argp;
56 1111d9d2 2022-10-06 src va_start(argp, fmt);
57 1111d9d2 2022-10-06 src vfprintf(stderr, fmt, argp);
58 1111d9d2 2022-10-06 src va_end(argp);
59 1111d9d2 2022-10-06 src }
60 1111d9d2 2022-10-06 src fputc('\n', stderr);
61 1111d9d2 2022-10-06 src exit(eval);
62 1111d9d2 2022-10-06 src }
63 1111d9d2 2022-10-06 src
64 b79428b4 2022-07-13 src int
65 1111d9d2 2022-10-06 src ren(char *from, char *to, char *f)
66 b79428b4 2022-07-13 src {
67 1111d9d2 2022-10-06 src int y = !(opts & O_NOOVERRIDE);
68 1111d9d2 2022-10-06 src
69 1111d9d2 2022-10-06 src char *p = strrchr(f, '/');
70 b79428b4 2022-07-13 src if (p) {
71 b79428b4 2022-07-13 src if (*++p == '\0')
72 1111d9d2 2022-10-06 src return 1;
73 b79428b4 2022-07-13 src } else
74 1111d9d2 2022-10-06 src p = f;
75 1111d9d2 2022-10-06 src if (!(p = strstr(p, from)))
76 1111d9d2 2022-10-06 src return 1;
77 b79428b4 2022-07-13 src int fromlen = strlen(from);
78 1111d9d2 2022-10-06 src if (opts & O_REPLACELAST)
79 1111d9d2 2022-10-06 src for(char *x; (x = strstr(p+fromlen, from)); p = x)
80 1111d9d2 2022-10-06 src ;
81 b79428b4 2022-07-13 src
82 1111d9d2 2022-10-06 src char *fp = f;
83 1111d9d2 2022-10-06 src char *newp = new;
84 b79428b4 2022-07-13 src char *top = to;
85 1111d9d2 2022-10-06 src for (;;) {
86 1111d9d2 2022-10-06 src for (; fp != p; *newp++ = *fp++)
87 1111d9d2 2022-10-06 src if (newp == newe)
88 1111d9d2 2022-10-06 src toolong:
89 1111d9d2 2022-10-06 src errx(1, "%s: final file name is too long", f);
90 1111d9d2 2022-10-06 src if (!*fp)
91 1111d9d2 2022-10-06 src break;
92 1111d9d2 2022-10-06 src for (top = to; *top != '\0'; *newp++ = *top++)
93 1111d9d2 2022-10-06 src if (newp == newe)
94 1111d9d2 2022-10-06 src goto toolong;
95 1111d9d2 2022-10-06 src fp += fromlen;
96 1111d9d2 2022-10-06 src if (!(opts & O_REPLACEALL) || !(p = strstr(fp, from)))
97 1111d9d2 2022-10-06 src p = strchr(fp, '\0');
98 b79428b4 2022-07-13 src }
99 b79428b4 2022-07-13 src *newp = '\0';
100 b79428b4 2022-07-13 src
101 1111d9d2 2022-10-06 src if (opts & O_INTERACTIVE && access(new, F_OK) == 0) {
102 1111d9d2 2022-10-06 src fprintf(stderr, "replace %s with %s? ", from, to);
103 1111d9d2 2022-10-06 src y = getchar() == 'y';
104 1111d9d2 2022-10-06 src }
105 1111d9d2 2022-10-06 src if (y && !(opts & O_NOACT) && !(y += rename(f, new))) {
106 66390331 2022-09-30 src warn("rename");
107 1111d9d2 2022-10-06 src return 0;
108 1111d9d2 2022-10-06 src }
109 1111d9d2 2022-10-06 src if (opts & O_VERBOSE && y)
110 b79428b4 2022-07-13 src printf("%s -> %s\n", f, new);
111 1111d9d2 2022-10-06 src return 1;
112 b79428b4 2022-07-13 src }
113 b79428b4 2022-07-13 src
114 66390331 2022-09-30 src void
115 66390331 2022-09-30 src usage(void)
116 66390331 2022-09-30 src {
117 66390331 2022-09-30 src fputs("usage: rene [-ailnov] from to file ...\n", stderr);
118 66390331 2022-09-30 src exit(EXIT_FAILURE);
119 66390331 2022-09-30 src }
120 66390331 2022-09-30 src
121 b79428b4 2022-07-13 src int
122 b79428b4 2022-07-13 src main(int argc, char *argv[])
123 b79428b4 2022-07-13 src {
124 1111d9d2 2022-10-06 src int c, ret = 0;
125 1e12e95d 2022-09-30 src #ifdef __OpenBSD__
126 1e12e95d 2022-09-30 src if (pledge("stdio cpath rpath", NULL) == -1)
127 1e12e95d 2022-09-30 src err(1, "pledge");
128 1e12e95d 2022-09-30 src #endif
129 b79428b4 2022-07-13 src while ((c = getopt(argc, argv, "ailnov")) != -1) {
130 b79428b4 2022-07-13 src switch (c) {
131 b79428b4 2022-07-13 src case 'a':
132 66390331 2022-09-30 src opts |= O_REPLACEALL;
133 b79428b4 2022-07-13 src break;
134 b79428b4 2022-07-13 src case 'i':
135 66390331 2022-09-30 src opts |= O_INTERACTIVE;
136 b79428b4 2022-07-13 src break;
137 b79428b4 2022-07-13 src case 'l':
138 66390331 2022-09-30 src opts |= O_REPLACELAST;
139 b79428b4 2022-07-13 src break;
140 b79428b4 2022-07-13 src case 'n':
141 66390331 2022-09-30 src opts |= O_NOACT;
142 b79428b4 2022-07-13 src break;
143 b79428b4 2022-07-13 src case 'o':
144 66390331 2022-09-30 src opts |= O_NOOVERRIDE;
145 b79428b4 2022-07-13 src break;
146 b79428b4 2022-07-13 src case 'v':
147 66390331 2022-09-30 src opts |= O_VERBOSE;
148 b79428b4 2022-07-13 src break;
149 b79428b4 2022-07-13 src default:
150 b79428b4 2022-07-13 src usage();
151 b79428b4 2022-07-13 src }
152 b79428b4 2022-07-13 src }
153 b79428b4 2022-07-13 src argc -= optind;
154 b79428b4 2022-07-13 src argv += optind;
155 b79428b4 2022-07-13 src
156 1111d9d2 2022-10-06 src if (argc < 3 || !argv[0] || !argv[1] || !argv[0][0])
157 b79428b4 2022-07-13 src usage();
158 b79428b4 2022-07-13 src for (int i = 2; i < argc; i++)
159 1111d9d2 2022-10-06 src if (!ren(argv[0], argv[1], argv[i]))
160 1111d9d2 2022-10-06 src ret = 1;
161 1111d9d2 2022-10-06 src return ret;
162 b79428b4 2022-07-13 src }