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
47char	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
62char *
63nexttok(str, delim, ros)
64char *str;
65register char *delim;
66int 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
102void
103parse(p, sp)
104register char *p;
105register 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
250char *
251trim(p)
252register 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
287char *
288pstate(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