|
|
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 = tdkexec(argv[optind], "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\n", name);
196: case FTW_D:
197: return(0);
198: }
199: alarm(60);
200: fprintf(torem, "stat %s %ld\n", remoten(name), statp->st_size);
201: fflush(torem);
202: vgetline(rem, buf, name);
203: if (sscanf(buf, "ok %ld %ld", &size, &date) != 2) {
204: if (vflag)
205: printf("track: %s not found (remote)\n", remoten(name));
206: return(0);
207: }
208: if (size == statp->st_size) {
209: fprintf(torem, "sum %s\n", remoten(name));
210: fflush(torem);
211: lsum = getsum(name);
212: vgetline(rem, buf, name);
213: if (sscanf(buf, "ok %ld", &rsum) != 1) {
214: printf("track: can't read sum for %s\n", remoten(name));
215: exit(1);
216: }
217: if (lsum == rsum) {
218: if (vflag > 1)
219: printf("track: %s OK\n", name);
220: return(0);
221: }
222: }
223: if (tflag && statp->st_mtime > date) {
224: if (vflag)
225: printf("track: %s newer locally\n", name);
226: return(0);
227: }
228: if (nflag) {
229: printf("track: would copy %s\n", name);
230: return(0);
231: }
232: printf("track: copy %s:", name);
233: copy(name, rem, date);
234: return(0);
235: }
236:
237: copy(name, fd, date)
238: char *name;
239: time_t date;
240: {
241: char buf[1024];
242: int ofd, nfd, i, n;
243: time_t ut[2];
244:
245: fprintf(torem, "send %s\n", remoten(name));
246: fflush(torem);
247: vgetline(fd, buf, name);
248: if (strcmp(buf, "ok") != 0) {
249: printf("can't open remote\n");
250: return;
251: }
252: if ((ofd = creat(tempfile, 0644)) < 0) {
253: printf("can't open temp\n");
254: return;
255: }
256: i = 10;
257: while ((n = read(fd, buf, 1024)) > 0) {
258: if (write(ofd, buf, n) != n) {
259: printf("write temp file\n");
260: return;
261: }
262: if (--i <= 0) {
263: alarm(60);
264: i = 10;
265: }
266: }
267: close(ofd);
268: ofd = open(tempfile, 0);
269: if (ofd < 0) {
270: printf("can't reopen temp\n");
271: return;
272: }
273: nfd = creat(name, 0777);
274: if (nfd < 0) {
275: printf("can't create new version\n");
276: return;
277: }
278: while ((n = read(ofd, buf, 1024)) > 0) {
279: if (write(nfd, buf, n) != n) {
280: printf("write error in copy\n");
281: return;
282: }
283: }
284: close(ofd);
285: close(nfd);
286: ut[0] = time((time_t)NULL);
287: ut[1] = date;
288: utime(name, ut);
289: printf("OK\n");
290: }
291:
292: char *
293: remoten(name)
294: register char *name;
295: {
296: static char rname[256];
297:
298: if (prefix[0] == '\0')
299: return(name);
300: if (name[0] != '/') {
301: strcpy(rname, prefix);
302: strcat(rname, "/");
303: strcat(rname, name);
304: return(rname);
305: }
306: strcpy(rname, prefix);
307: strcat(rname, name+nsize);
308: return(rname);
309: }
310:
311: vgetline(fd, buf, name)
312: char *buf, *name;
313: {
314: if (getline(fd, buf)==0) {
315: printf("track: EOF on remote, file %s\n", name);
316: exit(1);
317: }
318: }
319:
320: getline(fd, buf)
321: char *buf;
322: {
323: register char *bp;
324:
325: bp = buf;
326: for(;;) {
327: if (read(fd, bp, 1) <= 0)
328: return(0);
329: if (*bp == '\n') {
330: *bp = '\0';
331: return(1);
332: }
333: if (++bp >= &buf[128])
334: return(0);
335: }
336: }
337:
338: unsigned
339: getsum(name)
340: char *name;
341: {
342: register FILE *f;
343: register unsigned sum;
344: register c;
345:
346: if ((f = fopen(name, "r")) == NULL)
347: return(-1);
348: sum = 0;
349: while ((c = getc(f)) != EOF) {
350: if (sum & 01)
351: sum = (sum>>1) + 0x8000;
352: else
353: sum >>= 1;
354: sum += c;
355: sum &= 0xFFFF;
356: }
357: fclose(f);
358: return(sum);
359: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.