#include #include #include #include #include #include #include #define MAXFILES 100 /* Maximum number of files. */ #define MAXFILE 255 /* Maximum file name length. */ #define MAXLINE MAXFILE+1 /* Extra room for newline. */ extern char *optarg; extern int optind; void escape(char *, char **); void waitstdin(void); int main(int argc, char *argv[]) { char file[30], *name, *froms[MAXFILES], *tmp, *tos[MAXFILES]; FILE *fp; int c, i, j, s, xflag; /* Allocate memory. */ for (i = 0; i < MAXFILES; i++) if (!(froms[i]=malloc(MAXFILE)) || !(tos[i]=malloc(MAXFILE))) err(1, "malloc"); if (!(tmp = malloc(MAXLINE*4))) err(1, "malloc"); sprintf(file, "/var/tmp/re.%d", getppid()); /* * The existence of the temporary file is only checked when there * is input to be read on standard in, as re(1) doesn't create * the file until it starts writing on standard out. */ if (waitstdin(), access(file, F_OK)) { fprintf(stderr, "%s: %s does not exist\n", argv[0], file); return 1; } /* Read command-line options. */ name = argv[0]; xflag = 0; while ((c = getopt(argc, argv, "x")) != -1) switch (c) { case 'x': xflag = 1; break; default: goto usage; } argc -= optind; argv += optind; if (argc > 0) { usage: fprintf(stderr, "usage: %s [-x]\n", name); return 1; } if (!(fp = fopen(file, "r"))) err(1, "fopen"); /* Read original file names. */ for (i = 0; fgets(tmp, MAXLINE, fp); i++) { tmp[strcspn(tmp, "\n")] = 0; strcpy(froms[i], tmp); } /* Read new file names. */ for (j = 0; fgets(tmp, MAXLINE, stdin); j++) { tmp[strcspn(tmp, "\n")] = 0; strcpy(tos[j], tmp); } if (i != j) { fprintf(stderr, "%s: too %s lines\n", name, j > i ? "many" : "few"); return 1; } /* * The corresponding mv invocations are printed on standard out. * If the -x flag is given, they are executed too. */ for (i = 0; i < j; i++) { escape(froms[i], &tmp); printf("mv '%s'", tmp); escape(tos[i], &tmp); printf(" '%s'\n", tmp); if (xflag) { if (!fork()) { execl("/bin/mv", "mv", froms[i], tos[i], NULL); err(1, "execl"); } if (wait(&s), s) { fprintf(stderr, "/bin/mv exited with %d\n", WEXITSTATUS(s)); return 1; } } } unlink(file); fclose(fp); } void escape(char *str, char **res) { int i, j, offset; for (i = j = 0; str[i]; i++) { if (str[i] == '\'') { strcat(*res, "'\\''"); j += 4; } else (*res)[j++] = str[i]; } (*res)[j] = 0; } void waitstdin() { fd_set readfds; FD_ZERO(&readfds); FD_SET(0, &readfds); if (select(1, &readfds, NULL, NULL, NULL) == -1) err(1, "select"); }