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