/*
 * Copyright 1990 by Baylor College of Medicine ALL RIGHTS RESERVED. 
 *
 * This program is subject to a license agreement between 
 * Baylor College of Medicine and MIT. Any use inconsistent with
 * said license and any use by persons other than the faculty, 
 * students and staff at MIT or any use on a computer not operated 
 * as part of the Athena Computing Environment (ACE) is expressly 
 * prohibited.
 */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <malloc.h>

#include "dbsrv.h"

/* Finds database name in list of databases */
dbDatabase
find_database(db_name)
	char *db_name ;
{
	dbDatabase db = pc.dbs ;
	while(db != NULL)
	{
		if (!strcmp(db_name,db->name))
		{
			return db ;
		}
		db = db->next ;
	}
	return NULL ;
}

/*
 *	Processes connection requests.  Returns -1 if error.
 */
proc_init_info(c)
	Connection c ;
{
	long author_id ;
	dbDatabase db ;
	long client_major;
	long client_minor;
	dbAuthor author ;
	int err;

	/* get the major and minor protocol version numbers */
	if (read_f(c->conn_sock,"ll",&client_major,&client_minor) < 0)
	{
		return -1 ;
	}

	/* check the protocol version numbers and notify client */
	if (client_major != VNS_PROTO_MAJOR || client_minor != VNS_PROTO_MINOR)
	{
		write_f(c->conn_sock,"lll",-1,VNS_PROTO_MAJOR,VNS_PROTO_MINOR);
		return -1 ;
	}
	else
	{
		if (write_f(c->conn_sock,"lll",0,VNS_PROTO_MAJOR,VNS_PROTO_MINOR) < 0)
		{
			return -1;
		}
	}

	/* obtain the author id and the database name for checking authorization */
	{
		char db_name[256] ;
		if (read_f(c->conn_sock,"ls",&author_id,db_name,sizeof db_name) < 0)
		{
			return -1 ;
		}

		/* check if database is valid */
		db = find_database(db_name) ;
		if (db == NULL)
		{
			/* database is invalid (-1) */
			write_f(c->conn_sock,"l",-1);
			return -1 ;
		}

		/* check if the author is valid for the database specified */
		author = find_author_by_id(db,(int)author_id) ;
		if (author == NULL)
		{
			/* database is invalid (-1) */
			write_f(c->conn_sock,"l",-2);
			return -1 ;
		}

		/* allow the connection and set authorization level */
		if (pc.vns_uid == (int)author_id)
		{
			if (write_f(c->conn_sock,"l",1) < 0)
			{
				return -1;
			}
		}
		else
		{
			if (write_f(c->conn_sock,"l",0) < 0)
			{
				return -1;
			}
		}
	}

	/* Put in the information */
	c->db = db ;
	c->author = author ;

	/* Now set the state to being able to receive requests */
	c->state = STATE_REQ_OK ;

	/* tell everyone else about the new connection */
	{
		Connection cp = pc.cl.first;

		while(cp != NULL)
		{
			if (c != cp)
			{
				write_f(cp->conn_sock,"lll",EVT_AUTHOR_LOGIN,sizeof(long),c->author);
			}
			cp = cp->next;
		}
	}

	return 0 ;
}
