|
|
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:
37: if (argc <= 1) {
38: printf("track [-nvtr] {-f description | directory} machine\n");
39: exit(0);
40: }
41: for (;;) {
42: switch (getopt(argc, argv, "vnrtf:d:")) {
43:
44: case 'v':
45: vflag++;
46: continue;
47:
48: case 'r':
49: rflag++;
50: continue;
51:
52: case 'n':
53: nflag++;
54: continue;
55:
56: case 't':
57: tflag++;
58: continue;
59:
60: case 'f':
61: descfile = optarg;
62: continue;
63:
64: case 'd':
65: strcpy(prefix, optarg);
66: continue;
67: case '?':
68: exit(1);
69:
70: case EOF:
71: default:
72: break;
73: }
74: break;
75: }
76: if (setjmp(almbuf)) {
77: if (rflag==0)
78: printf("track: alarm talking to %s\n", argv[optind]);
79: exit(1);
80: }
81: if (rflag)
82: remote();
83: if (descfile) {
84: descfd = open(descfile, 0);
85: if (descfd <= 0) {
86: printf("track: can't open description %s", descfile);
87: exit(1);
88: }
89: } else {
90: if (optind >= argc) {
91: printf("track: no description file\n");
92: exit(1);
93: }
94: descfile = argv[optind];
95: optind++;
96: }
97: if (optind >= argc) {
98: printf("track: no machine given\n");
99: exit(1);
100: }
101: rem = ipcexec(argv[optind], "heavy delim", "track -r");
102: if (rem < 0) {
103: printf("track: can't execute on %s\n", argv[optind]);
104: exit(1);
105: }
106: torem = fdopen(rem, "w");
107: fprintf(torem, "testing 123\n");
108: fflush(torem);
109: vgetline(rem, buf, "<startup>");
110: if (strncmp(buf, "ok", 2) !=0) {
111: printf("track: can't talk to remote\n");
112: exit(1);
113: }
114: mktemp(tempfile);
115: if (descfd <= 0) {
116: if (prefix[0])
117: nsize = strlen(descfile);
118: ftw(descfile, consider, 10);
119: } else {
120: while (getline(descfd, buf)) {
121: if (prefix[0])
122: nsize = strlen(buf);
123: ftw(buf, consider, 10);
124: }
125: }
126: unlink(tempfile);
127: exit(1);
128: }
129:
130: remote()
131: {
132: char buf[1024];
133: struct stat statb;
134: char name[128];
135: int x, ofd;
136: char obuf[BUFSIZ];
137:
138: setbuf(stdout, obuf);
139: while (getline(0, buf) != 0) {
140: if (sscanf(buf, "testing %d", &x) == 1) {
141: printf("ok\n");
142: fflush(stdout);
143: continue;
144: }
145: if (sscanf(buf, "stat %s", name) == 1) {
146: if (stat(name, &statb) < 0) {
147: printf("ng\n");
148: fflush(stdout);
149: continue;
150: }
151: printf("ok %ld %ld\n", statb.st_size, statb.st_mtime);
152: fflush(stdout);
153: continue;
154: }
155: if (sscanf(buf, "sum %s", name) == 1) {
156: printf("ok %ld\n", (long)getsum(name));
157: fflush(stdout);
158: continue;
159: }
160: if (sscanf(buf, "send %s", name) == 1) {
161: ofd = open(name, 0);
162: if (ofd < 0) {
163: printf("ng\n");
164: fflush(stdout);
165: continue;
166: }
167: printf("ok\n");
168: fflush(stdout);
169: while ((x = read(ofd, buf, 1024)) > 0)
170: write(1, buf, x);
171: close(ofd);
172: write(1, buf, 0);
173: continue;
174: }
175: break;
176: }
177: exit(0);
178: }
179:
180: consider(name, statp, flag)
181: char *name;
182: struct stat *statp;
183: {
184: char buf[128];
185: long lsum, rsum;
186: long size;
187: time_t date;
188:
189: switch (flag) {
190:
191: case FTW_F:
192: break;
193:
194: default:
195: printf("track: trouble with %s (%d)\n", name, flag);
196: case FTW_D:
197: case FTW_DP:
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.