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