# include "../hdr/defines.h" # include "../hdr/had.h" static char Sccsid[] = "@(#)rmchg.c 4.4 02/02/88"; /* Program to remove a specified delta from an SCCS file, when invoked as 'rmdel', or to change the MRs and/or comments of a specified delta, when invoked as 'chghist'. (The program has two links to it, one called 'rmdel', the other 'chghist'.) The delta to be removed (or whose MRs and/or comments are to be changed) is specified via the r argument, in the form of an SID. If the delta is to be removed, it must be the most recent one in its branch in the delta tree (a so-called 'leaf' delta). For either function, the delta being processed must not have any 'delivered' MRs, and the user must have basically the same permissions as are required to make deltas. If a directory is given as an argument, each SCCS file within the directory will be processed as if it had been specifically named. If a name of '-' is given, the standard input will be read for a list of names of SCCS files to be processed. Non SCCS files are ignored. */ # define COPY 0 # define NOCOPY 1 struct sid sid; int num_files; char had[26]; char D_type; int D_serial; main(argc,argv) int argc; char *argv[]; { register int i; register char *p; char c; extern rmchg(); extern int Fcnt; /* Set flags for 'fatal' to issue message, call clean-up routine, and terminate processing. */ Fflags = FTLMSG | FTLCLN | FTLEXIT; for(i=1; i D_serial; n--) { p = &gpkt.p_idel[n]; if (p->i_pred == D_serial) fatal("not a 'leaf' delta (rc5)"); } /* For 'rmdel' check that the sid requested is not contained in p-file, should a p-file exist. */ if (exists(auxf(gpkt.p_file,'p'))) rdpfile(&gpkt,&sid); flushto(&gpkt,EUSERTXT,COPY); keep = YES; gpkt.p_chkeof = 1; /* set EOF is ok */ while ((p = getline(&gpkt)) != NULL) { if (*p++ == CTLCHAR) { cp = p++; NONBLANK(p); /* Convert serial number to binary. */ if (*(p = satoi(p,&n)) != '\n') fmterr(&gpkt); if (n == D_serial) { gpkt.p_wrttn = 1; if (*cp == INS) keep = NO; else keep = YES; } } else if (keep == NO) gpkt.p_wrttn = 1; } } else { /* This is for invocation as 'chghist'. Check MRs. */ if (Mrs) { if (!(p = Sflags[VALFLAG - 'a'])) fatal("MRs not allowed (rc6)"); if (*p && valmrs(&gpkt,p)) fatal("inavlid MRs (rc7)"); } else if (Sflags[VALFLAG - 'a']) fatal("MRs required (rc8)"); /* Indicate that EOF at this point is ok, and flush rest of s-file to x-file. */ gpkt.p_chkeof = 1; while (getline(&gpkt)) ; } flushline(&gpkt,0); /* Delete old s-file, change x-file name to s-file. */ rename(auxf(&gpkt,'x'),&gpkt); clean_up(); } escdodelt(pkt) struct packet *pkt; { extern int First_esc; char *p; extern long Timenow; if (D_type == 'D' && First_esc) { /* chghist, first time */ First_esc = 0; if (Mrs) putmrs(pkt); sprintf(line,"%c%c ",CTLCHAR,COMMENTS); putline(pkt,line); putline(pkt,Comments); putline(pkt,"\n"); sprintf(line,"%c%c ",CTLCHAR,COMMENTS); putline(pkt,line); putline(pkt,"*** CHANGED *** "); date_ba(&Timenow,line); /* get date and time */ putline(pkt,line); sprintf(line," %s\n",logname()); putline(pkt,line); } if (pkt->p_line[1] == MRNUM) { p = &pkt->p_line; while (*p) p++; if (*(p - 2) == DELIVER) fatal("delta specified has delivered MR (rc9)"); if (D_type == 'D') /* turn MRs into comments */ pkt->p_line[1] = COMMENTS; } } putmrs(pkt) struct packet *pkt; { register char **argv; char str[64]; extern char *Varg[]; for (argv = &Varg[VSTART]; *argv; argv++) { sprintf(str,"%c%c %s\n",CTLCHAR,MRNUM,*argv); putline(pkt,str); } } clean_up() { xrm(&gpkt); if (gpkt.p_file[0]) unlockit(auxf(gpkt.p_file,'z'),getpid()); if (exists(auxf(gpkt.p_file,'x'))) xunlink(auxf(gpkt.p_file,'x')); xfreeall(); } rdpfile(pkt,sp) register struct packet *pkt; struct sid *sp; { struct pfile pf; char line[BUFSIZ]; FILE *in; in = xfopen(auxf(pkt->p_file,'p'),0); while (fgets(line,sizeof(line),in) != NULL) { pf_ab(line,&pf,1); if (sp->s_rel == pf.pf_gsid.s_rel && sp->s_lev == pf.pf_gsid.s_lev && sp->s_br == pf.pf_gsid.s_br && sp->s_seq == pf.pf_gsid.s_seq) { fclose(in); fatal("being edited -- sid is in p-file (rc12)"); } } fclose(in); return; }