home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archimedes / arplib.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  23KB  |  1,069 lines

  1. /* -> c.plib
  2.  *
  3.  *      (c) Cosmos Nicolaou 25/6/87
  4.  */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "arthur.h"
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include "ckafio.h"
  13. #include "plib.h"
  14. #include "tty.h"
  15. #include "ckamis.h"
  16. #include "dir.h"
  17.  
  18.  
  19. /*
  20.  * Temporary kludge to allow use of fatal.
  21.  * It is not good practice to use an application function
  22.  * in a library!
  23.  */
  24. #include "ckcdeb.h"
  25. #include "ckuusr.h"
  26.  
  27. /*
  28.  * Source Code file for Panos compatibility library
  29.  */
  30.  
  31. #define UNUSED 0
  32.  
  33. #define FTYPE   1
  34. #define VDU     2
  35. #define RAWVDU  3
  36. #define KB      4
  37. #define RAWKB   5
  38. #define BBC     6
  39. #define TTY     7
  40. #define RS423   8
  41. #define PRINTER 9
  42. #define NULL_DEV 10
  43.  
  44.  
  45.  
  46. #define VDU_STR     "VDU:"
  47. #define RAWVDU_STR  "RAWVDU:"
  48. #define KB_STR      "KB:"
  49. #define RAWKB_STR   "RAWKB:"
  50. #define BBC_STR     "BBC:"
  51. #define TTY_STR     "TTY:"
  52. #define RS423_STR   "RS423:"
  53. #define PRINTER_STR "PRINTER:"
  54. #define INPUT_STR   "INPUT:"
  55. #define OUTPUT_STR  "OUTPUT"
  56. #define CTL_STR     "CONTROL:"
  57. #define ERR_STR     "ERROR:"
  58.  
  59. #define keybf      0
  60. #define rs423inbf  1
  61. #define rs423outbf 2
  62.  
  63. #define IP 0
  64. #define OP 1
  65.  
  66. static int getnextstr( void );
  67.  
  68. typedef struct {
  69.     int type;
  70.     int inout;
  71.     FILE *fp;
  72. } stream_desc;
  73.  
  74. #define MAXSTREAMS 20
  75.  
  76. static stream_desc streams[MAXSTREAMS];
  77.  
  78. static stream_desc *cur_desc;
  79.  
  80. int rs423_num_users = 0;
  81. int kb_num_users = 0;
  82.  
  83. static reg_set rs;
  84. static error *ret_val;
  85.  
  86.  
  87.  
  88. int
  89. GetFileInformation( info, tstamp, name, len )
  90. struct FileData *info;
  91. struct BTim *tstamp;
  92. char * name;
  93. int len;
  94. {
  95. static osfile_block o_b;
  96. static reg_set rs;
  97. error *ret;
  98.  
  99.     /* Open file for reading */
  100.     rs.r[0] = 64;
  101.     rs.r[1] = (int)name;
  102.     if( (ret=osfind( &rs )) != NULL )
  103.     {
  104.         fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
  105.         return -1;
  106.     }
  107.  
  108.     if( rs.r[0] == 0 )
  109.         /* File does not exist */
  110.         return -1;
  111.      
  112.     /* close the file just opened */
  113.     rs.r[1] = rs.r[0];
  114.     rs.r[0] = 0;
  115.  
  116.     if( (ret=osfind( &rs )) != NULL )
  117.     {
  118.         fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
  119.         return -1;
  120.     }
  121.  
  122.     o_b.action = 5;
  123.     o_b.name = name;
  124.  
  125.     if( (ret=osfile( &o_b )) != NULL )
  126.     {
  127.         fprintf(stderr,"%s (%d)\n",ret->errmess,ret->errnum);
  128.         return -1;
  129.     }
  130.  
  131.     info->loadaddr = o_b.loadaddr;
  132.     info->execaddr = o_b.execaddr;
  133.     info->length = o_b.start;
  134.     info->attrib = o_b.end;
  135.  
  136.     /* Return file type */
  137.     return o_b.action;
  138.  
  139. }
  140.  
  141.  
  142. int
  143. EndOfFile( stream )
  144. int stream;
  145. {
  146.    
  147.     cur_desc = &streams[stream];
  148.  
  149.     if( cur_desc->type == UNUSED )
  150.     {
  151.        fprintf(stderr,"ENDOFFILE, op on unused stream (%d)\n",stream);
  152.        fatal("ENDOFFILE, op on unused stream");
  153.     }
  154.  
  155.     if( cur_desc->type != FTYPE )
  156.         /* Not a file */
  157.         fatal("End of file unimplemented function");
  158.  
  159.     if( feof( cur_desc->fp ) != 0 )
  160.         /* At end of file */
  161.         return 1;
  162.     else
  163.         return 0;
  164.  
  165. }
  166.  
  167.  
  168. int
  169. SWriteByte( 
  170. #ifdef ANSI
  171. int stream, char ch)
  172. #else
  173. stream, ch )
  174. int stream;
  175. char ch;
  176. #endif
  177. {
  178.     cur_desc = &streams[stream];
  179.  
  180.  
  181.     switch( cur_desc->type )
  182.     {
  183.         case UNUSED:
  184.             fprintf(stderr,"SWRITEBYTE, op on unused stream (%d)\n",stream);
  185.             break;
  186.         case FTYPE:
  187.             if( fputc( ch, cur_desc->fp ) == EOF )
  188.                 return -9;
  189.             break;
  190.         case VDU:
  191.             /* printable ascii, clear-screen, newline, and carry return */
  192.             if( ch == '\n' )
  193.             {
  194.                 vdu(10);vdu(13);break;
  195.             }
  196.             if( !iscntrl(ch) || isspace(ch) )
  197.                 vdu( ch );
  198.             break;
  199.         case RAWVDU:
  200.             vdu( ch );
  201.             break;
  202.         case BBC:
  203.             /* RAWVDU for output */
  204.             cur_desc->type = RAWVDU;
  205.             if( SWriteByte( stream, ch ) < 0 )
  206.             {
  207.                 cur_desc->type = BBC;   
  208.                 return -1;
  209.             }
  210.             cur_desc->type = BBC;
  211.             break;
  212.         case TTY:
  213.             /* DU for output */
  214.             cur_desc->type = VDU;
  215.             if( SWriteByte( stream, ch ) < 0 )
  216.             {
  217.                 cur_desc->type = BBC;   
  218.                 return -1;
  219.             }
  220.             cur_desc->type = BBC;
  221.             break;
  222.         case RS423:
  223.             rs.r[0] = 153;
  224.             rs.r[1] = rs423outbf;
  225.             rs.r[2] = ch;
  226.             ret_val = osbyte( &rs );
  227.             inter();
  228.             break;
  229.         case PRINTER:
  230.         case NULL_DEV:
  231.             fatal("SWB unimplemented function");
  232.             break;
  233.         default:
  234.             fprintf(stderr,"SWRITEBYTE WOW should never get here!!\n");
  235.             return -1;
  236.             break;
  237.     }
  238.  
  239.     return 0;
  240.  
  241. }
  242.  
  243. int
  244. XSWriteByte(
  245. #ifdef ANSI
  246. int stream, char ch)
  247. #else
  248. stream, ch )
  249. int stream;
  250. char ch;
  251. #endif
  252. {
  253.     cur_desc = &streams[stream];
  254.  
  255.     switch( cur_desc->type )
  256.     {
  257.         case UNUSED:
  258.             fprintf(stderr,"XSWRITEBYTE, op on unused stream (%d)\n",stream);
  259.             break;
  260.         case FTYPE:
  261.             if( fputc( ch, cur_desc->fp ) == EOF )
  262.                 return -9;
  263.             break;
  264.         case VDU:
  265.             /* printable ascii, clear-screen, newline, and carry return */
  266.             if( ch == '\n' )
  267.             {
  268.                 vdu(10);vdu(13);break;
  269.             }
  270.             if( !iscntrl(ch) || isspace(ch) )
  271.                 vdu( ch );
  272.             break;
  273.         case RAWVDU:
  274.             vdu( ch );
  275.             break;
  276.         case KB:
  277.         case RAWKB:
  278.             fatal("XSWB unimplemented function");
  279.             break;
  280.         case BBC:
  281.             /* RAWVDU for output */
  282.             cur_desc->type = RAWVDU;
  283.             if( XSWriteByte( stream, ch ) < 0 )
  284.             {
  285.                 cur_desc->type = BBC;
  286.                 return -1;
  287.             }
  288.             cur_desc->type = BBC;
  289.             break;
  290.         case TTY:
  291.             /* VDU for output */
  292.             cur_desc->type = VDU;
  293.             if( XSWriteByte( stream, ch ) < 0 )
  294.             {
  295.                 cur_desc->type = BBC;
  296.                 return -1;
  297.             }
  298.             cur_desc->type = BBC;
  299.             break;
  300.         case RS423:
  301.             rs.r[0] = 153;
  302.             rs.r[1] = rs423outbf;
  303.             rs.r[2] = ch;
  304.             ret_val = osbyte( &rs );
  305.             inter();
  306.             break;
  307.         case PRINTER:
  308.         case NULL_DEV:
  309.             fatal("XSW unimplemented function");
  310.             break;
  311.         default:
  312.             fprintf(stderr,"XSWRITEBYTE WOW should never get here!!\n");
  313.             abort();
  314.             return -1;
  315.             break;
  316.     }
  317.  
  318.     return 0;
  319.  
  320. }
  321.  
  322. int
  323. XSBlockWrite( stream, bufsiz, buf )
  324. int stream, bufsiz;
  325. char * buf;
  326. {
  327. int i;
  328. int ch;
  329.  
  330.     cur_desc = &streams[stream];
  331.  
  332.     switch( cur_desc->type )
  333.     {
  334.         case UNUSED:
  335.             fprintf(stderr,"XSBLOCKWRITE, op on unused stream (%d)\n",stream);
  336.             break;
  337.         case FTYPE:
  338.             if( fwrite( buf, sizeof(char), bufsiz, cur_desc->fp ) != bufsiz )
  339.                 return -1;
  340.             break;
  341.         case VDU:
  342.             for( i=0; i < bufsiz; i++ )
  343.             {
  344.                 ch = *(buf+i);
  345.                 if( ch == '\n' )
  346.                 {
  347.                     vdu(10);vdu(13);break;
  348.                 }
  349.                 /* printable ascii, clear-screen, newline, and carry return */
  350.                 if( !iscntrl(ch) || isspace(ch) )
  351.                     vdu( ch );
  352.             }
  353.             break;
  354.         case RAWVDU:
  355.             for( i=0; i < bufsiz; i++ )
  356.                 vdu( *(buf+i) );
  357.             break;
  358.         case BBC:
  359.             /* RAWVDU for output */
  360.             cur_desc->type = RAWVDU;
  361.             if( XSBlockWrite( stream, bufsiz, buf ) < 0 )
  362.             {
  363.                 cur_desc->type = BBC;
  364.                 return -1;
  365.             }
  366.             cur_desc->type = BBC;
  367.             break;
  368.         case TTY:
  369.             /* VDU for output */
  370.             cur_desc->type = VDU;
  371.             if( XSBlockWrite( stream, bufsiz, buf ) < 0 )
  372.             {
  373.                 cur_desc->type = BBC;
  374.                 return -1;
  375.             }
  376.             cur_desc->type = BBC;
  377.             break;
  378.         case RS423:
  379.             for( i=0; i < bufsiz; i++ )
  380.             {
  381.  
  382.                 rs.r[0] = 153;
  383.                 rs.r[1] = rs423outbf;
  384.                 rs.r[2] = *(buf+i);
  385.                 ret_val = osbyte( &rs );
  386.  
  387.             }
  388.             inter();
  389.             break;
  390.         case PRINTER:
  391.         case NULL_DEV:
  392.             fatal("XSBLKW unimplemented function");
  393.             break;
  394.         default:
  395.             fprintf(stderr,"XSBLOCK WRITE WOW should never get here!!\n");
  396.             return -1;
  397.             break;
  398.     }
  399.  
  400.  
  401.     return 0;
  402.  
  403. }
  404.  
  405. int
  406. SReadByte( stream )
  407. int stream;
  408. {
  409. int ch;
  410.  
  411.     cur_desc = &streams[stream];
  412.  
  413.     switch( cur_desc->type )
  414.     {
  415.         case UNUSED:
  416.             fprintf(stderr,"SREADBYTE, op on unused stream (%d)\n",stream);
  417.             break;
  418.         case FTYPE:
  419.             if( (ch=fgetc( cur_desc->fp )) == EOF )
  420.                 return -9;
  421.             else
  422.                 return ch;
  423.             break;
  424.         case KB:
  425.             fatal("SRB unimplemented function");
  426.             break;
  427.         case RAWKB:
  428.             while( testbf( keybf, &ch ) == 0 )
  429.                 ;
  430.             return ch;
  431.             break;
  432.         case BBC:
  433.             /* RAWKB for input */
  434.             cur_desc->type = RAWKB;
  435.             ch = SReadByte( stream );
  436.             cur_desc->type = BBC;
  437.             return ch;
  438.             break;
  439.         case TTY:
  440.             /* KB for input */
  441.             cur_desc->type = KB;
  442.             ch = SReadByte( stream );
  443.             cur_desc->type = BBC;
  444.             return ch;
  445.             break;
  446.         case RS423:
  447.             if( (ch = rsremove(rs423inbf)) == 0 )
  448.                 return 0;
  449.             return ch & 0xff;
  450.             break;
  451.         case PRINTER:
  452.         case NULL_DEV:
  453.             fatal("SRB unimplemented function");
  454.             break;
  455.         default:
  456.             fprintf(stderr,"SREADBYTE WOW should never get here!!\n");
  457.             return -1;
  458.             break;
  459.     }
  460.  
  461.  
  462.     return 0;
  463.  
  464. }
  465.  
  466. int
  467. XSReadByte( stream )
  468. int stream;
  469. {
  470. int ch;
  471.  
  472.     cur_desc = &streams[stream];
  473.  
  474.     switch( cur_desc->type )
  475.     {
  476.         case UNUSED:
  477.             fprintf(stderr,"XSREADBYTE, op on unused stream (%d)\n",stream);
  478.             break;
  479.         case FTYPE:
  480.             if( (ch=fgetc( cur_desc->fp )) == EOF )
  481.                 return -9;
  482.             else
  483.                 return ch;
  484.             break;
  485.         case KB:
  486.             fatal("XSRB unimplemented function");
  487.             break;
  488.         case RAWKB:
  489.             while( testbf( keybf, &ch ) == 0 )
  490.                 ;
  491.             return ch;
  492.         case BBC:
  493.             /* RAWKB for input */
  494.             cur_desc->type = RAWKB;
  495.             ch = XSReadByte( stream );
  496.             cur_desc->type = BBC;
  497.             return ch;
  498.             break;
  499.         case TTY:
  500.             /* KB for input */
  501.             cur_desc->type = KB;
  502.             ch = XSReadByte( stream );
  503.             cur_desc->type = BBC;
  504.             return ch;
  505.             break;
  506.         case RS423:
  507.             if( (ch = rsremove(rs423inbf)) == 0 )
  508.                 return 0;
  509.             return ch & 0xff;
  510.             break;
  511.         case PRINTER:
  512.         case NULL_DEV:
  513.             fatal("XSRB unimplemented function");
  514.             break;
  515.         default:
  516.             fprintf(stderr,"XSREADBYTE WOW should never get here!!\n");
  517.             fprintf(stderr,"Type is %lx\n",cur_desc->type);
  518.             fprintf(stderr,"Type is %lx\n",-0xe);
  519.             return -1;
  520.             break;
  521.     }
  522.  
  523.  
  524.     return 0;
  525.  
  526. }
  527.  
  528. int
  529. XBytesOutstanding( stream )
  530. int stream;
  531. {
  532. int cur_pos, end_pos;
  533.  
  534.     cur_desc = &streams[stream];
  535.  
  536.     switch( cur_desc->type )
  537.     {
  538.         case UNUSED:
  539.             fprintf(stderr,"XBYTESOUTSTANDING, op on unused stream (%d)\n",
  540.                                                                       stream);
  541.             break;
  542.         case FTYPE:
  543.             cur_pos = ftell( cur_desc->fp );
  544.             fseek( cur_desc->fp, 0, SEEK_END );
  545.             end_pos = ftell( cur_desc->fp );
  546.             fseek( cur_desc->fp, cur_pos, SEEK_SET );
  547.             return end_pos - cur_pos;
  548.             break;
  549.         case KB:
  550.         case RAWKB:
  551.                return kbcount( 0, keybf );
  552.             break;
  553.         case BBC:
  554.         case TTY:
  555.             fatal("BO unimplemented function");
  556.             break;
  557.         case RS423:
  558.             if( cur_desc->inout == IP )
  559.                 return rscount( 0, rs423inbf );
  560.             else
  561.                 /* Output is unbufferred */
  562.                 return 0;
  563.             break;
  564.         case PRINTER:
  565.         case NULL_DEV:
  566.             fatal("BO unimplemented function");
  567.             break;
  568.         default:
  569.             fprintf(stderr,"BYTES OUTSTANDING WOW should never get here!!\n");
  570.             return -1;
  571.             break;
  572.     }
  573.  
  574.  
  575.     return -1;
  576. }
  577.  
  578. void
  579. dummy()
  580. {
  581.     return;
  582. }
  583.  
  584. int
  585. XFindInput( name, namlen )
  586. char *name;
  587. int namlen;
  588. {
  589. FILE *fp;
  590. int i;
  591. /*static int last;*/
  592.  
  593.     if( (i = getnextstr()) == -1 )
  594.         return -1;
  595.  
  596.     streams[i].inout = IP;
  597.  
  598.     if ( strcmp( name, VDU_STR ) == 0 )
  599.          fatal("XFI VDU unimplemented function");
  600.     else if ( strcmp( name, RAWVDU_STR ) == 0 )
  601.          fatal("XFI RVDU unimplemented function");
  602.     else if( strcmp( name, KB_STR ) == 0 )
  603.     {
  604.         streams[i].type = KB;
  605.         streams[i].fp = stdin;
  606.         if( kb_num_users == 0 )
  607.             kbintercept();
  608.         kb_num_users++;
  609.  
  610.     }
  611.     else if( strcmp( name, RAWKB_STR ) == 0 )
  612.     {
  613.         streams[i].type = RAWKB;
  614.         streams[i].fp = stdin;
  615.         if( kb_num_users == 0 )
  616.             kbintercept();
  617.         kb_num_users++;
  618.     }
  619.     else if( strcmp( name, BBC_STR ) == 0 )
  620.     {
  621.         streams[i].type = BBC;
  622.         streams[i].fp = stdin;
  623.     }
  624.     else if( strcmp( name, TTY_STR ) == 0 )
  625.     {
  626.         streams[i].type = TTY;
  627.         streams[i].fp = stdin;
  628.     }
  629.     else if( strcmp( name, RS423_STR ) == 0 )
  630.     {
  631.         streams[i].type = RS423;
  632.         if( rs423_num_users == 0 )
  633.         {
  634.   
  635.             /* Disable rs423 as output stream */
  636.             rs.r[0] = 3;
  637.             rs.r[1] = 0;
  638.             ret_val = osbyte( &rs );
  639.  
  640.             /* Enable kb and rs423 as input */
  641.             rs.r[0] = 2;
  642.             rs.r[1] = 2;
  643.             ret_val = osbyte( &rs );
  644.  
  645.             /* disable cursor editing and fn key nums to cursor and copy keys */            rs.r[0] = 4;
  646.             rs.r[1] = 2;
  647.             ret_val = osbyte( &rs );
  648.  
  649.             /* Disable escape */
  650.             rs.r[0] = 229;
  651.             rs.r[1] = 1;
  652.             ret_val = osbyte( &rs );
  653.  
  654.             rsintercept();
  655.         }
  656.         rs423_num_users++;
  657.     }
  658.     else if( strcmp( name, PRINTER_STR ) == 0 )
  659.         fatal("XFI PR unimplemented function");
  660.     else if( strcmp( name, INPUT_STR ) == 0 )
  661.     {
  662.  
  663.         fatal("XFI IP unimplemented function");
  664.  
  665.         /* Return currently selected input stream, a bug in
  666.            PANOS, reintroduced here for a laugh!! */
  667. /*fprintf(stderr,"findinput for INPUT: returning %d\n",last);
  668.         return last;*/
  669.  
  670.     }
  671.     else if( strcmp( name, OUTPUT_STR ) == 0 )
  672.         fatal("XFI OP unimplemented function");
  673.     else if( strcmp( name, CTL_STR ) == 0 )
  674.         fatal("XFI CTL unimplemented function");
  675.     else if( strcmp( name, ERR_STR ) == 0 )
  676.         fatal("XFI ERR unimplemented function");
  677.     else
  678.     {
  679.         /* An ordinary file */
  680.         if( (fp=fopen( name, "r")) == NULL )
  681.             return -1;
  682.  
  683.         streams[i].type = FTYPE;
  684.         streams[i].fp = fp;
  685.  
  686.     }   
  687.  
  688. /*    last = i;*/
  689.  
  690.     return i;
  691.  
  692. }
  693.  
  694. int
  695. XFindOutput( name, namlen )
  696. char *name;
  697. int namlen;
  698. {
  699. FILE *fp;
  700. int i;
  701.  
  702.  
  703.     if( (i = getnextstr()) == -1 )
  704.         return -1;
  705.  
  706.     streams[i].inout = OP; 
  707.   
  708.     if( strcmp( name, VDU_STR ) == 0 )
  709.     {
  710.         streams[i].type = VDU;
  711.         streams[i].fp = stdout;
  712.     }
  713.     else if( strcmp( name, RAWVDU_STR ) == 0 )
  714.     {
  715.         streams[i].type = RAWVDU;
  716.         streams[i].fp = stdout;
  717.     }
  718.     else if( strcmp( name, KB_STR ) == 0 )
  719.         fatal("XFO KB unimplemented function");
  720.     else if( strcmp( name, RAWKB_STR ) == 0 )
  721.         fatal("XFO RKB unimplemented function");
  722.     else if( strcmp( name, BBC_STR ) == 0 )
  723.     {
  724.         streams[i].type = BBC;
  725.         streams[i].fp = stdout;
  726.     }
  727.     else if( strcmp( name, TTY_STR ) == 0 )
  728.     {
  729.         streams[i].type = TTY;
  730.         streams[i].fp = stdout;
  731.     }
  732.     else if( strcmp( name, RS423_STR ) == 0 )
  733.     {
  734.         streams[i].type = RS423;
  735.         if( rs423_num_users == 1 )
  736.         {
  737.   
  738.             /* Disable rs423 as output stream */
  739.             rs.r[0] = 3;
  740.             rs.r[1] = 0;
  741.             ret_val = osbyte( &rs );
  742.  
  743.             /* Enable kb and rs423 as input */
  744.             rs.r[0] = 2;
  745.             rs.r[1] = 2;
  746.             ret_val = osbyte( &rs );
  747.  
  748.             /* disable cursor editing and fn key nums to cursor and copy keys */            rs.r[0] = 4;
  749.             rs.r[1] = 2;
  750.             ret_val = osbyte( &rs );
  751.  
  752.             /* Disable escape */
  753.             rs.r[0] = 229;
  754.             rs.r[1] = 1;
  755.             ret_val = osbyte( &rs );
  756.  
  757.             rsintercept();
  758.         }
  759.         rs423_num_users--;
  760.     }
  761.     else if( strcmp( name, PRINTER_STR ) == 0 )
  762.         fatal("XFO PR unimplemented function");
  763.     else if( strcmp( name, INPUT_STR ) == 0 )
  764.         fatal("XFO IP unimplemented function");
  765.     else if( strcmp( name, OUTPUT_STR ) == 0 )
  766.         fatal("XFO OP unimplemented function");
  767.     else if( strcmp( name, CTL_STR ) == 0 )
  768.         fatal("XFO CTL unimplemented function");
  769.     else if( strcmp( name, ERR_STR ) == 0 )
  770.         fatal("XFO ERR unimplemented function");
  771.     else
  772.     {
  773.         /* An ordinary file */
  774.         if( (fp=fopen( name, "w")) == NULL )
  775.             return -1;
  776.  
  777.         streams[i].type = FTYPE;
  778.         streams[i].fp = fp;
  779.  
  780.     }   
  781.  
  782.     return i;
  783.  
  784. }
  785.  
  786. int
  787. XCloseStream( stream )
  788. int stream;
  789. {
  790.  
  791.     cur_desc = &streams[stream];
  792.  
  793.     switch( cur_desc->type )
  794.     {
  795.         case UNUSED:
  796.             fprintf(stderr,"XCLOSESTREAM, op on unused stream (%d)\n",stream);
  797.             break;
  798.         case FTYPE:
  799.             if( fclose( cur_desc->fp ) != 0 )
  800.                 return -1;
  801.             break;
  802.         case VDU:
  803.         case RAWVDU:
  804.             break;
  805.         case KB:
  806.         case RAWKB:
  807.             if( kb_num_users == 1 )
  808.                 kbrelease();
  809.             kb_num_users--;
  810.             break;
  811.         case BBC:
  812.         case TTY:
  813.             fatal("XC TTY unimplemented function");
  814.             break;
  815.         case RS423:
  816.             if( rs423_num_users == 1 )
  817.             {
  818.  
  819.                 rs.r[0] = 2;
  820.                 rs.r[1] = 0;
  821.                 ret_val = osbyte( &rs );
  822.  
  823.                 rs.r[0] = 4;
  824.                 rs.r[1] = 0;
  825.                 ret_val = osbyte( &rs );
  826.  
  827.  
  828.                /* Disable escape */
  829.                rs.r[0] = 229;
  830.                rs.r[1] = 0;
  831.                ret_val = osbyte( &rs );
  832.  
  833.                 rsrelease();
  834.             }
  835.             rs423_num_users--;
  836.             break;
  837.         case PRINTER:
  838.         case NULL_DEV:
  839.             fatal("XC NULLDEV unimplemented function");
  840.             break;
  841.         default:
  842.             fprintf(stderr,"CLOSESTREAM OUTPUT WOW should never get here!!\n");
  843.             fprintf(stderr,"Type is %lx\n",cur_desc->type);
  844.             fprintf(stderr,"Type is %lx\n",-0xe);
  845.             return -1;
  846.             break;
  847.     }
  848.                                     
  849.     cur_desc->type = UNUSED;
  850.     return 0;
  851.  
  852. }
  853.  
  854. int
  855. XSFlushOutput( stream )
  856. int stream;
  857. {
  858.  
  859.  
  860.     cur_desc = &streams[stream];
  861.  
  862.     switch( cur_desc->type )
  863.     {
  864.         case UNUSED:
  865.             fprintf(stderr,"XSFLUSHOUTPUT, op on unused stream (%d)\n",stream);
  866.             break;   
  867.         case FTYPE:
  868.  
  869.             if( fflush( cur_desc->fp ) != 0 )
  870.                 return -1;
  871.             else    
  872.                 return 0;
  873.             break;
  874.         case VDU:
  875.         case RAWVDU:
  876.              break;
  877.         case KB:
  878.         case RAWKB:
  879.             return -1;
  880.             break;
  881.         case BBC:
  882.         case TTY:
  883.             if( cur_desc->inout == IP )
  884.                 return -1;
  885.             break;
  886.         case RS423:
  887.             if( cur_desc->inout == IP )
  888.                 rspurge( 1 );
  889.             else if( cur_desc->inout == OP )
  890.                 rspurge( 2 );
  891.             else
  892.                 fatal("XSF RS423 unimplemented function");
  893.             break;
  894.         case PRINTER:
  895.         case NULL_DEV:
  896.             fatal("XSV NULLDEV unimplemented function");
  897.             break;
  898.         default:
  899.             fprintf(stderr,"XSFLUSH OUTPUT WOW should never get here!!\n");
  900.             fprintf(stderr,"Type is %lx\n",cur_desc->type);
  901.             fprintf(stderr,"Type is %lx\n",-0xe);
  902.             return -1;
  903.             break;
  904.     }
  905.  
  906.     return 0;
  907.  
  908. }
  909.  
  910. int
  911. Expand( wildname, wildnamelen, addfn, arg, dir )
  912. char *wildname;
  913. int wildnamelen;
  914. int (*addfn)();
  915. int arg, dir ;
  916. {
  917. fatal("Expand - not yet implemented!!\n");
  918.     return -1;
  919. }
  920.  
  921. static int
  922. getnextstr()
  923. {
  924. int i;
  925.   
  926.     for(i=0; i < MAXSTREAMS; i++ )
  927.         if( streams[i].type == UNUSED )
  928.             return i;
  929.  
  930.     return -1;
  931.  
  932. }
  933.  
  934. int
  935. isatty( stream )
  936. int stream;
  937. {
  938.     
  939.     /* Assume stdin and stdout, are never redirected!!! */
  940.     return 1;
  941.  
  942. }
  943.  
  944. int
  945. XStandardTime( time, timelen )
  946. char *time;
  947. int timelen;
  948. {
  949.  
  950.     time[0] = 0;
  951.     if( (ret_val = osword( 0x0e, (int*)time )) != NULL )
  952.     {
  953.         fprintf(stderr,"%s (%d)\n",ret_val->errmess,ret_val->errnum);
  954.         return -1;
  955.     }
  956.  
  957.     time[24] = '\0';
  958.     return 0;
  959.  
  960.  
  961. }
  962.  
  963.  
  964. int
  965. XBinaryTime( time )
  966. timeval * time;
  967. {
  968.                
  969.     time->low = 0x3;
  970.     if( (ret_val = osword( 0x0e, (int*)time )) != NULL )
  971.     {
  972.         fprintf(stderr,"%s (%d)\n",ret_val->errmess,ret_val->errnum);
  973.         return -1;
  974.     }
  975.  
  976.     return 0;
  977.  
  978. }
  979.  
  980. /*
  981.  *      (c) Cosmos Nicolaou 14/6/87
  982.  *
  983.  *      4.2 BSD style directory operations.
  984.  */
  985.  
  986. DIR *
  987. opendir( filename )
  988. char *filename;
  989. {
  990. DIR * dirp;
  991.  
  992.         if( (dirp = (DIR*)malloc(sizeof(DIR))) == NULL )
  993.                 return NULL;
  994.  
  995.         if( (dirp->dd_dirent =
  996.                 (struct dirent*)malloc(sizeof(struct dirent))) == NULL )
  997.                 return NULL;
  998.  
  999.         dirp->dd_pos = 0;
  1000.         strcpy( dirp->dd_name, filename );
  1001.  
  1002.         return dirp;
  1003.  
  1004. }
  1005.  
  1006.  
  1007. struct dirent *
  1008. readdir( dirp )
  1009. DIR *dirp;
  1010. {
  1011. static osgbpb_block par;
  1012. struct dirent *dp;
  1013. char *name;
  1014.  
  1015.     par.action = 9;
  1016.     par.file_handle = (int)dirp->dd_name;
  1017.     par.data_addr = dirp->dd_buf;
  1018.     par.number = 1;
  1019.     par.seq_point = dirp->dd_pos;
  1020.     par.buf_len = sizeof( dirp->dd_buf );
  1021.     par.wild_fld = "*";
  1022.  
  1023.     if( osgbpb( &par ) != NULL )
  1024.         return NULL;
  1025.  
  1026.     if( (par.number != 1) || (par.seq_point == -1) )
  1027.         return NULL;
  1028.  
  1029.     name = dirp->dd_buf;
  1030.  
  1031.     dp = dirp->dd_dirent;
  1032.  
  1033.     dp->d_namlen = strlen( name );
  1034.     dp->d_reclen = sizeof(struct dirent) - (MAXNAMLEN+1) +
  1035.                                                   dp->d_namlen + 1;
  1036.     strcpy( dp->d_name, name );
  1037.  
  1038.     dirp->dd_pos++;
  1039.  
  1040.     return dp;
  1041.  
  1042. }
  1043.  
  1044. long
  1045. telldir( dirp )
  1046. DIR *dirp;
  1047. {
  1048.         return dirp->dd_pos;
  1049. }
  1050.  
  1051. void
  1052. seekdir( dirp, loc )
  1053. DIR *dirp;
  1054. long loc;
  1055. {
  1056.         dirp->dd_pos = loc;
  1057.         return;
  1058. }
  1059.  
  1060. void
  1061. closedir( dirp )
  1062. DIR *dirp;
  1063. {
  1064.  
  1065.         free( dirp->dd_dirent );
  1066.         free( dirp );
  1067.         return;
  1068. }
  1069.