home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / GNU_ATP_1_40.lzh / SRC / system.c < prev    next >
Text File  |  1993-08-30  |  20KB  |  936 lines

  1.  
  2. /*
  3.      ATP QWK MAIL READER FOR READING AND REPLYING TO QWK MAIL PACKETS.
  4.      Copyright (C) 1992  Thomas McWilliams
  5.      Copyright (C) 1990  Rene Cougnenc
  6.  
  7.      This program is free software; you can redistribute it and/or modify
  8.      it under the terms of the GNU General Public License as published by
  9.      the Free Software Foundation; either version 1, or ( at your option )
  10.      any later version.
  11.  
  12.      This program is distributed in the hope that it will be useful,
  13.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.      GNU General Public License for more details.
  16.  
  17.      You should have received a copy of the GNU General Public License
  18.      along with this program; if not, write to the Free Software
  19.      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. */
  22.  
  23. /*
  24.  * Change Log: $Log: system.c,v $
  25.  * Revision 1.400  1992/11/28  09:57:36  root
  26.  * second release
  27.  * Revision 1.310  1992/07/08  23:15:14  root
  28.  * first release -- minor bug fix in read.c
  29.  *
  30.  * Revision 1.30  1992/07/05  15:36:19  root first release of ATP
  31.  *
  32.  * Revision 1.2  1992/04/19  12:51:47  root 1st semifunctional UNIX version.
  33.  *
  34.  */
  35.  
  36.  
  37. /*
  38.  * OS-9/68000 System-Dependent functions for Read.c
  39.  */
  40.  
  41. #include <sgstat.h>
  42. #include <stdio.h>
  43. #include <strings.h>
  44. #include "system.h"
  45. #include "ansi.h"
  46.  
  47. #ifndef SEP
  48. #define SEP '/'
  49. #endif
  50.  
  51. #ifndef ERROR
  52. #define ERROR (-1)
  53. #endif
  54.  
  55. #ifndef ESC
  56. #define ESC (27)
  57. #endif
  58.  
  59. /* extern functions */
  60.  
  61. extern char *mktemp(); /* Microware C Standard Library */
  62. /*
  63.  * termcap functions
  64.  */
  65.  
  66. #include <termcap.h>
  67.  
  68. #define TCAPSLEN 400
  69.  
  70. extern char *getenv();
  71.  
  72. char tcapbuf[TCAPSLEN];        /* storage space for extracted termcap strings */
  73. /* the following are mandatory in order to use termcap */
  74. char *BC;                    /* backspace character */
  75. char *UP;                    /* cursor up */
  76. char PC_;                    /* pad character */
  77. short ospeed;                /* terminal speed */
  78. char *DO;                    /* down one line */
  79. char *ND;                    /* cursor right */
  80. char *CL;                    /* clear screen */
  81.  
  82. /* write one character */
  83.  
  84. int tputchar( c )
  85. char c;
  86. {
  87.     return( putchar( c ) );
  88. }
  89.  
  90. /* Cursor position */
  91.  
  92. void up( nb ) /* Cursor Up default 1 */
  93. int nb;
  94. {
  95.     if( nb < 1 ) 
  96.           nb = 1;
  97.     if( ansi )
  98.         printf( "%c[%dA",ESC,nb );
  99.     else
  100.         while( nb )
  101.         {
  102.             tputs( UP, 1, tputchar );
  103.             --nb;
  104.         }
  105. }
  106.  
  107. void dn( nb ) /* Cursor down default 1 */
  108. int nb;
  109. {
  110.     if( nb < 1 ) 
  111.         nb = 1;
  112.     if( ansi )
  113.         printf( "%c[%dB",ESC,nb );
  114.     else
  115.         while( nb )
  116.         {
  117.             tputs( DO, 1, tputchar );
  118.             --nb;
  119.         }
  120. }
  121.  
  122. void right( nb ) /* Cursor right default 1 */
  123. int nb;
  124. {
  125.     if( nb < 1 ) 
  126.         nb = 1;
  127.     if( ansi )
  128.            printf( "%c[%dC",ESC,nb );
  129.     else
  130.         while( nb )
  131.         {
  132.             tputs( ND, 1, tputchar );
  133.             nb--;
  134.         }
  135. }
  136.  
  137. void left( nb ) /* Cursor left default 1 */
  138. int nb;
  139. {
  140.     if( nb < 1 ) 
  141.         nb = 1;
  142.     if( ansi )
  143.            printf( "%c[%dD",ESC,nb );
  144.     else
  145.         while( nb )
  146.         {
  147.             tputs( ND, 1, tputchar );
  148.             --nb;
  149.         }
  150. }
  151.  
  152. void cls() /* Clear screen & home cursor */
  153. {
  154.     if( ansi )
  155.         printf( "%c[2J%c[H",ESC,ESC );
  156.     else
  157.         tputs( CL, 1, tputchar );
  158. }
  159.  
  160. /*
  161.  * sets up / restores terminal options for atp.
  162.  */
  163.  
  164. void _do_term( action )
  165. int action; /* 1 sets up options, 0 restores options */
  166. {
  167.     static struct sgbuf save_opt;
  168.     struct sgbuf temp_opt;
  169. #define STDOUT 1
  170.  
  171.     if( action )
  172.     {
  173.         stdin->_flag |= _UNBUF; /* use unbuffered output on stdin */
  174.         stdout->_flag |= _UNBUF; /* use unbuffered output on stdout */
  175.         if( _gs_opt( STDOUT, &temp_opt ) == -1 )
  176.             perror( "setup terminal options" );
  177.         memcpy( &save_opt, &temp_opt, sizeof( struct sgbuf ) );
  178.         temp_opt.sg_pause = (char) 0; /* nopause */
  179.         temp_opt.sg_echo = (char) 0; /* no echo */
  180.         ospeed = (short) temp_opt.sg_baud;
  181.         if( _ss_opt( STDOUT, &temp_opt ) == -1 )
  182.             perror( "setup terminal options" );
  183.     }
  184.     else
  185.     {
  186.         if( _ss_opt( STDOUT, &save_opt ) == -1 )
  187.             perror( "restore terminal options" );
  188.     }
  189.     return;
  190. }
  191.  
  192. void setup_term()
  193. {
  194.     
  195.     char *term_type;
  196.     char *temp;
  197.     char tcbuf[1024];
  198.     char *ptr;
  199.     
  200.     /* do the termcap thing */
  201.  
  202.     if( ( term_type = getenv( "TERM" ) ) == NULL )
  203.     {
  204.         fprintf( stderr, "Environment variable TERM not defined!\n" );
  205.         exit( -1 );
  206.     }
  207.     if( tgetent( tcbuf, term_type ) == 0 )
  208.     {
  209.         fprintf( stderr, "Unknown terminal type '%s'!\n", term_type );
  210.         exit( -1 );
  211.     }
  212.     ptr = tcapbuf;
  213.     /* collect the strings we need */
  214.     if( temp = tgetstr( "pc", &ptr ) )
  215.         PC_ = *temp;                /* pad character */
  216.     else
  217.         PC_ = '\0';
  218.     if( temp = tgetstr( "bc", &ptr ) )
  219.         BC = temp;                /* backspace string */
  220.     else
  221.         BC = "\b";
  222.     UP = tgetstr( "up", &ptr );    /* cursor up */
  223.     DO = tgetstr( "do", &ptr );    /* down one line */
  224.     ND = tgetstr( "nd", &ptr );    /* cursor right */
  225.     CL = tgetstr( "cl", &ptr ); /* clear screen */
  226.     if( !UP )
  227.     {
  228.         fprintf( stderr, "Need 'up' (cursor up) in termcap.\n" );
  229.         exit( -1 );
  230.     }
  231.     if( !DO )
  232.     {
  233.         fprintf( stderr, "Need 'do' (cursor down) in termcap.\n" );
  234.         exit( -1 );
  235.     }
  236.     if( !ND )
  237.     {
  238.         fprintf( stderr, "Need 'nd' (cursor right) in termcap.\n" );
  239.         exit( -1 );
  240.     }
  241.     if( !CL )
  242.     {
  243.         fprintf( stderr, "Need 'cl' in termcap.\n" );
  244.         exit( -1 );
  245.     }
  246.     /* turn pause off, etc. */
  247.     _do_term( 1 );
  248.     return;
  249. }
  250.  
  251. void restore_term()
  252. {
  253.     _do_term( 0 );
  254.     return;
  255. }
  256.  
  257. /*-----------------------------------------------------------------------*/
  258.  
  259. /*
  260.  * Deletes ALL files in a directory pointed by PathName. This is
  261.  * system-dependant.
  262.  */
  263.  
  264. void Erase( PathName )
  265. char *PathName;
  266. {
  267.     char Pattern[127];
  268.  
  269.     sprintf( Pattern, "del -f %s/*", PathName );
  270.     system( Pattern );
  271. }
  272.  
  273. /*
  274.  * strnicmp() compares the strings pointed to by s1 and s2 and
  275.  * returns an integer less than, equal to or greater than zero
  276.  * where s1 is less than, equal to or greater than s2.  Case
  277.  * insensitive.  Compares at most n characters.
  278.  */
  279.  
  280. int strnicmp( s1, s2, n )
  281. char *s1;
  282. char *s2;
  283. unsigned int n;
  284. {
  285.     while( n && *s1 && *s2 )
  286.     {
  287.         if( tolower( *s1 ) != tolower( *s2 ) )
  288.             return( tolower( *s1 ) > tolower( *s2 ) ? 1 : -1 );
  289.         s1++;
  290.         s2++;
  291.         n--;
  292.     }
  293.     if( n )
  294.     {
  295.         if( *s1 )
  296.             return( 1 );
  297.         if( *s2 )
  298.             return( -1 );
  299.     }
  300.     return( 0 );
  301. }
  302.  
  303. /*
  304.  * sticmp() compares the strings pointed to by s1 and s2 and
  305.  * returns an integer less than, equal to or greater than zero
  306.  * where s1 is less than, equal to or greater than s2.  Case
  307.  * insensitive.
  308.  */
  309.  
  310. int stricmp( s1, s2 )
  311. char *s1;
  312. char *s2;
  313. {
  314.     while( *s1 != '\0' && *s2 != '\0' )
  315.     {
  316.         if( tolower( *s1 ) != tolower( *s2 ) )
  317.             return( tolower( *s1 ) > tolower( *s2 ) ? 1 : -1 );
  318.         s1++;
  319.         s2++;
  320.     }
  321.     if( *s1 )
  322.         return( 1 );
  323.     if( *s2 )
  324.         return( -1 );
  325.     return( 0 );
  326. }
  327.  
  328. /*
  329.  * strlwr() converts string pointed to by s to lower case.
  330.  */
  331.  
  332. char *strlwr( s )
  333. char *s;
  334. {
  335.     char *s1;
  336.  
  337.     s1 = s;
  338.     while( *s1 )
  339.     {
  340.         *s1 = tolower( *s1 );
  341.         s1++;
  342.     }
  343.     return( s );
  344. }
  345.  
  346. /*
  347.  * strupr() converts string pointed to by s to upper case.
  348.  */
  349.  
  350. char *strupr( s )
  351. char *s;
  352. {
  353.     char *s1;
  354.  
  355.     s1 = s;
  356.     while( *s1 )
  357.     {
  358.         *s1 = toupper( *s1 );
  359.         s1++;
  360.     }
  361.     return( s );
  362. }
  363.  
  364. #define STOPIT ((int)'\n')
  365.  
  366. char *readline( prmt )
  367. char *prmt;
  368. {
  369.  
  370.     static char rdlnbuf[128];
  371.     static char buf[128];
  372.     extern char *luxptr;
  373.     char *tempr;
  374.     int cin = 0;
  375.     int idx = 0;
  376.     int i;
  377.     int firsthere = TRUE;
  378.  
  379.     /* initialize buffers */
  380.     rdlnbuf[0] = buf[0] = 0;
  381.  
  382.     /* display prompt */
  383.     printf( "%s", prmt );             
  384.     if( luxptr != NULL )
  385.     {
  386.         strcpy ( rdlnbuf, luxptr );
  387.         printf( "%s\n", luxptr );
  388.         up( 1 );
  389.         right( strlen( prmt ) );
  390.         buf[0] = 1;
  391.     }
  392.     while( ( cin = getchar() ) != STOPIT )
  393.     {
  394.         fflush( stdout );
  395.         if( firsthere )
  396.         {
  397.             /* clear line */
  398.             for( i=idx; i < 25; i++ ) 
  399.                 printf( " " ); 
  400.             for( i=idx; i < 25; i++ ) 
  401.                 printf( "\b" ); 
  402.             buf[0] = 1;
  403.             firsthere = FALSE;
  404.         }
  405.         if( cin > 31 && cin < 127 ) /* printable characters */
  406.         {
  407.             if( idx > 24 )
  408.                 buf[idx] = 0;
  409.             else
  410.             {
  411.                 buf[idx] = (char) cin; 
  412.                 idx++;
  413.                 buf[idx] = 0;
  414.                 printf( "%c", cin );
  415.             }
  416.         }
  417.         else if( cin == '\b' && idx > 0 ) /* backspace */
  418.         {  
  419.             buf[--idx] = 0;
  420.             /* do backspace, space, backspace */
  421.             printf( "\b \b" );
  422.         }
  423.         else /* all control characters */
  424.         {
  425.             buf[idx] = 0;
  426.         }
  427.     }
  428.     printf( "\n" );
  429.     if( buf[0] == 1 ) 
  430.         strcpy( buf, rdlnbuf );
  431.     return( buf );
  432. }
  433.  
  434. char *tempnam( workpath, rep )
  435. char *workpath;
  436. char *rep;
  437. {
  438.  
  439.     char *tp1, *tp2;
  440.     static char    tbuf[150];
  441.     char buffy[15];
  442.  
  443.     strcpy( buffy,"XXXXXX" );
  444.     tp2 = tbuf;
  445.     tp1 = mktemp( buffy );
  446.     if( tp1 != NULL )
  447.     {
  448.         strcpy( tbuf, workpath );
  449.         while( *tp2 ) tp2++;
  450.         tp2--;
  451.         if( *tp2 != SEP )
  452.         {
  453.             tp2++;
  454.             *tp2 = SEP;
  455.             tp2++;
  456.             *tp2 = '\0';
  457.        }
  458.        strcat( tbuf, rep );
  459.        strcat( tbuf, tp1 );
  460.        tp1 = tbuf;
  461.    }
  462.    return( tp1 );
  463. }
  464.  
  465. /*
  466.  * getcwd() get current working directory.
  467.  * by Robert A. Larson from "blarslib."
  468.  */
  469.  
  470. #include <modes.h>
  471. #include <direct.h>
  472.  
  473. char *getcwd( p, n )
  474. char *p;
  475. int n;
  476. {
  477.     register char *cp;
  478.     register struct dirent *dp;
  479.     register int l, olddot = 0, i, d, dot, dotdot;
  480.     struct dirent db[8];
  481.     char buf[1024];
  482.  
  483.     if( p==NULL )
  484.     {
  485.         p = ( char * ) malloc( ( unsigned ) n );
  486.         if( p==NULL )
  487.             return( NULL );
  488.     }
  489.     cp = &buf[1024-1];
  490.     *cp = '\0';
  491.     for( ;; )
  492.     {
  493.         if( ( d = open( ".", S_IREAD | S_IFDIR ) ) < 0 )
  494.         {
  495.             if( *cp ) chdir( cp+1 );
  496.                 return( NULL );
  497.         }
  498.         if( ( i = read( d, ( char * ) db, sizeof( db ) ) ) == 0 )
  499.         {
  500.             if( *cp )
  501.                 chdir( cp+1 );
  502.             close( d );
  503.             return( NULL );
  504.         }
  505.         dotdot = db[0].dir_addr;
  506.         dot = db[1].dir_addr;
  507.         if( olddot )
  508.         {
  509.             i -= 2 * sizeof( struct dirent );
  510.             dp = &db[2];
  511.             for( ;; )
  512.             {
  513.                 if( i <= 0 )
  514.                 {
  515.                     if( ( i = read( d, ( char * ) db, sizeof( db ) ) ) == 0 )
  516.                     {
  517.                         if( *cp )
  518.                             chdir( cp+1 );
  519.                         close( d );
  520.                         return( NULL );
  521.                     }
  522.                     dp = &db[0];
  523.                 }
  524.                 if( olddot == dp->dir_addr )
  525.                 {
  526.                     l = strlen( dp->dir_name );
  527.                     /* last character has parity bit set... */
  528.                     *--cp = dp->dir_name[--l] & 0x7f;
  529.                     while( l )
  530.                         *--cp = dp->dir_name[--l];
  531.                     *--cp = '/';
  532.                     break;
  533.                 }
  534.                 i -= sizeof( struct dirent );
  535.                 dp++;
  536.             }
  537.         }
  538.         if( dot == dotdot )
  539.         {
  540.             if( *cp )
  541.                 chdir( cp+1 );
  542.             *p = '/';
  543.             if( _gs_devn( d, p+1 ) < 0 )
  544.             {
  545.                 close( d );
  546.                 return( NULL );
  547.             }
  548.             close( d );
  549.             if( n < ( strlen( p ) + strlen( cp ) ) )
  550.                 return( NULL );
  551.             strcat( p, cp );
  552.             return( p );
  553.         }
  554.         close( d );
  555.         if( chdir( ".." ) != 0 )
  556.         {
  557.             if( *cp )
  558.                 chdir( cp+1 );
  559.             return( NULL );
  560.         }
  561.         olddot = dot;
  562.     }
  563. }
  564.  
  565. /*
  566.  *      strstr() returns a pointer to the first occurance of <pattern> in
  567.  *        <string>.  NULL is returned if <pattern> is not found.
  568.  */
  569.  
  570. char *strstr( string, pattern )
  571. register char *string;
  572. register char *pattern;
  573. {
  574.         register int plen;
  575.         char *strchr();
  576.  
  577.         plen = strlen( pattern );
  578.         while( string = index( string, *pattern ) )
  579.         {
  580.             if( strncmp( string, pattern, plen ) == 0 )
  581.                 return( string );
  582.             ++string;
  583.         }
  584.         return( NULL );
  585. }
  586.  
  587. static unsigned long _seed = 1;
  588.  
  589. int rand()
  590. {
  591.     _seed = ( _seed * 1103515245 ) + 12345;
  592.     return( ( unsigned int ) ( ( _seed / 65536 ) % 32768 ) );
  593. }
  594.  
  595. void srand( seed )
  596. unsigned int seed;
  597. {
  598.     _seed = seed;
  599. }
  600.  
  601. /* perror, sys_errlist and sys_nerr for os9/68k */
  602.  
  603. extern int errno;
  604.  
  605. int sys_nerr = 256;
  606.  
  607. char *sys_errlist[256] =
  608. {
  609.           "error 0",
  610.           "error 1",
  611.     /* 000:002 */ "keyboard quit",
  612.     /* 000:003 */ "keyboard interrupt",
  613.           "error 4",
  614.           "error 5",
  615.           "error 6",
  616.           "error 7",
  617.           "error 8",
  618.           "error 9",
  619.           "error 10",
  620.           "error 11",
  621.           "error 12",
  622.           "error 13",
  623.           "error 14",
  624.           "error 15",
  625.           "error 16",
  626.           "error 17",
  627.           "error 18",
  628.           "error 19",
  629.           "error 20",
  630.           "error 21",
  631.           "error 22",
  632.           "error 23",
  633.           "error 24",
  634.           "error 25",
  635.           "error 26",
  636.           "error 27",
  637.           "error 28",
  638.           "error 29",
  639.           "error 30",
  640.           "error 31",
  641.           "error 32",
  642.           "error 33",
  643.           "error 34",
  644.           "error 35",
  645.           "error 36",
  646.           "error 37",
  647.           "error 38",
  648.           "error 39",
  649.           "error 40",
  650.           "error 41",
  651.           "error 42",
  652.           "error 43",
  653.           "error 44",
  654.           "error 45",
  655.           "error 46",
  656.           "error 47",
  657.           "error 48",
  658.           "error 49",
  659.           "error 50",
  660.           "error 51",
  661.           "error 52",
  662.           "error 53",
  663.           "error 54",
  664.           "error 55",
  665.           "error 56",
  666.           "error 57",
  667.           "error 58",
  668.           "error 59",
  669.           "error 60",
  670.           "error 61",
  671.           "error 62",
  672.           "error 63",
  673.     /* 000:064 */ "illegal function code ( math )",
  674.     /* 000:065 */ "ascii->numeric format conversion error ( math )",
  675.     /* 000:066 */ "not a number ( math )",
  676.     /* 000:067 */ "illegal argument ( usually math )",
  677.           "error 68",
  678.           "error 69",
  679.           "error 70",
  680.           "error 71",
  681.           "error 72",
  682.           "error 73",
  683.           "error 74",
  684.           "error 75",
  685.           "error 76",
  686.           "error 77",
  687.           "error 78",
  688.           "error 79",
  689.           "error 80",
  690.           "error 81",
  691.           "error 82",
  692.           "error 83",
  693.           "error 84",
  694.           "error 85",
  695.           "error 86",
  696.           "error 87",
  697.           "error 88",
  698.           "error 89",
  699.           "error 90",
  700.           "error 91",
  701.           "error 92",
  702.           "error 93",
  703.           "error 94",
  704.           "error 95",
  705.           "error 96",
  706.           "error 97",
  707.           "error 98",
  708.           "error 99",
  709.           "error 100",
  710.           "error 101",
  711.     /* 000:102 */ "bus trap",
  712.     /* 000:103 */ "address trap",
  713.     /* 000:104 */ "illegal instruction",
  714.     /* 000:105 */ "divide by zero",
  715.     /* 000:106 */ "\"chk\" instruction trap",
  716.     /* 000:107 */ "\"trapv\" instruction trap",
  717.     /* 000:108 */ "privileged instruction",
  718.     /* 000:109 */ "trace exception",
  719.     /* 000:110 */ "illegal instruction ( 1010 )",
  720.     /* 000:111 */ "illegal instruction ( 1111 )",
  721.     /* 000:112 */ "exception 12",
  722.     /* 000:113 */ "coprocessor protocol violation",
  723.     /* 000:114 */ "system stack frame format error",
  724.     /* 000:115 */ "uninitialized interrupt",
  725.     /* 000:116 */ "exception 16",
  726.     /* 000:117 */ "exception 17",
  727.     /* 000:118 */ "exception 18",
  728.     /* 000:119 */ "exception 19",
  729.     /* 000:120 */ "exception 20",
  730.     /* 000:121 */ "exception 21",
  731.     /* 000:122 */ "exception 22",
  732.     /* 000:123 */ "exception 23",
  733.     /* 000:124 */ "spurious interrupt",
  734.           "error 125",
  735.           "error 126",
  736.           "error 127",
  737.           "error 128",
  738.           "error 129",
  739.           "error 130",
  740.           "error 131",
  741.           "error 132",
  742.     /* 000:133 */ "an uninitialized user TRAP ( 1-15 ) was executed",
  743.           "error 134",
  744.           "error 135",
  745.           "error 136",
  746.           "error 137",
  747.           "error 138",
  748.           "error 139",
  749.           "error 140",
  750.           "error 141",
  751.           "error 142",
  752.           "error 143",
  753.           "error 144",
  754.           "error 145",
  755.           "error 146",
  756.           "error 147",
  757.     /* 000:148 */ "fpcp unordered condition",
  758.     /* 000:149 */ "fpcp inexact result",
  759.     /* 000:150 */ "fpcp divide by zero",
  760.     /* 000:151 */ "fpcp underflow",
  761.     /* 000:152 */ "fpcp operand error",
  762.     /* 000:153 */ "fpcp overflow",
  763.     /* 000:154 */ "fpcp not a number",
  764.     /* 000:155 */ "exception 55",
  765.     /* 000:156 */ "pmmu configuration",
  766.     /* 000:157 */ "pmmu illegal operation",
  767.     /* 000:158 */ "pmmu access level violation",
  768.     /* 000:159 */ "exception 59",
  769.     /* 000:160 */ "exception 60",
  770.     /* 000:161 */ "exception 61",
  771.     /* 000:162 */ "exception 62",
  772.     /* 000:163 */ "exception 63",
  773.     /* 000:164 */ "no permission",
  774.     /* 000:165 */ "arguments to F$ChkNam didn't match",
  775.     /* 000:166 */ "system stack overflow",
  776.     /* 000:167 */ "invalid event ID number",
  777.     /* 000:168 */ "event not found",
  778.     /* 000:169 */ "the event is busy",
  779.     /* 000:170 */ "impossible event parameters",
  780.     /* 000:171 */ "system data structures have been damaged",
  781.     /* 000:172 */ "module revision is incompatable with operating system",
  782.     /* 000:173 */ "path became lost because network node was down",
  783.     /* 000:174 */ "bad disk partition, or no active partition",
  784.           "error 175",
  785.           "error 176",
  786.           "error 177",
  787.           "error 178",
  788.           "error 179",
  789.           "error 180",
  790.           "error 181",
  791.           "error 182",
  792.           "error 183",
  793.           "error 184",
  794.           "error 185",
  795.           "error 186",
  796.           "error 187",
  797.           "error 188",
  798.           "error 189",
  799.           "error 190",
  800.           "error 191",
  801.           "error 192",
  802.           "error 193",
  803.           "error 194",
  804.           "error 195",
  805.           "error 196",
  806.           "error 197",
  807.           "error 198",
  808.           "error 199",
  809.     /* 000:200 */ "the path table is full",
  810.     /* 000:201 */ "bad path number",
  811.     /* 000:202 */ "system IRQ table is full",
  812.     /* 000:203 */ "bad I/O mode",
  813.     /* 000:204 */ "system device table is full",
  814.     /* 000:205 */ "bad module header",
  815.     /* 000:206 */ "system module directory is full",
  816.     /* 000:207 */ "memory full",
  817.     /* 000:208 */ "unknown service code ",
  818.     /* 000:209 */ "non-sharable module is busy",
  819.     /* 000:210 */ "bad page address",
  820.     /* 000:211 */ "end of file",
  821.     /* 000:212 */ "IRQ vector is busy",
  822.     /* 000:213 */ "non-existing segment",
  823.     /* 000:214 */ "file not accessible",
  824.     /* 000:215 */ "bad pathlist",
  825.     /* 000:216 */ "file not found",
  826.     /* 000:217 */ "file segment list is full",
  827.     /* 000:218 */ "creating an existing file",
  828.     /* 000:219 */ "illegal memory block address",
  829.     /* 000:220 */ "modem data carrier lost",
  830.     /* 000:221 */ "module not found",
  831.     /* 000:222 */ "system clock not running",
  832.     /* 000:223 */ "deleting stack memory",
  833.     /* 000:224 */ "illegal process ID",
  834.     /* 000:225 */ "bad IRQ parameter",
  835.     /* 000:226 */ "no children",
  836.     /* 000:227 */ "invalid trap number",
  837.     /* 000:228 */ "process has aborted",
  838.     /* 000:229 */ "system process table is full",
  839.     /* 000:230 */ "illegal fork parameter",
  840.     /* 000:231 */ "known module",
  841.     /* 000:232 */ "bad module CRC",
  842.     /* 000:233 */ "unprocessed signal pending",
  843.     /* 000:234 */ "non executable module",
  844.     /* 000:235 */ "bad name",
  845.     /* 000:236 */ "bad module header parity",
  846.     /* 000:237 */ "no RAM available",
  847.     /* 000:238 */ "directory is not empty",
  848.     /* 000:239 */ "no available task number",
  849.     /* 000:240 */ "illegal unit ( drive ) number",
  850.     /* 000:241 */ "bad sector number",
  851.     /* 000:242 */ "media is write protected",
  852.     /* 000:243 */ "I/O error - bad check sum",
  853.     /* 000:244 */ "read error",
  854.     /* 000:245 */ "write error",
  855.     /* 000:246 */ "device not ready",
  856.     /* 000:247 */ "seek error",
  857.     /* 000:248 */ "media full",
  858.     /* 000:249 */ "incompatable media",
  859.     /* 000:250 */ "device busy",
  860.     /* 000:251 */ "disk media has changed",
  861.     /* 000:252 */ "record is busy",
  862.     /* 000:253 */ "non-sharable file/device is busy",
  863.     /* 000:254 */ "I/O deadlock error",
  864.     /* 000:255 */ "device is format protected",
  865. };
  866.  
  867. perror( s )
  868. register char *s;
  869. {
  870.     if( s && *s )
  871.     {
  872.         fprintf( stderr, "%s: %s\n", s, sys_errlist[errno&0xff] );
  873.     }
  874.     else
  875.     {
  876.         fprintf( stderr, "%s\n", sys_errlist[errno&0xff] );
  877.     }
  878. }
  879.  
  880. /*
  881.  * filesize() returns the size of the file named "pathname"
  882.  */
  883.  
  884. int filesize( pathname )
  885. char *pathname;
  886. {
  887.     int _gs_size();
  888.     int open();
  889.     
  890.     int pathnumber;
  891.     int size;
  892.     
  893.     pathnumber = open( pathname, (short) 0 );
  894.     if( pathnumber < 0 )
  895.         return( -1 );
  896.     size = _gs_size( pathnumber );
  897.     if( size < 0 )
  898.         return( -1 );
  899.     close( pathnumber );
  900.     return( size );
  901. }
  902.  
  903. /*
  904.  * fileage returns a number that represents 
  905.  * the age of the file named by "pathname".
  906.  */
  907.  
  908. int fileage( pathname )
  909. char *pathname;
  910. {
  911.     int open();
  912.     int _gs_gfd();
  913.     
  914.     int pathnumber;
  915.     struct fildes buffer;
  916.     
  917.     int date;
  918.  
  919.     pathnumber = open( pathname, S_IREAD );
  920.     if( pathnumber < 0 )
  921.         return( 0 );
  922.  
  923.     if( _gs_gfd( pathnumber, &buffer, sizeof( buffer ) ) < 0 )
  924.     {
  925.         close( pathnumber );
  926.         return( 0 );
  927.     }
  928.     
  929.     date = (int) buffer.fd_date[0];                        /* year */
  930.     date = ( (int) buffer.fd_date[1] - 1 ) + 12 * date;    /* month */
  931.     date = ( (int) buffer.fd_date[2] - 1 ) + 31 * date;    /* day of month */
  932.     date = (int) buffer.fd_date[3] + 24 * date;            /* hour */
  933.     date = (int) buffer.fd_date[4] + 60 * date;            /* minute */
  934.     return( date );
  935. }
  936.