home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / comm / net / amitcp / amitcp-2.2 / src / appl / finger / finger.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  8.1 KB  |  305 lines

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