Commit | Line | Data |
---|---|---|
b6b5501c RC |
1 | #ifndef lint |
2 | static char *sccsid = "@(#)docmd.c 4.1 (Berkeley) 83/09/07"; | |
3 | #endif | |
4 | ||
5 | #include "defs.h" | |
6 | ||
7 | FILE *lfp; /* log file for recording files updated */ | |
8 | ||
9 | /* | |
10 | * Routines to process commands. | |
11 | */ | |
12 | docmd(files, hosts, cmds) | |
13 | struct block *files, *hosts, *cmds; | |
14 | { | |
15 | register struct block *h, *f, *c; | |
16 | register char *cp, **cpp; | |
17 | int n; | |
18 | ||
19 | if (debug) | |
20 | printf("docmd()\n"); | |
21 | ||
22 | files = expand(files); | |
23 | hosts = expand(hosts); | |
24 | if (files == NULL) | |
25 | fatal("no files to be updated\n"); | |
26 | if (hosts == NULL) | |
27 | fatal("empty list of hosts to be updated\n"); | |
28 | except = cmds; | |
29 | ||
30 | for (h = hosts; h != NULL; h = h->b_next) { | |
31 | if (!nflag) { | |
32 | if ((lfp = fopen(tmpfile, "w")) == NULL) { | |
33 | fatal("cannot open %s\n", tmpfile); | |
34 | exit(1); | |
35 | } | |
36 | if (!makeconn(h->b_name)) | |
37 | continue; | |
38 | } | |
39 | for (f = files; f != NULL; f = f->b_next) { | |
40 | if (filec) { | |
41 | for (cpp = filev; *cpp; cpp++) | |
42 | if (!strcmp(f->b_name, *cpp)) | |
43 | goto found; | |
44 | continue; | |
45 | } | |
46 | found: | |
47 | n = 0; | |
48 | for (c = cmds; c != NULL; c = c->b_next) | |
49 | if (c->b_type == INSTALL) { | |
50 | install(f->b_name, c->b_name, 0); | |
51 | n++; | |
52 | } else if (c->b_type == VERIFY) { | |
53 | install(f->b_name, c->b_name, 1); | |
54 | n++; | |
55 | } | |
56 | if (n == 0) | |
57 | install(f->b_name, f->b_name, 0); | |
58 | } | |
59 | if (!nflag) { | |
60 | (void) fclose(lfp); | |
61 | (void) close(rem); | |
62 | } | |
63 | for (c = cmds; c != NULL; c = c->b_next) | |
64 | if (c->b_type == NOTIFY) | |
65 | notify(h->b_name, c->b_args); | |
66 | } | |
67 | if (!nflag) | |
68 | (void) unlink(tmpfile); | |
69 | } | |
70 | ||
71 | /* | |
72 | * Create a connection to the rdist server on the machine rhost. | |
73 | */ | |
74 | makeconn(rhost) | |
75 | char *rhost; | |
76 | { | |
77 | register char *ruser; | |
78 | extern char user[]; | |
79 | ||
80 | (void) sprintf(buf, "/usr/local/rdist -Server%s%s%s%s%s", | |
81 | vflag ? " -v" : "", qflag ? " -q" : "", nflag ? " -n" : "", | |
82 | yflag ? " -y" : "", debug ? " -d" : ""); | |
83 | ||
84 | ruser = rindex(rhost, '.'); | |
85 | if (ruser != NULL) { | |
86 | *ruser++ = '\0'; | |
87 | if (!okname(ruser)) | |
88 | return(0); | |
89 | } else | |
90 | ruser = user; | |
91 | ||
92 | if (debug) { | |
93 | printf("makeconn(%s)\n", rhost); | |
94 | printf("luser = %s, ruser = %s\n", user, ruser); | |
95 | printf("buf = %s\n", buf); | |
96 | } | |
97 | ||
98 | rem = rcmd(&rhost, IPPORT_CMDSERVER, user, ruser, buf, 0); | |
99 | if (rem < 0) | |
100 | return(0); | |
101 | if (response() < 0) | |
102 | return(0); | |
103 | return(1); | |
104 | } | |
105 | ||
106 | /* | |
107 | * Update the file(s) if they are different. | |
108 | */ | |
109 | install(src, dest, verify) | |
110 | char *src, *dest; | |
111 | int verify; | |
112 | { | |
113 | register char *cp; | |
114 | extern char *tp; | |
115 | char lbuf[BUFSIZ]; | |
116 | ||
117 | if (!qflag) | |
118 | printf("%s %s %s\n", verify ? "verify" : "install", src, dest); | |
119 | if (nflag) | |
120 | return; | |
121 | /* | |
122 | * Pass the destination file/directory name to remote. | |
123 | */ | |
124 | (void) sprintf(buf, "T%s\n", dest); | |
125 | if (debug) | |
126 | printf("buf = %s", buf); | |
127 | (void) write(rem, buf, strlen(buf)); | |
128 | tp = NULL; | |
129 | shexpand(lbuf, src); | |
130 | sendf(lbuf, verify); | |
131 | } | |
132 | ||
133 | /* | |
134 | * Notify the list of people the changes that were made. | |
135 | */ | |
136 | notify(host, to) | |
137 | char *host; | |
138 | register struct block *to; | |
139 | { | |
140 | register int fd, len; | |
141 | FILE *pf, *popen(); | |
142 | struct stat stb; | |
143 | ||
144 | if (vflag) | |
145 | return; | |
146 | if (!qflag) { | |
147 | printf("notify @%s ", host); | |
148 | prnames(to); | |
149 | } | |
150 | if (nflag) | |
151 | return; | |
152 | ||
153 | if ((fd = open(tmpfile, 0)) < 0) { | |
154 | error("%s: %s\n", tmpfile, sys_errlist[errno]); | |
155 | return; | |
156 | } | |
157 | /* | |
158 | * Create a pipe to mailling program. | |
159 | */ | |
160 | pf = popen(MAILCMD, "w"); | |
161 | if (pf == NULL) | |
162 | fatal("notify: \"%s\" failed\n", MAILCMD); | |
163 | /* | |
164 | * Output the proper header information. | |
165 | */ | |
166 | fprintf(pf, "From: rdist (Remote distribution program)\n"); | |
167 | fprintf(pf, "To:"); | |
168 | while (to != NULL) { | |
169 | fprintf(pf, " %s@%s", to->b_name, host); | |
170 | to = to->b_next; | |
171 | } | |
172 | putc('\n', pf); | |
173 | fprintf(pf, "Subject: files updated by rdist\n"); | |
174 | putc('\n', pf); | |
175 | ||
176 | while ((len = read(fd, buf, BUFSIZ)) > 0) | |
177 | (void) fwrite(buf, 1, len, pf); | |
178 | (void) close(fd); | |
179 | (void) pclose(pf); | |
180 | } | |
181 | ||
182 | struct block *except; /* list of files to exclude */ | |
183 | ||
184 | /* | |
185 | * Return true if name is in list. | |
186 | */ | |
187 | exclude(file) | |
188 | char *file; | |
189 | { | |
190 | register struct block *b, *c; | |
191 | ||
192 | for (c = except; c != NULL; c = c->b_next) { | |
193 | if (c->b_type != EXCEPT) | |
194 | continue; | |
195 | for (b = c->b_args; b != NULL; b = b->b_next) | |
196 | if (!strcmp(file, b->b_name)) | |
197 | return(1); | |
198 | } | |
199 | return(0); | |
200 | } | |
201 | ||
202 | okname(name) | |
203 | register char *name; | |
204 | { | |
205 | register char *cp = name; | |
206 | register int c; | |
207 | ||
208 | do { | |
209 | c = *cp; | |
210 | if (c & 0200) | |
211 | goto bad; | |
212 | if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-') | |
213 | goto bad; | |
214 | cp++; | |
215 | } while (*cp); | |
216 | return(1); | |
217 | bad: | |
218 | error("invalid user name %s\n", name); | |
219 | return(0); | |
220 | } | |
221 | ||
222 | char * | |
223 | colon(cp) | |
224 | register char *cp; | |
225 | { | |
226 | ||
227 | while (*cp) { | |
228 | if (*cp == ':') | |
229 | return(cp); | |
230 | if (*cp == '/') | |
231 | return(0); | |
232 | cp++; | |
233 | } | |
234 | return(0); | |
235 | } |