xref: /illumos-gate/usr/src/cmd/ttymon/tmpmtab.c (revision 3bb2c156)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27*3bb2c156SToomas Soome /*	  All Rights Reserved	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include	<unistd.h>
307c478bd9Sstevel@tonic-gate #include	<stdlib.h>
317c478bd9Sstevel@tonic-gate #include	<sys/types.h>
327c478bd9Sstevel@tonic-gate #include	<ctype.h>
337c478bd9Sstevel@tonic-gate #include	<string.h>
34*3bb2c156SToomas Soome #include	<pwd.h>
35*3bb2c156SToomas Soome #include	<grp.h>
367c478bd9Sstevel@tonic-gate #include	<signal.h>
377c478bd9Sstevel@tonic-gate #include	"ttymon.h"
387c478bd9Sstevel@tonic-gate #include	"tmstruct.h"
397c478bd9Sstevel@tonic-gate #include	"tmextern.h"
407c478bd9Sstevel@tonic-gate 
41*3bb2c156SToomas Soome static	int	get_flags(char *, long *);
42*3bb2c156SToomas Soome static	int	get_ttyflags(char *, long *);
43*3bb2c156SToomas Soome static	int	same_entry(struct pmtab *, struct pmtab *);
44*3bb2c156SToomas Soome static	int	check_pmtab(struct pmtab *);
45*3bb2c156SToomas Soome static	void	insert_pmtab(struct pmtab *);
46*3bb2c156SToomas Soome static	void	free_pmtab(struct pmtab *);
47*3bb2c156SToomas Soome static	char	*expand(char *, char *);
487c478bd9Sstevel@tonic-gate 
49*3bb2c156SToomas Soome int	check_identity(struct pmtab *);
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /*
52*3bb2c156SToomas Soome  * read_pmtab()
53*3bb2c156SToomas Soome  *	- read and parse pmtab
547c478bd9Sstevel@tonic-gate  *	- store table in linked list pointed by global variable "PMtab"
557c478bd9Sstevel@tonic-gate  *	- exit if file does not exist or error detected.
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate void
read_pmtab(void)58*3bb2c156SToomas Soome read_pmtab(void)
597c478bd9Sstevel@tonic-gate {
60*3bb2c156SToomas Soome 	struct pmtab *gptr;
61*3bb2c156SToomas Soome 	char *ptr, *wptr;
62*3bb2c156SToomas Soome 	FILE	 *fp;
63*3bb2c156SToomas Soome 	int	 input, state, size, rawc, field, linenum;
64*3bb2c156SToomas Soome 	char	 oldc;
65*3bb2c156SToomas Soome 	char	 line[BUFSIZ];
66*3bb2c156SToomas Soome 	char	 wbuf[BUFSIZ];
67*3bb2c156SToomas Soome 	static	 char *states[] = {
68*3bb2c156SToomas Soome 	    "", "tag", "flags", "identity", "reserved1", "reserved2",
69*3bb2c156SToomas Soome 	    "reserved3", "device", "ttyflags", "count", "service", "timeout",
70*3bb2c156SToomas Soome 	    "ttylabel", "modules", "prompt", "disable msg", "terminal type",
71*3bb2c156SToomas Soome 	    "soft-carrier"
727c478bd9Sstevel@tonic-gate 	};
737c478bd9Sstevel@tonic-gate 
74*3bb2c156SToomas Soome #ifdef DEBUG
757c478bd9Sstevel@tonic-gate 	debug("in read_pmtab");
76*3bb2c156SToomas Soome #endif
777c478bd9Sstevel@tonic-gate 
78*3bb2c156SToomas Soome 	if ((fp = fopen(PMTABFILE, "r")) == NULL) {
797c478bd9Sstevel@tonic-gate 		fatal("open pmtab (%s) failed", PMTABFILE);
807c478bd9Sstevel@tonic-gate 	}
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	Nentries = 0;
837c478bd9Sstevel@tonic-gate 	if (check_version(PMTAB_VERS, PMTABFILE) != 0)
847c478bd9Sstevel@tonic-gate 		fatal("check pmtab version failed");
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	for (gptr = PMtab; gptr; gptr = gptr->p_next) {
877c478bd9Sstevel@tonic-gate 		if ((gptr->p_status == SESSION) ||
887c478bd9Sstevel@tonic-gate 		    (gptr->p_status == LOCKED) ||
897c478bd9Sstevel@tonic-gate 		    (gptr->p_status == UNACCESS)) {
907c478bd9Sstevel@tonic-gate 			if (gptr->p_fd > 0) {
91*3bb2c156SToomas Soome 				(void) close(gptr->p_fd);
927c478bd9Sstevel@tonic-gate 				gptr->p_fd = 0;
937c478bd9Sstevel@tonic-gate 			}
947c478bd9Sstevel@tonic-gate 			gptr->p_inservice = gptr->p_status;
957c478bd9Sstevel@tonic-gate 		}
967c478bd9Sstevel@tonic-gate 		gptr->p_status = NOTVALID;
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	wptr = wbuf;
1007c478bd9Sstevel@tonic-gate 	input = ACTIVE;
1017c478bd9Sstevel@tonic-gate 	linenum = 0;
102*3bb2c156SToomas Soome 	field = FAILURE;
1037c478bd9Sstevel@tonic-gate 	do {
1047c478bd9Sstevel@tonic-gate 		linenum++;
1057c478bd9Sstevel@tonic-gate 		line[0] = '\0';
106*3bb2c156SToomas Soome 		for (ptr = line, oldc = '\0'; ptr < &line[sizeof (line) - 1] &&
107*3bb2c156SToomas Soome 		    (rawc = getc(fp)) != '\n' && rawc != EOF;
108*3bb2c156SToomas Soome 		    ptr++, oldc = (char)rawc) {
1097c478bd9Sstevel@tonic-gate 			if ((rawc == '#') && (oldc != '\\'))
1107c478bd9Sstevel@tonic-gate 				break;
1117c478bd9Sstevel@tonic-gate 			*ptr = (char)rawc;
1127c478bd9Sstevel@tonic-gate 		}
1137c478bd9Sstevel@tonic-gate 		*ptr = '\0';
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 		/* skip rest of the line */
1167c478bd9Sstevel@tonic-gate 		if (rawc != EOF && rawc != '\n') {
117*3bb2c156SToomas Soome 			if (rawc != '#')
1187c478bd9Sstevel@tonic-gate 				log("Entry too long.\n");
119*3bb2c156SToomas Soome 			while ((rawc = getc(fp)) != EOF && rawc != '\n')
1207c478bd9Sstevel@tonic-gate 				;
1217c478bd9Sstevel@tonic-gate 		}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		if (rawc == EOF) {
124*3bb2c156SToomas Soome 			if (ptr == line)
125*3bb2c156SToomas Soome 				break;
126*3bb2c156SToomas Soome 			else
127*3bb2c156SToomas Soome 				input = FINISHED;
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 		/* if empty line, skip */
131*3bb2c156SToomas Soome 		for (ptr = line; *ptr != '\0' && isspace(*ptr); ptr++)
1327c478bd9Sstevel@tonic-gate 			;
133*3bb2c156SToomas Soome 		if (*ptr == '\0')
134*3bb2c156SToomas Soome 			continue;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate #ifdef DEBUG
1377c478bd9Sstevel@tonic-gate 		debug("**** Next Entry ****\n%s", line);
1387c478bd9Sstevel@tonic-gate #endif
1397c478bd9Sstevel@tonic-gate 		log("Processing pmtab line #%d", linenum);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 		/* Now we have the complete line */
1427c478bd9Sstevel@tonic-gate 
143*3bb2c156SToomas Soome 		if ((gptr = ALLOC_PMTAB) == NULL)
1447c478bd9Sstevel@tonic-gate 			fatal("memory allocation failed");
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 		/* set hangup flag, this is the default */
1477c478bd9Sstevel@tonic-gate 		gptr->p_ttyflags |= H_FLAG;
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 		/*
1507c478bd9Sstevel@tonic-gate 		 * For compatibility reasons, we cannot rely on these
1517c478bd9Sstevel@tonic-gate 		 * having values assigned from pmtab.
1527c478bd9Sstevel@tonic-gate 		 */
1537c478bd9Sstevel@tonic-gate 		gptr->p_termtype = "";
1547c478bd9Sstevel@tonic-gate 		gptr->p_softcar = "";
1557c478bd9Sstevel@tonic-gate 
156*3bb2c156SToomas Soome 		for (state = P_TAG, ptr = line; state != FAILURE &&
157*3bb2c156SToomas Soome 		    state != SUCCESS;) {
158*3bb2c156SToomas Soome 			switch (state) {
1597c478bd9Sstevel@tonic-gate 			case P_TAG:
160*3bb2c156SToomas Soome 				gptr->p_tag = strsave(getword(ptr, &size, 0));
1617c478bd9Sstevel@tonic-gate 				break;
1627c478bd9Sstevel@tonic-gate 			case P_FLAGS:
163*3bb2c156SToomas Soome 				(void) strcpy(wptr, getword(ptr, &size, 0));
1647c478bd9Sstevel@tonic-gate 				if ((get_flags(wptr, &gptr->p_flags)) != 0) {
1657c478bd9Sstevel@tonic-gate 					field = state;
1667c478bd9Sstevel@tonic-gate 					state = FAILURE;
1677c478bd9Sstevel@tonic-gate 				}
1687c478bd9Sstevel@tonic-gate 				break;
1697c478bd9Sstevel@tonic-gate 			case P_IDENTITY:
170*3bb2c156SToomas Soome 				gptr->p_identity = strsave(
171*3bb2c156SToomas Soome 				    getword(ptr, &size, 0));
1727c478bd9Sstevel@tonic-gate 				break;
1737c478bd9Sstevel@tonic-gate 			case P_RES1:
174*3bb2c156SToomas Soome 				gptr->p_res1 = strsave(getword(ptr, &size, 0));
1757c478bd9Sstevel@tonic-gate 				break;
1767c478bd9Sstevel@tonic-gate 			case P_RES2:
177*3bb2c156SToomas Soome 				gptr->p_res2 = strsave(getword(ptr, &size, 0));
1787c478bd9Sstevel@tonic-gate 				break;
1797c478bd9Sstevel@tonic-gate 			case P_RES3:
180*3bb2c156SToomas Soome 				gptr->p_res3 = strsave(getword(ptr, &size, 0));
1817c478bd9Sstevel@tonic-gate 				break;
1827c478bd9Sstevel@tonic-gate 			case P_DEVICE:
183*3bb2c156SToomas Soome 				gptr->p_device = strsave(
184*3bb2c156SToomas Soome 				    getword(ptr, &size, 0));
1857c478bd9Sstevel@tonic-gate 				break;
1867c478bd9Sstevel@tonic-gate 			case P_TTYFLAGS:
187*3bb2c156SToomas Soome 				(void) strcpy(wptr, getword(ptr, &size, 0));
188*3bb2c156SToomas Soome 				if (get_ttyflags(wptr,
189*3bb2c156SToomas Soome 				    &gptr->p_ttyflags) != 0) {
1907c478bd9Sstevel@tonic-gate 					field = state;
1917c478bd9Sstevel@tonic-gate 					state = FAILURE;
1927c478bd9Sstevel@tonic-gate 				}
1937c478bd9Sstevel@tonic-gate 				break;
1947c478bd9Sstevel@tonic-gate 			case P_COUNT:
195*3bb2c156SToomas Soome 				(void) strcpy(wptr, getword(ptr, &size, 0));
1967c478bd9Sstevel@tonic-gate 				if (strcheck(wptr, NUM) != 0) {
197*3bb2c156SToomas Soome 					log("wait_read count must be a "
198*3bb2c156SToomas Soome 					    "positive number");
1997c478bd9Sstevel@tonic-gate 					field = state;
2007c478bd9Sstevel@tonic-gate 					state = FAILURE;
201*3bb2c156SToomas Soome 				} else {
202*3bb2c156SToomas Soome 					gptr->p_count = atoi(wptr);
2037c478bd9Sstevel@tonic-gate 				}
2047c478bd9Sstevel@tonic-gate 				break;
2057c478bd9Sstevel@tonic-gate 			case P_SERVER:
206*3bb2c156SToomas Soome 				gptr->p_server =
207*3bb2c156SToomas Soome 				    strsave(expand(getword(ptr, &size, 1),
208*3bb2c156SToomas Soome 				    gptr->p_device));
2097c478bd9Sstevel@tonic-gate 				break;
2107c478bd9Sstevel@tonic-gate 			case P_TIMEOUT:
211*3bb2c156SToomas Soome 				(void) strcpy(wptr, getword(ptr, &size, 0));
2127c478bd9Sstevel@tonic-gate 				if (strcheck(wptr, NUM) != 0) {
213*3bb2c156SToomas Soome 					log("timeout value must be a positive "
214*3bb2c156SToomas Soome 					    "number");
2157c478bd9Sstevel@tonic-gate 					field = state;
2167c478bd9Sstevel@tonic-gate 					state = FAILURE;
217*3bb2c156SToomas Soome 				} else {
218*3bb2c156SToomas Soome 					gptr->p_timeout = atoi(wptr);
2197c478bd9Sstevel@tonic-gate 				}
2207c478bd9Sstevel@tonic-gate 				break;
2217c478bd9Sstevel@tonic-gate 			case P_TTYLABEL:
222*3bb2c156SToomas Soome 				gptr->p_ttylabel = strsave(getword(ptr,
223*3bb2c156SToomas Soome 				    &size, 0));
2247c478bd9Sstevel@tonic-gate 				break;
2257c478bd9Sstevel@tonic-gate 			case P_MODULES:
226*3bb2c156SToomas Soome 				gptr->p_modules = strsave(getword(ptr,
227*3bb2c156SToomas Soome 				    &size, 0));
2287c478bd9Sstevel@tonic-gate 				if (vml(gptr->p_modules) != 0) {
2297c478bd9Sstevel@tonic-gate 					field = state;
2307c478bd9Sstevel@tonic-gate 					state = FAILURE;
2317c478bd9Sstevel@tonic-gate 				}
2327c478bd9Sstevel@tonic-gate 				break;
2337c478bd9Sstevel@tonic-gate 			case P_PROMPT:
234*3bb2c156SToomas Soome 				gptr->p_prompt = strsave(getword(ptr, &size,
235*3bb2c156SToomas Soome 				    TRUE));
2367c478bd9Sstevel@tonic-gate 				break;
2377c478bd9Sstevel@tonic-gate 			case P_DMSG:
238*3bb2c156SToomas Soome 				gptr->p_dmsg = strsave(getword(ptr, &size,
239*3bb2c156SToomas Soome 				    TRUE));
2407c478bd9Sstevel@tonic-gate 				break;
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 			case P_TERMTYPE:
243*3bb2c156SToomas Soome 				gptr->p_termtype = strsave(getword(ptr,
244*3bb2c156SToomas Soome 				    &size, TRUE));
2457c478bd9Sstevel@tonic-gate 				break;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 			case P_SOFTCAR:
248*3bb2c156SToomas Soome 				gptr->p_softcar = strsave(getword(ptr,
249*3bb2c156SToomas Soome 				    &size, TRUE));
2507c478bd9Sstevel@tonic-gate 				break;
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 			} /* end switch */
2537c478bd9Sstevel@tonic-gate 			ptr += size;
254*3bb2c156SToomas Soome 			if (state == FAILURE)
2557c478bd9Sstevel@tonic-gate 				break;
2567c478bd9Sstevel@tonic-gate 			if (*ptr == ':') {
2577c478bd9Sstevel@tonic-gate 				ptr++;	/* Skip the ':' */
258*3bb2c156SToomas Soome 				state++;
2597c478bd9Sstevel@tonic-gate 			} else if (*ptr != '\0') {
2607c478bd9Sstevel@tonic-gate 				field = state;
2617c478bd9Sstevel@tonic-gate 				state = FAILURE;
2627c478bd9Sstevel@tonic-gate 			}
2637c478bd9Sstevel@tonic-gate 			if (*ptr == '\0') {
2647c478bd9Sstevel@tonic-gate 				/*
2657c478bd9Sstevel@tonic-gate 				 * Maintain compatibility with older ttymon
2667c478bd9Sstevel@tonic-gate 				 * pmtab files.  If Sun-added fields are
2677c478bd9Sstevel@tonic-gate 				 * missing, this should not be an error.
2687c478bd9Sstevel@tonic-gate 				 */
269*3bb2c156SToomas Soome 				if (state > P_DMSG) {
2707c478bd9Sstevel@tonic-gate 					state = SUCCESS;
2717c478bd9Sstevel@tonic-gate 				} else {
2727c478bd9Sstevel@tonic-gate 					field = state;
2737c478bd9Sstevel@tonic-gate 					state = FAILURE;
2747c478bd9Sstevel@tonic-gate 				}
2757c478bd9Sstevel@tonic-gate 			}
2767c478bd9Sstevel@tonic-gate 		} /* end for loop */
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 		if (state == SUCCESS) {
2797c478bd9Sstevel@tonic-gate 			if (check_pmtab(gptr) == 0) {
280*3bb2c156SToomas Soome 				if (Nentries < Maxfds) {
2817c478bd9Sstevel@tonic-gate 					insert_pmtab(gptr);
282*3bb2c156SToomas Soome 				} else {
2837c478bd9Sstevel@tonic-gate 					log("can't add more entries to "
2847c478bd9Sstevel@tonic-gate 					    "pmtab, Maxfds = %d", Maxfds);
2857c478bd9Sstevel@tonic-gate 					free_pmtab(gptr);
286*3bb2c156SToomas Soome 					(void) fclose(fp);
2877c478bd9Sstevel@tonic-gate 					return;
2887c478bd9Sstevel@tonic-gate 				}
289*3bb2c156SToomas Soome 			} else {
2907c478bd9Sstevel@tonic-gate 				log("Parsing failure for entry: \n%s", line);
291*3bb2c156SToomas Soome 				log("----------------------------------------"
292*3bb2c156SToomas Soome 				    "---");
2937c478bd9Sstevel@tonic-gate 				free_pmtab(gptr);
2947c478bd9Sstevel@tonic-gate 			}
2957c478bd9Sstevel@tonic-gate 		} else {
2967c478bd9Sstevel@tonic-gate 			*++ptr = '\0';
2977c478bd9Sstevel@tonic-gate 			log("Parsing failure in the \"%s\" field,\n%s"
2987c478bd9Sstevel@tonic-gate 			    "<--error detected here", states[field], line);
2997c478bd9Sstevel@tonic-gate 			log("-------------------------------------------");
3007c478bd9Sstevel@tonic-gate 			free_pmtab(gptr);
3017c478bd9Sstevel@tonic-gate 		}
3027c478bd9Sstevel@tonic-gate 	} while (input == ACTIVE);
3037c478bd9Sstevel@tonic-gate 
304*3bb2c156SToomas Soome 	(void) fclose(fp);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate  * get_flags	- scan flags field to set U_FLAG and X_FLAG
3097c478bd9Sstevel@tonic-gate  */
3107c478bd9Sstevel@tonic-gate static	int
get_flags(char * wptr,long * flags)311*3bb2c156SToomas Soome get_flags(char *wptr, long *flags)
3127c478bd9Sstevel@tonic-gate {
313*3bb2c156SToomas Soome 	char	*p;
3147c478bd9Sstevel@tonic-gate 	for (p = wptr; *p; p++) {
3157c478bd9Sstevel@tonic-gate 		switch (*p) {
3167c478bd9Sstevel@tonic-gate 		case 'x':
3177c478bd9Sstevel@tonic-gate 			*flags |= X_FLAG;
3187c478bd9Sstevel@tonic-gate 			break;
3197c478bd9Sstevel@tonic-gate 		case 'u':
3207c478bd9Sstevel@tonic-gate 			*flags |= U_FLAG;
3217c478bd9Sstevel@tonic-gate 			break;
3227c478bd9Sstevel@tonic-gate 		default:
3237c478bd9Sstevel@tonic-gate 			log("Invalid flag -- %c", *p);
324*3bb2c156SToomas Soome 			return (-1);
325*3bb2c156SToomas Soome 		}
3267c478bd9Sstevel@tonic-gate 	}
327*3bb2c156SToomas Soome 	return (0);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate /*
3317c478bd9Sstevel@tonic-gate  * get_ttyflags	- scan ttyflags field to set corresponding flags
332*3bb2c156SToomas Soome  * char	*wptr		pointer to the input string
333*3bb2c156SToomas Soome  * long	*ttyflags	pointer to the flag to be set
3347c478bd9Sstevel@tonic-gate  */
3357c478bd9Sstevel@tonic-gate static	int
get_ttyflags(char * wptr,long * ttyflags)336*3bb2c156SToomas Soome get_ttyflags(char *wptr, long *ttyflags)
3377c478bd9Sstevel@tonic-gate {
338*3bb2c156SToomas Soome 	char	*p;
3397c478bd9Sstevel@tonic-gate 	for (p = wptr; *p; p++) {
3407c478bd9Sstevel@tonic-gate 		switch (*p) {
3417c478bd9Sstevel@tonic-gate 		case 'c':
3427c478bd9Sstevel@tonic-gate 			*ttyflags |= C_FLAG;
3437c478bd9Sstevel@tonic-gate 			break;
3447c478bd9Sstevel@tonic-gate 		case 'h': /* h means don't hangup */
3457c478bd9Sstevel@tonic-gate 			*ttyflags &= ~H_FLAG;
3467c478bd9Sstevel@tonic-gate 			break;
3477c478bd9Sstevel@tonic-gate 		case 'b':
3487c478bd9Sstevel@tonic-gate 			*ttyflags |= B_FLAG;
3497c478bd9Sstevel@tonic-gate 			break;
3507c478bd9Sstevel@tonic-gate 		case 'r':
3517c478bd9Sstevel@tonic-gate 			*ttyflags |= R_FLAG;
3527c478bd9Sstevel@tonic-gate 			break;
3537c478bd9Sstevel@tonic-gate 		case 'I':
3547c478bd9Sstevel@tonic-gate 			*ttyflags |= I_FLAG;
3557c478bd9Sstevel@tonic-gate 			break;
3567c478bd9Sstevel@tonic-gate 		default:
3577c478bd9Sstevel@tonic-gate 			log("Invalid ttyflag -- %c", *p);
358*3bb2c156SToomas Soome 			return (-1);
359*3bb2c156SToomas Soome 		}
3607c478bd9Sstevel@tonic-gate 	}
361*3bb2c156SToomas Soome 	return (0);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
364*3bb2c156SToomas Soome #ifdef DEBUG
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate  * pflags - put service flags into intelligible form for output
367*3bb2c156SToomas Soome  * long flags - binary representation of the flags
3687c478bd9Sstevel@tonic-gate  */
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate char *
pflags(long flags)371*3bb2c156SToomas Soome pflags(long flags)
3727c478bd9Sstevel@tonic-gate {
373*3bb2c156SToomas Soome 	int i;			/* scratch counter */
3747c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];	/* formatted flags */
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	if (flags == 0)
377*3bb2c156SToomas Soome 		return ("-");
3787c478bd9Sstevel@tonic-gate 	i = 0;
3797c478bd9Sstevel@tonic-gate 	if (flags & U_FLAG) {
3807c478bd9Sstevel@tonic-gate 		buf[i++] = 'u';
3817c478bd9Sstevel@tonic-gate 		flags &= ~U_FLAG;
3827c478bd9Sstevel@tonic-gate 	}
3837c478bd9Sstevel@tonic-gate 	if (flags & X_FLAG) {
3847c478bd9Sstevel@tonic-gate 		buf[i++] = 'x';
3857c478bd9Sstevel@tonic-gate 		flags &= ~X_FLAG;
3867c478bd9Sstevel@tonic-gate 	}
3877c478bd9Sstevel@tonic-gate 	if (flags)
3887c478bd9Sstevel@tonic-gate 		log("Internal error in pflags");
3897c478bd9Sstevel@tonic-gate 	buf[i] = '\0';
390*3bb2c156SToomas Soome 	return (buf);
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate /*
3947c478bd9Sstevel@tonic-gate  * pttyflags - put ttyflags into intelligible form for output
395*3bb2c156SToomas Soome  * long flags - binary representation of ttyflags
3967c478bd9Sstevel@tonic-gate  */
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate char *
pttyflags(long flags)399*3bb2c156SToomas Soome pttyflags(long flags)
4007c478bd9Sstevel@tonic-gate {
401*3bb2c156SToomas Soome 	int i;			/* scratch counter */
4027c478bd9Sstevel@tonic-gate 	static char buf[BUFSIZ];	/* formatted flags */
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	if (flags == 0)
405*3bb2c156SToomas Soome 		return ("h");
4067c478bd9Sstevel@tonic-gate 	i = 0;
4077c478bd9Sstevel@tonic-gate 	if (flags & C_FLAG) {
4087c478bd9Sstevel@tonic-gate 		buf[i++] = 'c';
4097c478bd9Sstevel@tonic-gate 		flags &= ~C_FLAG;
4107c478bd9Sstevel@tonic-gate 	}
411*3bb2c156SToomas Soome 	if (flags & H_FLAG)
4127c478bd9Sstevel@tonic-gate 		flags &= ~H_FLAG;
4137c478bd9Sstevel@tonic-gate 	else
4147c478bd9Sstevel@tonic-gate 		buf[i++] = 'h';
4157c478bd9Sstevel@tonic-gate 	if (flags & B_FLAG) {
4167c478bd9Sstevel@tonic-gate 		buf[i++] = 'b';
4177c478bd9Sstevel@tonic-gate 		flags &= ~B_FLAG;
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 	if (flags & R_FLAG) {
4207c478bd9Sstevel@tonic-gate 		buf[i++] = 'r';
4217c478bd9Sstevel@tonic-gate 		flags &= ~B_FLAG;
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 	if (flags & I_FLAG) {
4247c478bd9Sstevel@tonic-gate 		buf[i++] = 'I';
4257c478bd9Sstevel@tonic-gate 		flags &= ~I_FLAG;
4267c478bd9Sstevel@tonic-gate 	}
4277c478bd9Sstevel@tonic-gate 	if (flags)
4287c478bd9Sstevel@tonic-gate 		log("Internal error in p_ttyflags");
4297c478bd9Sstevel@tonic-gate 	buf[i] = '\0';
430*3bb2c156SToomas Soome 	return (buf);
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate void
dump_pmtab(void)434*3bb2c156SToomas Soome dump_pmtab(void)
4357c478bd9Sstevel@tonic-gate {
4367c478bd9Sstevel@tonic-gate 	struct	pmtab *gptr;
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	debug("in dump_pmtab");
4397c478bd9Sstevel@tonic-gate 	log("********** dumping pmtab **********");
4407c478bd9Sstevel@tonic-gate 	log(" ");
441*3bb2c156SToomas Soome 	for (gptr = PMtab; gptr != NULL; gptr = gptr->p_next) {
4427c478bd9Sstevel@tonic-gate 		log("-------------------------------------------");
4437c478bd9Sstevel@tonic-gate 		log("tag:\t\t%s", gptr->p_tag);
444*3bb2c156SToomas Soome 		log("flags:\t\t%s", pflags(gptr->p_flags));
4457c478bd9Sstevel@tonic-gate 		log("identity:\t%s", gptr->p_identity);
4467c478bd9Sstevel@tonic-gate 		log("reserved1:\t%s", gptr->p_res1);
4477c478bd9Sstevel@tonic-gate 		log("reserved2:\t%s", gptr->p_res2);
4487c478bd9Sstevel@tonic-gate 		log("reserved3:\t%s", gptr->p_res3);
4497c478bd9Sstevel@tonic-gate 		log("device:\t%s", gptr->p_device);
450*3bb2c156SToomas Soome 		log("ttyflags:\t%s", pttyflags(gptr->p_ttyflags));
4517c478bd9Sstevel@tonic-gate 		log("count:\t\t%d", gptr->p_count);
4527c478bd9Sstevel@tonic-gate 		log("server:\t%s", gptr->p_server);
4537c478bd9Sstevel@tonic-gate 		log("timeout:\t%d", gptr->p_timeout);
4547c478bd9Sstevel@tonic-gate 		log("ttylabel:\t%s", gptr->p_ttylabel);
4557c478bd9Sstevel@tonic-gate 		log("modules:\t%s", gptr->p_modules);
4567c478bd9Sstevel@tonic-gate 		log("prompt:\t%s", gptr->p_prompt);
4577c478bd9Sstevel@tonic-gate 		log("disable msg:\t%s", gptr->p_dmsg);
4587c478bd9Sstevel@tonic-gate 		log("terminal type:\t%s", gptr->p_termtype);
4597c478bd9Sstevel@tonic-gate 		log("soft-carrier:\t%s", gptr->p_softcar);
4607c478bd9Sstevel@tonic-gate 		log("status:\t\t%d", gptr->p_status);
4617c478bd9Sstevel@tonic-gate 		log("inservice:\t%d", gptr->p_inservice);
4627c478bd9Sstevel@tonic-gate 		log("fd:\t\t%d", gptr->p_fd);
463*3bb2c156SToomas Soome 		log("pid:\t\t%ld", gptr->p_childpid);
4647c478bd9Sstevel@tonic-gate 		log("uid:\t\t%ld", gptr->p_uid);
4657c478bd9Sstevel@tonic-gate 		log("gid:\t\t%ld", gptr->p_gid);
4667c478bd9Sstevel@tonic-gate 		log("dir:\t%s", gptr->p_dir);
4677c478bd9Sstevel@tonic-gate 		log(" ");
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 	log("********** end dumping pmtab **********");
4707c478bd9Sstevel@tonic-gate }
471*3bb2c156SToomas Soome #endif
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate /*
4747c478bd9Sstevel@tonic-gate  * same_entry(e1,e2) -    compare 2 entries of pmtab
4757c478bd9Sstevel@tonic-gate  *			if the fields are different, copy e2 to e1
476*3bb2c156SToomas Soome  *			return 1 if same, return 0 if different
4777c478bd9Sstevel@tonic-gate  */
4787c478bd9Sstevel@tonic-gate static	int
same_entry(struct pmtab * e1,struct pmtab * e2)479*3bb2c156SToomas Soome same_entry(struct pmtab	*e1, struct pmtab *e2)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_identity, e2->p_identity) != 0)
483*3bb2c156SToomas Soome 		return (0);
4847c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res1, e2->p_res1) != 0)
485*3bb2c156SToomas Soome 		return (0);
4867c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res2, e2->p_res2) != 0)
487*3bb2c156SToomas Soome 		return (0);
4887c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_res3, e2->p_res3) != 0)
489*3bb2c156SToomas Soome 		return (0);
4907c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_device, e2->p_device) != 0)
491*3bb2c156SToomas Soome 		return (0);
4927c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_server, e2->p_server) != 0)
493*3bb2c156SToomas Soome 		return (0);
4947c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_ttylabel, e2->p_ttylabel) != 0)
495*3bb2c156SToomas Soome 		return (0);
4967c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_modules, e2->p_modules) != 0)
497*3bb2c156SToomas Soome 		return (0);
4987c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_prompt, e2->p_prompt) != 0)
499*3bb2c156SToomas Soome 		return (0);
5007c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_dmsg, e2->p_dmsg) != 0)
501*3bb2c156SToomas Soome 		return (0);
5027c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_termtype, e2->p_termtype) != 0)
503*3bb2c156SToomas Soome 		return (0);
5047c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_softcar, e2->p_softcar) != 0)
505*3bb2c156SToomas Soome 		return (0);
5067c478bd9Sstevel@tonic-gate 	if (e1->p_flags != e2->p_flags)
507*3bb2c156SToomas Soome 		return (0);
5087c478bd9Sstevel@tonic-gate 	/*
509*3bb2c156SToomas Soome 	 * compare lowest 4 bits only,
5107c478bd9Sstevel@tonic-gate 	 * because A_FLAG is not part of original ttyflags
5117c478bd9Sstevel@tonic-gate 	 */
5127c478bd9Sstevel@tonic-gate 	if ((e1->p_ttyflags & ~A_FLAG) != (e2->p_ttyflags & ~A_FLAG))
513*3bb2c156SToomas Soome 		return (0);
5147c478bd9Sstevel@tonic-gate 	if (e1->p_count != e2->p_count)
515*3bb2c156SToomas Soome 		return (0);
5167c478bd9Sstevel@tonic-gate 	if (e1->p_timeout != e2->p_timeout)
517*3bb2c156SToomas Soome 		return (0);
5187c478bd9Sstevel@tonic-gate 	if (e1->p_uid != e2->p_uid)
519*3bb2c156SToomas Soome 		return (0);
5207c478bd9Sstevel@tonic-gate 	if (e1->p_gid != e2->p_gid)
521*3bb2c156SToomas Soome 		return (0);
5227c478bd9Sstevel@tonic-gate 	if (strcmp(e1->p_dir, e2->p_dir) != 0)
523*3bb2c156SToomas Soome 		return (0);
524*3bb2c156SToomas Soome 	return (1);
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate /*
5297c478bd9Sstevel@tonic-gate  * insert_pmtab - insert a pmtab entry into the linked list
5307c478bd9Sstevel@tonic-gate  */
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate static	void
insert_pmtab(struct pmtab * sp)533*3bb2c156SToomas Soome insert_pmtab(struct pmtab *sp)
5347c478bd9Sstevel@tonic-gate {
535*3bb2c156SToomas Soome 	struct pmtab *tsp, *savtsp;	/* scratch pointers */
5367c478bd9Sstevel@tonic-gate 	int ret;				/* strcmp return value */
5377c478bd9Sstevel@tonic-gate 
538*3bb2c156SToomas Soome #ifdef DEBUG
5397c478bd9Sstevel@tonic-gate 	debug("in insert_pmtab");
540*3bb2c156SToomas Soome #endif
5417c478bd9Sstevel@tonic-gate 	savtsp = tsp = PMtab;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  * find the correct place to insert this element
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	while (tsp) {
5487c478bd9Sstevel@tonic-gate 		ret = strcmp(sp->p_tag, tsp->p_tag);
5497c478bd9Sstevel@tonic-gate 		if (ret > 0) {
5507c478bd9Sstevel@tonic-gate 			/* keep on looking */
5517c478bd9Sstevel@tonic-gate 			savtsp = tsp;
5527c478bd9Sstevel@tonic-gate 			tsp = tsp->p_next;
5537c478bd9Sstevel@tonic-gate 			continue;
554*3bb2c156SToomas Soome 		} else if (ret == 0) {
5557c478bd9Sstevel@tonic-gate 			if (tsp->p_status) {
5567c478bd9Sstevel@tonic-gate 				/* this is a duplicate entry, ignore it */
5577c478bd9Sstevel@tonic-gate 				log("Ignoring duplicate entry for <%s>",
5587c478bd9Sstevel@tonic-gate 				    tsp->p_tag);
559*3bb2c156SToomas Soome 			} else {
560*3bb2c156SToomas Soome 				if (same_entry(tsp, sp)) {  /* same entry */
5617c478bd9Sstevel@tonic-gate 					tsp->p_status = VALID;
562*3bb2c156SToomas Soome 				} else {	/* entry changed */
563*3bb2c156SToomas Soome 					if ((sp->p_flags & X_FLAG) &&
564*3bb2c156SToomas Soome 					    ((sp->p_dmsg == NULL) ||
565*3bb2c156SToomas Soome 					    (*(sp->p_dmsg) == '\0'))) {
5667c478bd9Sstevel@tonic-gate 						/* disabled entry */
5677c478bd9Sstevel@tonic-gate 						tsp->p_status = NOTVALID;
568*3bb2c156SToomas Soome 					} else {
569*3bb2c156SToomas Soome #ifdef DEBUG
570*3bb2c156SToomas Soome 						debug("replacing <%s>",
571*3bb2c156SToomas Soome 						    sp->p_tag);
572*3bb2c156SToomas Soome #endif
5737c478bd9Sstevel@tonic-gate 						/* replace old entry */
5747c478bd9Sstevel@tonic-gate 						sp->p_next = tsp->p_next;
5757c478bd9Sstevel@tonic-gate 						if (tsp == PMtab) {
576*3bb2c156SToomas Soome 							PMtab = sp;
577*3bb2c156SToomas Soome 						} else {
578*3bb2c156SToomas Soome 							savtsp->p_next = sp;
5797c478bd9Sstevel@tonic-gate 						}
5807c478bd9Sstevel@tonic-gate 						sp->p_status = CHANGED;
5817c478bd9Sstevel@tonic-gate 						sp->p_fd = tsp->p_fd;
582*3bb2c156SToomas Soome 						sp->p_childpid =
583*3bb2c156SToomas Soome 						    tsp->p_childpid;
584*3bb2c156SToomas Soome 						sp->p_inservice =
585*3bb2c156SToomas Soome 						    tsp->p_inservice;
5867c478bd9Sstevel@tonic-gate 						sp = tsp;
5877c478bd9Sstevel@tonic-gate 					}
5887c478bd9Sstevel@tonic-gate 				}
5897c478bd9Sstevel@tonic-gate 				Nentries++;
5907c478bd9Sstevel@tonic-gate 			}
5917c478bd9Sstevel@tonic-gate 			free_pmtab(sp);
5927c478bd9Sstevel@tonic-gate 			return;
593*3bb2c156SToomas Soome 		} else {
594*3bb2c156SToomas Soome 			if ((sp->p_flags & X_FLAG) &&
595*3bb2c156SToomas Soome 			    ((sp->p_dmsg == NULL) ||
596*3bb2c156SToomas Soome 			    (*(sp->p_dmsg) == '\0'))) { /* disabled entry */
5977c478bd9Sstevel@tonic-gate 				free_pmtab(sp);
5987c478bd9Sstevel@tonic-gate 				return;
5997c478bd9Sstevel@tonic-gate 			}
6007c478bd9Sstevel@tonic-gate 			/*
6017c478bd9Sstevel@tonic-gate 			 * Set the state of soft-carrier.
6027c478bd9Sstevel@tonic-gate 			 * Since this is a one-time only operation,
6037c478bd9Sstevel@tonic-gate 			 * we do it when this service is added to
6047c478bd9Sstevel@tonic-gate 			 * the enabled list.
6057c478bd9Sstevel@tonic-gate 			 */
6067c478bd9Sstevel@tonic-gate 			if (*sp->p_softcar != '\0')
6077c478bd9Sstevel@tonic-gate 				set_softcar(sp);
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 			/* insert it here */
6107c478bd9Sstevel@tonic-gate 			if (tsp == PMtab) {
6117c478bd9Sstevel@tonic-gate 				sp->p_next = PMtab;
6127c478bd9Sstevel@tonic-gate 				PMtab = sp;
613*3bb2c156SToomas Soome 			} else {
6147c478bd9Sstevel@tonic-gate 				sp->p_next = savtsp->p_next;
6157c478bd9Sstevel@tonic-gate 				savtsp->p_next = sp;
6167c478bd9Sstevel@tonic-gate 			}
617*3bb2c156SToomas Soome #ifdef DEBUG
6187c478bd9Sstevel@tonic-gate 			debug("adding <%s>", sp->p_tag);
619*3bb2c156SToomas Soome #endif
6207c478bd9Sstevel@tonic-gate 			Nentries++;
6217c478bd9Sstevel@tonic-gate 			/* this entry is "current" */
6227c478bd9Sstevel@tonic-gate 			sp->p_status = VALID;
6237c478bd9Sstevel@tonic-gate 			return;
6247c478bd9Sstevel@tonic-gate 		}
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate /*
6287c478bd9Sstevel@tonic-gate  * either an empty list or should put element at end of list
6297c478bd9Sstevel@tonic-gate  */
6307c478bd9Sstevel@tonic-gate 
631*3bb2c156SToomas Soome 	if ((sp->p_flags & X_FLAG) &&
632*3bb2c156SToomas Soome 	    ((sp->p_dmsg == NULL) ||
633*3bb2c156SToomas Soome 	    (*(sp->p_dmsg) == '\0'))) { /* disabled entry */
6347c478bd9Sstevel@tonic-gate 		free_pmtab(sp);		 /* do not poll this entry */
6357c478bd9Sstevel@tonic-gate 		return;
6367c478bd9Sstevel@tonic-gate 	}
6377c478bd9Sstevel@tonic-gate 	/*
6387c478bd9Sstevel@tonic-gate 	 * Set the state of soft-carrier.
6397c478bd9Sstevel@tonic-gate 	 * Since this is a one-time only operation,
6407c478bd9Sstevel@tonic-gate 	 * we do it when this service is added to
6417c478bd9Sstevel@tonic-gate 	 * the enabled list.
6427c478bd9Sstevel@tonic-gate 	 */
6437c478bd9Sstevel@tonic-gate 	if (*sp->p_softcar != '\0')
6447c478bd9Sstevel@tonic-gate 		set_softcar(sp);
6457c478bd9Sstevel@tonic-gate 	sp->p_next = NULL;
6467c478bd9Sstevel@tonic-gate 	if (PMtab == NULL)
6477c478bd9Sstevel@tonic-gate 		PMtab = sp;
6487c478bd9Sstevel@tonic-gate 	else
6497c478bd9Sstevel@tonic-gate 		savtsp->p_next = sp;
650*3bb2c156SToomas Soome #ifdef DEBUG
6517c478bd9Sstevel@tonic-gate 	debug("adding <%s>", sp->p_tag);
652*3bb2c156SToomas Soome #endif
6537c478bd9Sstevel@tonic-gate 	++Nentries;
6547c478bd9Sstevel@tonic-gate 	/* this entry is "current" */
6557c478bd9Sstevel@tonic-gate 	sp->p_status = VALID;
6567c478bd9Sstevel@tonic-gate }
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate /*
6607c478bd9Sstevel@tonic-gate  * purge - purge linked list of "old" entries
6617c478bd9Sstevel@tonic-gate  */
6627c478bd9Sstevel@tonic-gate void
purge(void)663*3bb2c156SToomas Soome purge(void)
6647c478bd9Sstevel@tonic-gate {
665*3bb2c156SToomas Soome 	struct pmtab *sp;		/* working pointer */
666*3bb2c156SToomas Soome 	struct pmtab *savesp, *tsp;	/* scratch pointers */
6677c478bd9Sstevel@tonic-gate 
668*3bb2c156SToomas Soome #ifdef DEBUG
6697c478bd9Sstevel@tonic-gate 	debug("in purge");
670*3bb2c156SToomas Soome #endif
6717c478bd9Sstevel@tonic-gate 	sp = savesp = PMtab;
6727c478bd9Sstevel@tonic-gate 	while (sp) {
6737c478bd9Sstevel@tonic-gate 		if (sp->p_status) {
674*3bb2c156SToomas Soome #ifdef DEBUG
6757c478bd9Sstevel@tonic-gate 			debug("p_status not 0");
676*3bb2c156SToomas Soome #endif
6777c478bd9Sstevel@tonic-gate 			savesp = sp;
6787c478bd9Sstevel@tonic-gate 			sp = sp->p_next;
679*3bb2c156SToomas Soome 		} else {
6807c478bd9Sstevel@tonic-gate 			tsp = sp;
6817c478bd9Sstevel@tonic-gate 			if (tsp == PMtab) {
6827c478bd9Sstevel@tonic-gate 				PMtab = sp->p_next;
6837c478bd9Sstevel@tonic-gate 				savesp = PMtab;
684*3bb2c156SToomas Soome 			} else {
6857c478bd9Sstevel@tonic-gate 				savesp->p_next = sp->p_next;
686*3bb2c156SToomas Soome 			}
687*3bb2c156SToomas Soome #ifdef DEBUG
6887c478bd9Sstevel@tonic-gate 			debug("purging <%s>", sp->p_tag);
689*3bb2c156SToomas Soome #endif
6907c478bd9Sstevel@tonic-gate 			sp = sp->p_next;
6917c478bd9Sstevel@tonic-gate 			free_pmtab(tsp);
6927c478bd9Sstevel@tonic-gate 		}
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate }
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate /*
6977c478bd9Sstevel@tonic-gate  *	free_pmtab	- free one pmtab entry
6987c478bd9Sstevel@tonic-gate  */
6997c478bd9Sstevel@tonic-gate static	void
free_pmtab(struct pmtab * p)700*3bb2c156SToomas Soome free_pmtab(struct pmtab	*p)
7017c478bd9Sstevel@tonic-gate {
7027c478bd9Sstevel@tonic-gate #ifdef	DEBUG
7037c478bd9Sstevel@tonic-gate 	debug("in free_pmtab");
7047c478bd9Sstevel@tonic-gate #endif
7057c478bd9Sstevel@tonic-gate 	free(p->p_tag);
7067c478bd9Sstevel@tonic-gate 	free(p->p_identity);
7077c478bd9Sstevel@tonic-gate 	free(p->p_res1);
7087c478bd9Sstevel@tonic-gate 	free(p->p_res2);
7097c478bd9Sstevel@tonic-gate 	free(p->p_res3);
7107c478bd9Sstevel@tonic-gate 	free(p->p_device);
7117c478bd9Sstevel@tonic-gate 	free(p->p_server);
7127c478bd9Sstevel@tonic-gate 	free(p->p_ttylabel);
7137c478bd9Sstevel@tonic-gate 	free(p->p_modules);
7147c478bd9Sstevel@tonic-gate 	free(p->p_prompt);
7157c478bd9Sstevel@tonic-gate 	free(p->p_dmsg);
7167c478bd9Sstevel@tonic-gate 	free(p->p_termtype);
7177c478bd9Sstevel@tonic-gate 	free(p->p_softcar);
718*3bb2c156SToomas Soome 	free(p->p_dir);
7197c478bd9Sstevel@tonic-gate 	free(p);
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate /*
7237c478bd9Sstevel@tonic-gate  *	check_pmtab - check the fields to make sure things are correct
7247c478bd9Sstevel@tonic-gate  *		    - return 0 if everything is ok
7257c478bd9Sstevel@tonic-gate  *		    - return -1 if something is wrong
7267c478bd9Sstevel@tonic-gate  */
7277c478bd9Sstevel@tonic-gate static	int
check_pmtab(struct pmtab * p)728*3bb2c156SToomas Soome check_pmtab(struct pmtab *p)
7297c478bd9Sstevel@tonic-gate {
7307c478bd9Sstevel@tonic-gate 	if (p == NULL) {
7317c478bd9Sstevel@tonic-gate 		log("pmtab ptr is NULL");
732*3bb2c156SToomas Soome 		return (-1);
7337c478bd9Sstevel@tonic-gate 	}
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	/* check service tag */
7367c478bd9Sstevel@tonic-gate 	if ((p->p_tag == NULL) || (*(p->p_tag) == '\0')) {
7377c478bd9Sstevel@tonic-gate 		log("port/service tag is missing");
738*3bb2c156SToomas Soome 		return (-1);
7397c478bd9Sstevel@tonic-gate 	}
7407c478bd9Sstevel@tonic-gate 	if (strlen(p->p_tag) > (size_t)(MAXID - 1)) {
7417c478bd9Sstevel@tonic-gate 		log("port/service tag <%s> is longer than %d", p->p_tag,
7427c478bd9Sstevel@tonic-gate 		    MAXID-1);
743*3bb2c156SToomas Soome 		return (-1);
7447c478bd9Sstevel@tonic-gate 	}
7457c478bd9Sstevel@tonic-gate 	if (strcheck(p->p_tag, ALNUM) != 0) {
7467c478bd9Sstevel@tonic-gate 		log("port/service tag <%s> is not alphanumeric", p->p_tag);
747*3bb2c156SToomas Soome 		return (-1);
7487c478bd9Sstevel@tonic-gate 	}
7497c478bd9Sstevel@tonic-gate 	if (check_identity(p) != 0) {
750*3bb2c156SToomas Soome 		return (-1);
7517c478bd9Sstevel@tonic-gate 	}
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	if (check_device(p->p_device) != 0)
754*3bb2c156SToomas Soome 		return (-1);
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 	if (check_cmd(p->p_server) != 0)
757*3bb2c156SToomas Soome 		return (-1);
758*3bb2c156SToomas Soome 	return (0);
7597c478bd9Sstevel@tonic-gate }
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate /*
762*3bb2c156SToomas Soome  *	check_identity	- check to see if the identity is a valid user
763*3bb2c156SToomas Soome  *			- log name in the passwd file,
764*3bb2c156SToomas Soome  *			- and if its group id is a valid one
765*3bb2c156SToomas Soome  *			- return 0 if everything is ok. Otherwise, return -1
7667c478bd9Sstevel@tonic-gate  */
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate int
check_identity(struct pmtab * p)769*3bb2c156SToomas Soome check_identity(struct pmtab *p)
7707c478bd9Sstevel@tonic-gate {
771*3bb2c156SToomas Soome 	struct passwd *pwdp;
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	if ((p->p_identity == NULL) || (*(p->p_identity) == '\0')) {
7747c478bd9Sstevel@tonic-gate 		log("identity field is missing");
775*3bb2c156SToomas Soome 		return (-1);
7767c478bd9Sstevel@tonic-gate 	}
7777c478bd9Sstevel@tonic-gate 	if ((pwdp = getpwnam(p->p_identity)) == NULL) {
7787c478bd9Sstevel@tonic-gate 		log("missing or bad passwd entry for <%s>", p->p_identity);
7797c478bd9Sstevel@tonic-gate 		endpwent();
780*3bb2c156SToomas Soome 		return (-1);
7817c478bd9Sstevel@tonic-gate 	}
7827c478bd9Sstevel@tonic-gate 	if (getgrgid(pwdp->pw_gid) == NULL) {
7837c478bd9Sstevel@tonic-gate 		log("no group entry for %ld", pwdp->pw_gid);
7847c478bd9Sstevel@tonic-gate 		endgrent();
7857c478bd9Sstevel@tonic-gate 		endpwent();
786*3bb2c156SToomas Soome 		return (-1);
7877c478bd9Sstevel@tonic-gate 	}
7887c478bd9Sstevel@tonic-gate 	p->p_uid = pwdp->pw_uid;
7897c478bd9Sstevel@tonic-gate 	p->p_gid = pwdp->pw_gid;
7907c478bd9Sstevel@tonic-gate 	p->p_dir = strsave(pwdp->pw_dir);
7917c478bd9Sstevel@tonic-gate 	endgrent();
7927c478bd9Sstevel@tonic-gate 	endpwent();
793*3bb2c156SToomas Soome 	return (0);
7947c478bd9Sstevel@tonic-gate }
7957c478bd9Sstevel@tonic-gate 
7967c478bd9Sstevel@tonic-gate /*
7977c478bd9Sstevel@tonic-gate  * expand(cmdp, devp)	- expand %d to device name and %% to %,
7987c478bd9Sstevel@tonic-gate  *				- any other characters are untouched.
7997c478bd9Sstevel@tonic-gate  *				- return the expanded string
8007c478bd9Sstevel@tonic-gate  */
8017c478bd9Sstevel@tonic-gate static char	*
expand(char * cmdp,char * devp)802*3bb2c156SToomas Soome expand(char *cmdp, char *devp)
8037c478bd9Sstevel@tonic-gate {
804*3bb2c156SToomas Soome 	char	*cp, *dp, *np;
8057c478bd9Sstevel@tonic-gate 	static char	buf[BUFSIZ];
8067c478bd9Sstevel@tonic-gate 	cp = cmdp;
8077c478bd9Sstevel@tonic-gate 	np = buf;
8087c478bd9Sstevel@tonic-gate 	dp = devp;
8097c478bd9Sstevel@tonic-gate 	while (*cp) {
8107c478bd9Sstevel@tonic-gate 		if (*cp != '%') {
8117c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
8127c478bd9Sstevel@tonic-gate 			continue;
8137c478bd9Sstevel@tonic-gate 		}
8147c478bd9Sstevel@tonic-gate 		switch (*++cp) {
8157c478bd9Sstevel@tonic-gate 		case 'd':
8167c478bd9Sstevel@tonic-gate 			while (*dp) {
8177c478bd9Sstevel@tonic-gate 				*np++ = *dp++;
8187c478bd9Sstevel@tonic-gate 			}
8197c478bd9Sstevel@tonic-gate 			cp++;
8207c478bd9Sstevel@tonic-gate 			break;
8217c478bd9Sstevel@tonic-gate 		case '%':
8227c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
8237c478bd9Sstevel@tonic-gate 			break;
8247c478bd9Sstevel@tonic-gate 		default:
8257c478bd9Sstevel@tonic-gate 			*np++ = *cp++;
8267c478bd9Sstevel@tonic-gate 			break;
8277c478bd9Sstevel@tonic-gate 		}
8287c478bd9Sstevel@tonic-gate 	}
8297c478bd9Sstevel@tonic-gate 	*np = '\0';
830*3bb2c156SToomas Soome 	return (buf);
8317c478bd9Sstevel@tonic-gate }
832