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