main.c revision 1.12 1 /* $NetBSD: main.c,v 1.12 2001/11/01 16:31:48 tron Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
39 The Regents of the University of California. All rights reserved.\n");
40 #endif /* not lint */
41
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/9/93";
45 #else
46 __RCSID("$NetBSD: main.c,v 1.12 2001/11/01 16:31:48 tron Exp $");
47 #endif
48 #endif /* not lint */
49
50 #include <sys/types.h>
51
52 #include <err.h>
53 #include <errno.h>
54 #include <pwd.h>
55
56 #include "defs.h"
57
58 #define NHOSTS 100
59
60 /*
61 * Remote distribution program.
62 */
63
64 char *distfile = NULL;
65 #define _RDIST_TMP "/rdistXXXXXX"
66 char tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP + 1];
67 char *tempname;
68
69 int debug; /* debugging flag */
70 int nflag; /* NOP flag, just print commands without executing */
71 int qflag; /* Quiet. Don't print messages */
72 int options; /* global options */
73 int iamremote; /* act as remote server for transfering files */
74
75 FILE *fin = NULL; /* input file pointer */
76 int rem = -1; /* file descriptor to remote source/sink process */
77 char host[MAXHOSTNAMELEN + 1]; /* host name */
78 int nerrs; /* number of errors while sending/receiving */
79 char user[34]; /* user's name */
80 char homedir[PATH_MAX]; /* user's home directory */
81 uid_t userid; /* user's user ID */
82 gid_t groupid; /* user's group ID */
83
84 struct passwd *pw; /* pointer to static area used by getpwent */
85 struct group *gr; /* pointer to static area used by getgrent */
86
87 int main __P((int, char **));
88 static void usage __P((void));
89 static void docmdargs __P((int, char *[]));
90
91 int
92 main(argc, argv)
93 int argc;
94 char *argv[];
95 {
96 char *arg;
97 int cmdargs = 0;
98 char *dhosts[NHOSTS], **hp = dhosts;
99 int fd;
100
101 pw = getpwuid(userid = getuid());
102 if (pw == NULL) {
103 fprintf(stderr, "%s: Who are you?\n", argv[0]);
104 exit(1);
105 }
106 strcpy(user, pw->pw_name);
107 strcpy(homedir, pw->pw_dir);
108 groupid = pw->pw_gid;
109 gethostname(host, sizeof(host));
110 host[sizeof(host) - 1] = '\0';
111 strcpy(tempfile, _PATH_TMP);
112 strcat(tempfile, _RDIST_TMP);
113 if ((tempname = strrchr(tempfile, '/')) != 0)
114 tempname++;
115 else
116 tempname = tempfile;
117
118 while (--argc > 0) {
119 if ((arg = *++argv)[0] != '-')
120 break;
121 if (!strcmp(arg, "-Server"))
122 iamremote++;
123 else while (*++arg)
124 switch (*arg) {
125 case 'f':
126 if (--argc <= 0)
127 usage();
128 distfile = *++argv;
129 if (distfile[0] == '-' && distfile[1] == '\0')
130 fin = stdin;
131 break;
132
133 case 'm':
134 if (--argc <= 0)
135 usage();
136 if (hp >= &dhosts[NHOSTS-2]) {
137 fprintf(stderr, "rdist: too many destination hosts\n");
138 exit(1);
139 }
140 *hp++ = *++argv;
141 break;
142
143 case 'd':
144 if (--argc <= 0)
145 usage();
146 define(*++argv);
147 break;
148
149 case 'D':
150 debug++;
151 break;
152
153 case 'c':
154 cmdargs++;
155 break;
156
157 case 'n':
158 if (options & VERIFY) {
159 printf("rdist: -n overrides -v\n");
160 options &= ~VERIFY;
161 }
162 nflag++;
163 break;
164
165 case 'q':
166 qflag++;
167 break;
168
169 case 'b':
170 options |= COMPARE;
171 break;
172
173 case 'R':
174 options |= REMOVE;
175 break;
176
177 case 'v':
178 if (nflag) {
179 printf("rdist: -n overrides -v\n");
180 break;
181 }
182 options |= VERIFY;
183 break;
184
185 case 'w':
186 options |= WHOLE;
187 break;
188
189 case 'y':
190 options |= YOUNGER;
191 break;
192
193 case 'h':
194 options |= FOLLOW;
195 break;
196
197 case 'i':
198 options |= IGNLNKS;
199 break;
200
201 default:
202 usage();
203 }
204 }
205 *hp = NULL;
206
207 seteuid(userid);
208 fd = mkstemp(tempfile);
209 if (fd == -1)
210 err(1, "could not make a temporary file");
211 close (fd);
212
213 if (iamremote) {
214 server();
215 unlink(tempfile);
216 exit(nerrs != 0);
217 }
218
219 if (cmdargs)
220 docmdargs(argc, argv);
221 else {
222 if (fin == NULL) {
223 if (distfile == NULL) {
224 if ((fin = fopen("distfile","r")) == NULL)
225 fin = fopen("Distfile", "r");
226 } else
227 fin = fopen(distfile, "r");
228 if (fin == NULL) {
229 perror(distfile ? distfile : "distfile");
230 unlink(tempfile);
231 exit(1);
232 }
233 }
234 yyparse();
235 if (nerrs == 0)
236 docmds(dhosts, argc, argv);
237 }
238
239 unlink(tempfile);
240 exit(nerrs != 0);
241 }
242
243 static void
244 usage()
245 {
246 printf("Usage: rdist [-nqbRhivwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n");
247 printf("or: rdist [-nqbRhivwyD] -c source [...] machine[:dest]\n");
248 exit(1);
249 }
250
251 /*
252 * rcp like interface for distributing files.
253 */
254 static void
255 docmdargs(nargs, args)
256 int nargs;
257 char *args[];
258 {
259 struct namelist *nl, *prev;
260 char *cp;
261 struct namelist *files, *hosts;
262 struct subcmd *cmds;
263 char *dest;
264 static struct namelist tnl = { NULL, NULL };
265 int i;
266
267 if (nargs < 2)
268 usage();
269
270 files = NULL;
271 prev = NULL;
272 for (i = 0; i < nargs - 1; i++) {
273 nl = makenl(args[i]);
274 if (prev == NULL)
275 files = prev = nl;
276 else {
277 prev->n_next = nl;
278 prev = nl;
279 }
280 }
281
282 cp = args[i];
283 if ((dest = strchr(cp, ':')) != NULL)
284 *dest++ = '\0';
285 tnl.n_name = cp;
286 hosts = expand(&tnl, E_ALL);
287 if (nerrs)
288 return;
289
290 if (dest == NULL || *dest == '\0')
291 cmds = NULL;
292 else {
293 cmds = makesubcmd(INSTALL);
294 cmds->sc_options = options;
295 cmds->sc_name = dest;
296 }
297
298 if (debug) {
299 printf("docmdargs()\nfiles = ");
300 prnames(files);
301 printf("hosts = ");
302 prnames(hosts);
303 }
304 insert(NULL, files, hosts, cmds);
305 docmds(NULL, 0, NULL);
306 }
307
308 /*
309 * Print a list of NAME blocks (mostly for debugging).
310 */
311 void
312 prnames(nl)
313 struct namelist *nl;
314 {
315 printf("( ");
316 while (nl != NULL) {
317 printf("%s ", nl->n_name);
318 nl = nl->n_next;
319 }
320 printf(")\n");
321 }
322