114921Sralph #ifndef lint 2*17914Sralph static char *sccsid = "@(#)main.c 4.14 (Berkeley) 85/02/04"; 314921Sralph #endif 414921Sralph 514921Sralph #include "defs.h" 614921Sralph 7*17914Sralph #define NHOSTS 100 8*17914Sralph 914921Sralph /* 1014921Sralph * Remote distribution program. 1114921Sralph */ 1214921Sralph 1314921Sralph char *distfile = "distfile"; 1415611Sralph char tmpfile[] = "/tmp/rdistXXXXXX"; 1515113Sralph char *tmpname = &tmpfile[5]; 1614921Sralph 1714921Sralph int debug; /* debugging flag */ 1814921Sralph int nflag; /* NOP flag, just print commands without executing */ 1914921Sralph int qflag; /* Quiet. Don't print messages */ 2015218Sralph int options; /* global options */ 2114921Sralph int iamremote; /* act as remote server for transfering files */ 2214921Sralph 2314921Sralph FILE *fin = NULL; /* input file pointer */ 2416028Sralph int rem = -1; /* file descriptor to remote source/sink process */ 2514921Sralph char host[32]; /* host name */ 2616028Sralph int nerrs; /* number of errors while sending/receiving */ 2714921Sralph char user[10]; /* user's name */ 2814921Sralph char homedir[128]; /* user's home directory */ 2914921Sralph int userid; /* user's user ID */ 3015113Sralph int groupid; /* user's group ID */ 3114921Sralph 3215349Sralph struct passwd *pw; /* pointer to static area used by getpwent */ 3315349Sralph struct group *gr; /* pointer to static area used by getgrent */ 3415349Sralph 3514921Sralph main(argc, argv) 3614921Sralph int argc; 3714921Sralph char *argv[]; 3814921Sralph { 3914921Sralph register char *arg; 4015218Sralph int cmdargs = 0; 41*17914Sralph char *dhosts[NHOSTS], **hp = dhosts; 4214921Sralph 4314921Sralph pw = getpwuid(userid = getuid()); 4414921Sralph if (pw == NULL) { 4515113Sralph fprintf(stderr, "%s: Who are you?\n", argv[0]); 4614921Sralph exit(1); 4714921Sralph } 4814921Sralph strcpy(user, pw->pw_name); 4914921Sralph strcpy(homedir, pw->pw_dir); 5015113Sralph groupid = pw->pw_gid; 5114921Sralph gethostname(host, sizeof(host)); 5214921Sralph 5314921Sralph while (--argc > 0) { 5414921Sralph if ((arg = *++argv)[0] != '-') 5514921Sralph break; 5614921Sralph if (!strcmp(arg, "-Server")) 5714921Sralph iamremote++; 5814921Sralph else while (*++arg) 5914921Sralph switch (*arg) { 6014921Sralph case 'f': 6114921Sralph if (--argc <= 0) 6214921Sralph usage(); 6314921Sralph distfile = *++argv; 6414921Sralph if (distfile[0] == '-' && distfile[1] == '\0') 6514921Sralph fin = stdin; 6614921Sralph break; 6714921Sralph 68*17914Sralph case 'm': 69*17914Sralph if (--argc <= 0) 70*17914Sralph usage(); 71*17914Sralph if (hp >= &dhosts[NHOSTS-2]) { 72*17914Sralph fprintf(stderr, "rdist: too many destination hosts\n"); 73*17914Sralph exit(1); 74*17914Sralph } 75*17914Sralph *hp++ = *++argv; 76*17914Sralph break; 77*17914Sralph 7814921Sralph case 'd': 7915113Sralph if (--argc <= 0) 8015113Sralph usage(); 8115113Sralph define(*++argv); 8215113Sralph break; 8315113Sralph 8415113Sralph case 'D': 8514921Sralph debug++; 8614921Sralph break; 8714921Sralph 8815218Sralph case 'c': 8915218Sralph cmdargs++; 9015218Sralph break; 9115218Sralph 9214921Sralph case 'n': 9315611Sralph if (options & VERIFY) { 9415611Sralph printf("rdist: -n overrides -v\n"); 9515611Sralph options &= ~VERIFY; 9615611Sralph } 9714921Sralph nflag++; 9814921Sralph break; 9914921Sralph 10014921Sralph case 'q': 10114921Sralph qflag++; 10214921Sralph break; 10314921Sralph 10415293Sralph case 'b': 10515293Sralph options |= COMPARE; 10615293Sralph break; 10715293Sralph 10815611Sralph case 'R': 10915271Sralph options |= REMOVE; 11015271Sralph break; 11115271Sralph 11214921Sralph case 'v': 11315611Sralph if (nflag) { 11415611Sralph printf("rdist: -n overrides -v\n"); 11515611Sralph break; 11615611Sralph } 11715218Sralph options |= VERIFY; 11814921Sralph break; 11914921Sralph 12015218Sralph case 'w': 12115218Sralph options |= WHOLE; 12215218Sralph break; 12315218Sralph 12414921Sralph case 'y': 12515218Sralph options |= YOUNGER; 12614921Sralph break; 12714921Sralph 12816650Sralph case 'h': 12916650Sralph options |= FOLLOW; 13016650Sralph break; 13116650Sralph 13216650Sralph case 'i': 13316650Sralph options |= IGNLNKS; 13416650Sralph break; 13516650Sralph 13614921Sralph default: 13714921Sralph usage(); 13814921Sralph } 13914921Sralph } 140*17914Sralph *hp = NULL; 14115113Sralph 14217481Sralph setreuid(0, userid); 14315113Sralph mktemp(tmpfile); 14416028Sralph 14514921Sralph if (iamremote) { 14614921Sralph server(); 14717481Sralph exit(nerrs != 0); 14814921Sralph } 14914921Sralph 15015218Sralph if (cmdargs) 15115218Sralph docmdargs(argc, argv); 15215218Sralph else { 15315218Sralph if (fin == NULL && (fin = fopen(distfile, "r")) == NULL) { 15415218Sralph perror(distfile); 15515218Sralph exit(1); 15615218Sralph } 15715218Sralph yyparse(); 15816028Sralph if (nerrs == 0) 159*17914Sralph docmds(dhosts, argc, argv); 16015113Sralph } 16115113Sralph 16217481Sralph exit(nerrs != 0); 16314921Sralph } 16414921Sralph 16514921Sralph usage() 16614921Sralph { 167*17914Sralph printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n"); 16816650Sralph printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n"); 16914921Sralph exit(1); 17014921Sralph } 17114921Sralph 17214921Sralph /* 17315218Sralph * rcp like interface for distributing files. 17415218Sralph */ 17515218Sralph docmdargs(nargs, args) 17615218Sralph int nargs; 17715218Sralph char *args[]; 17815218Sralph { 17916028Sralph register struct namelist *nl, *prev; 18016028Sralph register char *cp; 18116028Sralph struct namelist *files, *hosts; 18216028Sralph struct subcmd *cmds; 18316028Sralph char *dest; 18416028Sralph static struct namelist tnl = { NULL, NULL }; 18515218Sralph int i; 18615218Sralph 18715218Sralph if (nargs < 2) 18815218Sralph usage(); 18915218Sralph 19015218Sralph prev = NULL; 19116028Sralph for (i = 0; i < nargs - 1; i++) { 19216028Sralph nl = makenl(args[i]); 19316028Sralph if (prev == NULL) 19416028Sralph files = prev = nl; 19516028Sralph else { 19616028Sralph prev->n_next = nl; 19716028Sralph prev = nl; 19816028Sralph } 19915218Sralph } 20015218Sralph 20116028Sralph cp = args[i]; 20216028Sralph if ((dest = index(cp, ':')) != NULL) 20316028Sralph *dest++ = '\0'; 20416028Sralph tnl.n_name = cp; 20516028Sralph hosts = expand(&tnl, E_ALL); 206*17914Sralph if (nerrs) 207*17914Sralph exit(1); 20815218Sralph 20916028Sralph if (dest == NULL || *dest == '\0') 21015218Sralph cmds = NULL; 21115218Sralph else { 21216028Sralph cmds = makesubcmd(INSTALL); 21316028Sralph cmds->sc_options = options; 21416028Sralph cmds->sc_name = dest; 21515218Sralph } 21615218Sralph 21715218Sralph if (debug) { 21815218Sralph printf("docmdargs()\nfiles = "); 21915218Sralph prnames(files); 22015218Sralph printf("hosts = "); 22115218Sralph prnames(hosts); 22215218Sralph } 22316317Sralph insert(NULL, files, hosts, cmds); 224*17914Sralph docmds(NULL, 0, NULL); 22515218Sralph } 22615218Sralph 22715218Sralph /* 22814921Sralph * Print a list of NAME blocks (mostly for debugging). 22914921Sralph */ 23016028Sralph prnames(nl) 23116028Sralph register struct namelist *nl; 23214921Sralph { 23314921Sralph printf("( "); 23416028Sralph while (nl != NULL) { 23516028Sralph printf("%s ", nl->n_name); 23616028Sralph nl = nl->n_next; 23714921Sralph } 23814921Sralph printf(")\n"); 23914921Sralph } 24014921Sralph 24114921Sralph /*VARARGS*/ 24214921Sralph warn(fmt, a1, a2,a3) 24314921Sralph char *fmt; 24414921Sralph { 24514921Sralph extern int yylineno; 24614921Sralph 24714921Sralph fprintf(stderr, "rdist: line %d: Warning: ", yylineno); 24814921Sralph fprintf(stderr, fmt, a1, a2, a3); 24914921Sralph fputc('\n', stderr); 25014921Sralph } 251