home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / ytalk-3.0.1 / user.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-27  |  6.7 KB  |  328 lines

  1. /* user.c -- user database */
  2.  
  3. /*               NOTICE
  4.  *
  5.  * Copyright (c) 1990,1992,1993 Britt Yenne.  All rights reserved.
  6.  * 
  7.  * This software is provided AS-IS.  The author gives no warranty,
  8.  * real or assumed, and takes no responsibility whatsoever for any 
  9.  * use or misuse of this software, or any damage created by its use
  10.  * or misuse.
  11.  * 
  12.  * This software may be freely copied and distributed provided that
  13.  * no part of this NOTICE is deleted or edited in any manner.
  14.  * 
  15.  */
  16.  
  17. /* Mail comments or questions to ytalk@austin.eds.com */
  18.  
  19. #include "header.h"
  20. #include <pwd.h>
  21.  
  22. extern char *getlogin();
  23.  
  24. yuser *me;            /* my user information */
  25. yuser *user_list;        /* list of invited/connected users */
  26. yuser *connect_list;        /* list of connected users */
  27. yuser *wait_list;        /* list of connected users */
  28. yuser *fd_to_user[MAX_FILES];    /* convert file descriptors to users */
  29. yuser *key_to_user[128];    /* convert menu ident chars to users */
  30. ylong def_flags = 0L;        /* default FL_* flags */
  31. static ylong daemon_id;    /* running daemon ID counter */
  32.  
  33. /* ---- local functions ----- */
  34.  
  35. static int passwd_opened = 0;
  36.  
  37. static int
  38. user_id(name)
  39.   char *name;
  40. {
  41.     register struct passwd *pw;
  42.     passwd_opened = 1;
  43.     if((pw = getpwnam(name)) == NULL)
  44.     return -60000;    /* for most archs, an impossible user ID */
  45.     return pw->pw_uid;
  46. }
  47.  
  48. static char *
  49. user_name(uid)
  50.   int uid;
  51. {
  52.     register struct passwd *pw;
  53.     passwd_opened = 1;
  54.     if((pw = getpwuid(uid)) == NULL)
  55.     return NULL;
  56.     return pw->pw_name;
  57. }
  58.  
  59. static void
  60. close_passwd()
  61. {
  62.     if(passwd_opened)
  63.     {
  64.     (void)endpwent();
  65.     passwd_opened = 0;
  66.     }
  67. }
  68.  
  69. static void
  70. generate_full_name(user)
  71.   yuser *user;
  72. {
  73.     register char *c, *d, *ce;
  74.  
  75.     if(user->full_name == NULL)
  76.     user->full_name = get_mem(50);
  77.     c = user->full_name, ce = user->full_name + 49;
  78.  
  79.     for(d = user->user_name; *d && c < ce; d++)
  80.     *(c++) = *d;
  81.  
  82.     if(c < ce)
  83.     *(c++) = '@';
  84.     for(d = user->host_name; *d && c < ce; d++)
  85.     *(c++) = *d;
  86.  
  87.     if(user->tty_name[0])
  88.     {
  89.     if(c < ce)
  90.         *(c++) = '#';
  91.     for(d = user->tty_name; *d && c < ce; d++)
  92.         *(c++) = *d;
  93.     }
  94.  
  95.     *c = '\0';
  96. }
  97.  
  98. static void
  99. assign_key(user)
  100.   yuser *user;
  101. {
  102.     register ychar old;
  103.     static ychar key = 'a';
  104.  
  105.     if(user->key != '\0' || user == me || user_list == NULL)
  106.     return;
  107.     old = key;
  108.     do {
  109.     if(key_to_user[key] == NULL)
  110.     {
  111.         key_to_user[key] = user;
  112.         user->key = key;
  113.         return;
  114.     }
  115.  
  116.     if(key == 'z')
  117.         key = 'A';
  118.     else if(key == 'Z')
  119.         key = 'a';
  120.     else
  121.         key++;
  122.     } while(old != key);
  123.     user->key = '\0';
  124. }
  125.  
  126. /* ---- global functions ----- */
  127.  
  128. /* Initialize user data structures.
  129.  */
  130. void
  131. init_user()
  132. {
  133.     int my_uid;
  134.     char *my_name;
  135.     char my_host[100];
  136.  
  137.     user_list = NULL;
  138.     connect_list = NULL;
  139.     wait_list = NULL;
  140.     daemon_id = getpid() << 10;
  141.     (void)memset(fd_to_user, 0, MAX_FILES * sizeof(yuser *));
  142.     (void)memset(key_to_user, 0, 128 * sizeof(yuser *));
  143.     my_uid = getuid();
  144.  
  145.     /* get my username */
  146.  
  147.     if((my_name = getlogin()) != NULL)
  148.     if(user_id(my_name) != my_uid)
  149.         my_name = NULL;
  150.     if(my_name == NULL)
  151.     my_name = user_name(my_uid);
  152.     if(my_name == NULL)
  153.     my_name = getlogin();
  154.     if(my_name == NULL || my_name[0] == '\0')
  155.     {
  156.     show_error("Who are you?");
  157.     bail(YTE_ERROR);
  158.     }
  159.  
  160.     /* get my hostname */
  161.  
  162.     if(gethostname(my_host, 100) < 0)
  163.     {
  164.     show_error("init_user: gethostname() failed");
  165.     bail(YTE_ERROR);
  166.     }
  167.  
  168.     /* get my user record */
  169.  
  170.     if((me = new_user(my_name, my_host, NULL)) == NULL)
  171.     bail(YTE_ERROR);
  172.     me->remote.protocol = YTP_NEW;
  173.     me->remote.vmajor = VMAJOR;
  174.     me->remote.vminor = VMINOR;
  175.     me->remote.pid = getpid();
  176.  
  177.     close_passwd();
  178. }
  179.  
  180. /* Create a new user record.
  181.  */
  182. yuser *
  183. new_user(name, hostname, tty)
  184.   char *name, *hostname, *tty;
  185. {
  186.     register yuser *out, *u;
  187.     ylong addr;
  188.  
  189.     /* find the host address */
  190.  
  191.     if(hostname == NULL || *hostname == '\0')
  192.     {
  193.     hostname = me->host_name;
  194.     addr = me->host_addr;
  195.     }
  196.     else if((addr = get_host_addr(hostname)) == (ylong)-1)
  197.     {
  198.     sprintf(errstr, "new_user: bad host: '%s'\n", hostname);
  199.     show_error(errstr);
  200.     return NULL;
  201.     }
  202.  
  203.     /* create the user record */
  204.  
  205.     out = (yuser *)get_mem(sizeof(yuser));
  206.     (void)memset(out, 0, sizeof(yuser));
  207.     out->user_name = str_copy(name);
  208.     out->host_name = str_copy(hostname);
  209.     out->host_addr = addr;
  210.     if(tty)
  211.     out->tty_name = str_copy(tty);
  212.     else
  213.     out->tty_name = str_copy("");
  214.     out->d_id = daemon_id++;
  215.     generate_full_name(out);
  216.     assign_key(out);
  217.     out->flags = def_flags;
  218.  
  219.     /* Actually make an effort to keep the user list in order */
  220.  
  221.     if(user_list == NULL || out->key <= user_list->key)
  222.     {
  223.     out->unext = user_list;
  224.     user_list = out;
  225.     }
  226.     else
  227.     {
  228.     for(u = user_list; u->unext != NULL; u = u->unext)
  229.         if(out->key <= u->unext->key)
  230.         break;
  231.     out->unext = u->unext;
  232.     u->unext = out;
  233.     }
  234.     return out;
  235. }
  236.  
  237. void
  238. free_user(user)
  239.   yuser *user;
  240. {
  241.     register yuser *u;
  242.  
  243.     /* remove him from the various blacklists */
  244.  
  245.     if(user == user_list)
  246.     user_list = user->unext;
  247.     else
  248.     for(u = user_list; u; u = u->unext)
  249.         if(u->unext == user)
  250.         {
  251.         u->unext = user->unext;
  252.         break;
  253.         }
  254.  
  255.     if(user == connect_list)
  256.     connect_list = user->next;
  257.     else
  258.     for(u = connect_list; u; u = u->next)
  259.         if(u->next == user)
  260.         {
  261.         u->next = user->next;
  262.         break;
  263.         }
  264.  
  265.     if(user == wait_list)
  266.     wait_list = user->next;
  267.     else
  268.     for(u = wait_list; u; u = u->next)
  269.         if(u->next == user)
  270.         {
  271.         u->next = user->next;
  272.         break;
  273.         }
  274.  
  275.     /* close him down */
  276.  
  277.     close_term(user);
  278.     free(user->full_name);
  279.     free(user->user_name);
  280.     free(user->host_name);
  281.     free(user->tty_name);
  282.     if(user->dbuf)
  283.     free(user->dbuf);
  284.     if(user->output_fd > 0)
  285.     close(user->output_fd);
  286.     if(user->fd)
  287.     {
  288.     remove_fd(user->fd);
  289.     fd_to_user[user->fd] = NULL;
  290.     close(user->fd);
  291.     }
  292.     if(user->key != '\0')
  293.     key_to_user[user->key] = NULL;
  294.     free(user);
  295.     if(connect_list == NULL && wait_list != NULL)
  296.     msg_term(me, "Waiting for connection...");
  297.     user_winch = 1;
  298. }
  299.  
  300. /* Find a user by name/host/pid.  If name is NULL, then it is not checked.
  301.  * If host_addr is (ylong)-1 then it is not checked.  If pid is (ylong)-1
  302.  * then it is not checked.
  303.  */
  304. yuser *
  305. find_user(name, host_addr, pid)
  306.   char *name;
  307.   ylong host_addr, pid;
  308. {
  309.     register yuser *u;
  310.  
  311.     for(u = user_list; u; u = u->unext)
  312.     if(name == NULL || strcmp(u->user_name, name) == 0)
  313.         if(host_addr == (ylong)-1 || u->host_addr == host_addr)
  314.         if(pid == (ylong)-1 || u->remote.pid == pid)
  315.             return u;
  316.     
  317.     /* it could be _me_! */
  318.  
  319.     if(name == NULL || strcmp(me->user_name, name) == 0)
  320.     if(host_addr == (ylong)-1 || me->host_addr == host_addr)
  321.         if(pid == (ylong)-1 || me->remote.pid == pid)
  322.         return me;
  323.  
  324.     /* nobody I know */
  325.  
  326.     return NULL;
  327. }
  328.