fix multiple connections to same (down) host and loss of connection.
[unix-history] / usr / src / usr.bin / rdist / main.c
CommitLineData
29e83471 1#ifndef lint
0fccdfef 2static char *sccsid = "@(#)main.c 4.10 (Berkeley) 84/02/09";
29e83471
RC
3#endif
4
5#include "defs.h"
6
7/*
8 * Remote distribution program.
9 */
10
11char *distfile = "distfile";
d6bccb44 12char tmpfile[] = "/tmp/rdistXXXXXX";
82572cb6 13char *tmpname = &tmpfile[5];
29e83471
RC
14
15int debug; /* debugging flag */
16int nflag; /* NOP flag, just print commands without executing */
17int qflag; /* Quiet. Don't print messages */
f7770429 18int options; /* global options */
29e83471
RC
19int iamremote; /* act as remote server for transfering files */
20
21int filec; /* number of files to update */
22char **filev; /* list of files/directories to update */
23FILE *fin = NULL; /* input file pointer */
0fccdfef 24int rem = -1; /* file descriptor to remote source/sink process */
29e83471 25char host[32]; /* host name */
0fccdfef 26int nerrs; /* number of errors while sending/receiving */
29e83471
RC
27char user[10]; /* user's name */
28char homedir[128]; /* user's home directory */
29int userid; /* user's user ID */
82572cb6 30int groupid; /* user's group ID */
29e83471 31
e8109cf8
RC
32struct passwd *pw; /* pointer to static area used by getpwent */
33struct group *gr; /* pointer to static area used by getgrent */
34
29e83471
RC
35main(argc, argv)
36 int argc;
37 char *argv[];
38{
39 register char *arg;
f7770429 40 int cmdargs = 0;
29e83471 41
29e83471 42 pw = getpwuid(userid = getuid());
29e83471 43 if (pw == NULL) {
82572cb6 44 fprintf(stderr, "%s: Who are you?\n", argv[0]);
29e83471
RC
45 exit(1);
46 }
47 strcpy(user, pw->pw_name);
48 strcpy(homedir, pw->pw_dir);
82572cb6 49 groupid = pw->pw_gid;
29e83471
RC
50 gethostname(host, sizeof(host));
51
52 while (--argc > 0) {
53 if ((arg = *++argv)[0] != '-')
54 break;
55 if (!strcmp(arg, "-Server"))
56 iamremote++;
57 else while (*++arg)
58 switch (*arg) {
59 case 'f':
60 if (--argc <= 0)
61 usage();
62 distfile = *++argv;
63 if (distfile[0] == '-' && distfile[1] == '\0')
64 fin = stdin;
65 break;
66
67 case 'd':
82572cb6
RC
68 if (--argc <= 0)
69 usage();
70 define(*++argv);
71 break;
72
73 case 'D':
29e83471
RC
74 debug++;
75 break;
76
f7770429
RC
77 case 'c':
78 cmdargs++;
79 break;
80
29e83471 81 case 'n':
d6bccb44
RC
82 if (options & VERIFY) {
83 printf("rdist: -n overrides -v\n");
84 options &= ~VERIFY;
85 }
29e83471
RC
86 nflag++;
87 break;
88
89 case 'q':
90 qflag++;
91 break;
92
024fde5b
RC
93 case 'b':
94 options |= COMPARE;
95 break;
96
d6bccb44 97 case 'R':
d1dee8e8
RC
98 options |= REMOVE;
99 break;
100
29e83471 101 case 'v':
d6bccb44
RC
102 if (nflag) {
103 printf("rdist: -n overrides -v\n");
104 break;
105 }
f7770429
RC
106 options |= VERIFY;
107 break;
108
109 case 'w':
110 options |= WHOLE;
29e83471
RC
111 break;
112
113 case 'y':
f7770429 114 options |= YOUNGER;
29e83471
RC
115 break;
116
117 default:
118 usage();
119 }
120 }
82572cb6
RC
121
122 mktemp(tmpfile);
0fccdfef 123
29e83471
RC
124 if (iamremote) {
125 server();
0fccdfef 126 exit(nerrs);
29e83471 127 }
29e83471 128
f7770429
RC
129 if (cmdargs)
130 docmdargs(argc, argv);
131 else {
f7770429
RC
132 if (fin == NULL && (fin = fopen(distfile, "r")) == NULL) {
133 perror(distfile);
134 exit(1);
135 }
136 yyparse();
0fccdfef
RC
137 if (nerrs == 0)
138 docmds(argc, argv);
82572cb6
RC
139 }
140
0fccdfef 141 exit(nerrs);
29e83471
RC
142}
143
144usage()
145{
024fde5b
RC
146 printf("Usage: rdist [-nqbrvwyD] [-f distfile] [-d var=value] [file ...]\n");
147 printf("or: rdist [-nqbrvwyD] -c source [...] machine[:dest]\n");
82572cb6
RC
148 exit(1);
149}
150
f7770429
RC
151/*
152 * rcp like interface for distributing files.
153 */
154docmdargs(nargs, args)
155 int nargs;
156 char *args[];
157{
0fccdfef
RC
158 register struct namelist *nl, *prev;
159 register char *cp;
160 struct namelist *files, *hosts;
161 struct subcmd *cmds;
162 char *dest;
163 static struct namelist tnl = { NULL, NULL };
f7770429 164 int i;
f7770429
RC
165
166 if (nargs < 2)
167 usage();
168
169 prev = NULL;
0fccdfef
RC
170 for (i = 0; i < nargs - 1; i++) {
171 nl = makenl(args[i]);
172 if (prev == NULL)
173 files = prev = nl;
174 else {
175 prev->n_next = nl;
176 prev = nl;
177 }
f7770429
RC
178 }
179
0fccdfef
RC
180 cp = args[i];
181 if ((dest = index(cp, ':')) != NULL)
182 *dest++ = '\0';
183 tnl.n_name = cp;
184 hosts = expand(&tnl, E_ALL);
f7770429 185
0fccdfef 186 if (dest == NULL || *dest == '\0')
f7770429
RC
187 cmds = NULL;
188 else {
0fccdfef
RC
189 cmds = makesubcmd(INSTALL);
190 cmds->sc_options = options;
191 cmds->sc_name = dest;
f7770429
RC
192 }
193
194 if (debug) {
195 printf("docmdargs()\nfiles = ");
196 prnames(files);
197 printf("hosts = ");
198 prnames(hosts);
199 }
0fccdfef
RC
200 insert(files, hosts, cmds);
201 docmds(0, NULL);
29e83471
RC
202}
203
204/*
205 * Print a list of NAME blocks (mostly for debugging).
206 */
0fccdfef
RC
207prnames(nl)
208 register struct namelist *nl;
29e83471
RC
209{
210 printf("( ");
0fccdfef
RC
211 while (nl != NULL) {
212 printf("%s ", nl->n_name);
213 nl = nl->n_next;
29e83471
RC
214 }
215 printf(")\n");
216}
217
218/*VARARGS*/
219warn(fmt, a1, a2,a3)
220 char *fmt;
221{
222 extern int yylineno;
223
224 fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
225 fprintf(stderr, fmt, a1, a2, a3);
226 fputc('\n', stderr);
227}