12145Seric # include "../hdr/defines.h" 22145Seric # include "../hdr/had.h" 32145Seric 4*30498Slepreau static char Sccsid[] = "@(#)cmt.c 4.4 02/15/87"; 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; 12*30498Slepreau static char ifde[] = "initial file does not exists"; 132145Seric 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 */ 61*30498Slepreau Fflags &= ~FTLEXIT; 62*30498Slepreau 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 75*30498Slepreau static char s_warn[] = "WARNING: MR flag is set; `%s' should contain both MR line and comment line\n"; 762145Seric 77*30498Slepreau static char ns_warn[] = "WARNING: MR flag is not set; `%s' should only contain comment line\n"; 782145Seric 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) 1222145Seric if (!equal(Pgmr,logname())) 1232145Seric fatal(sprintf(Error, 1242145Seric "you are neither owner nor '%s' (rc4)",Pgmr)); 1252145Seric 1262145Seric if ((HADF && had_ffile)) { 1272145Seric if (Sflags[VALFLAG - 'a']) 1282145Seric fprintf(stderr,s_warn,ffile); 1292145Seric else fprintf(stderr,ns_warn,ffile); 1302145Seric sleep(5); 1312145Seric } 1322145Seric flushto(&gpkt,EUSERTXT,1); 1332145Seric gpkt.p_chkeof = 1; /* indicate that EOF is okay */ 1342145Seric while (getline(&gpkt)) /* this will read body checking for cor */ 1352145Seric ; 1362145Seric 1372145Seric gpkt.p_upd = 1; /* x-file is to be used */ 1382145Seric gpkt.p_wrttn = 1; /* prevent printing of header line */ 1392145Seric getline(&gpkt); /* skip over old header record */ 1402145Seric gpkt.p_wrttn = 1; 1412145Seric 1422145Seric /* 1432145Seric Write new header. 1442145Seric */ 1452145Seric putline(&gpkt,sprintf(Line,"%c%c00000\n",CTLCHAR,HEAD)); 1462145Seric do_delt(&gpkt); /* read delta table second time */ 1472145Seric 1482145Seric flushto(&gpkt,EUSERNAM,0); 1492145Seric flushto(&gpkt,EUSERTXT,0); 1502145Seric while(getline(&gpkt)) 1512145Seric ; 1522145Seric 1532145Seric flushline(&gpkt,0); /* flush buffer, fix header, and close */ 1542145Seric rename(auxf(gpkt.p_file,'x'),gpkt.p_file); 1552145Seric xrm(&gpkt); 1562145Seric unlockit(auxf(gpkt.p_file,'z'),getpid()); 1572145Seric return; 1582145Seric } 1592145Seric 1602145Seric 161*30498Slepreau static char cle[] = "comment line for initial delta already exists"; 1622145Seric 1632145Seric do_delt(pkt) 1642145Seric register struct packet *pkt; 1652145Seric { 1662145Seric int n; 167*30498Slepreau int did_zero = 0; 1682145Seric struct deltab dt; 1692145Seric struct stats stats; 1702145Seric 1712145Seric while(getstats(pkt,&stats)) { 1722145Seric if(getadel(pkt,&dt) != BDELTAB) 1732145Seric fmterr(pkt); 1742145Seric if(dt.d_type == 'D' && dt.d_pred == 0) { 1752145Seric copy(dt.d_pgmr,Pgmr); 1762145Seric if (First) 1772145Seric did_zero++; 1782145Seric else { 1792145Seric putline(pkt,0); 1802145Seric fixintdel(); 1812145Seric } 1822145Seric } 1832145Seric while((n = getline(pkt)) != NULL) 1842145Seric if (pkt->p_line[0] != CTLCHAR) 1852145Seric break; 1862145Seric else { 1872145Seric switch(pkt->p_line[1]) { 1882145Seric case EDELTAB: 1892145Seric break; 1902145Seric case INCLUDE: 1912145Seric case EXCLUDE: 1922145Seric case IGNORE: 1932145Seric case MRNUM: 1942145Seric continue; 1952145Seric case COMMENTS: 1962145Seric if (First) 1972145Seric if(did_zero) 1982145Seric fatal(cle); 1992145Seric continue; 2002145Seric default: 2012145Seric fmterr(pkt); 2022145Seric } 2032145Seric break; 2042145Seric } 2052145Seric if (n ==NULL || pkt->p_line[0] != CTLCHAR) 2062145Seric fmterr(pkt); 2072145Seric } 2082145Seric First = 0; 2092145Seric } 2102145Seric 2112145Seric 2122145Seric getadel(pkt,dt) 2132145Seric register struct packet *pkt; 2142145Seric register struct deltab *dt; 2152145Seric { 2162145Seric if (getline(pkt) == NULL) 2172145Seric fmterr(pkt); 2182145Seric return(del_ab(pkt->p_line,dt,pkt)); 2192145Seric } 2202145Seric 2212145Seric 2222145Seric getstats(pkt,statp) 2232145Seric register struct packet *pkt; 2242145Seric register struct stats *statp; 2252145Seric { 2262145Seric register char *p; 2272145Seric extern char *satoi(); 2282145Seric 2292145Seric p = pkt->p_line; 2302145Seric if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS) 2312145Seric return(0); 2322145Seric NONBLANK(p); 2332145Seric p = satoi(p,&statp->s_ins); 2342145Seric p = satoi(++p,&statp->s_del); 2352145Seric satoi(++p,&statp->s_unc); 2362145Seric return(1); 2372145Seric } 2382145Seric 2392145Seric clean_up(n) 2402145Seric { 2412145Seric if (gpkt.p_file[0]) 2422145Seric unlockit(auxf(gpkt.p_file,'z'),getpid()); 2432145Seric if (gpkt.p_iop) 2442145Seric fclose(gpkt.p_iop); 2452145Seric 2462145Seric xrm(&gpkt); 2472145Seric if (exists(auxf(gpkt.p_file,'x'))) 2482145Seric remove(auxf(gpkt.p_file,'x')); /* remove x-file */ 2492145Seric Xiop = 0; 2502145Seric if (F_Opened) 2512145Seric fclose(iop); 2522145Seric iop = F_Opened = Opened = 0; 2532145Seric xfreeall(); 2542145Seric } 2552145Seric 2562145Seric 2572145Seric fixintdel() 2582145Seric { 2592145Seric 2602145Seric register char *p; 2612145Seric register int doprmt; 2622145Seric int tty[3]; 2632145Seric char str[128]; 2642145Seric 2652145Seric doprmt = 0; 2662145Seric if (gtty(0,tty) >= 0) 2672145Seric doprmt++; 2682145Seric 2692145Seric if (!HADF && !had_ffile) { 2702145Seric Opened++; 2712145Seric iop = stdin; 2722145Seric } 2732145Seric else if (HADF && had_ffile) { 2742145Seric iop = xfopen(ffile,0); 2752145Seric doprmt = 0; 2762145Seric Opened++; 2772145Seric F_Opened++; 2782145Seric } 2792145Seric else if (HADF && !had_ffile) 2802145Seric doprmt = 0; 2812145Seric 2822145Seric if ((p = Sflags[VALFLAG - 'a'])) { 2832145Seric if (doprmt) 2842145Seric printf("MRs? "); 2852145Seric if (Opened) { 2862145Seric Mrs = getinput(" ",Mstr); 2872145Seric mrfixup(); 2882145Seric if (*p && valmrs(&gpkt,p)) 2892145Seric fatal("invalid MRs (de9)"); 2902145Seric putmrs(&gpkt); 2912145Seric } 2922145Seric else putline(&gpkt,sprintf(Line,CTLSTR,CTLCHAR,MRNUM)); 2932145Seric } 2942145Seric if (doprmt) 2952145Seric printf("comments? "); 2962145Seric if (Opened) { 2972145Seric Comments = getinput(sprintf(Line,"\n%c%c ",CTLCHAR,COMMENTS), 2982145Seric Cstr); 2992145Seric putline(&gpkt,sprintf(str,"%c%c ",CTLCHAR,COMMENTS)); 3002145Seric putline(&gpkt,Comments); 3012145Seric putline(&gpkt,"\n"); 3022145Seric } 3032145Seric else putline(&gpkt,sprintf(Line,CTLSTR,CTLCHAR,COMMENTS)); 3042145Seric 3052145Seric if (F_Opened) 3062145Seric fclose(iop); 3072145Seric F_Opened = Opened = 0; 3082145Seric } 3092145Seric 3102145Seric 3112145Seric getinput(repstr,result) 3122145Seric char *repstr; 3132145Seric char *result; 3142145Seric { 3152145Seric char line[BUFSIZ]; 3162145Seric register int done, sz; 3172145Seric register char *p; 3182145Seric 3192145Seric result[0] = 0; 3202145Seric done = 0; 3212145Seric setbuf(iop,NULL); 3222145Seric sz = sizeof(line) - size(repstr); 3232145Seric while (!done && fgets(line,sz,iop) != NULL) { 32419941Ssam p = index(line, '\0'); 3252145Seric if (*--p == '\n') { 3262145Seric if (*--p == '\\') { 3272145Seric copy(repstr,p); 3282145Seric } 3292145Seric else { 3302145Seric *++p = 0; 3312145Seric ++done; 3322145Seric } 3332145Seric } 3342145Seric else 3352145Seric fatal("line too long (co18)"); 3362145Seric if ((size(line) + size(result)) > RESPSIZE) 3372145Seric fatal("response too long (co19)"); 3382145Seric strcat(result,line); 3392145Seric } 3402145Seric return(result); 3412145Seric } 3422145Seric 3432145Seric 3442145Seric putmrs(pkt) 3452145Seric struct packet *pkt; 3462145Seric { 3472145Seric register char **argv; 3482145Seric char str[64]; 3492145Seric extern char *Varg[]; 3502145Seric 3512145Seric for (argv = &Varg[VSTART]; *argv; argv++) 3522145Seric putline(pkt,sprintf(str,"%c%c %s\n",CTLCHAR,MRNUM,*argv)); 3532145Seric } 354