xref: /titanic_44/usr/src/cmd/saf/readtab.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate /*
26*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1998 by Sun Microsystems, Inc.
27*7c478bd9Sstevel@tonic-gate  * All rights reserved.
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"       /* SVr4.0 1.12*/
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate # include <stdio.h>
33*7c478bd9Sstevel@tonic-gate # include <signal.h>
34*7c478bd9Sstevel@tonic-gate # include "misc.h"
35*7c478bd9Sstevel@tonic-gate # include "msgs.h"
36*7c478bd9Sstevel@tonic-gate # include <sac.h>
37*7c478bd9Sstevel@tonic-gate # include "structs.h"
38*7c478bd9Sstevel@tonic-gate # include <sys/types.h>
39*7c478bd9Sstevel@tonic-gate # include <unistd.h>
40*7c478bd9Sstevel@tonic-gate # include "extern.h"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate /*
44*7c478bd9Sstevel@tonic-gate  * read_table - read in SAC's administrative file and build internal
45*7c478bd9Sstevel@tonic-gate  *		data structures
46*7c478bd9Sstevel@tonic-gate  *
47*7c478bd9Sstevel@tonic-gate  *	args:	startflag - flag to indicate if port monitor's should be
48*7c478bd9Sstevel@tonic-gate  *			    started as a side effect of reading
49*7c478bd9Sstevel@tonic-gate  */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate void
52*7c478bd9Sstevel@tonic-gate read_table(startflag)
53*7c478bd9Sstevel@tonic-gate int startflag;
54*7c478bd9Sstevel@tonic-gate {
55*7c478bd9Sstevel@tonic-gate 	FILE *fp;		/* scratch file pointer */
56*7c478bd9Sstevel@tonic-gate 	int ret;		/* return code from check_version */
57*7c478bd9Sstevel@tonic-gate 	struct sactab *sp;	/* working pointer to move through PM info */
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
60*7c478bd9Sstevel@tonic-gate 	debug("in read_table");
61*7c478bd9Sstevel@tonic-gate # endif
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate /*
64*7c478bd9Sstevel@tonic-gate  * make sure _sactab is ok
65*7c478bd9Sstevel@tonic-gate  */
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate 	Nentries = 0;
68*7c478bd9Sstevel@tonic-gate 	if ((ret = check_version(VERSION, SACTAB)) == 1)
69*7c478bd9Sstevel@tonic-gate 		error(E_BADVER, EXIT);
70*7c478bd9Sstevel@tonic-gate 	else if (ret == 2)
71*7c478bd9Sstevel@tonic-gate 		error(E_SACOPEN, EXIT);
72*7c478bd9Sstevel@tonic-gate 	else if (ret == 3)
73*7c478bd9Sstevel@tonic-gate 		error(E_BADFILE, EXIT);
74*7c478bd9Sstevel@tonic-gate 	fp = fopen(SACTAB, "r");
75*7c478bd9Sstevel@tonic-gate 	if (fp == NULL)
76*7c478bd9Sstevel@tonic-gate 		error(E_SACOPEN, EXIT);
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate /*
79*7c478bd9Sstevel@tonic-gate  * mark all entries as invalid
80*7c478bd9Sstevel@tonic-gate  */
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 	for (sp = Sactab; sp; sp = sp->sc_next)
83*7c478bd9Sstevel@tonic-gate 		sp->sc_valid = 0;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate /*
86*7c478bd9Sstevel@tonic-gate  * build internal structures
87*7c478bd9Sstevel@tonic-gate  */
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	while (sp = read_entry(fp))
90*7c478bd9Sstevel@tonic-gate 		insert(sp, startflag);
91*7c478bd9Sstevel@tonic-gate 	purge();
92*7c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
93*7c478bd9Sstevel@tonic-gate }
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate /*
97*7c478bd9Sstevel@tonic-gate  * read_entry - read an entry from _sactab
98*7c478bd9Sstevel@tonic-gate  *
99*7c478bd9Sstevel@tonic-gate  *	args:	fp - file pointer referencing _sactab
100*7c478bd9Sstevel@tonic-gate  */
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate struct sactab *
103*7c478bd9Sstevel@tonic-gate read_entry(fp)
104*7c478bd9Sstevel@tonic-gate FILE *fp;
105*7c478bd9Sstevel@tonic-gate {
106*7c478bd9Sstevel@tonic-gate 	register struct sactab *sp;	/* working pointer */
107*7c478bd9Sstevel@tonic-gate 	register char *p;		/* scratch pointer */
108*7c478bd9Sstevel@tonic-gate 	char buf[SIZE];			/* scratch buffer */
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate /*
111*7c478bd9Sstevel@tonic-gate  * retrieve a line from the file
112*7c478bd9Sstevel@tonic-gate  */
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate 	do {
115*7c478bd9Sstevel@tonic-gate 		if (fgets(buf, SIZE, fp) == NULL)
116*7c478bd9Sstevel@tonic-gate 			return(NULL);
117*7c478bd9Sstevel@tonic-gate 		p = trim(buf);
118*7c478bd9Sstevel@tonic-gate 	} while (*p == '\0');
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate /*
121*7c478bd9Sstevel@tonic-gate  * allocate a list element for it and then parse the line, parsed
122*7c478bd9Sstevel@tonic-gate  * info goes into list element
123*7c478bd9Sstevel@tonic-gate  */
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	sp = (struct sactab *) calloc(1, sizeof(struct sactab));
126*7c478bd9Sstevel@tonic-gate 	if (sp == NULL)
127*7c478bd9Sstevel@tonic-gate 		error(E_MALLOC, EXIT);
128*7c478bd9Sstevel@tonic-gate 	sp->sc_sstate = sp->sc_lstate = sp->sc_pstate = NOTRUNNING;
129*7c478bd9Sstevel@tonic-gate 	(void) memset(sp->sc_utid, '\0', IDLEN);
130*7c478bd9Sstevel@tonic-gate 	parse(p, sp);
131*7c478bd9Sstevel@tonic-gate 	return(sp);
132*7c478bd9Sstevel@tonic-gate }
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate /*
136*7c478bd9Sstevel@tonic-gate  * insert - insert a sactab entry into the linked list
137*7c478bd9Sstevel@tonic-gate  *
138*7c478bd9Sstevel@tonic-gate  *	args:	sp - entry to be inserted
139*7c478bd9Sstevel@tonic-gate  *		startflag - flag to indicate if port monitor's should be
140*7c478bd9Sstevel@tonic-gate  *			    started as a side effect of reading
141*7c478bd9Sstevel@tonic-gate  */
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate void
144*7c478bd9Sstevel@tonic-gate insert(sp, startflag)
145*7c478bd9Sstevel@tonic-gate register struct sactab *sp;
146*7c478bd9Sstevel@tonic-gate int startflag;
147*7c478bd9Sstevel@tonic-gate {
148*7c478bd9Sstevel@tonic-gate 	register struct sactab *tsp, *savtsp;	/* scratch pointers */
149*7c478bd9Sstevel@tonic-gate 	int ret;				/* strcmp return value */
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
152*7c478bd9Sstevel@tonic-gate 	debug("in insert");
153*7c478bd9Sstevel@tonic-gate # endif
154*7c478bd9Sstevel@tonic-gate 	savtsp = tsp = Sactab;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate /*
157*7c478bd9Sstevel@tonic-gate  * find the correct place to insert this element
158*7c478bd9Sstevel@tonic-gate  */
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	while (tsp) {
161*7c478bd9Sstevel@tonic-gate 		ret = strcmp(sp->sc_tag, tsp->sc_tag);
162*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
163*7c478bd9Sstevel@tonic-gate 		(void) sprintf(Scratch, "sp->sc_tag <%s> tsp->sc_tag <%s>, ret is %d", sp->sc_tag, tsp->sc_tag, ret);
164*7c478bd9Sstevel@tonic-gate 		debug(Scratch);
165*7c478bd9Sstevel@tonic-gate # endif
166*7c478bd9Sstevel@tonic-gate 		if (ret > 0) {
167*7c478bd9Sstevel@tonic-gate 			/* keep on looking */
168*7c478bd9Sstevel@tonic-gate 			savtsp = tsp;
169*7c478bd9Sstevel@tonic-gate 			tsp = tsp->sc_next;
170*7c478bd9Sstevel@tonic-gate 			continue;
171*7c478bd9Sstevel@tonic-gate 		}
172*7c478bd9Sstevel@tonic-gate 		else if (ret == 0) {
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate /*
175*7c478bd9Sstevel@tonic-gate  * found an entry for it in the list, either a duplicate or we're
176*7c478bd9Sstevel@tonic-gate  * rereading the file.
177*7c478bd9Sstevel@tonic-gate  */
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 			if (tsp->sc_valid) {
180*7c478bd9Sstevel@tonic-gate 				/* this is a duplicate entry, ignore it */
181*7c478bd9Sstevel@tonic-gate 				(void) sprintf(Scratch, "Ignoring duplicate entry for <%s>", tsp->sc_tag);
182*7c478bd9Sstevel@tonic-gate 				log(Scratch);
183*7c478bd9Sstevel@tonic-gate 			}
184*7c478bd9Sstevel@tonic-gate 			else {
185*7c478bd9Sstevel@tonic-gate 				/* found a valid match, replace flags & restart max only */
186*7c478bd9Sstevel@tonic-gate 				tsp->sc_rsmax = sp->sc_rsmax;
187*7c478bd9Sstevel@tonic-gate 				tsp->sc_flags = sp->sc_flags;
188*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
189*7c478bd9Sstevel@tonic-gate 				(void) sprintf(Scratch, "replacing <%s>", sp->sc_tag);
190*7c478bd9Sstevel@tonic-gate 				debug(Scratch);
191*7c478bd9Sstevel@tonic-gate # endif
192*7c478bd9Sstevel@tonic-gate 				/* this entry is "current" */
193*7c478bd9Sstevel@tonic-gate 				tsp->sc_valid = 1;
194*7c478bd9Sstevel@tonic-gate 				Nentries++;
195*7c478bd9Sstevel@tonic-gate 			}
196*7c478bd9Sstevel@tonic-gate 			free(sp->sc_cmd);
197*7c478bd9Sstevel@tonic-gate 			free(sp);
198*7c478bd9Sstevel@tonic-gate 			return;
199*7c478bd9Sstevel@tonic-gate 		}
200*7c478bd9Sstevel@tonic-gate 		else {
201*7c478bd9Sstevel@tonic-gate 			/* insert it here */
202*7c478bd9Sstevel@tonic-gate 			if (tsp == Sactab) {
203*7c478bd9Sstevel@tonic-gate 				sp->sc_next = Sactab;
204*7c478bd9Sstevel@tonic-gate 				Sactab = sp;
205*7c478bd9Sstevel@tonic-gate 			}
206*7c478bd9Sstevel@tonic-gate 			else {
207*7c478bd9Sstevel@tonic-gate 				sp->sc_next = savtsp->sc_next;
208*7c478bd9Sstevel@tonic-gate 				savtsp->sc_next = sp;
209*7c478bd9Sstevel@tonic-gate 			}
210*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
211*7c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "adding <%s>", sp->sc_tag);
212*7c478bd9Sstevel@tonic-gate 			debug(Scratch);
213*7c478bd9Sstevel@tonic-gate # endif
214*7c478bd9Sstevel@tonic-gate 			Nentries++;
215*7c478bd9Sstevel@tonic-gate 			/* this entry is "current" */
216*7c478bd9Sstevel@tonic-gate 			sp->sc_valid = 1;
217*7c478bd9Sstevel@tonic-gate 			if (startflag && !(sp->sc_flags & X_FLAG))
218*7c478bd9Sstevel@tonic-gate 				(void) startpm(sp);
219*7c478bd9Sstevel@tonic-gate 			return;
220*7c478bd9Sstevel@tonic-gate 		}
221*7c478bd9Sstevel@tonic-gate 	}
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate /*
224*7c478bd9Sstevel@tonic-gate  * either an empty list or should put element at end of list
225*7c478bd9Sstevel@tonic-gate  */
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 	sp->sc_next = NULL;
228*7c478bd9Sstevel@tonic-gate 	if (Sactab == NULL)
229*7c478bd9Sstevel@tonic-gate 		Sactab = sp;
230*7c478bd9Sstevel@tonic-gate 	else
231*7c478bd9Sstevel@tonic-gate 		savtsp->sc_next = sp;
232*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
233*7c478bd9Sstevel@tonic-gate 	(void) sprintf(Scratch, "adding <%s>", sp->sc_tag);
234*7c478bd9Sstevel@tonic-gate 	debug(Scratch);
235*7c478bd9Sstevel@tonic-gate # endif
236*7c478bd9Sstevel@tonic-gate 	++Nentries;
237*7c478bd9Sstevel@tonic-gate 	/* this entry is "current" */
238*7c478bd9Sstevel@tonic-gate 	sp->sc_valid = 1;
239*7c478bd9Sstevel@tonic-gate 	if (startflag && !(sp->sc_flags & X_FLAG))
240*7c478bd9Sstevel@tonic-gate 		(void) startpm(sp);
241*7c478bd9Sstevel@tonic-gate }
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate /*
246*7c478bd9Sstevel@tonic-gate  * purge - purge linked list of "old" entries
247*7c478bd9Sstevel@tonic-gate  */
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate void
251*7c478bd9Sstevel@tonic-gate purge()
252*7c478bd9Sstevel@tonic-gate {
253*7c478bd9Sstevel@tonic-gate 	register struct sactab *sp;		/* working pointer */
254*7c478bd9Sstevel@tonic-gate 	register struct sactab *savesp, *tsp;	/* scratch pointers */
255*7c478bd9Sstevel@tonic-gate 	sigset_t cset;				/* for signal handling */
256*7c478bd9Sstevel@tonic-gate 	sigset_t tset;				/* for signal handling */
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
259*7c478bd9Sstevel@tonic-gate 	debug("in purge");
260*7c478bd9Sstevel@tonic-gate # endif
261*7c478bd9Sstevel@tonic-gate 	/* get current signal mask */
262*7c478bd9Sstevel@tonic-gate 	(void) sigprocmask(SIG_SETMASK, NULL, &cset);
263*7c478bd9Sstevel@tonic-gate 	sp = savesp = Sactab;
264*7c478bd9Sstevel@tonic-gate 	while (sp) {
265*7c478bd9Sstevel@tonic-gate 		if (sp->sc_valid) {
266*7c478bd9Sstevel@tonic-gate 			savesp = sp;
267*7c478bd9Sstevel@tonic-gate 			sp = sp->sc_next;
268*7c478bd9Sstevel@tonic-gate 			continue;
269*7c478bd9Sstevel@tonic-gate 		}
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 		/* element should be removed */
272*7c478bd9Sstevel@tonic-gate 		switch (sp->sc_sstate) {
273*7c478bd9Sstevel@tonic-gate 		case UNKNOWN:
274*7c478bd9Sstevel@tonic-gate 		case ENABLED:
275*7c478bd9Sstevel@tonic-gate 		case DISABLED:
276*7c478bd9Sstevel@tonic-gate 		case STARTING:
277*7c478bd9Sstevel@tonic-gate 			/* need to kill it */
278*7c478bd9Sstevel@tonic-gate 			tset = cset;
279*7c478bd9Sstevel@tonic-gate 			(void) sigaddset(&tset, SIGALRM);
280*7c478bd9Sstevel@tonic-gate 			(void) sigaddset(&tset, SIGCLD);
281*7c478bd9Sstevel@tonic-gate 			(void) sigprocmask(SIG_SETMASK, &tset, NULL);
282*7c478bd9Sstevel@tonic-gate 			if (sendsig(sp, SIGTERM))
283*7c478bd9Sstevel@tonic-gate 				(void) sprintf(Scratch, "could not send SIGTERM to <%s>", sp->sc_tag);
284*7c478bd9Sstevel@tonic-gate 			else
285*7c478bd9Sstevel@tonic-gate 				(void) sprintf(Scratch, "terminating <%s>", sp->sc_tag);
286*7c478bd9Sstevel@tonic-gate 			log(Scratch);
287*7c478bd9Sstevel@tonic-gate 			(void) sigdelset(&tset, SIGALRM);
288*7c478bd9Sstevel@tonic-gate 			(void) sigprocmask(SIG_SETMASK, &tset, NULL);
289*7c478bd9Sstevel@tonic-gate 			/* fall thru */
290*7c478bd9Sstevel@tonic-gate 		case STOPPING:
291*7c478bd9Sstevel@tonic-gate 			(void) close(sp->sc_fd);
292*7c478bd9Sstevel@tonic-gate 			/* fall thru */
293*7c478bd9Sstevel@tonic-gate 		case NOTRUNNING:
294*7c478bd9Sstevel@tonic-gate 		case FAILED:
295*7c478bd9Sstevel@tonic-gate 			cleanutx(sp);
296*7c478bd9Sstevel@tonic-gate 			tsp = sp;
297*7c478bd9Sstevel@tonic-gate 			if (tsp == Sactab) {
298*7c478bd9Sstevel@tonic-gate 				Sactab = sp->sc_next;
299*7c478bd9Sstevel@tonic-gate 				savesp = Sactab;
300*7c478bd9Sstevel@tonic-gate 			}
301*7c478bd9Sstevel@tonic-gate 			else
302*7c478bd9Sstevel@tonic-gate 				savesp->sc_next = sp->sc_next;
303*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
304*7c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "purging <%s>", sp->sc_tag);
305*7c478bd9Sstevel@tonic-gate 			debug(Scratch);
306*7c478bd9Sstevel@tonic-gate # endif
307*7c478bd9Sstevel@tonic-gate 			sp = sp->sc_next;
308*7c478bd9Sstevel@tonic-gate 			free(tsp->sc_cmd);
309*7c478bd9Sstevel@tonic-gate 			free(tsp->sc_comment);
310*7c478bd9Sstevel@tonic-gate 			free(tsp);
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate /*
313*7c478bd9Sstevel@tonic-gate  * all done cleaning up, restore signal mask
314*7c478bd9Sstevel@tonic-gate  */
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 			(void) sigprocmask(SIG_SETMASK, &cset, NULL);
317*7c478bd9Sstevel@tonic-gate 			break;
318*7c478bd9Sstevel@tonic-gate 		}
319*7c478bd9Sstevel@tonic-gate 	}
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate /*
324*7c478bd9Sstevel@tonic-gate  * dump_table - dump the internal SAC table, used to satisfy sacadm -l
325*7c478bd9Sstevel@tonic-gate  */
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate char **
329*7c478bd9Sstevel@tonic-gate dump_table()
330*7c478bd9Sstevel@tonic-gate {
331*7c478bd9Sstevel@tonic-gate 	register struct sactab *sp;	/* working pointer */
332*7c478bd9Sstevel@tonic-gate 	register char *p;		/* scratch pointer */
333*7c478bd9Sstevel@tonic-gate 	register int size;		/* size of "dumped" table */
334*7c478bd9Sstevel@tonic-gate 	char **info, **savinfo;		/* scratch pointers */
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
337*7c478bd9Sstevel@tonic-gate 	(void) sprintf(Scratch, "about to 'info' malloc %d entries", Nentries);
338*7c478bd9Sstevel@tonic-gate 	debug(Scratch);
339*7c478bd9Sstevel@tonic-gate # endif
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate /*
342*7c478bd9Sstevel@tonic-gate  * get space for number of entries we have
343*7c478bd9Sstevel@tonic-gate  */
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate 	if (Nentries == 0)
346*7c478bd9Sstevel@tonic-gate 		return(NULL);
347*7c478bd9Sstevel@tonic-gate 	if ((info = (char **) malloc(Nentries * sizeof(char *))) == NULL) {
348*7c478bd9Sstevel@tonic-gate 		error(E_MALLOC, CONT);
349*7c478bd9Sstevel@tonic-gate 		return(NULL);
350*7c478bd9Sstevel@tonic-gate 	}
351*7c478bd9Sstevel@tonic-gate 	savinfo = info;
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate /*
354*7c478bd9Sstevel@tonic-gate  * traverse the list allocating space for entries and formatting them
355*7c478bd9Sstevel@tonic-gate  */
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 	for (sp = Sactab; sp; sp = sp->sc_next) {
358*7c478bd9Sstevel@tonic-gate 		size = strlen(sp->sc_tag) + strlen(sp->sc_type) + strlen(sp->sc_cmd) + strlen(sp->sc_comment) + SLOP;
359*7c478bd9Sstevel@tonic-gate 		if ((p = malloc((unsigned) size)) == NULL) {
360*7c478bd9Sstevel@tonic-gate 			error(E_MALLOC, CONT);
361*7c478bd9Sstevel@tonic-gate 			return(NULL);
362*7c478bd9Sstevel@tonic-gate 		}
363*7c478bd9Sstevel@tonic-gate 		(void) sprintf(p, "%s:%s:%d:%d:%d:%s:%s\n", sp->sc_tag, sp->sc_type,
364*7c478bd9Sstevel@tonic-gate 			sp->sc_flags, sp->sc_rsmax, sp->sc_pstate, sp->sc_cmd, sp->sc_comment);
365*7c478bd9Sstevel@tonic-gate 		*info++ = p;
366*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
367*7c478bd9Sstevel@tonic-gate 		debug(*(info - 1));
368*7c478bd9Sstevel@tonic-gate # endif
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate 	return(savinfo);
371*7c478bd9Sstevel@tonic-gate }
372