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