#ifndef lint static char sccsid[] = "@(#)rinstall.c 1.0 (Sri-Tsc) 5/10/83"; #endif /* * rinstall [-ssystems] [-afile] [-bcrv] file1 [file2] ... * * rinstall will take a file name and copy it to the same directory * on all of the other systems mentioned. The -s flag can be followed * by a comma seperated list of systems to install to. Otherwise, * rinstall will look for the environment variable call "systems" which * should contain a comma seperated list of system names. If that name * does not exist, an assumed default systems will be used. * * The -a flag will append the file to the file list. - will read from * standard input. * The -c flag will return checksum information (from the sum program) * on all files. * The -b flag will cause the a copy of the original, if it exists, to * be move to its original name with a "-" appended to it. * The -r flag will remove the given files. * The -v flag will cause verbose output. * */ #define SYSTEMS "tsca,tscb,prmh,joyce" #define INSTALL_DEMON "/etc/installd" #define INSTALL_LOG "/usr/lib/installd.log" /* characters to send to installd */ #define APPEND 'a' /* append info */ #define BACKUP_COPY 'b' /* copy but make backup if possible */ #define CHECKSUM 'k' /* checksum files */ #define COPY 'c' /* default thing to do */ #define REMOVE 'r' /* remove files */ #include #include #include #include #include char *getenv(); /* returns a ptr to environment value */ struct passwd *getpwuid(); FILE *fopen(); char *ctime(); long time(); char *mktemp(); int rem; /* remote socket descriptor */ int aflag = 0; /* append option */ char *aptr; /* ptr to append file */ int cflag = 0; /* checksum info */ int bflag = 0; /* backup flag */ int rflag = 0; /* remove flag */ int vflag = 0; /* verbose flag */ int argc2; /* hold argc for counting */ char **argv2; /* and argv too */ char tempfile[] = "/tmp/rinsXXXXXX"; /* temp. file template */ int gotinput = 0; /* say we get his input for -a- */ main(argc, argv) char **argv; int argc; { char *sptr = 0; /* ptr to systems to install to */ char *hptr; /* ptr to beginning of singe host name */ char buffer[BUFSIZ]; /* place to hold system name temporarily */ struct passwd *pwd; /* given passwd entry */ int loc; /* local file file descriptor */ struct stat fstatus; /* where file info will go */ int n; /* integer temporary */ char sysname[14]; /* where system name will go */ FILE *logfile; /* where audit trail will go */ long clock; /* put time in here */ char option; /* what to do */ char *tptr; /* ptr to temp file name */ char c; /* place to put a character */ long ready; /* */ while (--argc > 0 && **++argv == '-') { switch ((*argv)[1]) { case 'a': /* append option */ aptr =(*argv)+2; /* ptr to file name */ aflag = 1; break; case 'c': /* run "sum" program */ cflag = 1; break; case 'b': /* mv backup copy */ bflag = 1; break; case 'r': /* remove files */ rflag = 1; break; case 's': sptr = (*argv)+2; /* ptr to rest of string */ break; case 'v': vflag = 1; /* make a pest of ourself */ break; default: goto badflg; } } if (!argc) { badflg: fprintf(stderr,"usage: rinstall [-bcrv][-afile][-ssys1,sys2...] file1 [file2] ...\n"); exit(1); } if ((rflag&&aflag)||(rflag&&cflag)||(cflag&&aflag)) { fprintf(stderr, "rinstall: conflicting flags\n"); exit(1); } pwd = getpwuid(getuid()); if (pwd == NULL) { fprintf(stderr, "rinstall: who are you?\n"); exit(1); } if (!sptr) /* were we supplied systems */ if (!(sptr = getenv("SYSTEMS"))) sptr = SYSTEMS; /* use our default */ if (aflag) option = APPEND; /* want to append */ else if (bflag) option = BACKUP_COPY;/*copy w/backup*/ else if (cflag) option = CHECKSUM; else if (rflag) option = REMOVE; else option = COPY; if (vflag) fprintf(stdout, "Installing to %s\n", sptr); while (*sptr) { /* for each system we want to send to */ n = 0; while (*sptr != ',' && *sptr) sysname[n++] = *sptr++; if (*sptr == ',') sptr++; sysname[n] = NULL; hptr = sysname; rem = rcmd(&hptr, IPPORT_CMDSERVER, pwd->pw_name, pwd->pw_name, INSTALL_DEMON, 0); if (rem == -1) exit(1); if ((logfile = fopen(INSTALL_LOG, "a")) != NULL) { fprintf(logfile, "%s ", pwd->pw_name); if (aflag) fprintf(logfile, "appended %s to ", aptr); else if (cflag) fprintf(logfile, "checksummed "); else if (rflag) fprintf(logfile, "removed "); else if (bflag) fprintf(logfile, "copied w/backup to "); else fprintf(logfile, "copied to "); } argc2 = argc; argv2 = argv; while (argc2--) { /* process each file name */ if (**argv2 != '/') { fprintf(stderr, "rinstall: %s: must use absolute path name.\n", *argv2); exit(1); } else if (logfile != NULL) fprintf(logfile, "%s ", *argv2); argv2++; } if (logfile != NULL) { time(&clock); fprintf(logfile,"on %s at %s",sysname, ctime(&clock)); fclose(logfile); } argc2 = argc; argv2 = argv; while (argc2--) { /* process each file name */ if (vflag) { if (aflag) fprintf(stdout, "Appending %s to",(strcmp(aptr, "-") ? aptr : "(stdin)")); else if (cflag) fprintf(stdout, "Checksum of"); else if (rflag) fprintf(stdout, "Removing"); else if (bflag) fprintf(stdout, "Copying w/backup to"); else fprintf(stdout, "Copying to"); fprintf(stdout, " %s at %s.\n", *argv2, sysname); } sprintf(buffer, "%s\n%c", *argv2, option); write(rem, buffer, strlen(buffer)+1); read(rem, buffer, BUFSIZ); /* get result */ if (buffer[0]) /* problem */ problem(1); /* yes, go handle it */ if (option == COPY || option == BACKUP_COPY|| option == APPEND) { if (option == APPEND) { if (!strcmp(aptr, "-")) { if (!gotinput) { gotinput = 1; tptr = mktemp(tempfile); if ((logfile = fopen(tptr, "w")) == NULL) { fprintf(stderr, "rinstall: could not create temp. file\n"); exit(1); } fprintf(stdout, "Enter text followed by control-d (^D):\n"); fflush(stdout); while((c = getchar()) != EOF) putc(c, logfile); fclose(logfile); } loc = open(tptr, 0); } else loc = open(aptr, 0); } else loc = open(*argv2, 0); /* open file read */ if (loc < 0) { fprintf(stderr, "rinstall: couldn't open %s to read.\n", (option==APPEND ? aptr : *argv2)); exit(1); } if (fstat(loc, &fstatus)) { fprintf(stderr, "rinstall: could not get file status: %s\n", *argv2); exit(1); } sprintf(buffer, "%D",fstatus.st_size); write(rem, buffer, strlen(buffer)+1); read(rem, buffer, BUFSIZ); if (buffer[0]) /* problem */ problem(1); while (n = read(loc, buffer, BUFSIZ)) write(rem, buffer, n); close(loc); read(rem, buffer, BUFSIZ); /* get result */ if (buffer[0]) /* problem */ problem(1); /*yes, go handle it */ sprintf(buffer, "%u", fstatus.st_mode&07777); write(rem, buffer, strlen(buffer)+1); read(rem, buffer, BUFSIZ); /* get result */ if (buffer[0]) /* problem */ problem(1); /*yes, go handle it */ if (option == APPEND && !strcmp(aptr, "-")) unlink(tptr); } else if (option == CHECKSUM) { sleep(3); buffer[read(rem, buffer, BUFSIZ)] = '\0'; fprintf(stdout, "%s:%s:\t%s", sysname, *argv2, buffer); } else if (option == REMOVE) { read(rem, buffer, BUFSIZ); if (buffer[0]) problem(0); } else { fprintf(stderr, "rinstall: unknown option\n"); exit(1); } argv2++; /* point to next file */ } close(rem); /* tell other system done */ } } /* * problem() is called when the install demon process return a non-zero reply. * This usually means something recognizable went wrong and we should expect * a reason to follow. Read in the reason, output it on the terminal and die. */ problem(die) int die; { char buf[BUFSIZ]; /* place to read into */ if (read(rem, buf, BUFSIZ) > 0) /* if we have something */ fprintf(stderr, "rinstall: %s", buf); if (die) { close(rem); /* close network channel */ exit(1); } }