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