increased buffer size for long names in decode().
[unix-history] / usr / src / usr.bin / rdist / docmd.c
CommitLineData
b6b5501c
RC
1#ifndef lint
2static char *sccsid = "@(#)docmd.c 4.1 (Berkeley) 83/09/07";
3#endif
4
5#include "defs.h"
6
7FILE *lfp; /* log file for recording files updated */
8
9/*
10 * Routines to process commands.
11 */
12docmd(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 */
74makeconn(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 */
109install(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 */
136notify(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
182struct block *except; /* list of files to exclude */
183
184/*
185 * Return true if name is in list.
186 */
187exclude(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
202okname(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);
217bad:
218 error("invalid user name %s\n", name);
219 return(0);
220}
221
222char *
223colon(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}