home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / FINGER.TAR / finger / util.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-23  |  8.3 KB  |  356 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. /*static char sccsid[] = "from: @(#)util.c    5.14 (Berkeley) 1/17/91";*/
  39. static char rcsid[] = "$Id: util.c,v 1.3 1993/10/07 19:58:32 brezak Exp $";
  40. #endif /* not lint */
  41.  
  42. #include <sys/param.h>
  43. #include <sys/stat.h>
  44. #include <sys/file.h>
  45. #include <stdio.h>
  46. #include <ctype.h>
  47. #include <string.h>
  48. #include <paths.h>
  49. #include <errno.h>
  50. #include "finger.h"
  51. /* #include <lastlog.h> */
  52.  
  53. find_idle_and_ttywrite(w)
  54.     register WHERE *w;
  55. {
  56.     extern time_t now;
  57.     extern int errno;
  58.     struct stat sb;
  59.     char *strerror();
  60.  
  61.     (void)sprintf(tbuf, "%s/%s", _PATH_DEV, w->tty);
  62.     if (stat(tbuf, &sb) < 0) {
  63.         (void)fprintf(stderr,
  64.             "finger: %s: %s\n", tbuf, strerror(errno));
  65.         return;
  66.     }
  67.     w->idletime = now < sb.st_atime ? 0 : now - sb.st_atime;
  68.  
  69. #define    TALKABLE    0220        /* tty is writable if 220 mode */
  70.     w->writable = ((sb.st_mode & TALKABLE) == TALKABLE);
  71. }
  72.  
  73. userinfo(pn, pw)
  74.     register PERSON *pn;
  75.     register struct passwd *pw;
  76. {
  77.     extern time_t now;
  78.     register char *p, *t;
  79.     struct stat sb;
  80.     extern int errno;
  81.     char *bp, name[1024];
  82.  
  83.     pn->realname = pn->office = pn->officephone = pn->homephone = NULL;
  84.  
  85.     pn->uid = pw->pw_uid;
  86.     pn->name = strdup(pw->pw_name);
  87.     pn->dir = strdup(pw->pw_dir);
  88.     pn->shell = strdup(pw->pw_shell);
  89.  
  90.     /* why do we skip asterisks!?!? */
  91.     (void)strcpy(bp = tbuf, pw->pw_gecos);
  92.     if (*bp == '*')
  93.         ++bp;
  94.  
  95.     /* ampersands get replaced by the login name */
  96.     if (!(p = strsep(&bp, ",")))
  97.         return;
  98.     for (t = name; *t = *p; ++p)
  99.         if (*t == '&') {
  100.             (void)strcpy(t, pw->pw_name);
  101.             if (islower(*t))
  102.                 *t = toupper(*t);
  103.             while (*++t);
  104.         }
  105.         else
  106.             ++t;
  107.     pn->realname = strdup(name);
  108.     pn->office = ((p = strsep(&bp, ",")) && *p) ?
  109.         strdup(p) : NULL;
  110.     pn->officephone = ((p = strsep(&bp, ",")) && *p) ?
  111.         strdup(p) : NULL;
  112.     pn->homephone = ((p = strsep(&bp, ",")) && *p) ?
  113.         strdup(p) : NULL;
  114.     (void)sprintf(tbuf, "%s/%s", _PATH_MAILSPOOL, pw->pw_name);
  115.     pn->mailrecv = -1;        /* -1 == not_valid */
  116.     if (stat(tbuf, &sb) < 0) {
  117.         if (errno != ENOENT) {
  118.             (void)fprintf(stderr,
  119.                 "finger: %s: %s\n", tbuf, strerror(errno));
  120.             return;
  121.         }
  122.     } else if (sb.st_size != 0) {
  123.         pn->mailrecv = sb.st_mtime;
  124.         pn->mailread = sb.st_atime;
  125.     }
  126. }
  127.  
  128. match(pw, user)
  129.     struct passwd *pw;
  130.     char *user;
  131. {
  132.     register char *p, *t;
  133.     char name[1024];
  134.  
  135.     /* why do we skip asterisks!?!? */
  136.     (void)strcpy(p = tbuf, pw->pw_gecos);
  137.     if (*p == '*')
  138.         ++p;
  139.  
  140.     /* ampersands get replaced by the login name */
  141.     if (!(p = strtok(p, ",")))
  142.         return(0);
  143.     for (t = name; *t = *p; ++p)
  144.         if (*t == '&') {
  145.             (void)strcpy(t, pw->pw_name);
  146.             while (*++t);
  147.         }
  148.         else
  149.             ++t;
  150.     for (t = name; p = strtok(t, "\t "); t = (char *)NULL)
  151.         if (!strcasecmp(p, user))
  152.             return(1);
  153.     return(0);
  154. }
  155.  
  156. enter_lastlog(pn)
  157.     register PERSON *pn;
  158. {
  159.     register WHERE *w;
  160.     static int opened, fd;
  161.     struct lastlog ll;
  162.     char doit = 0;
  163.     off_t lseek();
  164.  
  165.     /* some systems may not maintain lastlog, don't report errors. */
  166.     if (!opened) {
  167.         fd = open(_PATH_LASTLOG, O_RDONLY, 0);
  168.         opened = 1;
  169.     }
  170.     if (fd == -1 ||
  171.         lseek(fd, (long)pn->uid * sizeof(ll), L_SET) !=
  172.         (long)pn->uid * sizeof(ll) ||
  173.         read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) {
  174.             /* as if never logged in */
  175.             ll.ll_line[0] = ll.ll_host[0] = '\0';
  176.             ll.ll_time = 0;
  177.         }
  178.     if ((w = pn->whead) == NULL)
  179.         doit = 1;
  180.     else if (ll.ll_time != 0) {
  181.         /* if last login is earlier than some current login */
  182.         for (; !doit && w != NULL; w = w->next)
  183.             if (w->info == LOGGEDIN && w->loginat < ll.ll_time)
  184.                 doit = 1;
  185.         /*
  186.          * and if it's not any of the current logins
  187.          * can't use time comparison because there may be a small
  188.          * discrepency since login calls time() twice
  189.          */
  190.         for (w = pn->whead; doit && w != NULL; w = w->next)
  191.             if (w->info == LOGGEDIN &&
  192.                 strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
  193.                 doit = 0;
  194.     }
  195.     if (doit) {
  196.         w = walloc(pn);
  197.         w->info = LASTLOG;
  198.         bcopy(ll.ll_line, w->tty, UT_LINESIZE);
  199.         w->tty[UT_LINESIZE] = 0;
  200.         bcopy(ll.ll_host, w->host, UT_HOSTSIZE);
  201.         w->host[UT_HOSTSIZE] = 0;
  202.         w->loginat = ll.ll_time;
  203.     }
  204. }
  205.  
  206. enter_where(ut, pn)
  207.     struct utmp *ut;
  208.     PERSON *pn;
  209. {
  210.     register WHERE *w = walloc(pn);
  211.  
  212.     w->info = LOGGEDIN;
  213.     bcopy(ut->ut_line, w->tty, UT_LINESIZE);
  214.     w->tty[UT_LINESIZE] = 0;
  215.     bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
  216.     w->host[UT_HOSTSIZE] = 0;
  217.     w->loginat = (time_t)ut->ut_time;
  218.     find_idle_and_ttywrite(w);
  219. }
  220.  
  221. PERSON *
  222. enter_person(pw)
  223.     register struct passwd *pw;
  224. {
  225.     register PERSON *pn, **pp;
  226.  
  227.     for (pp = htab + hash(pw->pw_name);
  228.          *pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0;
  229.          pp = &(*pp)->hlink)
  230.         ;
  231.     if ((pn = *pp) == NULL) {
  232.         pn = palloc();
  233.         entries++;
  234.         if (phead == NULL)
  235.             phead = ptail = pn;
  236.         else {
  237.             ptail->next = pn;
  238.             ptail = pn;
  239.         }
  240.         pn->next = NULL;
  241.         pn->hlink = NULL;
  242.         *pp = pn;
  243.         userinfo(pn, pw);
  244.         pn->whead = NULL;
  245.     }
  246.     return(pn);
  247. }
  248.  
  249. PERSON *
  250. find_person(name)
  251.     char *name;
  252. {
  253.     register PERSON *pn;
  254.  
  255.     /* name may be only UT_NAMESIZE long and not terminated */
  256.     for (pn = htab[hash(name)];
  257.          pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0;
  258.          pn = pn->hlink)
  259.         ;
  260.     return(pn);
  261. }
  262.  
  263. hash(name)
  264.     register char *name;
  265. {
  266.     register int h, i;
  267.  
  268.     h = 0;
  269.     /* name may be only UT_NAMESIZE long and not terminated */
  270.     for (i = UT_NAMESIZE; --i >= 0 && *name;)
  271.         h = ((h << 2 | h >> HBITS - 2) ^ *name++) & HMASK;
  272.     return(h);
  273. }
  274.  
  275. PERSON *
  276. palloc()
  277. {
  278.     PERSON *p;
  279.  
  280.     if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) {
  281.         (void)fprintf(stderr, "finger: out of space.\n");
  282.         exit(1);
  283.     }
  284.     return(p);
  285. }
  286.  
  287. WHERE *
  288. walloc(pn)
  289.     register PERSON *pn;
  290. {
  291.     register WHERE *w;
  292.  
  293.     if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) {
  294.         (void)fprintf(stderr, "finger: out of space.\n");
  295.         exit(1);
  296.     }
  297.     if (pn->whead == NULL)
  298.         pn->whead = pn->wtail = w;
  299.     else {
  300.         pn->wtail->next = w;
  301.         pn->wtail = w;
  302.     }
  303.     w->next = NULL;
  304.     return(w);
  305. }
  306.  
  307. char *
  308. prphone(num)
  309.     char *num;
  310. {
  311.     register char *p;
  312.     int len;
  313.     static char pbuf[15];
  314.  
  315.     /* don't touch anything if the user has their own formatting */
  316.     for (p = num; *p; ++p)
  317.         if (!isdigit(*p))
  318.             return(num);
  319.     len = p - num;
  320.     p = pbuf;
  321.     switch(len) {
  322.     case 11:            /* +0-123-456-7890 */
  323.         *p++ = '+';
  324.         *p++ = *num++;
  325.         *p++ = '-';
  326.         /* FALLTHROUGH */
  327.     case 10:            /* 012-345-6789 */
  328.         *p++ = *num++;
  329.         *p++ = *num++;
  330.         *p++ = *num++;
  331.         *p++ = '-';
  332.         /* FALLTHROUGH */
  333.     case 7:                /* 012-3456 */
  334.         *p++ = *num++;
  335.         *p++ = *num++;
  336.         *p++ = *num++;
  337.         break;
  338.     case 5:                /* x0-1234 */
  339.     case 4:                /* x1234 */
  340.         *p++ = 'x';
  341.         *p++ = *num++;
  342.         break;
  343.     default:
  344.         return(num);
  345.     }
  346.     if (len != 4) {
  347.         *p++ = '-';
  348.         *p++ = *num++;
  349.     }
  350.     *p++ = *num++;
  351.     *p++ = *num++;
  352.     *p++ = *num++;
  353.     *p = '\0';
  354.     return(pbuf);
  355. }
  356.