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