1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may use this file only in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.opensource.org/licenses/cddl1.txt
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
14 *
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
20 *
21 * CDDL HEADER END
22 */
23 /* Copyright (c) 1988 AT&T */
24 /* All Rights Reserved */
25 /*
26 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29 /*
30 * Copyright 2006-2019 J. Schilling
31 *
32 * @(#)dodelt.c 1.27 19/11/08 J. Schilling
33 */
34 #if defined(sun)
35 #pragma ident "@(#)dodelt.c 1.27 19/11/08 J. Schilling"
36 #endif
37 /*
38 * @(#)dodelt.c 1.8 06/12/12
39 */
40
41 #if defined(sun)
42 #pragma ident "@(#)dodelt.c"
43 #pragma ident "@(#)sccs:lib/comobj/dodelt.c"
44 #endif
45 #include <defines.h>
46 #include <had.h>
47
48 # define ONEYEAR 31536000L
49
50 static char getadel __PR((struct packet *,struct deltab *));
51 static void doixg __PR((char *,struct ixg **));
52
53 dtime_t Timenow;
54
55 struct idel *
dodelt(pkt,statp,sidp,type)56 dodelt(pkt,statp,sidp,type)
57 register struct packet *pkt;
58 struct stats *statp;
59 struct sid *sidp;
60 char type;
61 {
62 char *c = NULL;
63 struct deltab dt;
64 register struct idel *rdp = NULL;
65 int n, founddel;
66 int lhash;
67 register char *p;
68 time_t TN;
69 int Tns;
70
71 pkt->p_idel = 0;
72 founddel = 0;
73
74 dtime(&Timenow);
75 TN = Timenow.dt_sec;
76 Tns = Timenow.dt_nsec;
77 #if defined(BUG_1205145) || defined(GMT_TIME)
78 TN += Timenow.dt_zone;
79 #else
80 if (pkt->p_flags & PF_GMT)
81 TN += Timenow.dt_zone;
82 #endif
83 stats_ab(pkt,statp);
84 lhash = pkt->p_clhash;
85 while (getadel(pkt,&dt) == BDELTAB) {
86 if (pkt->p_idel == 0) {
87 if ((TN < dt.d_dtime.dt_sec) ||
88 ((TN == dt.d_dtime.dt_sec) &&
89 (Tns < dt.d_dtime.dt_nsec))) {
90 fprintf(stderr,
91 gettext(
92 "Time stamp later than current clock time (co10)\n"));
93 }
94 pkt->p_idel = (struct idel *)
95 fmalloc((unsigned) (n=((dt.d_serial+1)*
96 sizeof (*pkt->p_idel))));
97 zero((char *) pkt->p_idel,n);
98 pkt->p_apply = (struct apply *)
99 fmalloc((unsigned) (n=((dt.d_serial+1)*
100 sizeof (*pkt->p_apply))));
101 zero((char *) pkt->p_apply,n);
102 if (pkt->p_pgmrs != NULL) {
103 pkt->p_pgmrs = (char **)
104 fmalloc((unsigned) (n=((dt.d_serial+1)*
105 sizeof (char *))));
106 zero((char *) pkt->p_pgmrs, n);
107 }
108 pkt->p_idel->i_pred = dt.d_serial;
109 }
110 if (dt.d_type == 'D' || /* Delta */
111 dt.d_type == 'U') { /* Unlink */
112 /*
113 * sidp is != NULL only for rmchg
114 */
115 if (sidp && eqsid(&dt.d_sid,sidp)) {
116 copy(dt.d_pgmr, pkt->p_pgmr); /* for rmchg */
117 zero((char *) sidp,sizeof (*sidp));
118 founddel = 1;
119 pkt->p_first_esc = 1;
120 pkt->p_first_cmt = 1;
121 pkt->p_cdid_mrs = 0;
122 for (p = pkt->p_line;
123 *p && *p != dt.d_type; p++) {
124 ;
125 }
126 if (*p) {
127 /*
128 * Also correct saved line hash, used
129 * for putline() optimization.
130 */
131 pkt->p_clhash -= dt.d_type; /* D/U */
132 pkt->p_uclhash -= dt.d_type; /* D/U */
133 pkt->p_clhash += type;
134 pkt->p_uclhash += type;
135 *p = type;
136 }
137 if (type == 0) {
138 /*
139 * Go back before last stats line. The
140 * value 21 is the lenght of any stats
141 * line. Never change this length.
142 */
143 pkt->p_nhash -= lhash;
144 fseek(pkt->p_xiop, (off_t)-21, SEEK_CUR);
145 /*
146 * Skip this delta table entry.
147 */
148 pkt->p_wrttn = 1;
149 while ((c = getline(pkt)) != NULL) {
150 pkt->p_wrttn = 1;
151 if (pkt->p_line[0] != CTLCHAR)
152 break;
153 if (pkt->p_line[1] == EDELTAB)
154 break;
155 }
156 }
157 }
158 else
159 pkt->p_first_esc = pkt->p_first_cmt = founddel = 0;
160 pkt->p_maxr = max(pkt->p_maxr,dt.d_sid.s_rel);
161 if (pkt->p_pgmrs != NULL) {
162 pkt->p_pgmrs[dt.d_serial] =
163 lhash_lookup(dt.d_pgmr);
164 }
165 rdp = &pkt->p_idel[dt.d_serial];
166 rdp->i_sid.s_rel = dt.d_sid.s_rel;
167 rdp->i_sid.s_lev = dt.d_sid.s_lev;
168 rdp->i_sid.s_br = dt.d_sid.s_br;
169 rdp->i_sid.s_seq = dt.d_sid.s_seq;
170 rdp->i_pred = dt.d_pred;
171 rdp->i_dtype = dt.d_type;
172 rdp->i_datetime.tv_sec = dt.d_dtime.dt_sec;
173 rdp->i_datetime.tv_nsec = dt.d_dtime.dt_nsec;
174 if (founddel && type == 0) /* Already skipped */
175 goto nextdelta;
176 }
177 while ((c = getline(pkt)) != NULL)
178 if (pkt->p_line[0] != CTLCHAR)
179 break;
180 else {
181 switch (pkt->p_line[1]) {
182 case EDELTAB:
183 break;
184 case COMMENTS:
185 if (pkt->p_line[2] == '_')
186 sidext_v4compat_ab(pkt, &dt);
187 /* FALLTHRU */
188 case MRNUM:
189 if (founddel)
190 {
191 (*pkt->p_escdodelt)(pkt);
192 if (type == 'R' && HADZ && pkt->p_line[1] == MRNUM) {
193 (*pkt->p_fredck)(pkt);
194 }
195 }
196 continue;
197
198 case SIDEXTENS:
199 if (pkt->p_flags & PF_V6) {
200 sidext_ab(pkt, &dt, &pkt->p_line[2]);
201 continue;
202 }
203 /* FALLTHRU */
204 default:
205 fmterr(pkt);
206 /*FALLTHRU*/
207 case INCLUDE:
208 case EXCLUDE:
209 case IGNORE:
210 /*
211 * Is this really needed for type 'U' as well?
212 */
213 if (dt.d_type == 'D' ||
214 dt.d_type == 'U') {
215 doixg(pkt->p_line,&rdp->i_ixg);
216 }
217 continue;
218 }
219 break;
220 }
221 nextdelta:
222 if (c == NULL || pkt->p_line[0] != CTLCHAR || getline(pkt) == NULL)
223 fmterr(pkt);
224 if (pkt->p_line[0] != CTLCHAR || pkt->p_line[1] != STATS)
225 break;
226 lhash = pkt->p_clhash;
227 }
228 return (pkt->p_idel);
229 }
230
231 static char
getadel(pkt,dt)232 getadel(pkt,dt)
233 register struct packet *pkt;
234 register struct deltab *dt;
235 {
236 if (getline(pkt) == NULL)
237 fmterr(pkt);
238 return (del_ab(pkt->p_line,dt, pkt));
239 }
240
241 static void
doixg(p,ixgp)242 doixg(p,ixgp)
243 char *p;
244 struct ixg **ixgp;
245 {
246 int *v, *ip;
247 int type, cnt, i;
248 struct ixg *curp, *prevp;
249 int xtmp[MAXLINE];
250
251 v = ip = xtmp;
252 ++p;
253 type = *p++;
254 NONBLANK(p);
255 while (numeric(*p)) {
256 if ((ip - v) >= MAXLINE)
257 fatal(gettext("too many include exclude or ignore entries (co30)"));
258 p = satoi(p,ip++);
259 NONBLANK(p);
260 }
261 cnt = ip - v;
262 for (prevp = curp = (*ixgp); curp; curp = (prevp = curp)->i_next)
263 ;
264 curp = (struct ixg *) fmalloc((unsigned)
265 (sizeof (struct ixg) + (cnt-1)*sizeof (curp->i_ser[0])));
266 if (*ixgp == 0)
267 *ixgp = curp;
268 else
269 prevp->i_next = curp;
270 curp->i_next = 0;
271 curp->i_type = (char) type;
272 curp->i_cnt = (char) cnt;
273 for (i=0; cnt>0; --cnt)
274 curp->i_ser[i++] = *v++;
275 }
276