[comp.sources.games] v08i042: NetHack3 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (09/30/89)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 8, Issue 42
Archive-name: NetHack3/Patch4f
Patch-To: NetHack3: Volume 7, Issue 56-93

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 11)."
# Contents:  patches04f
# Wrapped by billr@saab on Fri Sep 29 13:14:30 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'patches04f' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patches04f'\"
else
echo shar: Extracting \"'patches04f'\" \(52494 characters\)
sed "s/^X//" >'patches04f' <<'END_OF_FILE'
X*** /dev/null	Wed Sep 27 12:46:46 1989
X--- vms/Install.vms	Tue Sep 26 22:10:07 1989
X***************
X*** 0 ****
X--- 1,44 ----
X+ Instructions for installing NetHack 3.0 on a VMS system
X+ =======================================================
X+ 
X+ First, consider reading Install.unix.  While many of the details will differ,
X+ it should give you an idea of how the NetHack files are set up, and what a
X+ full installation process is like.
X+ 
X+ You should not have to move any files from their default positions, but you
X+ will want to edit config.h and vmsconf.h.  Then run vms_build.com and
X+ spec_lev.com.  These will create all the necessary files, but not install
X+ them anywhere in particular.  That is left as an exercise for the installer.
X+ 
X+ 
X+ Some additional notes:
X+ 
X+ VMS Nethack uses the termcap routines supplied with GNU Emacs.  These have
X+ been supplied for those who do not already have GNU Emacs, but they are not
X+ properly a part of the NetHack distribution.  Since these files (vmstermcap.c
X+ and vmstparam.c) bear the usual GNU license, any executable made with these
X+ files is also under the GNU license, which among other things means you must
X+ be prepared to distribute all the source that went into the executable if you
X+ distribute the executable.  See the GNU license in the files for further
X+ details.
X+ 
X+ No termcap file is supplied.  One should be snarfable from any Unix system.
X+ If you do not have GNU Emacs installed, you will need to define the logical
X+ TERMCAP to point to the termcap file.
X+ 
X+ There is code which attempts to make Nethack secure in case it is installed
X+ with privileges (to allow the playground to be protected against world write).
X+ THIS HAS NOT BEEN TESTED.  Install Nethack with privileges at your own risk.
X+ If you do so, however, we would love to hear of your experiences, good or bad.
X+ 
X+ VMS Nethack uses SMG$READ_KEYSTROKE to read characters from the keyboard.
X+ This means that arrow keys work!  It also means that using escape to abort
X+ commands doesn't!  If you want to abort a command use ^Z.  Just about any
X+ non-arrow function key should also work.  Note that under Unix ^Z is the
X+ suspend command.  This is of little use on VMS so our use is harmless.
X+ 
X+ Nethack does not run in PASTHRU or PASSALL mode.  This is to allow ^C
X+ interrupts.  An unpleasant (albeit minor) side-effect of this is that some
X+ wizard commands don't work (^G, ^O, ^X).  Another side-effect is that ^Y and
X+ ^C echo the stupid, inverse-video "CANCEL" and "INTERRUPT" banners.  Is there
X+ no other way to turn these off???
X*** /dev/null	Wed Sep 27 12:46:56 1989
X--- vms/spec_lev.com	Tue Sep 26 20:00:12 1989
X***************
X*** 0 ****
X--- 1,25 ----
X+ $! yacc := bison/def			! .CLD version of bison
X+ $! yacc := $bison$dir:bison -y -d	! non-CLD version of bison
X+ $ yacc := $shell$exe:yacc -d		! yacc from DEC/Shell
X+ $! lex := $flex$dir:flex		! flex
X+ $ lex := $shell$exe:lex			! lex from DEC/Shell
X+ $ cc = "CC/NOLIST/OPT=NOINLINE/DEB/INCL=[-.INCLUDE]/DEFI=(""WIZARD=""""GENTZEL"""""")"
X+ $ link := link/nomap
X+ $
X+ $ yacc lev_comp.y
X+ $ rename y_tab.c lev_comp.c
X+ $ rename y_tab.h [-.include]lev_comp.h
X+ $ lex lev_comp.l
X+ $ rename lex_yy.c lev_lex.c
X+ $ cc lev_comp.c
X+ $ cc lev_lex.c
X+ $ cc lev_main.c
X+ $ link lev_comp.obj,lev_lex.obj,lev_main.obj,alloc.obj,monst.obj,objects.obj,panic.obj,vmsmisc.obj,sys$input:/opt
X+ sys$share:vaxcrtl/share
X+ $
X+ $ old_dir = f$environment("DEFAULT")
X+ $ set default [-.auxil]
X+ $ mcr sys$disk:[-.src]lev_comp castle.des
X+ $ mcr sys$disk:[-.src]lev_comp endgame.des
X+ $ mcr sys$disk:[-.src]lev_comp tower.des
X+ $ set default 'old_dir
X*** /dev/null	Wed Sep 27 12:47:07 1989
X--- vms/vmsbuild.com	Wed Sep 27 09:36:05 1989
X***************
X*** 0 ****
X--- 1,201 ----
X+ $ makedefs := $sys$disk:[]makedefs
X+ $ cc = "CC/NOLIST/OPT=NOINLINE/DEB/INCL=[-.INCLUDE]/DEFI=(""WIZARD=""""GENTZEL"""""")"
X+ $ link := link/nomap
X+ $ if p1 .eqs. "LINK" then goto link
X+ $ cc alloc.c
X+ $ cc makedefs.c
X+ $ cc monst.c
X+ $ cc objects.c
X+ $ cc panic.c
X+ $ cc [-.vms]vmsmisc
X+ $ link makedefs.obj,monst.obj,objects.obj,panic.obj,vmsmisc.obj,sys$input:/opt
X+ sys$share:vaxcrtl/share
X+ $ makedefs -p
X+ $ makedefs -o
X+ $ makedefs -t
X+ $ cc allmain.c
X+ $ cc apply.c
X+ $ cc artifact.c
X+ $ cc attrib.c
X+ $ cc bones.c
X+ $ cc cmd.c
X+ $ cc dbridge.c
X+ $ cc decl.c
X+ $ cc demon.c
X+ $ cc do.c
X+ $ cc do_name.c
X+ $ cc do_wear.c
X+ $ cc dog.c
X+ $ cc dogmove.c
X+ $ cc dokick.c
X+ $ cc dothrow.c
X+ $ cc eat.c
X+ $ cc end.c
X+ $ cc engrave.c
X+ $ cc exper.c
X+ $ cc extralev.c
X+ $ cc fountain.c
X+ $ cc getline.c
X+ $ cc hack.c
X+ $ cc invent.c
X+ $ cc lock.c
X+ $ cc mail.c
X+ $ cc [-.vms]vmsmain.c/obj=main.obj
X+ $ cc makemon.c
X+ $ cc mcastu.c
X+ $ cc mhitm.c
X+ $ cc mhitu.c
X+ $ cc mklev.c
X+ $ cc mkmaze.c
X+ $ cc mkobj.c
X+ $ cc mkroom.c
X+ $ cc mon.c
X+ $ cc mondata.c
X+ $ cc monmove.c
X+ $ cc mthrowu.c
X+ $ cc music.c
X+ $ cc o_init.c
X+ $ cc objnam.c
X+ $ cc options.c
X+ $ cc pager.c
X+ $ cc pickup.c
X+ $ cc polyself.c
X+ $ cc potion.c
X+ $ cc pray.c
X+ $ cc pri.c
X+ $ cc priest.c
X+ $ cc prisym.c
X+ $ cc read.c
X+ $ cc restore.c
X+ $ cc rip.c
X+ $ cc rnd.c
X+ $ cc rumors.c
X+ $ cc save.c
X+ $ cc search.c
X+ $ cc shk.c
X+ $ cc shknam.c
X+ $ cc sit.c
X+ $ cc sounds.c
X+ $ cc sp_lev.c
X+ $ cc spell.c
X+ $ cc steal.c
X+ $ cc termcap.c
X+ $ cc timeout.c
X+ $ cc topl.c
X+ $ cc topten.c
X+ $ cc track.c
X+ $ cc trap.c
X+ $ cc [-.vms]vmstty.c/obj=tty.obj
X+ $ cc u_init.c
X+ $ cc uhitm.c
X+ $ cc [-.vms]vmsunix.c/obj=unix.obj
X+ $ cc vault.c
X+ $ makedefs -v
X+ $ cc version.c
X+ $ cc weapon.c
X+ $ cc were.c
X+ $ cc wield.c
X+ $ cc wizard.c
X+ $ cc worm.c
X+ $ cc worn.c
X+ $ cc write.c
X+ $ cc zap.c
X+ $ cc [-.others]random.c
X+ $ cc/def="bcopy(s1,s2,sz)=memcpy(s2,s1,sz)" [-.vms]vmstermcap.c
X+ $ cc [-.vms]vmstparam.c
X+ $link:
X+ $ link/exe=nethack sys$input:/opt
X+ allmain.obj,-
X+ alloc.obj,-
X+ apply.obj,-
X+ artifact.obj,-
X+ attrib.obj,-
X+ bones.obj,-
X+ cmd.obj,-
X+ dbridge.obj,-
X+ decl.obj,-
X+ demon.obj,-
X+ do.obj,-
X+ do_name.obj,-
X+ do_wear.obj,-
X+ dog.obj,-
X+ dogmove.obj,-
X+ dokick.obj,-
X+ dothrow.obj,-
X+ eat.obj,-
X+ end.obj,-
X+ engrave.obj,-
X+ exper.obj,-
X+ extralev.obj,-
X+ fountain.obj,-
X+ getline.obj,-
X+ hack.obj,-
X+ invent.obj,-
X+ lock.obj,-
X+ mail.obj,-
X+ main.obj,-
X+ makemon.obj,-
X+ mcastu.obj,-
X+ mhitm.obj,-
X+ mhitu.obj,-
X+ mklev.obj,-
X+ mkmaze.obj,-
X+ mkobj.obj,-
X+ mkroom.obj,-
X+ mon.obj,-
X+ mondata.obj,-
X+ monmove.obj,-
X+ monst.obj,-
X+ mthrowu.obj,-
X+ music.obj,-
X+ o_init.obj,-
X+ objects.obj,-
X+ objnam.obj,-
X+ options.obj,-
X+ pager.obj,-
X+ pickup.obj,-
X+ polyself.obj,-
X+ potion.obj,-
X+ pray.obj,-
X+ pri.obj,-
X+ priest.obj,-
X+ prisym.obj,-
X+ read.obj,-
X+ restore.obj,-
X+ rip.obj,-
X+ rnd.obj,-
X+ rumors.obj,-
X+ save.obj,-
X+ search.obj,-
X+ shk.obj,-
X+ shknam.obj,-
X+ sit.obj,-
X+ sounds.obj,-
X+ sp_lev.obj,-
X+ spell.obj,-
X+ steal.obj,-
X+ termcap.obj,-
X+ timeout.obj,-
X+ topl.obj,-
X+ topten.obj,-
X+ track.obj,-
X+ trap.obj,-
X+ tty.obj,-
X+ u_init.obj,-
X+ uhitm.obj,-
X+ unix.obj,-
X+ vault.obj,-
X+ version.obj,-
X+ weapon.obj,-
X+ were.obj,-
X+ wield.obj,-
X+ wizard.obj,-
X+ worm.obj,-
X+ worn.obj,-
X+ write.obj,-
X+ zap.obj,-
X+ random.obj,-
X+ vmsmisc.obj,-
X+ vmstermcap.obj,-
X+ vmstparam.obj
X+ sys$library:vaxcrtl/library
X*** /dev/null	Wed Sep 27 12:47:15 1989
X--- vms/vmsmain.c	Tue Sep 26 18:45:52 1989
X***************
X*** 0 ****
X--- 1,378 ----
X+ /*	SCCS Id: @(#)vmsmain.c	3.0	89/01/13
X+ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X+ /* NetHack may be freely redistributed.  See license for details. */
X+ /* main.c - VMS NetHack */
X+ 
X+ #include <signal.h>
X+ 
X+ #include "hack.h"
X+ 
X+ char SAVEF[PL_NSIZ + 20];			/* [.save]<uic>player;1 */
X+ 
X+ char *hname = 0;		/* name of the game (argv[0] of call) */
X+ char obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
X+ int hackpid = 0;				/* current pid */
X+ int locknum = 0;				/* max num of players */
X+ 
X+ static void whoami();
X+ static void byebye();
X+ 
X+ int
X+ main(argc,argv)
X+ int argc;
X+ char *argv[];
X+ {
X+ 	extern int x_maze_max, y_maze_max;
X+ 	register int fd;
X+ #ifdef CHDIR
X+ 	register char *dir;
X+ #endif
X+ 
X+ 	atexit(byebye);
X+ 	hname = argv[0];
X+ 	hackpid = getpid();
X+ 	(void) umask(0);
X+ 
X+ 	/*
X+ 	 *  Remember tty modes, to be restored on exit.
X+ 	 *
X+ 	 *  gettty() must be called before startup()
X+ 	 *    due to ordering of LI/CO settings
X+ 	 *  startup() must be called before initoptions()
X+ 	 *    due to ordering of graphics settings
X+ 	 */
X+ 	gettty();
X+ 	setbuf(stdout,obuf);
X+ 	startup();
X+ 	initoptions();
X+ 	whoami();
X+ 
X+ #ifdef CHDIR			/* otherwise no chdir() */
X+ 	/*
X+ 	 * See if we must change directory to the playground.
X+ 	 * (Perhaps hack is installed with privs and playground is
X+ 	 *  inaccessible for the player.)
X+ 	 * The logical name HACKDIR is overridden by a
X+ 	 *  -d command line option (must be the first option given)
X+ 	 */
X+ 	dir = getenv("HACKDIR");
X+ #endif
X+ 	if(argc > 1) {
X+ #ifdef CHDIR
X+ 	    if (!strncmp(argv[1], "-d", 2)) {
X+ 		argc--;
X+ 		argv++;
X+ 		dir = argv[0]+2;
X+ 		if(*dir == '=' || *dir == ':') dir++;
X+ 		if(!*dir && argc > 1) {
X+ 			argc--;
X+ 			argv++;
X+ 			dir = argv[0];
X+ 		}
X+ 		if(!*dir)
X+ 		    error("Flag -d must be followed by a directory name.");
X+ 	    } else
X+ #endif /* CHDIR /**/
X+ 
X+ 	/*
X+ 	 * Now we know the directory containing 'record' and
X+ 	 * may do a prscore().
X+ 	 */
X+ 	    if (!strncmp(argv[1], "-s", 2)) {
X+ #ifdef CHDIR
X+ 		chdirx(dir,0);
X+ #endif
X+ 		prscore(argc, argv);
X+ 		getret();
X+ 		settty(NULL);
X+ 		exit(0);
X+ 	    }
X+ 	}
X+ 
X+ 	/*
X+ 	 * It seems you really want to play.
X+ 	 */
X+ 	setrandom();
X+ 	cls();
X+ 	u.uhp = 1;	/* prevent RIP on early quits */
X+ 	u.ux = FAR;	/* prevent nscr() */
X+ 	(void) signal(SIGHUP, (SIG_RET_TYPE) hangup);
X+ 
X+ 	/*
X+ 	 * Find the creation date of this game,
X+ 	 * so as to avoid restoring outdated savefiles.
X+ 	 */
X+ 	gethdate(hname);
X+ 
X+ 	/*
X+ 	 * We cannot do chdir earlier, otherwise gethdate will fail.
X+ 	 */
X+ #ifdef CHDIR
X+ 	chdirx(dir,1);
X+ #endif
X+ 
X+ 	/*
X+ 	 * Process options.
X+ 	 */
X+ 	while(argc > 1 && argv[1][0] == '-'){
X+ 		argv++;
X+ 		argc--;
X+ 		switch(argv[0][1]){
X+ #if defined(WIZARD) || defined(EXPLORE_MODE)
X+ # ifndef EXPLORE_MODE
X+ 		case 'X':
X+ 		case 'x':
X+ # endif
X+ 		case 'D':
X+ # ifdef WIZARD
X+ 			if(!strcmp(getenv("USER"), WIZARD))
X+ 				wizard = TRUE;
X+ 				break;
X+ 			}
X+ 			/* otherwise fall thru to discover */
X+ # endif
X+ # ifdef EXPLORE_MODE
X+ 		case 'X':
X+ 		case 'x':
X+ 			discover = TRUE;
X+ # endif
X+ 			break;
X+ #endif
X+ #ifdef NEWS
X+ 		case 'n':
X+ 			flags.nonews = TRUE;
X+ 			break;
X+ #endif
X+ 		case 'u':
X+ 			if(argv[0][2])
X+ 			  (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X+ 			else if(argc > 1) {
X+ 			  argc--;
X+ 			  argv++;
X+ 			  (void) strncpy(plname, argv[0], sizeof(plname)-1);
X+ 			} else
X+ 				Printf("Player name expected after -u\n");
X+ 			break;
X+ 		default:
X+ 			/* allow -T for Tourist, etc. */
X+ 			(void) strncpy(pl_character, argv[0]+1,
X+ 				sizeof(pl_character)-1);
X+ 
X+ 			/* Printf("Unknown option: %s\n", *argv); */
X+ 		}
X+ 	}
X+ 
X+ 	if(argc > 1)
X+ 		locknum = atoi(argv[1]);
X+ #ifdef MAX_NR_OF_PLAYERS
X+ 	if(!locknum || locknum > MAX_NR_OF_PLAYERS)
X+ 		locknum = MAX_NR_OF_PLAYERS;
X+ #endif
X+ #ifdef WIZARD
X+ 	if (wizard)
X+ 		Strcpy(plname, "wizard");
X+ 	else
X+ #endif
X+ 	if(!*plname || !strncmp(plname, "games", 4))
X+ 		askname();
X+ 	plnamesuffix();		/* strip suffix from name; calls askname() */
X+ 				/* again if suffix was whole name */
X+ 				/* accepts any suffix */
X+ #ifdef WIZARD
X+ 	if(!wizard) {
X+ #endif
X+ 		/*
X+ 		 * check for multiple games under the same name
X+ 		 * (if !locknum) or check max nr of players (otherwise)
X+ 		 */
X+ 		(void) signal(SIGQUIT,SIG_IGN);
X+ 		(void) signal(SIGINT,SIG_IGN);
X+ 		if(!locknum)
X+ 			Sprintf(lock, "%d%s", getuid(), plname);
X+ 		getlock();	/* sets lock if locknum != 0 */
X+ #ifdef WIZARD
X+ 	} else
X+ 		Sprintf(lock, "%d%s", getuid(), plname);
X+ #endif /* WIZARD /**/
X+ 	setftty();
X+ 
X+ 	/*
X+ 	 * Initialisation of the boundaries of the mazes
X+ 	 * Both boundaries have to be even.
X+ 	 */
X+ 
X+ 	x_maze_max = COLNO-1;
X+ 	if (x_maze_max % 2)
X+ 		x_maze_max--;
X+ 	y_maze_max = ROWNO-1;
X+ 	if (y_maze_max % 2)
X+ 		y_maze_max--;
X+ 
X+ 	/* initialize static monster strength array */
X+ 	init_monstr();
X+ 
X+ 	Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
X+ 	regularize(SAVEF+7);	/* avoid bogus chars in name */
X+ 	if((fd = open(SAVEF,0)) >= 0 &&
X+ 	   (uptodate(fd) || unlink(SAVEF) >= 0)) {
X+ #ifdef WIZARD
X+ 		/* Since wizard is actually flags.debug, restoring might
X+ 		 * overwrite it.
X+ 		 */
X+ 		boolean remember_wiz_mode = wizard;
X+ #endif
X+ 		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
X+ 		pline("Restoring old save file...");
X+ 		(void) fflush(stdout);
X+ 		if(!dorecover(fd))
X+ 			goto not_recovered;
X+ #ifdef WIZARD
X+ 		if(!wizard && remember_wiz_mode) wizard = TRUE;
X+ #endif
X+ 		pline("Hello %s, welcome to NetHack!", plname);
X+ 		/* get shopkeeper set properly if restore is in shop */
X+ 		(void) inshop();
X+ #ifdef EXPLORE_MODE
X+ 		if (discover)
X+ 			You("are in non-scoring discovery mode.");
X+ #endif
X+ #if defined(EXPLORE_MODE) || defined(WIZARD)
X+ 		if (discover || wizard) {
X+ 			pline("Do you want to keep the save file? ");
X+ 			if(yn() == 'n')
X+ 				(void) unlink(SAVEF);
X+ 		}
X+ #endif
X+ 		flags.move = 0;
X+ 	} else {
X+ not_recovered:
X+ 		newgame();
X+ 		/* give welcome message before pickup messages */
X+ 		pline("Hello %s, welcome to NetHack!", plname);
X+ #ifdef EXPLORE_MODE
X+ 		if (discover)
X+ 			You("are in non-scoring discovery mode.");
X+ #endif
X+ 		flags.move = 0;
X+ 		set_wear();
X+ 		pickup(1);
X+ 		read_engr_at(u.ux,u.uy);
X+ 	}
X+ 
X+ 	flags.moonphase = phase_of_the_moon();
X+ 	if(flags.moonphase == FULL_MOON) {
X+ 		You("are lucky!  Full moon tonight.");
X+ 		if(!u.uluck) change_luck(1);
X+ 	} else if(flags.moonphase == NEW_MOON) {
X+ 		pline("Be careful!  New moon tonight.");
X+ 	}
X+ 
X+ 	initrack();
X+ 
X+ 	moveloop();
X+ 	return(0);
X+ }
X+ 
X+ void
X+ glo(foo)
X+ register int foo;
X+ {
X+ 	/* construct the string  xlock.n  */
X+ 	register char *tf;
X+ 
X+ 	tf = lock;
X+ 	while(*tf && *tf != '.') tf++;
X+ 	Sprintf(tf, ".%d;1", foo);
X+ }
X+ 
X+ /*
X+  * plname is filled either by an option (-u Player  or  -uPlayer) or
X+  * explicitly (by being the wizard) or by askname.
X+  * It may still contain a suffix denoting pl_character.
X+  */
X+ void
X+ askname() {
X+ 	register int c, ct;
X+ 
X+ 	Printf("\nWho are you? ");
X+ 	(void) fflush(stdout);
X+ 	ct = 0;
X+ 	while((c = getchar()) != '\n') {
X+ 		if(c == EOF) error("End of input\n");
X+ 		if(c != '-')
X+ 		if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X+ 		if(ct < sizeof(plname)-1)
X+ 			plname[ct++] = c;
X+ 	}
X+ 	plname[ct] = 0;
X+ 	if(ct == 0) askname();
X+ }
X+ 
X+ #ifdef CHDIR
X+ void
X+ chdirx(dir, wr)
X+ char *dir;
X+ boolean wr;
X+ {
X+ 	static char *defdir = HACKDIR;
X+ 
X+ # ifdef HACKDIR
X+ 	if(dir == NULL)
X+ 		dir = defdir;
X+ 	else if (wr)
X+ 		/* If we're playing anywhere other than HACKDIR, turn off any
X+ 		   privs we may have been installed with. */
X+ 		privoff();
X+ # endif
X+ 
X+ 	if(dir && chdir(dir) < 0) {
X+ 		perror(dir);
X+ 		error("Cannot chdir to %s.", dir);
X+ 	}
X+ 
X+ 	/* warn the player if we can't write the record file */
X+ 	if(wr) {
X+ 	    register int fd;
X+ 
X+ 	    if(dir == NULL)
X+ 		dir = "";
X+ 	    if((fd = open(RECORD, 2)) < 0) {
X+ 		Printf("Warning: cannot write %s%s", dir, RECORD);
X+ 		getret();
X+ 	    } else
X+ 		(void) close(fd);
X+ 	}
X+ 	defdir = dir;
X+ }
X+ #endif /* CHDIR /**/
X+ 
X+ static void
X+ whoami() {
X+ 	/*
X+ 	 * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS
X+ 	 *			2. Use $USER	(if 1. fails)
X+ 	 * The resulting name is overridden by command line options.
X+ 	 * If everything fails, or if the resulting name is some generic
X+ 	 * account like "games" then eventually we'll ask him.
X+ 	 * Note that we trust him here; it is possible to play under
X+ 	 * somebody else's name.
X+ 	 */
X+ 	register char *s;
X+ 
X+ 	if(!*plname && (s = getenv("USER")))
X+ 		(void) strncpy(plname, s, sizeof(plname)-1);
X+ }
X+ 
X+ static void
X+ byebye()
X+ {
X+     void (*hup)();
X+     extern unsigned int dosh_pid;
X+ 
X+     /* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */
X+     hup = signal(SIGHUP, SIG_IGN);
X+     if (hup != SIG_DFL && hup != SIG_IGN)
X+ 	(*hup)();
X+     if (dosh_pid)
X+ 	SYS$DELPRC(&dosh_pid, 0);
X+ }
X*** /dev/null	Wed Sep 27 12:47:25 1989
X--- vms/vmsmisc.c	Sat Sep 16 12:25:25 1989
X***************
X*** 0 ****
X--- 1,14 ----
X+ #include <ssdef.h>
X+ 
X+ void
X+ vms_exit(status)
X+ int status;
X+ {
X+     exit(status ? SS$_ABORT : SS$_NORMAL);
X+ }
X+ 
X+ void
X+ vms_abort()
X+ {
X+     (void) LIB$SIGNAL(SS$_DEBUG);
X+ }
X*** /dev/null	Wed Sep 27 12:47:33 1989
X--- vms/vmstermcap.c	Sat Sep 16 12:24:04 1989
X***************
X*** 0 ****
X--- 1,742 ----
X+ /* Work-alike for termcap, plus extra features.
X+    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
X+ 
X+ 		       NO WARRANTY
X+ 
X+   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
X+ NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
X+ WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
X+ RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
X+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
X+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
X+ FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
X+ AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
X+ DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
X+ CORRECTION.
X+ 
X+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
X+ STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
X+ WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
X+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
X+ OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
X+ USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
X+ DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
X+ A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
X+ PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
X+ DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
X+ 
X+ 		GENERAL PUBLIC LICENSE TO COPY
X+ 
X+   1. You may copy and distribute verbatim copies of this source file
X+ as you receive it, in any medium, provided that you conspicuously and
X+ appropriately publish on each copy a valid copyright notice "Copyright
X+ (C) 1986 Free Software Foundation, Inc."; and include following the
X+ copyright notice a verbatim copy of the above disclaimer of warranty
X+ and of this License.  You may charge a distribution fee for the
X+ physical act of transferring a copy.
X+ 
X+   2. You may modify your copy or copies of this source file or
X+ any portion of it, and copy and distribute such modifications under
X+ the terms of Paragraph 1 above, provided that you also do the following:
X+ 
X+     a) cause the modified files to carry prominent notices stating
X+     that you changed the files and the date of any change; and
X+ 
X+     b) cause the whole of any work that you distribute or publish,
X+     that in whole or in part contains or is a derivative of this
X+     program or any part thereof, to be licensed at no charge to all
X+     third parties on terms identical to those contained in this
X+     License Agreement (except that you may choose to grant more extensive
X+     warranty protection to some or all third parties, at your option).
X+ 
X+     c) You may charge a distribution fee for the physical act of
X+     transferring a copy, and you may at your option offer warranty
X+     protection in exchange for a fee.
X+ 
X+ Mere aggregation of another unrelated program with this program (or its
X+ derivative) on a volume of a storage or distribution medium does not bring
X+ the other program under the scope of these terms.
X+ 
X+   3. You may copy and distribute this program (or a portion or derivative
X+ of it, under Paragraph 2) in object code or executable form under the terms
X+ of Paragraphs 1 and 2 above provided that you also do one of the following:
X+ 
X+     a) accompany it with the complete corresponding machine-readable
X+     source code, which must be distributed under the terms of
X+     Paragraphs 1 and 2 above; or,
X+ 
X+     b) accompany it with a written offer, valid for at least three
X+     years, to give any third party free (except for a nominal
X+     shipping charge) a complete machine-readable copy of the
X+     corresponding source code, to be distributed under the terms of
X+     Paragraphs 1 and 2 above; or,
X+ 
X+     c) accompany it with the information you received as to where the
X+     corresponding source code may be obtained.  (This alternative is
X+     allowed only for noncommercial distribution and only if you
X+     received the program in object code or executable form alone.)
X+ 
X+ For an executable file, complete source code means all the source code for
X+ all modules it contains; but, as a special exception, it need not include
X+ source code for modules which are standard libraries that accompany the
X+ operating system on which the executable file runs.
X+ 
X+   4. You may not copy, sublicense, distribute or transfer this program
X+ except as expressly provided under this License Agreement.  Any attempt
X+ otherwise to copy, sublicense, distribute or transfer this program is void and
X+ your rights to use the program under this License agreement shall be
X+ automatically terminated.  However, parties who have received computer
X+ software programs from you with this License Agreement will not have
X+ their licenses terminated so long as such parties remain in full compliance.
X+ 
X+   5. If you wish to incorporate parts of this program into other free
X+ programs whose distribution conditions are different, write to the Free
X+ Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
X+ worked out a simple rule that can be stated here, but we will often permit
X+ this.  We will be guided by the two goals of preserving the free status of
X+ all derivatives of our free software and of promoting the sharing and reuse of
X+ software.
X+ 
X+ 
X+ In other words, you are welcome to use, share and improve this program.
X+ You are forbidden to forbid anyone else to use, share and improve
X+ what you give them.   Help stamp out software-hoarding!  */
X+ 
X+ 
X+ 
X+ /* BUFSIZE is the initial size allocated for the buffer
X+    for reading the termcap file.
X+    It is not a limit.
X+    Make it large normally for speed.
X+    Make it variable when debugging, so can exercise
X+    increasing the space dynamically.  */
X+ 
X+ #ifdef emacs
X+ #include "config.h"
X+ #endif
X+ 
X+ #ifndef BUFSIZE
X+ #ifdef DEBUG
X+ #define BUFSIZE bufsize
X+ 
X+ int bufsize = 128;
X+ #else
X+ #define BUFSIZE 2048
X+ #endif
X+ #endif
X+ 
X+ #ifndef emacs
X+ static
X+ memory_out ()
X+ {
X+   write (2, "Virtual memory exhausted\n", 25);
X+   exit (1);
X+ }
X+ 
X+ static int
X+ xmalloc (size)
X+      int size;
X+ {
X+   register tem = malloc (size);
X+   if (!tem)
X+     memory_out ();
X+   return tem;
X+ }
X+ 
X+ static int
X+ xrealloc (ptr, size)
X+      int ptr;
X+      int size;
X+ {
X+   register tem = realloc (ptr, size);
X+   if (!tem)
X+     memory_out ();
X+   return tem;
X+ }
X+ #endif /* not emacs */
X+ 
X+ /* Looking up capabilities in the entry already found */
X+ 
X+ /* The pointer to the data made by tgetent is left here
X+    for tgetnum, tgetflag and tgetstr to find.  */
X+ 
X+ static char *term_entry;
X+ 
X+ static char *tgetst1 ();
X+ 
X+ /* This is the main subroutine that is used to search
X+    an entry for a particular capability */
X+ 
X+ static char *
X+ find_capability (bp, cap)
X+      register char *bp, *cap;
X+ {
X+   for (; *bp; bp++)
X+     if (bp[0] == ':'
X+ 	&& bp[1] == cap[0]
X+ 	&& bp[2] == cap[1])
X+       return &bp[4];
X+   return 0;
X+ }
X+ 
X+ int
X+ tgetnum (cap)
X+      char *cap;
X+ {
X+   register char *ptr = find_capability (term_entry, cap);
X+   if (!ptr || ptr[-1] != '#')
X+     return -1;
X+   return atoi (ptr);
X+ }
X+ 
X+ int
X+ tgetflag (cap)
X+      char *cap;
X+ {
X+   register char *ptr = find_capability (term_entry, cap);
X+   return 0 != ptr && ptr[-1] == ':';
X+ }
X+ 
X+ /* Look up a string-valued capability `cap'.
X+    If `area' is nonzero, it points to a pointer to a block in which
X+    to store the string.  That pointer is advanced over the space used.
X+    If `area' is zero, space is allocated with `malloc'.  */
X+ 
X+ char *
X+ tgetstr (cap, area)
X+      char *cap;
X+      char **area;
X+ {
X+   register char *ptr = find_capability (term_entry, cap);
X+   if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~'))
X+     return 0;
X+   return tgetst1 (ptr, area);
X+ }
X+ 
X+ /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted,
X+    gives meaning of character following \, or a space if no special meaning.
X+    Eight characters per line within the string.  */
X+ 
X+ static char esctab[]
X+   = " \007\010  \033\014 \
X+       \012 \
X+   \015 \011 \013 \
X+         ";
X+ 
X+ /* Given a pointer to a string value inside a termcap entry (`ptr'),
X+    copy the value and process \ and ^ abbreviations.
X+    Copy into block that *area points to,
X+    or to newly allocated storage if area is 0.  */
X+ 
X+ static char *
X+ tgetst1 (ptr, area)
X+      char *ptr;
X+      char **area;
X+ {
X+   register char *p, *r;
X+   register int c;
X+   register int size;
X+   char *ret;
X+   register int c1;
X+ 
X+   if (!ptr)
X+     return 0;
X+ 
X+   /* `ret' gets address of where to store the string */
X+   if (!area)
X+     {
X+       /* Compute size of block needed (may overestimate) */
X+       p = ptr;
X+       while ((c = *p++) && c != ':' && c != '\n');
X+       ret = (char *) xmalloc (p - ptr + 1);
X+     }
X+   else
X+     ret = *area;
X+ 
X+   /* Copy the string value, stopping at null or colon.  */
X+   /* Also process ^ and \ abbreviations.  */
X+   p = ptr;
X+   r = ret;
X+   while ((c = *p++) && c != ':' && c != '\n')
X+     {
X+       if (c == '^')
X+ 	c = *p++ & 037;
X+       else if (c == '\\')
X+ 	{
X+ 	  c = *p++;
X+ 	  if (c >= '0' && c <= '7')
X+ 	    {
X+ 	      c -= '0';
X+ 	      size = 0;
X+ 
X+ 	      while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7')
X+ 		{
X+ 		  c *= 8;
X+ 		  c += c1 - '0';
X+ 		  p++;
X+ 		}
X+ 	    }
X+ 	  else if (c >= 0100 && c < 0200)
X+ 	    {
X+ 	      c1 = esctab[(c & ~040) - 0100];
X+ 	      if (c1 != ' ')
X+ 		c = c1;
X+ 	    }
X+ 	}
X+       *r++ = c;
X+     }
X+   *r = 0;
X+   /* Update *area */
X+   if (area)
X+     *area = r + 1;
X+   return ret;
X+ }
X+ 
X+ /* Outputting a string with padding */
X+ 
X+ short ospeed;
X+ char PC;
X+ 
X+ /* Actual baud rate if positive;
X+    - baud rate / 100 if negative.  */
X+ 
X+ static short speeds[] =
X+   {
X+ #ifdef VMS
X+     0, 50, 75, 110, 134, 150, -3, -6, -12, -18,
X+     -20, -24, -36, -48, -72, -96, -192
X+ #else /* not VMS */
X+     0, 50, 75, 110, 135, 150, -2, -3, -6, -12,
X+     -18, -24, -48, -96, -192, -384
X+ #endif /* not VMS */
X+   };
X+ 
X+ tputs (string, nlines, outfun)
X+      register char *string;
X+      int nlines;
X+      register int (*outfun) ();
X+ {
X+   register int padcount = 0;
X+ 
X+   if (string == (char *) 0)
X+     return;
X+   while (*string >= '0' && *string <= '9')
X+     {
X+       padcount += *string++ - '0';
X+       padcount *= 10;
X+     }
X+   if (*string == '.')
X+     {
X+       string++;
X+       padcount += *string++ - '0';
X+     }
X+   if (*string == '*')
X+     {
X+       string++;
X+       padcount *= nlines;
X+     }
X+   while (*string)
X+     (*outfun) (*string++);
X+ 
X+   /* padcount is now in units of tenths of msec.  */
X+   padcount *= speeds[ospeed];
X+   padcount += 500;
X+   padcount /= 1000;
X+   if (speeds[ospeed] < 0)
X+     padcount = -padcount;
X+   else
X+     {
X+       padcount += 50;
X+       padcount /= 100;
X+     }
X+ 
X+   while (padcount-- > 0)
X+     (*outfun) (PC);
X+ }
X+ 
X+ /* Finding the termcap entry in the termcap data base */
X+ 
X+ struct buffer
X+   {
X+     char *beg;
X+     int size;
X+     char *ptr;
X+     int ateof;
X+     int full;
X+   };
X+ 
X+ /* Forward declarations of static functions */
X+ 
X+ static int scan_file ();
X+ static char *gobble_line ();
X+ static int compare_contin ();
X+ static int name_match ();
X+ 
X+ #ifdef VMS
X+ 
X+ #include <rmsdef.h>
X+ #include <fab.h>
X+ #include <nam.h>
X+ 
X+ static int
X+ legal_filename_p (fn)
X+      char *fn;
X+ {
X+   struct FAB fab = cc$rms_fab;
X+   struct NAM nam = cc$rms_nam;
X+   char esa[NAM$C_MAXRSS];
X+ 
X+   fab.fab$l_fna = fn;
X+   fab.fab$b_fns = strlen(fn);
X+   fab.fab$l_nam = &nam;
X+   fab.fab$l_fop = FAB$M_NAM;
X+ 
X+   nam.nam$l_esa = esa;
X+   nam.nam$b_ess = sizeof esa;
X+ 
X+   return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL;
X+ }
X+ 
X+ #endif /* VMS */
X+ 
X+ /* Find the termcap entry data for terminal type `name'
X+    and store it in the block that `bp' points to.
X+    Record its address for future use.
X+ 
X+    If `bp' is zero, space is dynamically allocated.  */
X+ 
X+ int
X+ tgetent (bp, name)
X+      char *bp, *name;
X+ {
X+   register char *tem;
X+   register int fd;
X+   struct buffer buf;
X+   register char *bp1;
X+   char *bp2;
X+   char *term;
X+   int malloc_size = 0;
X+   register int c;
X+   char *tcenv;			/* TERMCAP value, if it contais :tc=.  */
X+   char *indirect = 0;		/* Terminal type in :tc= in TERMCAP value.  */
X+   int filep;
X+ 
X+   tem = (char *) getenv ("TERMCAP");
X+   if (tem && *tem == 0) tem = 0;
X+ 
X+ #ifdef VMS
X+   filep = tem && legal_filename_p (tem);
X+ #else
X+   filep = tem && (*tem == '/');
X+ #endif /* VMS */
X+ 
X+   /* If tem is non-null and starts with / (in the un*x case, that is),
X+      it is a file name to use instead of /etc/termcap.
X+      If it is non-null and does not start with /,
X+      it is the entry itself, but only if
X+      the name the caller requested matches the TERM variable.  */
X+ 
X+   if (tem && !filep && !strcmp (name, getenv ("TERM")))
X+     {
X+       indirect = tgetst1 (find_capability (tem, "tc"), 0);
X+       if (!indirect)
X+ 	{
X+ 	  if (!bp)
X+ 	    bp = tem;
X+ 	  else
X+ 	    strcpy (bp, tem);
X+ 	  goto ret;
X+ 	}
X+       else
X+ 	{			/* we will need to read /etc/termcap */
X+ 	  tcenv = tem;
X+  	  tem = 0;
X+ 	}
X+     }
X+   else
X+     indirect = (char *) 0;
X+ 
X+   if (!tem)
X+ #ifdef VMS
X+     tem = "emacs_library:[etc]termcap.dat";
X+ #else
X+     tem = "/etc/termcap";
X+ #endif
X+ 
X+   /* Here we know we must search a file and tem has its name.  */
X+ 
X+   fd = open (tem, 0, 0);
X+   if (fd < 0)
X+     return -1;
X+ 
X+   buf.size = BUFSIZE;
X+   buf.beg = (char *) xmalloc (buf.size);
X+   term = indirect ? indirect : name;
X+ 
X+   if (!bp)
X+     {
X+       malloc_size = indirect ? strlen (tcenv) + 1 : buf.size;
X+       bp = (char *) xmalloc (malloc_size);
X+     }
X+   bp1 = bp;
X+ 
X+   if (indirect)			/* copy the data from the environment variable */
X+     {
X+       strcpy (bp, tcenv);
X+       bp1 += strlen (tcenv);
X+     }
X+ 
X+   while (term)
X+     {
X+       /* Scan file, reading it via buf, till find start of main entry */
X+       if (scan_file (term, fd, &buf) == 0)
X+ 	return 0;
X+ 
X+       /* Free old `term' if appropriate.  */
X+       if (term != name)
X+ 	free (term);
X+ 
X+       /* If `bp' is malloc'd by us, make sure it is big enough.  */
X+       if (malloc_size)
X+ 	{
X+ 	  malloc_size = bp1 - bp + buf.size;
X+ 	  tem = (char *) xrealloc (bp, malloc_size);
X+ 	  bp1 += tem - bp;
X+ 	  bp = tem;
X+ 	}
X+ 
X+       bp2 = bp1;
X+ 
X+       /* Copy the line of the entry from buf into bp.  */
X+       tem = buf.ptr;
X+       while ((*bp1++ = c = *tem++) && c != '\n')
X+ 	/* Drop out any \ newline sequence. */
X+ 	if (c == '\\' && *tem == '\n')
X+ 	  {
X+ 	    bp1--;
X+ 	    tem++;
X+ 	  }
X+       *bp1 = 0;
X+ 
X+       /* Does this entry refer to another terminal type's entry?  */
X+       /* If something is found, copy it into heap and null-terminate it */
X+       term = tgetst1 (find_capability (bp2, "tc"), 0);
X+     }
X+ 
X+   close (fd);
X+   free (buf.beg);
X+ 
X+   if (malloc_size)
X+     {
X+       bp = (char *) xrealloc (bp, bp1 - bp + 1);
X+     }
X+ 
X+  ret:
X+   term_entry = bp;
X+   if (malloc_size)
X+     return (int) bp;
X+   return 1;
X+ }
X+ 
X+ /* Given file open on `fd' and buffer `bufp',
X+    scan the file from the beginning until a line is found
X+    that starts the entry for terminal type `string'.
X+    Returns 1 if successful, with that line in `bufp',
X+    or returns 0 if no entry found in the file.  */
X+ 
X+ static int
X+ scan_file (string, fd, bufp)
X+      char *string;
X+      int fd;
X+      register struct buffer *bufp;
X+ {
X+   register char *tem;
X+   register char *end;
X+ 
X+   bufp->ptr = bufp->beg;
X+   bufp->full = 0;
X+   bufp->ateof = 0;
X+   *bufp->ptr = 0;
X+ 
X+   lseek (fd, 0L, 0);
X+ 
X+   while (!bufp->ateof)
X+     {
X+       /* Read a line into the buffer */
X+       end = 0;
X+       do
X+ 	{
X+ 	  /* if it is continued, append another line to it,
X+ 	     until a non-continued line ends */
X+ 	  end = gobble_line (fd, bufp, end);
X+ 	}
X+       while (!bufp->ateof && end[-2] == '\\');
X+ 
X+       if (*bufp->ptr != '#'
X+ 	  && name_match (bufp->ptr, string))
X+ 	return 1;
X+ 
X+       /* Discard the line just processed */
X+       bufp->ptr = end;
X+     }
X+   return 0;
X+ }
X+ 
X+ /* Return nonzero if NAME is one of the names specified
X+    by termcap entry LINE.  */
X+ 
X+ static int
X+ name_match (line, name)
X+      char *line, *name;
X+ {
X+   register char *tem;
X+ 
X+   if (!compare_contin (line, name))
X+     return 1;
X+   /* This line starts an entry.  Is it the right one?  */
X+   for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++)
X+     if (*tem == '|' && !compare_contin (tem + 1, name))
X+       return 1;
X+ 
X+   return 0;
X+ }
X+ 
X+ static int
X+ compare_contin (str1, str2)
X+      register char *str1, *str2;
X+ {
X+   register int c1, c2;
X+   while (1)
X+     {
X+       c1 = *str1++;
X+       c2 = *str2++;
X+       while (c1 == '\\' && *str1 == '\n')
X+ 	{
X+ 	  str1++;
X+ 	  while ((c1 = *str1++) == ' ' || c1 == '\t');
X+ 	}
X+       if (c2 == '\0')		/* end of type being looked up */
X+ 	{
X+ 	  if (c1 == '|' || c1 == ':') /* If end of name in data base, */
X+ 	    return 0;		/* we win. */
X+ 	  else
X+ 	    return 1;
X+         }
X+       else if (c1 != c2)
X+ 	return 1;
X+     }
X+ }
X+ 
X+ /* Make sure that the buffer <- `bufp' contains a full line
X+    of the file open on `fd', starting at the place `bufp->ptr'
X+    points to.  Can read more of the file, discard stuff before
X+    `bufp->ptr', or make the buffer bigger.
X+ 
X+    Returns the pointer to after the newline ending the line,
X+    or to the end of the file, if there is no newline to end it.
X+ 
X+    Can also merge on continuation lines.  If `append_end' is
X+    nonzero, it points past the newline of a line that is
X+    continued; we add another line onto it and regard the whole
X+    thing as one line.  The caller decides when a line is continued.  */
X+ 
X+ static char *
X+ gobble_line (fd, bufp, append_end)
X+      int fd;
X+      register struct buffer *bufp;
X+      char *append_end;
X+ {
X+   register char *end;
X+   register int nread;
X+   register char *buf = bufp->beg;
X+   register char *tem;
X+ 
X+   if (append_end == 0)
X+     append_end = bufp->ptr;
X+ 
X+   while (1)
X+     {
X+       end = append_end;
X+       while (*end && *end != '\n') end++;
X+       if (*end)
X+         break;
X+       if (bufp->ateof)
X+ 	return buf + bufp->full;
X+       if (bufp->ptr == buf)
X+ 	{
X+ 	  if (bufp->full == bufp->size)
X+ 	    {
X+ 	      bufp->size *= 2;
X+ 	      tem = (char *) xrealloc (buf, bufp->size);
X+ 	      bufp->ptr += tem - buf;
X+ 	      append_end += tem - buf;
X+ 	      bufp->beg = buf = tem;
X+ 	    }
X+ 	}
X+       else
X+ 	{
X+ 	  append_end -= bufp->ptr - buf;
X+ 	  bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf);
X+ 	  bufp->ptr = buf;
X+ 	}
X+       if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full)))
X+ 	bufp->ateof = 1;
X+       bufp->full += nread;
X+       if (bufp->full != bufp->size)
X+ 	buf[bufp->full] = 0;
X+     }
X+   return end + 1;
X+ }
X+ 
X+ #ifdef TEST
X+ 
X+ #include <stdio.h>
X+ 
X+ main (argc, argv)
X+      int argc;
X+      char **argv;
X+ {
X+   char *term;
X+   char *buf;
X+ 
X+   term = argv[1];
X+   printf ("TERM: %s\n", term);
X+ 
X+   buf = (char *) tgetent (0, term);
X+   if ((int) buf <= 0)
X+     {
X+       printf ("No entry.\n");
X+       return 0;
X+     }
X+ 
X+   printf ("Entry: %s\n", buf);
X+ 
X+   tprint ("cm");
X+   tprint ("AL");
X+ 
X+   printf ("co: %d\n", tgetnum ("co"));
X+   printf ("am: %d\n", tgetflag ("am"));
X+ }
X+ 
X+ tprint (cap)
X+      char *cap;
X+ {
X+   char *x = tgetstr (cap, 0);
X+   register char *y;
X+ 
X+   printf ("%s: ", cap);
X+   if (x)
X+     {
X+       for (y = x; *y; y++)
X+ 	if (*y <= ' ' || *y == 0177)
X+ 	  printf ("\\%0o", *y);
X+ 	else
X+ 	  putchar (*y);
X+       free (x);
X+     }
X+   else
X+     printf ("none");
X+   putchar ('\n');
X+ }
X+ 
X+ #endif /* TEST */
X*** /dev/null	Wed Sep 27 12:47:48 1989
X--- vms/vmstparam.c	Sat Sep 16 12:24:46 1989
X***************
X*** 0 ****
X--- 1,360 ----
X+ /* Merge parameters into a termcap entry string.
X+    Copyright (C) 1985, 1987 Free Software Foundation, Inc.
X+ 
X+ 
X+ 		       NO WARRANTY
X+ 
X+   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
X+ NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
X+ WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
X+ RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
X+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
X+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
X+ FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
X+ AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
X+ DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
X+ CORRECTION.
X+ 
X+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
X+ STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
X+ WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
X+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
X+ OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
X+ USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
X+ DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
X+ A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
X+ PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
X+ DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
X+ 
X+ 		GENERAL PUBLIC LICENSE TO COPY
X+ 
X+   1. You may copy and distribute verbatim copies of this source file
X+ as you receive it, in any medium, provided that you conspicuously and
X+ appropriately publish on each copy a valid copyright notice "Copyright
X+ (C) 1986 Free Software Foundation, Inc."; and include following the
X+ copyright notice a verbatim copy of the above disclaimer of warranty
X+ and of this License.  You may charge a distribution fee for the
X+ physical act of transferring a copy.
X+ 
X+   2. You may modify your copy or copies of this source file or
X+ any portion of it, and copy and distribute such modifications under
X+ the terms of Paragraph 1 above, provided that you also do the following:
X+ 
X+     a) cause the modified files to carry prominent notices stating
X+     that you changed the files and the date of any change; and
X+ 
X+     b) cause the whole of any work that you distribute or publish,
X+     that in whole or in part contains or is a derivative of this
X+     program or any part thereof, to be licensed at no charge to all
X+     third parties on terms identical to those contained in this
X+     License Agreement (except that you may choose to grant more extensive
X+     warranty protection to some or all third parties, at your option).
X+ 
X+     c) You may charge a distribution fee for the physical act of
X+     transferring a copy, and you may at your option offer warranty
X+     protection in exchange for a fee.
X+ 
X+ Mere aggregation of another unrelated program with this program (or its
X+ derivative) on a volume of a storage or distribution medium does not bring
X+ the other program under the scope of these terms.
X+ 
X+   3. You may copy and distribute this program (or a portion or derivative
X+ of it, under Paragraph 2) in object code or executable form under the terms
X+ of Paragraphs 1 and 2 above provided that you also do one of the following:
X+ 
X+     a) accompany it with the complete corresponding machine-readable
X+     source code, which must be distributed under the terms of
X+     Paragraphs 1 and 2 above; or,
X+ 
X+     b) accompany it with a written offer, valid for at least three
X+     years, to give any third party free (except for a nominal
X+     shipping charge) a complete machine-readable copy of the
X+     corresponding source code, to be distributed under the terms of
X+     Paragraphs 1 and 2 above; or,
X+ 
X+     c) accompany it with the information you received as to where the
X+     corresponding source code may be obtained.  (This alternative is
X+     allowed only for noncommercial distribution and only if you
X+     received the program in object code or executable form alone.)
X+ 
X+ For an executable file, complete source code means all the source code for
X+ all modules it contains; but, as a special exception, it need not include
X+ source code for modules which are standard libraries that accompany the
X+ operating system on which the executable file runs.
X+ 
X+   4. You may not copy, sublicense, distribute or transfer this program
X+ except as expressly provided under this License Agreement.  Any attempt
X+ otherwise to copy, sublicense, distribute or transfer this program is void and
X+ your rights to use the program under this License agreement shall be
X+ automatically terminated.  However, parties who have received computer
X+ software programs from you with this License Agreement will not have
X+ their licenses terminated so long as such parties remain in full compliance.
X+ 
X+   5. If you wish to incorporate parts of this program into other free
X+ programs whose distribution conditions are different, write to the Free
X+ Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
X+ worked out a simple rule that can be stated here, but we will often permit
X+ this.  We will be guided by the two goals of preserving the free status of
X+ all derivatives of our free software and of promoting the sharing and reuse of
X+ software.
X+ 
X+ 
X+ In other words, you are welcome to use, share and improve this program.
X+ You are forbidden to forbid anyone else to use, share and improve
X+ what you give them.   Help stamp out software-hoarding!  */
X+ 
X+ 
X+ /* config.h may rename various library functions such as malloc.  */
X+ #ifdef emacs
X+ #include "config.h"
X+ #endif
X+ 
X+ /* Assuming STRING is the value of a termcap string entry
X+    containing `%' constructs to expand parameters,
X+    merge in parameter values and store result in block OUTSTRING points to.
X+    LEN is the length of OUTSTRING.  If more space is needed,
X+    a block is allocated with `malloc'.
X+ 
X+    The value returned is the address of the resulting string.
X+    This may be OUTSTRING or may be the address of a block got with `malloc'.
X+    In the latter case, the caller must free the block.
X+ 
X+    The fourth and following args to tparam serve as the parameter values.  */
X+ 
X+ static char *tparam1 ();
X+ 
X+ /* VARARGS 2 */
X+ char *
X+ tparam (string, outstring, len, arg0, arg1, arg2, arg3)
X+      char *string;
X+      char *outstring;
X+      int len;
X+      int arg0, arg1, arg2, arg3;
X+ {
X+ #ifdef NO_ARG_ARRAY
X+   int arg[4];
X+   arg[0] = arg0;
X+   arg[1] = arg1;
X+   arg[2] = arg2;
X+   arg[3] = arg3;
X+   return tparam1 (string, outstring, len, 0, 0, arg);
X+ #else
X+   return tparam1 (string, outstring, len, 0, 0, &arg0);
X+ #endif
X+ }
X+ 
X+ char *BC;
X+ char *UP;
X+ 
X+ static char tgoto_buf[50];
X+ 
X+ char *
X+ tgoto (cm, hpos, vpos)
X+      char *cm;
X+      int hpos, vpos;
X+ {
X+   int args[2];
X+   if (!cm)
X+     return 0;
X+   args[0] = vpos;
X+   args[1] = hpos;
X+   return tparam1 (cm, tgoto_buf, 50, UP, BC, args);
X+ }
X+ 
X+ static char *
X+ tparam1 (string, outstring, len, up, left, argp)
X+      char *string;
X+      char *outstring;
X+      int len;
X+      char *up, *left;
X+      register int *argp;
X+ {
X+   register int c;
X+   register char *p = string;
X+   register char *op = outstring;
X+   char *outend;
X+   int outlen = 0;
X+ 
X+   register int tem;
X+   int *oargp = argp;
X+   int doleft = 0;
X+   int doup = 0;
X+ 
X+   outend = outstring + len;
X+ 
X+   while (1)
X+     {
X+       /* If the buffer might be too short, make it bigger.  */
X+       if (op + 5 >= outend)
X+ 	{
X+ 	  register char *new;
X+ 	  if (outlen == 0)
X+ 	    {
X+ 	      new = (char *) malloc (outlen = 40 + len);
X+ 	      outend += 40;
X+ 	    }
X+ 	  else
X+ 	    {
X+ 	      outend += outlen;
X+ 	      new = (char *) realloc (outstring, outlen *= 2);
X+ 	    }
X+ 	  op += new - outstring;
X+ 	  outend += new - outstring;
X+ 	  outstring = new;
X+ 	}
X+       if (!(c = *p++))
X+ 	break;
X+       if (c == '%')
X+ 	{
X+ 	  c = *p++;
X+ 	  tem = *argp;
X+ 	  switch (c)
X+ 	    {
X+ 	    case 'd':		/* %d means output in decimal */
X+ 	      if (tem < 10)
X+ 		goto onedigit;
X+ 	      if (tem < 100)
X+ 		goto twodigit;
X+ 	    case '3':		/* %3 means output in decimal, 3 digits. */
X+ 	      if (tem > 999)
X+ 		{
X+ 		  *op++ = tem / 1000 + '0';
X+ 		  tem %= 1000;
X+ 		}
X+ 	      *op++ = tem / 100 + '0';
X+ 	    case '2':		/* %2 means output in decimal, 2 digits. */
X+ 	    twodigit:
X+ 	      tem %= 100;
X+ 	      *op++ = tem / 10 + '0';
X+ 	    onedigit:
X+ 	      *op++ = tem % 10 + '0';
X+ 	      argp++;
X+ 	      break;
X+ 
X+ 	    case 'C':
X+ 	      /* For c-100: print quotient of value by 96, if nonzero,
X+ 		 then do like %+ */
X+ 	      if (tem >= 96)
X+ 		{
X+ 		  *op++ = tem / 96;
X+ 		  tem %= 96;
X+ 		}
X+ 	    case '+':		/* %+x means add character code of char x */
X+ 	      tem += *p++;
X+ 	    case '.':		/* %. means output as character */
X+ 	      if (left)
X+ 		{
X+ 		  /* If want to forbid output of 0 and \n and \t,
X+ 		     and this is one of them, increment it.  */
X+ 		  while (tem == 0 || tem == '\n' || tem == '\t')
X+ 		    {
X+ 		      tem++;
X+ 		      if (argp == oargp)
X+ 			doleft++, outend -= strlen (left);
X+ 		      else
X+ 			doup++, outend -= strlen (up);
X+ 		    }
X+ 		}
X+ 	      *op++ = tem | 0200;
X+ 	    case 'f':		/* %f means discard next arg */
X+ 	      argp++;
X+ 	      break;
X+ 
X+ 	    case 'b':		/* %b means back up one arg (and re-use it) */
X+ 	      argp--;
X+ 	      break;
X+ 
X+ 	    case 'r':		/* %r means interchange following two args */
X+ 	      argp[0] = argp[1];
X+ 	      argp[1] = tem;
X+ 	      oargp++;
X+ 	      break;
X+ 
X+ 	    case '>':		/* %>xy means if arg is > char code of x, */
X+ 	      if (argp[0] > *p++) /* then add char code of y to the arg, */
X+ 		argp[0] += *p;	/* and in any case don't output. */
X+ 	      p++;		/* Leave the arg to be output later. */
X+ 	      break;
X+ 
X+ 	    case 'a':		/* %a means arithmetic */
X+ 	      /* Next character says what operation.
X+ 		 Add or subtract either a constant or some other arg */
X+ 	      /* First following character is + to add or - to subtract
X+ 		 or = to assign.  */
X+ 	      /* Next following char is 'p' and an arg spec
X+ 		 (0100 plus position of that arg relative to this one)
X+ 		 or 'c' and a constant stored in a character */
X+ 	      tem = p[2] & 0177;
X+ 	      if (p[1] == 'p')
X+ 		tem = argp[tem - 0100];
X+ 	      if (p[0] == '-')
X+ 		argp[0] -= tem;
X+ 	      else if (p[0] == '+')
X+ 		argp[0] += tem;
X+ 	      else if (p[0] == '*')
X+ 		argp[0] *= tem;
X+ 	      else if (p[0] == '/')
X+ 		argp[0] /= tem;
X+ 	      else
X+ 		argp[0] = tem;
X+ 
X+ 	      p += 3;
X+ 	      break;
X+ 
X+ 	    case 'i':		/* %i means add one to arg, */
X+ 	      argp[0] ++;	/* and leave it to be output later. */
X+ 	      argp[1] ++;	/* Increment the following arg, too!  */
X+ 	      break;
X+ 
X+ 	    case '%':		/* %% means output %; no arg. */
X+ 	      goto ordinary;
X+ 
X+ 	    case 'n':		/* %n means xor each of next two args with 140 */
X+ 	      argp[0] ^= 0140;
X+ 	      argp[1] ^= 0140;
X+ 	      break;
X+ 
X+ 	    case 'm':		/* %m means xor each of next two args with 177 */
X+ 	      argp[0] ^= 0177;
X+ 	      argp[1] ^= 0177;
X+ 	      break;
X+ 
X+ 	    case 'B':		/* %B means express arg as BCD char code. */
X+ 	      argp[0] += 6 * (tem / 10);
X+ 	      break;
X+ 
X+ 	    case 'D':		/* %D means weird Delta Data transformation */
X+ 	      argp[0] -= 2 * (tem % 16);
X+ 	      break;
X+ 	    }
X+ 	}
X+       else
X+ 	/* Ordinary character in the argument string.  */
X+       ordinary:
X+ 	*op++ = c;
X+     }
X+   *op = 0;
X+   while (doleft-- > 0)
X+     strcpy (op, left);
X+   while (doup-- > 0)
X+     strcpy (op, up);
X+   return outstring;
X+ }
X+ 
X+ #ifdef DEBUG
X+ 
X+ main (argc, argv)
X+      int argc;
X+      char **argv;
X+ {
X+   char buf[50];
X+   int args[3];
X+   args[0] = atoi (argv[2]);
X+   args[1] = atoi (argv[3]);
X+   args[2] = atoi (argv[4]);
X+   tparam1 (argv[1], buf, "LEFT", "UP", args);
X+   printf ("%s\n", buf);
X+   return 0;
X+ }
X+ 
X+ #endif /* DEBUG */
X*** /dev/null	Wed Sep 27 12:48:01 1989
X--- vms/vmstty.c	Wed Sep 27 09:29:57 1989
X***************
X*** 0 ****
X--- 1,170 ----
X+ /*	SCCS Id: @(#)vmstty.c	3.0	88/05/03
X+ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X+ /* NetHack may be freely redistributed.  See license for details. */
X+ /* tty.c - (VMS) version */
X+ 
X+ #define NEED_VARARGS
X+ #include "hack.h"
X+ 
X+ #include	<descrip.h>
X+ #include	<iodef.h>
X+ #include	<smgdef.h>
X+ 
X+ #define LIB$M_CLI_CTRLT 0x100000
X+ #define LIB$M_CLI_CTRLY 0x2000000
X+ 
X+ extern short ospeed;
X+ char erase_char, intr_char, kill_char;
X+ static boolean settty_needed = FALSE;
X+ static unsigned int kb = 0;
X+ 
X+ int
X+ vms_getchar()
X+ {
X+     short key;
X+ 
X+     if (kb)
X+     {
X+ 	SMG$READ_KEYSTROKE(&kb, &key);
X+ 	switch (key)
X+ 	{
X+ 	  case SMG$K_TRM_UP:
X+ 	    key = 'k';
X+ 	    break;
X+ 	  case SMG$K_TRM_DOWN:
X+ 	    key = 'j';
X+ 	    break;
X+ 	  case SMG$K_TRM_LEFT:
X+ 	    key = 'h';
X+ 	    break;
X+ 	  case SMG$K_TRM_RIGHT:
X+ 	    key = 'l';
X+ 	    break;
X+ 	  case '\r':
X+ 	    key = '\n';
X+ 	    break;
X+ 	  default:
X+ 	    if (key == '\007' || key == '\032' || key > 255)
X+ 		key = '\033';
X+ 	    break;
X+ 	}
X+     }
X+     else
X+ 	key = getchar();
X+     return key;
X+ }
X+ 
X+ static struct sensemode {
X+     short status;
X+     unsigned char xmit_baud;
X+     unsigned char rcv_baud;
X+     unsigned char crfill;
X+     unsigned char lffill;
X+     unsigned char parity;
X+     unsigned char unused;
X+     char class;
X+     char type;
X+     short scr_wid;
X+     unsigned long tt_char: 24, scr_len: 8;
X+     unsigned long tt2_char;
X+ } sg;
X+ unsigned int ctrl_mask;
X+ 
X+ static void
X+ setctty(){
X+ }
X+ 
X+ /*
X+  * Get initial state of terminal, set ospeed (for termcap routines)
X+  * and switch off tab expansion if necessary.
X+  * Called by startup() in termcap.c and after returning from ! or ^Z
X+  */
X+ void
X+ gettty(){
X+     int status;
X+     int input_chan;
X+     $DESCRIPTOR (input_dsc, "TT");
X+     unsigned int zero = 0;
X+ 
X+     if (!(SYS$ASSIGN (&input_dsc, &input_chan, 0, 0) & 1))
X+ 	perror("NetHack (gettty)");
X+     status = SYS$QIOW(0, input_chan, IO$_SENSEMODE, &sg, 0, 0, &sg.class, 12,
X+ 		      0, 0, 0, 0);
X+     SYS$DASSGN (input_chan);
X+     if (!(status & 1))
X+ 	perror("NetHack (gettty)");
X+     ospeed = sg.xmit_baud;
X+     erase_char = '\177';
X+     kill_char = '\025';
X+     intr_char = '\003';
X+     (void) LIB$ENABLE_CTRL(&zero, &ctrl_mask);
X+     /* Use the systems's values for lines and columns if it has any idea. */
X+     if (sg.scr_len)
X+ 	LI = sg.scr_len;
X+     if (sg.scr_wid)
X+ 	CO = sg.scr_wid;
X+     settty_needed = TRUE;
X+ }
X+ 
X+ #ifdef MAIL
X+ unsigned long pasteboard_id = 0;
X+ #endif
X+ 
X+ /* reset terminal to original state */
X+ void
X+ settty(s)
X+ char *s;
X+ {
X+ 	clear_screen();
X+ 	end_screen();
X+ 	if(s) Printf(s);
X+ 	(void) fflush(stdout);
X+ 	SMG$DELETE_VIRTUAL_KEYBOARD(&kb);
X+ #ifdef MAIL
X+ 	SMG$DELETE_PASTEBOARD(&pasteboard_id);
X+ #endif
X+ 	if (ctrl_mask)
X+ 	    (void) LIB$ENABLE_CTRL(&ctrl_mask, 0);
X+ 	flags.echo = ON;
X+ 	flags.cbreak = OFF;
X+ }
X+ 
X+ #ifdef MAIL
X+ static void
X+ broadcast_ast(dummy)
X+ {
X+ 	extern int broadcasts;
X+ 
X+ 	broadcasts++;
X+ }
X+ #endif
X+ 
X+ void
X+ setftty(){
X+ 	unsigned int mask = LIB$M_CLI_CTRLT | LIB$M_CLI_CTRLY;
X+ 
X+ 	flags.cbreak = ON;
X+ 	flags.echo = OFF;
X+ 	(void) LIB$DISABLE_CTRL(&mask, 0);
X+ 	SMG$CREATE_VIRTUAL_KEYBOARD(&kb);
X+ #ifdef MAIL
X+ 	SMG$CREATE_PASTEBOARD(&pasteboard_id, 0, 0, 0, 0);
X+ 	SMG$SET_BROADCAST_TRAPPING(&pasteboard_id, broadcast_ast, 0);
X+ #endif
X+ 	start_screen();
X+ }
X+ 
X+ 
X+ /* fatal error */
X+ /*VARARGS1*/
X+ void
X+ error VA_DECL(char *,s)
X+ 	VA_START(s);
X+ 	VA_INIT(char *,s);
X+ 	if(settty_needed)
X+ 		settty(NULL);
X+ 	Vprintf(s,VA_ARGS);
X+ 	(void) putchar('\n');
X+ 	VA_END();
X+ 	exit(1);
X+ }
X
END_OF_FILE
if test 52494 -ne `wc -c <'patches04f'`; then
    echo shar: \"'patches04f'\" unpacked with wrong size!
fi
# end of 'patches04f'
fi
echo shar: End of archive 6 \(of 11\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0