#include #include #include #include #include #include #include #include #include #include struct file { struct file *next; char *name; char *newname; }; int main(int argc, char *argv[]) { char *dirname = "."; if (argc > 1) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printf("Usage: %s [-h] [directory]\n", argv[0]); exit(0); } dirname = argv[1]; } DIR *dir = opendir(dirname); if (!dir) { perror("opendir"); exit(1); } int fd = dirfd(dir); fchdir(fd); struct file *begin = NULL; struct file **cur = &begin; while (1) { errno = 0; struct dirent *entry = readdir(dir); if (!entry) { if (errno != 0) { perror("readdir"); exit(1); } break; } if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; *cur = malloc(sizeof(struct file)); if (!*cur) { perror("malloc"); exit(1); } (*cur)->name = strdup(entry->d_name); (*cur)->newname = NULL; cur = &(*cur)->next; } if (!begin) { exit(0); } char template[] = "/tmp/vidir-c.XXXXXX"; if (!mkstemp(template)) { perror("mkstemp"); exit(1); } FILE *tempfile = fopen(template, "w+"); if (!tempfile) { perror("fopen"); exit(1); } int i = 1; for (struct file *file = begin; file; file = file->next) { fprintf(tempfile, "%d %s\n", i, file->name); i ++; } fflush(tempfile); pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(1); } if (pid == 0) { char *editor = getenv("EDITOR"); if (!editor) editor = "nano"; execlp(editor, editor, template, (char *) NULL); perror("execlp"); exit(1); } wait(NULL); fseek(tempfile, 0, SEEK_SET); ssize_t nread; char *line = NULL; size_t n; while ((nread = getline(&line, &n, tempfile)) != -1) { line[nread - 1] = '\0'; char *endptr = NULL; long num = strtol(line, &endptr, 10); if (line == endptr) continue; if (*endptr != ' ') continue; char *filename = endptr + 1; struct file *file = begin; int i = 1; while (file && i ++ < num) file = file->next; if (!file) continue; file->newname = strdup(filename); } for (struct file *file = begin; file; file = file->next) { if (!file->newname) { printf("Delete: %s\n", file->name); remove(file->name); continue; } if (strcmp(file->name, file->newname) != 0) { printf("Rename: %s to %s\n", file->name, file->newname); rename(file->name, file->newname); continue; } } unlink(template); exit(0); }