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