Ultrix-3.1/sys/distr/fsup.c

Compare this file to the similar file:
Show the results in this format:

static	char	Sccsid[] = "@(#)fsup.c	3.0	4/21/86";

/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

/*
 * ULTRIX-11 Binary version file system update (fsup).
 *
 * Fred Canter
 *
 * This program updates the ULTRIX-11 binary version file system
 * prototypes (bvroot & bvusr), by comparing the last modified
 * date/time of each file and getting a new copy of the file from
 * the master system disk if necessary.
 *
 * The program also reports on any differences between the prototype
 * file systems and the master system disk, such as changed owner,
 * protection codes, and missing/extra files.
 *
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <time.h>

struct	stat	sb_from;
struct	stat	sb_to;
char	fi_from[100];
char	fi_to[100];
char	syscmd[100];

char	*bvroot = "/dev/hp10";
char	*bvusr = "/dev/hp11";
char	*bvos = "/dev/hp14";
char	*bvr_dir = "/bvroot";
char	*bvu_dir = "/bvusr";
char	*bvr_df = "./bvroot.dir";
char	*bvu_df	= "./bvusr.dir";
char	*bvo_df	= "./bvos.dir";
char	line[150];
char	buf[512];

int	stopflag;
int	allup;
int	noup;
int	iflag;
int	dflag;

main(argc, argv)
int	argc;
char	*argv[];
{
	int	intr();
	char	*p;
	int	i;

	for(i=1; i<argc; i++) {
		if(argv[i][0] != '-') {
	argerr:
			fprintf(stderr, "\nfsup: bad argument!\n");
			exit(1);
		}
		switch(argv[i][1]) {
		case 'a':
			allup++;
			break;
		case 'i':
			iflag++;
			break;
		case 'n':
			noup++;
			break;
		case 'd':
			noup++;
			allup = 0;
			dflag++;
			break;
		default:
			goto argerr;
		}
	}
	fprintf(stderr, "\n\nULTRIX-11 ");
	fprintf(stderr, "BVROOT/BVUSR/BVOS file system update program\n");
	if(iflag)
		goto ud_go;
ud_rdy:
	fprintf(stderr, "\nReady to begin update <y or n> ? ");
	p = gets(line);
	if((strcmp(p, "y")==0) || (strcmp(p, "yes")==0))
		goto ud_go;
	else if((strcmp(p, "n")==0) || (strcmp(p, "no")==0)) {
		printf("\n\n###### BVROOT/BVUSR/BVOS NOT UPDATED ######\n");
		exit(0);
	} else
		goto ud_rdy;
ud_go:
	signal(SIGINT, intr);
	fs_update(bvroot, bvr_dir, bvr_df);
	fs_update(bvusr, bvu_dir, bvu_df);
	fs_update(bvos, bvu_dir, bvo_df);
}

/*
 * Do the actual update.
 * sf  = special file to mount
 * dir = directory to mount on
 * df  = file system proto directory file
 */

fs_update(sf, dir, df)
char	*sf;
char	*dir;
char	*df;
{
	register FILE *fi;
	register int i;
	int	s_from, s_to;
	int	fin, fout, cc;
	time_t	timeb;

	if(noup)
		i = 1;
	else
		i = 0;
	if(mount(sf, dir, i) != 0) {
		fprintf(stderr, "\nCan't mount %s on %s\n", sf, dir);
		exit(1);
	}
	if((fi = fopen(df, "r")) == NULL) {
		fprintf(stderr, "\nCan't open directory file (%s)\n", df);
	um_xit:
		if(fi > 0)
			fclose(fi);
		if(fin > 0)
			close(fin);
		if(fout > 0)
			close(fout);
		if(umount(sf) != 0)
			fprintf(stderr, "\nCan't dismount %s\n", sf);
		exit(1);
	}
	clearerr(fi);	/* some day, find out if this is really needed */
	time(&timeb);
	printf("\n\n###### STARTING UPDATE OF %s (%s) @ %s",
		dir, sf, ctime(&timeb));
loop:
	if(stopflag) {
		printf("\n\n****** UPDATE ABORTED VIA CTRL/C ******\n");
		goto um_xit;
	}
	if(fgets(line, 100, fi) == NULL) {
		if(ferror(fi)) {
			fprintf(stderr, "\n\nREAD ERROR on %s file\n", df);
			goto um_xit;
		}
		if(feof(fi)) {
			printf("\n\n###### UPDATE OF %s (%s) COMPLETED @ %s",
				dir, sf, ctime(&timeb));
			fclose(fi);
			umount(sf);
			return;
		}
	}
	if(line[0] == '*') {
		printf("\n****** FILE IGNORED ******\n");
		printf("%s", line);
		goto loop;
	}
	for(i=0; i<150; i++)
		if((line[i] == '\n') || (line[i] == ' ')) {
			line[i] = '\0';
			break;
		}
	if(i >= 100) {
		fprintf(stderr, "\nPathname too long!\n");
		goto um_xit;
	}
	strcpy(fi_to, line);
	if(strcmp(dir, "/bvroot") == 0) {
		if(strcmp("/bvroot", line) == 0)
			sprintf(fi_from, "/");
		else
			strcpy(fi_from, &line[7]);
	} else {
		fi_from[0] = '/';
		strcpy(&fi_from[1], &line[3]);
	}
	s_from = stat(fi_from, &sb_from);
	s_to = stat(fi_to, &sb_to);
	if(s_to != 0) {
		fprintf(stderr, "\nCan't stat %s\n", fi_to);
		goto um_xit;
	}
	if(s_from != 0) {
		printf("\n****** MISSING FILE/DIRECTORY ******\n");
		printf("%s\n", fi_from);
		fflush(stdout);
		goto loop;
	}
	if(!dflag)
		goto no_diff;
	if((sb_to.st_mode & S_IFMT) != S_IFDIR)
		goto no_diff;
	if((sb_from.st_mode & S_IFMT) != S_IFDIR) {
		printf("\n** NOT A DIRECTORY: %s\n", fi_from);
		fflush(stdout);
		goto loop;
	}
	sprintf(&syscmd, "ls %s >fsup.dirf; ls %s >fsup.dirt",
		fi_from, fi_to);
	if(system(&syscmd) != 0) {
		printf("\n** Can't execute %s\n", syscmd);
		fflush(stdout);
		goto loop;
	}
	printf("\n** DIRECTORY CHECK: ");
	printf("[ < for %s ]  [ > for %s ]\n", fi_from, fi_to);
	fflush(stdout);
	system("diff fsup.dirf fsup.dirt");
	goto d_stat;
no_diff:
	if((s_to == 0) && ((sb_to.st_mode&S_IFMT) != S_IFREG)) {
		printf("\n****** ONLY REGULAR FILES UPDATED ******\n");
		printf("%s\n", fi_to);
		goto loop;
	}
	if((s_from == 0) && ((sb_from.st_mode&S_IFMT) != S_IFREG)) {
		printf("\n****** ONLY REGULAR FILES UPDATED ******\n");
		printf("%s\n", fi_from);
		goto loop;
	}

d_stat:
	if((sb_from.st_mode != sb_to.st_mode) ||
	    (sb_from.st_nlink != sb_to.st_nlink) ||
	    (sb_from.st_uid != sb_to.st_uid) ||
	    (sb_from.st_gid != sb_to.st_gid)) {
		printf("\n****** FILE STATUS MISMATCH ******\n");
		printf("%s\n", fi_from);
		printf("(mode=%o, nlink=%d, uid=%d, gid=%d)\n",
		  sb_from.st_mode,sb_from.st_nlink,sb_from.st_uid,sb_from.st_gid);
		printf("%s\n", fi_to);
		printf("(mode=%o, nlink=%d, uid=%d, gid=%d)\n",
		  sb_to.st_mode,sb_to.st_nlink,sb_to.st_uid,sb_to.st_gid);
	}
	if(dflag)
		goto loop;
	if((s_to == 0) && (sb_to.st_size == 0)) {
		printf("\n****** ZERO LENGTH FILE NOT UPDATED ******\n");
		printf("%s\n", fi_to);
		goto loop;
	}
	if(allup || (sb_from.st_mtime > sb_to.st_mtime)) {
		if(noup) {
			printf("\n****** FILE WOULD BE UPDATED ******\n");
			printf("FROM:\t%s\nTO:\t%s\n", fi_from, fi_to);
			goto loop;
		}
		if(!allup) {
			printf("\n****** FILE BEING UPDATED ******\n");
			printf("FROM:\t%s\nTO:\t%s\n", fi_from, fi_to);
		}
		if((fin = open(fi_from, 0)) < 0) {
			fprintf(stderr, "\nCan't open %s\n", fi_from);
			goto um_xit;
		}
		if((fout = creat(fi_to, 0666)) < 0) {
			fprintf(stderr, "\nCan't create %s\n", fi_to);
			goto um_xit;
		}
		while(cc = read(fin, buf, 512)) {
			if(cc < 0) {
				fprintf(stderr,"\nFATAL read error\n");
				goto um_xit;
			}
			if(write(fout, buf, cc) != cc) {
				fprintf(stderr,"\n FATAL write error\n");
				goto um_xit;
			}
		}
	close(fin);
	close(fout);
	if(!allup)
		printf("****** FILE UPDATE COMPLETE ******\n");
	}
	goto loop;
}

intr()
{
	signal(SIGINT, intr);
	stopflag = 1;
}