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