DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦c9eea8efd⟧ TextFile

    Length: 5470 (0x155e)
    Types: TextFile
    Names: »connect.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Xgo/connect.c« 

TextFile

/*
 * $Header: connect.c,v 1.2 88/02/13 12:43:37 hale Exp $
 */

/*

        Copyright 1987      Greg Hale

Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation.  No representations are made about the
suitability of this software for any purpose.  It is
provided "as is" without express or implied warranty.

*/


#include "go.h"
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <errno.h>

/*
 * Some systems do not have these defined in the include files.
 */
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
typedef short uid_t;
#endif

char *opponent;
char myhostname[MAXHOSTNAMELEN+1];
extern char *myname;

extern int errno;

FILE *inp, *out;

connectport (oppon, port)
char *oppon;
u_short port;
{
	struct sockaddr_in addr;
	struct hostent *host;
	struct passwd *mypasswd, *getpwuid();
	char *hishostname, *index(), *getpw(), *malloc();
	char *hisaddr, *myaddr;
	int hislen, mylen;
	u_long iaddr;
	uid_t getuid();
	u_short hashport(), hashaddr();
	char *copyhost();
	int s, i;

	opponent = oppon;
	if (gethostname (myhostname, MAXHOSTNAMELEN) < 0)
		error ("gethostname in connectport");
	host = gethostbyname(myhostname);
	if (host == NULL) {
		errno = 0;
		error("don't know my own name.");
	}
	mylen = host->h_length;
	myaddr = copyhost(host);
	if (hishostname = index (oppon, '@')) {
		*hishostname++ = '\0';        /* separate user and host */
		if (hishostname[0] >= '0' && hishostname[0] <= '9') {
			iaddr = inet_addr(hishostname);
			hisaddr = (char *)&iaddr;
			hislen = sizeof iaddr;
		} else {
			host = gethostbyname(hishostname);
			if (host == NULL) {
				errno = 0;
				error("Unknown host");
			}
			hislen = host->h_length;
			hisaddr = copyhost(host);
			hishostname = host->h_name;
		}
	} else {
		hislen = mylen;
		hisaddr = myaddr;
		hishostname = myhostname;
	}
	mypasswd = getpwuid ((int) getuid());
	myname = mypasswd -> pw_name;

	if (iamserver == UNSET)
		if (i = strcmp (myname, oppon))
			iamserver = (i < 0);
		else if (i = comparehost(myaddr, hisaddr, mylen))
			iamserver = (i < 0);
	if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
		error ("socket in connectport");
	bzero ((char *) &addr, sizeof (addr));
	if (port != 0) {
		if (port > 1000) {
			errno = 0;
			error ("bad port number");
		}
	} else if (iamserver) {
		port = hashaddr(myaddr, port, mylen);
		port = hashaddr(hisaddr, port, hislen);
		port = hashport(myname, port);
		port = hashport(oppon, port);
	} else {
		port = hashaddr(hisaddr, port, hislen);
		port = hashaddr(myaddr, port, mylen);
		port = hashport(oppon, port);
		port = hashport(myname, port);
	}
	port += 3000;
	addr.sin_family = AF_INET;
	addr.sin_port = htons (port);

	connectmes();

	if (iamserver) {
		s = sock;
		if (bind (s, /*(char *)*/ &addr, sizeof (addr)) < 0)
			if (errno == EADDRINUSE && iamserver == UNSET) {
				/* hope other player is server */
				iamserver = FALSE;
				close (s);
				if ((sock = socket (AF_INET, SOCK_STREAM, 0))
				    < 0)
					error ("socket in connectport");
			} else
				error ("bind in connectport");
		if (iamserver) {
			if (listen (s, 1) < 0)
				error ("listen in connectport");
			while ((sock = accept (s, (struct sockaddr_in *) NULL,
			    (int *) NULL)) < 0)
				if (errno != EINTR)
					error ("accept in connectport");
			close(s);
		}
	}
	if (!iamserver) {
		bcopy (hisaddr, (char *) &addr.sin_addr, hislen);
		while (connect (sock, /*(char *)*/ &addr, sizeof (addr)) < 0)
			if ( errno == EINTR || errno == ECONNREFUSED) {
				close (sock);
				sleep(2);
				if ((sock = socket (AF_INET, SOCK_STREAM, 0))
				    < 0)
					error ("socket in connectport");
			} else
				error ("connect in connectport");
	}
	if ((s = dup(sock)) < 0)
		error("dup");
	if ((inp = fdopen(sock, "r")) == NULL)
		error("fdopen");
	if ((out = fdopen(s, "w")) == NULL)
		error("fdopen");
	setlinebuf(out);

	sockmask[1] = 1 << sock;
}

u_short hashport (s, port)
	char *s;
	u_short port;
{
	while (*s)
		port = (port << 1) + *s++;
	return (port & 0x7fff);
}

/*
 * addr is in network byte order.
 */
u_short hashaddr(addr, port, len)
u_short port;
char *addr;
{

	while (len--)
		port = (port << 1) + *addr++;
	return (port & 0x7fff);
}

char *copyhost(host)
struct hostent *host;
{
	char *ret;

	ret = malloc(host->h_length);
	if (ret == NULL)
		error("malloc");
	bcopy(host->h_addr, ret, host->h_length);

	return ret;
}

comparehost(h1, h2, len)
char *h1, *h2;
{
	auto unsigned long l1, l2;

	bcopy(h1, &l1, sizeof l1);
	bcopy(h2, &l2, sizeof l2);

	if (l1 < l2)
		return -1;
	else if (l1 > l2)
		return 1;
	return 0;
}


receive(mes)
char *mes;
{
	char num[4];
	int u;
	num[3]='\0';
	if (read (sock,num,3) != 3) {
		error("\n\nError- bad transmission\n");
		getch();
	}
	u=read(sock,mes,atoi(num));
	mes[u]='\0';
	if (u !=  atoi(num)){
		error("\n\nRECEIVE: length does not match.\n");
	}
}


sendit(mes)
char *mes;
{
	char tbuf[MAXBUF];
	sprintf(tbuf,"%03d%s",strlen(mes),mes);
	write(sock,tbuf,strlen(tbuf));
}

readint(i)
int *i;
{
	RECV(buf);
	*i = atoi (buf);
}

sendint(i)
int i;
{
	sprintf(buf,"%d",i);
	SEND(buf);
}

/*
 * $Log:	connect.c,v $
 * Revision 1.2  88/02/13  12:43:37  hale
 * modified command line lookup of opponents name and saved as variable.
 * 
 */