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 409611 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 void20 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 void34 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 void49 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 int63 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 } else72 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';102 }103 if (y && !nflag && !(y += rename(f, new))) {104 warn("rename");105 return 0;106 }107 if (vflag && y)108 printf("%s -> %s\n", f, new);109 return 1;110 }112 void113 usage(void)114 {115 fputs("usage: rene [-ailnov] from to file ...\n", stderr);116 exit(EXIT_FAILURE);117 }119 int120 main(int argc, char *argv[])121 {122 int c, ret = 0;123 #ifdef __OpenBSD__124 if (pledge("stdio cpath rpath", NULL) == -1)125 err(1, "pledge");126 #endif127 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();149 }150 }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;160 }