ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
/*
 * webster - look words up in the dictionary
 *
 * This program connects to the Webster server to get definitions of words.
 * Words may be given on the command line, or, if no arguments are given,
 * the program runs interactively.  If -s or -d is given, it puts the program
 * in "spell" or "define" mode, respectively.  "define" is the default.
 *
 * In either mode, a word may include the wildcard characters '%' and '*'.
 * The '%' character matches exactly one character, while the '*' matches
 * zero or more characters.  If wildcards are used, the program will
 * return either "No match" or a list of matching words.  "!word" looks the
 * word up in the alternate mode.
 *
 * In interactive mode only, Tenex-style command completion may also be
 * used.  Typing a '?' following part of a word will cause the program
 * to print all words which begin with the partial word, or the program
 * will beep if nothing matches.  Typing an ESCape character causes the
 * program to attempt to complete the word.  If the word can be completed,
 * the new word is printed; otherwise, the program beeps.  Wildcards
 * may be used to specify the partial words.
 *
 * David A. Curry
 * Purdue University
 * davy@ee.purdue.edu
 * April, 1986
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sgtty.h>
#include <netdb.h>
#include <ctype.h>
#include <stdio.h>

#include <sys/un.h>
#include <arpa/inet.h>

#include "lint.h"
#include "interpret.h"
#include "config.h"
#include "comm.h"
#include "object.h"

#include <errno.h>

#include "webster.h"

#define BACKSPACE	010		/* backspace character       ^H */
#define WORDERASE	027		/* word erase character      ^W */
#define LINEERASE	030		/* line kill character       ^X */
#define LINERTYPE	022		/* line reprint character    ^R */
#define COMPLETE	033		/* word completion character ^[ */
#define ENDINGS		'?'		/* print matches character      */
#define ALTMODE		'!'		/* use other lookup mode	*/
#define THESMODE	'#'		/* lookup in thesaurus (sah)	*/
#define DEFINE		0		/* DEFINE mode			*/
#define SPELL		1		/* SPELL mode			*/
#define	THESAURUS	2		/* THESAURUS mode		*/

struct sgttyb sgttyb;			/* tty modes when interactive	*/
struct sgttyb rsgttyb;			/* original tty modes		*/

extern int errno;

/*
 * added at IU
 * ..sahayman 89/02/28
 */

struct tchars tchars;
struct ltchars ltchars;

int connectup(), socket(), connet(), byebye(), endings(), strlen(), send();
int strncmp(), connect(), getline();
void setitimer(), bzero(), define(), spell(), bcopy(), complete(), help();
void define(), listlines(), putline();
char *strcpy();

int mode = DEFINE;
FILE *WebsterSock;			/* for reading from the server	*/
int interactive = 0;			/* 1 when running interactive	*/
int full_search = 0;
char *pager = NULL;
char *getenv();

extern struct object *command_giver;
struct object c_g;

void
add_message2(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
char *fmt;
int a1, a2, a3, a4, a5, a6, a7, a8, a9;
{
  if (c_g.flags & O_DESTRUCTED) return;
/*  add_output(c_g.interactive, 0, fmt, a1, a2, a3, a4, a5, a6,
    a7, a8, a9); */
  add_message(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}

int webster(arg1, arg2)
char *arg1, *arg2;
{
	int didone = 0;
	struct itimerval value;
	void go_out();
	char aa[100], bb[100];

	mode = DEFINE;

	/*
	 * Connect to the server.
	 */

	if (!connectup()) return 0;
	c_g = *command_giver;

        value.it_value.tv_sec = 10;   /* 10 seconds, no more! */
	value.it_interval.tv_sec =10; /* Kickaha!             */
        setitimer(ITIMER_PROF, &value, NULL);
	signal(SIGPROF, go_out);

	bzero(aa, 100);
	bzero(bb, 100);

	if (arg1) sscanf(arg1, "%s %s", aa, bb);

	if (bb[0] == (char)0) strcpy(bb, arg1);

	/*
	 * If we were given command line arguments, just
	 * try to define each word.
	 */
	if (bb != (char *)0) {
			if (*aa == '-') {
				switch (*(aa+1)) {
				case 'd':
					mode = DEFINE;
					break;
				case 's':
					mode = SPELL;
					break;
				case 't':
					mode = THESAURUS;
					break;
				case 'f':
					full_search++;
					break;
				default:
					add_message2("Usage: webster [-d] [-s] [-t] [-f] [word]\n");
                                        value.it_value.tv_sec = 60*5;  /* 5 minutes must be enough */
                                        value.it_interval.tv_sec = 3600;       /* Kickaha ! */
                                        setitimer(ITIMER_PROF, &value, NULL);
					return 1;
				}
			}

			/*
			 * Look up the word.
			 */
			if (mode == DEFINE || mode == THESAURUS)
				define(bb, mode);
			else
				spell(bb);

			didone++;

		if (didone)
		{
                        value.it_value.tv_sec = 60*5;  /* 5 minutes must be enough */
                        value.it_interval.tv_sec = 3600;       /* Kickaha ! */
                        setitimer(ITIMER_PROF, &value, NULL);
			return 0;
                }
	}


	/*
	 * If no arguments were given, set up the
	 * terminal modes and run interactively.
	 */
/*	setup();
	interact(); */
        value.it_value.tv_sec = 60*5;  /* 5 minutes must be enough */
        value.it_interval.tv_sec = 3600;       /* Kickaha ! */
        setitimer(ITIMER_PROF, &value, NULL);
	add_message2("No word specified!\n");
	return 0;
}

void go_out()
{
  struct itimerval value;
  value.it_value.tv_sec = 60*5;  /* 5 minutes must be enough */
  value.it_interval.tv_sec = 3600;       /* Kickaha ! */
  setitimer(ITIMER_PROF, &value, NULL);
  signal(SIGPROF, SIG_DFL);
  add_message2("Couldn't reach server host!\n");
}

/*
 * connectup - connects to the Webster server.
 */
int connectup()
{
	int s;
	struct sockaddr_in sin;
	struct hostent *hp;
	struct servent *sp;
	struct hostent *gethostbyname();
	struct servent *getservbyname();
	extern int byebye();

	char *whichhost, *getenv();

	whichhost = getenv("WEBSTERHOST");
	if ( whichhost == NULL )
		whichhost = WEBSTERHOST;

	/*
	 * Look up the host in the host file.
	 */
	if ((hp = gethostbyname(whichhost)) == NULL) {
		add_message2("webster: %s: unknown host.\n", whichhost);
		return 0;
	}

	bzero(&sin, sizeof(struct sockaddr_in));

	/*
	 * Build the server's address.
	 */
	sin.sin_family = AF_INET;
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if ((sp = getservbyname(WEBSTERNAME, "tcp")) == NULL)
		sin.sin_port = htons(WEBSTERPORT);
	else
		sin.sin_port = sp->s_port;

	/*
	 * Get a TCP socket.
	 */
	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
/*		perror("webster: socket"); */
		add_message2("Webster couldn't get TCP socket.\n");
		return 0;
	}

	/*
	 * Try to connect.
	 */
/*        signal(SIGINT, byebye); */
	if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
		add_message2("Webster: host %s: ", whichhost);
/*		perror("connect"); */
		add_message2("couldn't connect (try again).\n");
		return 0;
	}
/*        signal(SIGINT, SIG_DFL); */

	/*
	 * Open the socket for stdio.
	 */
	WebsterSock = fdopen(s, "r");
	return 1;
}

/*
 * setup - turns on CBREAK, turns off ECHO.  Also trap signals.
 */
void setup()
{
	extern int byebye();
	extern int suspend();

	interactive = 1;
/*	ioctl(0, TIOCGETP, &sgttyb);
	ioctl(0, TIOCGETC, &tchars);
	ioctl(0, TIOCGLTC, &ltchars);

	rsgttyb = sgttyb;

	signal(SIGINT, byebye);
	signal(SIGQUIT, byebye);
	signal(SIGTSTP, suspend);

	sgttyb.sg_flags |= CBREAK;
	sgttyb.sg_flags &= ~ECHO;
	ioctl(0, TIOCSETP, &sgttyb); */
}

/*
 * interact - interact with the user.
 */
void interact()
{
	/*
	int c;
	*/
	char c;
	char buf[1024];
	char *s, *t;

	/*
	 * Forever...
	 */
	for (;;) {
		/*
		 * Prompt for a word.
		 */
		s = buf;
		write(1, "Word: ", 6);

		/*
		 * Forever... read characters.  We
		 * break out of this from inside.
		 */
		for (;;) {
			/*
			if ( (c = getchar()) < 0 )
			*/
			if (read(0, &c, 1) <= 0)
				byebye();

			/*
			 * Added at IU - use the user's own backspace,
			 * and line erase characters.  Check for EOF too.
			 *
			 * Could also do worderase here if really keen
			 * but would require looking up ltchars
			 * and I'm lazy, and we already have sgttyb sitting
			 * around... Should also probably handle EOF here.
			 * ..sahayman 89/02/28
			 */
			
			if ( c == sgttyb.sg_erase )
				c = BACKSPACE;
			else if ( c == sgttyb.sg_kill )
				c = LINEERASE;
			else if ( c == ltchars.t_werasc )
				c = WORDERASE;
			else if ( c == ltchars.t_rprntc )
				c = LINERTYPE;
			else if ( c == tchars.t_brkc )
				c = COMPLETE;
			else if ( c == tchars.t_eofc )
				byebye();



			switch (c) {
			case BACKSPACE:
				/*
				 * If not at the beginning of a line,
				 * back up one character.
				 */
				if (s > buf) {
					write(1, "\b \b", 3);
					s--;
				}
				continue;
			case WORDERASE:
				/*
				 * Until we hit beginning of line
				 * or beginning of word, back up.
				 */
				while ((s > buf) && (*s != ' ')) {
					write(1, "\b \b", 3);
					s--;
				}
				continue;
			case LINEERASE:
				/*
				 * Until we hit beginning of line,
				 * back up.
				 */
				while (s > buf) {
					write(1, "\b \b", 3);
					s--;
				}
				continue;
			case LINERTYPE:
				/*
				 * Retype the line.
				 */
				write(1, "\r\nWord: ", 8);

				for (t=buf; t < s; t++)
					write(1, t, 1);
				continue;
			case COMPLETE:
				/*
				 * Try to complete what they typed
				 * so far.  Put the pointer at the
				 * end of the new word.
				 */
				*s = NULL;
				complete(buf);
				for (s=buf; *s; s++)
					;
				continue;
			case ENDINGS:
				/*
				 * If it's the first character,
				 * then print some help.  Otherwise,
				 * try to find endings for the word.
				 * endings() returns 1 if no endings
				 * were found, 0 if some were found.
				 * This tells us whether to reprint
				 * the current word or not.
				 */
				if (s == buf) {
					help();
				}
				else {
					*s = NULL;
					if (endings(buf) == 0) {
						write(1, "Word: ", 6);

						for (s=buf; *s; s++)
							write(1, s, 1);
					}

					continue;
				}
				break;
			case '\n':
				/*
				 * If at the start of a word,
				 * newline is exit.
				 */
				if (s == buf)
					byebye();

				/*
				 * Otherwise, try to define
				 * the word.
				 */
				*s = NULL;
				write(1, "\n", 1);

				if (*buf == ALTMODE) {
					if (strlen(buf) == 1)
						break;
					if (mode == DEFINE || mode == THESAURUS)
						spell(buf+1);
					else
						define(buf+1,mode);
				}
				else if ( *buf == THESMODE ) {
					int oldmode = mode;
					if ( strlen(buf) == 1 )
						break;
					mode = THESAURUS;
					define(buf+1,mode);
					mode = oldmode;
				} else {
					if (mode == DEFINE || mode == THESAURUS)
						define(buf,mode);
					else
						spell(buf);
				}
				fflush(stdout);

				break;
			default:
				/*
				 * Echo the character and copy it.
				 */
				write(1, &c, 1);
				*s++ = c;
				continue;
			}

			break;
		}
	}
}

/*
 * define - try to define a word and print its definition.
 */
void define(word, mode2)
char *word;
int mode2;
{
	int c, refs;
	char buf[1024];

	/*
	 * first mode is the normal dictionary so that
	 * we don't send INDEX commands to an old server
	 */
	static int last_mode = DEFINE;
	static int last_full = 0;

	FILE *fpager, *popen();
	/*
	 * Command is "DEFINE<space>word<nl>".
	 */

	/*
	 * Send appropriate INDEX instruction if anything has changed
	 * since last time.
	 */
	if ( mode2 != last_mode || full_search != last_full ) {
	    last_mode = mode2;
	    last_full = full_search;

	    if ( mode2 == DEFINE ) {
		sprintf(buf, "INDEX %s\r\n",
			full_search ? "dictionary-full" : "dictionary" );
	    } else if ( mode2 == THESAURUS ) {
		sprintf(buf, "INDEX thesaurus\r\n");
	    }

	    if ( send(fileno(WebsterSock), buf, strlen(buf), 0) < 0 ) {
/*		perror("webster: send"); */
		add_message2("Webster couldn't send!\n");
		byebye();
	    }
	    /*
	    getline(buf);
	    */
	}

	sprintf(buf, "DEFINE %s\r\n", word);

	/*
	 * Send the command.
	 */
	if (send(fileno(WebsterSock), buf, strlen(buf), 0) < 0) {
/*		perror("webster: send"); */
		add_message2("Webster couldn't send.\n");
		byebye();
	}

	/*
	 * Read the first line back from the server.  This
	 * line tells us what the result of our DEFINE
	 * request was.
	 */
	getline(buf);

	/*
	 * "WILD<space>0<nl>" means they used wild cards and no
	 * matches were found.
	 */
	if (!strncmp(buf, "WILD 0", 6)) {
		add_message2("No match.\n");
		return;
	}

	/*
	 * "WILD<nl>" means that the wildcard matched, so we
	 * print a list of possible matches.
	 */
	if (!strncmp(buf, "WILD", 4)) {
		add_message2("Possible matches are:\n");

		/*
		 * List lines.
		 */
		listlines(0, 1);
		add_message2("\n");
		return;
	}

	/*
	 * "SPELLING<space>0<nl>" means the word is not defined,
	 * and there are no alternate spellings.
	 */
	if (!strncmp(buf, "SPELLING 0", 10)) {
		add_message2("No %s",
			mode2 == THESAURUS ? "thesaurus entry" : "definition ");
                add_message2(" for '%s'.\n", word);
		/*
		 * Everywhere else there's a blank line between words.
		 */
                add_message2("\n");
/*		putchar('\n'); */
		return;
	}

	/*
	 * "SPELLING<nl>" means the word is not defined, but
	 * some alternate spellings were found.  Print
	 * them out.
	 */
	if (!strncmp(buf, "SPELLING", 8)) {
		add_message2("No %s",
			mode2 == THESAURUS ? "thesaurus entry" : "definition ");
                add_message2(" for '%s'. Maybe you mean:\n", word);

		/*
		 * List lines.
		 */
		listlines(0, 1);
/*		putchar('\n'); */
		add_message2("\n");
		return;
	}

	/*
	 * "DEFINITION<space>n<nl>" means the word is defined,
	 * and there are n cross-references.
	 */
	if (!strncmp(buf, "DEFINITION", 10)) {
		/*
		 * Use pager if desired
		 */

		if ( pager ) {
		    fpager = popen(pager, "w");
		    if ( fpager == NULL ) {
			add_message2("Warning: pager program.\n");
/*			perror(pager); */

			fpager = stdout;
		    }
		} else {
		    fpager = stdout;
		}
		sscanf(buf+11, "%d", &refs);

		
		/*
		 * Print any cross references.
		 */
		if (refs > 0) {
			add_message2("Cross references:\n");

			/*
			 * List lines.
			 */
			listlines(refs, 1);
			add_message2(" \n");
		}

		/*
		 * Print the definition.
		 */
		while ((c = getc(WebsterSock)) != EOF) {
			if (c == EOFCH)
				break;

			c &= 0177;
			add_message2("%c", c);
		}

		add_message2("\n");
		if ( fpager != stdout )
		    pclose(fpager);
		return;
	}

	/*
	 * An error message.
	 */
	if (!strncmp(buf, "ERROR ", 6)) {
		if (!strncmp(buf+6, "FATAL", 5)) {
			add_message2("%s\n", buf+11);
			byebye();
		}
		else {
			add_message2("%s\n", buf+17);
			return;
		}
	}

	/*
	 * Should never get here.
	 */
	while (((c = getc(WebsterSock)) != EOF) && (c != EOFCH))
		;
}

/*
 * spell - look up a word and see if it's spelled correctly.
 */
void spell(word)
char *word;
{
	int c;
	char buf[1024];

	/*
	 * Command is "SPELL<space>word<nl>".
	 */
	sprintf(buf, "SPELL %s\r\n", word);

	/*
	 * Send the command.
	 */
	if (send(fileno(WebsterSock), buf, strlen(buf), 0) < 0) {
/*		perror("webster: send"); */
		add_message2("Webster couldn't send!\n");
		byebye();
	}

	/*
	 * Read the first line back from the server.  This
	 * line tells us what the result of our SPELL
	 * request was.
	 */
	getline(buf);

	/*
	 * "SPELLING<space>0<nl>" means the word is not spelled correctly,
	 * and there are no alternate spellings.
	 */
	if (!strncmp(buf, "SPELLING 0", 10)) {
		add_message2("'%s' is not a correct spelling.\n", word);
		return;
	}

	/*
	 * "SPELLING<space>1<nl>" means the word is spelled correctly.
	 */
	if (!strncmp(buf, "SPELLING 1", 10)) {
		add_message2("'%s' is spelled correctly.\n", word);
		return;
	}

	/*
	 * "SPELLING<nl>" means the word is not spelled correctly, but
	 * some alternate spellings were found.  Print them out.
	 */
	if (!strncmp(buf, "SPELLING", 8)) {
		add_message2("No spelling for '%s'.  Maybe you mean:\n", word);

		/*
		 * List lines.
		 */
		listlines(0, 1);
		add_message2("\n");
/*		putchar('\n'); */
		return;
	}

	/*
	 * An error message.
	 */
	if (!strncmp(buf, "ERROR ", 6)) {
		if (!strncmp(buf+6, "FATAL", 5)) {
			add_message2("%s\n", buf+11);
			byebye();
		}
		else {
			add_message2("%s\n", buf+17);
			return;
		}
	}

	/*
	 * Should never get here.
	 */
	while (((c = getc(WebsterSock)) != EOF) && (c != EOFCH))
		;
}

/*
 * complete - try to complete the word.
 */
void complete(word)
char *word;
{
	int c;
	char buf[1024];
	char *s;

	/*
	 * Command is "COMPLETE<space>word<nl>".
	 */
	sprintf(buf, "COMPLETE %s\r\n", word);

	/*
	 * Send the command.
	 */
	if (send(fileno(WebsterSock), buf, strlen(buf), 0) < 0) {
/*		perror("webster: send"); */
		add_message2("Webster couldn't send command.\n");
		byebye();
	}

	/*
	 * Get the first line from the server, which tells
	 * us the reult of our request.
	 */
	getline(buf);

	/*
	 * "AMBIGUOUS<space>n<nl>" means the word is ambiguous,
	 * with n possible matches.  We ignore the n, and just
	 * beep.
	 */
	if (!strncmp(buf, "AMBIGUOUS", 9)) {
		add_message2("");
/*		write(1, "\007", 1); */
		return;
	}

	/*
	 * "COMPLETION<space>full-word<nl>" means the
	 * word was completed.  Erase what they typed
	 * and print the new word over it.  This takes
	 * care of things if they used wildcards.
	 */
	if (!strncmp(buf, "COMPLETION", 10)) {
		for (s=word; *s; s++)
		{
			add_message2("\b");
/*			write(1, "\b", 1); */
                }

		s = buf+11;
		while (((*s & 0177) != '\r') && ((*s & 0177) != '\n') &&
		       ((*s & 0177) != NULL)) {
/*			write(1, s, 1); */
			add_message2("%c", s);
			s++;
		}

		/*
		 * Put the new word back into word.  This
		 * gets rid of the wildcards here.
		 */
		*s = NULL;
		strcpy(word, buf+11);

		return;
	}

	/*
	 * An error message.
	 */
	if (!strncmp(buf, "ERROR ", 6)) {
		if (!strncmp(buf+6, "FATAL", 5)) {
			add_message2("%s\n", buf+11);
			byebye();
		}
		else {
			add_message2("%s\n", buf+17);
			return;
		}
	}

	/*
	 * Should never get here.
	 */
	while (((c = getc(WebsterSock)) != EOF) && (c != EOFCH))
		;
}

/*
 * endings - find possible endings for a word.
 */
int endings(word)
char *word;
{
	int c;
	char buf[1024];

	/*
	 * Command is "ENDINGS<space>word<nl>".
	 */
	sprintf(buf, "ENDINGS %s\r\n", word);

	/*
	 * Send the command.
	 */
	if (send(fileno(WebsterSock), buf, strlen(buf), 0) < 0) {
/*		perror("webster: send"); */
		add_message2("Webster couldn't send command!\n");
		byebye();
	}

	/*
	 * Get the first line from the server, which tells
	 * us the result of the search.
	 */
	getline(buf);

	/*
	 * "MATCHS<space>0<nl>" means nothing matched,
	 * so we beep at them.
	 */
	if (!strncmp(buf, "MATCHS 0", 8)) {
/*		write(1, "\007", 1); */
		add_message2("");
		return(1);
	}

	/*
	 * "MATCHS<nl>" means there were matches, so
	 * print them out.
	 */
	if (!strncmp(buf, "MATCHS", 6)) {
		add_message2("\nMaybe you mean:\n");

		/*
		 * List lines.
		 */
		listlines(0, 0);
		add_message2("\n");
/*		putchar('\n'); */
		return(0);
	}

	/*
	 * An error message.
	 */
	if (!strncmp(buf, "ERROR ", 6)) {
		if (!strncmp(buf+6, "FATAL", 5)) {
			add_message2("%s\n", buf+11);
			byebye();
		}
		else {
			add_message2("%s\n", buf+17);
			return(0);
		}
	}

	/*
	 * Should never get here.
	 */
	while (((c = getc(WebsterSock)) != EOF) && (c != EOFCH))
		;

	return(0);
}

/*
 * getline - read one line from the server and put it in s.
 */
int getline(s)
char *s;
{
	int c;

	/*
	 * Read in chars.  If we hit EOFCH, return
	 * 0.
	 */
	while ((c = getc(WebsterSock)) != EOF) {
		if (c == EOFCH)
			return(0);

		c &= 0177;

		if (c == '\r')
			continue;

		if (c == '\n')
			break;

		*s++ = c;
	}

	*s = NULL;
	return(1);
}

/*
 * listlines - list WILD-style lines on the screen.
 */
void listlines(n, num)
int n;
int num;
{
	char buf[1024];
	int col;

	add_message2(" ");

	/*
	 * If n is non-zero, we only want to list n lines.
	 * Otherwise, we go till we hit EOFCH.  Lines are
	 * printed in four columns.
	 */
	if (n) {
		col = 0;
		while (n-- > 0) {
			getline(buf);
			putline(buf, num);

			if (++col == 3) {
				add_message2("\n ");
				col = 0;
			}
		}
	}
	else {
		col = 0;
		while (getline(buf) > 0) {
			putline(buf, num);

			if (++col == 3) {
				add_message2("\n ");
				col = 0;
			}
		}
	}

	if (col)
	{
/*		putchar('\n'); */
		add_message2("\n");
        }
}

/*
 * putline - put out a line, if num is 0, skip the line number.
 */
void putline(buf, num)
char *buf;
int num;
{
	int lnum;
	char line[1024];

	sscanf(buf, "%d %[^\n]", &lnum, line);

/*	sscanf(line, "%s\n", line);
	line[strlen(line)] = 0; */

	if (num)
	{
		add_message2("%2d. ", lnum);
/*		add_message2("%-22s", line); */
		add_message2("%s", line);
        }
	else
	{
/*		add_message2("%-26s", line); */
		add_message2("%s", line);
        }
}

/*
 * help - print a help message.
 */
void help()
{
	add_message2("\n   Type in the word you want defined, or a blank line to exit. Additionally,\n");
	add_message2("Webster can match words using wildcards.  The character '%%' in a word means\n");
	add_message2("match exactly one character; while the character '*' means match zero or more\n");
	add_message2("characters.  Typing \"!word\" will check the spelling of the word instead\n");
	add_message2("of checking its definition.\n");
	add_message2("   Typing a partial word followed by '?' will print all the words in the\n");
	add_message2("dictionary which match your partial word. Typing a partial word followed by an\n");
	add_message2("ESCape character will try to complete the word for you.  If the partial word\n");
	add_message2("is ambiguous, Webster will beep at you.  Note that you can use the wildcards\n");
	add_message2("along with ESC and ?.  For example (the underlined parts are typed by the\n");
	add_message2("user, the rest by Webster),\n");
	add_message2("\n");
	add_message2("Word: balla?   Maybe you mean:\n");
	add_message2("      ------\n");
	add_message2("  1. ballad           2. ballade          3. baladry         4. ballast\n");
	add_message2("Word: pluria<ESC>xial\n");
	add_message2("      -----------\n");
	add_message2("Word: plu*x<ESC>\n");
	add_message2("      ----------\n");
	add_message2("Word: pluriaxial\n");
	add_message2("\n---- End of Help File ----\n\n");
}

/*
 * byebye - called on exit.
 */
int byebye()
{
	/*
	 * If interactive, reset the tty modes.
	 */
/*	if (interactive)
		ioctl(0, TIOCSETP, &rsgttyb); */

	/*
	 * Close the socket and exit.
	 */
	fclose(WebsterSock);
/*	write(1, "\n", 1); */
	add_message2("\n");
	return 0;
}

/*
 * suspend - reset tty modes and supend ourselves.
 */
void suspend2()
{
	extern int suspend();

	/*
	 * Reset tty modes and suspend.
	 */
/*	ioctl(0, TIOCSETP, &rsgttyb);
	signal(SIGTSTP, SIG_DFL);
	blocked = sigsetmask(0);
	kill(0, SIGTSTP); */

	/*
	 * We come here on SIGCONT.  Reset
	 * the signal mask and tty modes.
	 */
/*	sigsetmask(blocked);
	signal(SIGTSTP, suspend);
	ioctl(0, TIOCSETP, &sgttyb);	 */
}