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