xref: /titanic_51/usr/src/cmd/ttymon/tmpmtab.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 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
34*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
35*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
36*7c478bd9Sstevel@tonic-gate #include	<ctype.h>
37*7c478bd9Sstevel@tonic-gate #include	<string.h>
38*7c478bd9Sstevel@tonic-gate #include 	<pwd.h>
39*7c478bd9Sstevel@tonic-gate #include 	<grp.h>
40*7c478bd9Sstevel@tonic-gate #include	<signal.h>
41*7c478bd9Sstevel@tonic-gate #include	"ttymon.h"
42*7c478bd9Sstevel@tonic-gate #include	"tmstruct.h"
43*7c478bd9Sstevel@tonic-gate #include	"tmextern.h"
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate extern	char	*strsave();
46*7c478bd9Sstevel@tonic-gate extern	void	set_softcar();
47*7c478bd9Sstevel@tonic-gate extern	int	vml();
48*7c478bd9Sstevel@tonic-gate void	purge();
49*7c478bd9Sstevel@tonic-gate static	int	get_flags();
50*7c478bd9Sstevel@tonic-gate static	int	get_ttyflags();
51*7c478bd9Sstevel@tonic-gate static	int	same_entry();
52*7c478bd9Sstevel@tonic-gate static	int	check_pmtab();
53*7c478bd9Sstevel@tonic-gate static	void	insert_pmtab();
54*7c478bd9Sstevel@tonic-gate static	void	free_pmtab();
55*7c478bd9Sstevel@tonic-gate static	char	*expand();
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate int	check_identity();
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate int	strcheck();
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate  * read_pmtab()
63*7c478bd9Sstevel@tonic-gate  *	- read and parse pmtab
64*7c478bd9Sstevel@tonic-gate  *	- store table in linked list pointed by global variable "PMtab"
65*7c478bd9Sstevel@tonic-gate  *	- exit if file does not exist or error detected.
66*7c478bd9Sstevel@tonic-gate  */
67*7c478bd9Sstevel@tonic-gate void
68*7c478bd9Sstevel@tonic-gate read_pmtab()
69*7c478bd9Sstevel@tonic-gate {
70*7c478bd9Sstevel@tonic-gate 	register struct pmtab *gptr;
71*7c478bd9Sstevel@tonic-gate 	register char *ptr, *wptr;
72*7c478bd9Sstevel@tonic-gate 	FILE 	 *fp;
73*7c478bd9Sstevel@tonic-gate 	int 	 input, state, size, rawc, field, linenum;
74*7c478bd9Sstevel@tonic-gate 	char 	 oldc;
75*7c478bd9Sstevel@tonic-gate 	char 	 line[BUFSIZ];
76*7c478bd9Sstevel@tonic-gate 	char 	 wbuf[BUFSIZ];
77*7c478bd9Sstevel@tonic-gate 	static 	 char *states[] = {
78*7c478bd9Sstevel@tonic-gate 	      "","tag","flags","identity","reserved1","reserved2","reserved3",
79*7c478bd9Sstevel@tonic-gate 	      "device","ttyflags","count","service", "timeout","ttylabel",
80*7c478bd9Sstevel@tonic-gate 	      "modules","prompt","disable msg","terminal type","soft-carrier"
81*7c478bd9Sstevel@tonic-gate 	};
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
84*7c478bd9Sstevel@tonic-gate 	debug("in read_pmtab");
85*7c478bd9Sstevel@tonic-gate # endif
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate 	if ((fp = fopen(PMTABFILE,"r")) == NULL) {
88*7c478bd9Sstevel@tonic-gate 		fatal("open pmtab (%s) failed", PMTABFILE);
89*7c478bd9Sstevel@tonic-gate 	}
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	Nentries = 0;
92*7c478bd9Sstevel@tonic-gate 	if (check_version(PMTAB_VERS, PMTABFILE) != 0)
93*7c478bd9Sstevel@tonic-gate 		fatal("check pmtab version failed");
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate 	for (gptr = PMtab; gptr; gptr = gptr->p_next) {
96*7c478bd9Sstevel@tonic-gate 		if ((gptr->p_status == SESSION) ||
97*7c478bd9Sstevel@tonic-gate 		    (gptr->p_status == LOCKED) ||
98*7c478bd9Sstevel@tonic-gate 		    (gptr->p_status == UNACCESS)) {
99*7c478bd9Sstevel@tonic-gate 			if (gptr->p_fd > 0) {
100*7c478bd9Sstevel@tonic-gate 				(void)close(gptr->p_fd);
101*7c478bd9Sstevel@tonic-gate 				gptr->p_fd = 0;
102*7c478bd9Sstevel@tonic-gate 			}
103*7c478bd9Sstevel@tonic-gate 			gptr->p_inservice = gptr->p_status;
104*7c478bd9Sstevel@tonic-gate 		}
105*7c478bd9Sstevel@tonic-gate 		gptr->p_status = NOTVALID;
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	wptr = wbuf;
109*7c478bd9Sstevel@tonic-gate 	input = ACTIVE;
110*7c478bd9Sstevel@tonic-gate 	linenum = 0;
111*7c478bd9Sstevel@tonic-gate 	do {
112*7c478bd9Sstevel@tonic-gate 		linenum++;
113*7c478bd9Sstevel@tonic-gate 		line[0] = '\0';
114*7c478bd9Sstevel@tonic-gate 		for (ptr= line,oldc = '\0'; ptr < &line[sizeof(line)-1] &&
115*7c478bd9Sstevel@tonic-gate 		 (rawc=getc(fp))!= '\n' && rawc != EOF; ptr++,oldc=(char)rawc){
116*7c478bd9Sstevel@tonic-gate 			if ((rawc == '#') && (oldc != '\\'))
117*7c478bd9Sstevel@tonic-gate 				break;
118*7c478bd9Sstevel@tonic-gate 			*ptr = (char)rawc;
119*7c478bd9Sstevel@tonic-gate 		}
120*7c478bd9Sstevel@tonic-gate 		*ptr = '\0';
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 		/* skip rest of the line */
123*7c478bd9Sstevel@tonic-gate 		if (rawc != EOF && rawc != '\n') {
124*7c478bd9Sstevel@tonic-gate 			if (rawc != '#')
125*7c478bd9Sstevel@tonic-gate 				log("Entry too long.\n");
126*7c478bd9Sstevel@tonic-gate 			while ((rawc = getc(fp)) != EOF && rawc != '\n')
127*7c478bd9Sstevel@tonic-gate 				;
128*7c478bd9Sstevel@tonic-gate 		}
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		if (rawc == EOF) {
131*7c478bd9Sstevel@tonic-gate 			if (ptr == line) break;
132*7c478bd9Sstevel@tonic-gate 			else input = FINISHED;
133*7c478bd9Sstevel@tonic-gate 		}
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 		/* if empty line, skip */
136*7c478bd9Sstevel@tonic-gate 		for (ptr=line; *ptr != '\0' && isspace(*ptr); ptr++)
137*7c478bd9Sstevel@tonic-gate 			;
138*7c478bd9Sstevel@tonic-gate 		if (*ptr == '\0') continue;
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
141*7c478bd9Sstevel@tonic-gate 		debug("**** Next Entry ****\n%s", line);
142*7c478bd9Sstevel@tonic-gate #endif
143*7c478bd9Sstevel@tonic-gate 		log("Processing pmtab line #%d", linenum);
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 		/* Now we have the complete line */
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 		if ((gptr = ALLOC_PMTAB) == PNULL)
148*7c478bd9Sstevel@tonic-gate 			fatal("memory allocation failed");
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 		/* set hangup flag, this is the default */
151*7c478bd9Sstevel@tonic-gate 		gptr->p_ttyflags |= H_FLAG;
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 		/*
154*7c478bd9Sstevel@tonic-gate 		 * For compatibility reasons, we cannot rely on these
155*7c478bd9Sstevel@tonic-gate 		 * having values assigned from pmtab.
156*7c478bd9Sstevel@tonic-gate 		 */
157*7c478bd9Sstevel@tonic-gate 		gptr->p_termtype = "";
158*7c478bd9Sstevel@tonic-gate 		gptr->p_softcar = "";
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 		for (state=P_TAG,ptr=line;state !=FAILURE && state !=SUCCESS;) {
161*7c478bd9Sstevel@tonic-gate 			switch(state) {
162*7c478bd9Sstevel@tonic-gate 			case P_TAG:
163*7c478bd9Sstevel@tonic-gate 				gptr->p_tag = strsave(getword(ptr,&size,0));
164*7c478bd9Sstevel@tonic-gate 				break;
165*7c478bd9Sstevel@tonic-gate 			case P_FLAGS:
166*7c478bd9Sstevel@tonic-gate 				(void)strcpy(wptr, getword(ptr,&size,0));
167*7c478bd9Sstevel@tonic-gate 				if ((get_flags(wptr, &gptr->p_flags)) != 0) {
168*7c478bd9Sstevel@tonic-gate 					field = state;
169*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
170*7c478bd9Sstevel@tonic-gate 				}
171*7c478bd9Sstevel@tonic-gate 				break;
172*7c478bd9Sstevel@tonic-gate 			case P_IDENTITY:
173*7c478bd9Sstevel@tonic-gate 				gptr->p_identity=strsave(getword(ptr,&size,0));
174*7c478bd9Sstevel@tonic-gate 				break;
175*7c478bd9Sstevel@tonic-gate 			case P_RES1:
176*7c478bd9Sstevel@tonic-gate 				gptr->p_res1=strsave(getword(ptr,&size,0));
177*7c478bd9Sstevel@tonic-gate 				break;
178*7c478bd9Sstevel@tonic-gate 			case P_RES2:
179*7c478bd9Sstevel@tonic-gate 				gptr->p_res2=strsave(getword(ptr,&size,0));
180*7c478bd9Sstevel@tonic-gate 				break;
181*7c478bd9Sstevel@tonic-gate 			case P_RES3:
182*7c478bd9Sstevel@tonic-gate 				gptr->p_res3=strsave(getword(ptr,&size,0));
183*7c478bd9Sstevel@tonic-gate 				break;
184*7c478bd9Sstevel@tonic-gate 			case P_DEVICE:
185*7c478bd9Sstevel@tonic-gate 				gptr->p_device = strsave(getword(ptr,&size,0));
186*7c478bd9Sstevel@tonic-gate 				break;
187*7c478bd9Sstevel@tonic-gate 			case P_TTYFLAGS:
188*7c478bd9Sstevel@tonic-gate 				(void)strcpy(wptr, getword(ptr,&size,0));
189*7c478bd9Sstevel@tonic-gate 				if ((get_ttyflags(wptr,&gptr->p_ttyflags))!=0) {
190*7c478bd9Sstevel@tonic-gate 					field = state;
191*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
192*7c478bd9Sstevel@tonic-gate 				}
193*7c478bd9Sstevel@tonic-gate 				break;
194*7c478bd9Sstevel@tonic-gate 			case P_COUNT:
195*7c478bd9Sstevel@tonic-gate 				(void)strcpy(wptr, getword(ptr,&size,0));
196*7c478bd9Sstevel@tonic-gate 				if (strcheck(wptr, NUM) != 0) {
197*7c478bd9Sstevel@tonic-gate 					log("wait_read count must be a positive number");
198*7c478bd9Sstevel@tonic-gate 					field = state;
199*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
200*7c478bd9Sstevel@tonic-gate 				}
201*7c478bd9Sstevel@tonic-gate 				else
202*7c478bd9Sstevel@tonic-gate 				    gptr->p_count = atoi(wptr);
203*7c478bd9Sstevel@tonic-gate 				break;
204*7c478bd9Sstevel@tonic-gate 			case P_SERVER:
205*7c478bd9Sstevel@tonic-gate 				gptr->p_server =
206*7c478bd9Sstevel@tonic-gate 				strsave(expand(getword(ptr,&size,1),
207*7c478bd9Sstevel@tonic-gate 					gptr->p_device));
208*7c478bd9Sstevel@tonic-gate 				break;
209*7c478bd9Sstevel@tonic-gate 			case P_TIMEOUT:
210*7c478bd9Sstevel@tonic-gate 				(void)strcpy(wptr, getword(ptr,&size,0));
211*7c478bd9Sstevel@tonic-gate 				if (strcheck(wptr, NUM) != 0) {
212*7c478bd9Sstevel@tonic-gate 					log("timeout value must be a positive number");
213*7c478bd9Sstevel@tonic-gate 					field = state;
214*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
215*7c478bd9Sstevel@tonic-gate 				}
216*7c478bd9Sstevel@tonic-gate 				else
217*7c478bd9Sstevel@tonic-gate 				    gptr->p_timeout = atoi(wptr);
218*7c478bd9Sstevel@tonic-gate 				break;
219*7c478bd9Sstevel@tonic-gate 			case P_TTYLABEL:
220*7c478bd9Sstevel@tonic-gate 				gptr->p_ttylabel=strsave(getword(ptr,&size,0));
221*7c478bd9Sstevel@tonic-gate 				break;
222*7c478bd9Sstevel@tonic-gate 			case P_MODULES:
223*7c478bd9Sstevel@tonic-gate 				gptr->p_modules = strsave(getword(ptr,&size,0));
224*7c478bd9Sstevel@tonic-gate 				if (vml(gptr->p_modules) != 0) {
225*7c478bd9Sstevel@tonic-gate 					field = state;
226*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
227*7c478bd9Sstevel@tonic-gate 				}
228*7c478bd9Sstevel@tonic-gate 				break;
229*7c478bd9Sstevel@tonic-gate 			case P_PROMPT:
230*7c478bd9Sstevel@tonic-gate 				gptr->p_prompt = strsave(getword(ptr,&size,TRUE));
231*7c478bd9Sstevel@tonic-gate 				break;
232*7c478bd9Sstevel@tonic-gate 			case P_DMSG:
233*7c478bd9Sstevel@tonic-gate 				gptr->p_dmsg = strsave(getword(ptr,&size,TRUE));
234*7c478bd9Sstevel@tonic-gate 				break;
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 			case P_TERMTYPE:
237*7c478bd9Sstevel@tonic-gate 				gptr->p_termtype = strsave(getword(ptr,&size,TRUE));
238*7c478bd9Sstevel@tonic-gate 				break;
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 			case P_SOFTCAR:
241*7c478bd9Sstevel@tonic-gate 				gptr->p_softcar = strsave(getword(ptr,&size,TRUE));
242*7c478bd9Sstevel@tonic-gate 				break;
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 			} /* end switch */
245*7c478bd9Sstevel@tonic-gate 			ptr += size;
246*7c478bd9Sstevel@tonic-gate 			if (state == FAILURE)
247*7c478bd9Sstevel@tonic-gate 				break;
248*7c478bd9Sstevel@tonic-gate 			if (*ptr == ':') {
249*7c478bd9Sstevel@tonic-gate 				ptr++;	/* Skip the ':' */
250*7c478bd9Sstevel@tonic-gate 				state++ ;
251*7c478bd9Sstevel@tonic-gate 			} else if (*ptr != '\0') {
252*7c478bd9Sstevel@tonic-gate 				field = state;
253*7c478bd9Sstevel@tonic-gate 				state = FAILURE;
254*7c478bd9Sstevel@tonic-gate 			}
255*7c478bd9Sstevel@tonic-gate 			if (*ptr == '\0') {
256*7c478bd9Sstevel@tonic-gate 				/*
257*7c478bd9Sstevel@tonic-gate 				 * Maintain compatibility with older ttymon
258*7c478bd9Sstevel@tonic-gate 				 * pmtab files.  If Sun-added fields are
259*7c478bd9Sstevel@tonic-gate 				 * missing, this should not be an error.
260*7c478bd9Sstevel@tonic-gate 				 */
261*7c478bd9Sstevel@tonic-gate 				if (state > P_DMSG) {
262*7c478bd9Sstevel@tonic-gate 					state = SUCCESS;
263*7c478bd9Sstevel@tonic-gate 				} else {
264*7c478bd9Sstevel@tonic-gate 					field = state;
265*7c478bd9Sstevel@tonic-gate 					state = FAILURE;
266*7c478bd9Sstevel@tonic-gate 				}
267*7c478bd9Sstevel@tonic-gate 			}
268*7c478bd9Sstevel@tonic-gate 		} /* end for loop */
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		if (state == SUCCESS) {
271*7c478bd9Sstevel@tonic-gate 			if (check_pmtab(gptr) == 0) {
272*7c478bd9Sstevel@tonic-gate 				if (Nentries < Maxfds)
273*7c478bd9Sstevel@tonic-gate 					insert_pmtab(gptr);
274*7c478bd9Sstevel@tonic-gate 				else {
275*7c478bd9Sstevel@tonic-gate 					log("can't add more entries to "
276*7c478bd9Sstevel@tonic-gate 					    "pmtab, Maxfds = %d", Maxfds);
277*7c478bd9Sstevel@tonic-gate 					free_pmtab(gptr);
278*7c478bd9Sstevel@tonic-gate 					(void)fclose(fp);
279*7c478bd9Sstevel@tonic-gate 					return;
280*7c478bd9Sstevel@tonic-gate 				}
281*7c478bd9Sstevel@tonic-gate 			}
282*7c478bd9Sstevel@tonic-gate 			else {
283*7c478bd9Sstevel@tonic-gate 				log("Parsing failure for entry: \n%s", line);
284*7c478bd9Sstevel@tonic-gate 			log("-------------------------------------------");
285*7c478bd9Sstevel@tonic-gate 				free_pmtab(gptr);
286*7c478bd9Sstevel@tonic-gate 			}
287*7c478bd9Sstevel@tonic-gate 		} else {
288*7c478bd9Sstevel@tonic-gate 			*++ptr = '\0';
289*7c478bd9Sstevel@tonic-gate 			log("Parsing failure in the \"%s\" field,\n%s"
290*7c478bd9Sstevel@tonic-gate 			    "<--error detected here", states[field], line);
291*7c478bd9Sstevel@tonic-gate 			log("-------------------------------------------");
292*7c478bd9Sstevel@tonic-gate 			free_pmtab(gptr);
293*7c478bd9Sstevel@tonic-gate 		}
294*7c478bd9Sstevel@tonic-gate 	} while (input == ACTIVE);
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	(void)fclose(fp);
297*7c478bd9Sstevel@tonic-gate 	return;
298*7c478bd9Sstevel@tonic-gate }
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate /*
301*7c478bd9Sstevel@tonic-gate  * get_flags	- scan flags field to set U_FLAG and X_FLAG
302*7c478bd9Sstevel@tonic-gate  */
303*7c478bd9Sstevel@tonic-gate static	int
304*7c478bd9Sstevel@tonic-gate get_flags(wptr, flags)
305*7c478bd9Sstevel@tonic-gate char	*wptr;		/* pointer to the input string	*/
306*7c478bd9Sstevel@tonic-gate long *flags;		/* pointer to the flag to set	*/
307*7c478bd9Sstevel@tonic-gate {
308*7c478bd9Sstevel@tonic-gate 	register char	*p;
309*7c478bd9Sstevel@tonic-gate 	for (p = wptr; *p; p++) {
310*7c478bd9Sstevel@tonic-gate 		switch (*p) {
311*7c478bd9Sstevel@tonic-gate 		case 'x':
312*7c478bd9Sstevel@tonic-gate 			*flags |= X_FLAG;
313*7c478bd9Sstevel@tonic-gate 			break;
314*7c478bd9Sstevel@tonic-gate 		case 'u':
315*7c478bd9Sstevel@tonic-gate 			*flags |= U_FLAG;
316*7c478bd9Sstevel@tonic-gate 			break;
317*7c478bd9Sstevel@tonic-gate 		default:
318*7c478bd9Sstevel@tonic-gate 			log("Invalid flag -- %c", *p);
319*7c478bd9Sstevel@tonic-gate 			return(-1);
320*7c478bd9Sstevel@tonic-gate 		}
321*7c478bd9Sstevel@tonic-gate 	}
322*7c478bd9Sstevel@tonic-gate 	return(0);
323*7c478bd9Sstevel@tonic-gate }
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate /*
326*7c478bd9Sstevel@tonic-gate  * get_ttyflags	- scan ttyflags field to set corresponding flags
327*7c478bd9Sstevel@tonic-gate  */
328*7c478bd9Sstevel@tonic-gate static	int
329*7c478bd9Sstevel@tonic-gate get_ttyflags(wptr, ttyflags)
330*7c478bd9Sstevel@tonic-gate char	*wptr;		/* pointer to the input string	*/
331*7c478bd9Sstevel@tonic-gate long 	*ttyflags;	/* pointer to the flag to be set*/
332*7c478bd9Sstevel@tonic-gate {
333*7c478bd9Sstevel@tonic-gate 	register char	*p;
334*7c478bd9Sstevel@tonic-gate 	for (p = wptr; *p; p++) {
335*7c478bd9Sstevel@tonic-gate 		switch (*p) {
336*7c478bd9Sstevel@tonic-gate 		case 'c':
337*7c478bd9Sstevel@tonic-gate 			*ttyflags |= C_FLAG;
338*7c478bd9Sstevel@tonic-gate 			break;
339*7c478bd9Sstevel@tonic-gate 		case 'h': /* h means don't hangup */
340*7c478bd9Sstevel@tonic-gate 			*ttyflags &= ~H_FLAG;
341*7c478bd9Sstevel@tonic-gate 			break;
342*7c478bd9Sstevel@tonic-gate 		case 'b':
343*7c478bd9Sstevel@tonic-gate 			*ttyflags |= B_FLAG;
344*7c478bd9Sstevel@tonic-gate 			break;
345*7c478bd9Sstevel@tonic-gate 		case 'r':
346*7c478bd9Sstevel@tonic-gate 			*ttyflags |= R_FLAG;
347*7c478bd9Sstevel@tonic-gate 			break;
348*7c478bd9Sstevel@tonic-gate 		case 'I':
349*7c478bd9Sstevel@tonic-gate 			*ttyflags |= I_FLAG;
350*7c478bd9Sstevel@tonic-gate 			break;
351*7c478bd9Sstevel@tonic-gate 		default:
352*7c478bd9Sstevel@tonic-gate 			log("Invalid ttyflag -- %c", *p);
353*7c478bd9Sstevel@tonic-gate 			return(-1);
354*7c478bd9Sstevel@tonic-gate 		}
355*7c478bd9Sstevel@tonic-gate 	}
356*7c478bd9Sstevel@tonic-gate 	return(0);
357*7c478bd9Sstevel@tonic-gate }
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
360*7c478bd9Sstevel@tonic-gate /*
361*7c478bd9Sstevel@tonic-gate  * pflags - put service flags into intelligible form for output
362*7c478bd9Sstevel@tonic-gate  */
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate char *
365*7c478bd9Sstevel@tonic-gate pflags(flags)
366*7c478bd9Sstevel@tonic-gate long flags;	/* binary representation of the flags */
367*7c478bd9Sstevel@tonic-gate {
368*7c478bd9Sstevel@tonic-gate 	register int i;			/* scratch counter */
369*7c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];	/* formatted flags */
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	if (flags == 0)
372*7c478bd9Sstevel@tonic-gate 		return("-");
373*7c478bd9Sstevel@tonic-gate 	i = 0;
374*7c478bd9Sstevel@tonic-gate 	if (flags & U_FLAG) {
375*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'u';
376*7c478bd9Sstevel@tonic-gate 		flags &= ~U_FLAG;
377*7c478bd9Sstevel@tonic-gate 	}
378*7c478bd9Sstevel@tonic-gate 	if (flags & X_FLAG) {
379*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'x';
380*7c478bd9Sstevel@tonic-gate 		flags &= ~X_FLAG;
381*7c478bd9Sstevel@tonic-gate 	}
382*7c478bd9Sstevel@tonic-gate 	if (flags)
383*7c478bd9Sstevel@tonic-gate 		log("Internal error in pflags");
384*7c478bd9Sstevel@tonic-gate 	buf[i] = '\0';
385*7c478bd9Sstevel@tonic-gate 	return(buf);
386*7c478bd9Sstevel@tonic-gate }
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate /*
389*7c478bd9Sstevel@tonic-gate  * pttyflags - put ttyflags into intelligible form for output
390*7c478bd9Sstevel@tonic-gate  */
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate char *
393*7c478bd9Sstevel@tonic-gate pttyflags(flags)
394*7c478bd9Sstevel@tonic-gate long flags;	/* binary representation of ttyflags */
395*7c478bd9Sstevel@tonic-gate {
396*7c478bd9Sstevel@tonic-gate 	register int i;			/* scratch counter */
397*7c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];	/* formatted flags */
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 	if (flags == 0)
400*7c478bd9Sstevel@tonic-gate 		return("h");
401*7c478bd9Sstevel@tonic-gate 	i = 0;
402*7c478bd9Sstevel@tonic-gate 	if (flags & C_FLAG) {
403*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'c';
404*7c478bd9Sstevel@tonic-gate 		flags &= ~C_FLAG;
405*7c478bd9Sstevel@tonic-gate 	}
406*7c478bd9Sstevel@tonic-gate 	if (flags & H_FLAG)
407*7c478bd9Sstevel@tonic-gate 		flags &= ~H_FLAG;
408*7c478bd9Sstevel@tonic-gate 	else
409*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'h';
410*7c478bd9Sstevel@tonic-gate 	if (flags & B_FLAG) {
411*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'b';
412*7c478bd9Sstevel@tonic-gate 		flags &= ~B_FLAG;
413*7c478bd9Sstevel@tonic-gate 	}
414*7c478bd9Sstevel@tonic-gate 	if (flags & R_FLAG) {
415*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'r';
416*7c478bd9Sstevel@tonic-gate 		flags &= ~B_FLAG;
417*7c478bd9Sstevel@tonic-gate 	}
418*7c478bd9Sstevel@tonic-gate 	if (flags & I_FLAG) {
419*7c478bd9Sstevel@tonic-gate 		buf[i++] = 'I';
420*7c478bd9Sstevel@tonic-gate 		flags &= ~I_FLAG;
421*7c478bd9Sstevel@tonic-gate 	}
422*7c478bd9Sstevel@tonic-gate 	if (flags)
423*7c478bd9Sstevel@tonic-gate 		log("Internal error in p_ttyflags");
424*7c478bd9Sstevel@tonic-gate 	buf[i] = '\0';
425*7c478bd9Sstevel@tonic-gate 	return(buf);
426*7c478bd9Sstevel@tonic-gate }
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate void
429*7c478bd9Sstevel@tonic-gate dump_pmtab()
430*7c478bd9Sstevel@tonic-gate {
431*7c478bd9Sstevel@tonic-gate 	struct	pmtab *gptr;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 	debug("in dump_pmtab");
434*7c478bd9Sstevel@tonic-gate 	log("********** dumping pmtab **********");
435*7c478bd9Sstevel@tonic-gate 	log(" ");
436*7c478bd9Sstevel@tonic-gate 	for (gptr=PMtab; gptr; gptr = gptr->p_next) {
437*7c478bd9Sstevel@tonic-gate 		log("-------------------------------------------");
438*7c478bd9Sstevel@tonic-gate 		log("tag:\t\t%s", gptr->p_tag);
439*7c478bd9Sstevel@tonic-gate 		log("flags:\t\t%s",pflags(gptr->p_flags));
440*7c478bd9Sstevel@tonic-gate 		log("identity:\t%s", gptr->p_identity);
441*7c478bd9Sstevel@tonic-gate 		log("reserved1:\t%s", gptr->p_res1);
442*7c478bd9Sstevel@tonic-gate 		log("reserved2:\t%s", gptr->p_res2);
443*7c478bd9Sstevel@tonic-gate 		log("reserved3:\t%s", gptr->p_res3);
444*7c478bd9Sstevel@tonic-gate 		log("device:\t%s", gptr->p_device);
445*7c478bd9Sstevel@tonic-gate 		log("ttyflags:\t%s",pttyflags(gptr->p_ttyflags));
446*7c478bd9Sstevel@tonic-gate 		log("count:\t\t%d", gptr->p_count);
447*7c478bd9Sstevel@tonic-gate 		log("server:\t%s", gptr->p_server);
448*7c478bd9Sstevel@tonic-gate 		log("timeout:\t%d", gptr->p_timeout);
449*7c478bd9Sstevel@tonic-gate 		log("ttylabel:\t%s", gptr->p_ttylabel);
450*7c478bd9Sstevel@tonic-gate 		log("modules:\t%s", gptr->p_modules);
451*7c478bd9Sstevel@tonic-gate 		log("prompt:\t%s", gptr->p_prompt);
452*7c478bd9Sstevel@tonic-gate 		log("disable msg:\t%s", gptr->p_dmsg);
453*7c478bd9Sstevel@tonic-gate 		log("terminal type:\t%s", gptr->p_termtype);
454*7c478bd9Sstevel@tonic-gate 		log("soft-carrier:\t%s", gptr->p_softcar);
455*7c478bd9Sstevel@tonic-gate 		log("status:\t\t%d", gptr->p_status);
456*7c478bd9Sstevel@tonic-gate 		log("inservice:\t%d", gptr->p_inservice);
457*7c478bd9Sstevel@tonic-gate 		log("fd:\t\t%d", gptr->p_fd);
458*7c478bd9Sstevel@tonic-gate 		log("pid:\t\t%ld", gptr->p_pid);
459*7c478bd9Sstevel@tonic-gate 		log("uid:\t\t%ld", gptr->p_uid);
460*7c478bd9Sstevel@tonic-gate 		log("gid:\t\t%ld", gptr->p_gid);
461*7c478bd9Sstevel@tonic-gate 		log("dir:\t%s", gptr->p_dir);
462*7c478bd9Sstevel@tonic-gate 		log(" ");
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 	log("********** end dumping pmtab **********");
465*7c478bd9Sstevel@tonic-gate }
466*7c478bd9Sstevel@tonic-gate # endif
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate /*
469*7c478bd9Sstevel@tonic-gate  * same_entry(e1,e2) -    compare 2 entries of pmtab
470*7c478bd9Sstevel@tonic-gate  *			if the fields are different, copy e2 to e1
471*7c478bd9Sstevel@tonic-gate  * 			return 1 if same, return 0 if different
472*7c478bd9Sstevel@tonic-gate  */
473*7c478bd9Sstevel@tonic-gate static	int
474*7c478bd9Sstevel@tonic-gate same_entry(e1,e2)
475*7c478bd9Sstevel@tonic-gate struct	pmtab	*e1,*e2;
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_identity, e2->p_identity) != 0)
479*7c478bd9Sstevel@tonic-gate 		return(0);
480*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res1, e2->p_res1) != 0)
481*7c478bd9Sstevel@tonic-gate 		return(0);
482*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res2, e2->p_res2) != 0)
483*7c478bd9Sstevel@tonic-gate 		return(0);
484*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res3, e2->p_res3) != 0)
485*7c478bd9Sstevel@tonic-gate 		return(0);
486*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_device, e2->p_device) != 0)
487*7c478bd9Sstevel@tonic-gate 		return(0);
488*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_server, e2->p_server) != 0)
489*7c478bd9Sstevel@tonic-gate 		return(0);
490*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_ttylabel, e2->p_ttylabel) != 0)
491*7c478bd9Sstevel@tonic-gate 		return(0);
492*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_modules, e2->p_modules) != 0)
493*7c478bd9Sstevel@tonic-gate 		return(0);
494*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_prompt, e2->p_prompt) != 0)
495*7c478bd9Sstevel@tonic-gate 		return(0);
496*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_dmsg, e2->p_dmsg) != 0)
497*7c478bd9Sstevel@tonic-gate 		return(0);
498*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_termtype, e2->p_termtype) != 0)
499*7c478bd9Sstevel@tonic-gate 		return(0);
500*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_softcar, e2->p_softcar) != 0)
501*7c478bd9Sstevel@tonic-gate 		return(0);
502*7c478bd9Sstevel@tonic-gate 	if (e1->p_flags != e2->p_flags)
503*7c478bd9Sstevel@tonic-gate 		return(0);
504*7c478bd9Sstevel@tonic-gate 	/*
505*7c478bd9Sstevel@tonic-gate 	 * compare lowest 4 bits only,
506*7c478bd9Sstevel@tonic-gate 	 * because A_FLAG is not part of original ttyflags
507*7c478bd9Sstevel@tonic-gate 	 */
508*7c478bd9Sstevel@tonic-gate 	if ((e1->p_ttyflags & ~A_FLAG) != (e2->p_ttyflags & ~A_FLAG))
509*7c478bd9Sstevel@tonic-gate 		return(0);
510*7c478bd9Sstevel@tonic-gate 	if (e1->p_count != e2->p_count)
511*7c478bd9Sstevel@tonic-gate 		return(0);
512*7c478bd9Sstevel@tonic-gate 	if (e1->p_timeout != e2->p_timeout)
513*7c478bd9Sstevel@tonic-gate 		return(0);
514*7c478bd9Sstevel@tonic-gate 	if (e1->p_uid != e2->p_uid)
515*7c478bd9Sstevel@tonic-gate 		return(0);
516*7c478bd9Sstevel@tonic-gate 	if (e1->p_gid != e2->p_gid)
517*7c478bd9Sstevel@tonic-gate 		return(0);
518*7c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_dir, e2->p_dir) != 0)
519*7c478bd9Sstevel@tonic-gate 		return(0);
520*7c478bd9Sstevel@tonic-gate 	return(1);
521*7c478bd9Sstevel@tonic-gate }
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate 
524*7c478bd9Sstevel@tonic-gate /*
525*7c478bd9Sstevel@tonic-gate  * insert_pmtab - insert a pmtab entry into the linked list
526*7c478bd9Sstevel@tonic-gate  */
527*7c478bd9Sstevel@tonic-gate 
528*7c478bd9Sstevel@tonic-gate static	void
529*7c478bd9Sstevel@tonic-gate insert_pmtab(sp)
530*7c478bd9Sstevel@tonic-gate register struct pmtab *sp;	/* ptr to entry to be inserted */
531*7c478bd9Sstevel@tonic-gate {
532*7c478bd9Sstevel@tonic-gate 	register struct pmtab *tsp, *savtsp;	/* scratch pointers */
533*7c478bd9Sstevel@tonic-gate 	int ret;				/* strcmp return value */
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
536*7c478bd9Sstevel@tonic-gate 	debug("in insert_pmtab");
537*7c478bd9Sstevel@tonic-gate # endif
538*7c478bd9Sstevel@tonic-gate 	savtsp = tsp = PMtab;
539*7c478bd9Sstevel@tonic-gate 
540*7c478bd9Sstevel@tonic-gate /*
541*7c478bd9Sstevel@tonic-gate  * find the correct place to insert this element
542*7c478bd9Sstevel@tonic-gate  */
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate 	while (tsp) {
545*7c478bd9Sstevel@tonic-gate 		ret = strcmp(sp->p_tag, tsp->p_tag);
546*7c478bd9Sstevel@tonic-gate 		if (ret > 0) {
547*7c478bd9Sstevel@tonic-gate 			/* keep on looking */
548*7c478bd9Sstevel@tonic-gate 			savtsp = tsp;
549*7c478bd9Sstevel@tonic-gate 			tsp = tsp->p_next;
550*7c478bd9Sstevel@tonic-gate 			continue;
551*7c478bd9Sstevel@tonic-gate 		}
552*7c478bd9Sstevel@tonic-gate 		else if (ret == 0) {
553*7c478bd9Sstevel@tonic-gate 			if (tsp->p_status) {
554*7c478bd9Sstevel@tonic-gate 				/* this is a duplicate entry, ignore it */
555*7c478bd9Sstevel@tonic-gate 				log("Ignoring duplicate entry for <%s>",
556*7c478bd9Sstevel@tonic-gate 				    tsp->p_tag);
557*7c478bd9Sstevel@tonic-gate 			}
558*7c478bd9Sstevel@tonic-gate 			else {
559*7c478bd9Sstevel@tonic-gate 				if (same_entry(tsp,sp)) {  /* same entry */
560*7c478bd9Sstevel@tonic-gate 					tsp->p_status = VALID;
561*7c478bd9Sstevel@tonic-gate 				}
562*7c478bd9Sstevel@tonic-gate 				else {	/* entry changed */
563*7c478bd9Sstevel@tonic-gate 					if ((sp->p_flags & X_FLAG) &&
564*7c478bd9Sstevel@tonic-gate 						((sp->p_dmsg == NULL) ||
565*7c478bd9Sstevel@tonic-gate 						(*(sp->p_dmsg) == '\0'))) {
566*7c478bd9Sstevel@tonic-gate 						/* disabled entry */
567*7c478bd9Sstevel@tonic-gate 						tsp->p_status = NOTVALID;
568*7c478bd9Sstevel@tonic-gate 					}
569*7c478bd9Sstevel@tonic-gate 					else {
570*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
571*7c478bd9Sstevel@tonic-gate 					debug("replacing <%s>", sp->p_tag);
572*7c478bd9Sstevel@tonic-gate # endif
573*7c478bd9Sstevel@tonic-gate 						/* replace old entry */
574*7c478bd9Sstevel@tonic-gate 						sp->p_next = tsp->p_next;
575*7c478bd9Sstevel@tonic-gate 						if (tsp == PMtab) {
576*7c478bd9Sstevel@tonic-gate 						   PMtab = sp;
577*7c478bd9Sstevel@tonic-gate 						}
578*7c478bd9Sstevel@tonic-gate 						else {
579*7c478bd9Sstevel@tonic-gate 						   savtsp->p_next = sp;
580*7c478bd9Sstevel@tonic-gate 						}
581*7c478bd9Sstevel@tonic-gate 						sp->p_status = CHANGED;
582*7c478bd9Sstevel@tonic-gate 						sp->p_fd = tsp->p_fd;
583*7c478bd9Sstevel@tonic-gate 						sp->p_pid = tsp->p_pid;
584*7c478bd9Sstevel@tonic-gate 					        sp->p_inservice =
585*7c478bd9Sstevel@tonic-gate 							tsp->p_inservice;
586*7c478bd9Sstevel@tonic-gate 						sp = tsp;
587*7c478bd9Sstevel@tonic-gate 					}
588*7c478bd9Sstevel@tonic-gate 				}
589*7c478bd9Sstevel@tonic-gate 				Nentries++;
590*7c478bd9Sstevel@tonic-gate 			}
591*7c478bd9Sstevel@tonic-gate 			free_pmtab(sp);
592*7c478bd9Sstevel@tonic-gate 			return;
593*7c478bd9Sstevel@tonic-gate 		}
594*7c478bd9Sstevel@tonic-gate 		else {
595*7c478bd9Sstevel@tonic-gate 			if ((sp->p_flags & X_FLAG) &&
596*7c478bd9Sstevel@tonic-gate 				((sp->p_dmsg == NULL) ||
597*7c478bd9Sstevel@tonic-gate 				(*(sp->p_dmsg) == '\0'))) { /* disabled entry */
598*7c478bd9Sstevel@tonic-gate 				free_pmtab(sp);
599*7c478bd9Sstevel@tonic-gate 				return;
600*7c478bd9Sstevel@tonic-gate 			}
601*7c478bd9Sstevel@tonic-gate 			/*
602*7c478bd9Sstevel@tonic-gate 			 * Set the state of soft-carrier.
603*7c478bd9Sstevel@tonic-gate 			 * Since this is a one-time only operation,
604*7c478bd9Sstevel@tonic-gate 			 * we do it when this service is added to
605*7c478bd9Sstevel@tonic-gate 			 * the enabled list.
606*7c478bd9Sstevel@tonic-gate 			 */
607*7c478bd9Sstevel@tonic-gate 			if (*sp->p_softcar != '\0')
608*7c478bd9Sstevel@tonic-gate 				set_softcar(sp);
609*7c478bd9Sstevel@tonic-gate 
610*7c478bd9Sstevel@tonic-gate 			/* insert it here */
611*7c478bd9Sstevel@tonic-gate 			if (tsp == PMtab) {
612*7c478bd9Sstevel@tonic-gate 				sp->p_next = PMtab;
613*7c478bd9Sstevel@tonic-gate 				PMtab = sp;
614*7c478bd9Sstevel@tonic-gate 			}
615*7c478bd9Sstevel@tonic-gate 			else {
616*7c478bd9Sstevel@tonic-gate 				sp->p_next = savtsp->p_next;
617*7c478bd9Sstevel@tonic-gate 				savtsp->p_next = sp;
618*7c478bd9Sstevel@tonic-gate 			}
619*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
620*7c478bd9Sstevel@tonic-gate 			debug("adding <%s>", sp->p_tag);
621*7c478bd9Sstevel@tonic-gate # endif
622*7c478bd9Sstevel@tonic-gate 			Nentries++;
623*7c478bd9Sstevel@tonic-gate 			/* this entry is "current" */
624*7c478bd9Sstevel@tonic-gate 			sp->p_status = VALID;
625*7c478bd9Sstevel@tonic-gate 			return;
626*7c478bd9Sstevel@tonic-gate 		}
627*7c478bd9Sstevel@tonic-gate 	}
628*7c478bd9Sstevel@tonic-gate 
629*7c478bd9Sstevel@tonic-gate /*
630*7c478bd9Sstevel@tonic-gate  * either an empty list or should put element at end of list
631*7c478bd9Sstevel@tonic-gate  */
632*7c478bd9Sstevel@tonic-gate 
633*7c478bd9Sstevel@tonic-gate 	if ((sp->p_flags & X_FLAG) &&
634*7c478bd9Sstevel@tonic-gate 		((sp->p_dmsg == NULL) ||
635*7c478bd9Sstevel@tonic-gate 		(*(sp->p_dmsg) == '\0'))) { /* disabled entry */
636*7c478bd9Sstevel@tonic-gate 		free_pmtab(sp);		 /* do not poll this entry */
637*7c478bd9Sstevel@tonic-gate 		return;
638*7c478bd9Sstevel@tonic-gate 	}
639*7c478bd9Sstevel@tonic-gate 	/*
640*7c478bd9Sstevel@tonic-gate 	 * Set the state of soft-carrier.
641*7c478bd9Sstevel@tonic-gate 	 * Since this is a one-time only operation,
642*7c478bd9Sstevel@tonic-gate 	 * we do it when this service is added to
643*7c478bd9Sstevel@tonic-gate 	 * the enabled list.
644*7c478bd9Sstevel@tonic-gate 	 */
645*7c478bd9Sstevel@tonic-gate 	if (*sp->p_softcar != '\0')
646*7c478bd9Sstevel@tonic-gate 		set_softcar(sp);
647*7c478bd9Sstevel@tonic-gate 	sp->p_next = NULL;
648*7c478bd9Sstevel@tonic-gate 	if (PMtab == NULL)
649*7c478bd9Sstevel@tonic-gate 		PMtab = sp;
650*7c478bd9Sstevel@tonic-gate 	else
651*7c478bd9Sstevel@tonic-gate 		savtsp->p_next = sp;
652*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
653*7c478bd9Sstevel@tonic-gate 	debug("adding <%s>", sp->p_tag);
654*7c478bd9Sstevel@tonic-gate # endif
655*7c478bd9Sstevel@tonic-gate 	++Nentries;
656*7c478bd9Sstevel@tonic-gate 	/* this entry is "current" */
657*7c478bd9Sstevel@tonic-gate 	sp->p_status = VALID;
658*7c478bd9Sstevel@tonic-gate }
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate 
661*7c478bd9Sstevel@tonic-gate /*
662*7c478bd9Sstevel@tonic-gate  * purge - purge linked list of "old" entries
663*7c478bd9Sstevel@tonic-gate  */
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate void
667*7c478bd9Sstevel@tonic-gate purge()
668*7c478bd9Sstevel@tonic-gate {
669*7c478bd9Sstevel@tonic-gate 	register struct pmtab *sp;		/* working pointer */
670*7c478bd9Sstevel@tonic-gate 	register struct pmtab *savesp, *tsp;	/* scratch pointers */
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
673*7c478bd9Sstevel@tonic-gate 	debug("in purge");
674*7c478bd9Sstevel@tonic-gate # endif
675*7c478bd9Sstevel@tonic-gate 	sp = savesp = PMtab;
676*7c478bd9Sstevel@tonic-gate 	while (sp) {
677*7c478bd9Sstevel@tonic-gate 		if (sp->p_status) {
678*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
679*7c478bd9Sstevel@tonic-gate 			debug("p_status not 0");
680*7c478bd9Sstevel@tonic-gate # endif
681*7c478bd9Sstevel@tonic-gate 			savesp = sp;
682*7c478bd9Sstevel@tonic-gate 			sp = sp->p_next;
683*7c478bd9Sstevel@tonic-gate 		}
684*7c478bd9Sstevel@tonic-gate 		else {
685*7c478bd9Sstevel@tonic-gate 			tsp = sp;
686*7c478bd9Sstevel@tonic-gate 			if (tsp == PMtab) {
687*7c478bd9Sstevel@tonic-gate 				PMtab = sp->p_next;
688*7c478bd9Sstevel@tonic-gate 				savesp = PMtab;
689*7c478bd9Sstevel@tonic-gate 			}
690*7c478bd9Sstevel@tonic-gate 			else
691*7c478bd9Sstevel@tonic-gate 				savesp->p_next = sp->p_next;
692*7c478bd9Sstevel@tonic-gate # ifdef DEBUG
693*7c478bd9Sstevel@tonic-gate 			debug("purging <%s>", sp->p_tag);
694*7c478bd9Sstevel@tonic-gate # endif
695*7c478bd9Sstevel@tonic-gate 			sp = sp->p_next;
696*7c478bd9Sstevel@tonic-gate 			free_pmtab(tsp);
697*7c478bd9Sstevel@tonic-gate 		}
698*7c478bd9Sstevel@tonic-gate 	}
699*7c478bd9Sstevel@tonic-gate }
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate /*
702*7c478bd9Sstevel@tonic-gate  *	free_pmtab	- free one pmtab entry
703*7c478bd9Sstevel@tonic-gate  */
704*7c478bd9Sstevel@tonic-gate static	void
705*7c478bd9Sstevel@tonic-gate free_pmtab(p)
706*7c478bd9Sstevel@tonic-gate struct	pmtab	*p;
707*7c478bd9Sstevel@tonic-gate {
708*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
709*7c478bd9Sstevel@tonic-gate 	debug("in free_pmtab");
710*7c478bd9Sstevel@tonic-gate #endif
711*7c478bd9Sstevel@tonic-gate 	free(p->p_tag);
712*7c478bd9Sstevel@tonic-gate 	free(p->p_identity);
713*7c478bd9Sstevel@tonic-gate 	free(p->p_res1);
714*7c478bd9Sstevel@tonic-gate 	free(p->p_res2);
715*7c478bd9Sstevel@tonic-gate 	free(p->p_res3);
716*7c478bd9Sstevel@tonic-gate 	free(p->p_device);
717*7c478bd9Sstevel@tonic-gate 	free(p->p_server);
718*7c478bd9Sstevel@tonic-gate 	free(p->p_ttylabel);
719*7c478bd9Sstevel@tonic-gate 	free(p->p_modules);
720*7c478bd9Sstevel@tonic-gate 	free(p->p_prompt);
721*7c478bd9Sstevel@tonic-gate 	free(p->p_dmsg);
722*7c478bd9Sstevel@tonic-gate 	free(p->p_termtype);
723*7c478bd9Sstevel@tonic-gate 	free(p->p_softcar);
724*7c478bd9Sstevel@tonic-gate 	if (p->p_dir)
725*7c478bd9Sstevel@tonic-gate 		free(p->p_dir);
726*7c478bd9Sstevel@tonic-gate 	free(p);
727*7c478bd9Sstevel@tonic-gate }
728*7c478bd9Sstevel@tonic-gate 
729*7c478bd9Sstevel@tonic-gate /*
730*7c478bd9Sstevel@tonic-gate  *	check_pmtab - check the fields to make sure things are correct
731*7c478bd9Sstevel@tonic-gate  *		    - return 0 if everything is ok
732*7c478bd9Sstevel@tonic-gate  *		    - return -1 if something is wrong
733*7c478bd9Sstevel@tonic-gate  */
734*7c478bd9Sstevel@tonic-gate 
735*7c478bd9Sstevel@tonic-gate static	int
736*7c478bd9Sstevel@tonic-gate check_pmtab(p)
737*7c478bd9Sstevel@tonic-gate struct	pmtab	*p;
738*7c478bd9Sstevel@tonic-gate {
739*7c478bd9Sstevel@tonic-gate 	if (p == NULL) {
740*7c478bd9Sstevel@tonic-gate 		log("pmtab ptr is NULL");
741*7c478bd9Sstevel@tonic-gate 		return(-1);
742*7c478bd9Sstevel@tonic-gate 	}
743*7c478bd9Sstevel@tonic-gate 
744*7c478bd9Sstevel@tonic-gate 	/* check service tag */
745*7c478bd9Sstevel@tonic-gate 	if ((p->p_tag == NULL) || (*(p->p_tag) == '\0')) {
746*7c478bd9Sstevel@tonic-gate 		log("port/service tag is missing");
747*7c478bd9Sstevel@tonic-gate 		return(-1);
748*7c478bd9Sstevel@tonic-gate 	}
749*7c478bd9Sstevel@tonic-gate 	if (strlen(p->p_tag) > (size_t)(MAXID - 1)) {
750*7c478bd9Sstevel@tonic-gate 		log("port/service tag <%s> is longer than %d", p->p_tag,
751*7c478bd9Sstevel@tonic-gate 		    MAXID-1);
752*7c478bd9Sstevel@tonic-gate 		return(-1);
753*7c478bd9Sstevel@tonic-gate 	}
754*7c478bd9Sstevel@tonic-gate 	if (strcheck(p->p_tag, ALNUM) != 0) {
755*7c478bd9Sstevel@tonic-gate 		log("port/service tag <%s> is not alphanumeric", p->p_tag);
756*7c478bd9Sstevel@tonic-gate 		return(-1);
757*7c478bd9Sstevel@tonic-gate 	}
758*7c478bd9Sstevel@tonic-gate 	if (check_identity(p) != 0) {
759*7c478bd9Sstevel@tonic-gate 		return(-1);
760*7c478bd9Sstevel@tonic-gate 	}
761*7c478bd9Sstevel@tonic-gate 
762*7c478bd9Sstevel@tonic-gate 	if (check_device(p->p_device) != 0)
763*7c478bd9Sstevel@tonic-gate 		return(-1);
764*7c478bd9Sstevel@tonic-gate 
765*7c478bd9Sstevel@tonic-gate 	if (check_cmd(p->p_server) != 0)
766*7c478bd9Sstevel@tonic-gate 		return(-1);
767*7c478bd9Sstevel@tonic-gate 	return(0);
768*7c478bd9Sstevel@tonic-gate }
769*7c478bd9Sstevel@tonic-gate 
770*7c478bd9Sstevel@tonic-gate extern  struct 	passwd *getpwnam();
771*7c478bd9Sstevel@tonic-gate extern  void 	endpwent();
772*7c478bd9Sstevel@tonic-gate extern  struct 	group *getgrgid();
773*7c478bd9Sstevel@tonic-gate extern  void 	endgrent();
774*7c478bd9Sstevel@tonic-gate 
775*7c478bd9Sstevel@tonic-gate /*
776*7c478bd9Sstevel@tonic-gate  *	check_identity - check to see if the identity is a valid user
777*7c478bd9Sstevel@tonic-gate  *		       - log name in the passwd file,
778*7c478bd9Sstevel@tonic-gate  *		       - and if its group id is a valid one
779*7c478bd9Sstevel@tonic-gate  *		  	- return 0 if everything is ok. Otherwise, return -1
780*7c478bd9Sstevel@tonic-gate  */
781*7c478bd9Sstevel@tonic-gate 
782*7c478bd9Sstevel@tonic-gate int
783*7c478bd9Sstevel@tonic-gate check_identity(p)
784*7c478bd9Sstevel@tonic-gate struct	pmtab	*p;
785*7c478bd9Sstevel@tonic-gate {
786*7c478bd9Sstevel@tonic-gate 	register struct passwd *pwdp;
787*7c478bd9Sstevel@tonic-gate 
788*7c478bd9Sstevel@tonic-gate 	if ((p->p_identity == NULL) || (*(p->p_identity) == '\0')) {
789*7c478bd9Sstevel@tonic-gate 		log("identity field is missing");
790*7c478bd9Sstevel@tonic-gate 		return(-1);
791*7c478bd9Sstevel@tonic-gate 	}
792*7c478bd9Sstevel@tonic-gate 	if ((pwdp = getpwnam(p->p_identity)) == NULL) {
793*7c478bd9Sstevel@tonic-gate 		log("missing or bad passwd entry for <%s>", p->p_identity);
794*7c478bd9Sstevel@tonic-gate 		endpwent();
795*7c478bd9Sstevel@tonic-gate 		return(-1);
796*7c478bd9Sstevel@tonic-gate 	}
797*7c478bd9Sstevel@tonic-gate 	if (getgrgid(pwdp->pw_gid) == NULL) {
798*7c478bd9Sstevel@tonic-gate 		log("no group entry for %ld", pwdp->pw_gid);
799*7c478bd9Sstevel@tonic-gate 		endgrent();
800*7c478bd9Sstevel@tonic-gate 		endpwent();
801*7c478bd9Sstevel@tonic-gate 		return(-1);
802*7c478bd9Sstevel@tonic-gate 	}
803*7c478bd9Sstevel@tonic-gate 	p->p_uid = pwdp->pw_uid;
804*7c478bd9Sstevel@tonic-gate 	p->p_gid = pwdp->pw_gid;
805*7c478bd9Sstevel@tonic-gate 	p->p_dir = strsave(pwdp->pw_dir);
806*7c478bd9Sstevel@tonic-gate 	endgrent();
807*7c478bd9Sstevel@tonic-gate 	endpwent();
808*7c478bd9Sstevel@tonic-gate 	return(0);
809*7c478bd9Sstevel@tonic-gate }
810*7c478bd9Sstevel@tonic-gate 
811*7c478bd9Sstevel@tonic-gate /*
812*7c478bd9Sstevel@tonic-gate  * expand(cmdp, devp)	- expand %d to device name and %% to %,
813*7c478bd9Sstevel@tonic-gate  *				- any other characters are untouched.
814*7c478bd9Sstevel@tonic-gate  *				- return the expanded string
815*7c478bd9Sstevel@tonic-gate  */
816*7c478bd9Sstevel@tonic-gate static char	*
817*7c478bd9Sstevel@tonic-gate expand(cmdp,devp)
818*7c478bd9Sstevel@tonic-gate char	*cmdp;		/* ptr to cmd string	*/
819*7c478bd9Sstevel@tonic-gate char	*devp;		/* ptr to device name	*/
820*7c478bd9Sstevel@tonic-gate {
821*7c478bd9Sstevel@tonic-gate 	register char	*cp, *dp, *np;
822*7c478bd9Sstevel@tonic-gate 	static char	buf[BUFSIZ];
823*7c478bd9Sstevel@tonic-gate 	cp = cmdp;
824*7c478bd9Sstevel@tonic-gate 	np = buf;
825*7c478bd9Sstevel@tonic-gate 	dp = devp;
826*7c478bd9Sstevel@tonic-gate 	while (*cp) {
827*7c478bd9Sstevel@tonic-gate 		if (*cp != '%') {
828*7c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
829*7c478bd9Sstevel@tonic-gate 			continue;
830*7c478bd9Sstevel@tonic-gate 		}
831*7c478bd9Sstevel@tonic-gate 		switch (*++cp) {
832*7c478bd9Sstevel@tonic-gate 		case 'd':
833*7c478bd9Sstevel@tonic-gate 			while (*dp) {
834*7c478bd9Sstevel@tonic-gate 				*np++ = *dp++;
835*7c478bd9Sstevel@tonic-gate 			}
836*7c478bd9Sstevel@tonic-gate 			cp++;
837*7c478bd9Sstevel@tonic-gate 			break;
838*7c478bd9Sstevel@tonic-gate 		case '%':
839*7c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
840*7c478bd9Sstevel@tonic-gate 			break;
841*7c478bd9Sstevel@tonic-gate 		default:
842*7c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
843*7c478bd9Sstevel@tonic-gate 			break;
844*7c478bd9Sstevel@tonic-gate 		}
845*7c478bd9Sstevel@tonic-gate 	}
846*7c478bd9Sstevel@tonic-gate 	*np = '\0';
847*7c478bd9Sstevel@tonic-gate 	return(buf);
848*7c478bd9Sstevel@tonic-gate }
849*7c478bd9Sstevel@tonic-gate 
850