[comp.sources.games] v12i063: larn2 - dungeon type adventure game

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, &regs, &regs);
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, &regs, &regs);
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(&regs, &regs);
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, &regs, &regs);
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, &regs, &regs);
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, &regs, &regs);
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