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

#ifndef	lint
static	char	RCSid[] = "$Header: /usr/users/mjr/hacks/umud/RWHO/RCS/mudwho.c,v 1.1 91/06/17 14:39:27 mjr Rel $";
#endif


#include	<stdio.h>
#include	<sys/types.h>
#include	<errno.h>
extern	int	errno;
#include	<ctype.h>
#include	<fcntl.h>
#include	<sys/file.h>
#include	<sys/time.h>
#include	<sys/socket.h>
#include	<netinet/in.h>
#include	<netdb.h>


#define	STREAMPORT		6889

#define	ENVHOST		"MUDWHOSERVER"
#define	ENVPORT		"MUDWHOPORT"


#ifndef	NO_HUGE_RESOLVER_CODE
extern	struct	hostent	*gethostbyname();
#endif

extern	char	*getenv();
extern	char	*optarg;


main(ac,av)
int	ac;
char	*av[];
{
	struct	sockaddr_in	addr;
	struct	hostent		*hp;
	int			fd;
	char			*p;
	int			red;
	char			rbuf[1024];
	char			*srv = (char *)0;
	int			portnum = STREAMPORT;
	char			*checkwho = (char *)0;
	char			*checkmud = (char *)0;

	srv = getenv(ENVHOST);
	if((p = getenv(ENVPORT)) != (char *)0)
		portnum = atoi(p);

	while((red = getopt(ac,av,"S:P:u:m:")) != EOF) {
		switch(red) {
		case 'S':
			srv = optarg;
			break;

		case 'P':
			portnum = atoi(optarg);
			break;

		case 'u':
			checkwho = optarg;
			break;

		case 'm':
			checkmud = optarg;
			break;

		default:
			exit(usage());
		}
	}

	if(srv == (char *)0) {
		fprintf(stderr,"rwho server host must be provided [-h host]\n");
		exit(1);
	}

	if(checkmud != (char *)0 && checkwho != (char *)0) {
		fprintf(stderr,"You can only search for one user or MUD entry\n");
		exit(1);
	}


	p = srv;
	while(*p != '\0' && (*p == '.' || isdigit(*p)))
		p++;

	/* not all digits or dots */
	if(*p != '\0') {
#ifndef	NO_HUGE_RESOLVER_CODE
		if((hp = gethostbyname(srv)) == (struct hostent *)0) {
			fprintf(stderr,"unknown host %s\n",srv);
			exit(1);
		}

		(void)bcopy(hp->h_addr,(char *)&addr.sin_addr,hp->h_length);
#else
		fprintf(stderr,"must use numerical notation for host name\n");
		exit(1);
#endif
	} else {
		unsigned long	f;

		if((f = inet_addr(srv)) == -1L) {
			fprintf(stderr,"unknown host %s\n",srv);
			exit(1);
		}
		(void)bcopy((char *)&f,(char *)&addr.sin_addr,sizeof(f));
	}

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

	if((fd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
		perror("socket");
		exit(1);
	}

	if(connect(fd,&addr,sizeof(addr)) < 0) {
		perror("connect");
		exit(1);
	}


	/* send request if one */
	if(checkmud != (char *)0 || checkwho != (char *)0) {
		char	xuf[512];
		int	xlen;

		sprintf(xuf,"%s=%.30s",
			checkmud == (char *)0 ? "who" : "mud",
			checkmud == (char *)0 ? checkwho : checkmud);

		xlen = strlen(xuf) + 1;
		if(write(fd,xuf,xlen) != xlen) {
			perror("write to rwho server failed");
			exit(1);
		}
	}


	while((red = read(fd,rbuf,sizeof(rbuf))) > 0)
		write(1,rbuf,red);
	exit(0);
}



usage()
{
	fprintf(stderr,"usage: mudwho [-S server] [-P servport] [-u user] [-m mud]\n");
	fprintf(stderr,"\twhere user is someone to scan for\n");
	fprintf(stderr,"\tmud is a specific MUD to scan for\n");
	fprintf(stderr,"\t%s and %s can be set in the environment\n",ENVPORT,ENVHOST);
	return(1);
}