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