# include "../hdr/defines.h"
static char Sccsid
[] = "@(#)delta.c 4.8 %G%";
char LogFile
[] = "/usr/adm/sccs-log";
char Diffpgm
[] = "/usr/local/bdiff";
char *ilist
, *elist
, *glist
;
char Pfilename
[FILESIZE
];
Fflags
= FTLEXIT
| FTLMSG
| FTLCLN
;
if(argv
[i
][0] == '-' && (c
=argv
[i
][1])) {
chksid(sid_ab(p
,&sid
),&sid
);
fatal("unknown key letter (cm1)");
"value after %c arg (cm7)",c
));
fatal("key letter twice (cm2)");
fatal("missing file arg (cm3)");
Logf
= fopen(LogFile
, "a");
extern char had_dir
, had_standinp
;
char dfilename
[FILESIZE
];
char gfilename
[FILESIZE
];
int inserted
, deleted
, orig
;
if (lockit(auxf(gpkt
.p_file
,'z'),2,getpid()))
fatal("cannot create lock file (cm4)");
copy(auxf(gpkt
.p_file
,'g'),gfilename
);
gin
= xfopen(gfilename
,0);
pp
= rdpfile(&gpkt
,&sid
);
gpkt
.p_cutoff
= pp
->pf_date
;
if (dodelt(&gpkt
,&stats
,0,0) == 0)
if ((ser
= sidtoser(&pp
->pf_gsid
,&gpkt
)) == 0 ||
sidtoser(&pp
->pf_nsid
,&gpkt
))
fatal("invalid sid in p-file (de3)");
doie(&gpkt
,ilist
,elist
,glist
);
bcopy(&pp
->pf_nsid
,&gpkt
.p_reqsid
,sizeof(gpkt
.p_reqsid
));
flushto(&gpkt
,EUSERTXT
,1);
copy(auxf(gpkt
.p_file
,'d'),dfilename
);
gpkt
.p_gout
= xfcreat(dfilename
,0444);
fputs(gpkt
.p_line
,gpkt
.p_gout
);
gpkt
.p_verbose
= verbosity
;
while (fgets(line
,sizeof(line
),gin
) != NULL
&& !chkid(line
))
if (gpkt
.p_verbose
&& (num_files
> 1 || had_dir
|| had_standinp
))
fprintf(gpkt
.p_stdout
,"\n%s:\n",gpkt
.p_file
);
if (Sflags
[IDFLAG
- 'a'])
fatal("no id keywords (cm6)");
fprintf(stderr
,"No id keywords (cm7)\n");
The following while loop executes 'bdiff' on g-file and
d-file. If 'bdiff' fails (usually because segmentation
limit it is using is too large for 'diff'), it is
invoked again, with a lower segmentation limit.
newser
= mkdelt(&gpkt
,&pp
->pf_nsid
,&pp
->pf_gsid
,
flushto(&gpkt
,EUSERTXT
,0);
Diffin
= dodiff(auxf(gpkt
.p_file
,'g'),dfilename
,difflim
);
while (n
= getdiff(&type
,&linenum
)) {
insert(&gpkt
,linenum
,n
,newser
);
delete(&gpkt
,linenum
,n
,newser
);
if (status
) { /* diff failed */
Check top byte (exit code of child).
if (((status
>> 8) & 0377) == 32) /* 'execl' failed */
"cannot execute '%s' (de12)",
if (difflim
=- 500) { /* reduce segmentation */
"'%s' failed, re-trying, segmentation = %d (de13)\n",
fclose(Xiop
); /* set up */
Xiop
= 0; /* for new x-file */
gpkt
.p_iop
= xfopen(gpkt
.p_file
,0);
setbuf(gpkt
.p_iop
,gpkt
.p_buf
);
/* tried up to 500 lines, can't go on */
fatal("diff failed (de4)");
else { /* no need to try again, worked */
break; /* exit while loop */
stats
.s_unc
= orig
- deleted
;
fprintf(gpkt
.p_stdout
,"%u inserted\n",stats
.s_ins
);
fprintf(gpkt
.p_stdout
,"%u deleted\n",stats
.s_del
);
fprintf(gpkt
.p_stdout
,"%u unchanged\n",stats
.s_unc
);
rename(auxf(gpkt
.p_file
,'x'),gpkt
.p_file
);
rename(auxf(&gpkt
.p_file
,'q'),Pfilename
);
xunlink(auxf(&gpkt
.p_file
,'q'));
mkdelt(pkt
,sp
,osp
,diffloop
,orig_nlines
)
int ser_inc
, opred
, nulldel
;
if (!diffloop
&& pkt
->p_verbose
) {
fprintf(pkt
->p_stdout
,"%s\n",str
);
putline(pkt
,sprintf(str
,"%c%c00000\n",CTLCHAR
,HEAD
));
bcopy(sp
,&dt
.d_sid
,sizeof(dt
.d_sid
));
Check if 'null' deltas should be inserted
(only if 'null' flag is in file and
releases are being skipped) and set
'nulldel' indicator appropriately.
if (Sflags
[NULLFLAG
- 'a'] && (sp
->s_rel
> osp
->s_rel
+ 1) &&
!sp
->s_br
&& !sp
->s_seq
&&
!osp
->s_br
&& !osp
->s_seq
)
Calculate how many serial numbers are needed.
ser_inc
= sp
->s_rel
- osp
->s_rel
;
Find serial number of the new delta.
newser
= dt
.d_serial
= maxser(pkt
) + ser_inc
;
Find old predecessor's serial number.
opred
= sidtoser(osp
,pkt
);
dt
.d_pred
= newser
- 1; /* set predecessor to 'null' delta */
substr(logname(),dt
.d_pgmr
,0,LNLNAM
);
if (pkt
->p_file
[0] != '/') {
fprintf(Logf
, "%s/", buf
);
fprintf(Logf
, "%s:\n%s%s\n", pkt
->p_file
, str
+ 5, Comments
);
mkixg(pkt
,INCLUSER
,INCLUDE
);
mkixg(pkt
,EXCLUSER
,EXCLUDE
);
mkixg(pkt
,IGNRUSER
,IGNORE
);
if (!(p
= Sflags
[VALFLAG
- 'a']))
fatal("MRs not allowed (de8)");
if (*p
&& !diffloop
&& valmrs(pkt
,p
))
fatal("invalid MRs (de9)");
else if (Sflags
[VALFLAG
- 'a'])
fatal("MRs required (de10)");
putline(pkt
,sprintf(str
,"%c%c ",CTLCHAR
,COMMENTS
));
putline(pkt
,sprintf(str
,CTLSTR
,CTLCHAR
,EDELTAB
));
if (nulldel
) /* insert 'null' deltas */
putline(pkt
,sprintf(str
,"%c%c %s/%s/%05u\n",
"00000", "00000", orig_nlines
));
dt
.d_pred
= opred
; /* point to old pred */
putline(pkt
,sprintf(str
,"%c%c ",CTLCHAR
,COMMENTS
));
putline(pkt
,"AUTO NULL DELTA\n");
putline(pkt
,sprintf(str
,CTLSTR
,CTLCHAR
,EDELTAB
));
putline(pkt
,sprintf(str
,"%c%c",CTLCHAR
,ch
));
for (n
= maxser(pkt
); n
; n
--) {
if (pkt
->p_apply
[n
].a_reason
== reason
)
putline(pkt
,sprintf(str
," %u",n
));
for (argv
= &Varg
[VSTART
]; *argv
; argv
++)
putline(pkt
,sprintf(str
,"%c%c %s\n",CTLCHAR
,MRNUM
,*argv
));
register struct packet
*pkt
;
static struct pfile goodpf
;
bzero(&goodpf
,sizeof(goodpf
));
in
= xfopen(auxf(pkt
->p_file
,'p'),0);
out
= xfcreat(auxf(pkt
->p_file
,'q'),0644);
while (fgets(line
,sizeof(line
),in
) != NULL
) {
if (root
|| equal(pf
.pf_user
,user
)) {
fatal("missing -r argument (de1)");
bcopy(&pf
,&goodpf
,sizeof(pf
));
else 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
) {
bcopy(&pf
,&goodpf
,sizeof(pf
));
fstat(fileno(out
),&Statbuf
);
Szqfile
= Statbuf
.st_size
;
copy(auxf(pkt
->p_file
,'p'),Pfilename
);
fatal("not in p-file (de2)");
dodiff(newf
,oldf
,difflim
)
fatal("cannot fork, try again (de11)");
for (i
= getdtablesize(); i
> 4; i
--)
sprintf(num
,"%d",difflim
);
execl(Diffpgm
,Diffpgm
,oldf
,newf
,num
,"-s",0);
exit(32); /* tell parent that 'execl' failed */
iop
= fdopen(pfd
[0],"r");
static int chg_num
, chg_ln
;
if ((p
= rddiff(line
,sizeof (line
))) == NULL
)
p
= linerange(p
,&lowline
,&highline
);
num_lines
= highline
- lowline
+ 1;
skiplines(line
,num_lines
);
linerange(p
,&lowline
,&highline
);
num_lines
= highline
- lowline
+ 1;
num_lines
= highline
- lowline
+ 1;
linerange(p
,&lowline
,&highline
);
chg_num
= highline
- lowline
+ 1;
skiplines(line
,num_lines
);
insert(pkt
,linenum
,n
,ser
)
register struct packet
*pkt
;
putline(pkt
,sprintf(str
,"%c%c %u\n",CTLCHAR
,INS
,ser
));
putline(pkt
,sprintf(str
,"%c%c %u\n",CTLCHAR
,END
,ser
));
delete(pkt
,linenum
,n
,ser
)
register struct packet
*pkt
;
putline(pkt
,sprintf(str
,"%c%c %u\n",CTLCHAR
,DEL
,ser
));
after(pkt
,linenum
+ n
- 1);
putline(pkt
,sprintf(str
,"%c%c %u\n",CTLCHAR
,END
,ser
));
register struct packet
*pkt
;
register struct packet
*pkt
;
while (pkt
->p_glnno
< n
) {
register int *low
, *high
;
if ((r
= fgets(s
,n
,Diffin
)) != NULL
&& HADP
)
register struct apply
*ap
;
if (pkt
->p_cutoff
> pkt
->p_idel
[n
].i_datetime
)
condset(ap
,APPLY
,INCLUSER
);
condset(ap
,NOAPPLY
,EXCLUSER
);
condset(ap
,EMPTY
,IGNRUSER
);
fatal("internal error in delta/enter() (de5)");
fatal("internal error in delta/enter() (de6)");
fatal("internal error in delta/enter() (de7)");
escdodelt() /* dummy routine for dodelt() */
unlockit(auxf(gpkt
.p_file
,'z'),getpid());