1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * 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 char copyright[] = 36 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)main.c 5.6 (Berkeley) 8/27/90"; 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 main(argc, argv) 76 int argc; 77 char *argv[]; 78 { 79 register char *arg; 80 int cmdargs = 0; 81 char *dhosts[NHOSTS], **hp = dhosts; 82 83 pw = getpwuid(userid = getuid()); 84 if (pw == NULL) { 85 fprintf(stderr, "%s: Who are you?\n", argv[0]); 86 exit(1); 87 } 88 strcpy(user, pw->pw_name); 89 strcpy(homedir, pw->pw_dir); 90 groupid = pw->pw_gid; 91 gethostname(host, sizeof(host)); 92 strcpy(tempfile, _PATH_TMP); 93 strcat(tempfile, _RDIST_TMP); 94 if ((tempname = rindex(tempfile, '/')) != 0) 95 tempname++; 96 else 97 tempname = tempfile; 98 99 while (--argc > 0) { 100 if ((arg = *++argv)[0] != '-') 101 break; 102 if (!strcmp(arg, "-Server")) 103 iamremote++; 104 else while (*++arg) 105 switch (*arg) { 106 case 'f': 107 if (--argc <= 0) 108 usage(); 109 distfile = *++argv; 110 if (distfile[0] == '-' && distfile[1] == '\0') 111 fin = stdin; 112 break; 113 114 case 'm': 115 if (--argc <= 0) 116 usage(); 117 if (hp >= &dhosts[NHOSTS-2]) { 118 fprintf(stderr, "rdist: too many destination hosts\n"); 119 exit(1); 120 } 121 *hp++ = *++argv; 122 break; 123 124 case 'd': 125 if (--argc <= 0) 126 usage(); 127 define(*++argv); 128 break; 129 130 case 'D': 131 debug++; 132 break; 133 134 case 'c': 135 cmdargs++; 136 break; 137 138 case 'n': 139 if (options & VERIFY) { 140 printf("rdist: -n overrides -v\n"); 141 options &= ~VERIFY; 142 } 143 nflag++; 144 break; 145 146 case 'q': 147 qflag++; 148 break; 149 150 case 'b': 151 options |= COMPARE; 152 break; 153 154 case 'R': 155 options |= REMOVE; 156 break; 157 158 case 'v': 159 if (nflag) { 160 printf("rdist: -n overrides -v\n"); 161 break; 162 } 163 options |= VERIFY; 164 break; 165 166 case 'w': 167 options |= WHOLE; 168 break; 169 170 case 'y': 171 options |= YOUNGER; 172 break; 173 174 case 'h': 175 options |= FOLLOW; 176 break; 177 178 case 'i': 179 options |= IGNLNKS; 180 break; 181 182 default: 183 usage(); 184 } 185 } 186 *hp = NULL; 187 188 setreuid(0, userid); 189 mktemp(tempfile); 190 191 if (iamremote) { 192 server(); 193 exit(nerrs != 0); 194 } 195 196 if (cmdargs) 197 docmdargs(argc, argv); 198 else { 199 if (fin == NULL) { 200 if(distfile == NULL) { 201 if((fin = fopen("distfile","r")) == NULL) 202 fin = fopen("Distfile", "r"); 203 } else 204 fin = fopen(distfile, "r"); 205 if(fin == NULL) { 206 perror(distfile ? distfile : "distfile"); 207 exit(1); 208 } 209 } 210 yyparse(); 211 if (nerrs == 0) 212 docmds(dhosts, argc, argv); 213 } 214 215 exit(nerrs != 0); 216 } 217 218 usage() 219 { 220 printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n"); 221 printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n"); 222 exit(1); 223 } 224 225 /* 226 * rcp like interface for distributing files. 227 */ 228 docmdargs(nargs, args) 229 int nargs; 230 char *args[]; 231 { 232 register struct namelist *nl, *prev; 233 register char *cp; 234 struct namelist *files, *hosts; 235 struct subcmd *cmds; 236 char *dest; 237 static struct namelist tnl = { NULL, NULL }; 238 int i; 239 240 if (nargs < 2) 241 usage(); 242 243 prev = NULL; 244 for (i = 0; i < nargs - 1; i++) { 245 nl = makenl(args[i]); 246 if (prev == NULL) 247 files = prev = nl; 248 else { 249 prev->n_next = nl; 250 prev = nl; 251 } 252 } 253 254 cp = args[i]; 255 if ((dest = index(cp, ':')) != NULL) 256 *dest++ = '\0'; 257 tnl.n_name = cp; 258 hosts = expand(&tnl, E_ALL); 259 if (nerrs) 260 exit(1); 261 262 if (dest == NULL || *dest == '\0') 263 cmds = NULL; 264 else { 265 cmds = makesubcmd(INSTALL); 266 cmds->sc_options = options; 267 cmds->sc_name = dest; 268 } 269 270 if (debug) { 271 printf("docmdargs()\nfiles = "); 272 prnames(files); 273 printf("hosts = "); 274 prnames(hosts); 275 } 276 insert(NULL, files, hosts, cmds); 277 docmds(NULL, 0, NULL); 278 } 279 280 /* 281 * Print a list of NAME blocks (mostly for debugging). 282 */ 283 prnames(nl) 284 register struct namelist *nl; 285 { 286 printf("( "); 287 while (nl != NULL) { 288 printf("%s ", nl->n_name); 289 nl = nl->n_next; 290 } 291 printf(")\n"); 292 } 293 294 /*VARARGS*/ 295 warn(fmt, a1, a2,a3) 296 char *fmt; 297 { 298 extern int yylineno; 299 300 fprintf(stderr, "rdist: line %d: Warning: ", yylineno); 301 fprintf(stderr, fmt, a1, a2, a3); 302 fputc('\n', stderr); 303 } 304