Blob


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