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