#ifndef lint
static char *RCSid = "$Header: user.c,v 1.3 90/03/19 11:30:11 mr-frog Exp $";
#endif

/*
 * user.c
 *
 * get a new user
 *
 * Dave Pare, 1986
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include "user.h"
#include "tm.h"
#include "misc.h"

#include "io.h"

struct	user userlist;

user_init()
{
	initque(&userlist.queue);
}

/*ARGSUSED*/
user_add(iop, op, assoc)
	iop_t	iop;
	int	op;
	s_char	*assoc;
{
	extern	int service();
	extern	int fd_reserve;
	struct	user *up;
	struct	sockaddr_un un;
	int	foo;
	int	ns;

	foo = sizeof(un);
	ns = accept(io_fileno(iop), (struct sockaddr *) &un, &foo);
	if (ns < 0) {
		logerror("new socket accept");
		return;
	}
	if (ns >= fd_reserve) {
		close(ns);
		logerror("new fd %d, max fd %d, no fd's left for new user!",
			ns, fd_reserve);
		return;
	}
	up = (struct user *) malloc(sizeof(*up));
	up->u_iop = io_open(ns, IO_READ|IO_WRITE, 4096, service, (s_char *)up);
	if (up->u_iop == 0) {
		(void) close(ns);
		logerror("io_open failed");
		return;
	}
	up->u_cnum = -1;
	up->u_pid = 0;
	insque(&up->queue, &userlist.queue);
	io_noblocking(up->u_iop, 1);
	sendnum(up->u_iop, 0, TM_OK);	/* its first packet, thus seq=0 */
}

user_remove(up)
	struct	user *up;
{
	remque(&up->queue);
	unlock_clean(up);
	io_close(up->u_iop);
	free((s_char *)up);
}
