home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / TERMNET / TFINGER / FINGER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-20  |  7.0 KB  |  258 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. /*
  38.  * Mail status reporting added 931007 by Luke Mewburn, <zak@rmit.edu.au>.
  39.  */
  40.  
  41. #ifndef lint
  42. char copyright[] =
  43. "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  44.  All rights reserved.\n";
  45. #endif /* not lint */
  46.  
  47. #ifndef lint
  48. /*static char sccsid[] = "from: @(#)finger.c    5.22 (Berkeley) 6/29/90";*/
  49. static char rcsid[] = "$Id: finger.c,v 1.3 1993/10/07 19:58:29 brezak Exp $";
  50. #endif /* not lint */
  51.  
  52. /*
  53.  * Finger prints out information about users.  It is not portable since
  54.  * certain fields (e.g. the full user name, office, and phone numbers) are
  55.  * extracted from the gecos field of the passwd file which other UNIXes
  56.  * may not have or may use for other things.
  57.  *
  58.  * There are currently two output formats; the short format is one line
  59.  * per user and displays login name, tty, login time, real name, idle time,
  60.  * and office location/phone number.  The long format gives the same
  61.  * information (in a more legible format) as well as home directory, shell,
  62.  * mail info, and .plan/.project files.
  63.  */
  64.  
  65. #include <sys/param.h>
  66. #include <sys/file.h>
  67. #include <stdio.h>
  68. #include <paths.h>
  69. #include "finger.h"
  70.  
  71. time_t now;
  72. int lflag, sflag, mflag, pplan;
  73. char tbuf[1024];
  74.  
  75. main(argc, argv)
  76.     int argc;
  77.     char **argv;
  78. {
  79.     extern int optind;
  80.     int ch;
  81.     time_t time();
  82.  
  83.     while ((ch = getopt(argc, argv, "lmps")) != EOF)
  84.         switch(ch) {
  85.         case 'l':
  86.             lflag = 1;        /* long format */
  87.             break;
  88.         case 'm':
  89.             mflag = 1;        /* force exact match of names */
  90.             break;
  91.         case 'p':
  92.             pplan = 1;        /* don't show .plan/.project */
  93.             break;
  94.         case 's':
  95.             sflag = 1;        /* short format */
  96.             break;
  97.         case '?':
  98.         default:
  99.             (void)fprintf(stderr,
  100.                 "usage: finger [-lmps] [login ...]\n");
  101.             exit(1);
  102.         }
  103.     argc -= optind;
  104.     argv += optind;
  105.  
  106.     (void)time(&now);
  107.     setpassent(1);
  108.     if (!*argv) {
  109.         /*
  110.          * Assign explicit "small" format if no names given and -l
  111.          * not selected.  Force the -s BEFORE we get names so proper
  112.          * screening will be done.
  113.          */
  114.         if (!lflag)
  115.             sflag = 1;    /* if -l not explicit, force -s */
  116.         loginlist();
  117.         if (entries == 0)
  118.             (void)printf("No one logged on.\n");
  119.     } else {
  120.         userlist(argc, argv);
  121.         /*
  122.          * Assign explicit "large" format if names given and -s not
  123.          * explicitly stated.  Force the -l AFTER we get names so any
  124.          * remote finger attempts specified won't be mishandled.
  125.          */
  126.         if (!sflag)
  127.             lflag = 1;    /* if -s not explicit, force -l */
  128.     }
  129.     if (entries != 0) {
  130.         if (lflag)
  131.             lflag_print();
  132.         else
  133.             sflag_print();
  134.     }
  135.     exit(0);
  136. }
  137.  
  138. loginlist()
  139. {
  140.     register PERSON *pn;
  141.     struct passwd *pw;
  142.     struct utmp user;
  143.     char name[UT_NAMESIZE + 1];
  144.  
  145.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  146.         (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
  147.         exit(2);
  148.     }
  149.     name[UT_NAMESIZE] = '\0';
  150.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  151.         if (!user.ut_name[0])
  152.             continue;
  153. #ifdef USER_PROCESS
  154.         if (user.ut_type != USER_PROCESS) continue;
  155. #endif
  156.         if ((pn = find_person(user.ut_name)) == NULL) {
  157.             bcopy(user.ut_name, name, UT_NAMESIZE);
  158.             if ((pw = getpwnam(name)) == NULL)
  159.                 continue;
  160.             pn = enter_person(pw);
  161.         }
  162.         enter_where(&user, pn);
  163.     }
  164.     for (pn = phead; lflag && pn != NULL; pn = pn->next)
  165.         enter_lastlog(pn);
  166. }
  167.  
  168. userlist(argc, argv)
  169.     register argc;
  170.     register char **argv;
  171. {
  172.     register i;
  173.     register PERSON *pn;
  174.     PERSON *nethead, **nettail;
  175.     struct utmp user;
  176.     struct passwd *pw;
  177.     int dolocal, *used;
  178.     char *index();
  179.  
  180.     if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) {
  181.         (void)fprintf(stderr, "finger: out of space.\n");
  182.         exit(1);
  183.     }
  184.  
  185.     /* pull out all network requests */
  186.     for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
  187.         if (!index(argv[i], '@')) {
  188.             dolocal = 1;
  189.             continue;
  190.         }
  191.         pn = palloc();
  192.         *nettail = pn;
  193.         nettail = &pn->next;
  194.         pn->name = argv[i];
  195.         used[i] = -1;
  196.     }
  197.     *nettail = NULL;
  198.  
  199.     if (!dolocal)
  200.         goto net;
  201.  
  202.     /*
  203.      * traverse the list of possible login names and check the login name
  204.      * and real name against the name specified by the user.
  205.      */
  206.     if (mflag) {
  207.         for (i = 0; i < argc; i++)
  208.             if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
  209.                 enter_person(pw);
  210.                 used[i] = 1;
  211.             }
  212.     } else while (pw = getpwent())
  213.         for (i = 0; i < argc; i++)
  214.             if (used[i] >= 0 &&
  215.                 (!strcasecmp(pw->pw_name, argv[i]) ||
  216.                 match(pw, argv[i]))) {
  217.                 enter_person(pw);
  218.                 used[i] = 1;
  219.             }
  220.  
  221.     /* list errors */
  222.     for (i = 0; i < argc; i++)
  223.         if (!used[i])
  224.             (void)fprintf(stderr,
  225.                 "finger: %s: no such user.\n", argv[i]);
  226.  
  227.     /* handle network requests */
  228. net:    for (pn = nethead; pn; pn = pn->next) {
  229.         netfinger(pn->name);
  230.         if (pn->next || entries)
  231.             putchar('\n');
  232.     }
  233.  
  234.     if (entries == 0)
  235.         return;
  236.  
  237.     /*
  238.      * Scan thru the list of users currently logged in, saving
  239.      * appropriate data whenever a match occurs.
  240.      */
  241.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  242.         (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
  243.         exit(1);
  244.     }
  245.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  246.         if (!user.ut_name[0])
  247.             continue;
  248. #ifdef USER_PROCESS
  249.         if (user.ut_type != USER_PROCESS) continue;
  250. #endif
  251.         if ((pn = find_person(user.ut_name)) == NULL)
  252.             continue;
  253.         enter_where(&user, pn);
  254.     }
  255.     for (pn = phead; pn != NULL; pn = pn->next)
  256.         enter_lastlog(pn);
  257. }
  258.