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 *
nexttok(str,delim,ros)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
parse(p,sp)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 *
trim(p)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 *
pstate(unchar state)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