home *** CD-ROM | disk | FTP | other *** search
- /*
- * conf.c -- read run time configuration file for finger
- *
- * Copyright (C) 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- /* TODO:
- * implement options and route
- * do ttylocs from here? (nah, hardle needs them)
- */
-
- /*
- * The idea for formatting phone numbers comes from
- * Michael Thompson <thompson@dalcs.UUCP> Dalhousie University,
- * Halifax, NS in comp.bugs.4bsd on Sept 25, 1987
- * "BSD4.3 finger is Berkley dependent. +FIX"
- */
-
- # ifndef lint
- static char *rcsid = "$Id: conf.c,v 3.0 90/07/06 13:10:27 budd Rel $";
- # endif /* lint not defined */
-
- # include <stdio.h>
- # include <strings.h>
- # include <ctype.h>
- # include <pwd.h>
- # include <grp.h>
- # include "person.h"
- # include "finger.h"
- # include "args.h" /* sw_debug */
-
- # define CONF "finger.conf"
- # define NUMBER '#'
- # define COMMENT '!'
-
- LOCAL int initialized = FALSE;
- LOCAL char *confdirs[] = {
- # ifdef CONFDIRS
- CONFDIRS,
- # endif /* CONFDIRS defined */
- "/etc",
- "/usr/local/etc",
- "/usr/etc",
- ".", /* for debugging.. move to first? */
- NULL
- };
-
- # define NBUILDINGS 10 /* UGH! */
- LOCAL struct building {
- char code;
- char *name;
- } buildings[NBUILDINGS];
- LOCAL int nbuildings = 0;
-
- # define NACCTS 32 /* UGH! */
- LOCAL struct acct {
- unsigned short min, max;
- char group, *name;
- } accts[NACCTS];
- LOCAL int naccts = 0;
-
- # define NPHONES 32 /* UGH! */
- LOCAL struct phone {
- int splats;
- char *pat;
- } phones[NPHONES];
- LOCAL int nphones = 0;
-
- # define NHIDDEN 32 /* UGH! */
- char *hidden[NHIDDEN];
- LOCAL int nhidden = 0;
-
- # define NPREFIX 32 /* UGH! */
- char *prefix[NPREFIX];
- LOCAL int nprefixes = 0;
-
- GLOBAL BOOL
- read_conf() {
- FILE *f;
- char **dp;
- char buf[ 512 ];
- enum { START, ACCT, BUILDING, HIDDEN, OPT, PHONE, PREFIX, ROUTE } state;
-
- if( initialized )
- return( TRUE );
- initialized = TRUE;
-
- /* read env variable for path(s)? */
-
- for( dp = confdirs, f = NULL; f == NULL && *dp != NULL; dp++ ) {
- sprintf( buf, "%s/%s", *dp, CONF );
- f = fopen( buf, "r" );
- }
- if( f == NULL )
- return( FALSE );
-
- if( sw_debug )
- printf("%s:\n", buf );
-
- state = START;
- if( fgets( buf, sizeof( buf ), f ) == NULL ) {
- fclose( f );
- return( FALSE );
- }
-
- do { /* ...while fgets */
- char *cp;
-
- switch( buf[0] ) {
- case '%':
- /* use perfect hashing? */
- # define PAIR(a,b) (a)<<7|(b)
- switch( PAIR(buf[1],buf[2]) ) {
- case PAIR('a','c'):
- state = ACCT;
- break;
- case PAIR('b','u'):
- state = BUILDING;
- break;
- case PAIR('h','i'):
- state = HIDDEN;
- break;
- case PAIR('o','p'):
- state = OPT;
- break;
- case PAIR('p','h'):
- state = PHONE;
- break;
- case PAIR('p','r'):
- state = PREFIX;
- break;
- case PAIR('r','o'):
- state = ROUTE;
- break;
- default:
- state = START;
- break;
- }
- /* fall */
- case COMMENT:
- /* # is used in phones */
- continue;
- } /* switch on buf[0] */
-
- cp = index( buf, '\n' );
- if( cp != NULL )
- *cp = EOS;
-
- switch( state ) {
- case START:
- break;
-
- case ACCT:
- if( naccts < NACCTS ) {
- char temp[ 128 ], *tp; /* FIXME */
- BOOL lit, name, hyp;
- int min, max, grp;
- struct passwd *pw;
- struct group *gr;
-
- name = FALSE; /* no letters */
- lit = FALSE; /* no litteral next */
- tp = temp; /* output buffer */
- for( cp = buf; *cp; cp++ ) {
- if( *cp == '\\' ) {
- lit = name = TRUE; /* quote next, interpret as name */
- continue;
- }
- if( isspace(*cp) && !lit )
- break;
- if( !isdigit(*cp) )
- name = TRUE;
- *tp++ = *cp;
- lit = FALSE;
- }
- *tp = EOS; /* tie off string */
- if( tp == temp || *cp == EOS ) /* empty string, or EOS? */
- break; /* must have two fields */
-
- hyp = (*cp == '-'); /* unquoted hypen means a range */
- if( !name )
- min = atoi( temp );
- else if( (gr = getgrnam( temp )) != NULL )
- min = gr->gr_gid;
- else if( (pw = getpwnam( temp )) != NULL )
- min = pw->pw_uid;
- else
- break;
-
- if( hyp ) {
- tp = temp;
- name = lit = FALSE;
- for( ; *cp ; cp++ ) {
- if( *cp == '\\' ) {
- /* quote next, interpret as name */
- lit = name = TRUE;
- continue;
- }
- if( isspace(*cp) && !lit )
- break;
- if( !isdigit(*cp) )
- name = TRUE;
-
- *tp++ = *cp;
- lit = FALSE;
- }
- if( tp == temp || *cp == EOS )
- break;
- *tp = EOS;
- if( !name )
- max = atoi( temp );
- else if( (gr = getgrnam( temp )) != NULL )
- max = gr->gr_gid;
- else if( (pw = getpwnam( temp )) != NULL )
- max = pw->pw_uid;
- else
- break;
- }
- else
- max = min;
-
- if( !skipwhite(&cp) )
- break;
- grp = *cp++;
- skipwhite(&cp);
-
- accts[naccts].min = min;
- accts[naccts].max = max;
- accts[naccts].group = grp;
- accts[naccts].name = savestr( cp );
- naccts++;
- if( sw_debug )
- printf("acct: %d-%d %c %s\n", min, max, grp, cp );
- }
- break;
-
- case BUILDING:
- if( nbuildings < NBUILDINGS ) {
- cp = buf+1;
- if( skipwhite(&cp) ) {
- buildings[nbuildings].code = buf[0];
- buildings[nbuildings].name = savestr( cp );
- nbuildings++;
- if( sw_debug )
- printf("bldg: %c %s\n", buf[0], cp );
- }
- }
- break;
-
- case OPT:
- /* options to set; ie; sw_berkeley, sw_its */
- break;
-
- case PHONE:
- if( nphones < NPHONES ) {
- int splats;
-
- splats = 0;
- for( cp = buf; *cp; cp++ )
- if( *cp == NUMBER )
- splats++;
- if( splats > 0 ) {
- phones[nphones].splats = splats;
- phones[nphones].pat = savestr( buf );
- nphones++;
- if( sw_debug )
- printf("phone: %d %s\n", splats, buf );
- }
- }
- break;
-
- case HIDDEN:
- if( nhidden < NHIDDEN ) {
- hidden[nhidden] = savestr( buf );
- nhidden++;
- if( sw_debug )
- printf("hidden: %s\n", buf );
- }
- break;
-
- case PREFIX:
- if( nprefixes < NPREFIX ) {
- prefix[nprefixes] = savestr( buf );
- nprefixes++;
- if( sw_debug )
- printf("prefix: %s\n", buf );
- }
- break;
-
- case ROUTE:
- break;
-
- } /* state switch */
- } while( fgets( buf, sizeof( buf ), f ) != NULL );
- if( sw_debug )
- printf("\
- conf: %d accts, %d buildings, %d hidden, %d phones, %d prefixes\n",
- naccts, nbuildings, nhidden, nphones, nprefixes );
- return( TRUE );
- } /* read_conf */
-
- /*
- * routines called from outside...
- */
-
- GLOBAL int ishidden( str )
- char *str;
- {
- register int i;
-
- for( i = 0; i < nhidden; i++ )
- if( strcmp( str, hidden[i] ) == 0 )
- return( TRUE );
- return( FALSE );
- }
-
- GLOBAL char *conf_prefix( i )
- int i;
- {
- if( i > nprefixes )
- return( NULL );
- return( prefix[i] );
- }
-
- GLOBAL void acct_group( pp )
- PERSON *pp;
- {
- int i;
- register struct acct *ap;
-
- for( i = 0, ap = accts; i < naccts; i++, ap++ ) {
- if( ap->min <= ap->max ) {
- if( pp->p_gid >= ap->min && pp->p_gid <= ap->max ) {
- pp->p_group = ap->group;
- return;
- }
- }
- else if( pp->p_gid >= ap->max && pp->p_gid <= ap->min ) {
- pp->p_group = ap->group;
- return;
- }
- }
- if( pp->p_gid == pp->p_uid )
- pp->p_group = '.'; /* use '=' ? */
- else
- pp->p_group = ' ';
- }
-
- GLOBAL char *acct_name( pp )
- PERSON *pp;
- {
- int i;
- register struct acct *ap;
-
- for( i = 0, ap = accts; i < naccts; i++, ap++ ) {
- if( ap->min <= ap->max ) {
- if( pp->p_gid >= ap->min && pp->p_gid <= ap->max )
- return( ap->name );
- }
- else if( pp->p_gid >= ap->max && pp->p_gid <= ap->min )
- return( ap->name );
- }
- return( NULL );
- }
-
- GLOBAL void catphone( dest, phone )
- register char *dest, *phone;
- {
- char *ph;
- int digits, other, i;
-
- ph = phone;
- for( digits = other = 0; *phone != EOS; phone++ )
- if( isdigit(*phone) )
- digits++;
- else
- other++;
-
- if(
- # ifdef FORMAT_DIGITS_ONLY
- other == 0 &&
- # endif /* FORMAT_DIGITS_ONLY defined */
- digits > 0 ) {
- while( *dest != EOS )
- dest++;
-
- for( i = 0; i < nphones; i++ )
- if( phones[i].splats == digits ) {
- register char *pat;
-
- phone = ph;
- for( pat = phones[i].pat; *pat != EOS; pat++ ) {
- if( *pat == NUMBER ) {
- while( !isdigit(*phone) )
- phone++;
- *dest++ = *phone++;
- }
- else
- *dest++ = *pat;
- }
- *dest = EOS;
- return;
- }
- } /* other == 0 && digits > 0 */
- strcat( dest, phone );
- }
-
- /* given an office string, return formatted in a static buffer */
- # define OFFSIZ 100
-
- GLOBAL char *office( s )
- char *s;
- {
- char offbuff[OFFSIZ];
- int i, l;
-
- l = strlen( s );
- if( l > OFFSIZ - 10 ) /* close? */
- return( s ); /* good-bye */
-
- for( i = 0; i < nbuildings; i++ )
- if( buildings[i].code == s[l-1] )
- break;
-
- if( i >= nbuildings )
- return( s );
-
- strcpy(offbuff, s);
- offbuff[l-1] = EOS;
- strcat(offbuff, buildings[i].name );
- return( offbuff );
- } /* office */
-