1 /* $NetBSD: main.c,v 1.13 2002/06/14 01:18:55 wiz 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.13 2002/06/14 01:18:55 wiz Exp $"); 47 #endif 48 #endif /* not lint */ 49 50 #include <sys/types.h> 51 52 #include <err.h> 53 #include <errno.h> 54 #include <pwd.h> 55 56 #include "defs.h" 57 58 #define NHOSTS 100 59 60 /* 61 * Remote distribution program. 62 */ 63 64 char *distfile = NULL; 65 #define _RDIST_TMP "/rdistXXXXXX" 66 char tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP + 1]; 67 char *tempname; 68 69 int debug; /* debugging flag */ 70 int nflag; /* NOP flag, just print commands without executing */ 71 int qflag; /* Quiet. Don't print messages */ 72 int options; /* global options */ 73 int iamremote; /* act as remote server for transfering files */ 74 75 FILE *fin = NULL; /* input file pointer */ 76 int rem = -1; /* file descriptor to remote source/sink process */ 77 char host[MAXHOSTNAMELEN + 1]; /* host name */ 78 int nerrs; /* number of errors while sending/receiving */ 79 char user[34]; /* user's name */ 80 char homedir[PATH_MAX]; /* user's home directory */ 81 uid_t userid; /* user's user ID */ 82 gid_t groupid; /* user's group ID */ 83 84 struct passwd *pw; /* pointer to static area used by getpwent */ 85 struct group *gr; /* pointer to static area used by getgrent */ 86 87 int main(int, char **); 88 static void usage(void); 89 static void docmdargs(int, char *[]); 90 91 int 92 main(int argc, char **argv) 93 { 94 char *arg; 95 int cmdargs = 0; 96 char *dhosts[NHOSTS], **hp = dhosts; 97 int fd; 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 fd = mkstemp(tempfile); 207 if (fd == -1) 208 err(1, "could not make a temporary file"); 209 close (fd); 210 211 if (iamremote) { 212 server(); 213 unlink(tempfile); 214 exit(nerrs != 0); 215 } 216 217 if (cmdargs) 218 docmdargs(argc, argv); 219 else { 220 if (fin == NULL) { 221 if (distfile == NULL) { 222 if ((fin = fopen("distfile","r")) == NULL) 223 fin = fopen("Distfile", "r"); 224 } else 225 fin = fopen(distfile, "r"); 226 if (fin == NULL) { 227 perror(distfile ? distfile : "distfile"); 228 unlink(tempfile); 229 exit(1); 230 } 231 } 232 yyparse(); 233 if (nerrs == 0) 234 docmds(dhosts, argc, argv); 235 } 236 237 unlink(tempfile); 238 exit(nerrs != 0); 239 } 240 241 static void 242 usage(void) 243 { 244 printf("Usage: rdist [-nqbRhivwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n"); 245 printf("or: rdist [-nqbRhivwyD] -c source [...] machine[:dest]\n"); 246 exit(1); 247 } 248 249 /* 250 * rcp like interface for distributing files. 251 */ 252 static void 253 docmdargs(int nargs, char **args) 254 { 255 struct namelist *nl, *prev; 256 char *cp; 257 struct namelist *files, *hosts; 258 struct subcmd *cmds; 259 char *dest; 260 static struct namelist tnl = { NULL, NULL }; 261 int i; 262 263 if (nargs < 2) 264 usage(); 265 266 files = NULL; 267 prev = NULL; 268 for (i = 0; i < nargs - 1; i++) { 269 nl = makenl(args[i]); 270 if (prev == NULL) 271 files = prev = nl; 272 else { 273 prev->n_next = nl; 274 prev = nl; 275 } 276 } 277 278 cp = args[i]; 279 if ((dest = strchr(cp, ':')) != NULL) 280 *dest++ = '\0'; 281 tnl.n_name = cp; 282 hosts = expand(&tnl, E_ALL); 283 if (nerrs) 284 return; 285 286 if (dest == NULL || *dest == '\0') 287 cmds = NULL; 288 else { 289 cmds = makesubcmd(INSTALL); 290 cmds->sc_options = options; 291 cmds->sc_name = dest; 292 } 293 294 if (debug) { 295 printf("docmdargs()\nfiles = "); 296 prnames(files); 297 printf("hosts = "); 298 prnames(hosts); 299 } 300 insert(NULL, files, hosts, cmds); 301 docmds(NULL, 0, NULL); 302 } 303 304 /* 305 * Print a list of NAME blocks (mostly for debugging). 306 */ 307 void 308 prnames(struct namelist *nl) 309 { 310 printf("( "); 311 while (nl != NULL) { 312 printf("%s ", nl->n_name); 313 nl = nl->n_next; 314 } 315 printf(")\n"); 316 } 317