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