1*2154Seric /************************************************************************/ 2*2154Seric /* */ 3*2154Seric /* val - */ 4*2154Seric /* val [-mname] [-rSID] [-s] [-ytype] file ... */ 5*2154Seric /* */ 6*2154Seric /************************************************************************/ 7*2154Seric 8*2154Seric # include "../hdr/defines.h" 9*2154Seric # include "../hdr/had.h" 10*2154Seric 11*2154Seric # define FILARG_ERR 0200 /* no file name given */ 12*2154Seric # define UNKDUP_ERR 0100 /* unknown or duplicate keyletter */ 13*2154Seric # define CORRUPT_ERR 040 /* corrupt file error code */ 14*2154Seric # define FILENAM_ERR 020 /* file name error code */ 15*2154Seric # define INVALSID_ERR 010 /* invalid or ambiguous SID error */ 16*2154Seric # define NONEXSID_ERR 04 /* non-existent SID error code */ 17*2154Seric # define TYPE_ERR 02 /* type arg value error code */ 18*2154Seric # define NAME_ERR 01 /* name arg value error code */ 19*2154Seric # define TRUE 1 20*2154Seric # define FALSE 0 21*2154Seric # define BLANK(l) while (!(*l == ' ' || *l == '\t')) l++; 22*2154Seric 23*2154Seric int ret_code; /* prime return code from 'main' program */ 24*2154Seric int inline_err; /* input line error code (from 'process') */ 25*2154Seric int infile_err; /* file error code (from 'validate') */ 26*2154Seric int inpstd; /* TRUE = args from standard input */ 27*2154Seric 28*2154Seric struct packet gpkt; 29*2154Seric 30*2154Seric char had[26]; /* had flag used in 'process' function */ 31*2154Seric char path[50]; /* storage for file name value */ 32*2154Seric char sid[50]; /* storage for sid (-r) value */ 33*2154Seric char type[50]; /* storage for type (-y) value */ 34*2154Seric char name[50]; /* storage for name (-m) value */ 35*2154Seric char line[BUFSIZ]; 36*2154Seric char *get_line(); /* function returning ptr to line read */ 37*2154Seric char *getval(); /* function returning adjusted ptr to line */ 38*2154Seric char *alloc(); /* function returning ptr */ 39*2154Seric char *fgets(); /* function returning i/o ptr */ 40*2154Seric 41*2154Seric struct delent { /* structure for delta table entry */ 42*2154Seric char type; 43*2154Seric char *osid; 44*2154Seric char *datetime; 45*2154Seric char *pgmr; 46*2154Seric char *serial; 47*2154Seric char *pred; 48*2154Seric } del; 49*2154Seric 50*2154Seric SCCSID(@(#)val.c 4.1); 51*2154Seric 52*2154Seric /* This is the main program that determines whether the command line 53*2154Seric * comes from the standard input or read off the original command 54*2154Seric * line. See VAL(I) for more information. 55*2154Seric */ 56*2154Seric main(argc,argv) 57*2154Seric int argc; 58*2154Seric char *argv[]; 59*2154Seric { 60*2154Seric FILE *iop; 61*2154Seric register int j; 62*2154Seric 63*2154Seric ret_code = 0; 64*2154Seric if (argc == 2 && argv[1][0] == '-' && !(argv[1][1])) { 65*2154Seric inpstd = TRUE; 66*2154Seric iop = stdin; /* read from standard input */ 67*2154Seric while (fgets(line,BUFSIZ,iop) != NULL) { 68*2154Seric if (line[0] != '\n') { 69*2154Seric repl (line,'\n','\0'); 70*2154Seric process(line); 71*2154Seric ret_code =| inline_err; 72*2154Seric } 73*2154Seric } 74*2154Seric } 75*2154Seric else { 76*2154Seric inpstd = FALSE; 77*2154Seric for (j = 1; j < argc; j++) 78*2154Seric sprintf(&(line[strlen(line)]),"%s ",argv[j]); 79*2154Seric j = strlen(line) - 1; 80*2154Seric line[j > 0 ? j : 0] = NULL; 81*2154Seric process(line); 82*2154Seric ret_code = inline_err; 83*2154Seric } 84*2154Seric exit(ret_code); 85*2154Seric } 86*2154Seric 87*2154Seric 88*2154Seric /* This function processes the line sent by the main routine. It 89*2154Seric * determines which keyletter values are present on the command 90*2154Seric * line and assigns the values to the correct storage place. It 91*2154Seric * then calls validate for each file name on the command line 92*2154Seric * It will return to main if the input line contains an error, 93*2154Seric * otherwise it returns any error code found by validate. 94*2154Seric */ 95*2154Seric process(p_line) 96*2154Seric char *p_line; 97*2154Seric { 98*2154Seric register int j; 99*2154Seric register int testklt; 100*2154Seric register int line_sw; 101*2154Seric 102*2154Seric int silent; 103*2154Seric int num_files; 104*2154Seric 105*2154Seric char filelist[50][50]; 106*2154Seric char *savelinep; 107*2154Seric char c; 108*2154Seric 109*2154Seric silent = FALSE; 110*2154Seric path[0] = sid[0] = type[0] = name[0] = 0; 111*2154Seric num_files = inline_err = 0; 112*2154Seric 113*2154Seric /* 114*2154Seric make copy of 'line' for use later 115*2154Seric */ 116*2154Seric savelinep = p_line; 117*2154Seric /* 118*2154Seric clear out had flags for each 'line' processed 119*2154Seric */ 120*2154Seric for (j = 0; j < 27; j++) 121*2154Seric had[j] = 0; 122*2154Seric /* 123*2154Seric execute loop until all characters in 'line' are checked. 124*2154Seric */ 125*2154Seric while (*p_line) { 126*2154Seric testklt = 1; 127*2154Seric NONBLANK(p_line); 128*2154Seric if (*p_line == '-') { 129*2154Seric p_line =+ 1; 130*2154Seric c = *p_line; 131*2154Seric p_line++; 132*2154Seric switch (c) { 133*2154Seric case 's': 134*2154Seric testklt = 0; 135*2154Seric /* 136*2154Seric turn on 'silent' flag. 137*2154Seric */ 138*2154Seric silent = TRUE; 139*2154Seric break; 140*2154Seric case 'r': 141*2154Seric p_line = getval(p_line,sid); 142*2154Seric break; 143*2154Seric case 'y': 144*2154Seric p_line = getval(p_line,type); 145*2154Seric break; 146*2154Seric case 'm': 147*2154Seric p_line = getval(p_line,name); 148*2154Seric break; 149*2154Seric default: 150*2154Seric inline_err =| UNKDUP_ERR; 151*2154Seric } 152*2154Seric /* 153*2154Seric use 'had' array and determine if the keyletter 154*2154Seric was given twice. 155*2154Seric */ 156*2154Seric if (had[c - 'a']++ && testklt++) 157*2154Seric inline_err =| UNKDUP_ERR; 158*2154Seric } 159*2154Seric else { 160*2154Seric /* 161*2154Seric assume file name if no '-' preceeded argument 162*2154Seric */ 163*2154Seric p_line = getval(p_line,filelist[num_files]); 164*2154Seric num_files++; 165*2154Seric } 166*2154Seric } 167*2154Seric /* 168*2154Seric check if any files were named as arguments 169*2154Seric */ 170*2154Seric if (num_files == 0) 171*2154Seric inline_err =| FILARG_ERR; 172*2154Seric /* 173*2154Seric check for error in command line. 174*2154Seric */ 175*2154Seric if (inline_err && !silent) { 176*2154Seric if (inpstd) 177*2154Seric report(inline_err,savelinep,""); 178*2154Seric else report(inline_err,"",""); 179*2154Seric return; /* return to 'main' routine */ 180*2154Seric } 181*2154Seric line_sw = 1; /* print command line flag */ 182*2154Seric /* 183*2154Seric loop through 'validate' for each file on command line. 184*2154Seric */ 185*2154Seric for (j = 0; j < num_files; j++) { 186*2154Seric /* 187*2154Seric read a file from 'filelist' and place into 'path'. 188*2154Seric */ 189*2154Seric sprintf(path,"%s",filelist[j]); 190*2154Seric validate(path,sid,type,name); 191*2154Seric inline_err =| infile_err; 192*2154Seric /* 193*2154Seric check for error from 'validate' and call 'report' 194*2154Seric depending on 'silent' flag. 195*2154Seric */ 196*2154Seric if (infile_err && !silent) { 197*2154Seric if (line_sw && inpstd) { 198*2154Seric report(infile_err,savelinep,path); 199*2154Seric line_sw = 0; 200*2154Seric } 201*2154Seric else report(infile_err,"",path); 202*2154Seric } 203*2154Seric } 204*2154Seric return; /* return to 'main' routine */ 205*2154Seric } 206*2154Seric 207*2154Seric 208*2154Seric /* This function actually does the validation on the named file. 209*2154Seric * It determines whether the file is an SCCS-file or if the file 210*2154Seric * exists. It also determines if the values given for type, SID, 211*2154Seric * and name match those in the named file. An error code is returned 212*2154Seric * if any mismatch occurs. See VAL(I) for more information. 213*2154Seric */ 214*2154Seric validate(c_path,c_sid,c_type,c_name) 215*2154Seric char *c_path; 216*2154Seric char *c_sid; 217*2154Seric char *c_type; 218*2154Seric char *c_name; 219*2154Seric { 220*2154Seric register char *l; 221*2154Seric int goods,goodt,goodn,hadmflag; 222*2154Seric 223*2154Seric infile_err = goods = goodt = goodn = hadmflag = 0; 224*2154Seric sinit(&gpkt,c_path); 225*2154Seric if (!sccsfile(c_path) || (gpkt.p_iop = fopen(c_path,"r")) == NULL) 226*2154Seric infile_err =| FILENAM_ERR; 227*2154Seric else { 228*2154Seric l = get_line(&gpkt); /* read first line in file */ 229*2154Seric /* 230*2154Seric check that it is header line. 231*2154Seric */ 232*2154Seric if (*l++ != CTLCHAR || *l++ != HEAD) 233*2154Seric infile_err =| CORRUPT_ERR; 234*2154Seric 235*2154Seric else { 236*2154Seric /* 237*2154Seric get old file checksum count 238*2154Seric */ 239*2154Seric satoi(l,&gpkt.p_ihash); 240*2154Seric gpkt.p_chash = 0; 241*2154Seric if (HADR) 242*2154Seric /* 243*2154Seric check for invalid or ambiguous SID. 244*2154Seric */ 245*2154Seric if (invalid(c_sid)) 246*2154Seric infile_err =| INVALSID_ERR; 247*2154Seric /* 248*2154Seric read delta table checking for errors and/or 249*2154Seric SID. 250*2154Seric */ 251*2154Seric if (do_delt(&gpkt,goods,c_sid)) { 252*2154Seric fclose(gpkt.p_iop); 253*2154Seric infile_err =| CORRUPT_ERR; 254*2154Seric return; 255*2154Seric } 256*2154Seric 257*2154Seric read_to(EUSERNAM,&gpkt); 258*2154Seric 259*2154Seric if (HADY || HADM) { 260*2154Seric /* 261*2154Seric read flag section of delta table. 262*2154Seric */ 263*2154Seric while ((l = get_line(&gpkt)) && 264*2154Seric *l++ == CTLCHAR && 265*2154Seric *l++ == FLAG) { 266*2154Seric NONBLANK(l); 267*2154Seric repl(l,'\n','\0'); 268*2154Seric if (*l == TYPEFLAG) { 269*2154Seric l =+ 2; 270*2154Seric if (equal(c_type,l)) 271*2154Seric goodt++; 272*2154Seric } 273*2154Seric else if (*l == MODFLAG) { 274*2154Seric hadmflag++; 275*2154Seric l =+ 2; 276*2154Seric if (equal(c_name,l)) 277*2154Seric goodn++; 278*2154Seric } 279*2154Seric } 280*2154Seric if (*(--l) != BUSERTXT) { 281*2154Seric fclose(gpkt.p_iop); 282*2154Seric infile_err =| CORRUPT_ERR; 283*2154Seric return; 284*2154Seric } 285*2154Seric /* 286*2154Seric check if 'y' flag matched '-y' arg value. 287*2154Seric */ 288*2154Seric if (!goodt && HADY) 289*2154Seric infile_err =| TYPE_ERR; 290*2154Seric /* 291*2154Seric check if 'm' flag matched '-m' arg value. 292*2154Seric */ 293*2154Seric if (HADM && !hadmflag) { 294*2154Seric if (!equal(auxf(sname(c_path),'g'),c_name)) 295*2154Seric infile_err =| NAME_ERR; 296*2154Seric } 297*2154Seric else if (HADM && hadmflag && !goodn) 298*2154Seric infile_err =| NAME_ERR; 299*2154Seric } 300*2154Seric else read_to(BUSERTXT,&gpkt); 301*2154Seric read_to(EUSERTXT,&gpkt); 302*2154Seric gpkt.p_chkeof = 1; 303*2154Seric /* 304*2154Seric read remainder of file so 'read_mod' 305*2154Seric can check for corruptness. 306*2154Seric */ 307*2154Seric while (read_mod(&gpkt)) 308*2154Seric ; 309*2154Seric } 310*2154Seric fclose(gpkt.p_iop); /* close file pointer */ 311*2154Seric } 312*2154Seric return; /* return to 'process' function */ 313*2154Seric } 314*2154Seric 315*2154Seric 316*2154Seric /* This function reads the 'delta' line from the named file and stores 317*2154Seric * the information into the structure 'del'. 318*2154Seric */ 319*2154Seric getdel(delp,lp) 320*2154Seric register struct delent *delp; 321*2154Seric register char *lp; 322*2154Seric { 323*2154Seric NONBLANK(lp); 324*2154Seric delp->type = *lp++; 325*2154Seric NONBLANK(lp); 326*2154Seric delp->osid = lp; 327*2154Seric BLANK(lp); 328*2154Seric *lp++ = '\0'; 329*2154Seric NONBLANK(lp); 330*2154Seric delp->datetime = lp; 331*2154Seric BLANK(lp); 332*2154Seric NONBLANK(lp); 333*2154Seric BLANK(lp); 334*2154Seric *lp++ = '\0'; 335*2154Seric NONBLANK(lp); 336*2154Seric delp->pgmr = lp; 337*2154Seric BLANK(lp); 338*2154Seric *lp++ = '\0'; 339*2154Seric NONBLANK(lp); 340*2154Seric delp->serial = lp; 341*2154Seric BLANK(lp); 342*2154Seric *lp++ = '\0'; 343*2154Seric NONBLANK(lp); 344*2154Seric delp->pred = lp; 345*2154Seric repl(lp,'\n','\0'); 346*2154Seric } 347*2154Seric 348*2154Seric 349*2154Seric /* This function does a read through the named file until it finds 350*2154Seric * the character sent over as an argument. 351*2154Seric */ 352*2154Seric read_to(ch,pkt) 353*2154Seric register char ch; 354*2154Seric register struct packet *pkt; 355*2154Seric { 356*2154Seric register char *n; 357*2154Seric while ((n = get_line(pkt)) && 358*2154Seric !(*n++ == CTLCHAR && *n == ch)) 359*2154Seric ; 360*2154Seric return; 361*2154Seric } 362*2154Seric 363*2154Seric 364*2154Seric /* This function places into a specified destination characters which 365*2154Seric * are delimited by either a space, tab or 0. It obtains the char- 366*2154Seric * acters from a line of characters. 367*2154Seric */ 368*2154Seric char *getval(sourcep,destp) 369*2154Seric register char *sourcep; 370*2154Seric register char *destp; 371*2154Seric { 372*2154Seric while (*sourcep != ' ' && *sourcep != '\t' && *sourcep != '\0') 373*2154Seric *destp++ = *sourcep++; 374*2154Seric *destp = 0; 375*2154Seric return(sourcep); 376*2154Seric } 377*2154Seric 378*2154Seric 379*2154Seric /* This function will report the error that occured on the command 380*2154Seric * line. It will print one diagnostic message for each error that 381*2154Seric * was found in the named file. 382*2154Seric */ 383*2154Seric report(code,inp_line,file) 384*2154Seric register int code; 385*2154Seric register char *inp_line; 386*2154Seric register char *file; 387*2154Seric { 388*2154Seric char percent; 389*2154Seric percent = '%'; /* '%' for -m and/or -y messages */ 390*2154Seric if (*inp_line) 391*2154Seric printf("%s\n\n",inp_line); 392*2154Seric if (code & NAME_ERR) 393*2154Seric printf(" %s: %cM%c, -m mismatch\n",file,percent,percent); 394*2154Seric if (code & TYPE_ERR) 395*2154Seric printf(" %s: %cY%c, -y mismatch\n",file,percent,percent); 396*2154Seric if (code & NONEXSID_ERR) 397*2154Seric printf(" %s: SID nonexistent\n",file); 398*2154Seric if (code & INVALSID_ERR) 399*2154Seric printf(" %s: SID invalid or ambiguous\n",file); 400*2154Seric if (code & FILENAM_ERR) 401*2154Seric printf(" %s: can't open file or file not SCCS\n",file); 402*2154Seric if (code & CORRUPT_ERR) 403*2154Seric printf(" %s: corrupted SCCS file\n",file); 404*2154Seric if (code & UNKDUP_ERR) 405*2154Seric printf(" %s: Unknown or dupilcate keyletter argument\n",file); 406*2154Seric if (code & FILARG_ERR) 407*2154Seric printf(" %s: missing file argument\n",file); 408*2154Seric return; 409*2154Seric } 410*2154Seric 411*2154Seric 412*2154Seric /* This function takes as it's argument the SID inputed and determines 413*2154Seric * whether or not it is valid (e. g. not ambiguous or illegal). 414*2154Seric */ 415*2154Seric invalid(i_sid) 416*2154Seric register char *i_sid; 417*2154Seric { 418*2154Seric register int count; 419*2154Seric register int digits; 420*2154Seric count = digits = 0; 421*2154Seric if (*i_sid == '0' || *i_sid == '.') 422*2154Seric return (1); 423*2154Seric i_sid++; 424*2154Seric digits++; 425*2154Seric while (*i_sid != '\0') { 426*2154Seric if (*i_sid++ == '.') { 427*2154Seric digits = 0; 428*2154Seric count++; 429*2154Seric if (*i_sid == '0' || *i_sid == '.') 430*2154Seric return (1); 431*2154Seric } 432*2154Seric digits++; 433*2154Seric if (digits > 5) 434*2154Seric return (1); 435*2154Seric } 436*2154Seric if (*(--i_sid) == '.' ) 437*2154Seric return (1); 438*2154Seric if (count == 1 || count == 3) 439*2154Seric return (0); 440*2154Seric return (1); 441*2154Seric } 442*2154Seric 443*2154Seric 444*2154Seric /* 445*2154Seric Routine to read a line into the packet. The main reason for 446*2154Seric it is to make sure that pkt->p_wrttn gets turned off, 447*2154Seric and to increment pkt->p_slnno. 448*2154Seric */ 449*2154Seric 450*2154Seric char *get_line(pkt) 451*2154Seric register struct packet *pkt; 452*2154Seric { 453*2154Seric register char *n; 454*2154Seric register char *p; 455*2154Seric 456*2154Seric if ((n = fgets(pkt->p_line,sizeof(pkt->p_line),pkt->p_iop)) != NULL) { 457*2154Seric pkt->p_slnno++; 458*2154Seric for (p = pkt->p_line; *p; ) 459*2154Seric pkt->p_chash =+ *p++; 460*2154Seric } 461*2154Seric else { 462*2154Seric if (!pkt->p_chkeof) 463*2154Seric infile_err =| CORRUPT_ERR; 464*2154Seric if (pkt->do_chksum && (pkt->p_chash ^ pkt->p_ihash)&0xFFFF) 465*2154Seric infile_err =| CORRUPT_ERR; 466*2154Seric } 467*2154Seric return(n); 468*2154Seric } 469*2154Seric 470*2154Seric 471*2154Seric /* 472*2154Seric Does initialization for sccs files and packet. 473*2154Seric */ 474*2154Seric 475*2154Seric sinit(pkt,file) 476*2154Seric register struct packet *pkt; 477*2154Seric register char *file; 478*2154Seric { 479*2154Seric 480*2154Seric zero(pkt,sizeof(*pkt)); 481*2154Seric copy(file,pkt->p_file); 482*2154Seric pkt->p_wrttn = 1; 483*2154Seric pkt->do_chksum = 1; /* turn on checksum check for getline */ 484*2154Seric } 485*2154Seric 486*2154Seric 487*2154Seric read_mod(pkt) 488*2154Seric register struct packet *pkt; 489*2154Seric { 490*2154Seric register char *p; 491*2154Seric int ser; 492*2154Seric int iord; 493*2154Seric register struct apply *ap; 494*2154Seric 495*2154Seric while (get_line(pkt) != NULL) { 496*2154Seric p = pkt->p_line; 497*2154Seric if (*p++ != CTLCHAR) 498*2154Seric continue; 499*2154Seric else { 500*2154Seric if (!((iord = *p++) == INS || iord == DEL || iord == END)) { 501*2154Seric infile_err =| CORRUPT_ERR; 502*2154Seric return(0); 503*2154Seric } 504*2154Seric NONBLANK(p); 505*2154Seric satoi(p,&ser); 506*2154Seric if (iord == END) 507*2154Seric remq(pkt,ser); 508*2154Seric else if ((ap = &pkt->p_apply[ser])->a_code == APPLY) 509*2154Seric addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER); 510*2154Seric else 511*2154Seric addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER); 512*2154Seric } 513*2154Seric } 514*2154Seric if (pkt->p_q) 515*2154Seric infile_err =| CORRUPT_ERR; 516*2154Seric return(0); 517*2154Seric } 518*2154Seric 519*2154Seric 520*2154Seric addq(pkt,ser,keep,iord,user) 521*2154Seric struct packet *pkt; 522*2154Seric int ser; 523*2154Seric int keep; 524*2154Seric int iord; 525*2154Seric { 526*2154Seric register struct queue *cur, *prev, *q; 527*2154Seric 528*2154Seric for (cur = &pkt->p_q; cur = (prev = cur)->q_next; ) 529*2154Seric if (cur->q_sernum <= ser) 530*2154Seric break; 531*2154Seric if (cur->q_sernum == ser) 532*2154Seric infile_err =| CORRUPT_ERR; 533*2154Seric prev->q_next = q = alloc(sizeof(*q)); 534*2154Seric q->q_next = cur; 535*2154Seric q->q_sernum = ser; 536*2154Seric q->q_keep = keep; 537*2154Seric q->q_iord = iord; 538*2154Seric q->q_user = user; 539*2154Seric if (pkt->p_ixuser && (q->q_ixmsg = chkix(q,&pkt->p_q))) 540*2154Seric ++(pkt->p_ixmsg); 541*2154Seric else 542*2154Seric q->q_ixmsg = 0; 543*2154Seric 544*2154Seric setkeep(pkt); 545*2154Seric } 546*2154Seric 547*2154Seric 548*2154Seric remq(pkt,ser) 549*2154Seric register struct packet *pkt; 550*2154Seric int ser; 551*2154Seric { 552*2154Seric register struct queue *cur, *prev; 553*2154Seric 554*2154Seric for (cur = &pkt->p_q; cur = (prev = cur)->q_next; ) 555*2154Seric if (cur->q_sernum == ser) 556*2154Seric break; 557*2154Seric if (cur) { 558*2154Seric if (cur->q_ixmsg) 559*2154Seric --(pkt->p_ixmsg); 560*2154Seric prev->q_next = cur->q_next; 561*2154Seric free(cur); 562*2154Seric setkeep(pkt); 563*2154Seric } 564*2154Seric else 565*2154Seric infile_err =| CORRUPT_ERR; 566*2154Seric } 567*2154Seric 568*2154Seric 569*2154Seric setkeep(pkt) 570*2154Seric register struct packet *pkt; 571*2154Seric { 572*2154Seric register struct queue *q; 573*2154Seric register struct sid *sp; 574*2154Seric 575*2154Seric for (q = &pkt->p_q; q = q->q_next; ) 576*2154Seric if (q->q_keep != NULL) { 577*2154Seric if ((pkt->p_keep = q->q_keep) == YES) { 578*2154Seric sp = &pkt->p_idel[q->q_sernum].i_sid; 579*2154Seric pkt->p_inssid.s_rel = sp->s_rel; 580*2154Seric pkt->p_inssid.s_lev = sp->s_lev; 581*2154Seric pkt->p_inssid.s_br = sp->s_br; 582*2154Seric pkt->p_inssid.s_seq = sp->s_seq; 583*2154Seric } 584*2154Seric return; 585*2154Seric } 586*2154Seric pkt->p_keep = NO; 587*2154Seric } 588*2154Seric 589*2154Seric 590*2154Seric # define apply(qp) ((qp->q_iord == INS && qp->q_keep == YES) || (qp->q_iord == DEL && qp->q_keep == NO)) 591*2154Seric 592*2154Seric chkix(new,head) 593*2154Seric register struct queue *new; 594*2154Seric struct queue *head; 595*2154Seric { 596*2154Seric register int retval; 597*2154Seric register struct queue *cur; 598*2154Seric int firstins, lastdel; 599*2154Seric 600*2154Seric if (!apply(new)) 601*2154Seric return(0); 602*2154Seric for (cur = head; cur = cur->q_next; ) 603*2154Seric if (cur->q_user) 604*2154Seric break; 605*2154Seric if (!cur) 606*2154Seric return(0); 607*2154Seric retval = 0; 608*2154Seric firstins = 0; 609*2154Seric lastdel = 0; 610*2154Seric for (cur = head; cur = cur->q_next; ) { 611*2154Seric if (apply(cur)) { 612*2154Seric if (cur->q_iord == DEL) 613*2154Seric lastdel = cur->q_sernum; 614*2154Seric else if (firstins == 0) 615*2154Seric firstins = cur->q_sernum; 616*2154Seric } 617*2154Seric else if (cur->q_iord == INS) 618*2154Seric retval++; 619*2154Seric } 620*2154Seric if (retval == 0) { 621*2154Seric if (lastdel && (new->q_sernum > lastdel)) 622*2154Seric retval++; 623*2154Seric if (firstins && (new->q_sernum < firstins)) 624*2154Seric retval++; 625*2154Seric } 626*2154Seric return(retval); 627*2154Seric } 628*2154Seric 629*2154Seric 630*2154Seric /* This function reads the delta table entries and checks for the format 631*2154Seric * as specifed in sccsfile(V). If the format is incorrect, a corrupt 632*2154Seric * error will be issued by 'val'. This function also checks 633*2154Seric * if the sid requested is in the file (depending if '-r' was specified). 634*2154Seric */ 635*2154Seric do_delt(pkt,goods,d_sid) 636*2154Seric register struct packet *pkt; 637*2154Seric register int goods; 638*2154Seric register char *d_sid; 639*2154Seric { 640*2154Seric char *l; 641*2154Seric 642*2154Seric while(getstats(pkt)) { 643*2154Seric if ((l = get_line(pkt)) && *l++ != CTLCHAR || *l++ != BDELTAB) 644*2154Seric return(1); 645*2154Seric if (HADR && !(infile_err & INVALSID_ERR)) { 646*2154Seric getdel(&del,l); 647*2154Seric if (equal(d_sid,del.osid) && del.type == 'D') 648*2154Seric goods++; 649*2154Seric } 650*2154Seric while ((l = get_line(pkt)) != NULL) 651*2154Seric if (pkt->p_line[0] != CTLCHAR) 652*2154Seric break; 653*2154Seric else { 654*2154Seric switch(pkt->p_line[1]) { 655*2154Seric case EDELTAB: 656*2154Seric break; 657*2154Seric case COMMENTS: 658*2154Seric case MRNUM: 659*2154Seric case INCLUDE: 660*2154Seric case EXCLUDE: 661*2154Seric case IGNORE: 662*2154Seric continue; 663*2154Seric default: 664*2154Seric return(1); 665*2154Seric } 666*2154Seric break; 667*2154Seric } 668*2154Seric if (l == NULL || pkt->p_line[0] != CTLCHAR) 669*2154Seric return(1); 670*2154Seric } 671*2154Seric if (pkt->p_line[1] != BUSERNAM) 672*2154Seric return(1); 673*2154Seric if (HADR && !goods && !(infile_err & INVALSID_ERR)) 674*2154Seric infile_err =| NONEXSID_ERR; 675*2154Seric return(0); 676*2154Seric } 677*2154Seric 678*2154Seric 679*2154Seric /* This function reads the stats line from the sccsfile */ 680*2154Seric getstats(pkt) 681*2154Seric register struct packet *pkt; 682*2154Seric { 683*2154Seric register char *p; 684*2154Seric p = pkt->p_line; 685*2154Seric if (get_line(pkt) == NULL || *p++ != CTLCHAR || *p != STATS) 686*2154Seric return(0); 687*2154Seric return(1); 688*2154Seric } 689