home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / ytalk-3.0 / part01 / user.c < prev    next >
C/C++ Source or Header  |  1993-08-20  |  7KB  |  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. u_long def_flags = 0L;        /* default FL_* flags */
  31. static u_long 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 -1;
  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.     extern void endpwent();
  63.  
  64.     if(passwd_opened)
  65.     {
  66.     endpwent();
  67.     passwd_opened = 0;
  68.     }
  69. }
  70.  
  71. static void
  72. generate_full_name(user)
  73.   yuser *user;
  74. {
  75.     register char *c, *d, *ce;
  76.  
  77.     if(user->full_name == NULL)
  78.     user->full_name = get_mem(50);
  79.     c = user->full_name, ce = user->full_name + 49;
  80.  
  81.     for(d = user->user_name; *d && c < ce; d++)
  82.     *(c++) = *d;
  83.  
  84.     if(c < ce)
  85.     *(c++) = '@';
  86.     for(d = user->host_name; *d && c < ce; d++)
  87.     *(c++) = *d;
  88.  
  89.     if(user->tty_name[0])
  90.     {
  91.     if(c < ce)
  92.         *(c++) = '#';
  93.     for(d = user->tty_name; *d && c < ce; d++)
  94.         *(c++) = *d;
  95.     }
  96.  
  97.     *c = '\0';
  98. }
  99.  
  100. static void
  101. assign_key(user)
  102.   yuser *user;
  103. {
  104.     register ychar old;
  105.     static ychar key = 'a';
  106.  
  107.     if(user->key != '\0' || user == me || user_list == NULL)
  108.     return;
  109.     old = key;
  110.     do {
  111.     if(key_to_user[key] == NULL)
  112.     {
  113.         key_to_user[key] = user;
  114.         user->key = key;
  115.         return;
  116.     }
  117.  
  118.     if(key == 'z')
  119.         key = 'A';
  120.     else if(key == 'Z')
  121.         key = 'a';
  122.     else
  123.         key++;
  124.     } while(old != key);
  125.     user->key = '\0';
  126. }
  127.  
  128. /* ---- global functions ----- */
  129.  
  130. /* Initialize user data structures.
  131.  */
  132. void
  133. init_user()
  134. {
  135.     int my_uid;
  136.     char *my_name;
  137.     char my_host[100];
  138.  
  139.     user_list = NULL;
  140.     connect_list = NULL;
  141.     wait_list = NULL;
  142.     daemon_id = getpid() << 10;
  143.     (void)memset(fd_to_user, 0, MAX_FILES * sizeof(yuser *));
  144.     (void)memset(key_to_user, 0, 128 * sizeof(yuser *));
  145.     my_uid = getuid();
  146.  
  147.     /* get my username */
  148.  
  149.     if((my_name = getlogin()) != NULL)
  150.     if(my_uid < 0 || user_id(my_name) != my_uid)
  151.         my_name = NULL;
  152.     if(my_name == NULL)
  153.     my_name = user_name(getuid());
  154.     if(my_name == NULL)
  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.     u_long 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)) == (u_long)-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 (u_long)-1 then it is not checked.  If pid is (u_long)-1
  302.  * then it is not checked.
  303.  */
  304. yuser *
  305. find_user(name, host_addr, pid)
  306.   char *name;
  307.   u_long 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 == (u_long)-1 || u->host_addr == host_addr)
  314.         if(pid == (u_long)-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 == (u_long)-1 || me->host_addr == host_addr)
  321.         if(pid == (u_long)-1 || me->remote.pid == pid)
  322.         return me;
  323.  
  324.     /* nobody I know */
  325.  
  326.     return NULL;
  327. }
  328.