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