1*2146Seric # include	"../hdr/defines.h"
2*2146Seric # include	"../hdr/had.h"
3*2146Seric 
4*2146Seric SCCSID(@(#)comb.c	4.1);
5*2146Seric USXALLOC();
6*2146Seric 
7*2146Seric struct packet gpkt;
8*2146Seric struct sid sid;
9*2146Seric int	num_files;
10*2146Seric char	had[26];
11*2146Seric char	*clist;
12*2146Seric int	*Cvec;
13*2146Seric int	Cnt;
14*2146Seric FILE	*iop;
15*2146Seric 
16*2146Seric main(argc,argv)
17*2146Seric int argc;
18*2146Seric register char *argv[];
19*2146Seric {
20*2146Seric 	register int i;
21*2146Seric 	register char *p;
22*2146Seric 	char c;
23*2146Seric 	int testmore;
24*2146Seric 	extern comb();
25*2146Seric 	extern int Fcnt;
26*2146Seric 
27*2146Seric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
28*2146Seric 	for(i = 1; i < argc; i++)
29*2146Seric 		if(argv[i][0] == '-' && (c=argv[i][1])) {
30*2146Seric 			p = &argv[i][2];
31*2146Seric 			testmore = 0;
32*2146Seric 			switch (c) {
33*2146Seric 
34*2146Seric 			case 'p':
35*2146Seric 				if (!p[0]) {
36*2146Seric 					argv[i] = 0;
37*2146Seric 					continue;
38*2146Seric 				}
39*2146Seric 				chksid(sid_ab(p,&sid),&sid);
40*2146Seric 				break;
41*2146Seric 			case 'c':
42*2146Seric 				clist = p;
43*2146Seric 				break;
44*2146Seric 			case 'o':
45*2146Seric 				testmore++;
46*2146Seric 				break;
47*2146Seric 			case 's':
48*2146Seric 				testmore++;
49*2146Seric 				break;
50*2146Seric 			default:
51*2146Seric 				fatal("unknown key letter (cm1)");
52*2146Seric 			}
53*2146Seric 
54*2146Seric 			if (testmore) {
55*2146Seric 				testmore = 0;
56*2146Seric 				if (*p)
57*2146Seric 					fatal(sprintf(Error,
58*2146Seric 					  "value after %c arg (cm7)",c));
59*2146Seric 			}
60*2146Seric 			if (had[c - 'a']++)
61*2146Seric 				fatal("key letter twice (cm2)");
62*2146Seric 			argv[i] = 0;
63*2146Seric 		}
64*2146Seric 		else num_files++;
65*2146Seric 
66*2146Seric 	if(num_files == 0)
67*2146Seric 		fatal("missing file arg (cm3)");
68*2146Seric 	if (HADP && HADC)
69*2146Seric 		fatal("can't have both -p and -c (cb2)");
70*2146Seric 	setsig();
71*2146Seric 	Fflags =& ~FTLEXIT;
72*2146Seric 	Fflags =| FTLJMP;
73*2146Seric 	iop = stdout;
74*2146Seric 	for (i = 1; i < argc; i++)
75*2146Seric 		if (p=argv[i])
76*2146Seric 			do_file(p,comb);
77*2146Seric 	fclose(iop);
78*2146Seric 	exit(Fcnt ? 1 : 0);
79*2146Seric }
80*2146Seric 
81*2146Seric 
82*2146Seric comb(file)
83*2146Seric {
84*2146Seric 	register int i, n;
85*2146Seric 	register struct idel *rdp;
86*2146Seric 	char *p;
87*2146Seric 	int succnt;
88*2146Seric 	struct sid *sp;
89*2146Seric 	extern char had_dir, had_standinp;
90*2146Seric 	extern char *Sflags[];
91*2146Seric 	struct stats stats;
92*2146Seric 
93*2146Seric 	if (setjmp(Fjmp))
94*2146Seric 		return;
95*2146Seric 	sinit(&gpkt, file, 1);
96*2146Seric 	gpkt.p_verbose = -1;
97*2146Seric 	gpkt.p_stdout = stderr;
98*2146Seric 	if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
99*2146Seric 		fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
100*2146Seric 	if (exists(auxf(gpkt.p_file, 'p')))
101*2146Seric 		fatal("p-file exists (cb1)");
102*2146Seric 
103*2146Seric 	if (dodelt(&gpkt,&stats,0,0) == 0)
104*2146Seric 		fmterr(&gpkt);
105*2146Seric 
106*2146Seric 	Cvec = alloc(n = ((maxser(&gpkt) + 1) * sizeof(*Cvec)));
107*2146Seric 	zero(Cvec, n);
108*2146Seric 	Cnt = 0;
109*2146Seric 
110*2146Seric 	if (HADP) {
111*2146Seric 		if (!(n = sidtoser(&sid, &gpkt)))
112*2146Seric 			fatal("sid doesn't exist (cb3)");
113*2146Seric 		while (n <= maxser(&gpkt))
114*2146Seric 			Cvec[Cnt++] = n++;
115*2146Seric 	}
116*2146Seric 	else if (HADC) {
117*2146Seric 		dolist(&gpkt, clist, 0);
118*2146Seric 	}
119*2146Seric 	else {
120*2146Seric 		rdp = gpkt.p_idel;
121*2146Seric 		for (i = 1; i <= maxser(&gpkt); i++) {
122*2146Seric 			succnt = 0;
123*2146Seric 			for (n = i + 1; n <= maxser(&gpkt); n++)
124*2146Seric 				if (rdp[n].i_pred == i)
125*2146Seric 					succnt++;
126*2146Seric 			if (succnt != 1)
127*2146Seric 				Cvec[Cnt++] = i;
128*2146Seric 		}
129*2146Seric 	}
130*2146Seric 	finduser(&gpkt);
131*2146Seric 	doflags(&gpkt);
132*2146Seric 	fclose(gpkt.p_iop);
133*2146Seric 	gpkt.p_iop = 0;
134*2146Seric 	if (!Cnt)
135*2146Seric 		fatal("nothing to do (cb4)");
136*2146Seric 	rdp = gpkt.p_idel;
137*2146Seric 	sp = prtget(rdp, Cvec[0], iop, gpkt.p_file);
138*2146Seric 	fprintf(iop, "admin -iCOMB -r%d s.COMB\n", sp->s_rel);
139*2146Seric 	fprintf(iop, "rm -f COMB\n");
140*2146Seric 	for (i = 1; i < Cnt; i++) {
141*2146Seric 		n = getpred(rdp, Cvec, i);
142*2146Seric 		if (HADO)
143*2146Seric 			fprintf(iop, "get -s -r%d -g -e -t s.COMB\n",
144*2146Seric 				rdp[Cvec[i]].i_sid.s_rel);
145*2146Seric 		else
146*2146Seric 			fprintf(iop, "get -s -a%d -r%d -g -e s.COMB\n",
147*2146Seric 				n + 1, rdp[Cvec[i]].i_sid.s_rel);
148*2146Seric 		prtget(rdp, Cvec[i], iop, gpkt.p_file);
149*2146Seric 		fprintf(iop, "delta -s '-yThis was COMBined' s.COMB\n");
150*2146Seric 	}
151*2146Seric 	fprintf(iop, "sed -n '/^%c%c$/,/^%c%c$/p' %s >comb${pid}\n",
152*2146Seric 		CTLCHAR, BUSERTXT, CTLCHAR, EUSERTXT, gpkt.p_file);
153*2146Seric 	fprintf(iop, "ed - comb${pid} <<\\!\n");
154*2146Seric 	fprintf(iop, "1d\n");
155*2146Seric 	fprintf(iop, "$c\n");
156*2146Seric 	fprintf(iop, " *** DELTA TABLE PRIOR TO COMBINE ***\n");
157*2146Seric 	fprintf(iop, ".\n");
158*2146Seric 	fprintf(iop, "w\n");
159*2146Seric 	fprintf(iop, "q\n");
160*2146Seric 	fprintf(iop, "!\n");
161*2146Seric 	fprintf(iop, "prt -a %s >>comb${pid}\n", gpkt.p_file);
162*2146Seric 	fprintf(iop, "admin -tcomb${pid} s.COMB\\\n");
163*2146Seric 	for (i = 0; i < NFLAGS; i++)
164*2146Seric 		if (p = Sflags[i])
165*2146Seric 			fprintf(iop, " -f%c%s\\\n", i + 'a', p);
166*2146Seric 	fprintf(iop, "\n");
167*2146Seric 	fprintf(iop, "sed -n '/^%c%c$/,/^%c%c$/p' %s >comb${pid}\n",
168*2146Seric 		CTLCHAR, BUSERNAM, CTLCHAR, EUSERNAM, gpkt.p_file);
169*2146Seric 	fprintf(iop, "ed - comb${pid} <<\\!\n");
170*2146Seric 	fprintf(iop, "v/^%c/s/.*/-a& \\\\/\n", CTLCHAR);
171*2146Seric 	fprintf(iop, "1c\n");
172*2146Seric 	fprintf(iop, "admin s.COMB\\\n");
173*2146Seric 	fprintf(iop, ".\n");
174*2146Seric 	fprintf(iop, "$c\n");
175*2146Seric 	fprintf(iop, "\n");
176*2146Seric 	fprintf(iop, ".\n");
177*2146Seric 	fprintf(iop, "w\n");
178*2146Seric 	fprintf(iop, "q\n");
179*2146Seric 	fprintf(iop, "!\n");
180*2146Seric 	fprintf(iop, "sh comb${pid}\n");
181*2146Seric 	fprintf(iop, "rm comb${pid}\n");
182*2146Seric 	if (!HADS) {
183*2146Seric 		fprintf(iop, "rm -f %s\n", gpkt.p_file);
184*2146Seric 		fprintf(iop, "mv s.COMB %s\n", gpkt.p_file);
185*2146Seric 	}
186*2146Seric 	else {
187*2146Seric 		fprintf(iop, "set a=`echo \\`ls -s s.COMB\\``\n");
188*2146Seric 		fprintf(iop, "set b=`echo \\`ls -s %s\\``\n",gpkt.p_file);
189*2146Seric 		fprintf(iop, "set c=`expr 100 - 100 '*' ${a} / ${b}`\n");
190*2146Seric 		fprintf(iop, "echo '%s\t' ${c}'%%\t' ${a}/${b}\n", gpkt.p_file);
191*2146Seric 		fprintf(iop, "rm -f s.COMB\n");
192*2146Seric 	}
193*2146Seric }
194*2146Seric 
195*2146Seric 
196*2146Seric enter(pkt,ch,n,sidp)
197*2146Seric struct packet *pkt;
198*2146Seric char ch;
199*2146Seric int n;
200*2146Seric struct sid *sidp;
201*2146Seric {
202*2146Seric 	Cvec[Cnt++] = n;
203*2146Seric }
204*2146Seric 
205*2146Seric 
206*2146Seric prtget(idp, ser, iop, file)
207*2146Seric struct idel *idp;
208*2146Seric int ser;
209*2146Seric FILE *iop;
210*2146Seric char *file;
211*2146Seric {
212*2146Seric 	char buf[32];
213*2146Seric 	struct sid *sp;
214*2146Seric 
215*2146Seric 	sid_ba(sp = &idp[ser].i_sid, buf);
216*2146Seric 	fprintf(iop, ":\t/bin/bsh\n");
217*2146Seric 	fprintf(iop, "get -s -k -r%s -p %s > COMB\n", buf, file);
218*2146Seric 	return(sp);
219*2146Seric }
220*2146Seric 
221*2146Seric 
222*2146Seric getpred(idp, vec, i)
223*2146Seric struct idel *idp;
224*2146Seric int *vec;
225*2146Seric int i;
226*2146Seric {
227*2146Seric 	int ser, pred, acpred;
228*2146Seric 
229*2146Seric 	ser = vec[i];
230*2146Seric 	while (--i) {
231*2146Seric 		pred = vec[i];
232*2146Seric 		for (acpred = idp[ser].i_pred; acpred; acpred = idp[acpred].i_pred)
233*2146Seric 			if (pred == acpred)
234*2146Seric 				break;
235*2146Seric 		if (pred == acpred)
236*2146Seric 			break;
237*2146Seric 	}
238*2146Seric 	return(i);
239*2146Seric }
240*2146Seric 
241*2146Seric 
242*2146Seric clean_up(n)
243*2146Seric {
244*2146Seric 	xfreeall();
245*2146Seric }
246*2146Seric 
247*2146Seric 
248*2146Seric escdodelt()	/* dummy for dodelt() */
249*2146Seric {
250*2146Seric }
251