commit - 083d96a2219dc723817ef1d64dbf2bd02ae83207
commit + 1111d9d28b2cad09f41a28e1d0724e68424f9cf7
blob - 8a935f2d25dfd8da5274a7b59ee6aea634dd559a
blob + eba20f4f993a8317ace186a8570f5307a313ac6a
--- rene.c
+++ rene.c
#define O_REPLACELAST (1<<4)
#define O_VERBOSE (1<<5)
+#define MAX_FILENAME 4096
+
uint8_t opts;
+char new[MAX_FILENAME], *newe = new + MAX_FILENAME-1;
void
warn(const char *fmt, ...)
exit(eval);
}
+void
+errx(int eval, const char *fmt, ...)
+{
+ fputs("rene: ", stderr);
+ if (fmt != NULL) {
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ }
+ fputc('\n', stderr);
+ exit(eval);
+}
+
int
-strrep(char *from, char *to, char *s, char **new)
+ren(char *from, char *to, char *f)
{
- char *p = strrchr(s, '/');
+ int y = !(opts & O_NOOVERRIDE);
+
+ char *p = strrchr(f, '/');
if (p) {
if (*++p == '\0')
- return 0;
+ return 1;
} else
- p = s;
- p = strstr(p, from);
- if (!p)
- return 0;
+ p = f;
+ if (!(p = strstr(p, from)))
+ return 1;
int fromlen = strlen(from);
- int count = 1;
- if (opts & O_REPLACELAST || opts & O_REPLACEALL) {
- char *temp = p;
- while (temp) {
- temp = strstr(temp+fromlen, from);
- count = (opts & O_REPLACEALL && temp) ? count + 1 :
- count;
- p = (opts & O_REPLACELAST && temp) ? temp : p;
- }
- }
+ if (opts & O_REPLACELAST)
+ for(char *x; (x = strstr(p+fromlen, from)); p = x)
+ ;
- if (!(*new =
- malloc(strlen(s) + strlen(to)*count - fromlen*count + 1))) {
- warn("malloc");
- return 0;
- }
-
- char *newp = *new;
+ char *fp = f;
+ char *newp = new;
char *top = to;
- while (p) {
- for (; s != p; *newp++ = *s++)
- ;
- for (; *top != '\0'; *newp++ = *top++)
- ;
- s += fromlen;
- p = opts & O_REPLACEALL ? strstr(s, from) : strchr(s, '\0');
- p = p ? p : strchr(s, '\0');
- for (; s != p; *newp++ = *s++)
- ;
- p = (*p == '\0') ? NULL : p;
- top = to;
+ for (;;) {
+ for (; fp != p; *newp++ = *fp++)
+ if (newp == newe)
+toolong:
+ errx(1, "%s: final file name is too long", f);
+ if (!*fp)
+ break;
+ for (top = to; *top != '\0'; *newp++ = *top++)
+ if (newp == newe)
+ goto toolong;
+ fp += fromlen;
+ if (!(opts & O_REPLACEALL) || !(p = strstr(fp, from)))
+ p = strchr(fp, '\0');
}
*newp = '\0';
- return 1;
-}
-int
-ask(char *from, char *to)
-{
- fprintf(stderr, "replace %s with %s? ", from, to);
- return getchar() == 'y';
-}
-
-void
-ren(char *from, char *to, char *f)
-{
- int yes = 1;
- char *new = NULL;
- if (!strrep(from, to, f, &new))
- return;
- if ((opts & O_NOOVERRIDE || opts & O_INTERACTIVE) &&
- access(new, F_OK) == 0)
- yes = opts & O_NOOVERRIDE ? 0 : ask(f, new);
- if (yes && !(opts & O_NOACT) && !(yes += rename(f, new)))
+ if (opts & O_INTERACTIVE && access(new, F_OK) == 0) {
+ fprintf(stderr, "replace %s with %s? ", from, to);
+ y = getchar() == 'y';
+ }
+ if (y && !(opts & O_NOACT) && !(y += rename(f, new))) {
warn("rename");
- if (opts & O_VERBOSE && yes)
+ return 0;
+ }
+ if (opts & O_VERBOSE && y)
printf("%s -> %s\n", f, new);
+ return 1;
}
void
int
main(int argc, char *argv[])
{
- char *from, *to;
-
+ int c, ret = 0;
#ifdef __OpenBSD__
if (pledge("stdio cpath rpath", NULL) == -1)
err(1, "pledge");
#endif
-
- int c;
while ((c = getopt(argc, argv, "ailnov")) != -1) {
switch (c) {
case 'a':
argc -= optind;
argv += optind;
- if (argc < 3)
+ if (argc < 3 || !argv[0] || !argv[1] || !argv[0][0])
usage();
- from = argv[0];
- to = argv[1];
for (int i = 2; i < argc; i++)
- ren(from, to, argv[i]);
- return 0;
+ if (!ren(argv[0], argv[1], argv[i]))
+ ret = 1;
+ return ret;
}