Annotation of pgp/src/system.c, revision 1.1.1.4

1.1.1.2   root        1: /*
                      2:  * system.c
                      3:  *
                      4:  * Routines specific for non-MSDOS implementations of pgp.
                      5:  * 
                      6:  *     Modified 24-Jun-92 HAJK
                      7:  *     Adapt for VAX/VMS.
                      8:  *
                      9:  *     Modified: 11-Nov-92 HAJK
                     10:  *     Add FDL Support Routines. 
1.1.1.3   root       11:  *
                     12:  *     Modified: 31-Jan-93 HAJK
                     13:  *     Misc. updates for terminal handling.
                     14:  *     Add VMS command stuff.
                     15:  *     Add fileparse routine.
1.1.1.2   root       16:  */
                     17: #include <stdio.h>
1.1.1.3   root       18: #include "exitpgp.h"
                     19: #include "system.h"
                     20: #include "usuals.h"
                     21: 
1.1.1.2   root       22: /*===========================================================================*/
                     23: /*
                     24:  * UNIX
                     25:  */
                     26: 
                     27: #ifdef UNIX
                     28: /*
                     29:  * Define USE_SELECT to use the select() system call to check if
                     30:  * keyboard input is available. Define USE_NBIO to use non-blocking
                     31:  * read(). If you don't define anything the FIONREAD ioctl() command
                     32:  * will be used.
                     33:  *
                     34:  * Define NOTERMIO if you don't have the termios stuff
                     35:  */
                     36: #include <sys/types.h>
                     37: #include <fcntl.h>
                     38: 
                     39: #ifndef        NOTERMIO
                     40: #ifndef SVR2
                     41: #include <termios.h>
                     42: #else
                     43: #include <termio.h>
                     44: #endif /* not SVR2 */
                     45: #else
                     46: #include <sgtty.h>
                     47: #endif
                     48: 
                     49: #ifdef USE_SELECT
                     50: #include <sys/time.h>
1.1.1.3   root       51: #ifdef _IBMR2
                     52: #include <sys/select.h>
                     53: #endif /* _IBMR2 */
1.1.1.2   root       54: #else
                     55: #ifndef USE_NBIO
                     56: #ifndef sun
                     57: #include <sys/ioctl.h>         /* for FIONREAD */
                     58: #else /* including both ioctl.h and termios.h gives a lot of warnings on sun */
                     59: #include <sys/filio.h>
                     60: #endif /* sun */
                     61: #ifndef FIONREAD
                     62: #define        FIONREAD        TIOCINQ
                     63: #endif
                     64: #endif
                     65: #endif
                     66: #include <signal.h>
                     67: 
                     68: static void setsigs(void);
                     69: static void rmsigs(void);
                     70: static void sig1(int);
                     71: static void sig2(int);
                     72: void breakHandler(int);
                     73: static int ttyfd= -1;
                     74: #ifndef SVR2
                     75: static void (*savesig)(int);
                     76: #else
                     77: static int (*savesig)(int);
                     78: #endif
                     79: 
                     80: void ttycbreak(void);
                     81: void ttynorm(void);
                     82: 
1.1.1.3   root       83: #ifndef NEED_KBHIT
                     84: #undef USE_NBIO
                     85: #endif
1.1.1.2   root       86: 
                     87: #ifndef NOTERMIO
                     88: #ifndef SVR2
                     89: static struct termios itio, tio;
                     90: #else
                     91: static struct termio itio, tio;
                     92: #endif /* not SVR2 */
                     93: #else
                     94: static struct sgttyb isg, sg;
                     95: #endif
                     96: 
                     97: #ifdef USE_NBIO
                     98: static int kbuf= -1;   /* buffer to store char read by kbhit() */
                     99: static int fflags;
                    100: #endif
                    101: 
                    102: static int gottio = 0;
                    103: 
                    104: void ttycbreak(void)
                    105: {
                    106:        if (ttyfd == -1) {
                    107:                if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) {
                    108:                    fprintf(stderr, "cannot open tty, using stdin\n");
                    109:                        ttyfd = 0;
                    110:                }
                    111:        }
                    112: #ifndef NOTERMIO
                    113: #ifndef SVR2
                    114:        if (tcgetattr(ttyfd, &tio) < 0)
                    115: #else
                    116:        if (ioctl(ttyfd, TCGETA, &tio) < 0)
                    117: #endif  /* not SVR2 */
                    118:        {       fprintf (stderr, "\nUnable to get terminal characteristics: ");
                    119:                perror("ioctl");
                    120:                exitPGP(1);
                    121:        }
                    122:        itio = tio;
                    123:        setsigs();
                    124:        gottio = 1;
                    125: #ifdef USE_NBIO
                    126:        tio.c_cc[VMIN] = 0;
                    127: #else
                    128:        tio.c_cc[VMIN] = 1;
                    129: #endif
                    130:        tio.c_cc[VTIME] = 0;
                    131:        tio.c_lflag &= ~(ECHO|ICANON);
                    132: #ifndef SVR2
                    133:        tcsetattr (ttyfd, TCSAFLUSH, &tio);
                    134: #else
1.1.1.3   root      135:        ioctl(ttyfd, TCSETAF, &tio);
1.1.1.2   root      136: #endif /* not SVR2 */
                    137: #else
                    138:     if (ioctl(ttyfd, TIOCGETP, &sg) < 0)
                    139:        {       fprintf (stderr, "\nUnable to get terminal characteristics: ");
                    140:                perror("ioctl");
                    141:                exitPGP(1);
                    142:        }
                    143:        isg = sg;
                    144:        setsigs();
                    145:        gottio = 1;
                    146: #ifdef CBREAK
                    147:     sg.sg_flags |= CBREAK;
                    148: #else
                    149:     sg.sg_flags |= RAW;
                    150: #endif
                    151:        sg.sg_flags &= ~ECHO;
                    152:     ioctl(ttyfd, TIOCSETP, &sg);
                    153: #endif /* !NOTERMIO */
                    154: #ifdef USE_NBIO
                    155: #ifndef O_NDELAY
                    156: #define        O_NDELAY        O_NONBLOCK
                    157: #endif
                    158:        if ((fflags = fcntl(ttyfd, F_GETFL, 0)) != -1)
                    159:                fcntl(ttyfd, F_SETFL, fflags|O_NDELAY);
                    160: #endif
                    161: }
                    162: 
                    163: 
                    164: void ttynorm(void)
                    165: {      gottio = 0;
                    166: #ifdef USE_NBIO
                    167:        if (fcntl(ttyfd, F_SETFL, fflags) == -1)
                    168:                perror("fcntl");
                    169: #endif
                    170: #ifndef NOTERMIO
                    171: #ifndef SVR2
                    172:        tcsetattr (ttyfd, TCSAFLUSH, &itio);
                    173: #else
1.1.1.3   root      174:        ioctl(ttyfd, TCSETAF, &itio);
1.1.1.2   root      175: #endif /* not SVR2 */
                    176: #else
                    177:     ioctl(ttyfd, TIOCSETP, &isg);
                    178: #endif
                    179:        rmsigs();
                    180: }
                    181: 
                    182: static void sig1 (int sig)
                    183: {
                    184: #ifndef NOTERMIO
                    185: #ifndef SVR2
                    186:        tcsetattr (ttyfd, TCSANOW, &itio);
                    187: #else
                    188:        ioctl(ttyfd, TCSETAW, &itio);
                    189: #endif /* not SVR2 */
                    190: #else
                    191:     ioctl(ttyfd, TIOCSETP, &isg);
                    192: #endif
                    193:        signal (sig, SIG_DFL);
                    194:        if (sig == SIGINT)
                    195:                breakHandler(SIGINT);
                    196:        kill (getpid(), sig);
                    197: }
                    198: 
                    199: static void sig2 (int sig)
                    200: {      if (gottio)
                    201:                ttycbreak();
                    202:        else
                    203:                setsigs();
                    204: }
                    205: 
                    206: static void setsigs(void)
                    207: {      savesig = signal (SIGINT, sig1);
                    208: #ifdef SIGTSTP
                    209:        signal (SIGCONT, sig2);
                    210:        signal (SIGTSTP, sig1);
                    211: #endif
                    212: }
                    213: 
                    214: static void rmsigs(void)
                    215: {      signal (SIGINT, savesig);
                    216: #ifdef SIGTSTP
                    217:        signal (SIGCONT, SIG_DFL);
                    218:        signal (SIGTSTP, SIG_DFL);
                    219: #endif
                    220: }
                    221: 
1.1.1.3   root      222: #ifdef NEED_KBHIT
1.1.1.2   root      223: #ifndef CRUDE
                    224: int kbhit(void)
                    225: /* Return TRUE if there is a key to be read */
                    226: {
                    227: #ifdef USE_SELECT              /* use select() system call */
                    228:        struct timeval t;
                    229:        fd_set n;
                    230:        int r;
                    231: 
                    232:        timerclear(&t);
                    233:        FD_ZERO(&n);
                    234:        FD_SET(ttyfd, &n);
                    235:        r = select(32, &n, NULL, NULL, &t);
                    236:        if (r == -1) {
                    237:                perror("select");
                    238:                exitPGP(1);
                    239:        }
                    240:        return r > 0;
                    241: #else
                    242: #ifdef USE_NBIO                /* use non-blocking read() */
                    243:        unsigned char ch;
                    244:        if (kbuf >= 0) 
                    245:                return(1);
                    246:        if (read(ttyfd, &ch, 1) == 1) {
                    247:                kbuf = ch;
                    248:                return(1);
                    249:        }
                    250:        return(0);
                    251: #else
                    252:        long lf;
                    253:        if (ioctl(ttyfd, FIONREAD, &lf) == -1) {
                    254:                perror("ioctl: FIONREAD");
                    255:                exitPGP(1);
                    256:        }
                    257:        return(lf);
                    258: #endif
                    259: #endif
                    260: }
                    261: #endif /* !CRUDE */
1.1.1.3   root      262: #endif
1.1.1.2   root      263: 
                    264: int getch(void)
                    265: {
                    266:        char c;
                    267: #ifdef USE_NBIO
                    268:        while (!kbhit());       /* kbhit() does the reading */
                    269:        c = kbuf;
                    270:        kbuf = -1;
                    271: #else
                    272:        read(ttyfd, &c, 1);
                    273: #endif
                    274:        return(c);
                    275: }
                    276: 
1.1.1.3   root      277: #if defined(_BSD) && !defined(__STDC__)
                    278: 
1.1.1.2   root      279: VOID *memset(s, c, n)
                    280: VOID *s;
                    281: register int c, n;
                    282: {
                    283:        register char *p = s;
                    284:        ++n;
                    285:        while (--n)
                    286:                *p++ = c;
                    287:        return(s);
                    288: }
                    289: int memcmp(s1, s2, n)
                    290: register unsigned char *s1, *s2;
                    291: register int n;
                    292: {
                    293:        if (!n)
                    294:                return(0);
                    295:        while (--n && *s1 == *s2) {
                    296:                ++s1;
                    297:                ++s2;
                    298:        }
                    299:        return(*s1 - *s2);
                    300: }
                    301: VOID *memcpy(s1, s2, n)
                    302: register char *s1, *s2;
                    303: register int n;
                    304: {
                    305:        char *p = s1;
                    306:        ++n;
                    307:        while (--n)
                    308:                *s1++ = *s2++;
                    309:        return(p);
                    310: }
1.1.1.3   root      311: #endif /* _BSD */
1.1.1.2   root      312: 
1.1.1.3   root      313: #if (defined(MACH) || defined(SVR2) || defined(_BSD)) && !defined(NEXT)
1.1.1.2   root      314: int remove(name)
                    315: char *name;
                    316: {
                    317:        return unlink(name);
                    318: }
                    319: #endif
                    320: 
                    321: #ifdef SVR2
                    322: int rename(old, new)
                    323: register char *old, *new;
                    324: {
                    325:        unlink(new);
                    326:        if (link(old, new) < 0)
                    327:                return -1;
                    328:        if (unlink(old) < 0) {
                    329:                unlink(new);
                    330:                return -1;
                    331:        }
                    332:        return 0;
                    333: }
                    334: #endif /* SVR2 */
                    335: 
                    336: /* not all unices have clock() */
                    337: long
                    338: Clock()        /* not a replacement for clock(), just for random number generation */
                    339: {
1.1.1.3   root      340: #if defined(_BSD) || defined(sun) || defined(MACH) || defined(linux)
1.1.1.2   root      341: #include <sys/time.h>
                    342: #include <sys/resource.h>
                    343:        struct rusage ru;
                    344: 
                    345:        getrusage(RUSAGE_SELF, &ru);
                    346:        return ru.ru_utime.tv_sec + ru.ru_utime.tv_usec +
                    347:                ru.ru_stime.tv_sec + ru.ru_stime.tv_usec +
                    348:                ru.ru_minflt + ru.ru_majflt +
                    349:                ru.ru_inblock + ru.ru_oublock +
                    350:                ru.ru_maxrss + ru.ru_nvcsw + ru.ru_nivcsw;
                    351: 
                    352: #else  /* no getrusage() */
                    353: #include <sys/times.h>
                    354:        struct tms tms;
                    355: 
                    356:        times(&tms);
                    357:        return(tms.tms_utime + tms.tms_stime);
                    358: #endif
                    359: }
                    360: #endif /* UNIX */
                    361: 
                    362: 
                    363: /*===========================================================================*/
                    364: /*
                    365:  * VMS
                    366:  */
                    367: 
                    368: #ifdef VMS                     /* kbhit()/getch() equivalent */
                    369: 
                    370: /*
                    371:  * This code defines an equivalent version of kbhit() and getch() for
                    372:  * use under VAX/VMS, together with an exit handler to reset terminal
                    373:  * characteristics.
                    374:  *
                    375:  * This code assumes that kbhit() has been invoked to test that there
                    376:  * are characters in the typeahead buffer before getch() is invoked to
                    377:  * get the answer.
                    378:  */
                    379: 
1.1.1.3   root      380: #include <signal.h>
                    381: #include <string.h>
                    382: #include <file.h>
                    383: #include <ctype.h>
                    384: #include "pgp.h"
                    385: #include "mpilib.h"
                    386: #include "mpiio.h"
                    387: #include "fileio.h"
                    388: extern byte textbuf[DISKBUFSIZE];   /* Defined in FILEIO.C */
                    389: 
                    390: /*       
                    391: **  VMS Private Macros
                    392: */       
1.1.1.2   root      393: #include <descrip.h>
                    394: #include <devdef>
                    395: #include <iodef.h>
                    396: #include <ttdef.h>
                    397: #include <tt2def.h>
                    398: #include <dcdef.h>
1.1.1.3   root      399: #include <climsgdef.h>
1.1.1.2   root      400: #include <rms.h>
1.1.1.3   root      401: #include <hlpdef.h>
                    402: 
                    403: #define MAX_CMDSIZ     256  /*  Maximum command size */
                    404: #define MAX_FILENM     255 /* Mamimum file name size */
1.1.1.2   root      405: 
                    406: #define FDL$M_FDL_STRING    2          /* Use string for fdl text */
                    407: #define FDLSIZE                    4096        /* Maximum possible file size */
                    408: 
1.1.1.3   root      409: #ifdef _USEDCL_
                    410: 
                    411: /*
                    412:  * Declare some external procedure prototypes (saves me confusion!)
                    413:  */
                    414: extern int lib$get_input(
                    415:            struct dsc$descriptor *resultant,
                    416:            struct dsc$descriptor *prompt, 
                    417:            unsigned short *resultant_length);
                    418: extern int lib$put_output(
                    419:            struct dsc$descriptor *output);
                    420: extern int lib$sig_to_ret();
                    421: /*       
                    422: **  The CLI routines are documented in the system routines manual.
                    423: */       
                    424: extern int cli$dcl_parse(
                    425:            struct dsc$descriptor *command,
                    426:            char cmd_table[],
                    427:            int (*get_command)(
                    428:                struct dsc$descriptor *resultant,
                    429:                struct dsc$descriptor *prompt, 
                    430:                unsigned short *resultant_length),
                    431:            int (*get_parameter)(
                    432:                struct dsc$descriptor *resultant,
                    433:                struct dsc$descriptor *prompt, 
                    434:                unsigned short *resultant_length),
                    435:            struct dsc$descriptor *prompt);
                    436: extern int cli$present( struct dsc$descriptor *object);
                    437: extern int cli$_get_value(
                    438:            struct dsc$descriptor *object,
                    439:            struct dsc$decsriptor *value,
                    440:            unsigned short *value_len);
                    441: /*
                    442:  * Static Data
                    443:  */
                    444: static $DESCRIPTOR (cmdprmt_d, "DROPSAFE> ");  /*  Prompt string */
                    445: 
1.1.1.4 ! root      446: #endif /* _USEDCL_ */
1.1.1.3   root      447: 
1.1.1.2   root      448: static volatile short  _kbhitChan_ = 0;
                    449: 
                    450: static volatile struct IOSB {
                    451:        unsigned short sts;
                    452:        unsigned short byteCount;
                    453:        unsigned short terminator;
                    454:        unsigned short terminatorSize;
                    455:        } iosb;
                    456: 
                    457: static $DESCRIPTOR (kbdev_desc, "SYS$COMMAND:");
                    458: 
                    459: static volatile struct {
                    460:        char Class;
                    461:        char Type;
                    462:        unsigned short BufferSize;
                    463:        unsigned int Mode;
                    464:        int ExtChar;
                    465:   } CharBuf, OldCharBuf;
                    466: 
                    467: static $DESCRIPTOR (out_file_descr, "SYS$DISK:[]"); /* Default Output File Descr */
                    468: 
                    469: static int flags = FDL$M_FDL_STRING;
                    470: 
1.1.1.3   root      471: /*
1.1.1.2   root      472:  * **-kbhit_handler-This exit handler restores the terminal characteristics
                    473:  *
                    474:  * Description:
                    475:  *
                    476:  * This procedure is invoked to return the the terminal to normality (depends
                    477:  * on what you think is normal!). Anyway, it gets called to restore
                    478:  * characteristics either through ttynorm or via an exit handler.
                    479:  */
1.1.1.3   root      480: static void kbhit_handler(int *sts)
1.1.1.2   root      481: {
1.1.1.3   root      482:   ttynorm();
1.1.1.2   root      483:   (void) sys$dassgn (
                    484:          _kbhitChan_);
                    485:   _kbhitChan_ = 0;
                    486: }
                    487: 
1.1.1.3   root      488: /*
                    489:  * Data Structures For Linking Up Exit Handler 
                    490:  */
1.1.1.2   root      491: unsigned int exsts;
                    492: 
                    493: static struct {
                    494:        int link;
1.1.1.4 ! root      495:        VOID *rtn;
1.1.1.2   root      496:        int argcnt;
                    497:        int *stsaddr;
                    498:    } exhblk = { 0, &(kbhit_handler), 1, &(exsts)};
1.1.1.3   root      499: /*
                    500:  * **-kbhit_Getchn-Get Channel
                    501:  *
                    502:  * Functional Description:
                    503:  *
                    504:  * Private routine to get a terminal channel and save the terminal
                    505:  * characteristics.
                    506:  *
                    507:  * Arguments:
                    508:  *
                    509:  *  None.
                    510:  *
                    511:  * Returns:
                    512:  *
                    513:  *  If 0, channel already assigned. If odd, then assign was successful
                    514:  * otherwise returns VMS error status.
                    515:  *
                    516:  * Implicit Inputs:
                    517:  *
                    518:  * _kbhitChan_ Channel assigned to the terminal (if any).
                    519:  *
                    520:  * Implicit Outputs:
                    521:  *
                    522:  *  OldCharBuf Initial terminal characteristics.
                    523:  *  _kbhitChan_        Channel assigned to the terminal.
                    524:  *
                    525:  * Side Effects:
                    526:  *
                    527:  *  Establishes an exit handler to restore characteristics and deassign
                    528:  * terminal channel.
                    529:  */
                    530: static int kbhit_Getchn()
                    531: {
                    532:     int sts = 0;
1.1.1.2   root      533: 
1.1.1.3   root      534:     if (_kbhitChan_ == 0) {
                    535:        if ((sts = sys$assign (
                    536:                           &kbdev_desc,
                    537:                           &_kbhitChan_,
                    538:                           0,
                    539:                           0)) & 1) {
                    540:            if ((sts = sys$qiow (
                    541:                               0,
                    542:                               _kbhitChan_,
                    543:                               IO$_SENSEMODE,
                    544:                               &iosb,
                    545:                               0,
                    546:                               0,
                    547:                               &OldCharBuf,
                    548:                               12,
                    549:                               0,
                    550:                               0,
                    551:                               0,
                    552:                               0)) & 01) sts = iosb.sts;
                    553:            if (sts & 01) {
                    554:              if (!(OldCharBuf.Class & DC$_TERM)) {
                    555:                fprintf(stderr,"\nNot running on a terminal");
                    556:                exitPGP(1);
                    557:              }
                    558:              (void) sys$dclexh (&exhblk);
                    559:            }
                    560:        }
                    561:     }
                    562:     return(sts);
                    563: }
                    564: /*       
                    565:  * **-ttynorm-Restore initial terminal characteristics
                    566:  *
                    567:  * Functional Description:
                    568:  *
                    569:  * This procedure is invoked to restore the initial terminal characteristics.
                    570:  */
                    571: void ttynorm()
1.1.1.2   root      572: /*
1.1.1.3   root      573:  * Arguments:
                    574:  *
                    575:  *  None.
                    576:  *
                    577:  * Implicit Inputs:
                    578:  *
                    579:  *  OldCharBuf Initial terminal characteristics.
                    580:  *  _kbhitChan_        Channel assigned to the terminal.
                    581:  *
                    582:  * Implicit Outputs:
                    583:  *
                    584:  *  None.
                    585:  */      
                    586: {
                    587:   int sts;
                    588: 
                    589:   if (_kbhitChan_ != 0) {
                    590:       CharBuf.Mode = OldCharBuf.Mode;
                    591:       CharBuf.ExtChar = OldCharBuf.ExtChar;
                    592:     /*
                    593:       CharBuf.Mode &= ~TT$M_NOECHO;
                    594:       CharBuf.ExtChar &= ~TT2$M_PASTHRU;
                    595:     */
                    596:       if ((sts = sys$qiow (
                    597:                               0,
                    598:                               _kbhitChan_,
                    599:                               IO$_SETMODE,
                    600:                               &iosb,
                    601:                               0,
                    602:                               0,
                    603:                               &OldCharBuf,
                    604:                               12,
                    605:                               0,
                    606:                               0,
                    607:                               0,
                    608:                               0)) & 01) sts = iosb.sts;
                    609:       if (!(sts & 01)) {
                    610:            fprintf(stderr,"\nFailed to reset terminal characteristics!");
                    611:            (void) lib$signal(sts);
                    612:       }
                    613:    }
                    614:    return;
                    615: }
                    616: /*
1.1.1.2   root      617:  * **-kbhit-Find out if a key has been pressed
                    618:  *
                    619:  * Description:
                    620:  *
                    621:  * Make the terminal noecho and sense the characters coming in by looking at
1.1.1.3   root      622:  * the typeahead count. Note that the character remains in the typeahead buffer
                    623:  * untill either read, or that the user types a Control-X when not in 'passall'
                    624:  * mode.
1.1.1.2   root      625:  */
                    626: int kbhit()
1.1.1.3   root      627: /*
                    628:  * Arguments:
                    629:  *
                    630:  *  None.
                    631:  *
                    632:  * Returns:
                    633:  *
                    634:  *  TRUE  if there is a character in the typeahead buffer.
                    635:  *  FALSE if there is no character in the typeahead buffer.
                    636:  */
                    637: 
                    638: 
1.1.1.2   root      639: {
1.1.1.3   root      640:   int sts;
1.1.1.2   root      641: 
                    642:   struct {
                    643:        unsigned short TypAhdCnt;
                    644:        char FirstChar;
                    645:        char Reserved[5];
                    646:   } TypCharBuf;
                    647: 
                    648:   /*
                    649:   **  Get typeahead count
                    650:   */
                    651:   if ((sts = sys$qiow (
                    652:                           0,
                    653:                           _kbhitChan_,
                    654:                           IO$_SENSEMODE | IO$M_TYPEAHDCNT,
                    655:                           &iosb,
                    656:                           0,
                    657:                           0,
                    658:                           &TypCharBuf,
                    659:                           8,
                    660:                           0,
                    661:                           0,
                    662:                           0,
                    663:                           0)) & 01) sts = iosb.sts;
                    664:   if (sts & 01) return(TypCharBuf.TypAhdCnt>0);
                    665:   (void) lib$signal(sts);
                    666:   exitPGP(1);
                    667: }
                    668: 
1.1.1.3   root      669: static int NoTerm[2] = { 0, 0};  /*  TT Terminator Mask (Nothing) */
                    670: 
1.1.1.2   root      671: /*
                    672:  * **-getch-Get a character and return it
                    673:  *
                    674:  * Description:
                    675:  *
1.1.1.3   root      676:  * Get a character from the keyboard and return it. Unlike Unix, the character
                    677:  * will be explicitly echoed unless ttycbreak() has been called first. If the
                    678:  * character is in the typeahead, that will be read first.
1.1.1.2   root      679:  */
                    680: int getch()
1.1.1.3   root      681: /*
                    682:  * Arguments:
                    683:  *
                    684:  *  None.
                    685:  *
                    686:  * Returns:
                    687:  *
                    688:  *  Character Read.
                    689:  */
1.1.1.2   root      690: {
                    691:   unsigned int sts;
                    692:   volatile char CharBuf;
                    693: 
1.1.1.3   root      694:   if (((sts = kbhit_Getchn()) & 01) || sts == 0) {
                    695:       if ((sts = sys$qiow (
                    696:                              0,
                    697:                              _kbhitChan_,
                    698:                              IO$_READVBLK,
                    699:                              &iosb,
                    700:                              0,
                    701:                              0,
                    702:                              &CharBuf,
                    703:                              1,
                    704:                              0,
                    705:                              &NoTerm,
                    706:                              0,
                    707:                              0)) & 01) sts = iosb.sts;
                    708:   }
1.1.1.2   root      709:   if (sts & 01) return ((int) CharBuf);
                    710:   fprintf(stderr,"\nFailed to get character");
                    711:   (void) lib$signal(sts);
                    712: }
1.1.1.3   root      713: /*
                    714:  * **-putch-Put Character To 'Console' Device
                    715:  *
                    716:  * This procedure is a companion to getch, outputing a character to the
                    717:  * terminal with a minimum of fuss (no VAXCRTLK, no RMS!). This routine
                    718:  * simply gets a channel (if there isn't one already and uses QIO to
                    719:  * output.
                    720:  *
                    721:  */
                    722: int putch(int chr)
                    723: /*
                    724:  * Arguments:
                    725:  *  chr                Character to output.
                    726:  *
                    727:  * Returns:
                    728:  *
                    729:  *  Status return from Getchn and qio.
                    730:  *
                    731:  * Side Effects
                    732:  *
                    733:  * May assign a channel to the terminal.
                    734:  */
1.1.1.2   root      735: {
1.1.1.3   root      736:   unsigned int sts;
1.1.1.2   root      737: 
1.1.1.3   root      738:   if (((sts = kbhit_Getchn()) & 01) || sts == 0) {
                    739:       if ((sts = sys$qiow (
                    740:                              0,
                    741:                              _kbhitChan_,
                    742:                              IO$_WRITEVBLK,
                    743:                              &iosb,
                    744:                              0,
                    745:                              0,
                    746:                              &chr,
                    747:                              1,
                    748:                              0,
                    749:                              0,
                    750:                              0,
                    751:                              0)) & 01) sts = iosb.sts;
1.1.1.2   root      752:   }
1.1.1.3   root      753:   if (sts & 01) return (sts);
                    754:   fprintf(stderr,"\nFailed to put character");
                    755:   (void) lib$signal(sts);
1.1.1.2   root      756: }
1.1.1.3   root      757: /*
                    758:  * **-ttycbreak-Set Unix-like Cbreak mode
                    759:  *
                    760:  * Functional Description:
                    761:  *
                    762:  * This code must be invoked to produce the Unix-like cbreak operation which
                    763:  * disables echo, allows control character input.
                    764:  */
1.1.1.2   root      765: void ttycbreak ()
1.1.1.3   root      766: /*
                    767:  * Arguments:
                    768:  *
                    769:  *  None.
                    770:  *
                    771:  * Returns:
                    772:  *
                    773:  *  None.
                    774:  *
                    775:  * Side Effects
                    776:  *
                    777:  * May assign a channel to the terminal.
                    778:  */
                    779: {
                    780:     struct {
                    781:        unsigned short TypAhdCnt;
                    782:        char FirstChar;
                    783:        char Reserved[5];
                    784:     } TypCharBuf;
                    785:     char buf[80];
                    786:     int sts;
                    787: 
                    788:     if (((sts = kbhit_Getchn()) & 01) || sts == 0) {
                    789: /*
                    790:  * Flush any typeahead before we change characteristics
                    791:  */
                    792:        if ((sts = sys$qiow (
                    793:                               0,
                    794:                               _kbhitChan_,
                    795:                               IO$_SENSEMODE | IO$M_TYPEAHDCNT,
                    796:                               &iosb,
                    797:                               0,
                    798:                               0,
                    799:                               &TypCharBuf,
                    800:                               8,
                    801:                               0,
                    802:                               0,
                    803:                               0,
                    804:                               0)) & 01) sts = iosb.sts;
                    805:        if (sts) {
                    806:            if (TypCharBuf.TypAhdCnt>0) {
                    807:                if ((sts = sys$qiow (
                    808:                            0,
                    809:                           _kbhitChan_,
                    810:                           IO$_READVBLK | IO$M_NOECHO | IO$M_TIMED,
                    811:                           &iosb,
                    812:                           0,
                    813:                           0,
                    814:                           &buf,
                    815:                           (TypCharBuf.TypAhdCnt >= 80 ? 80 : TypCharBuf.TypAhdCnt),
                    816:                           1,
                    817:                           &NoTerm,
                    818:                           0,
                    819:                           0)) & 01) sts = iosb.sts;
                    820:                           
                    821:                if (sts)
                    822:                    TypCharBuf.TypAhdCnt -= iosb.byteCount;
                    823:            }
                    824:        }
                    825:        if (!(sts & 01)) TypCharBuf.TypAhdCnt = 0;
                    826: /*
                    827:  * Modify characteristics
                    828:  */
                    829:        CharBuf = OldCharBuf;
                    830:        CharBuf.Mode = (OldCharBuf.Mode | TT$M_NOECHO) & ~TT$M_NOTYPEAHD;
                    831:        CharBuf.ExtChar = OldCharBuf.ExtChar | TT2$M_PASTHRU;
                    832:        if ((sts = sys$qiow (
                    833:                       0,
                    834:                       _kbhitChan_,
                    835:                       IO$_SETMODE,
                    836:                       &iosb,
                    837:                       0,
                    838:                       0,
                    839:                       &CharBuf,
                    840:                       12,
                    841:                       0,
                    842:                       0,
                    843:                       0,
                    844:                       0)) & 01) sts = iosb.sts;
                    845:        if (!(sts & 01)) {
                    846:          fprintf(stderr,"\nttybreak()- Failed to set terminal characteristics!");
                    847:          (void) lib$signal(sts);
                    848:          exitPGP(1);
                    849:        }
                    850:     }
                    851: }
                    852: 
                    853: 
                    854: #ifdef _USEDCL_
                    855: 
                    856: /*
                    857:  * **-vms_getcmd-Get VMS Style Foreign Command
                    858:  *
                    859:  * Functional Description:
                    860:  *
                    861:  *  Get command from VAX/VMS foreign command line interface and parse
                    862:  * according to DCL rules. If the command line is ok, it can then be
                    863:  * parsed according to the rules in the DCL command language table.
                    864:  *
                    865:  */
                    866: int vms_GetCmd( char *cmdtbl)
                    867: /*
                    868:  * Arguments:
                    869:  *
                    870:  *  cmdtbl     Pointer to command table to parse.
                    871:  *
                    872:  * Returns:
                    873:  *
                    874:  *  ...TBS...
                    875:  *
                    876:  * Implicit Inputs:
                    877:  *
                    878:  *  Command language table defined in DROPDCL.CLD
                    879:  */
                    880: {
                    881:     int sts;
                    882:     char cmdbuf[MAX_CMDSIZ];
                    883:     unsigned short cmdsiz;
                    884:     struct dsc$descriptor cmdbuf_d = {0,0,0,0};
                    885:     struct dsc$descriptor infile_d = {0,0,0,0};
                    886:     char filenm[MAX_FILENM];
                    887:     unsigned short filenmsiz;
                    888:     unsigned short verb_size;
                    889: 
                    890:     /*   
                    891:     **  DCL Parse Expects A Command Verb Prefixing The Argumnents
                    892:     ** fake it!
                    893:     */   
                    894:     verb_size = cmdprmt_d.dsc$w_length - 2;  /*  Loose '> ' characters */
                    895:     cmdbuf_d.dsc$w_length = MAX_CMDSIZ-verb_size-1;
                    896:     cmdbuf_d.dsc$a_pointer = strncpy(cmdbuf,cmdprmt_d.dsc$a_pointer,verb_size) +
                    897:        verb_size+1;
                    898:     cmdbuf[verb_size++]=' ';
                    899:     if ((sts = lib$get_foreign (  /*  Recover command line from DCL */
                    900:                   &cmdbuf_d, 
                    901:                   0, 
                    902:                   &cmdsiz, 
                    903:                   0)) & 01) {
                    904:        cmdbuf_d.dsc$a_pointer = cmdbuf;
                    905:        cmdbuf_d.dsc$w_length = cmdsiz + verb_size;
                    906:        VAXC$ESTABLISH(lib$sig_to_ret);   /*  Force unhandled exceptions to return */
                    907:         sts = cli$dcl_parse(  /*  Parse Command Line */
                    908:                    &cmdbuf_d,
                    909:                    cmdtbl,                     
                    910:                    lib$get_input,
                    911:                    lib$get_input,
                    912:                    &cmdprmt_d);
                    913:     }
                    914:     return(sts);
                    915: }
                    916: /*
                    917:  * **-vms_TstOpt-Test for command qualifier present
                    918:  *
                    919:  * Functional Description:
                    920:  *
                    921:  * This procedure is invoked to test whether an option is present. It is
                    922:  * really just a jacket routine for the system routine CLI$PRESENT
                    923:  * converting the argument and result into 'C' speak.
                    924:  *
                    925:  */
                    926: vms_TstOpt(char opt)
                    927: /*
                    928:  * Arguments:
                    929:  *
                    930:  *  opt            Character label of qualifier to test for.
                    931:  *
                    932:  * Returns:
                    933:  *
                    934:  *  +1 Option present.
                    935:  *  0  Option absent.
                    936:  *  -1 Option negated.
                    937:  *
                    938:  * Implicit Inputs:
                    939:  *
                    940:  * Uses DCL command line context established by vms_GetOpt.
                    941:  */
                    942: {
                    943:     int sts;
                    944:     char buf;
                    945:     struct dsc$descriptor option_d = { 1, 0, 0, &buf};
                    946: 
                    947:     buf = _toupper(opt);
                    948:     VAXC$ESTABLISH(lib$sig_to_ret);   /*  Force unhandled exceptions to return */
                    949:     switch (sts=cli$present(&option_d))
                    950:     {
                    951: 
                    952:        case CLI$_PRESENT :
                    953:            return(1);
                    954:        case CLI$_ABSENT:
                    955:            return(0);
                    956:        case CLI$_NEGATED:
                    957:            return(-1);
                    958:        default:
                    959:            return(0);
                    960:     }    
                    961: }
                    962: /*
                    963:  * **-vms_GetVal-Get Qualifier Value.
                    964:  *
                    965:  * Functional Description:
                    966:  *
                    967:  * This procedure is invoked to return the value associated with a
                    968:  * qualifier that exists (See TstOpt).
                    969:  */
                    970: vms_GetVal( char opt, char *resval, unsigned short maxsiz)
                    971: /*
                    972:  * Arguments:
                    973:  *
                    974:  *  opt            Character label of qualifier to test for.
                    975:  *  resval  Pointer to resulting value string.
                    976:  *  maxsiz  Maximum size of string.
                    977:  *
                    978:  * Returns:
                    979:  *
                    980:  *  ...TBS...
                    981:  *
                    982:  * Implicit Inputs:
                    983:  *
                    984:  * Uses DCL command line context established by vms_GetOpt.
                    985:  */
                    986: {
                    987:     int sts;
                    988:     char buf;
                    989:     struct dsc$descriptor option_d = { 1, 0, 0, &buf};
                    990:     struct dsc$descriptor value_d = {maxsiz-1, 0, 0, resval };
                    991:     unsigned short valsiz;
                    992: 
                    993:     VAXC$ESTABLISH(lib$sig_to_ret);   /*  Force unhandled exceptions to return */
                    994:     buf = _toupper(opt);
                    995:     if ((sts = cli$get_value( 
                    996:            &option_d,
                    997:            &value_d,
                    998:            &valsiz)) & 01) resval[valsiz] = '\0';
                    999:     return(sts);
                   1000: }
                   1001: /*
                   1002:  * **-vms_GetArg-Get Argument Value.
                   1003:  *
                   1004:  * Functional Description:
                   1005:  *
                   1006:  * This procedure is invoked to return the value associated with an
                   1007:  * argument.
                   1008:  */
                   1009: vms_GetArg( unsigned short arg, char *resval, unsigned short maxsiz)
                   1010: /*
                   1011:  * Arguments:
                   1012:  *
                   1013:  *  arg            Argument Number (1-9)
                   1014:  *  resval  Pointer to resulting value string.
                   1015:  *  maxsiz  Maximum size of string.
                   1016:  *
                   1017:  * Returns:
                   1018:  *
                   1019:  *  ...TBS...
                   1020:  *
                   1021:  * Implicit Inputs:
                   1022:  *
                   1023:  * Uses DCL command line context established by vms_GetOpt.
                   1024:  */
1.1.1.2   root     1025: {
1.1.1.3   root     1026:     int sts;
                   1027:     char buf[2] = "P";
                   1028:     struct dsc$descriptor option_d = { 2, 0, 0, buf};
                   1029:     struct dsc$descriptor value_d = {maxsiz-1, 0, 0, resval };
                   1030:     unsigned short valsiz;
                   1031: 
                   1032:     VAXC$ESTABLISH(lib$sig_to_ret);   /*  Force unhandled exceptions to return */
                   1033:     buf[1] = arg + '0';
                   1034:     if ((sts = cli$present(&option_d)) & 01) {
                   1035:        if ((sts = cli$get_value( 
                   1036:            &option_d,
                   1037:            &value_d,
                   1038:            &valsiz)) & 01) resval[valsiz] = '\0';
                   1039:     } else return(0);
                   1040:     return(sts);
1.1.1.2   root     1041: }
1.1.1.3   root     1042: 
                   1043: 
1.1.1.2   root     1044: 
1.1.1.3   root     1045: /*
                   1046:  * **-do_help-Invoke VMS Help Processor
                   1047:  *
                   1048:  * Functional Description:
                   1049:  *
                   1050:  * This procedure is invoked to display a suitable help message to the caller
                   1051:  * using the standard VMS help library.
                   1052:  *
                   1053:  */
                   1054: do_help(char *helptext, char *helplib)
                   1055: /*
                   1056:  * Arguments:
                   1057:  *
                   1058:  *  helptext   Text of help request.
                   1059:  *  helplib    Help library.
                   1060:  *
                   1061:  * Returns:
                   1062:  *
                   1063:  * As for kbhit_Getchn and lbr$output_help.
                   1064:  *
                   1065:  * Side Effects:
                   1066:  *
                   1067:  * A channel may be opened to the terminal. A library is opened.
                   1068:  */
                   1069: {
                   1070:     int sts;
                   1071:     int helpflags;
                   1072:     struct dsc$descriptor helptext_d = { strlen(helptext), 0, 0, helptext};
                   1073:     struct dsc$descriptor helplib_d = { strlen(helplib), 0, 0, helplib};
                   1074: 
                   1075:     VAXC$ESTABLISH(lib$sig_to_ret);   /*  Force unhandled exceptions to return */
                   1076:     if (((sts = kbhit_Getchn()) & 01) || sts == 0) {
                   1077:        helpflags = HLP$M_PROMPT|HLP$M_SYSTEM|HLP$M_GROUP|HLP$M_PROCESS;    
                   1078:        sts = lbr$output_help(
                   1079:                    lib$put_output,
                   1080:                    &OldCharBuf.BufferSize,
                   1081:                    &helptext_d,
                   1082:                    &helplib_d,
                   1083:                    &helpflags,
                   1084:                    lib$get_input);
                   1085:     }
                   1086:     return(sts);
                   1087: }
                   1088: #endif /* _USEDCL_ */
                   1089: unsigned long vms_clock_bits[2];      /* VMS Hardware Clock */
1.1.1.2   root     1090: const long     vms_ticks_per_update = 100000L; /* Clock update int. */
                   1091: 
                   1092: /*
                   1093:  * FDL Stuff For Getting & Setting File Characteristics
                   1094:  * This code was derived (loosely!) from the module LZVIO.C in the public 
                   1095:  * domain LZW compress routine as found on the DECUS VAX SIG tapes (no author
                   1096:  * given, so no credits!) 
                   1097:  */
                   1098: 
                   1099: /*
                   1100:  * **-fdl_generate-Generate An FDL
                   1101:  *
                   1102:  * Description:
                   1103:  *
                   1104:  * This procedure takes the name of an existing file as input and creates
                   1105:  * an fdl. The FDL is retuned by pointer and length. The FDL space should be
                   1106:  * released after use with a call to free();
                   1107:  */
                   1108: int fdl_generate(char *in_file, char **fdl, short *len)
                   1109: /*
                   1110:  * Arguments:
                   1111:  *
                   1112:  *     in_file     char*   Filename of file to examine (Zero terminated).
                   1113:  *
                   1114:  *     fdl         char*   Pointer to FDL that was created.
                   1115:  *
                   1116:  *     len         short   Length of FDL created.
                   1117:  *
                   1118:  * Status Returns:
                   1119:  *
                   1120:  * VMS style. lower bit set means success.
                   1121:  */
                   1122: {
                   1123: 
                   1124:     struct dsc$descriptor fdl_descr = { 0,
                   1125:                                DSC$K_DTYPE_T,
                   1126:                                DSC$K_CLASS_D,
                   1127:                                0};
                   1128:     struct FAB fab, *fab_addr;
                   1129:     struct RAB rab, *rab_addr;
                   1130:     struct NAM nam;
                   1131:     struct XABFHC xab;
                   1132:     int sts;
                   1133:     int badblk;
                   1134: 
                   1135: /*
                   1136:  * Build FDL Descriptor
                   1137:  */
                   1138:     if (!(sts = str$get1_dx(&FDLSIZE,&fdl_descr)) & 01) return(0);
                   1139: /*
                   1140:  * Build RMS Data Structures
                   1141:  */
                   1142:     fab = cc$rms_fab;
                   1143:     fab_addr = &fab;
                   1144:     nam = cc$rms_nam;
                   1145:     rab = cc$rms_rab;
                   1146:     rab_addr = &rab;
                   1147:     xab = cc$rms_xabfhc;
                   1148:     fab.fab$l_nam = &nam;
                   1149:     fab.fab$l_xab = &xab;
                   1150:     fab.fab$l_fna = in_file;
                   1151:     fab.fab$b_fns = strlen(in_file);
                   1152:     rab.rab$l_fab = &fab;
                   1153:     fab.fab$b_fac = FAB$M_GET | FAB$M_BIO; /* This open block mode only */
                   1154: /*
                   1155:  * Attempt to Open File
                   1156:  */
                   1157:     if (!((sts = sys$open(&fab)) & 01)) {
                   1158:        if (verbose) {
                   1159:            fprintf(stderr,"\n(SYSTEM) Failed to $OPEN %s\n",in_file);
                   1160:            (void) lib$signal(fab.fab$l_sts,fab.fab$l_stv);
                   1161:        }
                   1162:        return(sts);
                   1163:     }
                   1164:     if (fab.fab$l_dev & DEV$M_REC) {
                   1165:        fprintf(stderr,"\n(SYSTEM) Attempt to read from output only device\n");
                   1166:        sts = 0;
                   1167:     } else {
                   1168:        rab.rab$l_rop = RAB$M_BIO;
                   1169:        if (!((sts = sys$connect(&rab)) & 01)) {
                   1170:            if (verbose) {
                   1171:                fprintf(stderr,"\n(SYSTEM) Failed to $CONNECT %s\n",in_file);
                   1172:                (void) lib$signal(fab.fab$l_sts,fab.fab$l_stv);
                   1173:            }
                   1174:        } else {
                   1175:            if (!((sts = fdl$generate(
                   1176:                        &flags,
                   1177:                        &fab_addr,
                   1178:                        &rab_addr,
                   1179:                        NULL,NULL,
                   1180:                        &fdl_descr,
                   1181:                        &badblk,
                   1182:                        len)) & 01)) {
                   1183:                if (verbose)
                   1184:                    fprintf(stderr,"\n(SYSTEM) Failed to generate FDL\n",in_file);
                   1185:                free(fdl);
                   1186:            } else {
                   1187:                if (!(*fdl = malloc(*len))) return(0);
                   1188:                memcpy(*fdl,fdl_descr.dsc$a_pointer,*len);
                   1189:            }
                   1190:            (void) str$free1_dx(&fdl_descr);
                   1191:        }
                   1192:         sys$close(&fab);
                   1193:     }
                   1194:     return(sts);           
                   1195: }
                   1196: 
                   1197: /*       
                   1198:  * **-fdl_close-Closes files created by fdl_generate
                   1199:  *  
                   1200:  * Description:
                   1201:  *
                   1202:  * This procedure is invoked to close the file and release the data structures
                   1203:  * allocated by fdl$parse.
                   1204:  */
                   1205: void fdl_close(void* rab)
                   1206: /*
                   1207:  * Arguments:
                   1208:  *
1.1.1.4 ! root     1209:  *     rab     VOID *  Pointer to RAB (voided to avoid problems for caller).
1.1.1.2   root     1210:  *
                   1211:  * Returns:
                   1212:  *
                   1213:  *     None.
                   1214:  */
                   1215: {
                   1216:     struct FAB *fab;
                   1217: 
                   1218:     fab = ((struct RAB *) rab)->rab$l_fab;
                   1219:     if (fab) {  /*  Close file if not already closed */
                   1220:        if (fab->fab$w_ifi) sys$close(fab);
                   1221:     }
                   1222:     fdl$release( NULL, &rab);    
                   1223: }
                   1224: 
                   1225: /*
                   1226:  * **-fdl_create-Create A File Using the recorded FDL (hope we get it right!)
                   1227:  *
                   1228:  * Description:
                   1229:  *
                   1230:  * This procedure accepts an FDL and uses it create a file. Unfortunately
                   1231:  * there is no way we can easily patch into the back of the VAX C I/O
                   1232:  * subsystem.
                   1233:  */
1.1.1.4 ! root     1234: VOID * fdl_create( char *fdl, short len, char *outfile, char *preserved_name)
1.1.1.2   root     1235: /*
                   1236:  * Arguments:
                   1237:  *
                   1238:  *     fdl     char*   FDL string descriptor.
                   1239:  *
                   1240:  *     len     short   Returned string length.
                   1241:  *
                   1242:  *     outfile char*   Output filename.
                   1243:  *
                   1244:  *     preserved_name char*    Name from FDL.
                   1245:  *
                   1246:  * Returns:
                   1247:  *
                   1248:  *     0 in case of error, or otherwise the RAB pointer.
                   1249:  */
                   1250: {
1.1.1.4 ! root     1251:     VOID *sts;
1.1.1.2   root     1252:     int sts2;
                   1253:     struct FAB *fab;
                   1254:     struct RAB *rab;
                   1255:     struct NAM nam;
                   1256:     int badblk;
                   1257:     char *resnam;
                   1258: 
                   1259:     struct dsc$descriptor fdl_descr = {
                   1260:                            len,
                   1261:                            DSC$K_DTYPE_T,
                   1262:                            DSC$K_CLASS_S,
                   1263:                            fdl
                   1264:                            };
                   1265: 
                   1266:     sts = NULL;
                   1267: /*
                   1268:  * Initialize RMS NAM Block
                   1269:  */
                   1270:     nam = cc$rms_nam;
1.1.1.3   root     1271:     nam.nam$b_rss = NAM$C_MAXRSSLCL;
                   1272:     nam.nam$b_ess = NAM$C_MAXRSSLCL;
                   1273:     if (!(resnam = nam.nam$l_esa = malloc(NAM$C_MAXRSSLCL+1))) {
1.1.1.2   root     1274:        fprintf(stderr,"\n(FDL_CREATE) Out of memory!\n");
                   1275:        return(NULL);
                   1276:     }
                   1277: /*
                   1278:  * Parse FDL
                   1279:  */
                   1280:     if (!((sts2 = fdl$parse( &fdl_descr,
                   1281:                                &fab,
                   1282:                                &rab,
                   1283:                                &flags)) & 01)) {
                   1284:        fprintf(stderr,"\nCreating (fdl$parse)\n");
                   1285:        (void) lib$signal(sts2);
                   1286:     } else {
                   1287: /*
                   1288:  * Extract & Return Name of FDL Supplied Filename
                   1289:  */
                   1290:        memcpy (preserved_name,fab->fab$l_fna,fab->fab$b_fns);
                   1291:        preserved_name[fab->fab$b_fns] = '\0';
                   1292: /*
                   1293:  * Set Name Of Temporary File
                   1294:  */
                   1295:        fab->fab$l_fna = outfile;
                   1296:        fab->fab$b_fns = strlen(outfile);
                   1297: /*
                   1298:  * Connect NAM Block
                   1299:  */
                   1300:        fab->fab$l_nam = &nam;
                   1301:        fab->fab$l_fop |= FAB$M_NAM | FAB$M_CIF;
                   1302:        fab->fab$b_fac |= FAB$M_BIO | FAB$M_PUT;
                   1303: /*
                   1304:  * Create File
                   1305:  */
                   1306:        if (!(sys$create(fab) & 01)) {
                   1307:            fprintf(stderr,"\nCreating (RMS)\n");
                   1308:            (void) lib$signal(fab->fab$l_sts,fab->fab$l_stv);
                   1309:            fdl_close(rab);
                   1310:        } else {
                   1311:            if (verbose) {
                   1312:                resnam[nam.nam$b_esl+1] = '\0';
                   1313:                fprintf(stderr,"\nCreated %s successfully\n",resnam);
                   1314:            }
                   1315:            rab->rab$l_rop = RAB$M_BIO;
                   1316:            if (!(sys$connect(rab) & 01)) {
                   1317:                fprintf(stderr,"\nConnecting (RMS)\n");
                   1318:                (void) lib$signal(rab->rab$l_sts,rab->rab$l_stv);
                   1319:                fdl_close(rab);
                   1320:            } else sts = rab;
                   1321:        }
                   1322:        fab->fab$l_nam = 0; /* I allocated NAM block, so I must deallocate it! */
                   1323:     }
                   1324:     free(resnam);
                   1325:     return(sts);               
                   1326: }
                   1327: 
                   1328: /*
                   1329:  * **-fdl_copyfile2bin-Copies the input file to a 'binary' output file
                   1330:  *
                   1331:  * Description:
                   1332:  *
                   1333:  * This procedure is invoked to copy from an opened file f to a file opened
                   1334:  * directly through RMS. This allows us to make a block copy into one of the
                   1335:  * many esoteric RMS file types thus preserving characteristics without blowing
                   1336:  * up the C RTL. This code is based directly on copyfile from FILEIO.C.
                   1337:  *
                   1338:  * Calling Sequence:
                   1339:  */
1.1.1.4 ! root     1340: int fdl_copyfile2bin( FILE *f, VOID *rab, word32 longcount)
1.1.1.2   root     1341: /*
                   1342:  * Arguments:
                   1343:  *
                   1344:  *     f           FILE*       Pointer to input file
                   1345:  *
                   1346:  *     rab         RAB*        Pointer to output file RAB
                   1347:  * 
                   1348:  *     longcount   word32      Size of file
                   1349:  *
                   1350:  * Returns:
                   1351:  *
                   1352:  *     0   If we were successful.
                   1353:  *     -1  We had an error on the input file (VAXCRTL).
                   1354:  *     +1  We had an error on the output file (direct RMS).
                   1355:  */
                   1356: {
                   1357:     int status = 0;
                   1358:     word32 count;
                   1359:     ((struct RAB *) rab)->rab$l_rbf = &textbuf;
                   1360:     ((struct RAB *) rab)->rab$l_bkt = 0;
                   1361:     do { /*  Read and write longcount bytes */
                   1362:        if (longcount < (word32) DISKBUFSIZE)
                   1363:            count = longcount;
                   1364:        else
                   1365:            count = DISKBUFSIZE;
                   1366:        count = fread(textbuf,1,count,f);
                   1367:        if (count > 0) {
                   1368: /*       
                   1369:  *  No byte order conversion required, source and target system are both VMS so have
                   1370:  *  the same byte ordering.
                   1371:  */      
                   1372:            ((struct RAB *) rab)->rab$w_rsz = (unsigned short) count;
                   1373:            if (!(sys$write (
                   1374:                       rab, 
                   1375:                       NULL, 
                   1376:                       NULL) & 01)) {
                   1377:                  lib$signal(((struct RAB *) rab)->rab$l_sts,((struct RAB *) rab)->rab$l_stv);
                   1378:                  status = 1;
                   1379:                  break;
                   1380:            }
                   1381:            longcount -= count;
                   1382:        }
                   1383:     } while (count==DISKBUFSIZE);
                   1384:     burn(textbuf);
                   1385:     return(status);
                   1386: }
1.1.1.3   root     1387: /*
                   1388:  * **-vms_fileparse-Parse A VMS File Specification
                   1389:  *
                   1390:  * Functional Description:
                   1391:  *
                   1392:  * This procedure is invoked to parse a VMS file specification using default 
                   1393:  * and related specifications to fill in any missing components. This works a 
                   1394:  * little like DCL's F$PARSE function with the syntax check only specified
                   1395:  * (that is we don't check the device or the directory). The related file
                   1396:  * spec is really for when we want to use the name of an input file (w/o the
                   1397:  * directory) to supply the name of an output file.
                   1398:  *
                   1399:  * Note that we correctly handle the situation where the output buffer overlays
                   1400:  * the input filespec by testing for the case and then handling it by copying
                   1401:  * the primary input specification to a temporary buffer before parsing.
                   1402:  */
                   1403: int vms_fileparse( char *outbuf, char *filespec, char *defspec, char *relspec)
                   1404: /*
                   1405:  * Arguments:
                   1406:  *
                   1407:  *  outbuf     Returned file specification.
                   1408:  *  filespec   Primary file specification (optional).
                   1409:  *  defspec    Default file specification (optional).
                   1410:  *  relspec    Related file specification (optional).
                   1411:  *
                   1412:  * Returns:
                   1413:  *
                   1414:  *  As for SYS$PARSE.
                   1415:  *
                   1416:  * Implicit Inputs:
                   1417:  *
                   1418:  *  None.
                   1419:  *
                   1420:  * Implicit Outputs:
                   1421:  *
                   1422:  *  None.
                   1423:  *
                   1424:  * Side Effects:
                   1425:  *
                   1426:  *  ...TBS...
                   1427:  */
                   1428: {
                   1429:     struct FAB fab = cc$rms_fab;
                   1430:     struct NAM nam = cc$rms_nam;
                   1431:     struct NAM rlnam = cc$rms_nam;
                   1432:     int sts = 1;
                   1433:     int len;
                   1434:     char tmpbuf[NAM$C_MAXRSSLCL];
                   1435:     char expfnam2[NAM$C_MAXRSSLCL];
                   1436: 
                   1437:     if (outbuf != NULL) {
                   1438:        outbuf[0] = '\0';
                   1439:        fab.fab$l_fop != FAB$M_NAM;  /*  Enable RMS NAM block processing */
                   1440:        nam.nam$b_nop |= NAM$M_PWD | NAM$M_SYNCHK;
                   1441:        /*        
                   1442:        **  Handle Related Spec (If reqd).
                   1443:        */        
                   1444:        if (relspec != NULL) {
                   1445:            if ((len = strlen(relspec)) > 0) {
                   1446:                fab.fab$l_nam = &rlnam;
                   1447:                fab.fab$b_fns = len;
                   1448:                fab.fab$l_fna = relspec;
                   1449:                rlnam.nam$b_ess = NAM$C_MAXRSSLCL;
                   1450:                rlnam.nam$l_esa = expfnam2;
                   1451:                rlnam.nam$b_nop |= NAM$M_PWD | NAM$M_SYNCHK;
                   1452:                if ((sts = sys$parse (
                   1453:                            &fab, 
                   1454:                            0, 
                   1455:                            0)) & 01) {
                   1456:                    rlnam.nam$l_rsa = rlnam.nam$l_esa;
                   1457:                    rlnam.nam$b_rsl = rlnam.nam$b_esl;
                   1458:                    nam.nam$l_rlf = &rlnam;
                   1459:                    fab.fab$l_fop |= FAB$M_OFP;
                   1460:                }
                   1461:            }
                   1462:        }
                   1463:        if (sts) {
                   1464:            fab.fab$l_nam = &nam;
                   1465:            nam.nam$l_esa = outbuf;
                   1466:            nam.nam$b_ess = NAM$C_MAXRSSLCL;
                   1467:            /*    
                   1468:            **  Process Default Specification:
                   1469:            */    
                   1470:            if (defspec != NULL) {
                   1471:                if ((len = strlen(defspec)) > 0) {
                   1472:                    fab.fab$l_dna = defspec;
                   1473:                    fab.fab$b_dns = len;
                   1474:                }
                   1475:            }
                   1476:            /*    
                   1477:            **  Process Main File Specification:
                   1478:            */    
                   1479:            fab.fab$l_fna = NULL;
                   1480:            fab.fab$b_fns = 0;
                   1481:            if (filespec != NULL) {
                   1482:                if ((len = strlen(filespec)) > 0) {
                   1483:                    fab.fab$b_fns = len;
                   1484:                    if (filespec == outbuf)
                   1485:                        fab.fab$l_fna = memcpy(tmpbuf,filespec,len);
                   1486:                    else
                   1487:                        fab.fab$l_fna = filespec;
                   1488:                }
                   1489:            }
                   1490:            if ((sts = sys$parse(
                   1491:                       &fab, 
                   1492:                       0, 
                   1493:                       0)) && 01) outbuf[nam.nam$b_esl] = '\0';
                   1494:        }
                   1495:     }
                   1496:     return (sts);
                   1497: }
1.1.1.2   root     1498: #endif /* VMS */
                   1499: 
                   1500: 
                   1501: /*========================================================================*/
                   1502: /*
                   1503:  * AMIGA
                   1504:  */
                   1505: 
                   1506: #ifdef AMIGA   /* Amiga-specific stuff */
                   1507: 
                   1508: #include <exec/types.h>
                   1509: #include <exec/memory.h>
                   1510: #include <exec/ports.h>
                   1511: #include <libraries/dosextens.h>
                   1512: #ifdef LATTICE
                   1513: #include <proto/exec.h> 
                   1514: #include <proto/dos.h> 
                   1515: #endif /* LATTICE */
                   1516: extern FILE *pgpout;
                   1517: extern int aecho;
                   1518: 
                   1519: 
                   1520: /* amiga version of getch() 
                   1521:    Cor Bosman , jul-22-92 
                   1522: */
                   1523: 
                   1524: 
                   1525: sendpacket(struct MsgPort *rec,LONG action,LONG arg1) 
                   1526: {
                   1527:   struct StandardPacket *pkt;
                   1528:   struct msgPort *rp;
                   1529:   LONG res1 = 0L;
                   1530: 
                   1531:   if (rp = (struct MsgPort *)CreatePort(NULL,0L)) {
                   1532:     if (pkt = (struct StandardPacket *)\
                   1533:         AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
                   1534:           pkt->sp_Msg.mn_Node.ln_Name = (BYTE *)&pkt->sp_Pkt;
                   1535:           pkt->sp_Pkt.dp_Link = &pkt->sp_Msg;
                   1536:           pkt->sp_Pkt.dp_Port = rp;
                   1537:           pkt->sp_Pkt.dp_Type = action;
                   1538:           pkt->sp_Pkt.dp_Arg1 = arg1;
                   1539:           PutMsg(rec,&pkt->sp_Msg);
                   1540:           WaitPort(rp);
                   1541:           GetMsg(rp);
                   1542:           res1 = pkt->sp_Pkt.dp_Res1;
                   1543:           FreeMem((UBYTE*)pkt,sizeof(struct StandardPacket));
                   1544:         }
                   1545:         DeletePort(rp);
                   1546:        }
                   1547:        return(res1);
                   1548: 
                   1549: }
                   1550: 
                   1551: /* ttycbreak for amiga.
                   1552:  * Cor Bosman , jul-30-92
                   1553: */
                   1554: 
                   1555: void ttycbreak()
                   1556: {
                   1557:   BPTR in,out;
                   1558:   char buf[128];
                   1559:   struct MsgPort *ch;
                   1560: 
                   1561:   in=Input();
                   1562:   out=Output();
                   1563:   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
                   1564:   sendpacket(ch,ACTION_SCREEN_MODE,-1L);
                   1565: }
                   1566: 
                   1567: /* ttynorm for amiga
                   1568:  * Cor Bosman , jul-30-92
                   1569: */
                   1570: 
                   1571: void ttynorm()
                   1572: {
                   1573: 
                   1574:   BPTR in,out;
                   1575:   char buf[128];
                   1576:   struct MsgPort *ch;
                   1577: 
                   1578:   in=Input();
                   1579:   out=Output();
                   1580:   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
                   1581:   sendpacket(ch,ACTION_SCREEN_MODE,0L);
                   1582: }
                   1583: 
                   1584: char getch(void)
                   1585: {
                   1586:   char buf[128];
                   1587:   BPTR in,out;
                   1588: 
                   1589:   in = Input();
                   1590:   out = Output();
                   1591:   Read(in,buf,1);
                   1592:   if (aecho) 
                   1593:     Write(out, buf, 1);
                   1594:   return(buf[0]);
                   1595: }
                   1596: 
                   1597: /* kbhit() function for amiga.
                   1598:  * Cor Bosman , jul-30-92
                   1599: */
                   1600: 
                   1601: int kbhit() 
                   1602: {
                   1603:   if(WaitForChar(Input(), 1)) return 1;
                   1604:   return 0;
                   1605: }
                   1606: 
                   1607: #ifdef LATTICE
                   1608: 
                   1609: /*
                   1610:  *  Lattice-C  ^C-Handler 
                   1611: */
                   1612: 
                   1613: int CXBRK()
                   1614: {
                   1615:   BPTR in,out;
                   1616:   struct MsgPort *ch;
                   1617:   in=Input();
                   1618:   out=Output();
                   1619: 
                   1620:   /* it might happen we catch a ^C while in cbreak mode.
                   1621:    * so always set the screen to the normal mode.
                   1622:   */
                   1623: 
                   1624:   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
                   1625:   sendpacket(ch, ACTION_SCREEN_MODE, 0L);
                   1626: 
                   1627: 
                   1628:   fprintf(pgpout, "\n*** Program Aborted.\n");
                   1629:   exitPGP(6); /* INTERRUPT */
                   1630: }
                   1631: #endif
                   1632: 
                   1633: /*------------------------------------------------------------------------
                   1634:  * clock.c -- time in microseconds since first call of clock()
                   1635:  *
                   1636:  * RP: this function is missing from SAS/C library.
                   1637:  */
                   1638: 
                   1639: #include <time.h>
                   1640: 
                   1641: long clock()
                   1642: {
                   1643:        static unsigned long oldms = -1;
                   1644:        unsigned long cl[2],ms;
                   1645: 
                   1646:        timer(cl);
                   1647:        ms = cl[0] * 1000000 + cl[1] % 1000000;
                   1648:        if(oldms == -1) {
                   1649:                oldms = ms;
                   1650:                return 0;
                   1651:        } else {
                   1652:                return ((long)(ms-oldms));
                   1653:        }
                   1654: }
                   1655: 
                   1656: 
                   1657: #endif /* AMIGA */
                   1658: 
                   1659: 
                   1660: 
                   1661: /*===========================================================================*/
                   1662: /*
                   1663:  * other stuff for non-MSDOS systems
                   1664:  */
                   1665: 
                   1666: #ifdef ATARI
                   1667: #include <string.h>
                   1668: #endif
                   1669: 
                   1670: #if !defined(MSDOS) && !defined(ATARI)
                   1671: #include <ctype.h>
1.1.1.3   root     1672: #include "charset.h"
1.1.1.2   root     1673: char *strlwr(char *s)
                   1674: {      /*
                   1675:        **        Turns string s into lower case.
                   1676:        */
                   1677:        int c;
                   1678:        char *p = s;
                   1679:        while (c = *p)
                   1680:                *p++ = to_lower(c);
                   1681:        return(s);
                   1682: }
                   1683: #endif /* !MSDOS && !ATARI */
                   1684: 
                   1685: 
                   1686: #ifdef strstr
                   1687: #undef strstr
                   1688: /* Not implemented on some systems - return first instance of s2 in s1 */
                   1689: char *mystrstr (char *s1, char *s2)
                   1690: {      int i;
                   1691:        char *strchr();
                   1692: 
                   1693:        if (!s2 || !*s2)
                   1694:                return s1;
                   1695:        for ( ; ; )
                   1696:        {       if (!(s1 = strchr (s1, *s2)))
                   1697:                        return s1;
                   1698:                for (i=1; s2[i] && (s1[i]==s2[i]); ++i)
                   1699:                        ;
                   1700:                if (!s2[i])
                   1701:                        return s1;
                   1702:                ++s1;
                   1703:        }
                   1704: }
                   1705: #endif /* strstr */
                   1706: 
                   1707: 
                   1708: #ifdef fopen
                   1709: #undef fopen
                   1710: 
                   1711: #ifdef ATARI
                   1712: #define F_BUF_SIZE 8192  /* seems to be a good value ... */
                   1713: 
                   1714: FILE *myfopen(const char *filename, const char *mode)
                   1715: /* Open streams with larger buffer to increase disk I/O speed. */
                   1716: /* Adjust F_BUF_SIZE to change buffer size.                    */
                   1717: {
                   1718:     FILE *f;
                   1719: 
                   1720:     if ( (f = fopen(filename, mode)) != NULL )
                   1721:         if (setvbuf(f, NULL, _IOFBF, F_BUF_SIZE)) /* no memory? */
                   1722:         {
                   1723:             fclose(f);                 /* then close it again */
                   1724:             f = fopen(filename, mode); /* and try again in normal mode */
                   1725:         }
                   1726:     return(f);                         /* return either handle or NULL */
                   1727: }
                   1728:        
                   1729: #else /* ATARI */
                   1730: 
                   1731: /* Remove "b" from 2nd arg */
                   1732: FILE *myfopen(char *filename, char *type)
                   1733: {      char buf[10];
                   1734: 
                   1735:        buf[0] = *type++;
                   1736:        if (*type=='b')
                   1737:                ++type;
                   1738:        strcpy(buf+1,type);
                   1739:        return fopen(filename, buf);
                   1740: }
                   1741: #endif /* not ATARI */
                   1742: #endif /* fopen */
                   1743: 
                   1744: 
                   1745: #ifndef MSDOS
                   1746: #ifdef OS2
                   1747: 
                   1748: static int chr = -1;
                   1749: 
                   1750: int kbhit(void)
                   1751: {
                   1752:        if (chr == -1)
                   1753:                chr = _read_kbd(0, 0, 0);
                   1754:        return (chr != -1);
                   1755: }
                   1756: 
                   1757: int getch(void)
                   1758: {
                   1759:        int c;
                   1760: 
                   1761:        if (chr >= 0) {
                   1762:                c = chr;
                   1763:                chr = -1;
                   1764:        } else
                   1765:                c = _read_kbd(0, 1, 0);
                   1766: 
                   1767:        return c;
                   1768: }
                   1769: 
                   1770: #endif /* OS2 */
                   1771: #endif /* MSDOS */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.