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