xref: /csrg-svn/usr.bin/rdist/main.c (revision 15113)
114921Sralph #ifndef lint
2*15113Sralph static	char *sccsid = "@(#)main.c	4.2 (Berkeley) 83/09/27";
314921Sralph #endif
414921Sralph 
514921Sralph #include "defs.h"
614921Sralph 
714921Sralph /*
814921Sralph  * Remote distribution program.
914921Sralph  */
1014921Sralph 
1114921Sralph char	*distfile = "distfile";
12*15113Sralph char	tmpfile[] = "/tmp/rdistAXXXXXX";
13*15113Sralph char	*tmpname = &tmpfile[5];
14*15113Sralph char	*tmpinc = &tmpfile[10];
1514921Sralph 
1614921Sralph int	debug;		/* debugging flag */
1714921Sralph int	nflag;		/* NOP flag, just print commands without executing */
1814921Sralph int	qflag;		/* Quiet. Don't print messages */
1914921Sralph int	vflag;		/* verify only */
2014921Sralph int	yflag;		/* update iff remote younger than master */
2114921Sralph int	iamremote;	/* act as remote server for transfering files */
2214921Sralph 
2314921Sralph int	filec;		/* number of files to update */
2414921Sralph char	**filev;	/* list of files/directories to update */
2514921Sralph FILE	*fin = NULL;	/* input file pointer */
2614921Sralph int	rem = 0;	/* file descriptor to remote source/sink process */
2714921Sralph char	host[32];	/* host name */
2814921Sralph int	errs;		/* number of errors while sending/receiving */
2914921Sralph char	user[10];	/* user's name */
3014921Sralph char	homedir[128];	/* user's home directory */
3114921Sralph int	userid;		/* user's user ID */
32*15113Sralph int	groupid;	/* user's group ID */
33*15113Sralph int	iamupdate;
3414921Sralph 
3514921Sralph int	cleanup();
3614921Sralph int	lostconn();
3714921Sralph 
3814921Sralph main(argc, argv)
3914921Sralph 	int argc;
4014921Sralph 	char *argv[];
4114921Sralph {
4214921Sralph 	register char *arg;
4314921Sralph 	register struct	passwd *pw;
4414921Sralph 
45*15113Sralph 	arg = rindex(argv[0], '/');
46*15113Sralph 	if (arg == NULL)
47*15113Sralph 		arg = argv[0];
48*15113Sralph 	else
49*15113Sralph 		arg++;
50*15113Sralph 	if (!strcmp(arg, "update"))
51*15113Sralph 		iamupdate++;
52*15113Sralph 
5314921Sralph 	pw = getpwuid(userid = getuid());
5414921Sralph 	if (pw == NULL) {
55*15113Sralph 		fprintf(stderr, "%s: Who are you?\n", argv[0]);
5614921Sralph 		exit(1);
5714921Sralph 	}
5814921Sralph 	strcpy(user, pw->pw_name);
5914921Sralph 	strcpy(homedir, pw->pw_dir);
60*15113Sralph 	groupid = pw->pw_gid;
6114921Sralph 	gethostname(host, sizeof(host));
6214921Sralph 
6314921Sralph 	while (--argc > 0) {
6414921Sralph 		if ((arg = *++argv)[0] != '-')
6514921Sralph 			break;
6614921Sralph 		if (!strcmp(arg, "-Server"))
6714921Sralph 			iamremote++;
6814921Sralph 		else while (*++arg)
6914921Sralph 			switch (*arg) {
7014921Sralph 			case 'f':
7114921Sralph 				if (--argc <= 0)
7214921Sralph 					usage();
7314921Sralph 				distfile = *++argv;
7414921Sralph 				if (distfile[0] == '-' && distfile[1] == '\0')
7514921Sralph 					fin = stdin;
7614921Sralph 				break;
7714921Sralph 
7814921Sralph 			case 'd':
79*15113Sralph 				if (--argc <= 0)
80*15113Sralph 					usage();
81*15113Sralph 				define(*++argv);
82*15113Sralph 				break;
83*15113Sralph 
84*15113Sralph 			case 'D':
8514921Sralph 				debug++;
8614921Sralph 				break;
8714921Sralph 
8814921Sralph 			case 'n':
8914921Sralph 				nflag++;
9014921Sralph 				break;
9114921Sralph 
9214921Sralph 			case 'q':
9314921Sralph 				qflag++;
9414921Sralph 				break;
9514921Sralph 
9614921Sralph 			case 'v':
9714921Sralph 				vflag++;
9814921Sralph 				break;
9914921Sralph 
10014921Sralph 			case 'y':
10114921Sralph 				yflag++;
10214921Sralph 				break;
10314921Sralph 
10414921Sralph 			default:
10514921Sralph 				usage();
10614921Sralph 			}
10714921Sralph 	}
108*15113Sralph 
109*15113Sralph 	mktemp(tmpfile);
11014921Sralph 	signal(SIGPIPE, lostconn);
11114921Sralph 	if (iamremote) {
11214921Sralph 		server();
11314921Sralph 		exit(errs);
11414921Sralph 	}
11514921Sralph 
11614921Sralph 	signal(SIGHUP, cleanup);
11714921Sralph 	signal(SIGINT, cleanup);
11814921Sralph 	signal(SIGQUIT, cleanup);
11914921Sralph 	signal(SIGTERM, cleanup);
12014921Sralph 
121*15113Sralph 	if (iamupdate)
122*15113Sralph 		doupdate(argc, argv);
123*15113Sralph 	else {
124*15113Sralph 		filec = argc;
125*15113Sralph 		filev = argv;
126*15113Sralph 		if (fin == NULL && (fin = fopen(distfile, "r")) == NULL) {
127*15113Sralph 			perror(distfile);
128*15113Sralph 			exit(1);
129*15113Sralph 		}
130*15113Sralph 		yyparse();
131*15113Sralph 	}
132*15113Sralph 
13314921Sralph 	exit(errs);
13414921Sralph }
13514921Sralph 
13614921Sralph usage()
13714921Sralph {
138*15113Sralph 	printf("Usage: rdist [-f distfile] [-d var=value] [-nqyD] [file ...]\n");
13914921Sralph 	exit(1);
14014921Sralph }
14114921Sralph 
14214921Sralph /*
143*15113Sralph  * rcp like interface for distributing files.
144*15113Sralph  */
145*15113Sralph doupdate(nargs, args)
146*15113Sralph 	int nargs;
147*15113Sralph 	char *args[];
148*15113Sralph {
149*15113Sralph 	struct block *bp, *files, *hosts, *cmds, *prev;
150*15113Sralph 	int i, firsttime = 1;
151*15113Sralph 	char *pos, dest[BUFSIZ];
152*15113Sralph 
153*15113Sralph 	if (nargs < 2)
154*15113Sralph 		upusage();
155*15113Sralph 
156*15113Sralph 	prev = NULL;
157*15113Sralph 	bp = files = ALLOC(block);
158*15113Sralph 	for (i = 0; i < nargs - 1; bp = ALLOC(block), i++) {
159*15113Sralph 		bp->b_type = NAME;
160*15113Sralph 		bp->b_name = args[i];
161*15113Sralph 		if (prev != NULL)
162*15113Sralph 			prev->b_next = bp;
163*15113Sralph 		bp->b_next = bp->b_args = NULL;
164*15113Sralph 		prev = bp;
165*15113Sralph 	}
166*15113Sralph 
167*15113Sralph 	hosts = ALLOC(block);
168*15113Sralph 	hosts->b_type = NAME;
169*15113Sralph 	hosts->b_name = args[i];
170*15113Sralph 	hosts->b_name = args[i];
171*15113Sralph 	hosts->b_next = hosts->b_args = NULL;
172*15113Sralph 	if ((pos = index(hosts->b_name, ':')) != NULL) {
173*15113Sralph 		*pos++ = '\0';
174*15113Sralph 		strcpy(dest, pos);
175*15113Sralph 	} else
176*15113Sralph 		dest[0] = '\0';
177*15113Sralph 
178*15113Sralph 	hosts = expand(hosts, 0);
179*15113Sralph 
180*15113Sralph 	if (dest[0] == '\0')
181*15113Sralph 		cmds = NULL;
182*15113Sralph 	else {
183*15113Sralph 		cmds = ALLOC(block);
184*15113Sralph 		if (vflag)
185*15113Sralph 			cmds->b_type = VERIFY;
186*15113Sralph 		else
187*15113Sralph 			cmds->b_type = INSTALL;
188*15113Sralph 		cmds->b_name = dest;
189*15113Sralph 		cmds->b_next = cmds->b_args = NULL;
190*15113Sralph 	}
191*15113Sralph 
192*15113Sralph 	if (debug) {
193*15113Sralph 		printf("doupdate()\nfiles = ");
194*15113Sralph 		prnames(files);
195*15113Sralph 		printf("hosts = ");
196*15113Sralph 		prnames(hosts);
197*15113Sralph 	}
198*15113Sralph 	dohcmds(files, hosts, cmds);
199*15113Sralph }
200*15113Sralph 
201*15113Sralph upusage()
202*15113Sralph {
203*15113Sralph 	printf("Usage: update [-nqyD] source [...] machine[:dest]\n");
204*15113Sralph 	exit(1);
205*15113Sralph }
206*15113Sralph 
207*15113Sralph /*
20814921Sralph  * Remove temporary files and do any cleanup operations before exiting.
20914921Sralph  */
21014921Sralph cleanup()
21114921Sralph {
21214921Sralph 	(void) unlink(tmpfile);
21314921Sralph 	exit(1);
21414921Sralph }
21514921Sralph 
21614921Sralph /*
21714921Sralph  * Print a list of NAME blocks (mostly for debugging).
21814921Sralph  */
21914921Sralph prnames(bp)
22014921Sralph 	register struct block *bp;
22114921Sralph {
22214921Sralph 	printf("( ");
22314921Sralph 	while (bp != NULL) {
22414921Sralph 		printf("%s ", bp->b_name);
22514921Sralph 		bp = bp->b_next;
22614921Sralph 	}
22714921Sralph 	printf(")\n");
22814921Sralph }
22914921Sralph 
23014921Sralph /*VARARGS*/
23114921Sralph warn(fmt, a1, a2,a3)
23214921Sralph 	char *fmt;
23314921Sralph {
23414921Sralph 	extern int yylineno;
23514921Sralph 
23614921Sralph 	fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
23714921Sralph 	fprintf(stderr, fmt, a1, a2, a3);
23814921Sralph 	fputc('\n', stderr);
23914921Sralph }
240