1*2145Seric # include "../hdr/defines.h" 2*2145Seric # include "../hdr/had.h" 3*2145Seric 4*2145Seric SCCSID(@(#)cmt.c 4.1); 5*2145Seric 6*2145Seric struct packet gpkt; 7*2145Seric int num_files, had_ffile; 8*2145Seric int F_Opened, Opened, Domrs, First; 9*2145Seric char *Comments, *Mrs, *ffile; 10*2145Seric char Cstr[BUFSIZ], Mstr[BUFSIZ], Line[BUFSIZ], had[26]; 11*2145Seric FILE *iop, *Xiop; 12*2145Seric static char ifde[] "initial file does not exists"; 13*2145Seric 14*2145Seric main(argc,argv) 15*2145Seric int argc; 16*2145Seric register char *argv[]; 17*2145Seric { 18*2145Seric register int i; 19*2145Seric register char *p; 20*2145Seric char c; 21*2145Seric extern cmt(); 22*2145Seric extern int Fcnt; 23*2145Seric 24*2145Seric /* 25*2145Seric Flags for 'fatal'. 26*2145Seric */ 27*2145Seric Fflags = FTLEXIT | FTLMSG | FTLCLN; 28*2145Seric 29*2145Seric /* 30*2145Seric Process arguments. 31*2145Seric */ 32*2145Seric for (i = 1; i < argc; i++) 33*2145Seric if (argv[i][0] == '-' && (c = argv[i][1])) { 34*2145Seric p = &argv[i][2]; 35*2145Seric switch (c) { 36*2145Seric case 'f': 37*2145Seric if (*p) { 38*2145Seric ffile = p; 39*2145Seric ++had_ffile; 40*2145Seric if (!exists(ffile)) 41*2145Seric fatal(ifde); 42*2145Seric } 43*2145Seric break; 44*2145Seric default: 45*2145Seric fatal("unknown key letter (cm1)"); 46*2145Seric } 47*2145Seric if (had[c - 'a']++) 48*2145Seric fatal("key letter twice (cm2)"); 49*2145Seric argv[i] = 0; 50*2145Seric } 51*2145Seric else num_files++; 52*2145Seric 53*2145Seric if(num_files == 0) 54*2145Seric fatal("missing file arg (cm3)"); 55*2145Seric 56*2145Seric setsig(); 57*2145Seric /* 58*2145Seric Reset flags for 'fatal' so that it will return to 'main' 59*2145Seric rather than exiting. 60*2145Seric */ 61*2145Seric Fflags =& ~FTLEXIT; 62*2145Seric Fflags =| FTLJMP; 63*2145Seric 64*2145Seric /* 65*2145Seric Invoke 'cmt' for each file argument. 66*2145Seric */ 67*2145Seric for (i = 1; i < argc; i++) 68*2145Seric if (p = argv[i]) 69*2145Seric do_file(p,cmt); 70*2145Seric 71*2145Seric exit(Fcnt ? 1 : 0); 72*2145Seric } 73*2145Seric 74*2145Seric 75*2145Seric static char s_warn[] "WARNING: MR flag is set; `%s' should contain both MR line and comment line\n"; 76*2145Seric 77*2145Seric static char ns_warn[] "WARNING: MR flag is not set; `%s' should only contain comment line\n"; 78*2145Seric 79*2145Seric cmt(file) 80*2145Seric register char *file; 81*2145Seric { 82*2145Seric extern char had_dir, had_standinp; 83*2145Seric extern char *Sflags[]; 84*2145Seric extern char Pgmr[8]; 85*2145Seric char line[BUFSIZ]; 86*2145Seric int fowner, downer, user; 87*2145Seric 88*2145Seric /* 89*2145Seric Set up to return to caller ('main') from 'fatal'. 90*2145Seric */ 91*2145Seric if (setjmp(Fjmp)) 92*2145Seric return; 93*2145Seric 94*2145Seric sinit(&gpkt,file,1); /* init packet and open file */ 95*2145Seric 96*2145Seric if (lockit(auxf(gpkt.p_file,'z'),2,getpid())) 97*2145Seric fatal("cannot create lock file (cm4)"); 98*2145Seric 99*2145Seric if (num_files > 1 || had_dir || had_standinp) 100*2145Seric printf("\n%s:\n",gpkt.p_file); 101*2145Seric 102*2145Seric First = 1; 103*2145Seric gpkt.p_reopen = 1; 104*2145Seric do_delt(&gpkt); /* read delta table for First time */ 105*2145Seric finduser(&gpkt); 106*2145Seric doflags(&gpkt); /* get flags (see if v flag is set) */ 107*2145Seric permiss(&gpkt); 108*2145Seric 109*2145Seric /* 110*2145Seric Check that user is either owner of file or 111*2145Seric directory, or is one who made the initial delta 112*2145Seric */ 113*2145Seric 114*2145Seric fstat(fileno(gpkt.p_iop),&Statbuf); 115*2145Seric fowner = Statbuf.st_uid & 0377; 116*2145Seric copy(gpkt.p_file,line); /* temporary for dname() */ 117*2145Seric if (stat(dname(line),&Statbuf)) 118*2145Seric downer = -1; 119*2145Seric else downer = Statbuf.st_uid & 0377; 120*2145Seric user = getuid() & 0377; 121*2145Seric if (user != fowner || user != downer) 122*2145Seric if (!equal(Pgmr,logname())) 123*2145Seric fatal(sprintf(Error, 124*2145Seric "you are neither owner nor '%s' (rc4)",Pgmr)); 125*2145Seric 126*2145Seric if ((HADF && had_ffile)) { 127*2145Seric if (Sflags[VALFLAG - 'a']) 128*2145Seric fprintf(stderr,s_warn,ffile); 129*2145Seric else fprintf(stderr,ns_warn,ffile); 130*2145Seric sleep(5); 131*2145Seric } 132*2145Seric flushto(&gpkt,EUSERTXT,1); 133*2145Seric gpkt.p_chkeof = 1; /* indicate that EOF is okay */ 134*2145Seric while (getline(&gpkt)) /* this will read body checking for cor */ 135*2145Seric ; 136*2145Seric 137*2145Seric gpkt.p_upd = 1; /* x-file is to be used */ 138*2145Seric gpkt.p_wrttn = 1; /* prevent printing of header line */ 139*2145Seric getline(&gpkt); /* skip over old header record */ 140*2145Seric gpkt.p_wrttn = 1; 141*2145Seric 142*2145Seric /* 143*2145Seric Write new header. 144*2145Seric */ 145*2145Seric putline(&gpkt,sprintf(Line,"%c%c00000\n",CTLCHAR,HEAD)); 146*2145Seric do_delt(&gpkt); /* read delta table second time */ 147*2145Seric 148*2145Seric flushto(&gpkt,EUSERNAM,0); 149*2145Seric flushto(&gpkt,EUSERTXT,0); 150*2145Seric while(getline(&gpkt)) 151*2145Seric ; 152*2145Seric 153*2145Seric flushline(&gpkt,0); /* flush buffer, fix header, and close */ 154*2145Seric rename(auxf(gpkt.p_file,'x'),gpkt.p_file); 155*2145Seric xrm(&gpkt); 156*2145Seric unlockit(auxf(gpkt.p_file,'z'),getpid()); 157*2145Seric return; 158*2145Seric } 159*2145Seric 160*2145Seric 161*2145Seric static char cle[] "comment line for initial delta already exists"; 162*2145Seric 163*2145Seric do_delt(pkt) 164*2145Seric register struct packet *pkt; 165*2145Seric { 166*2145Seric int n; 167*2145Seric int did_zero 0; 168*2145Seric struct deltab dt; 169*2145Seric struct stats stats; 170*2145Seric 171*2145Seric while(getstats(pkt,&stats)) { 172*2145Seric if(getadel(pkt,&dt) != BDELTAB) 173*2145Seric fmterr(pkt); 174*2145Seric if(dt.d_type == 'D' && dt.d_pred == 0) { 175*2145Seric copy(dt.d_pgmr,Pgmr); 176*2145Seric if (First) 177*2145Seric did_zero++; 178*2145Seric else { 179*2145Seric putline(pkt,0); 180*2145Seric fixintdel(); 181*2145Seric } 182*2145Seric } 183*2145Seric while((n = getline(pkt)) != NULL) 184*2145Seric if (pkt->p_line[0] != CTLCHAR) 185*2145Seric break; 186*2145Seric else { 187*2145Seric switch(pkt->p_line[1]) { 188*2145Seric case EDELTAB: 189*2145Seric break; 190*2145Seric case INCLUDE: 191*2145Seric case EXCLUDE: 192*2145Seric case IGNORE: 193*2145Seric case MRNUM: 194*2145Seric continue; 195*2145Seric case COMMENTS: 196*2145Seric if (First) 197*2145Seric if(did_zero) 198*2145Seric fatal(cle); 199*2145Seric continue; 200*2145Seric default: 201*2145Seric fmterr(pkt); 202*2145Seric } 203*2145Seric break; 204*2145Seric } 205*2145Seric if (n ==NULL || pkt->p_line[0] != CTLCHAR) 206*2145Seric fmterr(pkt); 207*2145Seric } 208*2145Seric First = 0; 209*2145Seric } 210*2145Seric 211*2145Seric 212*2145Seric getadel(pkt,dt) 213*2145Seric register struct packet *pkt; 214*2145Seric register struct deltab *dt; 215*2145Seric { 216*2145Seric if (getline(pkt) == NULL) 217*2145Seric fmterr(pkt); 218*2145Seric return(del_ab(pkt->p_line,dt,pkt)); 219*2145Seric } 220*2145Seric 221*2145Seric 222*2145Seric getstats(pkt,statp) 223*2145Seric register struct packet *pkt; 224*2145Seric register struct stats *statp; 225*2145Seric { 226*2145Seric register char *p; 227*2145Seric extern char *satoi(); 228*2145Seric 229*2145Seric p = pkt->p_line; 230*2145Seric if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS) 231*2145Seric return(0); 232*2145Seric NONBLANK(p); 233*2145Seric p = satoi(p,&statp->s_ins); 234*2145Seric p = satoi(++p,&statp->s_del); 235*2145Seric satoi(++p,&statp->s_unc); 236*2145Seric return(1); 237*2145Seric } 238*2145Seric 239*2145Seric clean_up(n) 240*2145Seric { 241*2145Seric if (gpkt.p_file[0]) 242*2145Seric unlockit(auxf(gpkt.p_file,'z'),getpid()); 243*2145Seric if (gpkt.p_iop) 244*2145Seric fclose(gpkt.p_iop); 245*2145Seric 246*2145Seric xrm(&gpkt); 247*2145Seric if (exists(auxf(gpkt.p_file,'x'))) 248*2145Seric remove(auxf(gpkt.p_file,'x')); /* remove x-file */ 249*2145Seric Xiop = 0; 250*2145Seric if (F_Opened) 251*2145Seric fclose(iop); 252*2145Seric iop = F_Opened = Opened = 0; 253*2145Seric xfreeall(); 254*2145Seric } 255*2145Seric 256*2145Seric 257*2145Seric fixintdel() 258*2145Seric { 259*2145Seric 260*2145Seric register char *p; 261*2145Seric register int doprmt; 262*2145Seric int tty[3]; 263*2145Seric char str[128]; 264*2145Seric 265*2145Seric doprmt = 0; 266*2145Seric if (gtty(0,tty) >= 0) 267*2145Seric doprmt++; 268*2145Seric 269*2145Seric if (!HADF && !had_ffile) { 270*2145Seric Opened++; 271*2145Seric iop = stdin; 272*2145Seric } 273*2145Seric else if (HADF && had_ffile) { 274*2145Seric iop = xfopen(ffile,0); 275*2145Seric doprmt = 0; 276*2145Seric Opened++; 277*2145Seric F_Opened++; 278*2145Seric } 279*2145Seric else if (HADF && !had_ffile) 280*2145Seric doprmt = 0; 281*2145Seric 282*2145Seric if ((p = Sflags[VALFLAG - 'a'])) { 283*2145Seric if (doprmt) 284*2145Seric printf("MRs? "); 285*2145Seric if (Opened) { 286*2145Seric Mrs = getinput(" ",Mstr); 287*2145Seric mrfixup(); 288*2145Seric if (*p && valmrs(&gpkt,p)) 289*2145Seric fatal("invalid MRs (de9)"); 290*2145Seric putmrs(&gpkt); 291*2145Seric } 292*2145Seric else putline(&gpkt,sprintf(Line,CTLSTR,CTLCHAR,MRNUM)); 293*2145Seric } 294*2145Seric if (doprmt) 295*2145Seric printf("comments? "); 296*2145Seric if (Opened) { 297*2145Seric Comments = getinput(sprintf(Line,"\n%c%c ",CTLCHAR,COMMENTS), 298*2145Seric Cstr); 299*2145Seric putline(&gpkt,sprintf(str,"%c%c ",CTLCHAR,COMMENTS)); 300*2145Seric putline(&gpkt,Comments); 301*2145Seric putline(&gpkt,"\n"); 302*2145Seric } 303*2145Seric else putline(&gpkt,sprintf(Line,CTLSTR,CTLCHAR,COMMENTS)); 304*2145Seric 305*2145Seric if (F_Opened) 306*2145Seric fclose(iop); 307*2145Seric F_Opened = Opened = 0; 308*2145Seric } 309*2145Seric 310*2145Seric 311*2145Seric getinput(repstr,result) 312*2145Seric char *repstr; 313*2145Seric char *result; 314*2145Seric { 315*2145Seric char line[BUFSIZ]; 316*2145Seric register int done, sz; 317*2145Seric register char *p; 318*2145Seric 319*2145Seric result[0] = 0; 320*2145Seric done = 0; 321*2145Seric setbuf(iop,NULL); 322*2145Seric sz = sizeof(line) - size(repstr); 323*2145Seric while (!done && fgets(line,sz,iop) != NULL) { 324*2145Seric p = strend(line); 325*2145Seric if (*--p == '\n') { 326*2145Seric if (*--p == '\\') { 327*2145Seric copy(repstr,p); 328*2145Seric } 329*2145Seric else { 330*2145Seric *++p = 0; 331*2145Seric ++done; 332*2145Seric } 333*2145Seric } 334*2145Seric else 335*2145Seric fatal("line too long (co18)"); 336*2145Seric if ((size(line) + size(result)) > RESPSIZE) 337*2145Seric fatal("response too long (co19)"); 338*2145Seric strcat(result,line); 339*2145Seric } 340*2145Seric return(result); 341*2145Seric } 342*2145Seric 343*2145Seric 344*2145Seric putmrs(pkt) 345*2145Seric struct packet *pkt; 346*2145Seric { 347*2145Seric register char **argv; 348*2145Seric char str[64]; 349*2145Seric extern char *Varg[]; 350*2145Seric 351*2145Seric for (argv = &Varg[VSTART]; *argv; argv++) 352*2145Seric putline(pkt,sprintf(str,"%c%c %s\n",CTLCHAR,MRNUM,*argv)); 353*2145Seric } 354