1 /* $NetBSD: main.c,v 1.9 1999/01/31 10:02:25 mrg 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 #include <sys/cdefs.h> 37 #ifndef lint 38 __COPYRIGHT("@(#) 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 __RCSID("$NetBSD: main.c,v 1.9 1999/01/31 10:02:25 mrg Exp $"); 47 #endif 48 #endif /* not lint */ 49 50 #include <sys/types.h> 51 52 #include <errno.h> 53 #include <pwd.h> 54 55 #include "defs.h" 56 57 #define NHOSTS 100 58 59 /* 60 * Remote distribution program. 61 */ 62 63 char *distfile = NULL; 64 #define _RDIST_TMP "/rdistXXXXXX" 65 char tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP + 1]; 66 char *tempname; 67 68 int debug; /* debugging flag */ 69 int nflag; /* NOP flag, just print commands without executing */ 70 int qflag; /* Quiet. Don't print messages */ 71 int options; /* global options */ 72 int iamremote; /* act as remote server for transfering files */ 73 74 FILE *fin = NULL; /* input file pointer */ 75 int rem = -1; /* file descriptor to remote source/sink process */ 76 char host[MAXHOSTNAMELEN + 1]; /* host name */ 77 int nerrs; /* number of errors while sending/receiving */ 78 char user[34]; /* user's name */ 79 char homedir[PATH_MAX]; /* user's home directory */ 80 uid_t userid; /* user's user ID */ 81 gid_t groupid; /* user's group ID */ 82 83 struct passwd *pw; /* pointer to static area used by getpwent */ 84 struct group *gr; /* pointer to static area used by getgrent */ 85 86 int main __P((int, char **)); 87 static void usage __P((void)); 88 static void docmdargs __P((int, char *[])); 89 90 int 91 main(argc, argv) 92 int argc; 93 char *argv[]; 94 { 95 char *arg; 96 int cmdargs = 0; 97 char *dhosts[NHOSTS], **hp = dhosts; 98 99 pw = getpwuid(userid = getuid()); 100 if (pw == NULL) { 101 fprintf(stderr, "%s: Who are you?\n", argv[0]); 102 exit(1); 103 } 104 strcpy(user, pw->pw_name); 105 strcpy(homedir, pw->pw_dir); 106 groupid = pw->pw_gid; 107 gethostname(host, sizeof(host)); 108 host[sizeof(host) - 1] = '\0'; 109 strcpy(tempfile, _PATH_TMP); 110 strcat(tempfile, _RDIST_TMP); 111 if ((tempname = strrchr(tempfile, '/')) != 0) 112 tempname++; 113 else 114 tempname = tempfile; 115 116 while (--argc > 0) { 117 if ((arg = *++argv)[0] != '-') 118 break; 119 if (!strcmp(arg, "-Server")) 120 iamremote++; 121 else while (*++arg) 122 switch (*arg) { 123 case 'f': 124 if (--argc <= 0) 125 usage(); 126 distfile = *++argv; 127 if (distfile[0] == '-' && distfile[1] == '\0') 128 fin = stdin; 129 break; 130 131 case 'm': 132 if (--argc <= 0) 133 usage(); 134 if (hp >= &dhosts[NHOSTS-2]) { 135 fprintf(stderr, "rdist: too many destination hosts\n"); 136 exit(1); 137 } 138 *hp++ = *++argv; 139 break; 140 141 case 'd': 142 if (--argc <= 0) 143 usage(); 144 define(*++argv); 145 break; 146 147 case 'D': 148 debug++; 149 break; 150 151 case 'c': 152 cmdargs++; 153 break; 154 155 case 'n': 156 if (options & VERIFY) { 157 printf("rdist: -n overrides -v\n"); 158 options &= ~VERIFY; 159 } 160 nflag++; 161 break; 162 163 case 'q': 164 qflag++; 165 break; 166 167 case 'b': 168 options |= COMPARE; 169 break; 170 171 case 'R': 172 options |= REMOVE; 173 break; 174 175 case 'v': 176 if (nflag) { 177 printf("rdist: -n overrides -v\n"); 178 break; 179 } 180 options |= VERIFY; 181 break; 182 183 case 'w': 184 options |= WHOLE; 185 break; 186 187 case 'y': 188 options |= YOUNGER; 189 break; 190 191 case 'h': 192 options |= FOLLOW; 193 break; 194 195 case 'i': 196 options |= IGNLNKS; 197 break; 198 199 default: 200 usage(); 201 } 202 } 203 *hp = NULL; 204 205 seteuid(userid); 206 mktemp(tempfile); 207 208 if (iamremote) { 209 server(); 210 exit(nerrs != 0); 211 } 212 213 if (cmdargs) 214 docmdargs(argc, argv); 215 else { 216 if (fin == NULL) { 217 if(distfile == NULL) { 218 if((fin = fopen("distfile","r")) == NULL) 219 fin = fopen("Distfile", "r"); 220 } else 221 fin = fopen(distfile, "r"); 222 if(fin == NULL) { 223 perror(distfile ? distfile : "distfile"); 224 exit(1); 225 } 226 } 227 yyparse(); 228 if (nerrs == 0) 229 docmds(dhosts, argc, argv); 230 } 231 232 exit(nerrs != 0); 233 } 234 235 static void 236 usage() 237 { 238 printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n"); 239 printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n"); 240 exit(1); 241 } 242 243 /* 244 * rcp like interface for distributing files. 245 */ 246 static void 247 docmdargs(nargs, args) 248 int nargs; 249 char *args[]; 250 { 251 struct namelist *nl, *prev; 252 char *cp; 253 struct namelist *files, *hosts; 254 struct subcmd *cmds; 255 char *dest; 256 static struct namelist tnl = { NULL, NULL }; 257 int i; 258 259 if (nargs < 2) 260 usage(); 261 262 files = NULL; 263 prev = NULL; 264 for (i = 0; i < nargs - 1; i++) { 265 nl = makenl(args[i]); 266 if (prev == NULL) 267 files = prev = nl; 268 else { 269 prev->n_next = nl; 270 prev = nl; 271 } 272 } 273 274 cp = args[i]; 275 if ((dest = strchr(cp, ':')) != NULL) 276 *dest++ = '\0'; 277 tnl.n_name = cp; 278 hosts = expand(&tnl, E_ALL); 279 if (nerrs) 280 exit(1); 281 282 if (dest == NULL || *dest == '\0') 283 cmds = NULL; 284 else { 285 cmds = makesubcmd(INSTALL); 286 cmds->sc_options = options; 287 cmds->sc_name = dest; 288 } 289 290 if (debug) { 291 printf("docmdargs()\nfiles = "); 292 prnames(files); 293 printf("hosts = "); 294 prnames(hosts); 295 } 296 insert(NULL, files, hosts, cmds); 297 docmds(NULL, 0, NULL); 298 } 299 300 /* 301 * Print a list of NAME blocks (mostly for debugging). 302 */ 303 void 304 prnames(nl) 305 struct namelist *nl; 306 { 307 printf("( "); 308 while (nl != NULL) { 309 printf("%s ", nl->n_name); 310 nl = nl->n_next; 311 } 312 printf(")\n"); 313 } 314