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-2018 J. Schilling
31  *
32  * @(#)deltack.c	1.17 18/04/29 J. Schilling
33  */
34 #if defined(sun)
35 #pragma ident "@(#)deltack.c 1.17 18/04/29 J. Schilling"
36 #endif
37 /*
38  * @(#)deltack.c 1.8 06/12/12
39  */
40 
41 #if defined(sun)
42 #pragma ident	"@(#)deltack.c"
43 #pragma ident	"@(#)sccs:lib/cassi/deltack.c"
44 #endif
45 #include <defines.h>
46 #include <had.h>
47 #include <filehand.h>
48 #include <i18n.h>
49 #include <ccstypes.h>
50 
51 #define	FOREVER		1
52 #define	MAXLIST		15
53 #define	MAXLIST2	20
54 #define	MAXLENCMR	12
55 static char errorlog[FILESIZE];		 /* log cmts errors here */
56 static FILE *efd;
57 
58 	int	deltack __PR((char *pfile, char *mrs, char *nsid, char *apl, char *sflags[NFLAGS]));
59 static int	promdelt __PR((char *cmrs, char *statp, char *type, char *fred, char *sflags[NFLAGS]));
60 static int	msg __PR((char *syst, char *name, char *cmrs, char *stats, char *types, char *sids, char *fred, char *sflags[NFLAGS]));
61 static int	verif __PR((char *cmr, char *fred));
62 static int	getinfo __PR((char **freddy, char *sys));
63 static char *	xgets	__PR((char *buf, size_t len));
64 
65 /*
66  * deltack(pfile, mrs, nsid, apl) peforms the nessesary validations on a delta
67  * involving the CMF FRED file of active CMR's
68  */
69 
70 int
deltack(pfile,mrs,nsid,apl,sflags)71 deltack(pfile, mrs, nsid, apl, sflags)
72 	char pfile[];	/* the pfile name */
73 
74 	char *mrs;		/* list of mrs from pfile */
75 	char *nsid;		/* sid id */
76 	char *apl;		/* application from the file */
77 	char *sflags[NFLAGS];
78 {
79 	static char type[10], sthold[10];
80 	char hold[302], *h, *fred;
81 
82 	/* check for the existance of the p.file */
83 	if (!pfile) {
84 		cmrerror(gettext("Pfile non existant at deltack "));
85 		return (0);
86 	}
87 	/* if no application serious error */
88 	if (!apl) {
89 		cmrerror(gettext("no application found with -fz flag"));
90 		return (0);
91 	}
92 	/* check for and retrieve FRED given the application name */
93 	if (!getinfo(&fred, apl)) {
94 		cmrerror(NOGETTEXT("no FRED file or system name in admin directory "));
95 		return (0);
96 	}
97 	strlcpy(errorlog, fred, sizeof (errorlog));
98 	*(errorlog + strlen(errorlog) - 11) = '\0';
99 	strlcat(errorlog, NOGETTEXT("LOG"), sizeof (errorlog));
100 	if (!(mrs)) {
101 		if ((efd = fopen(errorlog, "ab")) != NULL) {
102 			fprintf(efd, gettext("***CASSI REPORTS ERROR: no CMRS in pfile: %s\n"), pfile);
103 			(void) fclose(efd);
104 			efd = NULL;
105 		}
106 		cmrerror(gettext("CMRs not on P.file -serious inconsistancy"));
107 		return (0);
108 	}
109 	if (!promdelt(mrs, sthold, type, fred, sflags)) {
110 		return (0);
111 	}
112 	/* now build the chpost line  */
113 	(void) strlcpy(hold, mrs, sizeof (hold));
114 	h = strtok(hold, ",\0");
115 	(void) msg(apl, pfile, h, sthold, type, nsid, fred, sflags);
116 	while ((h = strtok(0, ",\0 ")) != NULL) {
117 		(void) msg(apl, pfile, h, sthold, type, nsid, fred, sflags);
118 	}
119 	return (1);
120 }
121 
122 
123 
124 /*
125  * promdelt(cmrs, statp, type, fred) allows one to modify the cmrs list and
126  * enrter the type and status for the input to the MR system via the net
127  */
128 static int
promdelt(cmrs,statp,type,fred,sflags)129 promdelt(cmrs, statp, type, fred, sflags)
130 	char *cmrs, *statp, *type, *fred;
131 	char	*sflags[NFLAGS];
132 {
133 	static char hold[300], nold[300], *cmrlist[MAXLIST2 + 1];
134 	char answ[100];
135 	int i, j, numcmrs, fdflag = 0, eqflag = 0, badflag = 0;
136 	char *h;
137 
138 	/* place the cmrs list in the array of pointers and remove the commas */
139 	strlcpy(hold, cmrs, sizeof (hold));
140 	(void) strtok(hold, ",");
141 	cmrlist[0] = hold;
142 	for (i = 1; i < MAXLIST; i++) {
143 		if ((cmrlist[i] = strtok(0, ",\0")) == (char *)NULL) {
144 			break;
145 		}
146 	}
147 	numcmrs = i;
148 	/* remove invalid cmrs from the list if now none set flag */
149 	for (i = 0; cmrlist[i]; i++) {
150 		if (!verif(cmrlist[i], fred)) {
151 			/* a 'sd' cmr has been found */
152 			if (numcmrs > 1) {
153 				for (j = i; j < numcmrs; j++) {
154 					cmrlist[j] = cmrlist[j + 1];
155 				}
156 				numcmrs--;
157 			} else { /* there is a last cmr to delete set flag */
158 				cmrlist[0] = NULL;
159 				badflag = 1;
160 				numcmrs--;
161 			}
162 		}
163 	}
164 	if (HADZ) { /* force delta flag on */
165 		if (badflag) { /* no legal cmrs in list */
166 		    if ((efd = fopen(errorlog, "ab")) != NULL) {
167 			fprintf(efd, gettext("***CASSI REPORTS ERROR: no CMRS at sd\n"));
168 			(void) fclose(efd);
169 			efd = NULL;
170 		    }
171 			(void) fatal(gettext("no CMR's left, delta forbidden\n"));
172 		}
173 		(void) strcpy(statp, "sd");
174 		if (sflags[TYPEFLAG - 'a'])
175 			strcpy(type, sflags[TYPEFLAG - 'a']);
176 		else
177 			strcpy(type, NOGETTEXT("sw"));
178 			/* rebuild cmr comma separated list */
179 		cat(nold, cmrlist[0], (char *)0);
180 		for (i = 1; i < numcmrs; i++) {
181 			cat(nold, ",", cmrlist[i], (char *)0);
182 		}
183 		strcpy(cmrs, nold);
184 		return (1);
185 	}
186 	/* CONSTCOND */
187 	while (FOREVER) {
188 		if (!badflag) {
189 			printf(gettext("the CMRs for this delta now are:\n"));
190 			for (i = 0; cmrlist[i + 1]; i++) {
191 				printf(" %s, ", cmrlist[i]);
192 			}
193 			printf("%s\n", cmrlist[i]);
194 			printf(NOGETTEXT("OK ??"));
195 			(void) xgets(answ, sizeof (answ));
196 			if((strcmp(answ,NOGETTEXT("y")) == 0) || (strcmp(answ,NOGETTEXT("ye")) == 0) || (strcmp(answ,NOGETTEXT("yes")) == 0)) {
197 
198 				break;
199 			}
200 		} else {
201 			printf(gettext("you must input at least 1 valid cmr number \n"));
202 		}
203 		/* now prompt for new cmrs to add to the list */
204 		/* CONSTCOND */
205 		while (FOREVER) {
206 			eqflag = 0;
207 			printf(gettext("enter new CMR number or 'CR' "));
208 			(void) xgets(answ, sizeof (answ));
209 			if (answ[0] == '\0') {
210 				if (!badflag) {
211 					break;
212 				} else {
213 					continue;
214 				}
215 			}
216 			h = (char *) malloc((unsigned)(strlen(answ) + 6));
217 			strcpy(h, answ);
218 			/* check for duplicate */
219 			for (i = 0; i < numcmrs; i++) {
220 				if (strcmp(h, cmrlist[i]) == 0) {
221 					eqflag = 1;
222 					break;
223 				}
224 			}
225 			if (eqflag == 1) {
226 				printf(gettext(" \n duplicate CMR number ignored\n"));
227 				continue;
228 			}
229 			/* now verify that the cmr is in FRED */
230 			if (!verif(h, fred)) {
231 				printf(gettext(" \n invalid CMR ignored \n"));
232 				continue;
233 			}
234 			/* the addition is valid */
235 			cmrlist[numcmrs] = h;
236 			badflag = 0; /* turn off the no cmrs found indicator */
237 			if (++numcmrs > MAXLIST2) {
238 				printf(gettext(" \n too many CMRs added no more allowed \n"));
239 				break;
240 			}
241 		}
242 		/* now delete mrs from list */
243 		/* CONSTCOND */
244 		while (FOREVER) {
245 			fdflag = 0;
246 			printf(gettext(" \n CMR number to delete or (CR) ? "));
247 			(void) xgets(answ, sizeof (answ));
248 			if (!(*answ)) {
249 				break;
250 			}
251 			/* if one left break */
252 			if (numcmrs == 1) {
253 				printf(gettext("\n only one CMR left can't delete more\n"));
254 				break;
255 			}
256 			/* check if request is on list */
257 			for (i = 0; i < numcmrs; i++) {
258 				if (strcmp(answ, cmrlist[i]) == 0) {
259 					fdflag = 1;
260 					for (j = i; j < numcmrs; j++) {
261 						cmrlist[j] = cmrlist[j+1];
262 					}
263 					break;
264 				}
265 			}
266 			if (fdflag == 0) {
267 				printf(gettext("\n not on list request ignored\n"));
268 				continue;
269 			} else {
270 				numcmrs--;
271 				/* we have oneless cmr */
272 			}
273 		}
274 	}
275 	/* here ends the cmr loop */
276 	/* set type to proper value */
277 	if (sflags[TYPEFLAG - 'a'])
278 		strcpy(type, sflags[TYPEFLAG - 'a']);
279 	else
280 		strcpy(type, NOGETTEXT("sw"));
281 	/* set status */
282 	strcpy(statp, "sd");
283 	/* reformat the cmrlist into a comma separated cmr list */
284 	cat(nold, cmrlist[0], (char *)0);
285 	for (i = 1; i < numcmrs; i++) {
286 		cat(nold, nold, ",", cmrlist[i], (char *)0);
287 	}
288 	strcpy(cmrs, nold);
289 	return (1);
290 }
291 
292 
293 
294 /*
295  * msg(syst, cmrs, stats, types, sids) formats a message and calls cmrpost
296  */
297 static int
msg(syst,name,cmrs,stats,types,sids,fred,sflags)298 msg(syst, name, cmrs, stats, types, sids, fred, sflags)
299 	char *syst, *name, *cmrs, *stats, *types, *sids, *fred;
300 	char	*sflags[NFLAGS];
301 {
302 	FILE *fd;
303 	char *k;
304 	char pname[FILESIZE], *ptr, holdfred[100], dir[100], path[FILESIZE];
305 	struct stat stbuf;
306 	int noexist = 0;
307 
308 	/* if -fm flag contains a value substitute a the value for name */
309 	if ((k = sflags[MODFLAG - 'a']) != NULL) {
310 		name = k;
311 	}
312 	if (*name != '/') { /* not full path name */
313 		if (getcwd(path, sizeof (path)) == NULL)
314 			(void) fatal(gettext("getcwd() failed (ge20)"));
315 		cat(pname, path, "/", name, (char *)0);
316 	} else {
317 		strlcpy(pname, name, sizeof (pname));
318 	}
319 	(void) fixpath(pname);				/* get rid of . and .. */
320 /******** the net is replaced by psudonet ******
321 *	  sprintf(holdit, "netq %s chpost  %s q %s %s MID=%s MFS=%s q q", syst, cmrs, pname, types, sids, stats);
322 *	 system(holdit);
323 ************************************************/
324 	/* build the name of the  termLOG file */
325 	strlcpy(holdfred, fred, sizeof (holdfred));
326 	ptr = strchr(holdfred, '.');
327 	*ptr = '\0';
328 	strlcat(holdfred, NOGETTEXT("source"), sizeof (holdfred));
329 	strlcpy(dir, holdfred, sizeof (dir));
330 	strlcat(holdfred, NOGETTEXT("/termLOG"), sizeof (holdfred));
331 	if (stat(holdfred, &stbuf) == -1)
332 		noexist = 1; /* new termLOG */
333 	if (!(fd = fopen(holdfred, "ab"))) {
334 		if ((efd = fopen(errorlog, "ab")) != NULL) {
335 			fprintf(efd, gettext("***CASSI REPORTS ERROR: can't write to FRED : %s\n"), pname);
336 			(void) fclose(efd);
337 			efd = NULL;
338 		}
339 		(void) fatal(gettext(" Cassi Interface Msg not writable\n"));
340 		return (0);
341 	}
342 #if 0
343 	fprintf(fd, "%s chpost %s q %s %s MID=%s MFS=%s MPA=%s q q\n", syst, cmrs, pname, types, sids, stats, logname());
344 #else
345 	fprintf(fd, "%s chpost %s q %s %s MID=%s MFS=%s MPA=%s q q\n", syst, cmrs, pname, types, sids, stats, saveid);
346 #endif
347 	(void) fclose(fd);
348 	fd = NULL;
349 	if (noexist) { /* new termLOG make owner of /BD/source owner of file */
350 	    if (stat(dir, &stbuf) == -1) {
351 		if ((efd = fopen(errorlog, "ab")) != NULL) {
352 			fprintf(efd, gettext("***CASSI REPORTS ERROR: can't write to BD/source : %s\n"), pname);
353 			(void) fclose(efd);
354 			efd = NULL;
355 		}
356 		(void) fatal(gettext("Cassi BD/source not writeable\n"));
357 	    }
358 	    (void) chmod(holdfred, (mode_t)0666);
359 	    (void) chown(holdfred, stbuf.st_uid, stbuf.st_gid);
360 	}
361 	return (1);
362 }
363 
364 /*
365  * verif(cmr, fred) calls the verification prog and returns 0 if failed
366  */
367 static int
verif(cmr,fred)368 verif(cmr, fred)
369 	char *cmr, *fred;
370 	{
371 	int res;
372 	char *cmrpass[2];
373 
374 	/*
375 	 * if length of cmr number not = MAXLENCMR error
376 	 *    all cmr numbers are 12 characters long
377 	 */
378 	if (strlen(cmr) != MAXLENCMR)
379 		{
380 			return (0);
381 		}
382 	cmrpass[0] = cmr;
383 	cmrpass[1] = NULL;
384 	res = sweep(SEQVERIFY, fred, NULL, '\n', WHITE, 40, cmrpass, NULL, NULL,
385 		(int(*) __PR((char *, int, char **))) NULL, (int (*) __PR((char **, char **, int))) NULL);
386 	if (res != FOUND) {
387 		return (0);
388 	} else {
389 		return (1);
390 	}
391 }
392 
393 /*
394  * getinfo(freddy, sys)
395  *    get the name of the fred file and the system name
396  */
397 static int
getinfo(freddy,sys)398 getinfo(freddy, sys)
399 	char **freddy, *sys;
400 {
401 	struct stat buf;
402 
403 	*freddy = gf(sys);
404 	if (!(**freddy)) {
405 		printf(gettext("got to bad FRED file %s\n"), *freddy);
406 		return (0);
407 	}
408 	if (stat(*freddy, &buf)) {
409 		return (0);
410 	}
411 	return (1);
412 }
413 
414 static char *
xgets(buf,len)415 xgets(buf, len)
416 	char	*buf;
417 	size_t	len;
418 {
419 	size_t	l;
420 
421 	if (fgets(buf, len, stdin) == NULL)
422 		return (NULL);
423 	l = strlen(buf);
424 	if (l > 0 && buf[l-1] == '\n')
425 		buf[l-1] = '\0';
426 	return (buf);
427 }
428