12145Seric # include	"../hdr/defines.h"
22145Seric # include	"../hdr/had.h"
32145Seric 
4*36475Ssam static char Sccsid[] = "@(#)cmt.c	4.6	12/22/88";
52145Seric 
62145Seric struct packet gpkt;
72145Seric int	num_files, had_ffile;
82145Seric int	F_Opened, Opened, Domrs, First;
92145Seric char	*Comments, *Mrs, *ffile;
102145Seric char	Cstr[BUFSIZ], Mstr[BUFSIZ], Line[BUFSIZ], had[26];
112145Seric FILE	*iop, *Xiop;
1230498Slepreau static	char ifde[] = "initial file does not exists";
132145Seric 
main(argc,argv)142145Seric main(argc,argv)
152145Seric int argc;
162145Seric register char *argv[];
172145Seric {
182145Seric 	register int i;
192145Seric 	register char *p;
202145Seric 	char c;
212145Seric 	extern cmt();
222145Seric 	extern int Fcnt;
232145Seric 
242145Seric 	/*
252145Seric 	Flags for 'fatal'.
262145Seric 	*/
272145Seric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
282145Seric 
292145Seric 	/*
302145Seric 	Process arguments.
312145Seric 	*/
322145Seric 	for (i = 1; i < argc; i++)
332145Seric 		if (argv[i][0] == '-' && (c = argv[i][1])) {
342145Seric 			p = &argv[i][2];
352145Seric 			switch (c) {
362145Seric 			case 'f':
372145Seric 				if (*p) {
382145Seric 					ffile = p;
392145Seric 					++had_ffile;
402145Seric 					if (!exists(ffile))
412145Seric 						fatal(ifde);
422145Seric 				}
432145Seric 				break;
442145Seric 			default:
452145Seric 				fatal("unknown key letter (cm1)");
462145Seric 			}
472145Seric 			if (had[c - 'a']++)
482145Seric 				fatal("key letter twice (cm2)");
492145Seric 			argv[i] = 0;
502145Seric 		}
512145Seric 		else num_files++;
522145Seric 
532145Seric 	if(num_files == 0)
542145Seric 		fatal("missing file arg (cm3)");
552145Seric 
562145Seric 	setsig();
572145Seric 	/*
582145Seric 	Reset flags for 'fatal' so that it will return to 'main'
592145Seric 	rather than exiting.
602145Seric 	*/
6130498Slepreau 	Fflags &= ~FTLEXIT;
6230498Slepreau 	Fflags |= FTLJMP;
632145Seric 
642145Seric 	/*
652145Seric 	Invoke 'cmt' for each file argument.
662145Seric 	*/
672145Seric 	for (i = 1; i < argc; i++)
682145Seric 		if (p = argv[i])
692145Seric 			do_file(p,cmt);
702145Seric 
712145Seric 	exit(Fcnt ? 1 : 0);
722145Seric }
732145Seric 
742145Seric 
7530498Slepreau static char s_warn[] = "WARNING: MR flag is set; `%s' should contain both MR line and comment line\n";
762145Seric 
7730498Slepreau static char ns_warn[] = "WARNING: MR flag is not set; `%s' should only contain comment line\n";
782145Seric 
cmt(file)792145Seric cmt(file)
802145Seric register char *file;
812145Seric {
822145Seric 	extern char had_dir, had_standinp;
832145Seric 	extern	char	*Sflags[];
846173Seric 	extern	char	Pgmr[SZLNAM];
852145Seric 	char	line[BUFSIZ];
862145Seric 	int	fowner, downer, user;
872145Seric 
882145Seric 	/*
892145Seric 	Set up to return to caller ('main') from 'fatal'.
902145Seric 	*/
912145Seric 	if (setjmp(Fjmp))
922145Seric 		return;
932145Seric 
942145Seric 	sinit(&gpkt,file,1);	/* init packet and open file */
952145Seric 
962145Seric 	if (lockit(auxf(gpkt.p_file,'z'),2,getpid()))
972145Seric 		fatal("cannot create lock file (cm4)");
982145Seric 
992145Seric 	if (num_files > 1 || had_dir || had_standinp)
1002145Seric 		printf("\n%s:\n",gpkt.p_file);
1012145Seric 
1022145Seric 	First = 1;
1032145Seric 	gpkt.p_reopen = 1;
1042145Seric 	do_delt(&gpkt);		/* read delta table for First time */
1052145Seric 	finduser(&gpkt);
1062145Seric 	doflags(&gpkt);		/* get flags (see if v flag is set) */
1072145Seric 	permiss(&gpkt);
1082145Seric 
1092145Seric 	/*
1102145Seric 	Check that user is either owner of file or
1112145Seric 	directory, or is one who made the initial delta
1122145Seric 	*/
1132145Seric 
1142145Seric 	fstat(fileno(gpkt.p_iop),&Statbuf);
1152145Seric 	fowner = Statbuf.st_uid & 0377;
1162145Seric 	copy(gpkt.p_file,line);		/* temporary for dname() */
1172145Seric 	if (stat(dname(line),&Statbuf))
1182145Seric 		downer = -1;
1192145Seric 	else downer = Statbuf.st_uid & 0377;
1202145Seric 	user = getuid() & 0377;
1212145Seric 	if (user != fowner || user != downer)
12233423Sbostic 		if (!equal(Pgmr,logname())) {
12333423Sbostic 			sprintf(Error, "you are neither owner nor '%s' (rc4)",Pgmr);
12433423Sbostic 			fatal(Error);
12533423Sbostic 		}
1262145Seric 
1272145Seric 	if ((HADF && had_ffile)) {
1282145Seric 		if (Sflags[VALFLAG - 'a'])
1292145Seric 			fprintf(stderr,s_warn,ffile);
1302145Seric 		else fprintf(stderr,ns_warn,ffile);
1312145Seric 		sleep(5);
1322145Seric 	}
1332145Seric 	flushto(&gpkt,EUSERTXT,1);
1342145Seric 	gpkt.p_chkeof = 1;	/* indicate that EOF is okay */
1352145Seric 	while (getline(&gpkt))	/* this will read body checking for cor */
1362145Seric 		;
1372145Seric 
1382145Seric 	gpkt.p_upd = 1;		/* x-file is to be used */
1392145Seric 	gpkt.p_wrttn = 1;	/* prevent printing of header line */
1402145Seric 	getline(&gpkt);		/* skip over old header record */
1412145Seric 	gpkt.p_wrttn = 1;
1422145Seric 
1432145Seric 	/*
1442145Seric 	Write new header.
1452145Seric 	*/
14633423Sbostic 	sprintf(Line,"%c%c00000\n",CTLCHAR,HEAD);
14733423Sbostic 	putline(&gpkt,Line);
1482145Seric 	do_delt(&gpkt);		/* read delta table second time */
1492145Seric 
1502145Seric 	flushto(&gpkt,EUSERNAM,0);
1512145Seric 	flushto(&gpkt,EUSERTXT,0);
1522145Seric 	while(getline(&gpkt))
1532145Seric 		;
1542145Seric 
1552145Seric 	flushline(&gpkt,0);	/* flush buffer, fix header, and close */
1562145Seric 	rename(auxf(gpkt.p_file,'x'),gpkt.p_file);
1572145Seric 	xrm(&gpkt);
1582145Seric 	unlockit(auxf(gpkt.p_file,'z'),getpid());
1592145Seric 	return;
1602145Seric }
1612145Seric 
1622145Seric 
16330498Slepreau static	char cle[] = "comment line for initial delta already exists";
1642145Seric 
do_delt(pkt)1652145Seric do_delt(pkt)
1662145Seric register struct packet *pkt;
1672145Seric {
1682145Seric 	int	n;
16930498Slepreau 	int	did_zero = 0;
1702145Seric 	struct deltab dt;
1712145Seric 	struct stats stats;
1722145Seric 
1732145Seric 	while(getstats(pkt,&stats)) {
1742145Seric 		if(getadel(pkt,&dt) != BDELTAB)
1752145Seric 			fmterr(pkt);
1762145Seric 		if(dt.d_type == 'D' && dt.d_pred == 0) {
1772145Seric 			copy(dt.d_pgmr,Pgmr);
1782145Seric 			if (First)
1792145Seric 				did_zero++;
1802145Seric 			else {
1812145Seric 				putline(pkt,0);
1822145Seric 				fixintdel();
1832145Seric 			}
1842145Seric 		}
1852145Seric 		while((n = getline(pkt)) != NULL)
1862145Seric 			if (pkt->p_line[0] != CTLCHAR)
1872145Seric 				break;
1882145Seric 			else {
1892145Seric 				switch(pkt->p_line[1]) {
1902145Seric 				case EDELTAB:
1912145Seric 					break;
1922145Seric 				case INCLUDE:
1932145Seric 				case EXCLUDE:
1942145Seric 				case IGNORE:
1952145Seric 				case MRNUM:
1962145Seric 					continue;
1972145Seric 				case COMMENTS:
1982145Seric 					if (First)
1992145Seric 						if(did_zero)
2002145Seric 							fatal(cle);
2012145Seric 					continue;
2022145Seric 				default:
2032145Seric 					fmterr(pkt);
2042145Seric 				}
2052145Seric 				break;
2062145Seric 			}
2072145Seric 		if (n ==NULL || pkt->p_line[0] != CTLCHAR)
2082145Seric 			fmterr(pkt);
2092145Seric 	}
2102145Seric 	First = 0;
2112145Seric }
2122145Seric 
2132145Seric 
getadel(pkt,dt)2142145Seric getadel(pkt,dt)
2152145Seric register struct packet *pkt;
2162145Seric register struct deltab *dt;
2172145Seric {
2182145Seric 	if (getline(pkt) == NULL)
2192145Seric 		fmterr(pkt);
2202145Seric 	return(del_ab(pkt->p_line,dt,pkt));
2212145Seric }
2222145Seric 
2232145Seric 
getstats(pkt,statp)2242145Seric getstats(pkt,statp)
2252145Seric register struct packet *pkt;
2262145Seric register struct stats *statp;
2272145Seric {
2282145Seric 	register char *p;
2292145Seric 	extern	char	*satoi();
2302145Seric 
2312145Seric 	p = pkt->p_line;
2322145Seric 	if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS)
2332145Seric 		return(0);
2342145Seric 	NONBLANK(p);
2352145Seric 	p = satoi(p,&statp->s_ins);
2362145Seric 	p = satoi(++p,&statp->s_del);
2372145Seric 	satoi(++p,&statp->s_unc);
2382145Seric 	return(1);
2392145Seric }
2402145Seric 
clean_up(n)2412145Seric clean_up(n)
2422145Seric {
2432145Seric 	if (gpkt.p_file[0])
2442145Seric 		unlockit(auxf(gpkt.p_file,'z'),getpid());
2452145Seric 	if (gpkt.p_iop)
2462145Seric 		fclose(gpkt.p_iop);
2472145Seric 
2482145Seric 	xrm(&gpkt);
2492145Seric 	if (exists(auxf(gpkt.p_file,'x')))
2502145Seric 		remove(auxf(gpkt.p_file,'x'));	/* remove x-file */
2512145Seric 	Xiop = 0;
2522145Seric 	if (F_Opened)
2532145Seric 		fclose(iop);
2542145Seric 	iop = F_Opened = Opened = 0;
2552145Seric 	xfreeall();
2562145Seric }
2572145Seric 
2582145Seric 
fixintdel()2592145Seric fixintdel()
2602145Seric {
2612145Seric 
2622145Seric 	register char	*p;
2632145Seric 	register int	doprmt;
2642145Seric 	int	tty[3];
2652145Seric 	char	str[128];
2662145Seric 
2672145Seric 	doprmt = 0;
2682145Seric 	if (gtty(0,tty) >= 0)
2692145Seric 		doprmt++;
2702145Seric 
2712145Seric 	if (!HADF && !had_ffile) {
2722145Seric 		Opened++;
2732145Seric 		iop = stdin;
2742145Seric 	}
2752145Seric 	else if (HADF && had_ffile) {
2762145Seric 		iop = xfopen(ffile,0);
2772145Seric 		doprmt = 0;
2782145Seric 		Opened++;
2792145Seric 		F_Opened++;
2802145Seric 	}
2812145Seric 	else if (HADF && !had_ffile)
2822145Seric 		doprmt = 0;
2832145Seric 
2842145Seric 	if ((p = Sflags[VALFLAG - 'a'])) {
2852145Seric 		if (doprmt)
2862145Seric 			printf("MRs? ");
2872145Seric 		if (Opened) {
2882145Seric 			Mrs = getinput(" ",Mstr);
2892145Seric 			mrfixup();
2902145Seric 			if (*p && valmrs(&gpkt,p))
2912145Seric 				fatal("invalid MRs (de9)");
2922145Seric 			putmrs(&gpkt);
2932145Seric 		}
29433423Sbostic 		else {
29533423Sbostic 			sprintf(Line,CTLSTR,CTLCHAR,MRNUM);
29633423Sbostic 			putline(&gpkt,Line);
29733423Sbostic 		}
2982145Seric 	}
2992145Seric 	if (doprmt)
3002145Seric 		printf("comments? ");
3012145Seric 	if (Opened) {
30233423Sbostic 		sprintf(Line,"\n%c%c ",CTLCHAR,COMMENTS);
30333423Sbostic 		Comments = getinput(Line,Cstr);
30433423Sbostic 		sprintf(str,"%c%c ",CTLCHAR,COMMENTS);
30533423Sbostic 		putline(&gpkt,str);
3062145Seric 		putline(&gpkt,Comments);
3072145Seric 		putline(&gpkt,"\n");
3082145Seric 	}
30933423Sbostic 	else {
31033423Sbostic 		sprintf(Line,CTLSTR,CTLCHAR,COMMENTS);
31133423Sbostic 		putline(&gpkt,Line);
31233423Sbostic 	}
3132145Seric 
3142145Seric 	if (F_Opened)
3152145Seric 		fclose(iop);
3162145Seric 	F_Opened = Opened = 0;
3172145Seric }
3182145Seric 
3192145Seric 
getinput(repstr,result)3202145Seric getinput(repstr,result)
3212145Seric char *repstr;
3222145Seric char *result;
3232145Seric {
3242145Seric 	char line[BUFSIZ];
3252145Seric 	register int done, sz;
3262145Seric 	register char *p;
3272145Seric 
3282145Seric 	result[0] = 0;
3292145Seric 	done = 0;
3302145Seric 	setbuf(iop,NULL);
3312145Seric 	sz = sizeof(line) - size(repstr);
3322145Seric 	while (!done && fgets(line,sz,iop) != NULL) {
33319941Ssam 		p = index(line, '\0');
3342145Seric 		if (*--p == '\n') {
3352145Seric 			if (*--p == '\\') {
3362145Seric 				copy(repstr,p);
3372145Seric 			}
3382145Seric 			else {
3392145Seric 				*++p = 0;
3402145Seric 				++done;
3412145Seric 			}
3422145Seric 		}
3432145Seric 		else
3442145Seric 			fatal("line too long (co18)");
3452145Seric 		if ((size(line) + size(result)) > RESPSIZE)
3462145Seric 			fatal("response too long (co19)");
3472145Seric 		strcat(result,line);
3482145Seric 	}
3492145Seric 	return(result);
3502145Seric }
3512145Seric 
3522145Seric 
3532145Seric putmrs(pkt)
3542145Seric struct packet *pkt;
3552145Seric {
3562145Seric 	register char **argv;
3572145Seric 	char str[64];
3582145Seric 	extern char *Varg[];
3592145Seric 
36033423Sbostic 	for (argv = &Varg[VSTART]; *argv; argv++) {
36133423Sbostic 		sprintf(str,"%c%c %s\n",CTLCHAR,MRNUM,*argv);
36233423Sbostic 		putline(pkt,str);
36333423Sbostic 	}
3642145Seric }
365*36475Ssam 
366*36475Ssam /* Null routine to satisfy external reference from dodelt() */
escdodelt()367*36475Ssam escdodelt()
368*36475Ssam {}
369