2.9BSD/usr/net/local/rinstall/src/rinstall.c
#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 <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <net/in.h>
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);
}
}