xref: /titanic_44/usr/src/cmd/nlsadmin/nlsadmin.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * nlsadmin.c -- control program for the network listener service
35*7c478bd9Sstevel@tonic-gate  *
36*7c478bd9Sstevel@tonic-gate  * This program replaces a previous version of nlsadmin.
37*7c478bd9Sstevel@tonic-gate  *
38*7c478bd9Sstevel@tonic-gate  * This version of nlsadmin works with the service access facility to
39*7c478bd9Sstevel@tonic-gate  * control the network listener.  The functionality of the SVR3.2 nlsadmin
40*7c478bd9Sstevel@tonic-gate  * command is supported through calls to the more general sacadm and pmadm
41*7c478bd9Sstevel@tonic-gate  * commands available through SAF.  Users should migrate away from nlsadmin
42*7c478bd9Sstevel@tonic-gate  * to sacadm and pmadm for these functions.
43*7c478bd9Sstevel@tonic-gate  *
44*7c478bd9Sstevel@tonic-gate  * The -m option of the SVR3.2 nlsadmin command is now ignored.
45*7c478bd9Sstevel@tonic-gate  *
46*7c478bd9Sstevel@tonic-gate  * The -t option associates an address with service code 1 (same as in SVR3.2).
47*7c478bd9Sstevel@tonic-gate  * The -l option associates an address with service code 0.
48*7c478bd9Sstevel@tonic-gate  *
49*7c478bd9Sstevel@tonic-gate  * nlsadmin also contains new functionality -- the ability to format a
50*7c478bd9Sstevel@tonic-gate  * "listener-specific" string to put in the _pmtab database.  This
51*7c478bd9Sstevel@tonic-gate  * functionality is required by SAF.
52*7c478bd9Sstevel@tonic-gate  */
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
55*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
56*7c478bd9Sstevel@tonic-gate #include <stdio.h>
57*7c478bd9Sstevel@tonic-gate #include <ctype.h>
58*7c478bd9Sstevel@tonic-gate #include <errno.h>
59*7c478bd9Sstevel@tonic-gate #include <string.h>
60*7c478bd9Sstevel@tonic-gate #include <sac.h>
61*7c478bd9Sstevel@tonic-gate #include "nlsadmin.h"
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate #define OPTIONS	"a:c:d:e:ikl:mo:p:qr:st:vw:xy:z:A:N:VDR:"
64*7c478bd9Sstevel@tonic-gate #ifndef FALSE
65*7c478bd9Sstevel@tonic-gate #define TRUE	1
66*7c478bd9Sstevel@tonic-gate #define FALSE	0
67*7c478bd9Sstevel@tonic-gate #endif
68*7c478bd9Sstevel@tonic-gate /*
69*7c478bd9Sstevel@tonic-gate  * defines for -q exit codes: QZERO is used for conditions that the
70*7c478bd9Sstevel@tonic-gate  * man page documents as returning 0, QONE for those that return 1
71*7c478bd9Sstevel@tonic-gate  */
72*7c478bd9Sstevel@tonic-gate #define QZERO	0
73*7c478bd9Sstevel@tonic-gate #define QONE	1
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate /*
76*7c478bd9Sstevel@tonic-gate  * defines for simulated standard error format code
77*7c478bd9Sstevel@tonic-gate  */
78*7c478bd9Sstevel@tonic-gate #define MM_NOSEV        0
79*7c478bd9Sstevel@tonic-gate #define MM_HALT         1
80*7c478bd9Sstevel@tonic-gate #define MM_ERROR        2
81*7c478bd9Sstevel@tonic-gate #define MM_WARNING      3
82*7c478bd9Sstevel@tonic-gate #define MM_INFO         4
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate char	*Nlsname;		/* set to argv[0]			*/
85*7c478bd9Sstevel@tonic-gate char	Label[25];		/* label component for fmtmsg		*/
86*7c478bd9Sstevel@tonic-gate int	Quietflag = FALSE;	/* set to TRUE when -q used		*/
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate extern	int errno;
89*7c478bd9Sstevel@tonic-gate void	nlsmesg();
90*7c478bd9Sstevel@tonic-gate uid_t	geteuid();
91*7c478bd9Sstevel@tonic-gate char	*nexttok();
92*7c478bd9Sstevel@tonic-gate char	*pflags();
93*7c478bd9Sstevel@tonic-gate char	*gencmdstr();
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate struct	svcfields {
96*7c478bd9Sstevel@tonic-gate 	char	*pmtag;
97*7c478bd9Sstevel@tonic-gate 	char	*pmtype;
98*7c478bd9Sstevel@tonic-gate 	char	*svc_code;
99*7c478bd9Sstevel@tonic-gate 	char	*flags;
100*7c478bd9Sstevel@tonic-gate 	char	*id;
101*7c478bd9Sstevel@tonic-gate 	char	*res1;
102*7c478bd9Sstevel@tonic-gate 	char	*res2;
103*7c478bd9Sstevel@tonic-gate 	char	*res3;
104*7c478bd9Sstevel@tonic-gate 	char	*addr;
105*7c478bd9Sstevel@tonic-gate 	char	*rpc;
106*7c478bd9Sstevel@tonic-gate 	char	*lflags;
107*7c478bd9Sstevel@tonic-gate 	char	*modules;
108*7c478bd9Sstevel@tonic-gate 	char	*command;
109*7c478bd9Sstevel@tonic-gate 	char	*comment;
110*7c478bd9Sstevel@tonic-gate };
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate main(argc, argv)
114*7c478bd9Sstevel@tonic-gate int argc;
115*7c478bd9Sstevel@tonic-gate char **argv;
116*7c478bd9Sstevel@tonic-gate {
117*7c478bd9Sstevel@tonic-gate 	extern	char *optarg;
118*7c478bd9Sstevel@tonic-gate 	extern	int optind;
119*7c478bd9Sstevel@tonic-gate 	int	c;			/* used for return from getopt  */
120*7c478bd9Sstevel@tonic-gate 	char	*addrptr = NULL;	/* set when -A address is used	*/
121*7c478bd9Sstevel@tonic-gate 	char	*rpcptr = NULL;		/* set when -R rpcinfo is used	*/
122*7c478bd9Sstevel@tonic-gate 	char	*cmdptr = NULL;		/* set with -c command		*/
123*7c478bd9Sstevel@tonic-gate 	char	*comptr = NULL;		/* set with -y comment (old)	*/
124*7c478bd9Sstevel@tonic-gate 	char	*idptr = NULL;		/* set with -w id (old)		*/
125*7c478bd9Sstevel@tonic-gate 	char	*lptr = NULL;		/* set with -l addr (old)	*/
126*7c478bd9Sstevel@tonic-gate 	char	*moduleptr = NULL;	/* set with -m modules		*/
127*7c478bd9Sstevel@tonic-gate 	char	*pipeptr = NULL;	/* set with -o pipe		*/
128*7c478bd9Sstevel@tonic-gate 	char	*svcptr = NULL;		/* set when service code used (old) */
129*7c478bd9Sstevel@tonic-gate 	char	*tptr = NULL;		/* set when -t addr used (old)	*/
130*7c478bd9Sstevel@tonic-gate 	char	*netspec = NULL;	/* set to the network specification */
131*7c478bd9Sstevel@tonic-gate 	int	flag = 0;		/* bit flag of type of command	*/
132*7c478bd9Sstevel@tonic-gate 	int	exitcode = 0;		/* exit status of this command	*/
133*7c478bd9Sstevel@tonic-gate 	int	lflags = 0;		/* listener flags		*/
134*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];		/* temp buffer #1		*/
135*7c478bd9Sstevel@tonic-gate 	char	mesg[BUFSIZ];		/* temp buffer #2		*/
136*7c478bd9Sstevel@tonic-gate 	FILE	*fp;			/* used for checking netspec	*/
137*7c478bd9Sstevel@tonic-gate 	char	*ptr;			/* temp pointer			*/
138*7c478bd9Sstevel@tonic-gate 	char	*ptr2;			/* temp pointer			*/
139*7c478bd9Sstevel@tonic-gate 	int	sawsep = 0;		/* flag for RPC separator	*/
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	Nlsname = argv[0];
142*7c478bd9Sstevel@tonic-gate 	sprintf(Label, "UX:%.14s", argv[0]);	/* for standard message fmt */
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, OPTIONS)) != -1) {
145*7c478bd9Sstevel@tonic-gate 		switch (c) {
146*7c478bd9Sstevel@tonic-gate 		case 'a':
147*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG)) || svcptr || Quietflag
148*7c478bd9Sstevel@tonic-gate 			      || addrptr || rpcptr || lflags)
149*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
150*7c478bd9Sstevel@tonic-gate 			svcptr = optarg;
151*7c478bd9Sstevel@tonic-gate 			break;
152*7c478bd9Sstevel@tonic-gate 		case 'c':
153*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG)) || cmdptr || Quietflag )
154*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
155*7c478bd9Sstevel@tonic-gate 			cmdptr = optarg;
156*7c478bd9Sstevel@tonic-gate 			flag |= CMDFLAG;
157*7c478bd9Sstevel@tonic-gate 			break;
158*7c478bd9Sstevel@tonic-gate 		case 'd':
159*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
160*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
161*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
162*7c478bd9Sstevel@tonic-gate 			svcptr = optarg;
163*7c478bd9Sstevel@tonic-gate 			flag |= DISFLAG;
164*7c478bd9Sstevel@tonic-gate 			break;
165*7c478bd9Sstevel@tonic-gate 		case 'e':
166*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
167*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
168*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
169*7c478bd9Sstevel@tonic-gate 			svcptr = optarg;
170*7c478bd9Sstevel@tonic-gate 			flag |= ENAFLAG;
171*7c478bd9Sstevel@tonic-gate 			break;
172*7c478bd9Sstevel@tonic-gate 		case 'i':
173*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
174*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
175*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
176*7c478bd9Sstevel@tonic-gate 			flag |= INIFLAG;
177*7c478bd9Sstevel@tonic-gate 			break;
178*7c478bd9Sstevel@tonic-gate 		case 'k':
179*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
180*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
181*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
182*7c478bd9Sstevel@tonic-gate 			flag |= KILFLAG;
183*7c478bd9Sstevel@tonic-gate 			break;
184*7c478bd9Sstevel@tonic-gate 		case 'l':
185*7c478bd9Sstevel@tonic-gate 			if ( ( flag && (flag != ADRFLAG)) || svcptr || lptr
186*7c478bd9Sstevel@tonic-gate 			      || Quietflag || comptr || addrptr || rpcptr
187*7c478bd9Sstevel@tonic-gate 			      || cmdptr || idptr || lflags )
188*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
189*7c478bd9Sstevel@tonic-gate 			lptr = optarg;
190*7c478bd9Sstevel@tonic-gate 			flag |= ADRFLAG;
191*7c478bd9Sstevel@tonic-gate 			break;
192*7c478bd9Sstevel@tonic-gate 		case 'm':
193*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG)) || Quietflag || rpcptr || lflags )
194*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
195*7c478bd9Sstevel@tonic-gate 			flag |= CMDFLAG;
196*7c478bd9Sstevel@tonic-gate 			break;
197*7c478bd9Sstevel@tonic-gate 		case 'o':
198*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || idptr || netspec )
199*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
200*7c478bd9Sstevel@tonic-gate 			pipeptr = optarg;
201*7c478bd9Sstevel@tonic-gate 			flag |= PIPFLAG;
202*7c478bd9Sstevel@tonic-gate 			break;
203*7c478bd9Sstevel@tonic-gate 		case 'p':
204*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG)) || Quietflag )
205*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
206*7c478bd9Sstevel@tonic-gate 			moduleptr = optarg;
207*7c478bd9Sstevel@tonic-gate 			break;
208*7c478bd9Sstevel@tonic-gate 		case 'q':
209*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != ZZZFLAG)) || Quietflag || comptr
210*7c478bd9Sstevel@tonic-gate 			     || rpcptr || lflags || idptr )
211*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
212*7c478bd9Sstevel@tonic-gate 			Quietflag = TRUE;
213*7c478bd9Sstevel@tonic-gate 			break;
214*7c478bd9Sstevel@tonic-gate 		case 'r':
215*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
216*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
217*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
218*7c478bd9Sstevel@tonic-gate 			flag |= REMFLAG;
219*7c478bd9Sstevel@tonic-gate 			svcptr = optarg;
220*7c478bd9Sstevel@tonic-gate 			break;
221*7c478bd9Sstevel@tonic-gate 		case 's':
222*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || addrptr
223*7c478bd9Sstevel@tonic-gate 			     || rpcptr || cmdptr || idptr || lflags )
224*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
225*7c478bd9Sstevel@tonic-gate 			flag |= STAFLAG;
226*7c478bd9Sstevel@tonic-gate 			break;
227*7c478bd9Sstevel@tonic-gate 		case 't':
228*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != ADRFLAG)) || svcptr || tptr
229*7c478bd9Sstevel@tonic-gate 			      || Quietflag || comptr || addrptr || rpcptr
230*7c478bd9Sstevel@tonic-gate 			      || cmdptr || idptr || lflags )
231*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
232*7c478bd9Sstevel@tonic-gate 			tptr = optarg;
233*7c478bd9Sstevel@tonic-gate 			flag |= ADRFLAG;
234*7c478bd9Sstevel@tonic-gate 			break;
235*7c478bd9Sstevel@tonic-gate 		case 'v':
236*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || rpcptr
237*7c478bd9Sstevel@tonic-gate 			     || addrptr || idptr || lflags )
238*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
239*7c478bd9Sstevel@tonic-gate 			flag |= VBSFLAG;
240*7c478bd9Sstevel@tonic-gate 			break;
241*7c478bd9Sstevel@tonic-gate 		case 'w':
242*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG)) || Quietflag || idptr
243*7c478bd9Sstevel@tonic-gate 			     || rpcptr || addrptr || lflags )
244*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
245*7c478bd9Sstevel@tonic-gate 			idptr = optarg;
246*7c478bd9Sstevel@tonic-gate 			break;
247*7c478bd9Sstevel@tonic-gate 		case 'x':
248*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || netspec || comptr
249*7c478bd9Sstevel@tonic-gate 			     || rpcptr || addrptr || lflags || idptr )
250*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
251*7c478bd9Sstevel@tonic-gate 			flag |= NETFLAG;
252*7c478bd9Sstevel@tonic-gate 			break;
253*7c478bd9Sstevel@tonic-gate 		case 'y':
254*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG)) || Quietflag || comptr
255*7c478bd9Sstevel@tonic-gate 			     || rpcptr || addrptr || lflags )
256*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
257*7c478bd9Sstevel@tonic-gate 			comptr = optarg;
258*7c478bd9Sstevel@tonic-gate 			break;
259*7c478bd9Sstevel@tonic-gate 		case 'z':
260*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || comptr || addrptr || rpcptr
261*7c478bd9Sstevel@tonic-gate 			     || idptr || lflags )
262*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
263*7c478bd9Sstevel@tonic-gate 			flag |= ZZZFLAG;
264*7c478bd9Sstevel@tonic-gate 			svcptr = optarg;
265*7c478bd9Sstevel@tonic-gate 			break;
266*7c478bd9Sstevel@tonic-gate 		case 'A':
267*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
268*7c478bd9Sstevel@tonic-gate 			     || netspec || svcptr || idptr || comptr )
269*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
270*7c478bd9Sstevel@tonic-gate 			addrptr = optarg;
271*7c478bd9Sstevel@tonic-gate 			break;
272*7c478bd9Sstevel@tonic-gate 		case 'D':
273*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
274*7c478bd9Sstevel@tonic-gate 			     || netspec || svcptr || idptr || comptr || addrptr
275*7c478bd9Sstevel@tonic-gate 			     || lflags )
276*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
277*7c478bd9Sstevel@tonic-gate 			lflags |= DFLAG;
278*7c478bd9Sstevel@tonic-gate 			break;
279*7c478bd9Sstevel@tonic-gate 		case 'N':
280*7c478bd9Sstevel@tonic-gate 			if ( netspec )
281*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
282*7c478bd9Sstevel@tonic-gate 			netspec = optarg;
283*7c478bd9Sstevel@tonic-gate 			break;
284*7c478bd9Sstevel@tonic-gate 		case 'R':
285*7c478bd9Sstevel@tonic-gate 			if ( (flag && (flag != CMDFLAG) && (flag != PIPFLAG))
286*7c478bd9Sstevel@tonic-gate 			     || netspec || svcptr || idptr || comptr )
287*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
288*7c478bd9Sstevel@tonic-gate 			for (ptr = optarg; *ptr; ++ptr) {
289*7c478bd9Sstevel@tonic-gate 				if ((*ptr == ':') && !sawsep) {
290*7c478bd9Sstevel@tonic-gate 					/*
291*7c478bd9Sstevel@tonic-gate 					 * skip separator - note that if
292*7c478bd9Sstevel@tonic-gate 					 * separator has been seen, it's not
293*7c478bd9Sstevel@tonic-gate 					 * a digit so it will generate a usage
294*7c478bd9Sstevel@tonic-gate 					 * message below like we want
295*7c478bd9Sstevel@tonic-gate 					 */
296*7c478bd9Sstevel@tonic-gate 					sawsep++;
297*7c478bd9Sstevel@tonic-gate 					continue;
298*7c478bd9Sstevel@tonic-gate 				}
299*7c478bd9Sstevel@tonic-gate 				if (!isdigit(*ptr))
300*7c478bd9Sstevel@tonic-gate 					usage(USAGE);
301*7c478bd9Sstevel@tonic-gate 			}
302*7c478bd9Sstevel@tonic-gate 			ptr = strchr(optarg, ':');
303*7c478bd9Sstevel@tonic-gate 			if (ptr)
304*7c478bd9Sstevel@tonic-gate 				/* change the ':' to a ',' */
305*7c478bd9Sstevel@tonic-gate 				*ptr = ',';
306*7c478bd9Sstevel@tonic-gate 			else
307*7c478bd9Sstevel@tonic-gate 				usage(USAGE);
308*7c478bd9Sstevel@tonic-gate 			rpcptr = optarg;
309*7c478bd9Sstevel@tonic-gate 			break;
310*7c478bd9Sstevel@tonic-gate 		case 'V':
311*7c478bd9Sstevel@tonic-gate 			if ( flag || svcptr || Quietflag || comptr || netspec
312*7c478bd9Sstevel@tonic-gate 			     || rpcptr || addrptr || idptr || lflags )
313*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
314*7c478bd9Sstevel@tonic-gate 			flag |= VERFLAG;
315*7c478bd9Sstevel@tonic-gate 			break;
316*7c478bd9Sstevel@tonic-gate 		case '?':
317*7c478bd9Sstevel@tonic-gate 			usage(USAGE);
318*7c478bd9Sstevel@tonic-gate 		}
319*7c478bd9Sstevel@tonic-gate 	}
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 	if ((optind < argc) && ! netspec)
322*7c478bd9Sstevel@tonic-gate 		netspec = argv[optind++];
323*7c478bd9Sstevel@tonic-gate 	if (optind < argc)
324*7c478bd9Sstevel@tonic-gate 		usage(USAGE);
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	/* determine if this command requires a netspec */
328*7c478bd9Sstevel@tonic-gate 	if (flag != CMDFLAG) {
329*7c478bd9Sstevel@tonic-gate 		/* if flag is CMDFLAG, more complicated checking of netspec
330*7c478bd9Sstevel@tonic-gate 		 * is done below in switch
331*7c478bd9Sstevel@tonic-gate 		 */
332*7c478bd9Sstevel@tonic-gate 		if ((flag == PIPFLAG || flag == VERFLAG || flag == NETFLAG)) {
333*7c478bd9Sstevel@tonic-gate 			if (netspec)
334*7c478bd9Sstevel@tonic-gate 				usage(USAGE);
335*7c478bd9Sstevel@tonic-gate 		}
336*7c478bd9Sstevel@tonic-gate 		else if (!netspec)
337*7c478bd9Sstevel@tonic-gate 			usage(USAGE);
338*7c478bd9Sstevel@tonic-gate 	}
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (netspec && (flag != INIFLAG)) {
341*7c478bd9Sstevel@tonic-gate 		sprintf(buf, SAC_LSPM, netspec);
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 		if ((fp = popen(buf, "r")) == NULL) {
344*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_ERROR, "System error");
345*7c478bd9Sstevel@tonic-gate 			exit(NLS_SYSERR);
346*7c478bd9Sstevel@tonic-gate 		}
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 		if (fgets(buf, BUFSIZ, fp) == NULL) {
349*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_ERROR, "Invalid network specification");
350*7c478bd9Sstevel@tonic-gate 			exit(NLS_BADPM);
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 		else {
353*7c478bd9Sstevel@tonic-gate 			ptr = strchr(buf, ':');
354*7c478bd9Sstevel@tonic-gate 			ptr++;
355*7c478bd9Sstevel@tonic-gate 			ptr2 = strchr(ptr, ':');
356*7c478bd9Sstevel@tonic-gate 			*ptr2 = NULL;
357*7c478bd9Sstevel@tonic-gate 			if (strcmp(ptr, LISTENTYPE) != 0) {
358*7c478bd9Sstevel@tonic-gate 				sprintf(mesg, "Network specification \"%s\" is not of type %s", netspec, LISTENTYPE);
359*7c478bd9Sstevel@tonic-gate 				nlsmesg(MM_ERROR, mesg);
360*7c478bd9Sstevel@tonic-gate 				exit(NLS_BADPM);
361*7c478bd9Sstevel@tonic-gate 			}
362*7c478bd9Sstevel@tonic-gate 		}
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 		pclose(fp);
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 	if (svcptr) {
368*7c478bd9Sstevel@tonic-gate 		/* check to see if service code is "correct" -- right range
369*7c478bd9Sstevel@tonic-gate 		 * and format.  The -m flag is ignored, so no check for
370*7c478bd9Sstevel@tonic-gate 		 * "administrative" service codes (0-100) is done.
371*7c478bd9Sstevel@tonic-gate 		 */
372*7c478bd9Sstevel@tonic-gate 		c = strlen(svcptr);
373*7c478bd9Sstevel@tonic-gate 		if ((c == 0) || (c >= SVC_CODE_SZ)) {
374*7c478bd9Sstevel@tonic-gate 			sprintf(mesg, "Service code contains more than %d characters", SVC_CODE_SZ);
375*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_ERROR, mesg);
376*7c478bd9Sstevel@tonic-gate 			exit(NLS_SERV);
377*7c478bd9Sstevel@tonic-gate 		}
378*7c478bd9Sstevel@tonic-gate 	}
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 	switch (flag) {
381*7c478bd9Sstevel@tonic-gate 	default:
382*7c478bd9Sstevel@tonic-gate 		usage(USAGE);
383*7c478bd9Sstevel@tonic-gate 		break;
384*7c478bd9Sstevel@tonic-gate 	case NONE:
385*7c478bd9Sstevel@tonic-gate 		if ( svcptr || comptr || rpcptr || lflags || idptr )
386*7c478bd9Sstevel@tonic-gate 			usage(INCONSISTENT);
387*7c478bd9Sstevel@tonic-gate 		exitcode = prt_nets(netspec);
388*7c478bd9Sstevel@tonic-gate 		break;
389*7c478bd9Sstevel@tonic-gate 	case INIFLAG:
390*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
391*7c478bd9Sstevel@tonic-gate 			no_permission();
392*7c478bd9Sstevel@tonic-gate 		exitcode = add_pm(netspec);
393*7c478bd9Sstevel@tonic-gate 		break;
394*7c478bd9Sstevel@tonic-gate 	case CMDFLAG:
395*7c478bd9Sstevel@tonic-gate 		if ( svcptr || comptr || idptr || netspec ) {
396*7c478bd9Sstevel@tonic-gate 			if (geteuid() != ROOT)
397*7c478bd9Sstevel@tonic-gate 				no_permission();
398*7c478bd9Sstevel@tonic-gate 			if ((exitcode = old_addsvc(svcptr, "", cmdptr, comptr, moduleptr, idptr, NULL, netspec)) != NLS_OK)
399*7c478bd9Sstevel@tonic-gate 				switch (exitcode) {
400*7c478bd9Sstevel@tonic-gate 				case NLS_SERV:
401*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_ERROR, "Service code already exists");
402*7c478bd9Sstevel@tonic-gate 					break;
403*7c478bd9Sstevel@tonic-gate 				default:
404*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_ERROR, "Could not add service");
405*7c478bd9Sstevel@tonic-gate 					break;
406*7c478bd9Sstevel@tonic-gate 				}
407*7c478bd9Sstevel@tonic-gate 		}
408*7c478bd9Sstevel@tonic-gate 		else {
409*7c478bd9Sstevel@tonic-gate 			if (netspec)
410*7c478bd9Sstevel@tonic-gate 				usage(INCONSISTENT);
411*7c478bd9Sstevel@tonic-gate 			exitcode = prt_cmd(cmdptr, CFLAG | lflags, moduleptr, addrptr, rpcptr);
412*7c478bd9Sstevel@tonic-gate 		}
413*7c478bd9Sstevel@tonic-gate 		break;
414*7c478bd9Sstevel@tonic-gate 	case PIPFLAG:
415*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
416*7c478bd9Sstevel@tonic-gate 			no_permission();
417*7c478bd9Sstevel@tonic-gate 		exitcode = prt_cmd(pipeptr, PFLAG | lflags, moduleptr, addrptr, rpcptr);
418*7c478bd9Sstevel@tonic-gate 		break;
419*7c478bd9Sstevel@tonic-gate 	case VERFLAG:
420*7c478bd9Sstevel@tonic-gate 		printf("%d\n", VERSION);
421*7c478bd9Sstevel@tonic-gate 		exit(NLS_OK);
422*7c478bd9Sstevel@tonic-gate 		break;
423*7c478bd9Sstevel@tonic-gate 	case DISFLAG:
424*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
425*7c478bd9Sstevel@tonic-gate 			no_permission();
426*7c478bd9Sstevel@tonic-gate 		exitcode = disable_svc(svcptr, netspec);
427*7c478bd9Sstevel@tonic-gate 		break;
428*7c478bd9Sstevel@tonic-gate 	case ENAFLAG:
429*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
430*7c478bd9Sstevel@tonic-gate 			no_permission();
431*7c478bd9Sstevel@tonic-gate 		exitcode = enable_svc(svcptr, netspec);
432*7c478bd9Sstevel@tonic-gate 		break;
433*7c478bd9Sstevel@tonic-gate 	case KILFLAG:
434*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
435*7c478bd9Sstevel@tonic-gate 			no_permission();
436*7c478bd9Sstevel@tonic-gate 		exitcode = kill_listener(netspec);
437*7c478bd9Sstevel@tonic-gate 		break;
438*7c478bd9Sstevel@tonic-gate 	case ADRFLAG:
439*7c478bd9Sstevel@tonic-gate 		/* check for root permissions in setup_addr */
440*7c478bd9Sstevel@tonic-gate 		exitcode = setup_addr(lptr, tptr, netspec);
441*7c478bd9Sstevel@tonic-gate 		break;
442*7c478bd9Sstevel@tonic-gate 	case REMFLAG:
443*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
444*7c478bd9Sstevel@tonic-gate 			no_permission();
445*7c478bd9Sstevel@tonic-gate 		exitcode = remove_svc(svcptr, netspec, TRUE);
446*7c478bd9Sstevel@tonic-gate 		break;
447*7c478bd9Sstevel@tonic-gate 	case STAFLAG:
448*7c478bd9Sstevel@tonic-gate 		if (geteuid() != ROOT)
449*7c478bd9Sstevel@tonic-gate 			no_permission();
450*7c478bd9Sstevel@tonic-gate 		exitcode = start_listener(netspec);
451*7c478bd9Sstevel@tonic-gate 		break;
452*7c478bd9Sstevel@tonic-gate 	case VBSFLAG:
453*7c478bd9Sstevel@tonic-gate 		exitcode = prt_svcs(NULL, netspec);
454*7c478bd9Sstevel@tonic-gate 		break;
455*7c478bd9Sstevel@tonic-gate 	case NETFLAG:
456*7c478bd9Sstevel@tonic-gate 		exitcode = prt_nets(NULL);
457*7c478bd9Sstevel@tonic-gate 		break;
458*7c478bd9Sstevel@tonic-gate 	case ZZZFLAG:
459*7c478bd9Sstevel@tonic-gate 		exitcode = prt_svcs(svcptr, netspec);
460*7c478bd9Sstevel@tonic-gate 		break;
461*7c478bd9Sstevel@tonic-gate 	}
462*7c478bd9Sstevel@tonic-gate 	if (exitcode == NLS_SYSERR)
463*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "System error in SAC command");
464*7c478bd9Sstevel@tonic-gate 	exit(exitcode);
465*7c478bd9Sstevel@tonic-gate }
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate static char umsg[] = "usage: %s -x\n\
469*7c478bd9Sstevel@tonic-gate        %s [ options ] netspec\n\
470*7c478bd9Sstevel@tonic-gate        %s [ options ] -N port_monitor_tag\n\
471*7c478bd9Sstevel@tonic-gate        %s -V\n\
472*7c478bd9Sstevel@tonic-gate        %s -c cmd | -o pipename [ -p modules ] [ -A addr | -D ] \\\n\
473*7c478bd9Sstevel@tonic-gate           [ -R prognum:versnum ]\n\
474*7c478bd9Sstevel@tonic-gate \n\
475*7c478bd9Sstevel@tonic-gate        [ options ] are:\n\
476*7c478bd9Sstevel@tonic-gate        [ -a svc_code -c \"cmd\" -y \"cmt\" [-p modules] [-w id] ]\n\
477*7c478bd9Sstevel@tonic-gate        [-q] | [-v] | [-s] | [-k] | [-i] |\n\
478*7c478bd9Sstevel@tonic-gate        [-e svc_code] | [-d svc_code] | [-r svc_code] | [[-q] -z svc_code]\n\
479*7c478bd9Sstevel@tonic-gate        [[-l addr | -] [-t addr | -]] |\n\
480*7c478bd9Sstevel@tonic-gate ";
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate usage(flag)
483*7c478bd9Sstevel@tonic-gate int	flag;
484*7c478bd9Sstevel@tonic-gate {
485*7c478bd9Sstevel@tonic-gate 	switch (flag) {
486*7c478bd9Sstevel@tonic-gate 	case INCONSISTENT:
487*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Inconsistent options");
488*7c478bd9Sstevel@tonic-gate 		break;
489*7c478bd9Sstevel@tonic-gate 	case MISSINGARG:
490*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Missing argument");
491*7c478bd9Sstevel@tonic-gate 		break;
492*7c478bd9Sstevel@tonic-gate 	case USAGE:
493*7c478bd9Sstevel@tonic-gate 		break;
494*7c478bd9Sstevel@tonic-gate 	}
495*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, umsg, Nlsname, Nlsname, Nlsname, Nlsname, Nlsname);
496*7c478bd9Sstevel@tonic-gate 	exit(NLS_CMD);
497*7c478bd9Sstevel@tonic-gate }
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate 
500*7c478bd9Sstevel@tonic-gate /*
501*7c478bd9Sstevel@tonic-gate  * no_permission:  print out error message and exit when the user needs to
502*7c478bd9Sstevel@tonic-gate  *                 needs to be root and isn't.
503*7c478bd9Sstevel@tonic-gate  */
504*7c478bd9Sstevel@tonic-gate 
505*7c478bd9Sstevel@tonic-gate no_permission()
506*7c478bd9Sstevel@tonic-gate {
507*7c478bd9Sstevel@tonic-gate 	nlsmesg(MM_ERROR, "Must be super user");
508*7c478bd9Sstevel@tonic-gate 	exit(NLS_PERM);
509*7c478bd9Sstevel@tonic-gate }
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate /*
512*7c478bd9Sstevel@tonic-gate  * nlsmesg:  print out either an error or a warning message.  severity must
513*7c478bd9Sstevel@tonic-gate  *           be either MM_ERROR or MM_WARNING.  this routine will be converted
514*7c478bd9Sstevel@tonic-gate  *           to use the standard message format later.
515*7c478bd9Sstevel@tonic-gate  */
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate void
518*7c478bd9Sstevel@tonic-gate nlsmesg(severity, text)
519*7c478bd9Sstevel@tonic-gate int	severity;
520*7c478bd9Sstevel@tonic-gate char	*text;
521*7c478bd9Sstevel@tonic-gate {
522*7c478bd9Sstevel@tonic-gate 	int	class;
523*7c478bd9Sstevel@tonic-gate 
524*7c478bd9Sstevel@tonic-gate 	if (severity == MM_ERROR)
525*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s: error: %s\n", Nlsname, text);
526*7c478bd9Sstevel@tonic-gate 	else
527*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s: warning: %s\n", Nlsname, text);
528*7c478bd9Sstevel@tonic-gate 	return;
529*7c478bd9Sstevel@tonic-gate }
530*7c478bd9Sstevel@tonic-gate 
531*7c478bd9Sstevel@tonic-gate /*
532*7c478bd9Sstevel@tonic-gate  * prt_cmd:  print out the listener-dependent string for sacadm.
533*7c478bd9Sstevel@tonic-gate  */
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate prt_cmd(path, flags, modules, addr, rpcp)
536*7c478bd9Sstevel@tonic-gate char	*path;		/* full path of command or pipe */
537*7c478bd9Sstevel@tonic-gate long	flags;		/* listener flags		*/
538*7c478bd9Sstevel@tonic-gate 			/* PFLAG for pipe		*/
539*7c478bd9Sstevel@tonic-gate 			/* CFLAG for command		*/
540*7c478bd9Sstevel@tonic-gate 			/* DFLAG for dynamic addr	*/
541*7c478bd9Sstevel@tonic-gate char	*modules; 	/* STREAMS modules to push	*/
542*7c478bd9Sstevel@tonic-gate char	*addr;		/* private address		*/
543*7c478bd9Sstevel@tonic-gate char	*rpcp;		/* RPC prog and ver #		*/
544*7c478bd9Sstevel@tonic-gate {
545*7c478bd9Sstevel@tonic-gate 	struct	stat	sbuf;
546*7c478bd9Sstevel@tonic-gate 	char	mesgbuf[BUFSIZ];
547*7c478bd9Sstevel@tonic-gate 	char	*tmp;
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate 	if (*path != '/') {
550*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Must specify full path name");
551*7c478bd9Sstevel@tonic-gate 		return(NLS_CMD);
552*7c478bd9Sstevel@tonic-gate 	}
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 	if ((tmp = strchr(path, ' ')) != NULL)
555*7c478bd9Sstevel@tonic-gate 		*tmp = NULL;
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 	if (stat(path, &sbuf) < 0) {
558*7c478bd9Sstevel@tonic-gate 		if (errno != EFAULT) {
559*7c478bd9Sstevel@tonic-gate 			sprintf(mesgbuf, "%s does not exist", path);
560*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_WARNING, mesgbuf);
561*7c478bd9Sstevel@tonic-gate 		}
562*7c478bd9Sstevel@tonic-gate 		else
563*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
564*7c478bd9Sstevel@tonic-gate 	}
565*7c478bd9Sstevel@tonic-gate 
566*7c478bd9Sstevel@tonic-gate 	if (tmp)
567*7c478bd9Sstevel@tonic-gate 		*tmp = ' ';
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 	printf("%s:%s:%s:%s:%s\n", (addr ? addr : ""), (rpcp ? rpcp : ""),
570*7c478bd9Sstevel@tonic-gate 		pflags(flags), (modules ? modules : ""), path);
571*7c478bd9Sstevel@tonic-gate 	return(NLS_OK);
572*7c478bd9Sstevel@tonic-gate }
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate /*
575*7c478bd9Sstevel@tonic-gate  * old_addsvc:  use pmadm to add a service code to the listener.  this will
576*7c478bd9Sstevel@tonic-gate  *              not allow specification of a private address -- use pmadm!
577*7c478bd9Sstevel@tonic-gate  */
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate old_addsvc(svc, addr, cmd, com, module, id, flags, netspec)
580*7c478bd9Sstevel@tonic-gate char	*svc;
581*7c478bd9Sstevel@tonic-gate char	*addr;
582*7c478bd9Sstevel@tonic-gate char	*cmd;
583*7c478bd9Sstevel@tonic-gate char	*com;
584*7c478bd9Sstevel@tonic-gate char	*module;
585*7c478bd9Sstevel@tonic-gate char	*id;
586*7c478bd9Sstevel@tonic-gate char	*flags;
587*7c478bd9Sstevel@tonic-gate char	*netspec;
588*7c478bd9Sstevel@tonic-gate {
589*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
590*7c478bd9Sstevel@tonic-gate 	char	mesgbuf[BUFSIZ];
591*7c478bd9Sstevel@tonic-gate 	int	rtn;
592*7c478bd9Sstevel@tonic-gate 	struct	stat	sbuf;
593*7c478bd9Sstevel@tonic-gate 	char	*tmp;
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate 	if (!svc || !cmd || !com || !netspec)
596*7c478bd9Sstevel@tonic-gate 		usage(MISSINGARG);
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 	/* create "port-monitor specific" info in the same way as prt_cmd */
599*7c478bd9Sstevel@tonic-gate 
600*7c478bd9Sstevel@tonic-gate 	if (*cmd != '/') {
601*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Must specify full path name");
602*7c478bd9Sstevel@tonic-gate 		return(NLS_CMD);
603*7c478bd9Sstevel@tonic-gate 	}
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate 	if ((tmp = strchr(cmd, ' ')) != NULL)
606*7c478bd9Sstevel@tonic-gate 		*tmp = NULL;
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate 	if (stat(cmd, &sbuf) < 0) {
609*7c478bd9Sstevel@tonic-gate 		if (errno != EFAULT) {
610*7c478bd9Sstevel@tonic-gate 			sprintf(mesgbuf, "%s does not exist", cmd);
611*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_WARNING, mesgbuf);
612*7c478bd9Sstevel@tonic-gate 		}
613*7c478bd9Sstevel@tonic-gate 		else
614*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
615*7c478bd9Sstevel@tonic-gate 	}
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate 	if (tmp)
618*7c478bd9Sstevel@tonic-gate 		*tmp = ' ';
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate 	if (addr)
621*7c478bd9Sstevel@tonic-gate 		sprintf(mesgbuf, "'%s::c:%s:%s'", addr, module ? module : "" , cmd);
622*7c478bd9Sstevel@tonic-gate 	else
623*7c478bd9Sstevel@tonic-gate 		sprintf(mesgbuf, "'::c:%s:%s'", module ? module : "" , cmd);
624*7c478bd9Sstevel@tonic-gate 
625*7c478bd9Sstevel@tonic-gate 	if (flags && *flags)
626*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_ADDSVCF, netspec, svc, (id)?id:DEFAULTID, flags, mesgbuf, VERSION, com ? com : "");
627*7c478bd9Sstevel@tonic-gate 	else
628*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_ADDSVC, netspec, svc, (id)?id:DEFAULTID, mesgbuf, VERSION, com ? com : "");
629*7c478bd9Sstevel@tonic-gate 
630*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
631*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
632*7c478bd9Sstevel@tonic-gate 	}
633*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
634*7c478bd9Sstevel@tonic-gate 
635*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
636*7c478bd9Sstevel@tonic-gate 	case 0:
637*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
638*7c478bd9Sstevel@tonic-gate 		break;
639*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
640*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
641*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
642*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
643*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
644*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
645*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
646*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
647*7c478bd9Sstevel@tonic-gate 	default:
648*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
649*7c478bd9Sstevel@tonic-gate 		break;
650*7c478bd9Sstevel@tonic-gate 	case E_DUP:
651*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
652*7c478bd9Sstevel@tonic-gate 		break;
653*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
654*7c478bd9Sstevel@tonic-gate 		no_permission();
655*7c478bd9Sstevel@tonic-gate 		break;
656*7c478bd9Sstevel@tonic-gate 	}
657*7c478bd9Sstevel@tonic-gate }
658*7c478bd9Sstevel@tonic-gate 
659*7c478bd9Sstevel@tonic-gate /*
660*7c478bd9Sstevel@tonic-gate  * prt_nets:  print the status of one network, or all nets if netspec
661*7c478bd9Sstevel@tonic-gate  *            is NULL
662*7c478bd9Sstevel@tonic-gate  */
663*7c478bd9Sstevel@tonic-gate prt_nets(netspec)
664*7c478bd9Sstevel@tonic-gate char	*netspec;
665*7c478bd9Sstevel@tonic-gate {
666*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
667*7c478bd9Sstevel@tonic-gate 	FILE	*fp;
668*7c478bd9Sstevel@tonic-gate 	char	*name;
669*7c478bd9Sstevel@tonic-gate 	char	*state;
670*7c478bd9Sstevel@tonic-gate 	char	*type;
671*7c478bd9Sstevel@tonic-gate 	int	found = FALSE;
672*7c478bd9Sstevel@tonic-gate 	int	rtn = NLS_OK;
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate 	if (netspec == NULL)
675*7c478bd9Sstevel@tonic-gate 		sprintf(buf, SAC_LSTY, LISTENTYPE);
676*7c478bd9Sstevel@tonic-gate 	else
677*7c478bd9Sstevel@tonic-gate 		sprintf(buf, SAC_LSPM, netspec);
678*7c478bd9Sstevel@tonic-gate 
679*7c478bd9Sstevel@tonic-gate 	if ((fp = popen(buf, "r")) == NULL)
680*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
681*7c478bd9Sstevel@tonic-gate 
682*7c478bd9Sstevel@tonic-gate 	while (fgets(buf, BUFSIZ, fp) != NULL) {
683*7c478bd9Sstevel@tonic-gate 		if ((name = nexttok(buf, ":")) == NULL)
684*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
685*7c478bd9Sstevel@tonic-gate 		if ((type = nexttok(NULL, ":")) == NULL)
686*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
687*7c478bd9Sstevel@tonic-gate 
688*7c478bd9Sstevel@tonic-gate 		if (strcmp(type, LISTENTYPE) != 0)
689*7c478bd9Sstevel@tonic-gate 			continue;  /* ignore other types of port monitors */
690*7c478bd9Sstevel@tonic-gate 
691*7c478bd9Sstevel@tonic-gate 		found = TRUE;
692*7c478bd9Sstevel@tonic-gate 		if (nexttok(NULL, ":") == NULL)
693*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
694*7c478bd9Sstevel@tonic-gate 		if (nexttok(NULL, ":") == NULL)
695*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
696*7c478bd9Sstevel@tonic-gate 		if ((state = nexttok(NULL, ":")) == NULL)
697*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
698*7c478bd9Sstevel@tonic-gate 		if (strcmp(state, "ENABLED") == NULL ||
699*7c478bd9Sstevel@tonic-gate 		    strcmp(state, "STARTING") == NULL) {
700*7c478bd9Sstevel@tonic-gate 			rtn = QZERO;
701*7c478bd9Sstevel@tonic-gate 			if (!Quietflag)
702*7c478bd9Sstevel@tonic-gate 				printf("%s\t%s\n", name, "ACTIVE");
703*7c478bd9Sstevel@tonic-gate 		}
704*7c478bd9Sstevel@tonic-gate 		else {
705*7c478bd9Sstevel@tonic-gate 			rtn = QONE;
706*7c478bd9Sstevel@tonic-gate 			if (!Quietflag)
707*7c478bd9Sstevel@tonic-gate 				printf("%s\t%s\n", name, "INACTIVE");
708*7c478bd9Sstevel@tonic-gate 		}
709*7c478bd9Sstevel@tonic-gate 	}
710*7c478bd9Sstevel@tonic-gate 	pclose(fp);
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 	if (netspec && !found) {
713*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Invalid network specification");
714*7c478bd9Sstevel@tonic-gate 		return(NLS_BADPM);
715*7c478bd9Sstevel@tonic-gate 	}
716*7c478bd9Sstevel@tonic-gate 
717*7c478bd9Sstevel@tonic-gate 	if (netspec)
718*7c478bd9Sstevel@tonic-gate 		return(rtn);
719*7c478bd9Sstevel@tonic-gate 	else
720*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
721*7c478bd9Sstevel@tonic-gate 
722*7c478bd9Sstevel@tonic-gate }
723*7c478bd9Sstevel@tonic-gate 
724*7c478bd9Sstevel@tonic-gate 
725*7c478bd9Sstevel@tonic-gate /*
726*7c478bd9Sstevel@tonic-gate  * print info about service on netspec, or all services on netspec
727*7c478bd9Sstevel@tonic-gate  * if svc is NULL
728*7c478bd9Sstevel@tonic-gate  */
729*7c478bd9Sstevel@tonic-gate 
730*7c478bd9Sstevel@tonic-gate prt_svcs(svc, netspec)
731*7c478bd9Sstevel@tonic-gate char	*svc;
732*7c478bd9Sstevel@tonic-gate char	*netspec;
733*7c478bd9Sstevel@tonic-gate {
734*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
735*7c478bd9Sstevel@tonic-gate 	char	mesg[BUFSIZ];
736*7c478bd9Sstevel@tonic-gate 	FILE	*fp;
737*7c478bd9Sstevel@tonic-gate 	struct	svcfields entry;
738*7c478bd9Sstevel@tonic-gate 	int	rtn;
739*7c478bd9Sstevel@tonic-gate 	int	found = FALSE;
740*7c478bd9Sstevel@tonic-gate 	char	*p;
741*7c478bd9Sstevel@tonic-gate 
742*7c478bd9Sstevel@tonic-gate 	if (svc == NULL)
743*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_LSALL, netspec);
744*7c478bd9Sstevel@tonic-gate 	else
745*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_LSONE, netspec, svc);
746*7c478bd9Sstevel@tonic-gate 
747*7c478bd9Sstevel@tonic-gate 	if ((fp = popen(buf, "r")) == NULL)
748*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
749*7c478bd9Sstevel@tonic-gate 
750*7c478bd9Sstevel@tonic-gate 	while (fgets(buf, BUFSIZ, fp) != NULL) {
751*7c478bd9Sstevel@tonic-gate 		if ((rtn = svc_format(buf, &entry)) != 0) {
752*7c478bd9Sstevel@tonic-gate 			switch (rtn) {
753*7c478bd9Sstevel@tonic-gate 			case NOTLISTEN:
754*7c478bd9Sstevel@tonic-gate 				continue;
755*7c478bd9Sstevel@tonic-gate 				break;
756*7c478bd9Sstevel@tonic-gate 			case BADPMFMT:
757*7c478bd9Sstevel@tonic-gate 				return(NLS_SYSERR);
758*7c478bd9Sstevel@tonic-gate 				break;
759*7c478bd9Sstevel@tonic-gate 			case BADLISFMT:
760*7c478bd9Sstevel@tonic-gate 				sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
761*7c478bd9Sstevel@tonic-gate 				nlsmesg(MM_WARNING, mesg);
762*7c478bd9Sstevel@tonic-gate 				continue;
763*7c478bd9Sstevel@tonic-gate 				break;
764*7c478bd9Sstevel@tonic-gate 			}
765*7c478bd9Sstevel@tonic-gate 		}
766*7c478bd9Sstevel@tonic-gate 		found = TRUE;
767*7c478bd9Sstevel@tonic-gate 
768*7c478bd9Sstevel@tonic-gate 		if (!Quietflag) {
769*7c478bd9Sstevel@tonic-gate 			printf("%s\t", entry.svc_code);
770*7c478bd9Sstevel@tonic-gate 			if (*entry.addr)
771*7c478bd9Sstevel@tonic-gate 				printf("%s\t", entry.addr);
772*7c478bd9Sstevel@tonic-gate 			else if (strchr(entry.lflags, 'd'))
773*7c478bd9Sstevel@tonic-gate 				printf("DYNAMIC\t");
774*7c478bd9Sstevel@tonic-gate 			else
775*7c478bd9Sstevel@tonic-gate 				printf("NOADDR\t");
776*7c478bd9Sstevel@tonic-gate 
777*7c478bd9Sstevel@tonic-gate 			if (strchr(entry.flags, 'x') == NULL)
778*7c478bd9Sstevel@tonic-gate 				printf("ENABLED \t");
779*7c478bd9Sstevel@tonic-gate 			else
780*7c478bd9Sstevel@tonic-gate 				printf("DISABLED\t");
781*7c478bd9Sstevel@tonic-gate 
782*7c478bd9Sstevel@tonic-gate 
783*7c478bd9Sstevel@tonic-gate 			printf("%s\t%s\t%s\t%s\t# %s",
784*7c478bd9Sstevel@tonic-gate 				(*entry.rpc)?entry.rpc:"NORPC", entry.id,
785*7c478bd9Sstevel@tonic-gate 				(*entry.modules)?entry.modules:"NOMODULES",
786*7c478bd9Sstevel@tonic-gate 				entry.command, (*entry.comment)?entry.comment:"");
787*7c478bd9Sstevel@tonic-gate 		}
788*7c478bd9Sstevel@tonic-gate 		else {
789*7c478bd9Sstevel@tonic-gate 			if (strchr(entry.flags, 'x') == NULL)
790*7c478bd9Sstevel@tonic-gate 				return(QZERO);
791*7c478bd9Sstevel@tonic-gate 			else
792*7c478bd9Sstevel@tonic-gate 				return(QONE);
793*7c478bd9Sstevel@tonic-gate 		}
794*7c478bd9Sstevel@tonic-gate 	}
795*7c478bd9Sstevel@tonic-gate 
796*7c478bd9Sstevel@tonic-gate 	pclose(fp);
797*7c478bd9Sstevel@tonic-gate 
798*7c478bd9Sstevel@tonic-gate 	if (rtn == NOTLISTEN) { /* check last return to see if error */
799*7c478bd9Sstevel@tonic-gate 		sprintf(mesg, "Network specification \"%s\" is not of type %s", netspec, LISTENTYPE);
800*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, mesg);
801*7c478bd9Sstevel@tonic-gate 		return(NLS_BADPM);
802*7c478bd9Sstevel@tonic-gate 	}
803*7c478bd9Sstevel@tonic-gate 	if (svc && !found) {
804*7c478bd9Sstevel@tonic-gate 		if (!Quietflag) {
805*7c478bd9Sstevel@tonic-gate 			sprintf(mesg, "Service \"%s\" unknown", svc);
806*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_ERROR, mesg);
807*7c478bd9Sstevel@tonic-gate 		}
808*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
809*7c478bd9Sstevel@tonic-gate 	}
810*7c478bd9Sstevel@tonic-gate 
811*7c478bd9Sstevel@tonic-gate 	return(NLS_OK);
812*7c478bd9Sstevel@tonic-gate }
813*7c478bd9Sstevel@tonic-gate 
814*7c478bd9Sstevel@tonic-gate /*
815*7c478bd9Sstevel@tonic-gate  * disable_svc:  use pmadm to disable a service
816*7c478bd9Sstevel@tonic-gate  */
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate disable_svc(svc, netspec)
819*7c478bd9Sstevel@tonic-gate char	*svc;
820*7c478bd9Sstevel@tonic-gate char	*netspec;
821*7c478bd9Sstevel@tonic-gate {
822*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
823*7c478bd9Sstevel@tonic-gate 	int	rtn;
824*7c478bd9Sstevel@tonic-gate 
825*7c478bd9Sstevel@tonic-gate 	sprintf(buf, PM_DISABLE, netspec, svc);
826*7c478bd9Sstevel@tonic-gate 
827*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
828*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
829*7c478bd9Sstevel@tonic-gate 	}
830*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
833*7c478bd9Sstevel@tonic-gate 	case 0:
834*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
835*7c478bd9Sstevel@tonic-gate 		break;
836*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
837*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
838*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
839*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
840*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
841*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
842*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
843*7c478bd9Sstevel@tonic-gate 	default:
844*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
845*7c478bd9Sstevel@tonic-gate 		break;
846*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
847*7c478bd9Sstevel@tonic-gate 	case E_DUP:
848*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Non-existent service.");
849*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
850*7c478bd9Sstevel@tonic-gate 		break;
851*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
852*7c478bd9Sstevel@tonic-gate 		no_permission();
853*7c478bd9Sstevel@tonic-gate 		break;
854*7c478bd9Sstevel@tonic-gate 	}
855*7c478bd9Sstevel@tonic-gate }
856*7c478bd9Sstevel@tonic-gate 
857*7c478bd9Sstevel@tonic-gate 
858*7c478bd9Sstevel@tonic-gate enable_svc(svc, netspec)
859*7c478bd9Sstevel@tonic-gate char	*svc;
860*7c478bd9Sstevel@tonic-gate char	*netspec;
861*7c478bd9Sstevel@tonic-gate {
862*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
863*7c478bd9Sstevel@tonic-gate 	int	rtn;
864*7c478bd9Sstevel@tonic-gate 
865*7c478bd9Sstevel@tonic-gate 	sprintf(buf, PM_ENABLE, netspec, svc);
866*7c478bd9Sstevel@tonic-gate 
867*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
868*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
869*7c478bd9Sstevel@tonic-gate 	}
870*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
871*7c478bd9Sstevel@tonic-gate 
872*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
873*7c478bd9Sstevel@tonic-gate 	case 0:
874*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
875*7c478bd9Sstevel@tonic-gate 		break;
876*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
877*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
878*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
879*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
880*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
881*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
882*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
883*7c478bd9Sstevel@tonic-gate 	default:
884*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
885*7c478bd9Sstevel@tonic-gate 		break;
886*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
887*7c478bd9Sstevel@tonic-gate 	case E_DUP:
888*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Non-existent service.");
889*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
890*7c478bd9Sstevel@tonic-gate 		break;
891*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
892*7c478bd9Sstevel@tonic-gate 		no_permission();
893*7c478bd9Sstevel@tonic-gate 		break;
894*7c478bd9Sstevel@tonic-gate 	}
895*7c478bd9Sstevel@tonic-gate }
896*7c478bd9Sstevel@tonic-gate 
897*7c478bd9Sstevel@tonic-gate 
898*7c478bd9Sstevel@tonic-gate remove_svc(svc, netspec, printerrors)
899*7c478bd9Sstevel@tonic-gate char	*svc;
900*7c478bd9Sstevel@tonic-gate char	*netspec;
901*7c478bd9Sstevel@tonic-gate int	printerrors;
902*7c478bd9Sstevel@tonic-gate {
903*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
904*7c478bd9Sstevel@tonic-gate 	int	rtn;
905*7c478bd9Sstevel@tonic-gate 
906*7c478bd9Sstevel@tonic-gate 	sprintf(buf, PM_REMSVC, netspec, svc);
907*7c478bd9Sstevel@tonic-gate 
908*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
909*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
910*7c478bd9Sstevel@tonic-gate 	}
911*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
912*7c478bd9Sstevel@tonic-gate 
913*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
914*7c478bd9Sstevel@tonic-gate 	case 0:
915*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
916*7c478bd9Sstevel@tonic-gate 		break;
917*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
918*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
919*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
920*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
921*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
922*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
923*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
924*7c478bd9Sstevel@tonic-gate 	default:
925*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
926*7c478bd9Sstevel@tonic-gate 		break;
927*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
928*7c478bd9Sstevel@tonic-gate 	case E_DUP:
929*7c478bd9Sstevel@tonic-gate 		if (printerrors)
930*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_ERROR, "Non-existent service.");
931*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
932*7c478bd9Sstevel@tonic-gate 		break;
933*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
934*7c478bd9Sstevel@tonic-gate 		no_permission();
935*7c478bd9Sstevel@tonic-gate 		break;
936*7c478bd9Sstevel@tonic-gate 	}
937*7c478bd9Sstevel@tonic-gate }
938*7c478bd9Sstevel@tonic-gate 
939*7c478bd9Sstevel@tonic-gate 
940*7c478bd9Sstevel@tonic-gate kill_listener(netspec)
941*7c478bd9Sstevel@tonic-gate char	*netspec;
942*7c478bd9Sstevel@tonic-gate {
943*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
944*7c478bd9Sstevel@tonic-gate 	char	mesg[BUFSIZ];
945*7c478bd9Sstevel@tonic-gate 	int	rtn;
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate 	sprintf(buf, SAC_KILLPM, netspec);
948*7c478bd9Sstevel@tonic-gate 
949*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
950*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
951*7c478bd9Sstevel@tonic-gate 	}
952*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
953*7c478bd9Sstevel@tonic-gate 
954*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
955*7c478bd9Sstevel@tonic-gate 	case 0:
956*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
957*7c478bd9Sstevel@tonic-gate 		break;
958*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
959*7c478bd9Sstevel@tonic-gate 	case E_DUP:
960*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
961*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
962*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
963*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
964*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
965*7c478bd9Sstevel@tonic-gate 	default:
966*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
967*7c478bd9Sstevel@tonic-gate 		break;
968*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
969*7c478bd9Sstevel@tonic-gate 		sprintf(mesg, "No listener active on network \"%s\"", netspec);
970*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, mesg);
971*7c478bd9Sstevel@tonic-gate 		return(NLS_FAILED);
972*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
973*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Non-existent port monitor.");
974*7c478bd9Sstevel@tonic-gate 		return(NLS_SERV);
975*7c478bd9Sstevel@tonic-gate 		break;
976*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
977*7c478bd9Sstevel@tonic-gate 		no_permission();
978*7c478bd9Sstevel@tonic-gate 		break;
979*7c478bd9Sstevel@tonic-gate 	}
980*7c478bd9Sstevel@tonic-gate }
981*7c478bd9Sstevel@tonic-gate 
982*7c478bd9Sstevel@tonic-gate 
983*7c478bd9Sstevel@tonic-gate /*
984*7c478bd9Sstevel@tonic-gate  * add_pm:  add a port monitor (initialize directories) using sacadm
985*7c478bd9Sstevel@tonic-gate  */
986*7c478bd9Sstevel@tonic-gate 
987*7c478bd9Sstevel@tonic-gate add_pm(netspec)
988*7c478bd9Sstevel@tonic-gate char	*netspec;
989*7c478bd9Sstevel@tonic-gate {
990*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
991*7c478bd9Sstevel@tonic-gate 	char	mesg[BUFSIZ];
992*7c478bd9Sstevel@tonic-gate 	int	rtn;
993*7c478bd9Sstevel@tonic-gate 
994*7c478bd9Sstevel@tonic-gate 	sprintf(buf, SAC_ADDPM, netspec, LISTENTYPE, gencmdstr(netspec), VERSION);
995*7c478bd9Sstevel@tonic-gate 
996*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
997*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
998*7c478bd9Sstevel@tonic-gate 	}
999*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;	/* get child return value out of exit word */
1000*7c478bd9Sstevel@tonic-gate 
1001*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
1002*7c478bd9Sstevel@tonic-gate 	case 0:
1003*7c478bd9Sstevel@tonic-gate 		old_addsvc(NLPSSVCCODE, NULL, NLPSSRV, "NLPS server", "", "root", NULL, netspec);
1004*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
1005*7c478bd9Sstevel@tonic-gate 		break;
1006*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
1007*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
1008*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
1009*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
1010*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
1011*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
1012*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
1013*7c478bd9Sstevel@tonic-gate 	default:
1014*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
1015*7c478bd9Sstevel@tonic-gate 		break;
1016*7c478bd9Sstevel@tonic-gate 	case E_DUP:
1017*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
1018*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Listener already initialized");
1019*7c478bd9Sstevel@tonic-gate 		return(NLS_FAILED);
1020*7c478bd9Sstevel@tonic-gate 		break;
1021*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
1022*7c478bd9Sstevel@tonic-gate 		no_permission();
1023*7c478bd9Sstevel@tonic-gate 		break;
1024*7c478bd9Sstevel@tonic-gate 	}
1025*7c478bd9Sstevel@tonic-gate }
1026*7c478bd9Sstevel@tonic-gate 
1027*7c478bd9Sstevel@tonic-gate 
1028*7c478bd9Sstevel@tonic-gate /*
1029*7c478bd9Sstevel@tonic-gate  * gencmdstr:  generate the correct string to invoke the listener (starlan
1030*7c478bd9Sstevel@tonic-gate  *             requires special handling)
1031*7c478bd9Sstevel@tonic-gate  */
1032*7c478bd9Sstevel@tonic-gate 
1033*7c478bd9Sstevel@tonic-gate char *
1034*7c478bd9Sstevel@tonic-gate gencmdstr(netspec)
1035*7c478bd9Sstevel@tonic-gate char *netspec;
1036*7c478bd9Sstevel@tonic-gate {
1037*7c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];
1038*7c478bd9Sstevel@tonic-gate 
1039*7c478bd9Sstevel@tonic-gate 	(void) strcpy(buf, LISTENCMD);
1040*7c478bd9Sstevel@tonic-gate 	if (!strcmp(netspec, "starlan"))
1041*7c478bd9Sstevel@tonic-gate 		(void) strcat(buf, " -m slan");
1042*7c478bd9Sstevel@tonic-gate 	(void) strcat(buf, " ");
1043*7c478bd9Sstevel@tonic-gate 	(void) strcat(buf, netspec);
1044*7c478bd9Sstevel@tonic-gate 	return(buf);
1045*7c478bd9Sstevel@tonic-gate }
1046*7c478bd9Sstevel@tonic-gate 
1047*7c478bd9Sstevel@tonic-gate 
1048*7c478bd9Sstevel@tonic-gate /*
1049*7c478bd9Sstevel@tonic-gate  * start_listener: start the listener
1050*7c478bd9Sstevel@tonic-gate  */
1051*7c478bd9Sstevel@tonic-gate 
1052*7c478bd9Sstevel@tonic-gate start_listener(netspec)
1053*7c478bd9Sstevel@tonic-gate char	*netspec;
1054*7c478bd9Sstevel@tonic-gate {
1055*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
1056*7c478bd9Sstevel@tonic-gate 	char	scratch[BUFSIZ];
1057*7c478bd9Sstevel@tonic-gate 	int	rtn;
1058*7c478bd9Sstevel@tonic-gate 
1059*7c478bd9Sstevel@tonic-gate 	sprintf(buf, SAC_STARTPM, netspec);
1060*7c478bd9Sstevel@tonic-gate 
1061*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0)
1062*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
1063*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;
1064*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
1065*7c478bd9Sstevel@tonic-gate 	case 0:
1066*7c478bd9Sstevel@tonic-gate 		break;
1067*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
1068*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
1069*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
1070*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
1071*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
1072*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
1073*7c478bd9Sstevel@tonic-gate 	default:
1074*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
1075*7c478bd9Sstevel@tonic-gate 		break;
1076*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
1077*7c478bd9Sstevel@tonic-gate 	case E_DUP:
1078*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Non-existent port monitor.");
1079*7c478bd9Sstevel@tonic-gate 		return(NLS_BADPM);
1080*7c478bd9Sstevel@tonic-gate 		break;
1081*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
1082*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Listener already running");
1083*7c478bd9Sstevel@tonic-gate 		return(NLS_FAILED);
1084*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
1085*7c478bd9Sstevel@tonic-gate 		no_permission();
1086*7c478bd9Sstevel@tonic-gate 		break;
1087*7c478bd9Sstevel@tonic-gate 	}
1088*7c478bd9Sstevel@tonic-gate 
1089*7c478bd9Sstevel@tonic-gate 	sprintf(buf, SAC_ENABLPM, netspec);
1090*7c478bd9Sstevel@tonic-gate 
1091*7c478bd9Sstevel@tonic-gate 	if ((rtn = system(buf)) < 0) {
1092*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
1093*7c478bd9Sstevel@tonic-gate 	}
1094*7c478bd9Sstevel@tonic-gate 	rtn = (rtn>>8) & 0xff;
1095*7c478bd9Sstevel@tonic-gate 	switch (rtn) {
1096*7c478bd9Sstevel@tonic-gate 	case 0:
1097*7c478bd9Sstevel@tonic-gate 		return(NLS_OK);
1098*7c478bd9Sstevel@tonic-gate 		break;
1099*7c478bd9Sstevel@tonic-gate 	case E_BADARGS:
1100*7c478bd9Sstevel@tonic-gate 	case E_SAFERR:
1101*7c478bd9Sstevel@tonic-gate 	case E_SYSERR:
1102*7c478bd9Sstevel@tonic-gate 	case E_RECOVER:
1103*7c478bd9Sstevel@tonic-gate 	case E_SACNOTRUN:
1104*7c478bd9Sstevel@tonic-gate 	default:
1105*7c478bd9Sstevel@tonic-gate 		return(NLS_SYSERR);
1106*7c478bd9Sstevel@tonic-gate 		break;
1107*7c478bd9Sstevel@tonic-gate 	case E_NOEXIST:
1108*7c478bd9Sstevel@tonic-gate 	case E_DUP:
1109*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Non-existent port monitor.");
1110*7c478bd9Sstevel@tonic-gate 		return(NLS_BADPM);
1111*7c478bd9Sstevel@tonic-gate 		break;
1112*7c478bd9Sstevel@tonic-gate 	case E_PMRUN:
1113*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Listener already running");
1114*7c478bd9Sstevel@tonic-gate 		return(NLS_FAILED);
1115*7c478bd9Sstevel@tonic-gate 	case E_PMNOTRUN:
1116*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Listener start failed");
1117*7c478bd9Sstevel@tonic-gate 		return(NLS_FAILED);
1118*7c478bd9Sstevel@tonic-gate 	case E_NOPRIV:
1119*7c478bd9Sstevel@tonic-gate 		no_permission();
1120*7c478bd9Sstevel@tonic-gate 		break;
1121*7c478bd9Sstevel@tonic-gate 	}
1122*7c478bd9Sstevel@tonic-gate }
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate 
1125*7c478bd9Sstevel@tonic-gate /*
1126*7c478bd9Sstevel@tonic-gate  * setup_addr:  setup the -l and -t addresses.
1127*7c478bd9Sstevel@tonic-gate  */
1128*7c478bd9Sstevel@tonic-gate 
1129*7c478bd9Sstevel@tonic-gate setup_addr(laddr, taddr, netspec)
1130*7c478bd9Sstevel@tonic-gate char	*laddr;
1131*7c478bd9Sstevel@tonic-gate char	*taddr;
1132*7c478bd9Sstevel@tonic-gate char	*netspec;
1133*7c478bd9Sstevel@tonic-gate {
1134*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
1135*7c478bd9Sstevel@tonic-gate 	char	mesg[BUFSIZ];
1136*7c478bd9Sstevel@tonic-gate 	char	*p;
1137*7c478bd9Sstevel@tonic-gate 	int	rtn;
1138*7c478bd9Sstevel@tonic-gate 	int	qlisten = FALSE;
1139*7c478bd9Sstevel@tonic-gate 	int	qtty = FALSE;
1140*7c478bd9Sstevel@tonic-gate 	FILE	*fp;
1141*7c478bd9Sstevel@tonic-gate 	struct	svcfields entry;
1142*7c478bd9Sstevel@tonic-gate 
1143*7c478bd9Sstevel@tonic-gate 	if (laddr && *laddr == '-')
1144*7c478bd9Sstevel@tonic-gate 		qlisten = TRUE;
1145*7c478bd9Sstevel@tonic-gate 
1146*7c478bd9Sstevel@tonic-gate 	if (taddr && *taddr == '-')
1147*7c478bd9Sstevel@tonic-gate 		qtty = TRUE;
1148*7c478bd9Sstevel@tonic-gate 
1149*7c478bd9Sstevel@tonic-gate 	if (laddr) {
1150*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_LSONE, netspec, NLPSSVCCODE);
1151*7c478bd9Sstevel@tonic-gate 
1152*7c478bd9Sstevel@tonic-gate 		if ((fp = popen(buf, "r")) == NULL) {
1153*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
1154*7c478bd9Sstevel@tonic-gate 		}
1155*7c478bd9Sstevel@tonic-gate 
1156*7c478bd9Sstevel@tonic-gate 		if (fgets(buf, BUFSIZ, fp) != NULL) {
1157*7c478bd9Sstevel@tonic-gate 			if ((rtn = svc_format(buf, &entry)) != 0) {
1158*7c478bd9Sstevel@tonic-gate 				switch (rtn) {
1159*7c478bd9Sstevel@tonic-gate 				case NOTLISTEN:
1160*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_ERROR, "Incorrect port monitor type.  Must be of type listen");
1161*7c478bd9Sstevel@tonic-gate 					return(NLS_FAILED);
1162*7c478bd9Sstevel@tonic-gate 					break;
1163*7c478bd9Sstevel@tonic-gate 				case BADPMFMT:
1164*7c478bd9Sstevel@tonic-gate 					return(NLS_SYSERR);
1165*7c478bd9Sstevel@tonic-gate 					break;
1166*7c478bd9Sstevel@tonic-gate 				case BADLISFMT:
1167*7c478bd9Sstevel@tonic-gate 					sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
1168*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_WARNING, mesg);
1169*7c478bd9Sstevel@tonic-gate 					break;
1170*7c478bd9Sstevel@tonic-gate 				}
1171*7c478bd9Sstevel@tonic-gate 			}
1172*7c478bd9Sstevel@tonic-gate 			else {
1173*7c478bd9Sstevel@tonic-gate 				if (qlisten)
1174*7c478bd9Sstevel@tonic-gate 					printf("%s\n", entry.addr);
1175*7c478bd9Sstevel@tonic-gate 				else {
1176*7c478bd9Sstevel@tonic-gate 					if (geteuid() != ROOT)
1177*7c478bd9Sstevel@tonic-gate 						no_permission();
1178*7c478bd9Sstevel@tonic-gate 					/* add address */
1179*7c478bd9Sstevel@tonic-gate 					remove_svc(NLPSSVCCODE, netspec, FALSE);
1180*7c478bd9Sstevel@tonic-gate 					p = strchr(entry.comment, '\n');
1181*7c478bd9Sstevel@tonic-gate 					if (p)
1182*7c478bd9Sstevel@tonic-gate 						*p = '\0';
1183*7c478bd9Sstevel@tonic-gate 					old_addsvc(NLPSSVCCODE, laddr, entry.command, entry.comment, entry.modules, entry.id, entry.flags, netspec);
1184*7c478bd9Sstevel@tonic-gate 				}
1185*7c478bd9Sstevel@tonic-gate 			}
1186*7c478bd9Sstevel@tonic-gate 			pclose(fp);
1187*7c478bd9Sstevel@tonic-gate 		}
1188*7c478bd9Sstevel@tonic-gate 		else if (!qlisten)
1189*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_WARNING, "NLPS service not defined");
1190*7c478bd9Sstevel@tonic-gate 	}
1191*7c478bd9Sstevel@tonic-gate 	if (taddr) {
1192*7c478bd9Sstevel@tonic-gate 		sprintf(buf, PM_LSONE, netspec, TTYSVCCODE);
1193*7c478bd9Sstevel@tonic-gate 
1194*7c478bd9Sstevel@tonic-gate 		if ((fp = popen(buf, "r")) == NULL) {
1195*7c478bd9Sstevel@tonic-gate 			return(NLS_SYSERR);
1196*7c478bd9Sstevel@tonic-gate 		}
1197*7c478bd9Sstevel@tonic-gate 
1198*7c478bd9Sstevel@tonic-gate 		if (fgets(buf, BUFSIZ, fp) != NULL) {
1199*7c478bd9Sstevel@tonic-gate 			if ((rtn = svc_format(buf, &entry)) != 0) {
1200*7c478bd9Sstevel@tonic-gate 				switch (rtn) {
1201*7c478bd9Sstevel@tonic-gate 				case NOTLISTEN:
1202*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_ERROR, "Incorrect port monitor type.  Must be of type listen");
1203*7c478bd9Sstevel@tonic-gate 					return(NLS_FAILED);
1204*7c478bd9Sstevel@tonic-gate 					break;
1205*7c478bd9Sstevel@tonic-gate 				case BADPMFMT:
1206*7c478bd9Sstevel@tonic-gate 					return(NLS_SYSERR);
1207*7c478bd9Sstevel@tonic-gate 					break;
1208*7c478bd9Sstevel@tonic-gate 				case BADLISFMT:
1209*7c478bd9Sstevel@tonic-gate 					sprintf(mesg, "Entry for code \"%s\" has incorrect format", entry.svc_code);
1210*7c478bd9Sstevel@tonic-gate 					nlsmesg(MM_WARNING, mesg);
1211*7c478bd9Sstevel@tonic-gate 					break;
1212*7c478bd9Sstevel@tonic-gate 				}
1213*7c478bd9Sstevel@tonic-gate 			}
1214*7c478bd9Sstevel@tonic-gate 			else {
1215*7c478bd9Sstevel@tonic-gate 				if (qtty)
1216*7c478bd9Sstevel@tonic-gate 					printf("%s\n", entry.addr);
1217*7c478bd9Sstevel@tonic-gate 				else {
1218*7c478bd9Sstevel@tonic-gate 					if (geteuid() != ROOT)
1219*7c478bd9Sstevel@tonic-gate 						no_permission();
1220*7c478bd9Sstevel@tonic-gate 					/* add address */
1221*7c478bd9Sstevel@tonic-gate 					remove_svc(TTYSVCCODE, netspec, FALSE);
1222*7c478bd9Sstevel@tonic-gate 					p = strchr(entry.comment, '\n');
1223*7c478bd9Sstevel@tonic-gate 					if (p)
1224*7c478bd9Sstevel@tonic-gate 						*p = '\0';
1225*7c478bd9Sstevel@tonic-gate 					old_addsvc(TTYSVCCODE, taddr, entry.command, entry.comment, entry.modules, entry.id, entry.flags, netspec);
1226*7c478bd9Sstevel@tonic-gate 				}
1227*7c478bd9Sstevel@tonic-gate 			}
1228*7c478bd9Sstevel@tonic-gate 			pclose(fp);
1229*7c478bd9Sstevel@tonic-gate 		}
1230*7c478bd9Sstevel@tonic-gate 		else if (!qtty)
1231*7c478bd9Sstevel@tonic-gate 			nlsmesg(MM_WARNING, "remote login service not defined");
1232*7c478bd9Sstevel@tonic-gate 	}
1233*7c478bd9Sstevel@tonic-gate 	return(NLS_OK);
1234*7c478bd9Sstevel@tonic-gate }
1235*7c478bd9Sstevel@tonic-gate 
1236*7c478bd9Sstevel@tonic-gate 
1237*7c478bd9Sstevel@tonic-gate /*
1238*7c478bd9Sstevel@tonic-gate  * svc_format:  scan a line of output from pmadm to separate it into fields.
1239*7c478bd9Sstevel@tonic-gate  *              returns BADPMFMT for missing fields or incorrect syntax.
1240*7c478bd9Sstevel@tonic-gate  *                      NOTLISTEN is the port monitor type is not listen.
1241*7c478bd9Sstevel@tonic-gate  *                      BADLISFMT if the listener-specific data is incorrect.
1242*7c478bd9Sstevel@tonic-gate  *                      NLS_OK if everything checked out and data is broken
1243*7c478bd9Sstevel@tonic-gate  *                             into the structure.
1244*7c478bd9Sstevel@tonic-gate  */
1245*7c478bd9Sstevel@tonic-gate 
1246*7c478bd9Sstevel@tonic-gate svc_format(buf, entry)
1247*7c478bd9Sstevel@tonic-gate char	*buf;
1248*7c478bd9Sstevel@tonic-gate struct	svcfields *entry;
1249*7c478bd9Sstevel@tonic-gate {
1250*7c478bd9Sstevel@tonic-gate 	char	*ptr;		/* temporary pointer into buffer	*/
1251*7c478bd9Sstevel@tonic-gate 	char	*tmp;		/* temporary pointer into buffer	*/
1252*7c478bd9Sstevel@tonic-gate 
1253*7c478bd9Sstevel@tonic-gate 	entry->pmtag = buf;
1254*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(buf, ':')) == NULL)
1255*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1256*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1257*7c478bd9Sstevel@tonic-gate 	entry->pmtype = ptr;
1258*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->pmtype, ':')) == NULL)
1259*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1260*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1261*7c478bd9Sstevel@tonic-gate 	entry->svc_code = ptr;
1262*7c478bd9Sstevel@tonic-gate 
1263*7c478bd9Sstevel@tonic-gate 	if (strcmp(entry->pmtype, LISTENTYPE) != 0)
1264*7c478bd9Sstevel@tonic-gate 		return(NOTLISTEN);
1265*7c478bd9Sstevel@tonic-gate 
1266*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->svc_code, ':')) == NULL)
1267*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1268*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1269*7c478bd9Sstevel@tonic-gate 	entry->flags = ptr;
1270*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->flags, ':')) == NULL)
1271*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1272*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1273*7c478bd9Sstevel@tonic-gate 	entry->id = ptr;
1274*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->id, ':')) == NULL)
1275*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1276*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1277*7c478bd9Sstevel@tonic-gate 	entry->res1 = ptr;
1278*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->res1, ':')) == NULL)
1279*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1280*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1281*7c478bd9Sstevel@tonic-gate 	entry->res2 = ptr;
1282*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->res2, ':')) == NULL)
1283*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1284*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1285*7c478bd9Sstevel@tonic-gate 	entry->res3 = ptr;
1286*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->res3, ':')) == NULL)
1287*7c478bd9Sstevel@tonic-gate 		return(BADPMFMT);
1288*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1289*7c478bd9Sstevel@tonic-gate 	entry->addr = ptr;
1290*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->addr, ':')) == NULL)
1291*7c478bd9Sstevel@tonic-gate 		return(BADLISFMT);
1292*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1293*7c478bd9Sstevel@tonic-gate 	entry->rpc = ptr;
1294*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->rpc, ':')) == NULL)
1295*7c478bd9Sstevel@tonic-gate 		return(BADLISFMT);
1296*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1297*7c478bd9Sstevel@tonic-gate 	if (*entry->rpc) {
1298*7c478bd9Sstevel@tonic-gate 		if ((tmp = strchr(entry->rpc, ',')) == NULL)
1299*7c478bd9Sstevel@tonic-gate 			return(BADLISFMT);
1300*7c478bd9Sstevel@tonic-gate 		*tmp = ':';
1301*7c478bd9Sstevel@tonic-gate 	}
1302*7c478bd9Sstevel@tonic-gate 	entry->lflags = ptr;
1303*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->lflags, ':')) == NULL)
1304*7c478bd9Sstevel@tonic-gate 		return(BADLISFMT);
1305*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1306*7c478bd9Sstevel@tonic-gate 	entry->modules = ptr;
1307*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->modules, ':')) == NULL)
1308*7c478bd9Sstevel@tonic-gate 		return(BADLISFMT);
1309*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1310*7c478bd9Sstevel@tonic-gate 	entry->command = ptr;
1311*7c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(entry->command, '#')) == NULL)
1312*7c478bd9Sstevel@tonic-gate 		return(BADLISFMT);
1313*7c478bd9Sstevel@tonic-gate 	*ptr++ = NULL;
1314*7c478bd9Sstevel@tonic-gate 	entry->comment = ptr;
1315*7c478bd9Sstevel@tonic-gate 	return(NLS_OK);
1316*7c478bd9Sstevel@tonic-gate }
1317*7c478bd9Sstevel@tonic-gate 
1318*7c478bd9Sstevel@tonic-gate 
1319*7c478bd9Sstevel@tonic-gate /*
1320*7c478bd9Sstevel@tonic-gate  * nexttok - return next token, essentially a strtok, but it can
1321*7c478bd9Sstevel@tonic-gate  *	deal with null fields and strtok can not
1322*7c478bd9Sstevel@tonic-gate  *
1323*7c478bd9Sstevel@tonic-gate  *	args:	str - the string to be examined, NULL if we should
1324*7c478bd9Sstevel@tonic-gate  *		      examine the remembered string
1325*7c478bd9Sstevel@tonic-gate  *		delim - the list of valid delimiters
1326*7c478bd9Sstevel@tonic-gate  */
1327*7c478bd9Sstevel@tonic-gate 
1328*7c478bd9Sstevel@tonic-gate 
1329*7c478bd9Sstevel@tonic-gate char *
1330*7c478bd9Sstevel@tonic-gate nexttok(str, delim)
1331*7c478bd9Sstevel@tonic-gate char *str;
1332*7c478bd9Sstevel@tonic-gate register char *delim;
1333*7c478bd9Sstevel@tonic-gate {
1334*7c478bd9Sstevel@tonic-gate 	static char *savep;	/* the remembered string */
1335*7c478bd9Sstevel@tonic-gate 	register char *p;	/* pointer to start of token */
1336*7c478bd9Sstevel@tonic-gate 	register char *ep;	/* pointer to end of token */
1337*7c478bd9Sstevel@tonic-gate 
1338*7c478bd9Sstevel@tonic-gate 	p = (str == NULL) ? savep : str ;
1339*7c478bd9Sstevel@tonic-gate 	if (p == NULL)
1340*7c478bd9Sstevel@tonic-gate 		return(NULL);
1341*7c478bd9Sstevel@tonic-gate 	ep = strpbrk(p, delim);
1342*7c478bd9Sstevel@tonic-gate 	if (ep == NULL) {
1343*7c478bd9Sstevel@tonic-gate 		savep = NULL;
1344*7c478bd9Sstevel@tonic-gate 		return(p);
1345*7c478bd9Sstevel@tonic-gate 	}
1346*7c478bd9Sstevel@tonic-gate 	savep = ep + 1;
1347*7c478bd9Sstevel@tonic-gate 	*ep = '\0';
1348*7c478bd9Sstevel@tonic-gate 	return(p);
1349*7c478bd9Sstevel@tonic-gate }
1350*7c478bd9Sstevel@tonic-gate 
1351*7c478bd9Sstevel@tonic-gate 
1352*7c478bd9Sstevel@tonic-gate /*
1353*7c478bd9Sstevel@tonic-gate  * pflags - put flags into intelligible form for output
1354*7c478bd9Sstevel@tonic-gate  *
1355*7c478bd9Sstevel@tonic-gate  *	args:	flags - binary representation of flags
1356*7c478bd9Sstevel@tonic-gate  */
1357*7c478bd9Sstevel@tonic-gate 
1358*7c478bd9Sstevel@tonic-gate char *
1359*7c478bd9Sstevel@tonic-gate pflags(flags)
1360*7c478bd9Sstevel@tonic-gate long flags;
1361*7c478bd9Sstevel@tonic-gate {
1362*7c478bd9Sstevel@tonic-gate 	register int i;			/* scratch counter */
1363*7c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];	/* formatted flags */
1364*7c478bd9Sstevel@tonic-gate 
1365*7c478bd9Sstevel@tonic-gate 	if (flags == 0)
1366*7c478bd9Sstevel@tonic-gate 		return("");
1367*7c478bd9Sstevel@tonic-gate 	i = 0;
1368*7c478bd9Sstevel@tonic-gate 	if (flags & CFLAG) {
1369*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'c';
1370*7c478bd9Sstevel@tonic-gate 		flags &= ~CFLAG;
1371*7c478bd9Sstevel@tonic-gate 	}
1372*7c478bd9Sstevel@tonic-gate 	if (flags & DFLAG) {
1373*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'd';
1374*7c478bd9Sstevel@tonic-gate 		flags &= ~DFLAG;
1375*7c478bd9Sstevel@tonic-gate 	}
1376*7c478bd9Sstevel@tonic-gate 	if (flags & PFLAG) {
1377*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'p';
1378*7c478bd9Sstevel@tonic-gate 		flags &= ~PFLAG;
1379*7c478bd9Sstevel@tonic-gate 	}
1380*7c478bd9Sstevel@tonic-gate 	if (flags) {
1381*7c478bd9Sstevel@tonic-gate 		nlsmesg(MM_ERROR, "Internal error in pflags");
1382*7c478bd9Sstevel@tonic-gate 		exit(NLS_FAILED);
1383*7c478bd9Sstevel@tonic-gate 	}
1384*7c478bd9Sstevel@tonic-gate 	buf[i] = '\0';
1385*7c478bd9Sstevel@tonic-gate 	return(buf);
1386*7c478bd9Sstevel@tonic-gate }
1387