Blame


1 5993a8f2 2003-11-23 devnull #include <u.h>
2 5993a8f2 2003-11-23 devnull #include <libc.h>
3 5993a8f2 2003-11-23 devnull #include <bio.h>
4 5993a8f2 2003-11-23 devnull #include "diff.h"
5 5993a8f2 2003-11-23 devnull
6 5993a8f2 2003-11-23 devnull #define DIRECTORY(s) ((s)->qid.type&QTDIR)
7 5993a8f2 2003-11-23 devnull #define REGULAR_FILE(s) ((s)->type == 'M' && !DIRECTORY(s))
8 5993a8f2 2003-11-23 devnull
9 5993a8f2 2003-11-23 devnull Biobuf stdout;
10 5993a8f2 2003-11-23 devnull
11 a2d66357 2005-01-29 devnull static char *tmp[] = {"/tmp/diff1XXXXXXXXXXX", "/tmp/diff2XXXXXXXXXXX"};
12 5993a8f2 2003-11-23 devnull static int whichtmp;
13 5993a8f2 2003-11-23 devnull static char *progname;
14 65da8598 2005-01-29 devnull static char usage[] = "diff [ -acefmnbwr ] file1 ... file2\n";
15 5993a8f2 2003-11-23 devnull
16 5993a8f2 2003-11-23 devnull static void
17 5993a8f2 2003-11-23 devnull rmtmpfiles(void)
18 5993a8f2 2003-11-23 devnull {
19 5993a8f2 2003-11-23 devnull while (whichtmp > 0) {
20 5993a8f2 2003-11-23 devnull whichtmp--;
21 5993a8f2 2003-11-23 devnull remove(tmp[whichtmp]);
22 5993a8f2 2003-11-23 devnull }
23 5993a8f2 2003-11-23 devnull }
24 5993a8f2 2003-11-23 devnull
25 fa325e9b 2020-01-10 cross void
26 5993a8f2 2003-11-23 devnull done(int status)
27 5993a8f2 2003-11-23 devnull {
28 5993a8f2 2003-11-23 devnull rmtmpfiles();
29 5993a8f2 2003-11-23 devnull switch(status)
30 5993a8f2 2003-11-23 devnull {
31 5993a8f2 2003-11-23 devnull case 0:
32 5993a8f2 2003-11-23 devnull exits("");
33 5993a8f2 2003-11-23 devnull case 1:
34 5993a8f2 2003-11-23 devnull exits("some");
35 5993a8f2 2003-11-23 devnull default:
36 5993a8f2 2003-11-23 devnull exits("error");
37 5993a8f2 2003-11-23 devnull }
38 5993a8f2 2003-11-23 devnull /*NOTREACHED*/
39 5993a8f2 2003-11-23 devnull }
40 5993a8f2 2003-11-23 devnull
41 5993a8f2 2003-11-23 devnull void
42 5993a8f2 2003-11-23 devnull panic(int status, char *fmt, ...)
43 5993a8f2 2003-11-23 devnull {
44 5993a8f2 2003-11-23 devnull va_list arg;
45 5993a8f2 2003-11-23 devnull
46 5993a8f2 2003-11-23 devnull Bflush(&stdout);
47 5993a8f2 2003-11-23 devnull
48 5993a8f2 2003-11-23 devnull fprint(2, "%s: ", progname);
49 5993a8f2 2003-11-23 devnull va_start(arg, fmt);
50 5993a8f2 2003-11-23 devnull vfprint(2, fmt, arg);
51 5993a8f2 2003-11-23 devnull va_end(arg);
52 5993a8f2 2003-11-23 devnull if (status)
53 5993a8f2 2003-11-23 devnull done(status);
54 5993a8f2 2003-11-23 devnull /*NOTREACHED*/
55 5993a8f2 2003-11-23 devnull }
56 5993a8f2 2003-11-23 devnull
57 5993a8f2 2003-11-23 devnull static int
58 5993a8f2 2003-11-23 devnull catch(void *a, char *msg)
59 5993a8f2 2003-11-23 devnull {
60 5993a8f2 2003-11-23 devnull USED(a);
61 5993a8f2 2003-11-23 devnull panic(2, msg);
62 5993a8f2 2003-11-23 devnull return 1;
63 5993a8f2 2003-11-23 devnull }
64 5993a8f2 2003-11-23 devnull
65 5993a8f2 2003-11-23 devnull int
66 5993a8f2 2003-11-23 devnull mkpathname(char *pathname, char *path, char *name)
67 5993a8f2 2003-11-23 devnull {
68 5993a8f2 2003-11-23 devnull if (strlen(path) + strlen(name) > MAXPATHLEN) {
69 5993a8f2 2003-11-23 devnull panic(0, "pathname %s/%s too long\n", path, name);
70 5993a8f2 2003-11-23 devnull return 1;
71 5993a8f2 2003-11-23 devnull }
72 5993a8f2 2003-11-23 devnull sprint(pathname, "%s/%s", path, name);
73 5993a8f2 2003-11-23 devnull return 0;
74 5993a8f2 2003-11-23 devnull }
75 fa325e9b 2020-01-10 cross
76 5993a8f2 2003-11-23 devnull static char *
77 5993a8f2 2003-11-23 devnull mktmpfile(int input, Dir **sb)
78 5993a8f2 2003-11-23 devnull {
79 5993a8f2 2003-11-23 devnull int fd, i;
80 5993a8f2 2003-11-23 devnull char *p;
81 5993a8f2 2003-11-23 devnull char buf[8192];
82 5993a8f2 2003-11-23 devnull
83 5993a8f2 2003-11-23 devnull atnotify(catch, 1);
84 a2d66357 2005-01-29 devnull /*
85 a2d66357 2005-01-29 devnull p = mktemp(tmp[whichtmp++]);
86 5993a8f2 2003-11-23 devnull fd = create(p, OWRITE, 0600);
87 a2d66357 2005-01-29 devnull */
88 a2d66357 2005-01-29 devnull fd = mkstemp(p=tmp[whichtmp++]);
89 5993a8f2 2003-11-23 devnull if (fd < 0) {
90 5993a8f2 2003-11-23 devnull panic(mflag ? 0: 2, "cannot create %s: %r\n", p);
91 5993a8f2 2003-11-23 devnull return 0;
92 5993a8f2 2003-11-23 devnull }
93 5993a8f2 2003-11-23 devnull while ((i = read(input, buf, sizeof(buf))) > 0) {
94 5993a8f2 2003-11-23 devnull if ((i = write(fd, buf, i)) < 0)
95 5993a8f2 2003-11-23 devnull break;
96 5993a8f2 2003-11-23 devnull }
97 5993a8f2 2003-11-23 devnull *sb = dirfstat(fd);
98 5993a8f2 2003-11-23 devnull close(fd);
99 5993a8f2 2003-11-23 devnull if (i < 0) {
100 5993a8f2 2003-11-23 devnull panic(mflag ? 0: 2, "cannot read/write %s: %r\n", p);
101 5993a8f2 2003-11-23 devnull return 0;
102 5993a8f2 2003-11-23 devnull }
103 5993a8f2 2003-11-23 devnull return p;
104 5993a8f2 2003-11-23 devnull }
105 5993a8f2 2003-11-23 devnull
106 5993a8f2 2003-11-23 devnull static char *
107 5993a8f2 2003-11-23 devnull statfile(char *file, Dir **sb)
108 5993a8f2 2003-11-23 devnull {
109 5993a8f2 2003-11-23 devnull Dir *dir;
110 5993a8f2 2003-11-23 devnull int input;
111 5993a8f2 2003-11-23 devnull
112 5993a8f2 2003-11-23 devnull dir = dirstat(file);
113 5993a8f2 2003-11-23 devnull if(dir == nil) {
114 5993a8f2 2003-11-23 devnull if (strcmp(file, "-") || (dir = dirfstat(0)) == nil) {
115 5993a8f2 2003-11-23 devnull panic(mflag ? 0: 2, "cannot stat %s: %r\n", file);
116 5993a8f2 2003-11-23 devnull return 0;
117 5993a8f2 2003-11-23 devnull }
118 5993a8f2 2003-11-23 devnull free(dir);
119 5993a8f2 2003-11-23 devnull return mktmpfile(0, sb);
120 5993a8f2 2003-11-23 devnull }
121 5993a8f2 2003-11-23 devnull else if (!REGULAR_FILE(dir) && !DIRECTORY(dir)) {
122 5993a8f2 2003-11-23 devnull free(dir);
123 5993a8f2 2003-11-23 devnull if ((input = open(file, OREAD)) == -1) {
124 5993a8f2 2003-11-23 devnull panic(mflag ? 0: 2, "cannot open %s: %r\n", file);
125 5993a8f2 2003-11-23 devnull return 0;
126 5993a8f2 2003-11-23 devnull }
127 5993a8f2 2003-11-23 devnull file = mktmpfile(input, sb);
128 5993a8f2 2003-11-23 devnull close(input);
129 5993a8f2 2003-11-23 devnull }
130 5993a8f2 2003-11-23 devnull else
131 5993a8f2 2003-11-23 devnull *sb = dir;
132 5993a8f2 2003-11-23 devnull return file;
133 5993a8f2 2003-11-23 devnull }
134 5993a8f2 2003-11-23 devnull
135 5993a8f2 2003-11-23 devnull void
136 5993a8f2 2003-11-23 devnull diff(char *f, char *t, int level)
137 5993a8f2 2003-11-23 devnull {
138 5993a8f2 2003-11-23 devnull char *fp, *tp, *p, fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
139 5993a8f2 2003-11-23 devnull Dir *fsb, *tsb;
140 5993a8f2 2003-11-23 devnull
141 5993a8f2 2003-11-23 devnull if ((fp = statfile(f, &fsb)) == 0)
142 1c096fa4 2005-01-11 devnull goto Return;
143 5993a8f2 2003-11-23 devnull if ((tp = statfile(t, &tsb)) == 0){
144 5993a8f2 2003-11-23 devnull free(fsb);
145 1c096fa4 2005-01-11 devnull goto Return;
146 5993a8f2 2003-11-23 devnull }
147 5993a8f2 2003-11-23 devnull if (DIRECTORY(fsb) && DIRECTORY(tsb)) {
148 5993a8f2 2003-11-23 devnull if (rflag || level == 0)
149 5993a8f2 2003-11-23 devnull diffdir(fp, tp, level);
150 5993a8f2 2003-11-23 devnull else
151 5993a8f2 2003-11-23 devnull Bprint(&stdout, "Common subdirectories: %s and %s\n",
152 5993a8f2 2003-11-23 devnull fp, tp);
153 5993a8f2 2003-11-23 devnull }
154 5993a8f2 2003-11-23 devnull else if (REGULAR_FILE(fsb) && REGULAR_FILE(tsb))
155 5993a8f2 2003-11-23 devnull diffreg(fp, tp);
156 5993a8f2 2003-11-23 devnull else {
157 5993a8f2 2003-11-23 devnull if (REGULAR_FILE(fsb)) {
158 5993a8f2 2003-11-23 devnull if ((p = utfrrune(f, '/')) == 0)
159 5993a8f2 2003-11-23 devnull p = f;
160 5993a8f2 2003-11-23 devnull else
161 5993a8f2 2003-11-23 devnull p++;
162 5993a8f2 2003-11-23 devnull if (mkpathname(tb, tp, p) == 0)
163 5993a8f2 2003-11-23 devnull diffreg(fp, tb);
164 5993a8f2 2003-11-23 devnull }
165 5993a8f2 2003-11-23 devnull else {
166 5993a8f2 2003-11-23 devnull if ((p = utfrrune(t, '/')) == 0)
167 5993a8f2 2003-11-23 devnull p = t;
168 5993a8f2 2003-11-23 devnull else
169 5993a8f2 2003-11-23 devnull p++;
170 5993a8f2 2003-11-23 devnull if (mkpathname(fb, fp, p) == 0)
171 5993a8f2 2003-11-23 devnull diffreg(fb, tp);
172 5993a8f2 2003-11-23 devnull }
173 5993a8f2 2003-11-23 devnull }
174 5993a8f2 2003-11-23 devnull free(fsb);
175 5993a8f2 2003-11-23 devnull free(tsb);
176 1c096fa4 2005-01-11 devnull Return:
177 1c096fa4 2005-01-11 devnull rmtmpfiles();
178 5993a8f2 2003-11-23 devnull }
179 5993a8f2 2003-11-23 devnull
180 5993a8f2 2003-11-23 devnull void
181 5993a8f2 2003-11-23 devnull main(int argc, char *argv[])
182 5993a8f2 2003-11-23 devnull {
183 5993a8f2 2003-11-23 devnull char *p;
184 5993a8f2 2003-11-23 devnull int i;
185 5993a8f2 2003-11-23 devnull Dir *fsb, *tsb;
186 eb5d2a54 2007-11-05 rsc extern int _p9usepwlibrary;
187 fa325e9b 2020-01-10 cross
188 eb5d2a54 2007-11-05 rsc _p9usepwlibrary = 0;
189 5993a8f2 2003-11-23 devnull Binit(&stdout, 1, OWRITE);
190 5993a8f2 2003-11-23 devnull progname = *argv;
191 5993a8f2 2003-11-23 devnull while (--argc && (*++argv)[0] == '-' && (*argv)[1]) {
192 5993a8f2 2003-11-23 devnull for (p = *argv+1; *p; p++) {
193 5993a8f2 2003-11-23 devnull switch (*p) {
194 a2d66357 2005-01-29 devnull
195 5993a8f2 2003-11-23 devnull case 'e':
196 5993a8f2 2003-11-23 devnull case 'f':
197 5993a8f2 2003-11-23 devnull case 'n':
198 a2d66357 2005-01-29 devnull case 'c':
199 a2d66357 2005-01-29 devnull case 'a':
200 5993a8f2 2003-11-23 devnull mode = *p;
201 5993a8f2 2003-11-23 devnull break;
202 5993a8f2 2003-11-23 devnull
203 5993a8f2 2003-11-23 devnull case 'w':
204 5993a8f2 2003-11-23 devnull bflag = 2;
205 5993a8f2 2003-11-23 devnull break;
206 5993a8f2 2003-11-23 devnull
207 5993a8f2 2003-11-23 devnull case 'b':
208 5993a8f2 2003-11-23 devnull bflag = 1;
209 5993a8f2 2003-11-23 devnull break;
210 5993a8f2 2003-11-23 devnull
211 5993a8f2 2003-11-23 devnull case 'r':
212 5993a8f2 2003-11-23 devnull rflag = 1;
213 eb5d2a54 2007-11-05 rsc mflag = 1;
214 5993a8f2 2003-11-23 devnull break;
215 5993a8f2 2003-11-23 devnull
216 5993a8f2 2003-11-23 devnull case 'm':
217 fa325e9b 2020-01-10 cross mflag = 1;
218 5993a8f2 2003-11-23 devnull break;
219 5993a8f2 2003-11-23 devnull
220 5993a8f2 2003-11-23 devnull case 'h':
221 5993a8f2 2003-11-23 devnull default:
222 5993a8f2 2003-11-23 devnull progname = "Usage";
223 5993a8f2 2003-11-23 devnull panic(2, usage);
224 5993a8f2 2003-11-23 devnull }
225 5993a8f2 2003-11-23 devnull }
226 5993a8f2 2003-11-23 devnull }
227 5993a8f2 2003-11-23 devnull if (argc < 2)
228 5993a8f2 2003-11-23 devnull panic(2, usage, progname);
229 5993a8f2 2003-11-23 devnull if ((tsb = dirstat(argv[argc-1])) == nil)
230 5993a8f2 2003-11-23 devnull panic(2, "can't stat %s\n", argv[argc-1]);
231 5993a8f2 2003-11-23 devnull if (argc > 2) {
232 5993a8f2 2003-11-23 devnull if (!DIRECTORY(tsb))
233 5993a8f2 2003-11-23 devnull panic(2, usage, progname);
234 5993a8f2 2003-11-23 devnull mflag = 1;
235 5993a8f2 2003-11-23 devnull }
236 5993a8f2 2003-11-23 devnull else {
237 5993a8f2 2003-11-23 devnull if ((fsb = dirstat(argv[0])) == nil)
238 5993a8f2 2003-11-23 devnull panic(2, "can't stat %s\n", argv[0]);
239 5993a8f2 2003-11-23 devnull if (DIRECTORY(fsb) && DIRECTORY(tsb))
240 5993a8f2 2003-11-23 devnull mflag = 1;
241 5993a8f2 2003-11-23 devnull free(fsb);
242 5993a8f2 2003-11-23 devnull }
243 5993a8f2 2003-11-23 devnull free(tsb);
244 1c096fa4 2005-01-11 devnull for (i = 0; i < argc-1; i++)
245 5993a8f2 2003-11-23 devnull diff(argv[i], argv[argc-1], 0);
246 5993a8f2 2003-11-23 devnull done(anychange);
247 5993a8f2 2003-11-23 devnull /*NOTREACHED*/
248 5993a8f2 2003-11-23 devnull }
249 5993a8f2 2003-11-23 devnull
250 5993a8f2 2003-11-23 devnull static char noroom[] = "out of memory - try diff -h\n";
251 5993a8f2 2003-11-23 devnull
252 5993a8f2 2003-11-23 devnull void *
253 5993a8f2 2003-11-23 devnull emalloc(unsigned n)
254 5993a8f2 2003-11-23 devnull {
255 5993a8f2 2003-11-23 devnull register void *p;
256 5993a8f2 2003-11-23 devnull
257 5993a8f2 2003-11-23 devnull if ((p = malloc(n)) == 0)
258 5993a8f2 2003-11-23 devnull panic(2, noroom);
259 5993a8f2 2003-11-23 devnull return p;
260 5993a8f2 2003-11-23 devnull }
261 5993a8f2 2003-11-23 devnull
262 5993a8f2 2003-11-23 devnull void *
263 5993a8f2 2003-11-23 devnull erealloc(void *p, unsigned n)
264 5993a8f2 2003-11-23 devnull {
265 5993a8f2 2003-11-23 devnull register void *rp;
266 5993a8f2 2003-11-23 devnull
267 5993a8f2 2003-11-23 devnull if ((rp = realloc(p, n)) == 0)
268 5993a8f2 2003-11-23 devnull panic(2, noroom);
269 5993a8f2 2003-11-23 devnull return rp;
270 5993a8f2 2003-11-23 devnull }