xref: /illumos-gate/usr/src/cmd/saf/util.c (revision 34e48580)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 /*
26  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 
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
46 
47 char	Comment[SIZE];	/* place holder for comments */
48 
49 
50 /*
51  * nexttok - return next token, essentially a strtok, but it can
52  *	deal with null fields and strtok can not
53  *
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)
59  */
60 
61 
62 char *
nexttok(str,delim,ros)63 nexttok(str, delim, ros)
64 char *str;
65 register char *delim;
66 int ros;
67 {
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 */
71 
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);
81 	}
82 	savep = ep + 1;
83 	*ep = '\0';
84 	return(p);
85 }
86 
87 
88 /*
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.
91  *
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
95  *
96  *	A line in the file has the following format:
97  *
98  *	tag:type:flags:restart_count:command_string	#comment
99  */
100 
101 
102 void
parse(p,sp)103 parse(p, sp)
104 register char *p;
105 register struct sactab *sp;
106 {
107 	char scratch[SIZE];	/* a scratch buffer */
108 
109 /*
110  * get the PM tag
111  */
112 
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
121 	}
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
130 	}
131 	(void) strcpy(sp->sc_tag, p);
132 
133 /*
134  * get the PM type
135  */
136 
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
145 	}
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
154 	}
155 	(void) strcpy(sp->sc_type, p);
156 
157 /*
158  * get the flags
159  */
160 
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
169 	}
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;
188 		}
189 	}
190 
191 /*
192  * get the restart count
193  */
194 
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
203 	}
204 	sp->sc_rsmax = atoi(p);
205 
206 /*
207  * get the command string
208  */
209 
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
218 	}
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
226 	}
227 	(void) strcpy(sp->sc_cmd, p);
228 
229 /*
230  * remember the comment string
231  */
232 
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
240 	}
241 	(void) strcpy(sp->sc_comment, Comment);
242 }
243 
244 
245 /*
246  * trim - remove comments, trim off trailing white space, done in place
247  *	args:	p - string to be acted upon
248  */
249 
250 char *
trim(p)251 trim(p)
252 register char *p;
253 {
254 	register char *tp;	/* temp pointer */
255 
256 /*
257  * remove comments, if any, but remember them for later
258  */
259 
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';
268 	}
269 
270 /*
271  * remove trailing whitespace, if any
272  */
273 
274 	for (tp = p + strlen(p) - 1; tp >= p && isspace(*tp); --tp)
275 		*tp = '\0';
276 	return(p);
277 }
278 
279 
280 /*
281  * pstate - put port monitor state into intelligible form for output
282  *	SSTATE is only used by sacadm
283  *
284  *	args:	state - binary representation of state
285  */
286 
287 char *
pstate(unchar state)288 pstate(unchar state)
289 {
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
316 	}
317 	/* NOTREACHED */
318 	return (NULL);
319 }
320