billr@saab.CNA.TEK.COM (Bill Randle) (04/24/91)
Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley) Posting-number: Volume 12, Issue 63 Archive-name: larn2/Part10 Supersedes: larn: Volume 11, Issue 84-94 Environment: Unix, VMS, MS-DOS, OS/2, termcap #! /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 10 (of 12)." # Contents: fortune.c iventory.c larnhlp.uue msdos.c tgetent.c # Wrapped by billr@saab on Tue Apr 23 13:50:35 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'fortune.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fortune.c'\" else echo shar: Extracting \"'fortune.c'\" \(4263 characters\) sed "s/^X//" >'fortune.c' <<'END_OF_FILE' X/* fortune.c */ X#ifdef VMS X#include <types.h> X#include <stat.h> X#include <file.h> X#else X# include <sys/types.h> X# include <sys/stat.h> X# ifndef BSD4.1 X# include <fcntl.h> X# else BSD4.1 X# define O_RDONLY 0 X# endif BSD4.1 X#endif VMS X X#include "header.h" X#include "player.h" X#include "larndefs.h" Xextern char fortfile[]; X Xoutfortune() X { X char *p; X X lprcat("\nThe cookie was delicious."); X if (c[BLINDCOUNT]) X return; X#ifdef MSDOS X msdosfortune(); X#else X if (p=fortune(fortfile)) X { X lprcat(" Inside you find a scrap of paper that says:\n"); X lprcat(p); X } X#endif X } X X# ifdef MSDOS X# include <stdio.h> X/* Rumors has been entirely rewritten to be disk based. This is marginally X * slower, but requires no mallocked memory. Notice this in only valid for X * files smaller than 32K. X */ Xstatic int fortsize = 0; X Xstatic msdosfortune() X{ X int fd, status, i; X char buf[BUFSIZ], ch; X X if (fortsize < 0) /* We couldn't open fortunes */ X return; X if ((fd = open(fortfile, O_RDONLY | O_BINARY)) >= 0) { X if (fortsize == 0) X fortsize = (int) lseek(fd, 0L, 2); X if (lseek(fd, (long) rund(fortsize), 0) < 0) X return; X X /* Skip to next newline or EOF X */ X do { X status = read(fd, &ch, 1); X } while (status != EOF && ch != '\n'); X if (status == EOF) X if (lseek(fd, 0L, 0) < 0) /* back to the beginning */ X return; X X /* Read in the line. Search for CR ('\r'), not NL X */ X for (i = 0; i < BUFSIZ - 1; i++) X if (read(fd, &buf[i], 1) == EOF || buf[i] == '\r') X break; X buf[i] = '\0'; X X /* And spit it out X */ X lprcat(" Inside you find a scrap of paper that says:\n"); X lprcat(buf); X close(fd); X } else X fortsize = -1; /* Don't try opening it again */ X} X X# else X X/* X * function to return a random fortune from the fortune file X */ Xstatic char *base=0; /* pointer to the fortune text */ Xstatic char **flines=0; /* array of pointers to each fortune */ Xstatic int fd=0; /* true if we have load the fortune info */ Xstatic int nlines=0; /* # lines in fortune database */ X Xstatic char *fortune(file) Xchar *file; X{ X register char *p; X register int lines,tmp; X struct stat stat; X void *malloc(); X X if (fd == 0) { X if ((fd=open(file,O_RDONLY)) < 0) /* open the file */ X return(0); /* can't find file */ X X /* find out how big fortune file is and get memory for it */ X stat.st_size = 16384; X if ((fstat(fd,&stat) < 0) X || ((base=(char *)malloc(1+stat.st_size)) == 0)) { X close(fd); X fd= -1; X free((char*)base); X return(0); /* can't stat file */ X } X X /* read in the entire fortune file */ X#ifdef VMS X /* X * fstat lies about the size (each record has up to X * three bytes of fill reported as actual size). X * vread returns correct size. X */ X stat.st_size = vread(fd,base,stat.st_size); X if (stat.st_size <= 0) X#else X if (vread(fd,base,stat.st_size) != stat.st_size) X#endif X { X close(fd); X fd= -1; X free((char*)base); X return(0); /* can't read file */ X } X close(fd); X base[stat.st_size]=0; /* final NULL termination */ X X /* count up all the lines (and 0 terminate) to know memory X * needs X */ X for (p=base,lines=0; p<base+stat.st_size; p++) /* count lines */ X if (*p == '\n') *p=0,lines++; X nlines = lines; X X /* get memory for array of pointers to each fortune */ X if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0) { X free((char*)base); X fd= -1; X return(0); /* malloc() failure */ X } X X /* now assign each pointer to a line */ X for (p=base,tmp=0; tmp<nlines; tmp++) X { X flines[tmp]=p; while (*p++); /* advance to next line */ X } X } X X if (fd > 2) /* if we have a database to look at */ X return(flines[rund((nlines<=0)?1:nlines)]); X else X return(0); X} X# endif END_OF_FILE if test 4263 -ne `wc -c <'fortune.c'`; then echo shar: \"'fortune.c'\" unpacked with wrong size! fi # end of 'fortune.c' fi if test -f 'iventory.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'iventory.c'\" else echo shar: Extracting \"'iventory.c'\" \(12705 characters\) sed "s/^X//" >'iventory.c' <<'END_OF_FILE' X#include "header.h" X#include "larndefs.h" X#include "objects.h" X#include "player.h" X X#ifdef __STDC__ X show1( int, char*[] ); X show3( int ); Xstatic show2( int ); Xstatic void t_setup( int ); Xstatic void t_endup( int ); X X#define SIGNED signed X#else X show1( ); X show3( ); Xstatic show2( ); Xstatic void t_setup( ); Xstatic void t_endup( ); X X#define SIGNED X#endif X Xstatic int qshowstr(); Xshowwear(); Xshowwield(); Xshowread(); Xshowquaff(); Xshoweat(); Xextern int dropflag; X X/* Allow only 26 items (a to z) in the player's inventory */ X#define MAXINVEN 26 X X/* The starting limit to the number of items the player can carry. X The limit should probably be based on player strength and the X weight of the items. X*/ X#define MIN_LIMIT 15 X X/* define a sentinel to place at the end of the sorted inventory. X (speeds up display reads ) X*/ X#define END_SENTINEL 255 X X/* declare the player's inventory. These should only be referenced X in this module. X iven - objects in the player's inventory X ivenarg - attribute of each item ( + values, etc ) X ivensort - sorted inventory (so we don't sort each time) X*/ Xchar iven[MAXINVEN]; XSIGNED short ivenarg[MAXINVEN]; Xunsigned char ivensort[MAXINVEN+1]; /* extra is for sentinel */ X Xstatic char srcount = 0 ; /* line counter for showstr() */ X X/* X Initialize the player's inventory X*/ Xvoid init_inventory( ) X { X int i; X X for ( i = 0; i < MAXINVEN ; i++ ) X { X iven[i] = ivenarg[i] = 0; X ivensort[i] = END_SENTINEL ; X } X ivensort[MAXINVEN] = END_SENTINEL; X X /* For zero difficulty games, start the player out with armor and weapon. X We can sort the inventory right away because a dagger is 'later' than X leather armor. X */ X if (c[HARDGAME] <= 0) X { X iven[0] = OLEATHER; X iven[1] = ODAGGER; X ivenarg[0] = ivenarg[1] = c[WEAR] = ivensort[0] = 0; X ivensort[1] = c[WIELD] = 1; X } X } X X/* X show character's inventory X*/ Xshowstr(select_allowed) Xchar select_allowed; X { X register int i,number, item_select; X X for (number=3, i=0; i<MAXINVEN; i++) X if (iven[i]) X number++; /* count items in inventory */ X t_setup(number); X item_select = qshowstr(select_allowed); X t_endup(number); X return( item_select ); X } X Xstatic int qshowstr(select_allowed) Xchar select_allowed; X { X register int i,j,k,sigsav,itemselect=0; X X srcount=0; X sigsav=nosignal; X nosignal=1; /* don't allow ^c etc */ X if (c[GOLD]) X { X lprintf(".) %d gold pieces",(long)c[GOLD]); X srcount++; X } X for (k=(MAXINVEN-1); k>=0; k--) X if (iven[k]) X { X for (i=22; i<84; i++) X for (j=0; j<=k; j++) X if (i==iven[j]) X { X itemselect = show2(j); X if (itemselect && select_allowed) X goto quitit; X } X k=0; X } X X lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100)); X itemselect = more(select_allowed); Xquitit: X nosignal=sigsav; X if (select_allowed) X return( (itemselect > 0) ? itemselect : 0 ); X else X return( 0 ); X } X X/* X subroutine to clear screen depending on # lines to display X X*/ Xstatic void t_setup(count) Xregister int count; X { X if (count<20) /* how do we clear the screen? */ X { X cl_up(79,count); X cursor(1,1); X } X else X { X resetscroll(); X clear(); X } X } X X/* X subroutine to restore normal display screen depending on t_setup() X X*/ Xstatic void t_endup(count) Xregister int count; X { X if (count<18) /* how did we clear the screen? */ X draws(0,MAXX,0,(count>MAXY) ? MAXY : count); X else X { X drawscreen(); X setscroll(); X } X } X X/* X function to show the things player is wearing only X */ Xshowwear() X { X register int i,j,sigsav,count,itemselect=0; X X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) /* count number of items we will display */ X if (i=iven[j]) X switch(i) X { X case OLEATHER: case OPLATE: case OCHAIN: X case ORING: case OSTUDLEATHER: case OSPLINT: X case OPLATEARMOR: case OSSPLATE: case OSHIELD: X count++; X }; X X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OLEATHER: case OPLATE: case OCHAIN: X case ORING: case OSTUDLEATHER: case OSPLINT: X case OPLATEARMOR: case OSSPLATE: case OSHIELD: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X function to show the things player can wield only X */ Xshowwield() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) /* count how many items */ X if (i=iven[j]) X switch(i) X { X case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: X case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: X case OSPIRITSCARAB: case OCUBEofUNDEAD: X case OPOTION: case OSCROLL: break; X default: count++; X }; X X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: X case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: X case OSPIRITSCARAB: case OCUBEofUNDEAD: X case OPOTION: case OSCROLL: X break; X default: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X * function to show the things player can read only X */ Xshowread() X { X register int i,j,sigsav,count,itemselect = 0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OBOOK: case OSCROLL: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OBOOK: case OSCROLL: X if (itemselect = show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return((itemselect > 1) ? itemselect : 0 ); X } X X/* X * function to show the things player can eat only X */ Xshoweat() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OCOOKIE: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OCOOKIE: X if (itemselect=show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1) ? itemselect : 0 ); X } X X/* X function to show the things player can quaff only X */ Xshowquaff() X { X register int i,j,sigsav,count,itemselect=0; X sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ X srcount=0; X X for (count=2,j=0; j< MAXINVEN; j++) X switch(iven[j]) X { X case OPOTION: count++; X }; X t_setup(count); X X for (i=22; i<84; i++) X for (j=0; j< MAXINVEN; j++) X if (i==iven[j]) X switch(i) X { X case OPOTION: X if (itemselect=show2(j)) X goto quitit; X }; X itemselect = more(TRUE); Xquitit: X nosignal=sigsav; X t_endup(count); X return( (itemselect > 1 ) ? itemselect : 0 ); X } X Xshow1(idx,str2) X register int idx; X register char *str2[]; X { X lprc('\n'); X cltoeoln(); X if (str2==0) X lprintf("%c) %s",idx+'a',objectname[iven[idx]]); X else if (*str2[ivenarg[idx]]==0) X lprintf("%c) %s",idx+'a',objectname[iven[idx]]); X else X lprintf("%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]); X } X Xshow3(index) Xregister int index ; X { X srcount=0; X return( show2(index) ); X } X Xstatic int show2(index) Xregister int index; X { X register int itemselect = 0; X X switch(iven[index]) X { X case OPOTION: show1(index,potionname); break; X case OSCROLL: show1(index,scrollname); break; X X case OLARNEYE: case OBOOK: case OSPIRITSCARAB: X case ODIAMOND: case ORUBY: case OCUBEofUNDEAD: X case OEMERALD: case OCHEST: case OCOOKIE: X case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break; X X default: X lprc('\n'); X cltoeoln(); X lprintf("%c) %s",index+'a',objectname[iven[index]]); X if (ivenarg[index]>0) X lprintf(" + %d",(long)ivenarg[index]); X else if (ivenarg[index]<0) X lprintf(" %d",(long)ivenarg[index]); X break; X } X if (c[WIELD]==index) lprcat(" (weapon in hand)"); X if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)"); X if (++srcount>=22) X { X srcount=0; X itemselect = more(TRUE); X clear(); X } X return( itemselect ); X } X X/* X function to put something in the players inventory X returns 0 if success, 1 if a failure X*/ Xtake(itm,arg) X int itm,arg; X { X register int i,limit; X/* cursors(); */ X if ((limit = 15+(c[LEVEL]>>1)) > MAXINVEN) X limit=MAXINVEN; X for (i=0; i<limit; i++) X if (iven[i]==0) X { X iven[i] = itm; ivenarg[i] = arg; limit=0; X switch(itm) X { X case OPROTRING: case ODAMRING: case OBELT: limit=1; break; X case ODEXRING: c[DEXTERITY] += ivenarg[i]+1; limit=1; break; X case OSTRRING: c[STREXTRA] += ivenarg[i]+1; limit=1; break; X case OCLEVERRING: c[INTELLIGENCE] += ivenarg[i]+1; limit=1; break; X case OHAMMER: c[DEXTERITY] += 10; c[STREXTRA]+=10; X c[INTELLIGENCE]-=10; limit=1; break; X X case OORBOFDRAGON: c[SLAYING]++; break; X case OSPIRITSCARAB: c[NEGATESPIRIT]++; break; X case OCUBEofUNDEAD: c[CUBEofUNDEAD]++; break; X case ONOTHEFT: c[NOTHEFT]++; break; X case OSWORDofSLASHING: c[DEXTERITY] +=5; limit=1; break; X }; X lprcat("\nYou pick up:"); show3(i); X if (limit) bottomline(); return(0); X } X lprcat("\nYou can't carry anything else"); return(1); X } X X/* X subroutine to drop an object returns 1 if something there already else 0 X */ Xdrop_object(k) X int k; X { X int itm; X if ((k<0) || (k>=MAXINVEN)) X return(0); X itm = iven[k]; cursors(); X if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); } X if (item[playerx][playery]) X { beep(); lprcat("\nThere's something here already"); return(1); } X if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */ X item[playerx][playery] = itm; X iarg[playerx][playery] = ivenarg[k]; X lprcat("\n You drop:"); show3(k); /* show what item you dropped*/ X know[playerx][playery] = 0; iven[k]=0; X if (c[WIELD]==k) c[WIELD]= -1; if (c[WEAR]==k) c[WEAR] = -1; X if (c[SHIELD]==k) c[SHIELD]= -1; X adjustcvalues(itm,ivenarg[k]); X dropflag=1; /* say dropped an item so wont ask to pick it up right away */ X return(0); X } X X/* X routine to tell if player can carry one more thing X returns 1 if pockets are full, else 0 X*/ Xpocketfull() X { X register int i,limit; X if ((limit = MIN_LIMIT + (c[LEVEL]>>1) ) > MAXINVEN ) X limit = MAXINVEN; X for (i=0; i<limit; i++) X if (iven[i]==0) X return(0); X return(1); X } END_OF_FILE if test 12705 -ne `wc -c <'iventory.c'`; then echo shar: \"'iventory.c'\" unpacked with wrong size! fi # end of 'iventory.c' fi if test -f 'larnhlp.uue' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'larnhlp.uue'\" else echo shar: Extracting \"'larnhlp.uue'\" \(11735 characters\) sed "s/^X//" >'larnhlp.uue' <<'END_OF_FILE' Xbegin 644 larn.hlp XM-R`@("!796QC;VUE('1O('1H92!G86UE(&]F($QA<FXN("!!="!T:&ES(&UO XM;65N="P@>6]U(&9A8V4@82!G<F5A="!P<F]B;&5M+@I9;W5R(&1A=6=H=&5R XM(&AA<R!C;VYT<F%C=&5D(&$@<W1R86YG92!D:7-E87-E+"!A;F0@;F]N92!O XM9B!Y;W5R(&AO;64@<F5M961I97,*<V5E;2!T;R!H879E(&%N>2!E9F9E8W0N XM("!9;W4@<V5N<V4@=&AA="!S:&4@:7,@:6X@;6]R=&%L(&1A;F=E<BP@86YD XM('EO=2!M=7-T"G1R>2!T;R!S879E(&AE<BX@(%1I;64@86=O('EO=2!H96%R XM9"!O9B!A(&QA;F0@;V8@9W)E870@9&%N9V5R(&%N9"!O<'!O<G1U;FET>2X* XM4&5R:&%P<R!H97)E(&ES('1H92!S;VQU=&EO;B!Y;W4@;F5E9"X*"B`@("!) XM="!H87,@8F5E;B!S86ED('1H870@=&AE<F4@;VYC92!W87,@82!G<F5A="!M XM86=I8VEA;B!W:&\@8V%L;&5D(&AI;7-E;&8*4&]L:6YN96%U<RX@($UA;GD@ XM>65A<G,@86=O+"!A9G1E<B!H879I;F<@;6%N>2!M:7)A8W5L;W5S('-U8V-E XM<W-E<RP@4&]L:6YN96%U<PIR971I<F5D('1O('1H92!C879E<FYS(&]F($QA XM<FXL('=H97)E(&AE(&1E=F]T960@;6]S="!O9B!H:7,@=&EM92!T;R!T:&4* XM8W)E871I;VX@;V8@;6%G:6,N("`@4G5M;W)S(&AA=F4@:70@=&AA="!O;F4@ XM9&%Y(%!O;&EN;F5A=7,@<V5T(&]U="!T;R!D:7-P96P*86X@871T86-K:6YG XM(&%R;7D@:6X@82!F;W)E<W0@<V]M92!D:7-T86YC92!T;R!T:&4@;F]R=&@N XM("!)="!I<R!B96QI979E9"!T:&%T"FAE<F4@:&4@;65T(&AI<R!D96UI<V4N XM"@H@("`@5&AE(&-A=F5R;G,@;V8@3&%R;BP@:70@:7,@=&AO=6=H="P@;75S XM="!B92!M86=N:69I8V5N="!I;B!D97-I9VXL"F%N9"!C;VYT86EN(&UU8V@@ XM;6%G:6,@86YD('1R96%S=7)E+B`@3VYE(&]P=&EO;B!Y;W4@:&%V92!I<R!T XM;R!U;F1E<G1A:V4@80IJ;W5R;F5Y(&EN=&\@=&AE<V4@8V%V97)N<RX*"@H@ XM("`@1V]O9"!,=6-K(2`@66]U)W)E(&=O:6YG('1O(&YE960@:70A"@H*"@H@ XM("`@("`@("`@("`@("`@&ULW;4AE;'`@1FEL92!F;W(@5&AE($-A=F5R;G,@ XM;V8@3&%R;BP@4')O;7!T($UO9&4;6VT*"F(@(&UO=F4@<V]U=&AW97-T("`@ XM("`@("`@($(@(')U;B!S;W5T:'=E<W0@("`@("`@("`@("!3("!S879E('1H XM92!G86UE"F@@(&UO=F4@;&5F="`@("`@("`@("`@("`@($@@(')U;B!L969T XM("`@("`@("`@("`@("`@("`N("!S=&%Y(&AE<F4*:B`@;6]V92!D;W=N("`@ XM("`@("`@("`@("`@2B`@<G5N(&1O=VX@("`@("`@("`@("`@("`@(%X@(&ED XM96YT:69Y(&$@=')A<`IK("!M;W9E('5P("`@("`@("`@("`@("`@("!+("!R XM=6X@=7`@("`@("`@("`@("`@("`@("`@5"`@=&%K92!O9F8@87)M;W(*;"`@ XM;6]V92!R:6=H="`@("`@("`@("`@("`@3"`@<G5N(')I9VAT"FX@(&UO=F4@ XM<V]U=&AE87-T("`@("`@("`@($X@(')U;B!S;W5T:&5A<W0*=2`@;6]V92!N XM;W)T:&5A<W0@("`@("`@("`@52`@<G5N(&YO<G1H96%S=`IY("!M;W9E(&YO XM<G1H=V5S="`@("`@("`@("!9("!R=6X@;F]R=&AW97-T("`@("`@("`@("`@ XM7DP@<F5D<F%W('1H92!S8W)E96X*8R`@8V%S="!A('-P96QL("`@("`@("`@ XM("`@6B`@=&5L97!O<G0@>6]U<G-E;&8*9"`@9')O<"!A;B!I=&5M("`@("`@ XM("`@("`@92`@96%T('-O;65T:&EN9PIG("!G970@<')E<V5N="!P86-K('=E XM:6=H="!0("!G:79E('1A>"!S=&%T=7,*:2`@:6YV96YT;W)Y('EO=7(@<&]C XM:V5T<R`@22`@;&ES="!A;&P@:71E;7,@9F]U;F0@("`@(#\@('1H:7,@:&5L XM<"!S8W)E96X*<2`@<75A9F8@82!P;W1I;VX@("`@("`@("`@42`@<75I="!T XM:&4@9V%M90IR("!R96%D(&$@<V-R;VQL("`@("`@("`@("!V("!P<FEN="!P XM<F]G<F%M('9E<G-I;VX*=R`@=VEE;&0@82!W96%P;VX@("`@("`@("`@5R`@ XM=V5A<B!A<FUO<B`@("`@("`@("`@("`@(%Y,(')E9')A=R!T:&4@<V-R965N XM"@H*"@H*"B`@("`@("`@("`@("`@("`;6S=M2&5L<"!&:6QE(&9O<B!4:&4@ XM0V%V97)N<R!O9B!,87)N+"!#;VUM86YD($UO9&4;6VT*"F(@(&UO=F4@<V]U XM=&AW97-T("`@("`@("`@($(@(')U;B!S;W5T:'=E<W0@("`@("`@("`@("!! XM("!D97-E8W)A=&4@86X@86QT87(*8R`@8V%S="!A('-P96QL("`@("`@("`@ XM("`@0R`@8VQO<V4@82!D;V]R("`@("`@("`@("`@(%H@('1E;&5P;W)T('EO XM=7)S96QF"F0@(&1R;W`@86X@:71E;2`@("`@("`@("`@($0@(&1R:6YK(&%T XM(&$@9F]U;G1A:6X@("`@("`\("!G;R!U<"!S=&%I<G,@;W(*92`@96%T('-O XM;65T:&EN9R`@("`@("`@("`@12`@96YT97(@82!S=&]R92P@9'5N9V5O;B`@ XM("`@('9O;&-A;FEC('-H869T"F<@(&=E="!P<F5S96YT('!A8VL@=V5I9VAT XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`^("!G;R!D;W=N('-T86ER XM<R!O<@IH("!M;W9E(&QE9G0@("`@("`@("`@("`@("!(("!R=6X@;&5F="`@ XM("`@("`@("`@("`@("`@("`@=F]L8V%N:6,@<VAA9G0*:2`@:6YV96YT;W)Y XM('EO=7(@<&]C:V5T<R`@22`@;&ES="!A;&P@:71E;7,@9F]U;F0@("`@(#\@ XM('1H:7,@:&5L<"!S8W)E96X*:B`@;6]V92!D;W=N("`@("`@("`@("`@("`@ XM2B`@<G5N(&1O=VX@("`@("`@("`@("`@("`@(%X@(&ED96YT:69Y(&$@=')A XM<`IK("!M;W9E('5P("`@("`@("`@("`@("`@("!+("!R=6X@=7`@("`@("`@ XM("`@("`@("`@("`@+"`@<&EC:R!U<"!I=&5M"FP@(&UO=F4@<FEG:'0@("`@ XM("`@("`@("`@($P@(')U;B!R:6=H="`@("`@("`@("`@("`@("`Z("!L;V]K XM(&%T(&]B:F5C="!Y;W4*;B`@;6]V92!S;W5T:&5A<W0@("`@("`@("`@3B`@ XM<G5N('-O=71H96%S="`@("`@("`@("`@("`@(&%R92!S=&%N9&EN9R!O;@H@ XM("`@("`@("`@("`@("`@("`@("`@("`@("!/("!O<&5N(&$@9&]O<B!O<B!C XM:&5S="`@("`@+B`@<W1A>2!H97)E"G`@('!R87D@870@86X@86QT87(@("`@ XM("`@(%`@(&=I=F4@=&%X('-T871U<R`@("`@("`@("!M("!M;W9E('=I=&AO XM=70@<&EC:VEN9PIQ("!Q=6%F9B!A('!O=&EO;B`@("`@("`@("!1("!Q=6ET XM('1H92!G86UE("`@("`@("`@("`@("`@=7`@86X@;V)J96-T"G(@(')E860@ XM82!S8W)O;&P@("`@("`@("`@(%(@(')E;6]V92!G96US(&9R;VT@=&AR;VYE XM("!`("!T;V=G;&4@875T;RUP:6-K=7`*<R`@<VET(&]N(&$@=&AR;VYE("`@ XM("`@("`@4R`@<V%V92!T:&4@9V%M92`@("`@("`@("`@("\@(&ED96YT:69Y XM(&]B:F5C=',@:6X*="`@=&ED>2!U<"!A="!A(&9O=6YT86EN("`@5"`@=&%K XM92!O9F8@87)M;W(@("`@("`@("`@("`@('1H92!G86UE"G4@(&UO=F4@;F]R XM=&AE87-T("`@("`@("`@(%4@(')U;B!N;W)T:&5A<W0*=B`@<')I;G0@<')O XM9W)A;2!V97)S:6]N"G<@('=I96QD(&$@=V5A<&]N("`@("`@("`@(%<@('=E XM87(@87)M;W(*>2`@;6]V92!N;W)T:'=E<W0@("`@("`@("`@62`@<G5N(&YO XM<G1H=V5S="`@("`@("`@("`@(%Y,(')E9')A=R!T:&4@<V-R965N"B`@("`@ XM("`@("`@("`@("`;6S=M4W!E8VEA;"!.;W1E<QM;;0H*5VAE;B`;6S=M9')O XM<'!I;F<@9V]L9!M;;2P@:68@>6]U('1Y<&4@)RHG(&%S('EO=7(@86UO=6YT XM+"!A;&P@>6]U<B!G;VQD(&=E=',@9')O<'!E9"X*26X@9V5N97)A;"P@='EP XM:6YG(&EN("<J)R!M96%N<R!A;&P@;V8@=VAA="!Y;W5R(&EN=&5R97-T960@ XM:6XN("!4:&ES(&ES('1R=64*=VAE;B!V:7-I=&EN9R!T:&4@8F%N:RP@;W(@ XM=VAE;B!C;VYT<FEB=71I;F<@870@86QT87)S+@H*3&%R;B!N965D<R!T:&4@ XM04Y322Y365,@*&]R('!R969E<F%B;'DL('1H92!.04Y322Y365,I(&1E=FEC XM92!D<FEV97(@:6YS=&%L;&5D"FEN('EO=7(@0T].1DE'+E-94R!F:6QE+B`@ XM5&AE('-U<'!L:65D(")T97)M8V%P(B!F:6QE(&1E<V-R:6)E<R!T:&4@97-C XM87!E"G-E<75E;F-E<R!T;R!C:&%N9V4@=FED96\@;6]D97,@*'-E92!C:"`Q XM,R!O9B!T:&4@1$]3(#(N,"!M86YU86PI+B`@4V5E('1H90HB5$5234-!4"(@ XM<V5C=&EO;B!I;B!,05).+D1/0R!F;W(@9G5R=&AE<B!D971A:6QS+@H*5VAE XM;B!I;B!T:&4@<W1O<F4L('1R861I;F<@<&]S="P@<V-H;V]L+"!O<B!H;VUE XM+"!A;B`;6S=M/&5S8V%P93X;6VT@=VEL;"!G970@>6]U(&]U="X*"E=H96X@ XM8V%S=&EN9R!A('-P96QL+"!I9B!Y;W4@;F5E9"!A(&QI<W0@;V8@<W!E;&QS XM('EO=2!C86X@8V%S="P@='EP92`G&ULW;4D;6VTG(&%S"G1H92!F:7)S="!L XM971T97(@;V8@>6]U<B!S<&5L;"X@(%1H92!A=F%I;&%B;&4@;&ES="!O9B!S XM<&5L;',@=VEL;"!B92!S:&]W;BP*869T97(@=VAI8V@@>6]U(&UA>2!E;G1E XM<B!T:&4@<W!E;&P@8V]D92X@(%1H:7,@;VYL>2!W;W)K<R!O;B!T:&4@,7-T XM(&QE='1E<@IO9B!T:&4@<W!E;&P@>6]U(&%R92!C87-T:6YG+@H*5VAE;B!A XM;B!I;G9E;G1O<GD@;&ES="!I<R!O;B!T:&4@<V-R965N(&9R;VT@82!D<F]P XM+"!Q=6%F9BP@<F5A9"P@;W(@<VEM:6QA<@IC;VUM86YD+"!Y;W4@8V%N('1Y XM<&4@=&AE(&QE='1E<B!O9B!T:&4@;V)J96-T('1H870@>6]U('=I<V@@=&\@ XM86-T(&%P;VXL"G=I=&AO=70@:&%V:6YG('1O('1Y<&4@82!S<&%C92!T;R!G XM970@8F%C:R!T;R!T:&4@<')O;7!T+@H*5&AI<R!V97)S:6]N(&]F($QA<FX@ XM:7,@8GD@2V5V:6X@4F]U=&QE>2X*("`@("`@("`@("`@("`@("`@("`@("`@ XM&ULW;4QA<FX@0V]M;6%N9"!,:6YE($]P=&EO;G,;6VT*"FQA<FX@*RL@("`@ XM("`@("`@("`@("`@(')E<W1O<F4@8VAE8VMP;VEN=&5D(&=A;64*;&%R;B`M XM<R`@("`@("`@("`@("`@("`@;&ES="!T:&4@<V-O<F5B;V%R9`IL87)N("UI XM("`@("`@("`@("`@("`@("!L:7-T('-C;W)E<R!W:71H(&EN=F5N=&]R:65S XM"FQA<FX@+6X@("`@("`@("`@("`@("`@('-U<'!R97-S('=E;&-O;64@;65S XM<V%G92!W:&5N(&)E9VEN;FEN9R!A(&=A;64*;&%R;B`M:"`@("`@("`@("`@ XM("`@("`@<')I;G0@;W5T(&%L;"!T:&4@8V]M;6%N9"!L:6YE(&]P=&EO;G,* XM;&%R;B`M/R`@("`@("`@("`@("`@("`@<')I;G0@;W5T(&%L;"!T:&4@8V]M XM;6%N9"!L:6YE(&]P=&EO;G,*;&%R;B`M/&YU;6)E<CX@("`@("`@("`@<W!E XM8VEF>2!D:69F:6-U;'1Y(&]F('1H92!G86UE"FQA<FX@+6\\;W!T<V9I;&4^ XM("`@("`@('-P96-I9GD@=&AE(&]P=&EO;B!F:6QE('1O(&)E('5S960*;&%R XM;B`M8R`@("`@("`@("`@("`@("`@8W)E871E(&YE=R!S8V]R96)O87)D<R`M XM+2!P<F]M<'1S(&9O<B!A('!A<W-W;W)D"FQA<FX@+6P@("`@("`@("`@("`@ XM("`@('!R:6YT(&]U="!T:&4@;&%R;B!L;V<@9FEL90IL87)N("UP("`@("`@ XM("`@("`@("`@("!P;&%Y(&EN('!R;VUP="!M;V1E"@H*"@H*"@H*"@H@("`@ XM("`@("`@("`;6S=M0F%C:V=R;W5N9"!);F9O<FUA=&EO;B!F;W(@3&%R;AM; XM;0H*("`@(%=E;&-O;64@=&\@=&AE(&=A;64@;V8@3&%R;BX@($%T('1H:7,@ XM;6]M96YT+"!Y;W4@9F%C92!A(&=R96%T('!R;V)L96TN"EEO=7(@9&%U9VAT XM97(@:&%S(&-O;G1R86-T960@82!S=')A;F=E(&1I<V5A<V4L(&%N9"!N;VYE XM(&]F('EO=7(@:&]M92!R96UE9&EE<PIS965M('1O(&AA=F4@86YY(&5F9F5C XM="X@(%EO=2!S96YS92!T:&%T('-H92!I<R!I;B!M;W)T86P@9&%N9V5R+"!A XM;F0@>6]U(&UU<W0*=')Y('1O('-A=F4@:&5R+B`@5&EM92!A9V\@>6]U(&AE XM87)D(&]F(&$@;&%N9"!O9B!G<F5A="!D86YG97(@86YD(&]P<&]R='5N:71Y XM+@I097)H87!S(&AE<F4@:7,@=&AE('-O;'5T:6]N('EO=2!N965D+@H*("`@ XM($ET(&AA<R!B965N('-A:60@=&AA="!T:&5R92!O;F-E('=A<R!A(&=R96%T XM(&UA9VEC:6%N('=H;R!C86QL960@:&EM<V5L9@I0;VQI;FYE875S+B`@36%N XM>2!Y96%R<R!A9V\L(&%F=&5R(&AA=FEN9R!M86YY(&UI<F%C=6QO=7,@<W5C XM8V5S<V5S+"!0;VQI;FYE875S"G)E=&ER960@=&\@=&AE(&-A=F5R;G,@;V8@ XM3&%R;BP@=VAE<F4@:&4@9&5V;W1E9"!M;W-T(&]F(&AI<R!T:6UE('1O('1H XM90IC<F5A=&EO;B!O9B!M86=I8RX@("!2=6UO<G,@:&%V92!I="!T:&%T(&]N XM92!D87D@4&]L:6YN96%U<R!S970@;W5T('1O(&1I<W!E;`IA;B!A='1A8VMI XM;F<@87)M>2!I;B!A(&9O<F5S="!S;VUE(&1I<W1A;F-E('1O('1H92!N;W)T XM:"X@($ET(&ES(&)E;&EE=F5D('1H870*:&5R92!H92!M970@:&ES(&1E;6ES XM92X*"B`@("!4:&4@8V%V97)N<R!O9B!,87)N+"!I="!I<R!T:&]U9VAT+"!M XM=7-T(&)E(&UA9VYI9FEC96YT(&EN(&1E<VEG;BP*86YD(&-O;G1A:6X@;75C XM:"!M86=I8R!A;F0@=')E87-U<F4N("!/;F4@;W!T:6]N('EO=2!H879E(&ES XM('1O('5N9&5R=&%K92!A"FIO=7)N97D@:6YT;R!T:&5S92!C879E<FYS+@H* XM("`@($=O;V0@3'5C:R$@(%EO=2=R92!G;VEN9R!T;R!N965D(&ET(0H*"@H@ XM("`@("`@("`@("`;6S=M2&]W('1O('5S92!T:&4@;&%R;BYO<'0@;W!T:6]N XM(&9I;&4;6VT*"E1H92!F:6QE(")L87)N+F]P="(L(&EF('5S960L('-H;W5L XM9"!B92!I;B!A(&1I<F5C=&]R>2!A;&]N9R!Y;W5R(%!!5$@N"D$@<V5Q=65N XM8V4@;V8@=V]R9',@=&5R;6EN871E9"!B>2!W:&ET97-P86-E(&ES('5S960@ XM=&\@<W!E8VEF>2!O<'1I;VYS+@H*("`@(%=O<F0@("`@("`@("`@("`@("`@ XM("`@("`@365A;FEN9PH@("`@8W5R<V]R.B!L;W=S8V%N(&AI9VAS8V%N("!C XM:&%N9V4@=&AE('-H87!E(&]F('1H92!C=7)S;W(*("`@($1%0U)A:6YB;W<@ XM("`@("`@("`@("`@("`@=&5L;"!,05).('EO=2!H879E('1H870@8V]M<'5T XM97(*("`@(&5N86)L92UC:&5C:W!O:6YT:6YG("`@("`@='5R;B!O;B!P97)I XM;V1I8R!C:&5C:W!O:6YT:6YG"B`@("!G<F%P:&EC<SH@=V%L;&,@9FQO;W)C XM("`@('-E;&5C="!G<F%P:&EC<R!M87IE(&-H87)A8W1E<G,*("`@(&ME>7!A XM9"`@("`@("`@("`@("`@("`@("`@96YA8FQE('1H92!N=6UE<FEC(&ME>7!A XM9"!F;W(@;6]V:6YG"B`@("!L87)N9&ER.B`@9&ER96-T;W)Y("`@("`@('1H XM92!D:7)E8W1O<GD@=&\@=7-E(&9O<B!L87)N(&9I;&5S"B`@("!M;VYS=&5R XM.B`@(FUO;G-T(&YA;64B("`@(&-H;V]S92!A(&YA;64@9F]R(&$@;6]N<W1E XM<@H@("`@;F%M93H@("`@(")Y;W5R(&YA;64B("`@("!C:&]O<V4@>6]U<B!P XM;&%Y:6YG(&YA;64*("`@(&YO+6)E97`@("`@("`@("`@("`@("`@("`@9&ES XM86)L92!B965P:6YG(&]F('1H92!T97)M:6YA;`H@("`@;F\M:6YT<F]D=6-T XM:6]N("`@("`@("`@("!D;R!N;W0@9&ES<&QA>2!I;G1R;R!M97-S86=E"B`@ XM("!S879E9FEL93H@<V%V92UF:6QE+6YA;64@(&1E9FEN92!W:&%T('1H92!S XM879E9V%M92!F:6QE;F%M92!W:6QL(&)E"B`@("!S=V%P9FEL93H@<W=A<"UF XM:6QE+6YA;64@(&1E9FEN92!T:&4@;F%M92!O9B!T:&4@<W=A<&9I;&4*"EEO XM=7(@;F%M92!A;F0@;6]N<W1E<B!N86UE<R!M=7-T(&)E(&5N8VQO<V5D(&EN XM(&1O=6)L92!Q=6]T871I;VX@;6%R:W,@86YD(&UA>0IB92!U<"!T;R`S-"!C XM:&%R86-T97)S(&QO;F<N("!,;VYG97(@;F%M97,@87)E('1R=6YC871E9"X@ XM($%N>71H:6YG(&5N8VQO<V5D(&EN"G%U;W1A=&EO;B!M87)K<R!I<R!C;VYS XM:61E<F5D(&]N92!W;W)D+"!A;F0@;75S="!B92!S97!A<F%T960@9G)O;2!O XM=&AE<B!W;W)D<PIB>2!W:&ET97-P86-E+@H@("`@("`@("`@(!M;-VU%>'!L XM86YA=&EO;B!O9B!T:&4@3&%R;B!S8V]R96)O87)D(&9A8VEL:71Y&UMM"@H@ XM("`@3&%R;B!S=7!P;W)T<R!45T\@<V-O<F5B;V%R9',L(&]N92!F;W(@=VEN XM;F5R<RP@86YD(&]N92!F;W(@9&5C96%S960*8VAA<F%C=&5R<RX@($5A8V@@ XM<&QA>65R("AB>2!U<V5R:60@;W(@<&QA>65R:60L('-E92!524130T]212!I XM;B!-86ME9FEL92D*:7,@86QL;W=E9"!O;F4@<VQO="!O;B!E86-H('-C;W)E XM8F]A<F0L(&EF('1H92!S8V]R92!I<R!I;B!T:&4@=&]P('1E;B!F;W(*=&AA XM="!S8V]R96)O87)D+B`@5&AI<R!D97-I9VX@:&5L<',@:6YS=7)E('1H870@ XM9G)E<75E;G0@<&QA>65R<R!O9B!,87)N"F1O(&YO="!H;V<@=&AE('-C;W)E XM8F]A<F0L(&%N9"!G:79E<R!M;W)E('!L87EE<G,@82!C:&%N8V4@9F]R(&=L XM;W)Y+B`@3&5V96P*;V8@9&EF9FEC=6QT>2!I<R!A;'-O(&YO=&5D(&]N('1H XM92!S8V]R96)O87)D<RP@86YD('1H:7,@=&%K97,@<')E8V5D96YC90IO=F5R XM('-C;W)E(&9O<B!D971E<FUI;FEN9R!W:&%T(&5N=')Y(&ES(&]N('1H92!S XM8V]R96)O87)D+B`@1F]R(&5X86UP;&4Z"FEF(")987(L('1H92!"=6<@4VQA XM>65R(B!H87,@82!S8V]R92!O9B`Q,C@P,#,@;VX@=&AE('-C;W)E8F]A<F0@ XM870@9&EF9B`P+`IT:&5N(&$@9V%M92!A="!D:69F(#$@86YD(&$@<V-O<F4@ XM;V8@-#$Q,B!W;W5L9"!R97!L86-E('1H92!P<F5V:6]U<PIE;G1R>2!O;B!T XM:&4@<V-O<F5B;V%R9"X@($YO=&4@=&AA="!W:&5N(&$@<&QA>65R(&1I97,L XM('1H92!I;G9E;G1O<GD@:7,*<W1O<F5D(&EN('1H92!S8V]R96)O87)D('-O XM('1H870@979E<GEO;F4@8V%N('-E92!W:&%T(&ET96US('1H92!P;&%Y97(@ XE:&%D"F%T('1H92!T:6UE(&]F(&1E871H+@H*"@H*"@H*"@HN"B!P X` Xend END_OF_FILE if test 11735 -ne `wc -c <'larnhlp.uue'`; then echo shar: \"'larnhlp.uue'\" unpacked with wrong size! fi # end of 'larnhlp.uue' fi if test -f 'msdos.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'msdos.c'\" else echo shar: Extracting \"'msdos.c'\" \(11570 characters\) sed "s/^X//" >'msdos.c' <<'END_OF_FILE' X#ifdef MSDOS X# include <stdio.h> X# include <process.h> X# include <dos.h> X# include <fcntl.h> X# include <sys/types.h> X# include <sys/stat.h> X# include "header.h" X# include "larndefs.h" X X# define DEVICE 0x80 X# define RAW 0x20 X# define IOCTL 0x44 X# define STDIN 0 X# define STDOUT 1 X# define GETBITS 0 X# define SETBITS 1 X# define PATHSEP ';' X X/* Normal characters are output when the shift key is not pushed. X * Shift characters are output when either shift key is pushed. X */ X# define KEYPADHI 83 X# define KEYPADLOW 71 X# define iskeypad(x) (KEYPADLOW <= (x) && (x) <= KEYPADHI) Xstatic struct { X char normal, shift; X } pad[KEYPADHI - KEYPADLOW + 1] = { X {'y', 'Y'}, /* 7 */ X {'k', 'K'}, /* 8 */ X {'u', 'U'}, /* 9 */ X {' ', ' '}, /* - */ X {'h', 'H'}, /* 4 */ X {' ', ' '}, /* 5 */ X {'l', 'L'}, /* 6 */ X {' ', ' '}, /* + */ X {'b', 'B'}, /* 1 */ X {'j', 'J'}, /* 2 */ X {'n', 'N'}, /* 3 */ X {'i', 'i'}, /* Ins */ X {'.', '.'} /* Del */ X}; X X/* BIOSgetch gets keys directly with a BIOS call. X */ X#ifdef OS2LARN X# define SHIFT (RIGHTSHIFT | LEFTSHIFT) X#else X# define SHIFT (0x1 | 0x2) X#endif X# define KEYBRD_BIOS 0x16 X Xstatic char XBIOSgetch() { X unsigned char scan, shift, ch; X union REGS regs; X X#ifdef OS2LARN X KBDKEYINFO kbd; X X KbdCharIn(&kbd,IO_WAIT,(HKBD) 0); X ch = kbd.chChar; X scan = kbd.chScan; X shift = kbd.fsState; X#else X /* Get scan code. X */ X regs.h.ah = 0; X int86(KEYBRD_BIOS, ®s, ®s); X ch = regs.h.al; X scan = regs.h.ah; X X /* Get shift status. X */ X regs.h.ah = 2; X int86(KEYBRD_BIOS, ®s, ®s); X shift = regs.h.al; X#endif X X /* If scan code is for the keypad, translate it. X */ X if (iskeypad(scan)) { X if (shift & SHIFT) X ch = pad[scan - KEYPADLOW].shift; X else X ch = pad[scan - KEYPADLOW].normal; X } X return ch; X} X Xkgetch() X{ X /* BIOSgetch can use the numeric key pad on IBM compatibles. */ X if (keypad) X return BIOSgetch(); X else X return getch(); X} X Xdoshell() X{ X char *comspec = getenv("COMSPEC"); X X clear(); X lflush(); X if (comspec == NULL X || (spawnl(P_WAIT, comspec, comspec, NULL) < 0)) { X write(2, "A> ", 3); X while (getche() != '\r') X ; X } X} X Xstatic unsigned old_stdin, old_stdout, ioctl(); X Xstatic unsigned Xioctl(handle, mode, setvalue) Xunsigned setvalue; X{ X#ifndef OS2LARN X union REGS regs; X X regs.h.ah = IOCTL; X regs.h.al = mode; X regs.x.bx = handle; X regs.h.dl = setvalue; X regs.h.dh = 0; /* Zero out dh */ X intdos(®s, ®s); X return (regs.x.dx); X#endif X} X Xint rawio; Xvoid Xsetraw() X{ X if (!rawio) X return; X old_stdin = ioctl(STDIN, GETBITS, 0); X old_stdout = ioctl(STDOUT, GETBITS, 0); X if (old_stdin & DEVICE) X (void) ioctl(STDIN, SETBITS, old_stdin | RAW); X if (old_stdout & DEVICE) X (void) ioctl(STDOUT, SETBITS, old_stdout | RAW); X} X Xvoid Xunsetraw() X{ X if (!rawio) X return; X if (old_stdin) X (void) ioctl(STDIN, SETBITS, old_stdin); X if (old_stdout) X (void) ioctl(STDOUT, SETBITS, old_stdout); X} X X X/* Add a backslash to any name not ending in /, \ or : There must X * be room for the \ X */ Xvoid Xappend_slash(name) Xchar *name; X{ X char *ptr; X X if (!*name) X return; X ptr = name + (strlen(name) - 1); X if (*ptr != '\\' && *ptr != '/' && *ptr != ':') { X *++ptr = '\\'; X *++ptr = '\0'; X } X} X X/* Lopen a file somewhere along the PATH X */ Xplopen(name) Xchar *name; X{ X char buf[PATHLEN], *bp, *pp, lastch, *strchr(); X int fd; X X /* Try the default directory first. Then look along PATH unless X * the name has path components. X */ X if ((fd = lopen(name)) >= 0) X return fd; X else if (strpbrk(name, "\\/:") == NULL) { X pp = getenv("PATH"); X while (pp && *pp) { X bp = buf; X while (*pp && *pp != PATHSEP) X lastch = *bp++ = *pp++; X if (strchr("\\/:", lastch) == NULL) X *bp++ = '\\'; X strcpy(bp, name); X if ((fd = lopen(buf)) >= 0) X return fd; X if (*pp) X pp++; X } X } X return -1; X} X X X/* Follow the PATH, trying to fopen the file. Takes one additional X * argument which can be NULL. Otherwise this argument gets filled X * in the full path to the file. Returns as does fopen(). X */ XFILE * Xfopenp(name, mode, pathname) Xchar *name, *mode, *pathname; X{ X char buffer[BUFSIZ], *buf, *bufp, *pathp, *getenv(), lastch; X FILE *fp; X X /* If pathname is given, use it instead of buf so the calling X * process knows the path we found name under X */ X if (pathname) X buf = pathname; X else X buf = buffer; X X /* Try the default directory first. If the file can't be opened, X * start looking along the path. X */ X strcpy(buf, name); X if (fp = fopen(buf, mode)) X return fp; X else if (strpbrk(name, "\\/:") == NULL) { X pathp = getenv("PATH"); X while (pathp && *pathp) { X bufp = buf; X while (*pathp && *pathp != PATHSEP) X lastch = *bufp++ = *pathp++; X if (lastch != '\\' && lastch != '/') X *bufp++ = '\\'; X strcpy(bufp, name); X if (fp = fopen(buf, mode)) X return fp; X if (*pathp) X pathp++; X } X } X return NULL; X} X X/* Diagnositic information about the disposition of levels between ram X * and disk. X */ Xlevelinfo() X{ X DISKBLOCK *dp; X RAMBLOCK *rp; X X cursors(); X lflush(); X fprintf(stderr, "\nRAM:\n"); X for (rp = ramblks; rp; rp = rp->next) X fprintf(stderr, "%4d gt:%6ld\n", rp->level, rp->gtime); X fprintf(stderr, "\nDISK:\n"); X for (dp = diskblks; dp; dp = dp->next) X fprintf(stderr, "%4d gt:%6ld fpos:%ld\n", X dp->level, dp->gtime, dp->fpos); X nomove=1; X return (yrepcount = 0); X} X Xint swapfd = 0; /* file descriptor for the swap file */ Xint ramlevels = MAXLEVEL + MAXVLEVEL; /* the maximum */ X X X/* Allocate as many levels as possible, then check that the swap file X * will have enough storage for the overflow. You must be able to allocate X * at least one level or there will be nowhere to swap to/from. If a swap X * file is opened it remains open for the whole game. X */ Xallocate_memory() X{ X register int i; X DISKBLOCK *dp, *dp2; X RAMBLOCK *rp; X X /* First allocate the maximum number of disk blocks, some of which X * may not be used, but must do the allocation now since we don't X * yet know how many levels will be allocatable. X */ X for (i = 0; i < MAXLEVEL + MAXVLEVEL; i++) { X if ((dp = (DISKBLOCK *) malloc(sizeof(DISKBLOCK))) == NULL) X died(-285); X dp->next = diskblks; X diskblks = dp; X } X dp = diskblks; /* Move this along in the next loop */ X X /* Now allocate ram storage, up to ramlevels in count. X */ X for (i = 0; i < MAXLEVEL + MAXVLEVEL; i++) { X if (i < ramlevels) X rp = (RAMBLOCK *) malloc(sizeof(RAMBLOCK)); X else X rp = NULL; X if (rp == NULL) { X if (i == 0) X died(-285); /* have to have at least one */ X X /* Open the swap file if not yet done so X */ X if (swapfd == 0) { X swapfd = open(swapfile, X O_RDWR | O_CREAT | O_TRUNC | O_BINARY, X S_IWRITE | S_IREAD); X if (swapfd < 0) X error("Can't open swapfile `%s'\n", X swapfile); X X /* First block is FREE and will be used to X * swap out the first level. When another X * level gets swapped in, its block will be X * FREE. X */ X if (dp == NULL) X error("NULL1 disk pointer?\n"); X dp->level = FREEBLOCK; X dp->fpos = 0; X dp->gtime = 0; X lseek(swapfd, (long) sizeof rp->cell, 0); X } X X /* And try to seek the size of this level X */ X dp = dp->next; X if (dp == NULL) X error("NULL2 disk pointer?\n"); X dp->level = FREEBLOCK; X dp->gtime = 0; X dp->fpos = tell(swapfd); X if (lseek(swapfd, (long) sizeof rp->cell, 1) < 0L) X error("Not enough disk space for swapfile `%s'\n", X swapfile); X } else { X rp->next = ramblks; X ramblks = rp; X rp->level = FREEBLOCK; X rp->gtime = 0; X } X } X X /* dp now points to the last diskblock used. Truncate the diskblock X * list here and free up the other blocks (for what it's worth ...) X */ X dp2 = dp->next; X dp->next = NULL; X dp = dp2; X while (dp) { X dp2 = dp->next; X free((char *) dp); X dp = dp2; X } X} X X X/* VARARGS1 */ Xwarn(format, a1, a2, a3) Xchar *format; Xlong a1, a2, a3; X{ X fprintf(stderr, format, a1, a2, a3); X} X X/* VARARGS1 */ Xerror(format, a1, a2, a3, a4) Xchar *format; Xlong a1, a2, a3, a4; X{ X unsetraw(); X resetcursor(); X fputc('\n', stderr); X fprintf(stderr, format, a1, a2, a3, a4); X sleep(5); X exit(1); X} X Xstatic unsigned char ocursorstart, ocursorend; Xunsigned char cursorstart, cursorend; Xint cursorset; X X/* Save the old value of the cursor then put in the new value. X */ X# define READCURSORPOS 0x03 X# define SETCURSORTYPE 0x01 X# define BIOSVIDEO 0x10 Xsetcursor() X{ X#ifdef OS2LARN X USHORT rc; X VIOCURSORINFO curinfo; X X if (cursorset == 0) X return; X X /* Save the cursor type in 'ocursorstart' and 'ocursorend'. X */ X rc = VioGetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X if (rc != 0) X { X /* errors don't happen. */ X } X ocursorstart = curinfo.yStart; X ocursorend = curinfo.cEnd; X X /* set the cursor type according to global variables X 'cursorstart' and 'cursorend'. X */ X curinfo.cEnd = cursorend; X curinfo.yStart = cursorstart; X curinfo.cx = 0; /* default width, 1 char */ X curinfo.attr = 0; /* 'Normal' attribute */ X X rc = VioSetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X if (rc != 0) X { X /* errors don't happen. */ X } X X#else X union REGS regs; X X if (cursorset == 0) X return; X X regs.h.ah = READCURSORPOS; X regs.h.bh = 0; X int86(BIOSVIDEO, ®s, ®s); X ocursorstart = regs.h.ch; X ocursorend = regs.h.cl; X X regs.h.ah = SETCURSORTYPE; X regs.h.bh = 0; X regs.h.ch = cursorstart; X#if 0 X regs.h.ch = 0x20 ; X#endif X regs.h.cl = cursorend; X int86(BIOSVIDEO, ®s, ®s); X#endif X} X X/* Restore the old cursor upon exit X */ Xresetcursor() X{ X#ifdef OS2LARN X VIOCURSORINFO curinfo; X X if (cursorset == 0) X return; X X curinfo.cEnd = ocursorend; X curinfo.yStart = ocursorstart; X curinfo.cx = 0; /* default width, 1 char */ X curinfo.attr = 0; /* 'Normal' attribute */ X X VioSetCurType((PVIOCURSORINFO) &curinfo, (HVIO) NULL); X#else X union REGS regs; X X if (cursorset == 0) X return; X regs.h.ah = SETCURSORTYPE; X regs.h.bh = 0; X regs.h.ch = ocursorstart; X regs.h.cl = ocursorend; X int86(BIOSVIDEO, ®s, ®s); X#endif X} X# endif /* MSDOS */ END_OF_FILE if test 11570 -ne `wc -c <'msdos.c'`; then echo shar: \"'msdos.c'\" unpacked with wrong size! fi # end of 'msdos.c' fi if test -f 'tgetent.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tgetent.c'\" else echo shar: Extracting \"'tgetent.c'\" \(10470 characters\) sed "s/^X//" >'tgetent.c' <<'END_OF_FILE' X/************************************************************************ X * * X * Copyright (c) 1982, Fred Fish * X * All Rights Reserved * X * * X * This software and/or documentation is released for public * X * distribution for personal, non-commercial use only. * X * Limited rights to use, modify, and redistribute are hereby * X * granted for non-commercial purposes, provided that all * X * copyright notices remain intact and all changes are clearly * X * documented. The author makes no warranty of any kind with * X * respect to this product and explicitly disclaims any implied * X * warranties of merchantability or fitness for any particular * X * purpose. * X * * X ************************************************************************ X */ X X/* X * LIBRARY FUNCTION X * X * tgetent load buffer with entry for specified terminal X * X * KEY WORDS X * X * termcap functions X * utility routines X * X * SYNOPSIS X * X * int tgetent(bp,name) X * char *bp; X * char *name; X * X * DESCRIPTION X * X * Extracts the entry for terminal <name> from the termcap file X * and places it in the character buffer <bp>. It is currently X * assumed that bp is at least 1024 characters. If the entry in X * the termcap file is larger than 1023 characters the excess X * characters will be discarded and appropriate status will X * be returned. X * X * Also note that since bp is used by other termcap X * routines, the storage associated with the termcap entry X * cannot be freed until all termcap calls are completed. X * X * Tgetent can be directed to look in a file other than X * the default (/etc/termcap) by defining an environment X * variable called TERMCAP to be the pathname of the desired X * termcap file. This is useful for debugging new entries. X#ifndef VMS X * NOTE: the pathname MUST begin with a '/' character. X * X * Also, if the string assigned to TERMCAP does not begin with X * a '/' and if the environment variable TERM matches <name> then X * the string assigned to TERMCAP is copied to buffer <bp> X * instead of reading a termcap file. X#endif X * X * If the termcap entry contains a "tc" string then the termcap X * entry named in the string is appended to the buffer (minus the X * names). X * X * RETURNS X * X * -1 if the termcap file cannot be opened X * 0 if no entry in termcap file matches <name> X * 1 if extraction is successful with no errors X * 2 if extraction is successful but entry truncated X * X * SEE ALSO X * X * tgetnum extract numeric type capability X * tgetflag test boolean type capability X * tgetstr get string value of capability X * X * AUTHOR X * X * Fred Fish X * X */ X X#include <stdio.h> X X#define TRUE 1 X#define FALSE 0 X#define BUFSIZE 1024 /* Assumed size of external buffer */ X X#define NO_FILE -1 /* Returned if can't open file */ X#define NO_ENTRY 0 /* Returned if can't find entry */ X#define SUCCESS 1 /* Returned if entry found ok */ X#define TRUNCATED 2 /* Returned if entry found but trunc */ X X#ifdef MSDOS XFILE *fopenp(); X#endif X X#define DEFAULT_ROOT "termcap" /* name without path component */ X#ifdef VMS X#define DEFAULT_FILE "sys$library:termcap" X#else X#define DEFAULT_FILE "/etc/termcap" /* default termcap filename */ X#endif VMS X Xchar *_tcpbuf; /* Place to remember buffer pointer */ X X/* X * PSEUDO CODE X * X * Begin tgetent X * Erase any previous buffer contents. X * Remember the buffer pointer. X * If termcap file is not found then X * If buffer was filled anyway then X * Return SUCCESS. X * Else X * Return NO_FILE. X * End if X * Else X * While records left to process X * If this is entry is what we want then X * Close the termcap file. X * If entry was truncated then X * Return TRUNCATED status X * Else X * Return SUCCESS status. X * End if X * End if X * End while X * Return NO_ENTRY status. X * End if X * End tgetent X * X */ X Xint tgetent(bp,name) Xchar *bp; /* Pointer to buffer (1024 char min) */ Xchar *name; /* Pointer to terminal entry to find */ X{ X FILE *fp, *find_file(); X char *nbp, tc[80]; X X *bp = (char)NULL; X _tcpbuf = bp; X if ((fp = find_file(bp)) == NULL) { X if (*bp != NULL) { X return(SUCCESS); X } else { X return(NO_FILE); X } X } else { X while (fgetlr(bp,BUFSIZE,fp)) { X if (gotcha(bp,name)) { X fclose(fp); X nbp = &bp[strlen(bp)-1]; X if (*nbp != '\n') { X return(TRUNCATED); X } else { X /* check for a recursive call (i.e. :tc=vt100:) X * added 18-dec-86 RDE (single recursion...) X */ X char *area; X area = &tc[0]; X if (tgetstr("tc", &area) == NULL) X return(SUCCESS); X else { X fp = find_file(0); /* know it works and is file */ X while (fgetlr(nbp, BUFSIZE-(nbp-bp), fp)) { X if (gotcha(nbp,tc)) { X char *cp1, *cp2; /* scrunch out names */ X fclose(fp); X cp1 = nbp; X while (*cp1++ != ':') /* search for first */ X ; X cp2 = nbp; X while (*cp2++ = *cp1++) /* move the chars. */ X ; X if (bp[strlen(bp)-1] != '\n') { X return(TRUNCATED); X } else { X return(SUCCESS); X } X } X } X return (NO_ENTRY); X } X } X } X } X return(NO_ENTRY); X } X} X X/* X * INTERNAL FUNCTION X * X * find_file find the termcap file and open it if possible X * X * KEY WORDS X * X * internal functions X * find_file X * X * SYNOPSIS X * X * static FILE *find_file(bp) X * char *bp; X * X * DESCRIPTION X * X * Attempts to locate and open the termcap file. Also handles X * using the environment TERMCAP string as the actual buffer X * (that's why bp has to be an input parameter). X * X#ifdef VMS X * If TERMCAP is defined as a valid filespec then it will be X * opened. If this fails then the default termcap file will X * be used. X#else X * If TERMCAP is defined an begins with a '/' character then X * it is taken to be the pathname of the termcap file and X * an attempt is made to open it. If this fails then X * the default termcap file is used instead. X * X * If TERMCAP is defined but does not begin with a '/' then X * it is assumed to be the actual buffer contents provided X * that <name> matches the environment variable TERM. X#endif X * X * BUGS X * X * There is currently no way to be sure which termcap X * file was opened since the default will always be X * tried. X * X */ X X/* X * PSEUDO CODE X * X * Begin find_file X * If there is a TERMCAP environment string then X * If the string is not null then X * If the string is a pathname then X * If that file is opened successfully then X * Return its pointer. X * End if X * Else X * If there is a TERM environment string then X * If TERM matches <name> then X * Copy TERMCAP string to buffer. X * Return NULL for no file. X * End if X * End if X * End if X * End if X * End if X * Open default termcap file and return results. X * End find_file X * X */ X Xstatic FILE *find_file(bp) Xchar *bp; X{ X FILE *fp, *fopen(); X char *cp, *ncp, *getenv(); X X if ((cp = getenv("TERMCAP")) != NULL) { X if (*cp != NULL) { X#ifdef VMS X if ((fp = fopen(cp, "r")) != NULL) X return(fp); X#else X if (*cp == '/' || *cp == '\\') { X if ((fp = fopen(cp,"r")) != NULL) { X return(fp); X } X } else { X if ((ncp = getenv("TERM")) != NULL) { X if (strcmp(cp,ncp) == 0) { X strcpy(bp,cp); X return((FILE *)NULL); X } X } X } X#endif X } X } X /* X * Try current directory, then /etc/termcap X */ X if (fp = fopen(DEFAULT_ROOT, "r")) X return fp; X else X#ifdef MSDOS X if (fp = fopen(DEFAULT_FILE, "r") ) X return fp; X else /* try along the PATH */ X return( fopenp(DEFAULT_ROOT, "r", NULL)); X#else X return (fopen(DEFAULT_FILE, "r")); X#endif X} X X X/* X * INTERNAL FUNCTION X * X * gotcha test to see if entry is for specified terminal X * X * SYNOPSIS X * X * gotcha(bp,name) X * char *bp; X * char *name; X * X * DESCRIPTION X * X * Tests to see if the entry in buffer bp matches the terminal X * specified by name. Returns TRUE if match is detected, FALSE X * otherwise. X * X */ X X/* X * PSEUDO CODE X * X * Begin gotcha X * If buffer character is comment character then X * Return FALSE since remainder is comment X * Else X * Initialize name scan pointer. X * Compare name and buffer until end or mismatch. X * If valid terminators for both name and buffer strings X * Return TRUE since a match was found. X * Else X * Find next non-name character in buffer. X * If not an alternate name separater character X * Return FALSE since no more names to check. X * Else X * Test next name and return results. X * End if X * End if X * End if X * End gotcha X * X */ X Xgotcha(bp,name) Xchar *bp; Xchar *name; X{ X char *np; X X if (*bp == '#') { X return(FALSE); X } else { X np = name; X while (*np == *bp && *np != NULL) {np++; bp++;} X if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) { X return(TRUE); X } else { X while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;} X if (*bp != '|') { X return(FALSE); X } else { X return(gotcha(++bp,name)); X } X } X } X} X X#ifdef MSDOS X/* X * index(buffer, char) X * Find character in buffer. Return the pointer X * to it. Shouldn't be necessary to write this X * myself but VMS didn't. Oh Well... X * Used by lots of files in the termcap library. X * Rich Ellison, 16-DEC-1986 X */ Xchar X*index(buf, ch) Xchar *buf; Xchar ch; X{ X register int c; X while ((c= *buf++) != '\0') X if (c == ch) X return (buf-1); X return (NULL); X} X#endif END_OF_FILE if test 10470 -ne `wc -c <'tgetent.c'`; then echo shar: \"'tgetent.c'\" unpacked with wrong size! fi # end of 'tgetent.c' fi echo shar: End of archive 10 \(of 12\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 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