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