/*
   Copyright (C) 1991, Marcus J. Ranum. All rights reserved.

   Mod history:

   ANSIfied function headers, 9/91, glenn@ces.cwru.edu
   STREAMS/TLIified, 7/93, vasoll@a.cs.okstate.edu
 */

/*
   code to interface client MUDs with rwho server
   This is a standalone library.
 */

#include "autoconf.h"
#include "copyright.h"
#ifndef	lint
static char *RCSid = "$Id: rwho_clilib.c,v 1.7 1995/03/17 05:28:07 ambar Exp $";
USE(RCSid);
#endif

#include "mudconf.h"
#include "config.h"
#include "externs.h"

#ifndef __bsdi__
#include	<netinet/in.h>
#endif
#include	<netdb.h>

#ifdef TLI
#include <sys/stream.h>
#include <sys/tiuser.h>
#include <sys/tihdr.h>
#include <netinet/netinet.h>
#else
#include <arpa/inet.h>
#endif

static int dgramfd = -1;
static char *password;
static char *localnam;
static char *lcomment;
static struct sockaddr_in addr;

#ifdef TLI
static struct t_unitdata *pbuf;

#endif


/* enable RWHO and send the server a "we are up" message */
int 
rwhocli_setup(server, dgramport, serverpw, myname, comment)
    char *server, *serverpw, *myname, *comment;
    int dgramport;
{
    struct hostent *hp;
#ifndef TLI
    char pbuf[512];

#endif
    char *p;

    if (dgramfd != -1)
	return 1;

    password = strsave(serverpw);
    localnam = strsave(myname);
    lcomment = strsave(comment);
    if (password == (char *) NULL || localnam == (char *) NULL ||
	lcomment == (char *) NULL)
	return 1;

#ifdef TLI
#endif
    p = server;
    while (*p != '\0' && (*p == '.' || isdigit(*p)))
	p++;

    if (*p != '\0') {
	if ((hp = gethostbyname(server)) == (struct hostent *) NULL)
	    return 1;
	(void) bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
    } else {
	unsigned long f;

	if ((f = inet_addr(server)) == -1L)
	    return 1;
	(void) bcopy((char *) &f, (char *) &addr.sin_addr, sizeof(f));
    }

    addr.sin_port = htons(dgramport);
    addr.sin_family = AF_INET;

#ifdef TLI
    if ((dgramfd = t_open(TLI_UDP, O_RDWR, NULL)) < 0)
	return 1;
    if (t_bind(dgramfd, NULL, NULL) < 0) {
	t_close(dgramfd);
	dgramfd = -1;
	return 1;
    }
    pbuf = (struct t_unitdata *) t_alloc(dgramfd, T_UNITDATA, T_ALL);
    if (pbuf == NULL) {
	t_close(dgramfd);
	dgramfd = -1;
	return 1;
    }
    bcopy(&addr, pbuf->addr.buf, sizeof(struct sockaddr_in));
    pbuf->addr.len = sizeof(struct sockaddr_in);

    sprintf(pbuf->udata.buf, "U\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.25s",
	    localnam, password, localnam, (int)mudstate.now, comment);
    pbuf->udata.len = strlen(pbuf->udata.buf);
    t_sndudata(dgramfd, pbuf);
#else
    if ((dgramfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	return 1;

    sprintf(pbuf, "U\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.25s",
	    localnam, password, localnam, (int)mudstate.now, comment);
    sendto(dgramfd, pbuf, strlen(pbuf), 0, (void *) &addr, sizeof(addr));
#endif
    return 0;
}

/* disable RWHO */
int 
NDECL(rwhocli_shutdown)
{
#ifndef TLI
    char pbuf[512];

#endif

    if (dgramfd != -1) {
#ifdef TLI
	sprintf(pbuf->udata.buf, "D\t%.20s\t%.20s\t%.20s",
		localnam, password, localnam);
	pbuf->udata.len = strlen(pbuf->udata.buf);
	t_sndudata(dgramfd, pbuf);
	t_close(dgramfd);
#else
	sprintf(pbuf, "D\t%.20s\t%.20s\t%.20s",
		localnam, password, localnam);
	sendto(dgramfd, pbuf, strlen(pbuf), 0, (void *) &addr, sizeof(addr));
	close(dgramfd);
#endif
	dgramfd = -1;
	free(password);
	free(localnam);
    }
    return 0;
}

/* send an update ping that we're alive */
int 
NDECL(rwhocli_pingalive)
{
#ifndef TLI
    char pbuf[512];

#endif

    if (dgramfd != -1) {
#ifdef TLI
	sprintf(pbuf->udata.buf, "M\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.25s",
		localnam, password, localnam, (int)mudstate.now, lcomment);
	pbuf->udata.len = strlen(pbuf->udata.buf);
	t_sndudata(dgramfd, pbuf);
#else
	sprintf(pbuf, "M\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.25s",
		localnam, password, localnam, (int)mudstate.now, lcomment);
	sendto(dgramfd, pbuf, strlen(pbuf), 0, (void *) &addr, sizeof(addr));
#endif
    }
    return 0;
}

/* send a "so-and-so-logged in" message */
int 
rwhocli_userlogin(uid, name, tim)
    char *uid, *name;
    time_t tim;
{
#ifndef TLI
    char pbuf[512];

#endif

    if (dgramfd != -1) {
#ifdef TLI
	sprintf(pbuf->udata.buf, "A\t%.20s\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.20s",
		localnam, password, localnam, uid, (int)tim, name);
	pbuf->udata.len = strlen(pbuf->udata.buf);
	t_sndudata(dgramfd, pbuf);
#else
	sprintf(pbuf, "A\t%.20s\t%.20s\t%.20s\t%.20s\t%.10d\t0\t%.20s",
		localnam, password, localnam, uid, (int)tim, name);
	sendto(dgramfd, pbuf, strlen(pbuf), 0, (void *) &addr, sizeof(addr));
#endif
    }
    return 0;
}

/* send a "so-and-so-logged out" message */
int 
rwhocli_userlogout(uid)
    char *uid;
{
#ifndef TLI
    char pbuf[512];

#endif

    if (dgramfd != -1) {
#ifdef TLI
	sprintf(pbuf->udata.buf, "Z\t%.20s\t%.20s\t%.20s\t%.20s",
		localnam, password, localnam, uid);
	pbuf->udata.len = strlen(pbuf->udata.buf);
	t_sndudata(dgramfd, pbuf);
#else
	sprintf(pbuf, "Z\t%.20s\t%.20s\t%.20s\t%.20s",
		localnam, password, localnam, uid);
	sendto(dgramfd, pbuf, strlen(pbuf), 0, (void *) &addr, sizeof(addr));
#endif
    }
    return 0;
}
