home *** CD-ROM | disk | FTP | other *** search
- /*
- * select.c -- perform selection process for finger
- *
- * Copyright (C) 1986, 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.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: select.c,v 3.0 90/07/06 13:11:41 budd Rel $";
- # endif /* lint not defined */
-
- # include <pwd.h>
- # include <stdio.h>
- # include <sys/types.h>
- # include <strings.h>
- # include "person.h"
- # include "args.h" /* before luser.h */
- # include "luser.h"
- # include "finger.h"
- # include "inquire.h"
-
- typedef struct sel {
- char *s_name; /* name of selector (upper case) */
- /* for match against lusers */
- int s_matches; /* number of users matched */
- char *s_orig; /* name in living color (orig case) */
- /* for passwd file lookup */
- struct switches s_sw; /* per selector flags!! */
- struct sel *s_next; /* next in chain */
- } SEL;
-
- extern PERSON *makeperson(); /* from getperson.c */
- extern LTREE *linsert(), *ent_select(); /* from getent.c */
- extern LUSER *newluser(); /* from getent.c */
- extern BOOL useinquire; /* from args.c */
-
- LOCAL SEL *selhead; /* chain of selectors */
- LOCAL SEL *seltail; /* tail of selector chain */
-
- LOCAL LTREE *luser_tree; /* tree of lusers from selectors */
-
- LOCAL LUSER *copy_not_found(); /* forward */
- LOCAL void insert_winner(); /* forward */
-
- GLOBAL void ini_select() { /* initialize select.c statics */
- selhead = seltail = NULL;
- luser_tree = NULL;
- } /* ini_select */
-
- GLOBAL BOOL have_locals() { /* find out if we have any SEL's */
- return( selhead != NULL );
- } /* havelocal */
-
- GLOBAL void addlocal( name ) /* add a local finger selector */
- char *name;
- {
- register SEL *new;
-
- if( (new = (SEL *)malloc( sizeof( SEL ) )) == NULL ) {
- fprintf(stderr, "malloc failed in sinsert\n");
- exit( 1 );
- } /* malloc failed */
-
- new->s_orig = savestr( name );
- new->s_name = name;
- zup( name );
- new->s_matches = 0;
- new->s_sw = Sw;
- new->s_next = NULL;
-
- if( selhead == NULL )
- selhead = seltail = new;
- else {
- seltail->s_next = new;
- seltail = new;
- }
- } /* addlocal */
-
- GLOBAL void select_go() { /* here to finger local users */
- struct passwd *pw;
- LTREE *tree2;
- int flag;
- SEL *sp;
-
- setpwent();
- if( !useinquire ) {
- while( (pw = getpwent()) != NULL ) {
- LOCAL SEL *match();
- SEL *winner; /* the selector that matched */
- char person[ 100 ], *tp;
-
- if( selhead == NULL )
- break;
-
- /* BUG: handle USG format gecos fields!! */
- /* copy gecos (WISH: only if comma)*/
- strcpy( person, pw->pw_gecos );
- if( (tp = index(person, ',')) != NULL ) /* find a comma? */
- *tp = EOS; /* yes, blast it. */
-
- /* find a selector that matches uname or personal name */
- winner = match( pw->pw_name, person );
- if( winner != NULL )
- insert_winner( winner, pw->pw_name, pw );
- } /* while */
- } /* no inquire */
- # ifdef INQUIRE
- else { /* use inquire */
- struct block *bp;
-
- for( sp = selhead; sp != NULL; sp = sp->s_next ) {
- if( Read( sp->s_name, BPs ) != NULL )
- insert_winner( sp, BPs[_UNAME], NULL, BPs );
-
- if( sp->s_sw.sw_match )
- continue;
-
- /* Use FindPerson (inquire internal lastname lookup) */
- for(bp = FindPerson( sp->s_name ); bp != NULL; /* find all */
- bp = NextPerson( sp->s_name, bp) ){ /* matching lastnames */
- Expand( bp, BPs );
- insert_winner( sp, BPs[_UNAME], NULL, BPs );
- } /* for matching persons */
- } /* for each sel */
- } /* useinquire */
- # endif /* INQUIRE defined */
-
- /* one last try for unmatched selectors (or ones added by /follow!) */
- for( sp = selhead; sp != NULL; sp = sp->s_next ) {
- if( sp->s_matches == 0 ) {
- struct passwd *pw;
-
- pw = getpwnam( sp->s_orig );
- if( pw != NULL )
- insert_winner( sp, pw->pw_name, pw, NULL );
- } /* no matches */
- } /* for */
-
- endpwent();
-
- tree2 = ent_select( luser_tree ); /* get tree of logged in people */
- tree2 = copy_not_found( luser_tree, tree2 ); /* merge people not on */
-
- flag = 0;
- for( sp = selhead; sp != NULL; sp = sp->s_next )
- if( sp->s_matches == 0 ) {
- if( flag == 0 )
- fprintf(stderr, "%%No matches for ");
- else
- fputs( ", ", stderr );
- fputs( sp->s_orig, stderr );
- flag++;
- }
- if( flag > 0 )
- putc( '\n', stderr );
-
- if( tree2 != NULL ) /* get anything? */
- dofinger( tree2 );
- } /* select_go */
-
- /* PERHAPS LUSERS SHOULD BE IN A LIST (avoid recursion) */
- /* see newluser in getent.c? WISH */
-
- /* returns merged tree of logged in users and prototypes never found (NLI) */
-
- LOCAL LUSER *copy_not_found( proto, out )
- LUSER *proto, *out; /* not logged in, output tree */
- {
- if( proto != NULL ) {
- /* travese bottom up, so safe to remove elements */
- out = copy_not_found( proto->u_left, out );
- out = copy_not_found( proto->u_right, out );
-
- if( (proto->u_flags & U_FOUND) == 0 ) { /* proto never found? */
- proto->u_left = proto->u_right = NULL; /* remove from tree */
- out = linsert( proto, out ); /* insert into output tree */
- } /* if not found */
- } /* have a prototype */
- return( out );
- } /* copy_not_found */
-
- LOCAL SEL *match(uname, fullname) /* return a sel that matches */
- char *uname, *fullname;
- {
- char *tp;
- int nfull;
- register SEL *sp;
- char temp[ 512 ], temp2[ 512 ], *fullp[ 128 ];
-
- strupcpy(temp, uname ); /* make upper case copy of uname */
-
- nfull = 0;
- if( fullname != NULL ) {
- strupcpy(temp2, fullname); /* copy personal, upper case */
- tp = temp2; /* point to fullname */
- for( ; ; ) {
- register char *bp; /* pointer to start of token */
-
- if( !skipwhite( &tp ) ) /* skip leading white */
- break;
-
- bp = tp; /* save start of token */
- if( !skipblack( &tp ) && bp == tp )
- break;
-
- *tp++ = EOS; /* tie off token */
- fullp[ nfull++ ] = bp;
- } /* forever */
- } /* have fullname */
-
- for( sp = selhead; sp != NULL; sp = sp->s_next ) {
- register int i;
-
- if( strcmp( temp, sp->s_name ) == 0 )
- return( sp );
-
- if( sp->s_sw.sw_match /* allow match on fullname? */
- || nfull == 0 ) /* have one?? */
- continue;
-
- for( i = 0; i < nfull; i++ )
- if( strcmp( fullp[i], sp->s_name ) == 0 )
- return( sp );
- }
- return( NULL );
- } /* match */
-
- LOCAL void insert_winner( winner, uname, pw, inq )
- SEL *winner;
- char *uname;
- struct passwd *pw;
- struct info *inq; /* for INQUIRE */
- {
- register LUSER *u;
-
- /* find a matching selector? is it in luser_tree already? */
- if( winner == NULL || treefind( luser_tree, uname ) != NULL )
- return;
- winner->s_matches++; /* count our conquests */
-
- if( pw == NULL ) {
- pw = getpwnam( uname );
- # ifdef DEBUG
- if( pw == NULL )
- printf("no pw entry for %s\n", uname );
- # endif /* DEBUG defined */
- }
-
- /* found a new matching selector. create entry */
-
- u = newluser(); /* create a user */
- strcpy(u->u_user, uname); /* set user name! */
- # ifdef INQUIRE
- u->u_person = makeperson( u, pw, inq ); /* build person struct */
- # else /* INQUIRE not defined */
- u->u_person = makeperson( u, pw, NULL ); /* build person struct */
- # endif /* INQUIRE not defined */
- u->u_flags |= U_NLI; /* say not logged in */
- u->u_sw = winner->s_sw; /* inherit switched from SEL */
- luser_tree = linsert(u, luser_tree);
- } /* insert_winner */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-