/*
 * $Header: /udir/vixie/src/mail11/d-1.7beta/RCS/sunlink-dni.c,v 1.1 1991/09/02 23:58:25 vixie Exp vixie $
 * Copyright (c) 1989 Keith Moore
 */
/*
 * These routines maintain a single connection to a DECnet object.
 * This implementation for a Sun running Sunlink/DNI.
 */

#include "mail11.h"
#include "decnet.h"
#include <sys/ioctl.h>
#ifdef OLD_SUNLINK_DNI
#include <netdna/dna.h>
#else
#include <netdni/dni.h>
#endif
#include <ctype.h>

static int decnet_in;
static int decnet_out;
extern char *DECNET_RemoteUser;
extern char *DECNET_RemoteNode;
extern char *DECNET_NodeName;
extern char *strsave ();
extern char *gethostname ();
extern char *strchr ();

int
DECNET_Read (buf, size)
char *buf;
{
    return read (decnet_in, buf, size);
}

int
DECNET_Write (buf, size)
char *buf;
{
    return write (decnet_out, buf, size);
}

/*
 * return true iff the other end closed the DECnet channel.
 */
int
DECNET_EOF ()
{
#if 1
    return 0;
#else
    /* This wasn't working properly.  Fortunately the mail-11 protocol
       is such that you don't have to detect EOF to make things work --
       only to recover from failures intelligently. -km */
    long status;
    if (ioctl (decnet_in, SES_STATUS, &status) == 0 &&
	status == LINK_CONNECT)
	return 0;
    return 1;
#endif
}

/*
 * LOG a DECnet-specific error message for the last error.
 * For now, we do nothing.
 * Eventually this should go to the system logger.
 * (mabye the error should be mailed to postmaster?)
 */
DECNET_Error (message)
char *message;
{
}

/*
 * For now, the DECNET object spawner does the job of accepting the
 * DECnet connection and setting things up.  All we do is initialize
 * some variables.
 *
 * Eventually, we should exchange configuration information with the
 * other DECnet task.
 */
void
DECNET_AcceptConnection (client_config, server_config)
struct mail11_config *client_config, *server_config;
{
    OpenBlock open_block;
    SessionData session_data;
    char buf[100];
    char *ptr;

    decnet_in = decnet_out = 3;

    /* Get access control information, including config information */
    if (ioctl (decnet_in, SES_GET_AI, &open_block) < 0) {
	DECNET_Error ("mail11d: can't get access control information");
	exit (1);
    }

    /* copy config information (if present) into our structure */
    if (open_block.op_opt_data.im_length > 0)
	GetConfigInfo (client_config, open_block.op_opt_data.im_data);

    PrintConfigInfo ("client info", client_config);
    if (client_config->iomode & CCSEND)
	server_config->iomode |= CCRECV;
    if (client_config->iomode & BLKSEND)
	server_config->iomode |= BLKRECV;
    PrintConfigInfo ("server info", server_config);

    /* copy our config information into accept buffer */
    session_data.sd_data.im_length = 16;
    PutConfigInfo (session_data.sd_data.im_data, server_config);

    /* accept connection, passing our config data */
    if (ioctl (decnet_in, SES_ACCEPT, &session_data) < 0) {
	DECNET_Error ("mail11d: cannot accept inbound connection");
	exit (1);
    }

    DECNET_RemoteNode = strsave (open_block.op_node_name);
    DECNET_RemoteUser = strsave (open_block.op_userid);
    /*
     * SunLink/DNI needs a call to get the DECnet name of the local host.
     * The cheap way to do this is to call gethostname(), but this may
     * not yield the desired result.  A more robust way to do this is
     * to get the DECnet name of node 0.
     */
    gethostname (buf, sizeof buf);
    if ((ptr = strchr (buf, '.')))
	*ptr = '\0';
    for (ptr = buf; *ptr; ++ptr)
	if (islower (*ptr))
	    *ptr = toupper (*ptr);
    DECNET_NodeName = strsave (buf);
}
