home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archimedes
/
arplib.c
< prev
next >
Wrap
C/C++ Source or Header
|
2020-01-01
|
23KB
|
1,069 lines
/* -> c.plib
*
* (c) Cosmos Nicolaou 25/6/87
*/
#include <stdio.h>
#include <stdlib.h>
#include "arthur.h"
#include <string.h>
#include <ctype.h>
#include "ckafio.h"
#include "plib.h"
#include "tty.h"
#include "ckamis.h"
#include "dir.h"
/*
* Temporary kludge to allow use of fatal.
* It is not good practice to use an application function
* in a library!
*/
#include "ckcdeb.h"
#include "ckuusr.h"
/*
* Source Code file for Panos compatibility library
*/
#define UNUSED 0
#define FTYPE 1
#define VDU 2
#define RAWVDU 3
#define KB 4
#define RAWKB 5
#define BBC 6
#define TTY 7
#define RS423 8
#define PRINTER 9
#define NULL_DEV 10
#define VDU_STR "VDU:"
#define RAWVDU_STR "RAWVDU:"
#define KB_STR "KB:"
#define RAWKB_STR "RAWKB:"
#define BBC_STR "BBC:"
#define TTY_STR "TTY:"
#define RS423_STR "RS423:"
#define PRINTER_STR "PRINTER:"
#define INPUT_STR "INPUT:"
#define OUTPUT_STR "OUTPUT"
#define CTL_STR "CONTROL:"
#define ERR_STR "ERROR:"
#define keybf 0
#define rs423inbf 1
#define rs423outbf 2
#define IP 0
#define OP 1
static int getnextstr( void );
typedef struct {
int type;
int inout;
FILE *fp;
} stream_desc;
#define MAXSTREAMS 20
static stream_desc streams[MAXSTREAMS];
static stream_desc *cur_desc;
int rs423_num_users = 0;
int kb_num_users = 0;
static reg_set rs;
static error *ret_val;
int
GetFileInformation( info, tstamp, name, len )
struct FileData *info;
struct BTim *tstamp;
char * name;
int len;
{
static osfile_block o_b;
static reg_set rs;
error *ret;
/* Open file for reading */
rs.r[0] = 64;
rs.r[1] = (int)name;
if( (ret=osfind( &rs )) != NULL )
{
fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
return -1;
}
if( rs.r[0] == 0 )
/* File does not exist */
return -1;
/* close the file just opened */
rs.r[1] = rs.r[0];
rs.r[0] = 0;
if( (ret=osfind( &rs )) != NULL )
{
fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
return -1;
}
o_b.action = 5;
o_b.name = name;
if( (ret=osfile( &o_b )) != NULL )
{
fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
return -1;
}
info->loadaddr = o_b.loadaddr;
info->execaddr = o_b.execaddr;
info->length = o_b.start;
info->attrib = o_b.end;
/* Return file type */
return o_b.action;
}
int
EndOfFile( stream )
int stream;
{
cur_desc = &streams[stream];
if( cur_desc->type == UNUSED )
{
fprintf(stderr,"ENDOFFILE, op on unused stream (%d)\n",stream);
fatal("ENDOFFILE, op on unused stream");
}
if( cur_desc->type != FTYPE )
/* Not a file */
fatal("End of file unimplemented function");
if( feof( cur_desc->fp ) != 0 )
/* At end of file */
return 1;
else
return 0;
}
int
SWriteByte(
#ifdef ANSI
int stream, char ch)
#else
stream, ch )
int stream;
char ch;
#endif
{
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"SWRITEBYTE, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( fputc( ch, cur_desc->fp ) == EOF )
return -9;
break;
case VDU:
/* printable ascii, clear-screen, newline, and carry return */
if( ch == '\n' )
{
vdu(10);vdu(13);break;
}
if( !iscntrl(ch) || isspace(ch) )
vdu( ch );
break;
case RAWVDU:
vdu( ch );
break;
case BBC:
/* RAWVDU for output */
cur_desc->type = RAWVDU;
if( SWriteByte( stream, ch ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case TTY:
/* DU for output */
cur_desc->type = VDU;
if( SWriteByte( stream, ch ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case RS423:
rs.r[0] = 153;
rs.r[1] = rs423outbf;
rs.r[2] = ch;
ret_val = osbyte( &rs );
inter();
break;
case PRINTER:
case NULL_DEV:
fatal("SWB unimplemented function");
break;
default:
fprintf(stderr,"SWRITEBYTE WOW should never get here!!\n");
return -1;
break;
}
return 0;
}
int
XSWriteByte(
#ifdef ANSI
int stream, char ch)
#else
stream, ch )
int stream;
char ch;
#endif
{
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XSWRITEBYTE, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( fputc( ch, cur_desc->fp ) == EOF )
return -9;
break;
case VDU:
/* printable ascii, clear-screen, newline, and carry return */
if( ch == '\n' )
{
vdu(10);vdu(13);break;
}
if( !iscntrl(ch) || isspace(ch) )
vdu( ch );
break;
case RAWVDU:
vdu( ch );
break;
case KB:
case RAWKB:
fatal("XSWB unimplemented function");
break;
case BBC:
/* RAWVDU for output */
cur_desc->type = RAWVDU;
if( XSWriteByte( stream, ch ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case TTY:
/* VDU for output */
cur_desc->type = VDU;
if( XSWriteByte( stream, ch ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case RS423:
rs.r[0] = 153;
rs.r[1] = rs423outbf;
rs.r[2] = ch;
ret_val = osbyte( &rs );
inter();
break;
case PRINTER:
case NULL_DEV:
fatal("XSW unimplemented function");
break;
default:
fprintf(stderr,"XSWRITEBYTE WOW should never get here!!\n");
abort();
return -1;
break;
}
return 0;
}
int
XSBlockWrite( stream, bufsiz, buf )
int stream, bufsiz;
char * buf;
{
int i;
int ch;
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XSBLOCKWRITE, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( fwrite( buf, sizeof(char), bufsiz, cur_desc->fp ) != bufsiz )
return -1;
break;
case VDU:
for( i=0; i < bufsiz; i++ )
{
ch = *(buf+i);
if( ch == '\n' )
{
vdu(10);vdu(13);break;
}
/* printable ascii, clear-screen, newline, and carry return */
if( !iscntrl(ch) || isspace(ch) )
vdu( ch );
}
break;
case RAWVDU:
for( i=0; i < bufsiz; i++ )
vdu( *(buf+i) );
break;
case BBC:
/* RAWVDU for output */
cur_desc->type = RAWVDU;
if( XSBlockWrite( stream, bufsiz, buf ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case TTY:
/* VDU for output */
cur_desc->type = VDU;
if( XSBlockWrite( stream, bufsiz, buf ) < 0 )
{
cur_desc->type = BBC;
return -1;
}
cur_desc->type = BBC;
break;
case RS423:
for( i=0; i < bufsiz; i++ )
{
rs.r[0] = 153;
rs.r[1] = rs423outbf;
rs.r[2] = *(buf+i);
ret_val = osbyte( &rs );
}
inter();
break;
case PRINTER:
case NULL_DEV:
fatal("XSBLKW unimplemented function");
break;
default:
fprintf(stderr,"XSBLOCK WRITE WOW should never get here!!\n");
return -1;
break;
}
return 0;
}
int
SReadByte( stream )
int stream;
{
int ch;
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"SREADBYTE, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( (ch=fgetc( cur_desc->fp )) == EOF )
return -9;
else
return ch;
break;
case KB:
fatal("SRB unimplemented function");
break;
case RAWKB:
while( testbf( keybf, &ch ) == 0 )
;
return ch;
break;
case BBC:
/* RAWKB for input */
cur_desc->type = RAWKB;
ch = SReadByte( stream );
cur_desc->type = BBC;
return ch;
break;
case TTY:
/* KB for input */
cur_desc->type = KB;
ch = SReadByte( stream );
cur_desc->type = BBC;
return ch;
break;
case RS423:
if( (ch = rsremove(rs423inbf)) == 0 )
return 0;
return ch & 0xff;
break;
case PRINTER:
case NULL_DEV:
fatal("SRB unimplemented function");
break;
default:
fprintf(stderr,"SREADBYTE WOW should never get here!!\n");
return -1;
break;
}
return 0;
}
int
XSReadByte( stream )
int stream;
{
int ch;
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XSREADBYTE, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( (ch=fgetc( cur_desc->fp )) == EOF )
return -9;
else
return ch;
break;
case KB:
fatal("XSRB unimplemented function");
break;
case RAWKB:
while( testbf( keybf, &ch ) == 0 )
;
return ch;
case BBC:
/* RAWKB for input */
cur_desc->type = RAWKB;
ch = XSReadByte( stream );
cur_desc->type = BBC;
return ch;
break;
case TTY:
/* KB for input */
cur_desc->type = KB;
ch = XSReadByte( stream );
cur_desc->type = BBC;
return ch;
break;
case RS423:
if( (ch = rsremove(rs423inbf)) == 0 )
return 0;
return ch & 0xff;
break;
case PRINTER:
case NULL_DEV:
fatal("XSRB unimplemented function");
break;
default:
fprintf(stderr,"XSREADBYTE WOW should never get here!!\n");
fprintf(stderr,"Type is %lx\n",cur_desc->type);
fprintf(stderr,"Type is %lx\n",-0xe);
return -1;
break;
}
return 0;
}
int
XBytesOutstanding( stream )
int stream;
{
int cur_pos, end_pos;
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XBYTESOUTSTANDING, op on unused stream (%d)\n",
stream);
break;
case FTYPE:
cur_pos = ftell( cur_desc->fp );
fseek( cur_desc->fp, 0, SEEK_END );
end_pos = ftell( cur_desc->fp );
fseek( cur_desc->fp, cur_pos, SEEK_SET );
return end_pos - cur_pos;
break;
case KB:
case RAWKB:
return kbcount( 0, keybf );
break;
case BBC:
case TTY:
fatal("BO unimplemented function");
break;
case RS423:
if( cur_desc->inout == IP )
return rscount( 0, rs423inbf );
else
/* Output is unbufferred */
return 0;
break;
case PRINTER:
case NULL_DEV:
fatal("BO unimplemented function");
break;
default:
fprintf(stderr,"BYTES OUTSTANDING WOW should never get here!!\n");
return -1;
break;
}
return -1;
}
void
dummy()
{
return;
}
int
XFindInput( name, namlen )
char *name;
int namlen;
{
FILE *fp;
int i;
/*static int last;*/
if( (i = getnextstr()) == -1 )
return -1;
streams[i].inout = IP;
if ( strcmp( name, VDU_STR ) == 0 )
fatal("XFI VDU unimplemented function");
else if ( strcmp( name, RAWVDU_STR ) == 0 )
fatal("XFI RVDU unimplemented function");
else if( strcmp( name, KB_STR ) == 0 )
{
streams[i].type = KB;
streams[i].fp = stdin;
if( kb_num_users == 0 )
kbintercept();
kb_num_users++;
}
else if( strcmp( name, RAWKB_STR ) == 0 )
{
streams[i].type = RAWKB;
streams[i].fp = stdin;
if( kb_num_users == 0 )
kbintercept();
kb_num_users++;
}
else if( strcmp( name, BBC_STR ) == 0 )
{
streams[i].type = BBC;
streams[i].fp = stdin;
}
else if( strcmp( name, TTY_STR ) == 0 )
{
streams[i].type = TTY;
streams[i].fp = stdin;
}
else if( strcmp( name, RS423_STR ) == 0 )
{
streams[i].type = RS423;
if( rs423_num_users == 0 )
{
/* Disable rs423 as output stream */
rs.r[0] = 3;
rs.r[1] = 0;
ret_val = osbyte( &rs );
/* Enable kb and rs423 as input */
rs.r[0] = 2;
rs.r[1] = 2;
ret_val = osbyte( &rs );
/* disable cursor editing and fn key nums to cursor and copy keys */ rs.r[0] = 4;
rs.r[1] = 2;
ret_val = osbyte( &rs );
/* Disable escape */
rs.r[0] = 229;
rs.r[1] = 1;
ret_val = osbyte( &rs );
rsintercept();
}
rs423_num_users++;
}
else if( strcmp( name, PRINTER_STR ) == 0 )
fatal("XFI PR unimplemented function");
else if( strcmp( name, INPUT_STR ) == 0 )
{
fatal("XFI IP unimplemented function");
/* Return currently selected input stream, a bug in
PANOS, reintroduced here for a laugh!! */
/*fprintf(stderr,"findinput for INPUT: returning %d\n",last);
return last;*/
}
else if( strcmp( name, OUTPUT_STR ) == 0 )
fatal("XFI OP unimplemented function");
else if( strcmp( name, CTL_STR ) == 0 )
fatal("XFI CTL unimplemented function");
else if( strcmp( name, ERR_STR ) == 0 )
fatal("XFI ERR unimplemented function");
else
{
/* An ordinary file */
if( (fp=fopen( name, "r")) == NULL )
return -1;
streams[i].type = FTYPE;
streams[i].fp = fp;
}
/* last = i;*/
return i;
}
int
XFindOutput( name, namlen )
char *name;
int namlen;
{
FILE *fp;
int i;
if( (i = getnextstr()) == -1 )
return -1;
streams[i].inout = OP;
if( strcmp( name, VDU_STR ) == 0 )
{
streams[i].type = VDU;
streams[i].fp = stdout;
}
else if( strcmp( name, RAWVDU_STR ) == 0 )
{
streams[i].type = RAWVDU;
streams[i].fp = stdout;
}
else if( strcmp( name, KB_STR ) == 0 )
fatal("XFO KB unimplemented function");
else if( strcmp( name, RAWKB_STR ) == 0 )
fatal("XFO RKB unimplemented function");
else if( strcmp( name, BBC_STR ) == 0 )
{
streams[i].type = BBC;
streams[i].fp = stdout;
}
else if( strcmp( name, TTY_STR ) == 0 )
{
streams[i].type = TTY;
streams[i].fp = stdout;
}
else if( strcmp( name, RS423_STR ) == 0 )
{
streams[i].type = RS423;
if( rs423_num_users == 1 )
{
/* Disable rs423 as output stream */
rs.r[0] = 3;
rs.r[1] = 0;
ret_val = osbyte( &rs );
/* Enable kb and rs423 as input */
rs.r[0] = 2;
rs.r[1] = 2;
ret_val = osbyte( &rs );
/* disable cursor editing and fn key nums to cursor and copy keys */ rs.r[0] = 4;
rs.r[1] = 2;
ret_val = osbyte( &rs );
/* Disable escape */
rs.r[0] = 229;
rs.r[1] = 1;
ret_val = osbyte( &rs );
rsintercept();
}
rs423_num_users--;
}
else if( strcmp( name, PRINTER_STR ) == 0 )
fatal("XFO PR unimplemented function");
else if( strcmp( name, INPUT_STR ) == 0 )
fatal("XFO IP unimplemented function");
else if( strcmp( name, OUTPUT_STR ) == 0 )
fatal("XFO OP unimplemented function");
else if( strcmp( name, CTL_STR ) == 0 )
fatal("XFO CTL unimplemented function");
else if( strcmp( name, ERR_STR ) == 0 )
fatal("XFO ERR unimplemented function");
else
{
/* An ordinary file */
if( (fp=fopen( name, "w")) == NULL )
return -1;
streams[i].type = FTYPE;
streams[i].fp = fp;
}
return i;
}
int
XCloseStream( stream )
int stream;
{
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XCLOSESTREAM, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( fclose( cur_desc->fp ) != 0 )
return -1;
break;
case VDU:
case RAWVDU:
break;
case KB:
case RAWKB:
if( kb_num_users == 1 )
kbrelease();
kb_num_users--;
break;
case BBC:
case TTY:
fatal("XC TTY unimplemented function");
break;
case RS423:
if( rs423_num_users == 1 )
{
rs.r[0] = 2;
rs.r[1] = 0;
ret_val = osbyte( &rs );
rs.r[0] = 4;
rs.r[1] = 0;
ret_val = osbyte( &rs );
/* Disable escape */
rs.r[0] = 229;
rs.r[1] = 0;
ret_val = osbyte( &rs );
rsrelease();
}
rs423_num_users--;
break;
case PRINTER:
case NULL_DEV:
fatal("XC NULLDEV unimplemented function");
break;
default:
fprintf(stderr,"CLOSESTREAM OUTPUT WOW should never get here!!\n");
fprintf(stderr,"Type is %lx\n",cur_desc->type);
fprintf(stderr,"Type is %lx\n",-0xe);
return -1;
break;
}
cur_desc->type = UNUSED;
return 0;
}
int
XSFlushOutput( stream )
int stream;
{
cur_desc = &streams[stream];
switch( cur_desc->type )
{
case UNUSED:
fprintf(stderr,"XSFLUSHOUTPUT, op on unused stream (%d)\n",stream);
break;
case FTYPE:
if( fflush( cur_desc->fp ) != 0 )
return -1;
else
return 0;
break;
case VDU:
case RAWVDU:
break;
case KB:
case RAWKB:
return -1;
break;
case BBC:
case TTY:
if( cur_desc->inout == IP )
return -1;
break;
case RS423:
if( cur_desc->inout == IP )
rspurge( 1 );
else if( cur_desc->inout == OP )
rspurge( 2 );
else
fatal("XSF RS423 unimplemented function");
break;
case PRINTER:
case NULL_DEV:
fatal("XSV NULLDEV unimplemented function");
break;
default:
fprintf(stderr,"XSFLUSH OUTPUT WOW should never get here!!\n");
fprintf(stderr,"Type is %lx\n",cur_desc->type);
fprintf(stderr,"Type is %lx\n",-0xe);
return -1;
break;
}
return 0;
}
int
Expand( wildname, wildnamelen, addfn, arg, dir )
char *wildname;
int wildnamelen;
int (*addfn)();
int arg, dir ;
{
fatal("Expand - not yet implemented!!\n");
return -1;
}
static int
getnextstr()
{
int i;
for(i=0; i < MAXSTREAMS; i++ )
if( streams[i].type == UNUSED )
return i;
return -1;
}
int
isatty( stream )
int stream;
{
/* Assume stdin and stdout, are never redirected!!! */
return 1;
}
int
XStandardTime( time, timelen )
char *time;
int timelen;
{
time[0] = 0;
if( (ret_val = osword( 0x0e, (int*)time )) != NULL )
{
fprintf(stderr,"%s (%d)\n",ret_val->errmess,ret_val->errnum);
return -1;
}
time[24] = '\0';
return 0;
}
int
XBinaryTime( time )
timeval * time;
{
time->low = 0x3;
if( (ret_val = osword( 0x0e, (int*)time )) != NULL )
{
fprintf(stderr,"%s (%d)\n",ret_val->errmess,ret_val->errnum);
return -1;
}
return 0;
}
/*
* (c) Cosmos Nicolaou 14/6/87
*
* 4.2 BSD style directory operations.
*/
DIR *
opendir( filename )
char *filename;
{
DIR * dirp;
if( (dirp = (DIR*)malloc(sizeof(DIR))) == NULL )
return NULL;
if( (dirp->dd_dirent =
(struct dirent*)malloc(sizeof(struct dirent))) == NULL )
return NULL;
dirp->dd_pos = 0;
strcpy( dirp->dd_name, filename );
return dirp;
}
struct dirent *
readdir( dirp )
DIR *dirp;
{
static osgbpb_block par;
struct dirent *dp;
char *name;
par.action = 9;
par.file_handle = (int)dirp->dd_name;
par.data_addr = dirp->dd_buf;
par.number = 1;
par.seq_point = dirp->dd_pos;
par.buf_len = sizeof( dirp->dd_buf );
par.wild_fld = "*";
if( osgbpb( &par ) != NULL )
return NULL;
if( (par.number != 1) || (par.seq_point == -1) )
return NULL;
name = dirp->dd_buf;
dp = dirp->dd_dirent;
dp->d_namlen = strlen( name );
dp->d_reclen = sizeof(struct dirent) - (MAXNAMLEN+1) +
dp->d_namlen + 1;
strcpy( dp->d_name, name );
dirp->dd_pos++;
return dp;
}
long
telldir( dirp )
DIR *dirp;
{
return dirp->dd_pos;
}
void
seekdir( dirp, loc )
DIR *dirp;
long loc;
{
dirp->dd_pos = loc;
return;
}
void
closedir( dirp )
DIR *dirp;
{
free( dirp->dd_dirent );
free( dirp );
return;
}