|
|
1.1 root 1: /*
2: * track
3: */
4:
5: #include <stdio.h>
6: #include <sys/types.h>
7: #include <sys/stat.h>
8: #include <dk.h>
9: #include <signal.h>
10: #include <setjmp.h>
11: #include <ftw.h>
12:
13: int vflag; /* verbose */
14: int nflag; /* don't actually copy */
15: int rflag; /* act as remote slave */
16: int tflag; /* update only if remote is newer */
17: char prefix[128]; /* alternate prefix on remote (-d flag) */
18: int nsize; /* amount to strip off local name */
19:
20: char *descfile;
21: extern char *optarg;
22: extern int optind;
23: FILE *torem;
24: int rem;
25: int descfd;
26: jmp_buf almbuf;
27: char tempfile[] = "/tmp/trckXXXXXX";
28: unsigned getsum();
29: char *remoten();
30:
31: main(argc, argv)
32: char **argv;
33: {
34: int consider();
35: char buf[128];
36: extern char *dkerror;
37:
38: if (argc <= 1) {
39: printf("track [-nvtr] {-f description | directory} machine\n");
40: exit(0);
41: }
42: for (;;) {
43: switch (getopt(argc, argv, "vnrtf:d:")) {
44:
45: case 'v':
46: vflag++;
47: continue;
48:
49: case 'r':
50: rflag++;
51: continue;
52:
53: case 'n':
54: nflag++;
55: continue;
56:
57: case 't':
58: tflag++;
59: continue;
60:
61: case 'f':
62: descfile = optarg;
63: continue;
64:
65: case 'd':
66: strcpy(prefix, optarg);
67: continue;
68: case '?':
69: exit(1);
70:
71: case EOF:
72: default:
73: break;
74: }
75: break;
76: }
77: if (setjmp(almbuf)) {
78: if (rflag==0)
79: printf("track: alarm talking to %s\n", argv[optind]);
80: exit(1);
81: }
82: if (rflag)
83: remote();
84: if (descfile) {
85: descfd = open(descfile, 0);
86: if (descfd <= 0) {
87: printf("track: can't open description %s", descfile);
88: exit(1);
89: }
90: } else {
91: if (optind >= argc) {
92: printf("track: no description file\n");
93: exit(1);
94: }
95: descfile = argv[optind];
96: optind++;
97: }
98: if (optind >= argc) {
99: printf("track: no machine given\n");
100: exit(1);
101: }
102: rem = tdkexec(argv[optind], "track -r");
103: if (rem < 0) {
104: printf("track: %s call failed: %s\n", argv[optind], dkerror);
105: exit(1);
106: }
107: torem = fdopen(rem, "w");
108: fprintf(torem, "testing 123\n");
109: fflush(torem);
110: vgetline(rem, buf, "<startup>");
111: if (strncmp(buf, "ok", 2) !=0) {
112: printf("track: can't talk to remote\n");
113: exit(1);
114: }
115: mktemp(tempfile);
116: if (descfd <= 0) {
117: if (prefix[0])
118: nsize = strlen(descfile);
119: ftw(descfile, consider, 10);
120: } else {
121: while (getline(descfd, buf)) {
122: if (prefix[0])
123: nsize = strlen(buf);
124: ftw(buf, consider, 10);
125: }
126: }
127: unlink(tempfile);
128: exit(1);
129: }
130:
131: remote()
132: {
133: char buf[1024];
134: struct stat statb;
135: char name[128];
136: int x, ofd;
137: char obuf[BUFSIZ];
138:
139: setbuf(stdout, obuf);
140: while (getline(0, buf) != 0) {
141: if (sscanf(buf, "testing %d", &x) == 1) {
142: printf("ok\n");
143: fflush(stdout);
144: continue;
145: }
146: if (sscanf(buf, "stat %s", name) == 1) {
147: if (stat(name, &statb) < 0) {
148: printf("ng\n");
149: fflush(stdout);
150: continue;
151: }
152: printf("ok %ld %ld\n", statb.st_size, statb.st_mtime);
153: fflush(stdout);
154: continue;
155: }
156: if (sscanf(buf, "sum %s", name) == 1) {
157: printf("ok %ld\n", (long)getsum(name));
158: fflush(stdout);
159: continue;
160: }
161: if (sscanf(buf, "send %s", name) == 1) {
162: ofd = open(name, 0);
163: if (ofd < 0) {
164: printf("ng\n");
165: fflush(stdout);
166: continue;
167: }
168: printf("ok\n");
169: fflush(stdout);
170: while ((x = read(ofd, buf, 1024)) > 0)
171: write(1, buf, x);
172: close(ofd);
173: write(1, buf, 0);
174: continue;
175: }
176: break;
177: }
178: exit(0);
179: }
180:
181: consider(name, statp, flag)
182: char *name;
183: struct stat *statp;
184: {
185: char buf[128];
186: long lsum, rsum;
187: long size;
188: time_t date;
189:
190: switch (flag) {
191:
192: case FTW_F:
193: break;
194:
195: default:
196: printf("track: trouble with %s\n", name);
197: case FTW_D:
198: return(0);
199: }
200: alarm(60);
201: fprintf(torem, "stat %s %ld\n", remoten(name), statp->st_size);
202: fflush(torem);
203: vgetline(rem, buf, name);
204: if (sscanf(buf, "ok %ld %ld", &size, &date) != 2) {
205: if (vflag)
206: printf("track: %s not found (remote)\n", remoten(name));
207: return(0);
208: }
209: if (size == statp->st_size) {
210: fprintf(torem, "sum %s\n", remoten(name));
211: fflush(torem);
212: lsum = getsum(name);
213: vgetline(rem, buf, name);
214: if (sscanf(buf, "ok %ld", &rsum) != 1) {
215: printf("track: can't read sum for %s\n", remoten(name));
216: exit(1);
217: }
218: if (lsum == rsum) {
219: if (vflag > 1)
220: printf("track: %s OK\n", name);
221: return(0);
222: }
223: }
224: if (tflag && statp->st_mtime > date) {
225: if (vflag)
226: printf("track: %s newer locally\n", name);
227: return(0);
228: }
229: if (nflag) {
230: printf("track: would copy %s\n", name);
231: return(0);
232: }
233: printf("track: copy %s:", name);
234: copy(name, rem, date);
235: return(0);
236: }
237:
238: copy(name, fd, date)
239: char *name;
240: time_t date;
241: {
242: char buf[1024];
243: int ofd, nfd, i, n;
244: time_t ut[2];
245:
246: fprintf(torem, "send %s\n", remoten(name));
247: fflush(torem);
248: vgetline(fd, buf, name);
249: if (strcmp(buf, "ok") != 0) {
250: printf("can't open remote\n");
251: return;
252: }
253: if ((ofd = creat(tempfile, 0644)) < 0) {
254: printf("can't open temp\n");
255: return;
256: }
257: i = 10;
258: while ((n = read(fd, buf, 1024)) > 0) {
259: if (write(ofd, buf, n) != n) {
260: printf("write temp file\n");
261: return;
262: }
263: if (--i <= 0) {
264: alarm(60);
265: i = 10;
266: }
267: }
268: close(ofd);
269: ofd = open(tempfile, 0);
270: if (ofd < 0) {
271: printf("can't reopen temp\n");
272: return;
273: }
274: nfd = creat(name, 0777);
275: if (nfd < 0) {
276: printf("can't create new version\n");
277: return;
278: }
279: while ((n = read(ofd, buf, 1024)) > 0) {
280: if (write(nfd, buf, n) != n) {
281: printf("write error in copy\n");
282: return;
283: }
284: }
285: close(ofd);
286: close(nfd);
287: ut[0] = time((time_t)NULL);
288: ut[1] = date;
289: utime(name, ut);
290: printf("OK\n");
291: }
292:
293: char *
294: remoten(name)
295: register char *name;
296: {
297: static char rname[256];
298:
299: if (prefix[0] == '\0')
300: return(name);
301: if (name[0] != '/') {
302: strcpy(rname, prefix);
303: strcat(rname, "/");
304: strcat(rname, name);
305: return(rname);
306: }
307: strcpy(rname, prefix);
308: strcat(rname, name+nsize);
309: return(rname);
310: }
311:
312: vgetline(fd, buf, name)
313: char *buf, *name;
314: {
315: if (getline(fd, buf)==0) {
316: printf("track: EOF on remote, file %s\n", name);
317: exit(1);
318: }
319: }
320:
321: getline(fd, buf)
322: char *buf;
323: {
324: register char *bp;
325:
326: bp = buf;
327: for(;;) {
328: if (read(fd, bp, 1) <= 0)
329: return(0);
330: if (*bp == '\n') {
331: *bp = '\0';
332: return(1);
333: }
334: if (++bp >= &buf[128])
335: return(0);
336: }
337: }
338:
339: unsigned
340: getsum(name)
341: char *name;
342: {
343: register FILE *f;
344: register unsigned sum;
345: register c;
346:
347: if ((f = fopen(name, "r")) == NULL)
348: return(-1);
349: sum = 0;
350: while ((c = getc(f)) != EOF) {
351: if (sum & 01)
352: sum = (sum>>1) + 0x8000;
353: else
354: sum >>= 1;
355: sum += c;
356: sum &= 0xFFFF;
357: }
358: fclose(f);
359: return(sum);
360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.