Merge commit '00f1a4f432b3d8aad1aa270e91c44c57f03ef407'
[unleashed.git] / usr / src / cmd / saf / util.c
blobbc05e98107a99bdcea5825e59900e768491a3505
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"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <ctype.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include "extern.h"
40 #include "misc.h"
41 #include <sac.h>
42 #include "structs.h"
43 #ifdef SAC
44 #include "msgs.h"
45 #endif
47 char Comment[SIZE]; /* place holder for comments */
51 * nexttok - return next token, essentially a strtok, but it can
52 * deal with null fields and strtok can not
54 * args: str - the string to be examined, NULL if we should
55 * examine the remembered string
56 * delim - the list of valid delimiters
57 * ros - rest of string flag (1 for rest of string, 0 for
58 * normal processing)
62 char *
63 nexttok(str, delim, ros)
64 char *str;
65 register char *delim;
66 int ros;
68 static char *savep; /* the remembered string */
69 register char *p; /* pointer to start of token */
70 register char *ep; /* pointer to end of token */
72 p = (str == NULL) ? savep : str ;
73 if (ros)
74 return(p);
75 if (p == NULL)
76 return(NULL);
77 ep = strpbrk(p, delim);
78 if (ep == NULL) {
79 savep = NULL;
80 return(p);
82 savep = ep + 1;
83 *ep = '\0';
84 return(p);
89 * parse - parse a line from _sactab. This routine will return if the parse
90 * was successful, otherwise it will output an error and exit.
92 * args: p - pointer to the data read from the file
93 * sp - pointer to a structure in which the separated fields
94 * are placed
96 * A line in the file has the following format:
98 * tag:type:flags:restart_count:command_string #comment
102 void
103 parse(p, sp)
104 register char *p;
105 register struct sactab *sp;
107 char scratch[SIZE]; /* a scratch buffer */
110 * get the PM tag
113 p = nexttok(p, DELIM, FALSE);
114 if (p == NULL) {
115 # ifdef SAC
116 error(E_BADFILE, EXIT);
117 # else
118 Saferrno = E_SAFERR;
119 error("_sactab file is corrupt");
120 # endif
122 if (strlen(p) > PMTAGSIZE) {
123 p[PMTAGSIZE] = '\0';
124 # ifdef SAC
125 (void) sprintf(scratch, "tag too long, truncated to <%s>", p);
126 log(scratch);
127 # else
128 (void) fprintf(stderr, "tag too long, truncated to <%s>", p);
129 # endif
131 (void) strcpy(sp->sc_tag, p);
134 * get the PM type
137 p = nexttok(NULL, DELIM, FALSE);
138 if (p == NULL) {
139 # ifdef SAC
140 error(E_BADFILE, EXIT);
141 # else
142 Saferrno = E_SAFERR;
143 error("_sactab file is corrupt");
144 # endif
146 if (strlen(p) > PMTYPESIZE) {
147 p[PMTYPESIZE] = '\0';
148 # ifdef SAC
149 (void) sprintf(scratch, "type too long, truncated to <%s>", p);
150 log(scratch);
151 # else
152 (void) fprintf(stderr, "type too long, truncated to <%s>", p);
153 # endif
155 (void) strcpy(sp->sc_type, p);
158 * get the flags
161 p = nexttok(NULL, DELIM, FALSE);
162 if (p == NULL) {
163 # ifdef SAC
164 error(E_BADFILE, EXIT);
165 # else
166 Saferrno = E_SAFERR;
167 error("_sactab file is corrupt");
168 # endif
170 sp->sc_flags = 0;
171 while (*p) {
172 switch (*p++) {
173 case 'd':
174 sp->sc_flags |= D_FLAG;
175 break;
176 case 'x':
177 sp->sc_flags |= X_FLAG;
178 break;
179 default:
180 (void) sprintf(scratch, "Unrecognized flag <%c>", *(p - 1));
181 # ifdef SAC
182 log(scratch);
183 # else
184 Saferrno = E_SAFERR;
185 error(scratch);
186 # endif
187 break;
192 * get the restart count
195 p = nexttok(NULL, DELIM, FALSE);
196 if (p == NULL) {
197 # ifdef SAC
198 error(E_BADFILE, EXIT);
199 # else
200 Saferrno = E_SAFERR;
201 error("_sactab file is corrupt");
202 # endif
204 sp->sc_rsmax = atoi(p);
207 * get the command string
210 p = nexttok(NULL, DELIM, FALSE);
211 if (p == NULL) {
212 # ifdef SAC
213 error(E_BADFILE, EXIT);
214 # else
215 Saferrno = E_SAFERR;
216 error("_sactab file is corrupt");
217 # endif
219 if ((sp->sc_cmd = malloc((unsigned) (strlen(p) + 1))) == NULL) {
220 # ifdef SAC
221 error(E_MALLOC, EXIT);
222 # else
223 Saferrno = E_SAFERR;
224 error("malloc failed");
225 # endif
227 (void) strcpy(sp->sc_cmd, p);
230 * remember the comment string
233 if ((sp->sc_comment = malloc((unsigned) (strlen(Comment) + 1))) == NULL) {
234 # ifdef SAC
235 error(E_MALLOC, EXIT);
236 # else
237 Saferrno = E_SAFERR;
238 error("malloc failed");
239 # endif
241 (void) strcpy(sp->sc_comment, Comment);
246 * trim - remove comments, trim off trailing white space, done in place
247 * args: p - string to be acted upon
250 char *
251 trim(p)
252 register char *p;
254 register char *tp; /* temp pointer */
257 * remove comments, if any, but remember them for later
260 tp = strchr(p, COMMENT);
261 Comment[0] = '\0';
262 if (tp) {
263 (void) strcpy(Comment, tp + 1); /* skip the '#' */
264 *tp = '\0';
265 tp = strchr(Comment, '\n');
266 if (tp)
267 *tp ='\0';
271 * remove trailing whitespace, if any
274 for (tp = p + strlen(p) - 1; tp >= p && isspace(*tp); --tp)
275 *tp = '\0';
276 return(p);
281 * pstate - put port monitor state into intelligible form for output
282 * SSTATE is only used by sacadm
284 * args: state - binary representation of state
287 char *
288 pstate(unchar state)
290 switch (state) {
291 case NOTRUNNING:
292 return("NOTRUNNING");
293 case STARTING:
294 return("STARTING");
295 case ENABLED:
296 return("ENABLED");
297 case DISABLED:
298 return("DISABLED");
299 case STOPPING:
300 return("STOPPING");
301 case FAILED:
302 return("FAILED");
303 case UNKNOWN:
304 return("UNKNOWN");
305 # ifndef SAC
306 case SSTATE:
307 return("NO_SAC");
308 # endif
309 default:
310 # ifdef SAC
311 error(E_BADSTATE, EXIT);
312 # else
313 Saferrno = E_SAFERR;
314 error("Improper message from SAC\n");
315 # endif
317 /* NOTREACHED */
318 return (NULL);