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

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: 
        !           446: #endif _USEDCL_
        !           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;
                    495:        void *rtn;
                    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:  *
                   1209:  *     rab     void *  Pointer to RAB (voided to avoid problems for caller).
                   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:  */
                   1234: void * fdl_create( char *fdl, short len, char *outfile, char *preserved_name)
                   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: {
                   1251:     void *sts;
                   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:  */
                   1340: int fdl_copyfile2bin( FILE *f, void *rab, word32 longcount)
                   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.