/* -> c.plib * * (c) Cosmos Nicolaou 25/6/87 */ #include #include #include "arthur.h" #include #include #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; }