1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char copyright[] = 36 "@(#) Copyright (c) 1983, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/9/93"; 42 #endif /* not lint */ 43 44 #include "defs.h" 45 46 #define NHOSTS 100 47 48 /* 49 * Remote distribution program. 50 */ 51 52 char *distfile = NULL; 53 #define _RDIST_TMP "/rdistXXXXXX" 54 char tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP + 1]; 55 char *tempname; 56 57 int debug; /* debugging flag */ 58 int nflag; /* NOP flag, just print commands without executing */ 59 int qflag; /* Quiet. Don't print messages */ 60 int options; /* global options */ 61 int iamremote; /* act as remote server for transfering files */ 62 63 FILE *fin = NULL; /* input file pointer */ 64 int rem = -1; /* file descriptor to remote source/sink process */ 65 char host[32]; /* host name */ 66 int nerrs; /* number of errors while sending/receiving */ 67 char user[10]; /* user's name */ 68 char homedir[128]; /* user's home directory */ 69 int userid; /* user's user ID */ 70 int groupid; /* user's group ID */ 71 72 struct passwd *pw; /* pointer to static area used by getpwent */ 73 struct group *gr; /* pointer to static area used by getgrent */ 74 75 static void usage __P((void)); 76 static void docmdargs __P((int, char *[])); 77 78 int 79 main(argc, argv) 80 int argc; 81 char *argv[]; 82 { 83 register char *arg; 84 int cmdargs = 0; 85 char *dhosts[NHOSTS], **hp = dhosts; 86 87 pw = getpwuid(userid = getuid()); 88 if (pw == NULL) { 89 fprintf(stderr, "%s: Who are you?\n", argv[0]); 90 exit(1); 91 } 92 strcpy(user, pw->pw_name); 93 strcpy(homedir, pw->pw_dir); 94 groupid = pw->pw_gid; 95 gethostname(host, sizeof(host)); 96 strcpy(tempfile, _PATH_TMP); 97 strcat(tempfile, _RDIST_TMP); 98 if ((tempname = rindex(tempfile, '/')) != 0) 99 tempname++; 100 else 101 tempname = tempfile; 102 103 while (--argc > 0) { 104 if ((arg = *++argv)[0] != '-') 105 break; 106 if (!strcmp(arg, "-Server")) 107 iamremote++; 108 else while (*++arg) 109 switch (*arg) { 110 case 'f': 111 if (--argc <= 0) 112 usage(); 113 distfile = *++argv; 114 if (distfile[0] == '-' && distfile[1] == '\0') 115 fin = stdin; 116 break; 117 118 case 'm': 119 if (--argc <= 0) 120 usage(); 121 if (hp >= &dhosts[NHOSTS-2]) { 122 fprintf(stderr, "rdist: too many destination hosts\n"); 123 exit(1); 124 } 125 *hp++ = *++argv; 126 break; 127 128 case 'd': 129 if (--argc <= 0) 130 usage(); 131 define(*++argv); 132 break; 133 134 case 'D': 135 debug++; 136 break; 137 138 case 'c': 139 cmdargs++; 140 break; 141 142 case 'n': 143 if (options & VERIFY) { 144 printf("rdist: -n overrides -v\n"); 145 options &= ~VERIFY; 146 } 147 nflag++; 148 break; 149 150 case 'q': 151 qflag++; 152 break; 153 154 case 'b': 155 options |= COMPARE; 156 break; 157 158 case 'R': 159 options |= REMOVE; 160 break; 161 162 case 'v': 163 if (nflag) { 164 printf("rdist: -n overrides -v\n"); 165 break; 166 } 167 options |= VERIFY; 168 break; 169 170 case 'w': 171 options |= WHOLE; 172 break; 173 174 case 'y': 175 options |= YOUNGER; 176 break; 177 178 case 'h': 179 options |= FOLLOW; 180 break; 181 182 case 'i': 183 options |= IGNLNKS; 184 break; 185 186 default: 187 usage(); 188 } 189 } 190 *hp = NULL; 191 192 seteuid(userid); 193 mktemp(tempfile); 194 195 if (iamremote) { 196 server(); 197 exit(nerrs != 0); 198 } 199 200 if (cmdargs) 201 docmdargs(argc, argv); 202 else { 203 if (fin == NULL) { 204 if(distfile == NULL) { 205 if((fin = fopen("distfile","r")) == NULL) 206 fin = fopen("Distfile", "r"); 207 } else 208 fin = fopen(distfile, "r"); 209 if(fin == NULL) { 210 perror(distfile ? distfile : "distfile"); 211 exit(1); 212 } 213 } 214 yyparse(); 215 if (nerrs == 0) 216 docmds(dhosts, argc, argv); 217 } 218 219 exit(nerrs != 0); 220 } 221 222 static void 223 usage() 224 { 225 printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n"); 226 printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n"); 227 exit(1); 228 } 229 230 /* 231 * rcp like interface for distributing files. 232 */ 233 static void 234 docmdargs(nargs, args) 235 int nargs; 236 char *args[]; 237 { 238 register struct namelist *nl, *prev; 239 register char *cp; 240 struct namelist *files, *hosts; 241 struct subcmd *cmds; 242 char *dest; 243 static struct namelist tnl = { NULL, NULL }; 244 int i; 245 246 if (nargs < 2) 247 usage(); 248 249 prev = NULL; 250 for (i = 0; i < nargs - 1; i++) { 251 nl = makenl(args[i]); 252 if (prev == NULL) 253 files = prev = nl; 254 else { 255 prev->n_next = nl; 256 prev = nl; 257 } 258 } 259 260 cp = args[i]; 261 if ((dest = index(cp, ':')) != NULL) 262 *dest++ = '\0'; 263 tnl.n_name = cp; 264 hosts = expand(&tnl, E_ALL); 265 if (nerrs) 266 exit(1); 267 268 if (dest == NULL || *dest == '\0') 269 cmds = NULL; 270 else { 271 cmds = makesubcmd(INSTALL); 272 cmds->sc_options = options; 273 cmds->sc_name = dest; 274 } 275 276 if (debug) { 277 printf("docmdargs()\nfiles = "); 278 prnames(files); 279 printf("hosts = "); 280 prnames(hosts); 281 } 282 insert(NULL, files, hosts, cmds); 283 docmds(NULL, 0, NULL); 284 } 285 286 /* 287 * Print a list of NAME blocks (mostly for debugging). 288 */ 289 void 290 prnames(nl) 291 register struct namelist *nl; 292 { 293 printf("( "); 294 while (nl != NULL) { 295 printf("%s ", nl->n_name); 296 nl = nl->n_next; 297 } 298 printf(")\n"); 299 } 300 301 #if __STDC__ 302 #include <stdarg.h> 303 #else 304 #include <varargs.h> 305 #endif 306 307 void 308 #if __STDC__ 309 warn(const char *fmt, ...) 310 #else 311 warn(fmt, va_alist) 312 char *fmt; 313 va_dcl 314 #endif 315 { 316 extern int yylineno; 317 va_list ap; 318 #if __STDC__ 319 va_start(ap, fmt); 320 #else 321 va_start(ap); 322 #endif 323 (void)fprintf(stderr, "rdist: line %d: Warning: ", yylineno); 324 (void)vfprintf(stderr, fmt, ap); 325 (void)fprintf(stderr, "\n"); 326 va_end(ap); 327 } 328