admin.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,184 行 · 第 1/2 页

C
1,184
字号
#ifndef lintstatic	char	*sccsid = "@(#)admin.c	4.2	(ULTRIX)	12/6/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984, 1988 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * * Modification history: * * 28 Jun 88 -- D. Long *	Use atomic rename operation in xremove instead of link and unlink. * * 14 Sep 88 -- D. Long *	Use new LINEWIDTH constant for maximum text line length throughout *	instead of hard coded sizes and BUFSIZ.  Also check for input *	lines exceeding this size. * * 03 Mar 89 -- D. Long *	Applied fix for processing of LOCKFLAG and LOCKGET. */# include	"../hdr/defines.h"# include	"../hdr/had.h"# include	<sys/dir.h>/*	Program to create new SCCS files and change parameters	of existing ones. Arguments to the program may appear in	any order and consist of keyletters, which begin with '-',	and named files. Named files which do not exist are created	and their parameters are initialized according to the given	keyletter arguments, or are given default values if the	corresponding keyletters were not supplied. Named files which	do exist have those parameters corresponding to given key-letter	arguments changed and other parameters are left as is.	If a directory is given as an argument, each SCCS file within	the directory is processed as if it had been specifically named.	If a name of '-' is given, the standard input is read for a list	of names of SCCS files to be processed.	Non-SCCS files are ignored.	Files created are given mode 444.*/# define MAXNAMES 9# define COPY 0# define NOCOPY 1struct stat Statbuf;char Null[1];char Error[128];char *ifile, *tfile;char	*CMFAPPL;						/* CMF MODS */char *z;	/* for validation program name */extern FILE *Xiop;char	*getval();	/* function returning character ptr */char	*adjust();	/* function returning character ptr */char	*auxf();char had[NFLAGS], had_flag[NFLAGS], rm_flag[NFLAGS];char	*Comments, *Mrs;char Valpgm[]	=	"val";int irel, fexists, num_files;int	VFLAG  =  0;int	Domrs;struct sid newsid;extern char *Sflags[];char *anames[MAXNAMES], *enames[MAXNAMES];char	*unlock;char	*locks;char *flag_p[NFLAGS];int asub, esub;int check_id;int Did_id;static char b_dir[]  =  "directory `%s' specified as `%c' keyletter value (ad29)";main(argc,argv)int argc;char *argv[];{	register int j;	register char *p;	char c, f;	int i, testklt;	extern admin();	extern	char *savecmt();	char *sid_ab();	char *gf();	extern int Fcnt;	struct sid sid;	/*	Set flags for 'fatal' to issue message, call clean-up	routine and terminate processing.	*/	Fflags = FTLMSG | FTLCLN | FTLEXIT;	testklt = 1;	/*	The following loop processes keyletters and arguments.	Note that these are processed only once for each	invocation of 'main'.	*/	for(j=1; j<argc; j++)		if(argv[j][0] == '-' && (c = argv[j][1])) {			p = &argv[j][2];			switch (c) {			case 'i':	/* name of file of body */				ifile = p;				if (*ifile && exists(ifile))					if ((Statbuf.st_mode & S_IFMT) ==						 S_IFDIR) {					sprintf(Error,b_dir,ifile,c);					fatal(Error);				}				break;			case 't':	/* name of file of descriptive text */				tfile = p;				if (*tfile && exists(tfile))					if ((Statbuf.st_mode & S_IFMT) ==						S_IFDIR) {					sprintf(Error,b_dir,tfile,c);					fatal(Error);				}				break;			case 'm':	/* mr flag */				Mrs = p;				repl(Mrs,'\n',' ');				break;			case 'y':	/* comments flag for entry */				Comments = p;				break;			case 'd':	/* flags to be deleted */				testklt = 0;				if (!(f = *p))					fatal("d has no argument (ad1)");				p = &argv[j][3];				switch (f) {				case IDFLAG:	/* see 'f' keyletter */				case BRCHFLAG:	/* for meanings of flags */				case VALFLAG:				case TYPEFLAG:				case MODFLAG:				case QSECTFLAG:				case NULLFLAG:				case FLORFLAG:				case CEILFLAG:				case DEFTFLAG:				case JOINTFLAG:					if (*p) {						sprintf(Error,						"value after %c flag (ad12)",f);						fatal(Error);					}					break;				case CMFFLAG:	/* option installed by CMF */					if (*p) {						sprintf(Error,						"value after %c flag (ad12)",f);						fatal(Error);					}					break;				case LOCKFLAG:					if (*p) {						/*						set pointer to releases						to be unlocked for						editing 						*/						repl(p,',',' ');						if (!val_list(p))							fatal("bad list format (ad27)");						if (!range(p))							fatal("element in list out of range (ad28)");						if (*p != 'a')							unlock = p;					}					break;				case LOCKGET:					if (*p) {						/*						set pointer to releases						to be unlocked for						getting						*/						repl(p,',',' ');						if (!val_list(p))							fatal("bad list format (ad27)");						if (!range(p))							fatal("element in list out of range (ad28)");						if (*p != 'a')							unlock = p;					}					break;				default:					fatal("unknown flag (ad3)");				}				if (rm_flag[f - 'a']++)					fatal("flag twice (ad4)");				break;			case 'f':	/* flags to be added */				testklt = 0;				if (!(f = *p))					fatal("f has no argument (ad5)");				p = &argv[j][3];				switch (f) {				case IDFLAG:	/* id-kwd message (err/warn) */				case BRCHFLAG:	/* branch */				case NULLFLAG:	/* null deltas */				case JOINTFLAG:	/* joint edit flag */					if (*p) {						sprintf(Error,						"value after %c flag (ad13)",f);						fatal(Error);					}					break;				case VALFLAG:	/* mr validation */					VFLAG++;					if (*p)						z = p;					break;				case CMFFLAG:			/* CMFNET MODS */					if (*p)				/* CMFNET MODS */						CMFAPPL = p;	/* CMFNET MODS */					else				/* CMFNET MODS */						fatal ("No application with application flag.");					if (gf (CMFAPPL) == (char*) NULL)						fatal ("No .FRED file exists for this application.");					break;				/* END CMFNET MODS */				case FLORFLAG:	/* floor */					if ((i = patoi(p)) == -1)						fatal("floor not numeric (ad22)");					if ((size(p) > 5) || (i < MINR) ||							(i > MAXR))						fatal("floor out of range (ad23)");					break;				case CEILFLAG:	/* ceiling */					if ((i = patoi(p)) == -1)						fatal("ceiling not numeric (ad24)");					if ((size(p) > 5) || (i < MINR) ||							(i > MAXR))						fatal("ceiling out of range (ad25)");					break;				case DEFTFLAG:	/* default sid */					if (!(*p))						fatal("no default sid (ad14)");					chksid(sid_ab(p,&sid),&sid);					break;				case TYPEFLAG:	/* type */				case MODFLAG:	/* module name */				case QSECTFLAG:	/* csect name */					if (!(*p)) {						sprintf(Error,						"flag %c has no value (ad2)",f);						fatal(Error);					}					break;				case LOCKFLAG:	/* release lock */					if (!(*p))						/*						lock all releases						*/						p = "a";					/*					replace all commas with					blanks in SCCS file					*/					repl(p,',',' ');					if (!val_list(p))						fatal("bad list format (ad27)");					if (!range(p))						fatal("element in list out of range (ad28)");					break;				case LOCKGET:	/* release lock for						getting */					if (!(*p))						/*						lock all releases						*/						p = "a";					/*					replace all commas with					blanks in SCCS file					*/					repl(p,',',' ');					if (!val_list(p))						fatal("bad list format (ad27)");					if (!range(p))						fatal("element in list out of range (ad28)");					break;				default:					fatal("unknown flag (ad3)");				}				if (had_flag[f - 'a']++)					fatal("flag twice (ad4)");				flag_p[f - 'a'] = p;				break;			case 'r':	/* initial release number supplied */				 chksid(sid_ab(p,&newsid),&newsid);				 if ((newsid.s_rel < MINR) ||				     (newsid.s_rel > MAXR))					fatal("r out of range (ad7)");				 break;			case 'n':	/* creating new SCCS file */			case 'h':	/* only check hash of file */			case 'z':	/* zero the input hash */				break;			case 'a':	/* user-name allowed to make deltas */				testklt = 0;				if (!(*p))					fatal("bad a argument (ad8)");				if (asub > MAXNAMES)					fatal("too many 'a' keyletters (ad9)");				anames[asub++] = p;				break;			case 'e':	/* user-name to be removed */				testklt = 0;				if (!(*p))					fatal("bad e argument (ad10)");				if (esub > MAXNAMES)					fatal("too many 'e' keyletters (ad11)");				enames[esub++] = p;				break;			default:				fatal("unknown key letter (cm1)");			}			if (had[c - 'a']++ && testklt++)				fatal("key letter twice (cm2)");			argv[j] = 0;		}		else			num_files++;	if (num_files == 0)		fatal("missing file arg (cm3)");	if ((HADY || HADM) && ! (HADI || HADN))		fatal("illegal use of 'y' or 'm' keyletter (ad30)");	if (HADI && num_files > 1) /* only one file allowed with `i' */		fatal("more than one file (ad15)");	if ((HADI || HADN) && ! logname())		fatal("USER ID not in password file (cm9)");	setsig();	/*	Change flags for 'fatal' so that it will return to this	routine (main) instead of terminating processing.	*/	Fflags &= ~FTLEXIT;	Fflags |= FTLJMP;	/*	Call 'admin' routine for each file argument.	*/	for (j=1; j<argc; j++)		if (p = argv[j])			do_file(p,admin);	exit(Fcnt ? 1 : 0);}/*	Routine that actually does admin's work on SCCS files.	Existing s-files are copied, with changes being made, to a	temporary file (x-file). The name of the x-file is the same as the	name of the s-file, with the 's.' replaced by 'x.'.	s-files which are to be created are processed in a similar	manner, except that a dummy s-file is first created with	mode 444.	At end of processing, the x-file is renamed with the name of s-file	and the old s-file is removed.*/struct packet gpkt;	/* see file defines.h */char	Zhold[BUFSIZ];	/* temporary z-file name */admin(afile)char	*afile;{	struct deltab dt;	/* see file defines.h */	struct stats stats;	/* see file defines.h */	struct stat sbuf;	FILE	*iptr, *fdfopen();	register int k;	register char *cp, *q;	char	*in_f;		/* ptr holder for lockflag vals in SCCS file */	char	nline[LINEWIDTH+1];	char	*getline();	char	*p_lval, *tval, *lval;	char	f;		/* character holder for flag character */	char	line[LINEWIDTH+1];	char	*del_ba(), *fmalloc();	int	i;		/* used in forking procedure */	int	ck_it  =  0;	/* used for lockflag checking */	int	status;		/* used for status return from fork */	long	time();	extern	nfiles;	extern	char had_dir;	if (setjmp(Fjmp))	/* set up to return here from 'fatal' */		return;		/* and return to caller of admin */	zero(&stats,sizeof(stats));	if (HADI && had_dir) /* directory not allowed with `i' keyletter */		fatal("directory named with `i' keyletter (ad26)");	fexists = exists(afile);	if (HADI)		HADN = 1;	if (HADI || HADN) {			if (VFLAG && had_flag[CMFFLAG - 'a'])			fatal ("Can't have two verification routines.");		if (HADM && !VFLAG && !had_flag[CMFFLAG - 'a'])			fatal("MRs not allowed (de8)");		if (VFLAG && !HADM)			fatal("MRs required (de10)");	}	if (!HADI && HADR)		fatal("r only allowed with i (ad16)");	if (HADN && HADT && !(*tfile))		fatal("t has no argument (ad17)");	if (HADN && HADD)		fatal("d not allowed with n (ad18)");	if (HADN && fexists) {		sprintf(Error,"file %s exists (ad19)",afile);		fatal(Error);	}	if (!HADN && !fexists) {		sprintf(Error,"file %s does not exist (ad20)",afile);		fatal(Error);	}	if (HADH) {		/*		   fork here so 'admin' can execute 'val' to		   check for a corrupted file.		*/		if ((i = fork()) < 0)			fatal("cannot fork, try again");		if (i == 0) {		/* child */			/*			   perform 'val' with appropriate keyletters			*/			execlp(Valpgm, Valpgm, "-s", afile, 0);			sprintf(Error,"cannot execute '%s'",Valpgm);			fatal(Error);		}		else {			wait(&status);	   /* wait on status from 'execlp' */			if (status)				fatal("corrupted file (co6)");			return;		/* return to caller of 'admin' */		}	}	/*	Lock out any other user who may be trying to process	the same file.	*/	if (!HADH && lockit(copy(auxf(afile,'z'),Zhold),2,getpid()))		fatal("cannot create lock file (cm4)");	if (fexists)		sinit(&gpkt,afile,1);	/* init pkt & open s-file */	else {		if (strlen(sname(afile)) > MAXNAMLEN) {			sprintf(Error, "file name is greater than %d characters"					, MAXNAMLEN);			fatal(Error);		}		xfcreat(afile,0444);	/* create dummy s-file */		sinit(&gpkt,afile,0);	/* and init pkt */	}	if (!HADH)		/*		   set the flag for 'putline' routine to open		   the 'x-file' and allow writing on it.		*/		gpkt.p_upd = 1;	if (HADZ) {		gpkt.do_chksum = 0;	/* ignore checksum processing */		gpkt.p_ihash = 0;	}	/*	Get statistics of latest delta in old file.	*/	if (!HADN) {		stats_ab(&gpkt,&stats);		gpkt.p_wrttn++;		newstats(&gpkt,line,"0");	}	if (HADN) {		/*   N E W   F I L E   */		/*		Beginning of SCCS file.		*/		sprintf(line,"%c%c%s\n",CTLCHAR,HEAD,"00000");		putline(&gpkt,line);		/*		Statistics.		*/		newstats(&gpkt,line,"0");		dt.d_type = 'D';	/* type of delta */		/*		Set initial release, level, branch and		sequence values.		*/		if (HADR)			{			 dt.d_sid.s_rel = newsid.s_rel;			 dt.d_sid.s_lev = newsid.s_lev;			 dt.d_sid.s_br  = newsid.s_br ;			 dt.d_sid.s_seq = newsid.s_seq;			 if (dt.d_sid.s_lev == 0) dt.d_sid.s_lev = 1;			 if ((dt.d_sid.s_br) && ( ! dt.d_sid.s_seq))				dt.d_sid.s_seq = 1;			}		else			{			 dt.d_sid.s_rel = 1;			 dt.d_sid.s_lev = 1;			 dt.d_sid.s_br = dt.d_sid.s_seq = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?