aboutsummaryrefslogtreecommitdiff
path: root/name.c
blob: fce3fbad8e2b0d0ded358e6175ddb73c92cb9c02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <sys/wait.h>

#define MAXFILES 100
#define MAXFILE 255
#define MAXLINE MAXFILE+1

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;

	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;
	}

	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 new file names. */
	for(j = 0; j < MAXFILES && fgets(tmp, MAXLINE, stdin); j++){
		tmp[strcspn(tmp, "\n")] = 0;
		strcpy(tos[j], tmp);
	}

	/* Read original file names. */
	for(i = 0; i < MAXFILES && fgets(tmp, MAXLINE, fp); i++){
		tmp[strcspn(tmp, "\n")] = 0;
		strcpy(froms[i], tmp);
	}

	if(i != j){
		fprintf(stderr, "%s: too %s lines\n",
			name, j > i ? "many" : "few");
		return 1;
	}

	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;

	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");
}