6cedc84d696744a7caa0a4df8156467f8092babb
[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  * @(#) Copyright (c) 1983, 1993 The Regents of the University of California.  All rights reserved.
34  * @(#)main.c   8.1 (Berkeley) 6/9/93
35  * $FreeBSD: src/usr.bin/rdist/main.c,v 1.5 1999/08/28 01:05:07 peter Exp $
36  * $DragonFly: src/usr.bin/rdist/main.c,v 1.2 2003/06/17 04:29:30 dillon Exp $
37  */
38
39 #include "defs.h"
40
41 #define NHOSTS 100
42
43 /*
44  * Remote distribution program.
45  */
46
47 char    *distfile = NULL;
48 #define _RDIST_TMP      "/rdistXXXXXX"
49 char    tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP + 1];
50 char    *tempname;
51
52 int     debug;          /* debugging flag */
53 int     nflag;          /* NOP flag, just print commands without executing */
54 int     qflag;          /* Quiet. Don't print messages */
55 int     options;        /* global options */
56 int     iamremote;      /* act as remote server for transfering files */
57
58 FILE    *fin = NULL;    /* input file pointer */
59 int     rem = -1;       /* file descriptor to remote source/sink process */
60 char    host[32];       /* host name */
61 int     nerrs;          /* number of errors while sending/receiving */
62 char    user[10];       /* user's name */
63 char    homedir[128];   /* user's home directory */
64 int     userid;         /* user's user ID */
65 int     groupid;        /* user's group ID */
66 char    *path_rsh = _PATH_RSH;  /* rsh (or equiv command) path */
67
68 struct  passwd *pw;     /* pointer to static area used by getpwent */
69 struct  group *gr;      /* pointer to static area used by getgrent */
70
71 static void usage __P((void));
72 static void docmdargs __P((int, char *[]));
73
74 int
75 main(argc, argv)
76         int argc;
77         char *argv[];
78 {
79         register char *arg;
80         int cmdargs = 0;
81         char *dhosts[NHOSTS], **hp = dhosts;
82
83         pw = getpwuid(userid = getuid());
84         if (pw == NULL) {
85                 fprintf(stderr, "%s: Who are you?\n", argv[0]);
86                 exit(1);
87         }
88         strcpy(user, pw->pw_name);
89         strcpy(homedir, pw->pw_dir);
90         groupid = pw->pw_gid;
91         gethostname(host, sizeof(host));
92         strcpy(tempfile, _PATH_TMP);
93         strcat(tempfile, _RDIST_TMP);
94         if ((tempname = rindex(tempfile, '/')) != 0)
95                 tempname++;
96         else
97                 tempname = tempfile;
98
99         while (--argc > 0) {
100                 if ((arg = *++argv)[0] != '-')
101                         break;
102                 if (!strcmp(arg, "-Server"))
103                         iamremote++;
104                 else while (*++arg)
105                         switch (*arg) {
106                         case 'P':
107                                 if (--argc <= 0)
108                                         usage();
109                                 path_rsh = *++argv;
110                                 break;
111
112                         case 'f':
113                                 if (--argc <= 0)
114                                         usage();
115                                 distfile = *++argv;
116                                 if (distfile[0] == '-' && distfile[1] == '\0')
117                                         fin = stdin;
118                                 break;
119
120                         case 'm':
121                                 if (--argc <= 0)
122                                         usage();
123                                 if (hp >= &dhosts[NHOSTS-2]) {
124                                         fprintf(stderr, "rdist: too many destination hosts\n");
125                                         exit(1);
126                                 }
127                                 *hp++ = *++argv;
128                                 break;
129
130                         case 'd':
131                                 if (--argc <= 0)
132                                         usage();
133                                 define(*++argv);
134                                 break;
135
136                         case 'D':
137                                 debug++;
138                                 break;
139
140                         case 'c':
141                                 cmdargs++;
142                                 break;
143
144                         case 'n':
145                                 if (options & VERIFY) {
146                                         printf("rdist: -n overrides -v\n");
147                                         options &= ~VERIFY;
148                                 }
149                                 nflag++;
150                                 break;
151
152                         case 'q':
153                                 qflag++;
154                                 break;
155
156                         case 'b':
157                                 options |= COMPARE;
158                                 break;
159
160                         case 'R':
161                                 options |= REMOVE;
162                                 break;
163
164                         case 'v':
165                                 if (nflag) {
166                                         printf("rdist: -n overrides -v\n");
167                                         break;
168                                 }
169                                 options |= VERIFY;
170                                 break;
171
172                         case 'w':
173                                 options |= WHOLE;
174                                 break;
175
176                         case 'y':
177                                 options |= YOUNGER;
178                                 break;
179
180                         case 'h':
181                                 options |= FOLLOW;
182                                 break;
183
184                         case 'i':
185                                 options |= IGNLNKS;
186                                 break;
187
188                         default:
189                                 usage();
190                         }
191         }
192         *hp = NULL;
193
194         seteuid(userid);
195         mktemp(tempfile);
196
197         if (iamremote) {
198                 server();
199                 exit(nerrs != 0);
200         }
201
202         if (cmdargs)
203                 docmdargs(argc, argv);
204         else {
205                 if (fin == NULL) {
206                         if(distfile == NULL) {
207                                 if((fin = fopen("distfile","r")) == NULL)
208                                         fin = fopen("Distfile", "r");
209                         } else
210                                 fin = fopen(distfile, "r");
211                         if(fin == NULL) {
212                                 perror(distfile ? distfile : "distfile");
213                                 exit(1);
214                         }
215                 }
216                 yyparse();
217                 if (nerrs == 0)
218                         docmds(dhosts, argc, argv);
219         }
220
221         exit(nerrs != 0);
222 }
223
224 static void
225 usage()
226 {
227         printf("%s\n%s\n%s\n",
228 "usage: rdist [-nqbhirvwyD] [-P /path/to/rsh ] [-f distfile] [-d var=value]",
229 "             [-m host] [file ...]",
230 "       rdist [-nqbhirvwyD] [-P /path/to/rsh ] -c source [...] machine[:dest]");
231         exit(1);
232 }
233
234 /*
235  * rcp like interface for distributing files.
236  */
237 static void
238 docmdargs(nargs, args)
239         int nargs;
240         char *args[];
241 {
242         register struct namelist *nl, *prev;
243         register char *cp;
244         struct namelist *files = NULL, *hosts;
245         struct subcmd *cmds;
246         char *dest;
247         static struct namelist tnl = { NULL, NULL };
248         int i;
249
250         if (nargs < 2)
251                 usage();
252
253         prev = NULL;
254         for (i = 0; i < nargs - 1; i++) {
255                 nl = makenl(args[i]);
256                 if (prev == NULL)
257                         files = prev = nl;
258                 else {
259                         prev->n_next = nl;
260                         prev = nl;
261                 }
262         }
263
264         cp = args[i];
265         if ((dest = index(cp, ':')) != NULL)
266                 *dest++ = '\0';
267         tnl.n_name = cp;
268         hosts = expand(&tnl, E_ALL);
269         if (nerrs)
270                 exit(1);
271
272         if (dest == NULL || *dest == '\0')
273                 cmds = NULL;
274         else {
275                 cmds = makesubcmd(INSTALL);
276                 cmds->sc_options = options;
277                 cmds->sc_name = dest;
278         }
279
280         if (debug) {
281                 printf("docmdargs()\nfiles = ");
282                 prnames(files);
283                 printf("hosts = ");
284                 prnames(hosts);
285         }
286         insert(NULL, files, hosts, cmds);
287         docmds(NULL, 0, NULL);
288 }
289
290 /*
291  * Print a list of NAME blocks (mostly for debugging).
292  */
293 void
294 prnames(nl)
295         register struct namelist *nl;
296 {
297         printf("( ");
298         while (nl != NULL) {
299                 printf("%s ", nl->n_name);
300                 nl = nl->n_next;
301         }
302         printf(")\n");
303 }
304
305 #if __STDC__
306 #include <stdarg.h>
307 #else
308 #include <varargs.h>
309 #endif
310
311 void
312 #if __STDC__
313 warn(const char *fmt, ...)
314 #else
315 warn(fmt, va_alist)
316         char *fmt;
317         va_dcl
318 #endif
319 {
320         extern int yylineno;
321         va_list ap;
322 #if __STDC__
323         va_start(ap, fmt);
324 #else
325         va_start(ap);
326 #endif
327         (void)fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
328         (void)vfprintf(stderr, fmt, ap);
329         (void)fprintf(stderr, "\n");
330         va_end(ap);
331 }