869 lines
18 KiB
C
Executable File
869 lines
18 KiB
C
Executable File
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
|
/* All Rights Reserved */
|
|
|
|
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
|
/* The copyright notice above does not evidence any */
|
|
/* actual or intended publication of such source code. */
|
|
|
|
#ident "@(#)tmpmtab.c 1.9 95/05/15 SMI" /* SVr4.0 1.13 */
|
|
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <signal.h>
|
|
#include "ttymon.h"
|
|
#include "tmstruct.h"
|
|
#include "tmextern.h"
|
|
|
|
extern char *strsave();
|
|
extern void set_softcar();
|
|
extern int vml();
|
|
void purge();
|
|
static int get_flags();
|
|
static int get_ttyflags();
|
|
static int same_entry();
|
|
static int check_pmtab();
|
|
static void insert_pmtab();
|
|
static void free_pmtab();
|
|
static char *expand();
|
|
|
|
int check_identity();
|
|
|
|
int strcheck();
|
|
|
|
/*
|
|
* read_pmtab()
|
|
* - read and parse pmtab
|
|
* - store table in linked list pointed by global variable "PMtab"
|
|
* - exit if file does not exist or error detected.
|
|
*/
|
|
void
|
|
read_pmtab()
|
|
{
|
|
register struct pmtab *gptr;
|
|
register char *ptr, *wptr;
|
|
FILE *fp;
|
|
int input,state,size,rawc,field;
|
|
char oldc;
|
|
char line[BUFSIZ];
|
|
char wbuf[BUFSIZ];
|
|
static char *states[] = {
|
|
"","tag","flags","identity","reserved1","reserved2","reserved3",
|
|
"device","ttyflags","count","service", "timeout","ttylabel",
|
|
"modules","prompt","disable msg","terminal type","soft-carrier"
|
|
};
|
|
|
|
# ifdef DEBUG
|
|
debug("in read_pmtab");
|
|
# endif
|
|
|
|
if ((fp = fopen(PMTABFILE,"r")) == NULL) {
|
|
logexit(1, "open pmtab failed");
|
|
}
|
|
|
|
Nentries = 0;
|
|
if (check_version(PMTAB_VERS, PMTABFILE) != 0)
|
|
logexit(1,"check pmtab version failed");
|
|
|
|
for (gptr = PMtab; gptr; gptr = gptr->p_next) {
|
|
if ((gptr->p_status == SESSION) ||
|
|
(gptr->p_status == LOCKED) ||
|
|
(gptr->p_status == UNACCESS)) {
|
|
if (gptr->p_fd > 0) {
|
|
(void)close(gptr->p_fd);
|
|
gptr->p_fd = 0;
|
|
}
|
|
gptr->p_inservice = gptr->p_status;
|
|
}
|
|
gptr->p_status = NOTVALID;
|
|
}
|
|
|
|
wptr = wbuf;
|
|
input = ACTIVE;
|
|
do {
|
|
line[0] = '\0';
|
|
for (ptr= line,oldc = '\0'; ptr < &line[sizeof(line)-1] &&
|
|
(rawc=getc(fp))!= '\n' && rawc != EOF; ptr++,oldc=(char)rawc){
|
|
if ((rawc == '#') && (oldc != '\\'))
|
|
break;
|
|
*ptr = (char)rawc;
|
|
}
|
|
*ptr = '\0';
|
|
|
|
/* skip rest of the line */
|
|
if (rawc != EOF && rawc != '\n') {
|
|
if (rawc != '#')
|
|
log("Entry too long.\n");
|
|
while ((rawc = getc(fp)) != EOF && rawc != '\n')
|
|
;
|
|
}
|
|
|
|
if (rawc == EOF) {
|
|
if (ptr == line) break;
|
|
else input = FINISHED;
|
|
}
|
|
|
|
/* if empty line, skip */
|
|
for (ptr=line; *ptr != '\0' && isspace(*ptr); ptr++)
|
|
;
|
|
if (*ptr == '\0') continue;
|
|
|
|
#ifdef DEBUG
|
|
(void)sprintf(Scratch,"**** Next Entry ****\n%s",line);
|
|
debug(Scratch);
|
|
#endif
|
|
|
|
/* Now we have the complete line */
|
|
|
|
if ((gptr = ALLOC_PMTAB) == PNULL)
|
|
logexit(1,"memory allocation failed");
|
|
|
|
/* set hangup flag, this is the default */
|
|
gptr->p_ttyflags |= H_FLAG;
|
|
|
|
/*
|
|
* For compatibility reasons, we cannot rely on these
|
|
* having values assigned from pmtab.
|
|
*/
|
|
gptr->p_termtype = "";
|
|
gptr->p_softcar = "";
|
|
|
|
for (state=P_TAG,ptr=line;state !=FAILURE && state !=SUCCESS;) {
|
|
switch(state) {
|
|
case P_TAG:
|
|
gptr->p_tag = strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_FLAGS:
|
|
(void)strcpy(wptr, getword(ptr,&size,0));
|
|
if ((get_flags(wptr, &gptr->p_flags)) != 0) {
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
break;
|
|
case P_IDENTITY:
|
|
gptr->p_identity=strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_RES1:
|
|
gptr->p_res1=strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_RES2:
|
|
gptr->p_res2=strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_RES3:
|
|
gptr->p_res3=strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_DEVICE:
|
|
gptr->p_device = strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_TTYFLAGS:
|
|
(void)strcpy(wptr, getword(ptr,&size,0));
|
|
if ((get_ttyflags(wptr,&gptr->p_ttyflags))!=0) {
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
break;
|
|
case P_COUNT:
|
|
(void)strcpy(wptr, getword(ptr,&size,0));
|
|
if (strcheck(wptr, NUM) != 0) {
|
|
log("wait_read count must be a positive number");
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
else
|
|
gptr->p_count = atoi(wptr);
|
|
break;
|
|
case P_SERVER:
|
|
gptr->p_server =
|
|
strsave(expand(getword(ptr,&size,1),
|
|
gptr->p_device));
|
|
break;
|
|
case P_TIMEOUT:
|
|
(void)strcpy(wptr, getword(ptr,&size,0));
|
|
if (strcheck(wptr, NUM) != 0) {
|
|
log("timeout value must be a positive number");
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
else
|
|
gptr->p_timeout = atoi(wptr);
|
|
break;
|
|
case P_TTYLABEL:
|
|
gptr->p_ttylabel=strsave(getword(ptr,&size,0));
|
|
break;
|
|
case P_MODULES:
|
|
gptr->p_modules = strsave(getword(ptr,&size,0));
|
|
if (vml(gptr->p_modules) != 0) {
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
break;
|
|
case P_PROMPT:
|
|
gptr->p_prompt = strsave(getword(ptr,&size,TRUE));
|
|
break;
|
|
case P_DMSG:
|
|
gptr->p_dmsg = strsave(getword(ptr,&size,TRUE));
|
|
break;
|
|
|
|
case P_TERMTYPE:
|
|
gptr->p_termtype = strsave(getword(ptr,&size,TRUE));
|
|
break;
|
|
|
|
case P_SOFTCAR:
|
|
gptr->p_softcar = strsave(getword(ptr,&size,TRUE));
|
|
break;
|
|
|
|
} /* end switch */
|
|
ptr += size;
|
|
if (state == FAILURE)
|
|
break;
|
|
if (*ptr == ':') {
|
|
ptr++; /* Skip the ':' */
|
|
state++ ;
|
|
} else if (*ptr != '\0') {
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
if (*ptr == '\0') {
|
|
log("*ptr == 0");
|
|
/*
|
|
* Maintain compatibility with older ttymon pmtab
|
|
* files. If Sun-added fields are missing, this
|
|
* should not be an error.
|
|
*/
|
|
if (state > P_DMSG) {
|
|
log("SUCCESS");
|
|
state = SUCCESS;
|
|
} else {
|
|
log("FAILURE");
|
|
field = state;
|
|
state = FAILURE;
|
|
}
|
|
}
|
|
} /* end for loop */
|
|
|
|
if (state == SUCCESS) {
|
|
if (check_pmtab(gptr) == 0) {
|
|
if (Nentries < Maxfds)
|
|
insert_pmtab(gptr);
|
|
else {
|
|
(void)sprintf(Scratch,
|
|
"can't add more entries to pmtab, Maxfds = %d", Maxfds);
|
|
log(Scratch);
|
|
free_pmtab(gptr);
|
|
(void)fclose(fp);
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
(void)sprintf(Scratch,
|
|
"Parsing failure for entry: \n%s",line);
|
|
log(Scratch);
|
|
log("-------------------------------------------");
|
|
free_pmtab(gptr);
|
|
}
|
|
} else {
|
|
*++ptr = '\0';
|
|
(void)sprintf(Scratch,
|
|
"Parsing failure in the \"%s\" field,\n%s<--error detected here", states[field],line);
|
|
log(Scratch);
|
|
log("-------------------------------------------");
|
|
free_pmtab(gptr);
|
|
}
|
|
} while (input == ACTIVE);
|
|
|
|
(void)fclose(fp);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* get_flags - scan flags field to set U_FLAG and X_FLAG
|
|
*/
|
|
static int
|
|
get_flags(wptr, flags)
|
|
char *wptr; /* pointer to the input string */
|
|
long *flags; /* pointer to the flag to set */
|
|
{
|
|
register char *p;
|
|
for (p = wptr; *p; p++) {
|
|
switch (*p) {
|
|
case 'x':
|
|
*flags |= X_FLAG;
|
|
break;
|
|
case 'u':
|
|
*flags |= U_FLAG;
|
|
break;
|
|
default:
|
|
(void)sprintf(Scratch,"Invalid flag -- %c", *p);
|
|
log(Scratch);
|
|
return(-1);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* get_ttyflags - scan ttyflags field to set corresponding flags
|
|
*/
|
|
static int
|
|
get_ttyflags(wptr, ttyflags)
|
|
char *wptr; /* pointer to the input string */
|
|
long *ttyflags; /* pointer to the flag to be set*/
|
|
{
|
|
register char *p;
|
|
for (p = wptr; *p; p++) {
|
|
switch (*p) {
|
|
case 'c':
|
|
*ttyflags |= C_FLAG;
|
|
break;
|
|
case 'h': /* h means don't hangup */
|
|
*ttyflags &= ~H_FLAG;
|
|
break;
|
|
case 'b':
|
|
*ttyflags |= B_FLAG;
|
|
break;
|
|
case 'r':
|
|
*ttyflags |= R_FLAG;
|
|
break;
|
|
case 'I':
|
|
*ttyflags |= I_FLAG;
|
|
break;
|
|
default:
|
|
(void)sprintf(Scratch,"Invalid ttyflag -- %c", *p);
|
|
log(Scratch);
|
|
return(-1);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
# ifdef DEBUG
|
|
/*
|
|
* pflags - put service flags into intelligible form for output
|
|
*/
|
|
|
|
char *
|
|
pflags(flags)
|
|
long flags; /* binary representation of the flags */
|
|
{
|
|
register int i; /* scratch counter */
|
|
static char buf[BUFSIZ]; /* formatted flags */
|
|
|
|
if (flags == 0)
|
|
return("-");
|
|
i = 0;
|
|
if (flags & U_FLAG) {
|
|
buf[i++] = 'u';
|
|
flags &= ~U_FLAG;
|
|
}
|
|
if (flags & X_FLAG) {
|
|
buf[i++] = 'x';
|
|
flags &= ~X_FLAG;
|
|
}
|
|
if (flags)
|
|
log("Internal error in pflags");
|
|
buf[i] = '\0';
|
|
return(buf);
|
|
}
|
|
|
|
/*
|
|
* pttyflags - put ttyflags into intelligible form for output
|
|
*/
|
|
|
|
char *
|
|
pttyflags(flags)
|
|
long flags; /* binary representation of ttyflags */
|
|
{
|
|
register int i; /* scratch counter */
|
|
static char buf[BUFSIZ]; /* formatted flags */
|
|
|
|
if (flags == 0)
|
|
return("h");
|
|
i = 0;
|
|
if (flags & C_FLAG) {
|
|
buf[i++] = 'c';
|
|
flags &= ~C_FLAG;
|
|
}
|
|
if (flags & H_FLAG)
|
|
flags &= ~H_FLAG;
|
|
else
|
|
buf[i++] = 'h';
|
|
if (flags & B_FLAG) {
|
|
buf[i++] = 'b';
|
|
flags &= ~B_FLAG;
|
|
}
|
|
if (flags & R_FLAG) {
|
|
buf[i++] = 'r';
|
|
flags &= ~B_FLAG;
|
|
}
|
|
if (flags & I_FLAG) {
|
|
buf[i++] = 'I';
|
|
flags &= ~I_FLAG;
|
|
}
|
|
if (flags)
|
|
log("Internal error in p_ttyflags");
|
|
buf[i] = '\0';
|
|
return(buf);
|
|
}
|
|
|
|
void
|
|
dump_pmtab()
|
|
{
|
|
struct pmtab *gptr;
|
|
|
|
debug("in dump_pmtab");
|
|
log("********** dumping pmtab **********");
|
|
log(" ");
|
|
for (gptr=PMtab; gptr; gptr = gptr->p_next) {
|
|
log("-------------------------------------------");
|
|
(void)sprintf(Scratch,"tag:\t\t%s",gptr->p_tag);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"flags:\t\t%s",pflags(gptr->p_flags));
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"identity:\t%s",gptr->p_identity);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"reserved1:\t%s",gptr->p_res1);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"reserved2:\t%s",gptr->p_res2);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"reserved3:\t%s",gptr->p_res3);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"device:\t%s",gptr->p_device);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"ttyflags:\t%s",pttyflags(gptr->p_ttyflags));
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"count:\t\t%d",gptr->p_count);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"server:\t%s",gptr->p_server);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"timeout:\t%d",gptr->p_timeout);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"ttylabel:\t%s",gptr->p_ttylabel);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"modules:\t%s",gptr->p_modules);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"prompt:\t%s",gptr->p_prompt);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"disable msg:\t%s",gptr->p_dmsg);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"terminal type:\t%s",gptr->p_termtype);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"soft-carrier:\t%s",gptr->p_softcar);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"status:\t\t%d",gptr->p_status);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"inservice:\t%d",gptr->p_inservice);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"fd:\t\t%d",gptr->p_fd);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"pid:\t\t%ld",gptr->p_pid);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"uid:\t\t%ld",gptr->p_uid);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"gid:\t\t%ld",gptr->p_gid);
|
|
log(Scratch);
|
|
(void)sprintf(Scratch,"dir:\t%s",gptr->p_dir);
|
|
log(Scratch);
|
|
log(" ");
|
|
}
|
|
log("********** end dumping pmtab **********");
|
|
}
|
|
# endif
|
|
|
|
/*
|
|
* same_entry(e1,e2) - compare 2 entries of pmtab
|
|
* if the fields are different, copy e2 to e1
|
|
* return 1 if same, return 0 if different
|
|
*/
|
|
static int
|
|
same_entry(e1,e2)
|
|
struct pmtab *e1,*e2;
|
|
{
|
|
|
|
if (strcmp(e1->p_identity, e2->p_identity) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_res1, e2->p_res1) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_res2, e2->p_res2) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_res3, e2->p_res3) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_device, e2->p_device) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_server, e2->p_server) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_ttylabel, e2->p_ttylabel) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_modules, e2->p_modules) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_prompt, e2->p_prompt) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_dmsg, e2->p_dmsg) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_termtype, e2->p_termtype) != 0)
|
|
return(0);
|
|
if (strcmp(e1->p_softcar, e2->p_softcar) != 0)
|
|
return(0);
|
|
if (e1->p_flags != e2->p_flags)
|
|
return(0);
|
|
/*
|
|
* compare lowest 4 bits only,
|
|
* because A_FLAG is not part of original ttyflags
|
|
*/
|
|
if ((e1->p_ttyflags & ~A_FLAG) != (e2->p_ttyflags & ~A_FLAG))
|
|
return(0);
|
|
if (e1->p_count != e2->p_count)
|
|
return(0);
|
|
if (e1->p_timeout != e2->p_timeout)
|
|
return(0);
|
|
if (e1->p_uid != e2->p_uid)
|
|
return(0);
|
|
if (e1->p_gid != e2->p_gid)
|
|
return(0);
|
|
if (strcmp(e1->p_dir, e2->p_dir) != 0)
|
|
return(0);
|
|
return(1);
|
|
}
|
|
|
|
|
|
/*
|
|
* insert_pmtab - insert a pmtab entry into the linked list
|
|
*/
|
|
|
|
static void
|
|
insert_pmtab(sp)
|
|
register struct pmtab *sp; /* ptr to entry to be inserted */
|
|
{
|
|
register struct pmtab *tsp, *savtsp; /* scratch pointers */
|
|
int ret; /* strcmp return value */
|
|
|
|
# ifdef DEBUG
|
|
debug("in insert_pmtab");
|
|
# endif
|
|
savtsp = tsp = PMtab;
|
|
|
|
/*
|
|
* find the correct place to insert this element
|
|
*/
|
|
|
|
while (tsp) {
|
|
ret = strcmp(sp->p_tag, tsp->p_tag);
|
|
if (ret > 0) {
|
|
/* keep on looking */
|
|
savtsp = tsp;
|
|
tsp = tsp->p_next;
|
|
continue;
|
|
}
|
|
else if (ret == 0) {
|
|
if (tsp->p_status) {
|
|
/* this is a duplicate entry, ignore it */
|
|
(void) sprintf(Scratch, "Ignoring duplicate entry for <%s>", tsp->p_tag);
|
|
log(Scratch);
|
|
}
|
|
else {
|
|
if (same_entry(tsp,sp)) { /* same entry */
|
|
tsp->p_status = VALID;
|
|
}
|
|
else { /* entry changed */
|
|
if ((sp->p_flags & X_FLAG) &&
|
|
((sp->p_dmsg == NULL) ||
|
|
(*(sp->p_dmsg) == '\0'))) {
|
|
/* disabled entry */
|
|
tsp->p_status = NOTVALID;
|
|
}
|
|
else {
|
|
# ifdef DEBUG
|
|
(void)sprintf(Scratch, "replacing <%s>", sp->p_tag);
|
|
debug(Scratch);
|
|
# endif
|
|
/* replace old entry */
|
|
sp->p_next = tsp->p_next;
|
|
if (tsp == PMtab) {
|
|
PMtab = sp;
|
|
}
|
|
else {
|
|
savtsp->p_next = sp;
|
|
}
|
|
sp->p_status = CHANGED;
|
|
sp->p_fd = tsp->p_fd;
|
|
sp->p_pid = tsp->p_pid;
|
|
sp->p_inservice =
|
|
tsp->p_inservice;
|
|
sp = tsp;
|
|
}
|
|
}
|
|
Nentries++;
|
|
}
|
|
free_pmtab(sp);
|
|
return;
|
|
}
|
|
else {
|
|
if ((sp->p_flags & X_FLAG) &&
|
|
((sp->p_dmsg == NULL) ||
|
|
(*(sp->p_dmsg) == '\0'))) { /* disabled entry */
|
|
free_pmtab(sp);
|
|
return;
|
|
}
|
|
/*
|
|
* Set the state of soft-carrier.
|
|
* Since this is a one-time only operation,
|
|
* we do it when this service is added to
|
|
* the enabled list.
|
|
*/
|
|
if (*sp->p_softcar != '\0')
|
|
set_softcar(sp);
|
|
|
|
/* insert it here */
|
|
if (tsp == PMtab) {
|
|
sp->p_next = PMtab;
|
|
PMtab = sp;
|
|
}
|
|
else {
|
|
sp->p_next = savtsp->p_next;
|
|
savtsp->p_next = sp;
|
|
}
|
|
# ifdef DEBUG
|
|
(void) sprintf(Scratch, "adding <%s>", sp->p_tag);
|
|
debug(Scratch);
|
|
# endif
|
|
Nentries++;
|
|
/* this entry is "current" */
|
|
sp->p_status = VALID;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* either an empty list or should put element at end of list
|
|
*/
|
|
|
|
if ((sp->p_flags & X_FLAG) &&
|
|
((sp->p_dmsg == NULL) ||
|
|
(*(sp->p_dmsg) == '\0'))) { /* disabled entry */
|
|
free_pmtab(sp); /* do not poll this entry */
|
|
return;
|
|
}
|
|
/*
|
|
* Set the state of soft-carrier.
|
|
* Since this is a one-time only operation,
|
|
* we do it when this service is added to
|
|
* the enabled list.
|
|
*/
|
|
if (*sp->p_softcar != '\0')
|
|
set_softcar(sp);
|
|
sp->p_next = NULL;
|
|
if (PMtab == NULL)
|
|
PMtab = sp;
|
|
else
|
|
savtsp->p_next = sp;
|
|
# ifdef DEBUG
|
|
(void) sprintf(Scratch, "adding <%s>", sp->p_tag);
|
|
debug(Scratch);
|
|
# endif
|
|
++Nentries;
|
|
/* this entry is "current" */
|
|
sp->p_status = VALID;
|
|
}
|
|
|
|
|
|
/*
|
|
* purge - purge linked list of "old" entries
|
|
*/
|
|
|
|
|
|
void
|
|
purge()
|
|
{
|
|
register struct pmtab *sp; /* working pointer */
|
|
register struct pmtab *savesp, *tsp; /* scratch pointers */
|
|
|
|
# ifdef DEBUG
|
|
debug("in purge");
|
|
# endif
|
|
sp = savesp = PMtab;
|
|
while (sp) {
|
|
if (sp->p_status) {
|
|
# ifdef DEBUG
|
|
debug("p_status not 0");
|
|
# endif
|
|
savesp = sp;
|
|
sp = sp->p_next;
|
|
}
|
|
else {
|
|
tsp = sp;
|
|
if (tsp == PMtab) {
|
|
PMtab = sp->p_next;
|
|
savesp = PMtab;
|
|
}
|
|
else
|
|
savesp->p_next = sp->p_next;
|
|
# ifdef DEBUG
|
|
(void) sprintf(Scratch, "purging <%s>", sp->p_tag);
|
|
debug(Scratch);
|
|
# endif
|
|
sp = sp->p_next;
|
|
free_pmtab(tsp);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* free_pmtab - free one pmtab entry
|
|
*/
|
|
static void
|
|
free_pmtab(p)
|
|
struct pmtab *p;
|
|
{
|
|
#ifdef DEBUG
|
|
debug("in free_pmtab");
|
|
#endif
|
|
free(p->p_tag);
|
|
free(p->p_identity);
|
|
free(p->p_res1);
|
|
free(p->p_res2);
|
|
free(p->p_res3);
|
|
free(p->p_device);
|
|
free(p->p_server);
|
|
free(p->p_ttylabel);
|
|
free(p->p_modules);
|
|
free(p->p_prompt);
|
|
free(p->p_dmsg);
|
|
free(p->p_termtype);
|
|
free(p->p_softcar);
|
|
if (p->p_dir)
|
|
free(p->p_dir);
|
|
free(p);
|
|
}
|
|
|
|
/*
|
|
* check_pmtab - check the fields to make sure things are correct
|
|
* - return 0 if everything is ok
|
|
* - return -1 if something is wrong
|
|
*/
|
|
|
|
static int
|
|
check_pmtab(p)
|
|
struct pmtab *p;
|
|
{
|
|
if (p == NULL) {
|
|
log("pmtab ptr is NULL");
|
|
return(-1);
|
|
}
|
|
|
|
/* check service tag */
|
|
if ((p->p_tag == NULL) || (*(p->p_tag) == '\0')) {
|
|
log("port/service tag is missing");
|
|
return(-1);
|
|
}
|
|
if (strlen(p->p_tag) > (size_t)(MAXID - 1)) {
|
|
(void)sprintf(Scratch,"port/service tag <%s> is longer than %d",
|
|
p->p_tag, MAXID-1);
|
|
log(Scratch);
|
|
return(-1);
|
|
}
|
|
if (strcheck(p->p_tag, ALNUM) != 0) {
|
|
(void)sprintf(Scratch,
|
|
"port/service tag <%s> is not alphanumeric", p->p_tag);
|
|
log(Scratch);
|
|
return(-1);
|
|
}
|
|
if (check_identity(p) != 0) {
|
|
return(-1);
|
|
}
|
|
|
|
if (check_device(p->p_device) != 0)
|
|
return(-1);
|
|
|
|
if (check_cmd(p->p_server) != 0)
|
|
return(-1);
|
|
return(0);
|
|
}
|
|
|
|
extern struct passwd *getpwnam();
|
|
extern void endpwent();
|
|
extern struct group *getgrgid();
|
|
extern void endgrent();
|
|
|
|
/*
|
|
* check_identity - check to see if the identity is a valid user
|
|
* - log name in the passwd file,
|
|
* - and if its group id is a valid one
|
|
* - return 0 if everything is ok. Otherwise, return -1
|
|
*/
|
|
|
|
int
|
|
check_identity(p)
|
|
struct pmtab *p;
|
|
{
|
|
register struct passwd *pwdp;
|
|
|
|
if ((p->p_identity == NULL) || (*(p->p_identity) == '\0')) {
|
|
log("identity field is missing");
|
|
return(-1);
|
|
}
|
|
if ((pwdp = getpwnam(p->p_identity)) == NULL) {
|
|
(void)sprintf(Scratch, "missing or bad passwd entry for <%s>",
|
|
p->p_identity);
|
|
log(Scratch);
|
|
endpwent();
|
|
return(-1);
|
|
}
|
|
if (getgrgid(pwdp->pw_gid) == NULL) {
|
|
(void)sprintf(Scratch, "no group entry for %ld", pwdp->pw_gid);
|
|
log(Scratch);
|
|
endgrent();
|
|
endpwent();
|
|
return(-1);
|
|
}
|
|
p->p_uid = pwdp->pw_uid;
|
|
p->p_gid = pwdp->pw_gid;
|
|
p->p_dir = strsave(pwdp->pw_dir);
|
|
endgrent();
|
|
endpwent();
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* expand(cmdp, devp) - expand %d to device name and %% to %,
|
|
* - any other characters are untouched.
|
|
* - return the expanded string
|
|
*/
|
|
static char *
|
|
expand(cmdp,devp)
|
|
char *cmdp; /* ptr to cmd string */
|
|
char *devp; /* ptr to device name */
|
|
{
|
|
register char *cp, *dp, *np;
|
|
static char buf[BUFSIZ];
|
|
cp = cmdp;
|
|
np = buf;
|
|
dp = devp;
|
|
while (*cp) {
|
|
if (*cp != '%') {
|
|
*np++ = *cp++;
|
|
continue;
|
|
}
|
|
switch (*++cp) {
|
|
case 'd':
|
|
while (*dp) {
|
|
*np++ = *dp++;
|
|
}
|
|
cp++;
|
|
break;
|
|
case '%':
|
|
*np++ = *cp++;
|
|
break;
|
|
default:
|
|
*np++ = *cp++;
|
|
break;
|
|
}
|
|
}
|
|
*np = '\0';
|
|
return(buf);
|
|
}
|
|
|