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