|
|
1.1 root 1: /* docmd.c -- driver for the whole thing */
2:
3: /*
4: * $Header: /f/osi/others/idist/RCS/docmd.c,v 7.0 89/11/23 21:58:24 mrose Rel $
5: *
6: * The major alterations to this file are the replacing of the
7: * connection stuff with the ISODE functions necessary. These new
8: * functions appear in a new file.
9: *
10: * Julian Onions <[email protected]>
11: * Nottingham University, Computer Science.
12: *
13: *
14: * $Log: docmd.c,v $
15: * Revision 7.0 89/11/23 21:58:24 mrose
16: * Release 6.0
17: *
18: */
19:
20:
21: /*
22: * Copyright (c) 1983 Regents of the University of California.
23: * All rights reserved. The Berkeley software License Agreement
24: * specifies the terms and conditions for redistribution.
25: */
26:
27: #ifndef lint
28: static char sccsid[] = "@(#)docmd.c 5.1 (Berkeley) 6/6/85";
29: static char *rcsid = "$Header: /f/osi/others/idist/RCS/docmd.c,v 7.0 89/11/23 21:58:24 mrose Rel $";
30: #endif
31:
32: #include "defs.h"
33: #include <setjmp.h>
34: #include <sys/file.h>
35:
36: FILE *lfp; /* log file for recording files updated */
37: struct subcmd *subcmds; /* list of sub-commands for current cmd */
38: jmp_buf env;
39:
40: int cleanup();
41: int lostconn();
42:
43: /*
44: * Do the commands in cmds (initialized by yyparse).
45: */
46: docmds(dhosts, argc, argv)
47: char **dhosts;
48: int argc;
49: char **argv;
50: {
51: register struct cmd *c;
52: register struct namelist *f;
53: register char **cpp;
54: extern struct cmd *cmds;
55:
56: (void) signal(SIGHUP, cleanup);
57: (void) signal(SIGINT, cleanup);
58: (void) signal(SIGQUIT, cleanup);
59: (void) signal(SIGTERM, cleanup);
60:
61: for (c = cmds; c != NULL; c = c->c_next) {
62: if (dhosts != NULL && *dhosts != NULL) {
63: for (cpp = dhosts; *cpp; cpp++)
64: if (strcmp(c->c_name, *cpp) == 0)
65: goto fndhost;
66: continue;
67: }
68: fndhost:
69: if (argc) {
70: for (cpp = argv; *cpp; cpp++) {
71: if (c->c_label != NULL &&
72: strcmp(c->c_label, *cpp) == 0) {
73: cpp = NULL;
74: goto found;
75: }
76: for (f = c->c_files; f != NULL; f = f->n_next)
77: if (strcmp(f->n_name, *cpp) == 0)
78: goto found;
79: }
80: continue;
81: } else
82: cpp = NULL;
83: found:
84: switch (c->c_type) {
85: case ARROW:
86: doarrow(cpp, c->c_files, c->c_name, c->c_cmds);
87: break;
88: case DCOLON:
89: dodcolon(cpp, c->c_files, c->c_name, c->c_cmds);
90: break;
91: default:
92: adios (NULLCP, "illegal command type %d\n", c->c_type);
93: }
94: }
95: closeconn();
96: }
97:
98: /*
99: * Process commands for sending files to other machines.
100: */
101: doarrow(filev, files, rhost, scmds)
102: char **filev;
103: struct namelist *files;
104: char *rhost;
105: struct subcmd *scmds;
106: {
107: register struct namelist *f;
108: register struct subcmd *sc;
109: register char **cpp;
110: int n, ddir, opts = options;
111:
112: if (debug)
113: printf("doarrow(%x, %s, %x)\n", files, rhost, scmds);
114:
115: if (files == NULL) {
116: advise(NULLCP, "no files to be updated");
117: return;
118: }
119:
120: subcmds = scmds;
121: ddir = files->n_next != NULL; /* destination is a directory */
122: if (nflag)
123: printf("updating host %s\n", rhost);
124: else {
125: if (setjmp(env))
126: goto done;
127: (void) signal(SIGPIPE, lostconn);
128: if (!makeconn(rhost))
129: return;
130: if ((lfp = fopen(utmpfile, "w")) == NULL)
131: adios (utmpfile, "cannot open file");
132: }
133: for (f = files; f != NULL; f = f->n_next) {
134: if (filev) {
135: for (cpp = filev; *cpp; cpp++)
136: if (strcmp(f->n_name, *cpp) == 0)
137: goto found;
138: if (!nflag)
139: (void) fclose(lfp);
140: continue;
141: }
142: found:
143: n = 0;
144: for (sc = scmds; sc != NULL; sc = sc->sc_next) {
145: if (sc->sc_type != INSTALL)
146: continue;
147: n++;
148: install(f->n_name, sc->sc_name,
149: sc->sc_name == NULL ? 0 : ddir, sc->sc_options);
150: opts = sc->sc_options;
151: }
152: if (n == 0)
153: install(f->n_name, (char *)NULL, 0, options);
154: }
155: done:
156: if (!nflag) {
157: (void) signal(SIGPIPE, cleanup);
158: (void) fclose(lfp);
159: lfp = NULL;
160: }
161: for (sc = scmds; sc != NULL; sc = sc->sc_next)
162: if (sc->sc_type == NOTIFY)
163: notify(utmpfile, rhost, sc->sc_args, 0L);
164: if (!nflag) {
165: (void) unlink(utmpfile);
166: for (; ihead != NULL; ihead = ihead->nextp) {
167: free((char *)ihead);
168: if ((opts & IGNLNKS) || ihead->count == 0)
169: continue;
170: log(lfp, "%s: Warning: missing links\n",
171: ihead->pathname);
172: }
173: }
174: }
175:
176:
177: lostconn()
178: {
179: log(lfp, "idist: lost connection\n");
180: longjmp(env, 1);
181: }
182:
183:
184: time_t lastmod;
185: FILE *tfp;
186: extern char target[], *tp;
187:
188: /*
189: * Process commands for comparing files to time stamp files.
190: */
191: dodcolon(filev, files, stamp, scmds)
192: char **filev;
193: struct namelist *files;
194: char *stamp;
195: struct subcmd *scmds;
196: {
197: register struct subcmd *sc;
198: register struct namelist *f;
199: register char **cpp;
200: struct timeval tv[2];
201: struct timezone tz;
202: struct stat stb;
203:
204: if (debug)
205: printf("dodcolon()\n");
206:
207: if (files == NULL) {
208: advise (NULLCP, "no files to be updated");
209: return;
210: }
211: if (stat(stamp, &stb) < 0) {
212: advise(stamp, "Can't stat");
213: return;
214: }
215: if (debug)
216: printf("%s: %d\n", stamp, stb.st_mtime);
217:
218: subcmds = scmds;
219: lastmod = stb.st_mtime;
220: if (nflag || (options & VERIFY))
221: tfp = NULL;
222: else {
223: if ((tfp = fopen(utmpfile, "w")) == NULL) {
224: advise (utmpfile, "Can't open file");
225: return;
226: }
227: (void) gettimeofday(&tv[0], &tz);
228: tv[1] = tv[0];
229: (void) utimes(stamp, tv);
230: }
231:
232: for (f = files; f != NULL; f = f->n_next) {
233: if (filev) {
234: for (cpp = filev; *cpp; cpp++)
235: if (strcmp(f->n_name, *cpp) == 0)
236: goto found;
237: continue;
238: }
239: found:
240: tp = NULL;
241: cmptime(f->n_name);
242: }
243:
244: if (tfp != NULL)
245: (void) fclose(tfp);
246: for (sc = scmds; sc != NULL; sc = sc->sc_next)
247: if (sc->sc_type == NOTIFY)
248: notify(utmpfile, (char *)NULL, sc->sc_args, lastmod);
249: if (!nflag && !(options & VERIFY))
250: (void) unlink(utmpfile);
251: }
252:
253: /*
254: * Compare the mtime of file to the list of time stamps.
255: */
256: cmptime(name)
257: char *name;
258: {
259: struct stat stb;
260:
261: if (debug)
262: printf("cmptime(%s)\n", name);
263:
264: if (except(name))
265: return;
266:
267: if (nflag) {
268: printf("comparing dates: %s\n", name);
269: return;
270: }
271:
272: /*
273: * first time cmptime() is called?
274: */
275: if (tp == NULL) {
276: if (exptilde(target, name) == NULL)
277: return;
278: tp = name = target;
279: while (*tp)
280: tp++;
281: }
282: if (access(name, 4) < 0 || stat(name, &stb) < 0) {
283: advise (name, "Can't access");
284: return;
285: }
286:
287: switch (stb.st_mode & S_IFMT) {
288: case S_IFREG:
289: break;
290:
291: case S_IFDIR:
292: rcmptime(&stb);
293: return;
294:
295: default:
296: advise(NULLCP, "%s not a plain file", name);
297: return;
298: }
299:
300: if (stb.st_mtime > lastmod)
301: log(tfp, "new: %s\n", name);
302: }
303:
304: rcmptime(st)
305: struct stat *st;
306: {
307: register DIR *d;
308: register struct direct *dp;
309: register char *cp;
310: char *otp;
311: int len;
312:
313: if (debug)
314: printf("rcmptime(%x)\n", st);
315:
316: if ((d = opendir(target)) == NULL) {
317: advise (target, "can't open directory");
318: return;
319: }
320: otp = tp;
321: len = tp - target;
322: while (dp = readdir(d)) {
323: if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
324: continue;
325: if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
326: advise (NULLCP, "%s/%s name too long",
327: target, dp->d_name);
328: continue;
329: }
330: tp = otp;
331: *tp++ = '/';
332: cp = dp->d_name;
333: while (*tp++ = *cp++)
334: ;
335: tp--;
336: cmptime(target);
337: }
338: closedir(d);
339: tp = otp;
340: *tp = '\0';
341: }
342:
343: /*
344: * Notify the list of people the changes that were made.
345: * rhost == NULL if we are mailing a list of changes compared to at time
346: * stamp file.
347: */
348: notify(file, rhost, to, lmod)
349: char *file, *rhost;
350: register struct namelist *to;
351: time_t lmod;
352: {
353: register int fd, len;
354: FILE *pf, *popen();
355: struct stat stb;
356: char buf[BUFSIZ];
357:
358: if ((options & VERIFY) || to == NULL)
359: return;
360: if (!qflag) {
361: printf("notify ");
362: if (rhost)
363: printf("@%s ", rhost);
364: prnames(to);
365: }
366: if (nflag)
367: return;
368:
369: if ((fd = open(file, O_RDONLY, 0)) < 0) {
370: advise (file, "Can't open file");
371: return;
372: }
373: if (fstat(fd, &stb) < 0) {
374: advise (file, "Can't stat");
375: (void) close(fd);
376: return;
377: }
378: if (stb.st_size == 0) {
379: (void) close(fd);
380: return;
381: }
382: /*
383: * Create a pipe to mailling program.
384: */
385: pf = popen(MAILCMD, "w");
386: if (pf == NULL) {
387: advise (NULLCP, "notify: \"%s\" failed", MAILCMD);
388: (void) close(fd);
389: return;
390: }
391: /*
392: * Output the proper header information.
393: */
394: fprintf(pf, "From: idist (Remote ISO distribution program)\n");
395: fprintf(pf, "To:");
396: if (!any('@', to->n_name) && rhost != NULL)
397: fprintf(pf, " %s@%s", to->n_name, rhost);
398: else
399: fprintf(pf, " %s", to->n_name);
400: to = to->n_next;
401: while (to != NULL) {
402: if (!any('@', to->n_name) && rhost != NULL)
403: fprintf(pf, ", %s@%s", to->n_name, rhost);
404: else
405: fprintf(pf, ", %s", to->n_name);
406: to = to->n_next;
407: }
408: (void) putc('\n', pf);
409: if (rhost != NULL)
410: fprintf(pf, "Subject: files updated by idist from %s to %s\n",
411: host, rhost);
412: else
413: fprintf(pf, "Subject: files updated after %s\n", ctime(&lmod));
414: (void) putc('\n', pf);
415:
416: while ((len = read(fd, buf, BUFSIZ)) > 0)
417: (void) fwrite(buf, 1, len, pf);
418: (void) close(fd);
419: (void) pclose(pf);
420: }
421:
422: /*
423: * Return true if name is in the list.
424: */
425: inlist(list, file)
426: struct namelist *list;
427: char *file;
428: {
429: register struct namelist *nl;
430:
431: for (nl = list; nl != NULL; nl = nl->n_next)
432: if (!strcmp(file, nl->n_name))
433: return(1);
434: return(0);
435: }
436:
437: /*
438: * Return TRUE if file is in the exception list.
439: */
440: except(file)
441: char *file;
442: {
443: register struct subcmd *sc;
444: register struct namelist *nl;
445: char *p, *re_comp ();
446:
447: if (debug)
448: printf("except(%s)\n", file);
449:
450: for (sc = subcmds; sc != NULL; sc = sc->sc_next) {
451: if (sc->sc_type != EXCEPT && sc->sc_type != PATTERN)
452: continue;
453: for (nl = sc->sc_args; nl != NULL; nl = nl->n_next) {
454: if (sc->sc_type == EXCEPT) {
455: if (!strcmp(file, nl->n_name))
456: return(1);
457: continue;
458: }
459: if (p = re_comp(nl->n_name)) {
460: advise (NULLCP, "'%s' - %s", nl -> n_name, p);
461: continue;
462: }
463: if (re_exec(file) > 0)
464: return(1);
465: }
466: }
467: return(0);
468: }
469:
470: char *
471: colon(cp)
472: register char *cp;
473: {
474:
475: while (*cp) {
476: if (*cp == ':')
477: return(cp);
478: if (*cp == '/')
479: return(0);
480: cp++;
481: }
482: return(0);
483: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.