12145Seric # include "../hdr/defines.h" 22145Seric # include "../hdr/had.h" 32145Seric 4*33423Sbostic static char Sccsid[] = "@(#)cmt.c 4.5 02/02/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 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 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) 122*33423Sbostic if (!equal(Pgmr,logname())) { 123*33423Sbostic sprintf(Error, "you are neither owner nor '%s' (rc4)",Pgmr); 124*33423Sbostic fatal(Error); 125*33423Sbostic } 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 */ 146*33423Sbostic sprintf(Line,"%c%c00000\n",CTLCHAR,HEAD); 147*33423Sbostic 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 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 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 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 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 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 } 294*33423Sbostic else { 295*33423Sbostic sprintf(Line,CTLSTR,CTLCHAR,MRNUM); 296*33423Sbostic putline(&gpkt,Line); 297*33423Sbostic } 2982145Seric } 2992145Seric if (doprmt) 3002145Seric printf("comments? "); 3012145Seric if (Opened) { 302*33423Sbostic sprintf(Line,"\n%c%c ",CTLCHAR,COMMENTS); 303*33423Sbostic Comments = getinput(Line,Cstr); 304*33423Sbostic sprintf(str,"%c%c ",CTLCHAR,COMMENTS); 305*33423Sbostic putline(&gpkt,str); 3062145Seric putline(&gpkt,Comments); 3072145Seric putline(&gpkt,"\n"); 3082145Seric } 309*33423Sbostic else { 310*33423Sbostic sprintf(Line,CTLSTR,CTLCHAR,COMMENTS); 311*33423Sbostic putline(&gpkt,Line); 312*33423Sbostic } 3132145Seric 3142145Seric if (F_Opened) 3152145Seric fclose(iop); 3162145Seric F_Opened = Opened = 0; 3172145Seric } 3182145Seric 3192145Seric 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 360*33423Sbostic for (argv = &Varg[VSTART]; *argv; argv++) { 361*33423Sbostic sprintf(str,"%c%c %s\n",CTLCHAR,MRNUM,*argv); 362*33423Sbostic putline(pkt,str); 363*33423Sbostic } 3642145Seric } 365