home *** CD-ROM | disk | FTP | other *** search
- /* user.c -- user database */
-
- /* NOTICE
- *
- * Copyright (c) 1990,1992,1993 Britt Yenne. All rights reserved.
- *
- * This software is provided AS-IS. The author gives no warranty,
- * real or assumed, and takes no responsibility whatsoever for any
- * use or misuse of this software, or any damage created by its use
- * or misuse.
- *
- * This software may be freely copied and distributed provided that
- * no part of this NOTICE is deleted or edited in any manner.
- *
- */
-
- /* Mail comments or questions to ytalk@austin.eds.com */
-
- #include "header.h"
- #include <pwd.h>
-
- extern char *getlogin();
-
- yuser *me; /* my user information */
- yuser *user_list; /* list of invited/connected users */
- yuser *connect_list; /* list of connected users */
- yuser *wait_list; /* list of connected users */
- yuser *fd_to_user[MAX_FILES]; /* convert file descriptors to users */
- yuser *key_to_user[128]; /* convert menu ident chars to users */
- u_long def_flags = 0L; /* default FL_* flags */
- static u_long daemon_id; /* running daemon ID counter */
-
- /* ---- local functions ----- */
-
- static int passwd_opened = 0;
-
- static int
- user_id(name)
- char *name;
- {
- register struct passwd *pw;
- passwd_opened = 1;
- if((pw = getpwnam(name)) == NULL)
- return -1;
- return pw->pw_uid;
- }
-
- static char *
- user_name(uid)
- int uid;
- {
- register struct passwd *pw;
- passwd_opened = 1;
- if((pw = getpwuid(uid)) == NULL)
- return NULL;
- return pw->pw_name;
- }
-
- static void
- close_passwd()
- {
- extern void endpwent();
-
- if(passwd_opened)
- {
- endpwent();
- passwd_opened = 0;
- }
- }
-
- static void
- generate_full_name(user)
- yuser *user;
- {
- register char *c, *d, *ce;
-
- if(user->full_name == NULL)
- user->full_name = get_mem(50);
- c = user->full_name, ce = user->full_name + 49;
-
- for(d = user->user_name; *d && c < ce; d++)
- *(c++) = *d;
-
- if(c < ce)
- *(c++) = '@';
- for(d = user->host_name; *d && c < ce; d++)
- *(c++) = *d;
-
- if(user->tty_name[0])
- {
- if(c < ce)
- *(c++) = '#';
- for(d = user->tty_name; *d && c < ce; d++)
- *(c++) = *d;
- }
-
- *c = '\0';
- }
-
- static void
- assign_key(user)
- yuser *user;
- {
- register ychar old;
- static ychar key = 'a';
-
- if(user->key != '\0' || user == me || user_list == NULL)
- return;
- old = key;
- do {
- if(key_to_user[key] == NULL)
- {
- key_to_user[key] = user;
- user->key = key;
- return;
- }
-
- if(key == 'z')
- key = 'A';
- else if(key == 'Z')
- key = 'a';
- else
- key++;
- } while(old != key);
- user->key = '\0';
- }
-
- /* ---- global functions ----- */
-
- /* Initialize user data structures.
- */
- void
- init_user()
- {
- int my_uid;
- char *my_name;
- char my_host[100];
-
- user_list = NULL;
- connect_list = NULL;
- wait_list = NULL;
- daemon_id = getpid() << 10;
- (void)memset(fd_to_user, 0, MAX_FILES * sizeof(yuser *));
- (void)memset(key_to_user, 0, 128 * sizeof(yuser *));
- my_uid = getuid();
-
- /* get my username */
-
- if((my_name = getlogin()) != NULL)
- if(my_uid < 0 || user_id(my_name) != my_uid)
- my_name = NULL;
- if(my_name == NULL)
- my_name = user_name(getuid());
- if(my_name == NULL)
- {
- show_error("Who are you?");
- bail(YTE_ERROR);
- }
-
- /* get my hostname */
-
- if(gethostname(my_host, 100) < 0)
- {
- show_error("init_user: gethostname() failed");
- bail(YTE_ERROR);
- }
-
- /* get my user record */
-
- if((me = new_user(my_name, my_host, NULL)) == NULL)
- bail(YTE_ERROR);
- me->remote.protocol = YTP_NEW;
- me->remote.vmajor = VMAJOR;
- me->remote.vminor = VMINOR;
- me->remote.pid = getpid();
-
- close_passwd();
- }
-
- /* Create a new user record.
- */
- yuser *
- new_user(name, hostname, tty)
- char *name, *hostname, *tty;
- {
- register yuser *out, *u;
- u_long addr;
-
- /* find the host address */
-
- if(hostname == NULL || *hostname == '\0')
- {
- hostname = me->host_name;
- addr = me->host_addr;
- }
- else if((addr = get_host_addr(hostname)) == (u_long)-1)
- {
- sprintf(errstr, "new_user: bad host: '%s'\n", hostname);
- show_error(errstr);
- return NULL;
- }
-
- /* create the user record */
-
- out = (yuser *)get_mem(sizeof(yuser));
- (void)memset(out, 0, sizeof(yuser));
- out->user_name = str_copy(name);
- out->host_name = str_copy(hostname);
- out->host_addr = addr;
- if(tty)
- out->tty_name = str_copy(tty);
- else
- out->tty_name = str_copy("");
- out->d_id = daemon_id++;
- generate_full_name(out);
- assign_key(out);
- out->flags = def_flags;
-
- /* Actually make an effort to keep the user list in order */
-
- if(user_list == NULL || out->key <= user_list->key)
- {
- out->unext = user_list;
- user_list = out;
- }
- else
- {
- for(u = user_list; u->unext != NULL; u = u->unext)
- if(out->key <= u->unext->key)
- break;
- out->unext = u->unext;
- u->unext = out;
- }
- return out;
- }
-
- void
- free_user(user)
- yuser *user;
- {
- register yuser *u;
-
- /* remove him from the various blacklists */
-
- if(user == user_list)
- user_list = user->unext;
- else
- for(u = user_list; u; u = u->unext)
- if(u->unext == user)
- {
- u->unext = user->unext;
- break;
- }
-
- if(user == connect_list)
- connect_list = user->next;
- else
- for(u = connect_list; u; u = u->next)
- if(u->next == user)
- {
- u->next = user->next;
- break;
- }
-
- if(user == wait_list)
- wait_list = user->next;
- else
- for(u = wait_list; u; u = u->next)
- if(u->next == user)
- {
- u->next = user->next;
- break;
- }
-
- /* close him down */
-
- close_term(user);
- free(user->full_name);
- free(user->user_name);
- free(user->host_name);
- free(user->tty_name);
- if(user->dbuf)
- free(user->dbuf);
- if(user->output_fd > 0)
- close(user->output_fd);
- if(user->fd)
- {
- remove_fd(user->fd);
- fd_to_user[user->fd] = NULL;
- close(user->fd);
- }
- if(user->key != '\0')
- key_to_user[user->key] = NULL;
- free(user);
- if(connect_list == NULL && wait_list != NULL)
- msg_term(me, "Waiting for connection...");
- user_winch = 1;
- }
-
- /* Find a user by name/host/pid. If name is NULL, then it is not checked.
- * If host_addr is (u_long)-1 then it is not checked. If pid is (u_long)-1
- * then it is not checked.
- */
- yuser *
- find_user(name, host_addr, pid)
- char *name;
- u_long host_addr, pid;
- {
- register yuser *u;
-
- for(u = user_list; u; u = u->unext)
- if(name == NULL || strcmp(u->user_name, name) == 0)
- if(host_addr == (u_long)-1 || u->host_addr == host_addr)
- if(pid == (u_long)-1 || u->remote.pid == pid)
- return u;
-
- /* it could be _me_! */
-
- if(name == NULL || strcmp(me->user_name, name) == 0)
- if(host_addr == (u_long)-1 || me->host_addr == host_addr)
- if(pid == (u_long)-1 || me->remote.pid == pid)
- return me;
-
- /* nobody I know */
-
- return NULL;
- }
-