xref: /original-bsd/usr.bin/rdist/main.c (revision 00986467)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)main.c	5.3 (Berkeley) 06/29/88";
26 #endif /* not lint */
27 
28 #include "defs.h"
29 
30 #define NHOSTS 100
31 
32 /*
33  * Remote distribution program.
34  */
35 
36 char	*distfile = NULL;
37 char	tmpfile[] = "/tmp/rdistXXXXXX";
38 char	*tmpname = &tmpfile[5];
39 
40 int	debug;		/* debugging flag */
41 int	nflag;		/* NOP flag, just print commands without executing */
42 int	qflag;		/* Quiet. Don't print messages */
43 int	options;	/* global options */
44 int	iamremote;	/* act as remote server for transfering files */
45 
46 FILE	*fin = NULL;	/* input file pointer */
47 int	rem = -1;	/* file descriptor to remote source/sink process */
48 char	host[32];	/* host name */
49 int	nerrs;		/* number of errors while sending/receiving */
50 char	user[10];	/* user's name */
51 char	homedir[128];	/* user's home directory */
52 int	userid;		/* user's user ID */
53 int	groupid;	/* user's group ID */
54 
55 struct	passwd *pw;	/* pointer to static area used by getpwent */
56 struct	group *gr;	/* pointer to static area used by getgrent */
57 
58 main(argc, argv)
59 	int argc;
60 	char *argv[];
61 {
62 	register char *arg;
63 	int cmdargs = 0;
64 	char *dhosts[NHOSTS], **hp = dhosts;
65 
66 	pw = getpwuid(userid = getuid());
67 	if (pw == NULL) {
68 		fprintf(stderr, "%s: Who are you?\n", argv[0]);
69 		exit(1);
70 	}
71 	strcpy(user, pw->pw_name);
72 	strcpy(homedir, pw->pw_dir);
73 	groupid = pw->pw_gid;
74 	gethostname(host, sizeof(host));
75 
76 	while (--argc > 0) {
77 		if ((arg = *++argv)[0] != '-')
78 			break;
79 		if (!strcmp(arg, "-Server"))
80 			iamremote++;
81 		else while (*++arg)
82 			switch (*arg) {
83 			case 'f':
84 				if (--argc <= 0)
85 					usage();
86 				distfile = *++argv;
87 				if (distfile[0] == '-' && distfile[1] == '\0')
88 					fin = stdin;
89 				break;
90 
91 			case 'm':
92 				if (--argc <= 0)
93 					usage();
94 				if (hp >= &dhosts[NHOSTS-2]) {
95 					fprintf(stderr, "rdist: too many destination hosts\n");
96 					exit(1);
97 				}
98 				*hp++ = *++argv;
99 				break;
100 
101 			case 'd':
102 				if (--argc <= 0)
103 					usage();
104 				define(*++argv);
105 				break;
106 
107 			case 'D':
108 				debug++;
109 				break;
110 
111 			case 'c':
112 				cmdargs++;
113 				break;
114 
115 			case 'n':
116 				if (options & VERIFY) {
117 					printf("rdist: -n overrides -v\n");
118 					options &= ~VERIFY;
119 				}
120 				nflag++;
121 				break;
122 
123 			case 'q':
124 				qflag++;
125 				break;
126 
127 			case 'b':
128 				options |= COMPARE;
129 				break;
130 
131 			case 'R':
132 				options |= REMOVE;
133 				break;
134 
135 			case 'v':
136 				if (nflag) {
137 					printf("rdist: -n overrides -v\n");
138 					break;
139 				}
140 				options |= VERIFY;
141 				break;
142 
143 			case 'w':
144 				options |= WHOLE;
145 				break;
146 
147 			case 'y':
148 				options |= YOUNGER;
149 				break;
150 
151 			case 'h':
152 				options |= FOLLOW;
153 				break;
154 
155 			case 'i':
156 				options |= IGNLNKS;
157 				break;
158 
159 			default:
160 				usage();
161 			}
162 	}
163 	*hp = NULL;
164 
165 	setreuid(0, userid);
166 	mktemp(tmpfile);
167 
168 	if (iamremote) {
169 		server();
170 		exit(nerrs != 0);
171 	}
172 
173 	if (cmdargs)
174 		docmdargs(argc, argv);
175 	else {
176 		if (fin == NULL) {
177 			if(distfile == NULL) {
178 				if((fin = fopen("distfile","r")) == NULL)
179 					fin = fopen("Distfile", "r");
180 			} else
181 				fin = fopen(distfile, "r");
182 			if(fin == NULL) {
183 				perror(distfile ? distfile : "distfile");
184 				exit(1);
185 			}
186 		}
187 		yyparse();
188 		if (nerrs == 0)
189 			docmds(dhosts, argc, argv);
190 	}
191 
192 	exit(nerrs != 0);
193 }
194 
195 usage()
196 {
197 	printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n");
198 	printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n");
199 	exit(1);
200 }
201 
202 /*
203  * rcp like interface for distributing files.
204  */
205 docmdargs(nargs, args)
206 	int nargs;
207 	char *args[];
208 {
209 	register struct namelist *nl, *prev;
210 	register char *cp;
211 	struct namelist *files, *hosts;
212 	struct subcmd *cmds;
213 	char *dest;
214 	static struct namelist tnl = { NULL, NULL };
215 	int i;
216 
217 	if (nargs < 2)
218 		usage();
219 
220 	prev = NULL;
221 	for (i = 0; i < nargs - 1; i++) {
222 		nl = makenl(args[i]);
223 		if (prev == NULL)
224 			files = prev = nl;
225 		else {
226 			prev->n_next = nl;
227 			prev = nl;
228 		}
229 	}
230 
231 	cp = args[i];
232 	if ((dest = index(cp, ':')) != NULL)
233 		*dest++ = '\0';
234 	tnl.n_name = cp;
235 	hosts = expand(&tnl, E_ALL);
236 	if (nerrs)
237 		exit(1);
238 
239 	if (dest == NULL || *dest == '\0')
240 		cmds = NULL;
241 	else {
242 		cmds = makesubcmd(INSTALL);
243 		cmds->sc_options = options;
244 		cmds->sc_name = dest;
245 	}
246 
247 	if (debug) {
248 		printf("docmdargs()\nfiles = ");
249 		prnames(files);
250 		printf("hosts = ");
251 		prnames(hosts);
252 	}
253 	insert(NULL, files, hosts, cmds);
254 	docmds(NULL, 0, NULL);
255 }
256 
257 /*
258  * Print a list of NAME blocks (mostly for debugging).
259  */
260 prnames(nl)
261 	register struct namelist *nl;
262 {
263 	printf("( ");
264 	while (nl != NULL) {
265 		printf("%s ", nl->n_name);
266 		nl = nl->n_next;
267 	}
268 	printf(")\n");
269 }
270 
271 /*VARARGS*/
272 warn(fmt, a1, a2,a3)
273 	char *fmt;
274 {
275 	extern int yylineno;
276 
277 	fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
278 	fprintf(stderr, fmt, a1, a2, a3);
279 	fputc('\n', stderr);
280 }
281