home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / finger / finger.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-17  |  6.7 KB  |  246 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. char copyright[] =
  39. "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)finger.c    5.22 (Berkeley) 6/29/90";
  45. #endif /* not lint */
  46.  
  47. /*
  48.  * Finger prints out information about users.  It is not portable since
  49.  * certain fields (e.g. the full user name, office, and phone numbers) are
  50.  * extracted from the gecos field of the passwd file which other UNIXes
  51.  * may not have or may use for other things.
  52.  *
  53.  * There are currently two output formats; the short format is one line
  54.  * per user and displays login name, tty, login time, real name, idle time,
  55.  * and office location/phone number.  The long format gives the same
  56.  * information (in a more legible format) as well as home directory, shell,
  57.  * mail info, and .plan/.project files.
  58.  */
  59.  
  60. #include <sys/param.h>
  61. #include <sys/file.h>
  62. #include <stdio.h>
  63. #include "finger.h"
  64.  
  65. time_t now;
  66. int lflag, sflag, mflag, pplan;
  67. char tbuf[1024];
  68.  
  69. main(argc, argv)
  70.     int argc;
  71.     char **argv;
  72. {
  73.     extern int optind;
  74.     int ch;
  75.     time_t time();
  76.  
  77.     while ((ch = getopt(argc, argv, "lmps")) != EOF)
  78.         switch(ch) {
  79.         case 'l':
  80.             lflag = 1;        /* long format */
  81.             break;
  82.         case 'm':
  83.             mflag = 1;        /* force exact match of names */
  84.             break;
  85.         case 'p':
  86.             pplan = 1;        /* don't show .plan/.project */
  87.             break;
  88.         case 's':
  89.             sflag = 1;        /* short format */
  90.             break;
  91.         case '?':
  92.         default:
  93.             (void)fprintf(stderr,
  94.                 "usage: finger [-lmps] [login ...]\n");
  95.             exit(1);
  96.         }
  97.     argc -= optind;
  98.     argv += optind;
  99.  
  100.     (void)time(&now);
  101.     setpassent(1);
  102.     if (!*argv) {
  103.         /*
  104.          * Assign explicit "small" format if no names given and -l
  105.          * not selected.  Force the -s BEFORE we get names so proper
  106.          * screening will be done.
  107.          */
  108.         if (!lflag)
  109.             sflag = 1;    /* if -l not explicit, force -s */
  110.         loginlist();
  111.         if (entries == 0)
  112.             (void)printf("No one logged on.\n");
  113.     } else {
  114.         userlist(argc, argv);
  115.         /*
  116.          * Assign explicit "large" format if names given and -s not
  117.          * explicitly stated.  Force the -l AFTER we get names so any
  118.          * remote finger attempts specified won't be mishandled.
  119.          */
  120.         if (!sflag)
  121.             lflag = 1;    /* if -s not explicit, force -l */
  122.     }
  123.     if (entries != 0) {
  124.         if (lflag)
  125.             lflag_print();
  126.         else
  127.             sflag_print();
  128.     }
  129.     exit(0);
  130. }
  131.  
  132. loginlist()
  133. {
  134.     register PERSON *pn;
  135.     struct passwd *pw;
  136.     struct utmp user;
  137.     char name[UT_NAMESIZE + 1];
  138.  
  139.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  140.         (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
  141.         exit(2);
  142.     }
  143.     name[UT_NAMESIZE] = NULL;
  144.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  145.         if (!user.ut_name[0])
  146.             continue;
  147.         if ((pn = find_person(user.ut_name)) == NULL) {
  148.             bcopy(user.ut_name, name, UT_NAMESIZE);
  149.             if ((pw = getpwnam(name)) == NULL)
  150.                 continue;
  151.             pn = enter_person(pw);
  152.         }
  153.         enter_where(&user, pn);
  154.     }
  155.     for (pn = phead; lflag && pn != NULL; pn = pn->next)
  156.         enter_lastlog(pn);
  157. }
  158.  
  159. userlist(argc, argv)
  160.     register argc;
  161.     register char **argv;
  162. {
  163.     register i;
  164.     register PERSON *pn;
  165.     PERSON *nethead, **nettail;
  166.     struct utmp user;
  167.     struct passwd *pw;
  168.     int dolocal, *used;
  169.     char *index();
  170.  
  171.     if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) {
  172.         (void)fprintf(stderr, "finger: out of space.\n");
  173.         exit(1);
  174.     }
  175.  
  176.     /* pull out all network requests */
  177.     for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
  178.         if (!index(argv[i], '@')) {
  179.             dolocal = 1;
  180.             continue;
  181.         }
  182.         pn = palloc();
  183.         *nettail = pn;
  184.         nettail = &pn->next;
  185.         pn->name = argv[i];
  186.         used[i] = -1;
  187.     }
  188.     *nettail = NULL;
  189.  
  190.     if (!dolocal)
  191.         goto net;
  192.  
  193.     /*
  194.      * traverse the list of possible login names and check the login name
  195.      * and real name against the name specified by the user.
  196.      */
  197.     if (mflag) {
  198.         for (i = 0; i < argc; i++)
  199.             if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
  200.                 enter_person(pw);
  201.                 used[i] = 1;
  202.             }
  203.     } else while (pw = getpwent())
  204.         for (i = 0; i < argc; i++)
  205.             if (used[i] >= 0 &&
  206.                 (!strcasecmp(pw->pw_name, argv[i]) ||
  207.                 match(pw, argv[i]))) {
  208.                 enter_person(pw);
  209.                 used[i] = 1;
  210.             }
  211.  
  212.     /* list errors */
  213.     for (i = 0; i < argc; i++)
  214.         if (!used[i])
  215.             (void)fprintf(stderr,
  216.                 "finger: %s: no such user.\n", argv[i]);
  217.  
  218.     /* handle network requests */
  219. net:    for (pn = nethead; pn; pn = pn->next) {
  220.         netfinger(pn->name);
  221.         if (pn->next || entries)
  222.             putchar('\n');
  223.     }
  224.  
  225.     if (entries == 0)
  226.         return;
  227.  
  228.     /*
  229.      * Scan thru the list of users currently logged in, saving
  230.      * appropriate data whenever a match occurs.
  231.      */
  232.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  233.         (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
  234.         exit(1);
  235.     }
  236.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  237.         if (!user.ut_name[0])
  238.             continue;
  239.         if ((pn = find_person(user.ut_name)) == NULL)
  240.             continue;
  241.         enter_where(&user, pn);
  242.     }
  243.     for (pn = phead; pn != NULL; pn = pn->next)
  244.         enter_lastlog(pn);
  245. }
  246.