home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part04 / select.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  7.4 KB  |  275 lines

  1. /*
  2.  * select.c -- perform selection process for finger
  3.  *
  4.  * Copyright (C) 1986, 1990  Philip L. Budne
  5.  *
  6.  * This file is part of "Phil's Finger Program".
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  *
  13.  */
  14.  
  15. # ifndef lint
  16. static char *rcsid = "$Id: select.c,v 3.0 90/07/06 13:11:41 budd Rel $";
  17. # endif /* lint not defined */
  18.  
  19. # include <pwd.h>
  20. # include <stdio.h>
  21. # include <sys/types.h>
  22. # include <strings.h>
  23. # include "person.h"
  24. # include "args.h"            /* before luser.h */
  25. # include "luser.h"
  26. # include "finger.h"
  27. # include "inquire.h"
  28.  
  29. typedef struct sel {
  30.     char *s_name;            /* name of selector (upper case) */
  31.                     /* for match against lusers */
  32.     int s_matches;            /* number of users matched */
  33.     char *s_orig;            /* name in living color (orig case) */
  34.                     /* for passwd file lookup */
  35.     struct switches s_sw;        /* per selector flags!! */
  36.     struct sel *s_next;            /* next in chain */
  37. } SEL;
  38.  
  39. extern PERSON *makeperson();        /* from getperson.c */
  40. extern LTREE *linsert(), *ent_select();    /* from getent.c  */
  41. extern LUSER *newluser();        /* from getent.c */
  42. extern BOOL useinquire;            /* from args.c */
  43.  
  44. LOCAL SEL *selhead;            /* chain of selectors */
  45. LOCAL SEL *seltail;            /* tail of selector chain */
  46.  
  47. LOCAL LTREE *luser_tree;        /* tree of lusers from selectors */
  48.  
  49. LOCAL LUSER *copy_not_found();        /* forward */
  50. LOCAL void insert_winner();        /* forward */
  51.  
  52. GLOBAL void ini_select() {        /* initialize select.c statics */
  53.     selhead = seltail = NULL;
  54.     luser_tree = NULL;
  55. } /* ini_select */
  56.  
  57. GLOBAL BOOL have_locals() {        /* find out if we have any SEL's */
  58.     return( selhead != NULL );
  59. } /* havelocal */
  60.  
  61. GLOBAL void addlocal( name )        /* add a local finger selector */
  62. char *name;
  63. {
  64.     register SEL *new;
  65.  
  66.     if( (new = (SEL *)malloc( sizeof( SEL ) )) == NULL ) {
  67.     fprintf(stderr, "malloc failed in sinsert\n");
  68.     exit( 1 );
  69.     } /* malloc failed */
  70.  
  71.     new->s_orig = savestr( name );
  72.     new->s_name = name;
  73.     zup( name );
  74.     new->s_matches = 0;
  75.     new->s_sw = Sw;
  76.     new->s_next = NULL;
  77.  
  78.     if( selhead == NULL )
  79.     selhead = seltail = new;
  80.     else {
  81.     seltail->s_next = new;
  82.     seltail = new;
  83.     }
  84. } /* addlocal */
  85.  
  86. GLOBAL void select_go() {        /* here to finger local users */
  87.     struct passwd *pw;
  88.     LTREE *tree2;
  89.     int flag;
  90.     SEL *sp;
  91.  
  92.     setpwent();
  93.     if( !useinquire ) {
  94.     while( (pw = getpwent()) != NULL ) {
  95.         LOCAL SEL *match();
  96.         SEL *winner;        /* the selector that matched */
  97.         char person[ 100 ], *tp;
  98.  
  99.         if( selhead == NULL )
  100.         break;
  101.  
  102.         /* BUG: handle USG format gecos fields!! */
  103.         /* copy gecos (WISH: only if comma)*/
  104.         strcpy( person, pw->pw_gecos );
  105.         if( (tp = index(person, ',')) != NULL ) /* find a comma? */
  106.         *tp = EOS;            /* yes, blast it. */
  107.  
  108.         /* find a selector that matches uname or personal name */
  109.         winner = match( pw->pw_name, person );
  110.         if( winner != NULL )
  111.         insert_winner( winner, pw->pw_name, pw );
  112.     } /* while */
  113.     } /* no inquire */
  114. # ifdef INQUIRE
  115.     else {                /* use inquire */
  116.     struct block *bp;
  117.  
  118.     for( sp = selhead; sp != NULL; sp = sp->s_next ) {
  119.         if( Read( sp->s_name, BPs ) != NULL )
  120.         insert_winner( sp, BPs[_UNAME], NULL, BPs );
  121.  
  122.         if( sp->s_sw.sw_match )
  123.         continue;
  124.  
  125.         /* Use FindPerson (inquire internal lastname lookup) */
  126.         for(bp = FindPerson( sp->s_name ); bp != NULL; /* find all */
  127.         bp = NextPerson( sp->s_name, bp) ){ /* matching lastnames */
  128.         Expand( bp, BPs );
  129.         insert_winner( sp, BPs[_UNAME], NULL, BPs );
  130.         } /* for matching persons */
  131.     } /* for each sel */
  132.     } /* useinquire */
  133. # endif /* INQUIRE defined */
  134.  
  135.     /* one last try for unmatched selectors (or ones added by /follow!) */
  136.     for( sp = selhead; sp != NULL; sp = sp->s_next ) {
  137.     if( sp->s_matches == 0 ) {
  138.         struct passwd *pw;
  139.  
  140.         pw = getpwnam( sp->s_orig );
  141.         if( pw != NULL )
  142.         insert_winner( sp, pw->pw_name, pw, NULL );
  143.     } /* no matches */
  144.     } /* for */
  145.  
  146.     endpwent();
  147.  
  148.     tree2 = ent_select( luser_tree );     /* get tree of logged in people */
  149.     tree2 = copy_not_found( luser_tree, tree2 ); /* merge people not on */
  150.  
  151.     flag = 0;
  152.     for( sp = selhead; sp != NULL; sp = sp->s_next )
  153.     if( sp->s_matches == 0 ) {
  154.         if( flag == 0 )
  155.         fprintf(stderr, "%%No matches for ");
  156.         else
  157.         fputs( ", ", stderr );
  158.         fputs( sp->s_orig, stderr );
  159.         flag++;
  160.     }
  161.     if( flag > 0 )
  162.     putc( '\n', stderr );
  163.  
  164.     if( tree2 != NULL )            /* get anything? */
  165.     dofinger( tree2 );
  166. } /* select_go */
  167.  
  168. /* PERHAPS LUSERS SHOULD BE IN A LIST (avoid recursion) */
  169. /* see newluser in getent.c?  WISH */
  170.  
  171. /* returns merged tree of logged in users and prototypes never found (NLI) */
  172.  
  173. LOCAL LUSER *copy_not_found( proto, out )
  174. LUSER *proto, *out;            /* not logged in, output tree */
  175. {
  176.     if( proto != NULL ) {
  177.     /* travese bottom up, so safe to remove elements */
  178.     out = copy_not_found( proto->u_left, out );
  179.     out = copy_not_found( proto->u_right, out );
  180.     
  181.     if( (proto->u_flags & U_FOUND) == 0 ) {    /* proto never found? */
  182.         proto->u_left = proto->u_right = NULL; /* remove from tree */
  183.         out = linsert( proto, out ); /* insert into output tree */
  184.     } /* if not found */
  185.     } /* have a prototype */
  186.     return( out );
  187. } /* copy_not_found */
  188.  
  189. LOCAL SEL *match(uname, fullname)    /* return a sel that matches */
  190. char *uname, *fullname;
  191. {
  192.     char *tp;
  193.     int nfull;
  194.     register SEL *sp;
  195.     char temp[ 512 ], temp2[ 512 ], *fullp[ 128 ];
  196.  
  197.     strupcpy(temp, uname );        /* make upper case copy of uname */
  198.  
  199.     nfull = 0;
  200.     if( fullname != NULL ) {
  201.     strupcpy(temp2, fullname);    /* copy personal, upper case */
  202.     tp = temp2;            /* point to fullname */
  203.     for( ; ; ) {
  204.         register char *bp;        /* pointer to start of token */
  205.  
  206.         if( !skipwhite( &tp ) )    /* skip leading white */
  207.         break;
  208.  
  209.         bp = tp;            /* save start of token */
  210.         if( !skipblack( &tp ) && bp == tp )
  211.         break;
  212.  
  213.         *tp++ = EOS;        /* tie off token */
  214.         fullp[ nfull++ ] = bp;
  215.     } /* forever */
  216.     } /* have fullname */
  217.  
  218.     for( sp = selhead; sp != NULL; sp = sp->s_next ) {
  219.     register int i;
  220.  
  221.     if( strcmp( temp, sp->s_name ) == 0 )
  222.         return( sp );
  223.  
  224.     if( sp->s_sw.sw_match        /* allow match on fullname? */
  225.        || nfull == 0 )        /* have one?? */
  226.         continue;
  227.  
  228.     for( i = 0; i < nfull; i++ )
  229.         if( strcmp( fullp[i], sp->s_name ) == 0 )
  230.         return( sp );
  231.     }
  232.     return( NULL );
  233. } /* match */
  234.  
  235. LOCAL void insert_winner( winner, uname, pw, inq )
  236. SEL *winner;
  237. char *uname;
  238. struct passwd *pw;
  239. struct info *inq;            /* for INQUIRE */
  240. {
  241.     register LUSER *u;
  242.  
  243.     /* find a matching selector? is it in luser_tree already? */
  244.     if( winner == NULL  ||  treefind( luser_tree, uname ) != NULL )
  245.     return;
  246.     winner->s_matches++;        /* count our conquests */
  247.  
  248.     if( pw == NULL ) {
  249.     pw = getpwnam( uname );
  250. # ifdef DEBUG
  251.     if( pw == NULL )
  252.         printf("no pw entry for %s\n", uname );
  253. # endif /* DEBUG defined */
  254.     }
  255.  
  256.     /* found a new matching selector. create entry */
  257.  
  258.     u = newluser();            /* create a user */
  259.     strcpy(u->u_user, uname);        /* set user name! */
  260. # ifdef INQUIRE
  261.     u->u_person = makeperson( u, pw, inq ); /* build person struct */
  262. # else  /* INQUIRE not defined */
  263.     u->u_person = makeperson( u, pw, NULL ); /* build person struct */
  264. # endif /* INQUIRE not defined */
  265.     u->u_flags |= U_NLI;        /* say not logged in */
  266.     u->u_sw = winner->s_sw;        /* inherit switched from SEL */
  267.     luser_tree = linsert(u, luser_tree);
  268. } /* insert_winner */
  269.  
  270. /*
  271.  * Local variables:
  272.  * comment-column: 40
  273.  * End:
  274.  */
  275.