146 lines
2.5 KiB
C
146 lines
2.5 KiB
C
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
|
|
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);
|
|
}
|