|
|
1.1.1.2 ! root 1: /* ! 2: * system.c ! 3: * ! 4: * Routines specific for non-MSDOS implementations of pgp. ! 5: * ! 6: * Modified 24-Jun-92 HAJK ! 7: * Adapt for VAX/VMS. ! 8: * ! 9: * Modified: 11-Nov-92 HAJK ! 10: * Add FDL Support Routines. ! 11: */ ! 12: #include <stdio.h> ! 13: #ifdef VMS ! 14: #include <file.h> ! 15: #include "pgp.h" ! 16: #include "mpilib.h" ! 17: #include "mpiio.h" ! 18: #include "fileio.h" ! 19: extern byte textbuf[DISKBUFSIZE]; /* Defined in FILEIO.C */ ! 20: #endif /* VMS */ ! 21: /*===========================================================================*/ ! 22: /* ! 23: * UNIX ! 24: */ ! 25: ! 26: #ifdef UNIX ! 27: /* ! 28: * Define USE_SELECT to use the select() system call to check if ! 29: * keyboard input is available. Define USE_NBIO to use non-blocking ! 30: * read(). If you don't define anything the FIONREAD ioctl() command ! 31: * will be used. ! 32: * ! 33: * Define NOTERMIO if you don't have the termios stuff ! 34: */ ! 35: #include <sys/types.h> ! 36: #include <fcntl.h> ! 37: #if !defined(MACH) && !defined(BSD) ! 38: #include <unistd.h> ! 39: #endif ! 40: ! 41: #ifndef NOTERMIO ! 42: #ifndef SVR2 ! 43: #include <termios.h> ! 44: #else ! 45: #include <termio.h> ! 46: #endif /* not SVR2 */ ! 47: #else ! 48: #include <sgtty.h> ! 49: #endif ! 50: ! 51: #ifdef USE_SELECT ! 52: #include <sys/time.h> ! 53: #else ! 54: #ifndef USE_NBIO ! 55: #ifndef sun ! 56: #include <sys/ioctl.h> /* for FIONREAD */ ! 57: #else /* including both ioctl.h and termios.h gives a lot of warnings on sun */ ! 58: #include <sys/filio.h> ! 59: #endif /* sun */ ! 60: #ifndef FIONREAD ! 61: #define FIONREAD TIOCINQ ! 62: #endif ! 63: #endif ! 64: #endif ! 65: #include <signal.h> ! 66: ! 67: static void setsigs(void); ! 68: static void rmsigs(void); ! 69: static void sig1(int); ! 70: static void sig2(int); ! 71: void breakHandler(int); ! 72: static int ttyfd= -1; ! 73: #ifndef SVR2 ! 74: static void (*savesig)(int); ! 75: #else ! 76: static int (*savesig)(int); ! 77: #endif ! 78: ! 79: void ttycbreak(void); ! 80: void ttynorm(void); ! 81: ! 82: ! 83: #ifndef NOTERMIO ! 84: #ifndef SVR2 ! 85: static struct termios itio, tio; ! 86: #else ! 87: static struct termio itio, tio; ! 88: #endif /* not SVR2 */ ! 89: #else ! 90: static struct sgttyb isg, sg; ! 91: #endif ! 92: ! 93: #ifdef USE_NBIO ! 94: static int kbuf= -1; /* buffer to store char read by kbhit() */ ! 95: static int fflags; ! 96: #endif ! 97: ! 98: static int gottio = 0; ! 99: ! 100: void ttycbreak(void) ! 101: { ! 102: if (ttyfd == -1) { ! 103: if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) { ! 104: fprintf(stderr, "cannot open tty, using stdin\n"); ! 105: ttyfd = 0; ! 106: } ! 107: } ! 108: #ifndef NOTERMIO ! 109: #ifndef SVR2 ! 110: if (tcgetattr(ttyfd, &tio) < 0) ! 111: #else ! 112: if (ioctl(ttyfd, TCGETA, &tio) < 0) ! 113: #endif /* not SVR2 */ ! 114: { fprintf (stderr, "\nUnable to get terminal characteristics: "); ! 115: perror("ioctl"); ! 116: exitPGP(1); ! 117: } ! 118: itio = tio; ! 119: setsigs(); ! 120: gottio = 1; ! 121: #ifdef USE_NBIO ! 122: tio.c_cc[VMIN] = 0; ! 123: #else ! 124: tio.c_cc[VMIN] = 1; ! 125: #endif ! 126: tio.c_cc[VTIME] = 0; ! 127: tio.c_lflag &= ~(ECHO|ICANON); ! 128: #ifndef SVR2 ! 129: tcsetattr (ttyfd, TCSAFLUSH, &tio); ! 130: #else ! 131: ioctl(ttyfd, TCSETAW, &tio); ! 132: #endif /* not SVR2 */ ! 133: #else ! 134: if (ioctl(ttyfd, TIOCGETP, &sg) < 0) ! 135: { fprintf (stderr, "\nUnable to get terminal characteristics: "); ! 136: perror("ioctl"); ! 137: exitPGP(1); ! 138: } ! 139: isg = sg; ! 140: setsigs(); ! 141: gottio = 1; ! 142: #ifdef CBREAK ! 143: sg.sg_flags |= CBREAK; ! 144: #else ! 145: sg.sg_flags |= RAW; ! 146: #endif ! 147: sg.sg_flags &= ~ECHO; ! 148: ioctl(ttyfd, TIOCSETP, &sg); ! 149: #endif /* !NOTERMIO */ ! 150: #ifdef USE_NBIO ! 151: #ifndef O_NDELAY ! 152: #define O_NDELAY O_NONBLOCK ! 153: #endif ! 154: if ((fflags = fcntl(ttyfd, F_GETFL, 0)) != -1) ! 155: fcntl(ttyfd, F_SETFL, fflags|O_NDELAY); ! 156: #endif ! 157: } ! 158: ! 159: ! 160: void ttynorm(void) ! 161: { gottio = 0; ! 162: #ifdef USE_NBIO ! 163: if (fcntl(ttyfd, F_SETFL, fflags) == -1) ! 164: perror("fcntl"); ! 165: #endif ! 166: #ifndef NOTERMIO ! 167: #ifndef SVR2 ! 168: tcsetattr (ttyfd, TCSAFLUSH, &itio); ! 169: #else ! 170: ioctl(ttyfd, TCSETAW, &itio); ! 171: #endif /* not SVR2 */ ! 172: #else ! 173: ioctl(ttyfd, TIOCSETP, &isg); ! 174: #endif ! 175: rmsigs(); ! 176: } ! 177: ! 178: static void sig1 (int sig) ! 179: { ! 180: #ifndef NOTERMIO ! 181: #ifndef SVR2 ! 182: tcsetattr (ttyfd, TCSANOW, &itio); ! 183: #else ! 184: ioctl(ttyfd, TCSETAW, &itio); ! 185: #endif /* not SVR2 */ ! 186: #else ! 187: ioctl(ttyfd, TIOCSETP, &isg); ! 188: #endif ! 189: signal (sig, SIG_DFL); ! 190: if (sig == SIGINT) ! 191: breakHandler(SIGINT); ! 192: kill (getpid(), sig); ! 193: } ! 194: ! 195: static void sig2 (int sig) ! 196: { if (gottio) ! 197: ttycbreak(); ! 198: else ! 199: setsigs(); ! 200: } ! 201: ! 202: static void setsigs(void) ! 203: { savesig = signal (SIGINT, sig1); ! 204: #ifdef SIGTSTP ! 205: signal (SIGCONT, sig2); ! 206: signal (SIGTSTP, sig1); ! 207: #endif ! 208: } ! 209: ! 210: static void rmsigs(void) ! 211: { signal (SIGINT, savesig); ! 212: #ifdef SIGTSTP ! 213: signal (SIGCONT, SIG_DFL); ! 214: signal (SIGTSTP, SIG_DFL); ! 215: #endif ! 216: } ! 217: ! 218: #ifndef CRUDE ! 219: int kbhit(void) ! 220: /* Return TRUE if there is a key to be read */ ! 221: { ! 222: #ifdef USE_SELECT /* use select() system call */ ! 223: struct timeval t; ! 224: fd_set n; ! 225: int r; ! 226: ! 227: timerclear(&t); ! 228: FD_ZERO(&n); ! 229: FD_SET(ttyfd, &n); ! 230: r = select(32, &n, NULL, NULL, &t); ! 231: if (r == -1) { ! 232: perror("select"); ! 233: exitPGP(1); ! 234: } ! 235: return r > 0; ! 236: #else ! 237: #ifdef USE_NBIO /* use non-blocking read() */ ! 238: unsigned char ch; ! 239: if (kbuf >= 0) ! 240: return(1); ! 241: if (read(ttyfd, &ch, 1) == 1) { ! 242: kbuf = ch; ! 243: return(1); ! 244: } ! 245: return(0); ! 246: #else ! 247: long lf; ! 248: if (ioctl(ttyfd, FIONREAD, &lf) == -1) { ! 249: perror("ioctl: FIONREAD"); ! 250: exitPGP(1); ! 251: } ! 252: return(lf); ! 253: #endif ! 254: #endif ! 255: } ! 256: #endif /* !CRUDE */ ! 257: ! 258: int getch(void) ! 259: { ! 260: char c; ! 261: #ifdef USE_NBIO ! 262: while (!kbhit()); /* kbhit() does the reading */ ! 263: c = kbuf; ! 264: kbuf = -1; ! 265: #else ! 266: read(ttyfd, &c, 1); ! 267: #endif ! 268: return(c); ! 269: } ! 270: ! 271: #ifdef BSD ! 272: VOID *memset(s, c, n) ! 273: VOID *s; ! 274: register int c, n; ! 275: { ! 276: register char *p = s; ! 277: ++n; ! 278: while (--n) ! 279: *p++ = c; ! 280: return(s); ! 281: } ! 282: int memcmp(s1, s2, n) ! 283: register unsigned char *s1, *s2; ! 284: register int n; ! 285: { ! 286: if (!n) ! 287: return(0); ! 288: while (--n && *s1 == *s2) { ! 289: ++s1; ! 290: ++s2; ! 291: } ! 292: return(*s1 - *s2); ! 293: } ! 294: VOID *memcpy(s1, s2, n) ! 295: register char *s1, *s2; ! 296: register int n; ! 297: { ! 298: char *p = s1; ! 299: ++n; ! 300: while (--n) ! 301: *s1++ = *s2++; ! 302: return(p); ! 303: } ! 304: #endif /* BSD */ ! 305: ! 306: #if defined(MACH) || defined(SVR2) || defined(BSD) ! 307: int remove(name) ! 308: char *name; ! 309: { ! 310: return unlink(name); ! 311: } ! 312: #endif ! 313: ! 314: #ifdef SVR2 ! 315: int rename(old, new) ! 316: register char *old, *new; ! 317: { ! 318: unlink(new); ! 319: if (link(old, new) < 0) ! 320: return -1; ! 321: if (unlink(old) < 0) { ! 322: unlink(new); ! 323: return -1; ! 324: } ! 325: return 0; ! 326: } ! 327: #endif /* SVR2 */ ! 328: ! 329: /* not all unices have clock() */ ! 330: long ! 331: Clock() /* not a replacement for clock(), just for random number generation */ ! 332: { ! 333: #if defined(BSD) || defined(sun) || defined(MACH) || defined(linux) ! 334: #include <sys/time.h> ! 335: #include <sys/resource.h> ! 336: struct rusage ru; ! 337: ! 338: getrusage(RUSAGE_SELF, &ru); ! 339: return ru.ru_utime.tv_sec + ru.ru_utime.tv_usec + ! 340: ru.ru_stime.tv_sec + ru.ru_stime.tv_usec + ! 341: ru.ru_minflt + ru.ru_majflt + ! 342: ru.ru_inblock + ru.ru_oublock + ! 343: ru.ru_maxrss + ru.ru_nvcsw + ru.ru_nivcsw; ! 344: ! 345: #else /* no getrusage() */ ! 346: #include <sys/times.h> ! 347: struct tms tms; ! 348: ! 349: times(&tms); ! 350: return(tms.tms_utime + tms.tms_stime); ! 351: #endif ! 352: } ! 353: #endif /* UNIX */ ! 354: ! 355: ! 356: /*===========================================================================*/ ! 357: /* ! 358: * VMS ! 359: */ ! 360: ! 361: #ifdef VMS /* kbhit()/getch() equivalent */ ! 362: ! 363: /* ! 364: * This code defines an equivalent version of kbhit() and getch() for ! 365: * use under VAX/VMS, together with an exit handler to reset terminal ! 366: * characteristics. ! 367: * ! 368: * This code assumes that kbhit() has been invoked to test that there ! 369: * are characters in the typeahead buffer before getch() is invoked to ! 370: * get the answer. ! 371: */ ! 372: ! 373: #include <descrip.h> ! 374: #include <devdef> ! 375: #include <iodef.h> ! 376: #include <ttdef.h> ! 377: #include <tt2def.h> ! 378: #include <dcdef.h> ! 379: #include <rms.h> ! 380: ! 381: #define FDL$M_FDL_STRING 2 /* Use string for fdl text */ ! 382: #define FDLSIZE 4096 /* Maximum possible file size */ ! 383: ! 384: static volatile short _kbhitChan_ = 0; ! 385: ! 386: static volatile struct IOSB { ! 387: unsigned short sts; ! 388: unsigned short byteCount; ! 389: unsigned short terminator; ! 390: unsigned short terminatorSize; ! 391: } iosb; ! 392: ! 393: static $DESCRIPTOR (kbdev_desc, "SYS$COMMAND:"); ! 394: ! 395: static volatile struct { ! 396: char Class; ! 397: char Type; ! 398: unsigned short BufferSize; ! 399: unsigned int Mode; ! 400: int ExtChar; ! 401: } CharBuf, OldCharBuf; ! 402: ! 403: static $DESCRIPTOR (out_file_descr, "SYS$DISK:[]"); /* Default Output File Descr */ ! 404: ! 405: static int flags = FDL$M_FDL_STRING; ! 406: ! 407: ! 408: /* ! 409: * **-kbhit_handler-This exit handler restores the terminal characteristics ! 410: * ! 411: * Description: ! 412: * ! 413: * This procedure is invoked to return the the terminal to normality (depends ! 414: * on what you think is normal!). Anyway, it gets called to restore ! 415: * characteristics either through ttynorm or via an exit handler. ! 416: */ ! 417: void kbhit_handler(int *sts) ! 418: { ! 419: int mysts; ! 420: ! 421: CharBuf.Mode = OldCharBuf.Mode; ! 422: CharBuf.ExtChar = OldCharBuf.ExtChar; ! 423: CharBuf.Mode &= ~TT$M_NOECHO; ! 424: CharBuf.ExtChar &= ~TT2$M_PASTHRU; ! 425: if ((mysts = sys$qiow ( ! 426: 0, ! 427: _kbhitChan_, ! 428: IO$_SETMODE, ! 429: &iosb, ! 430: 0, ! 431: 0, ! 432: &CharBuf, ! 433: 12, ! 434: 0, ! 435: 0, ! 436: 0, ! 437: 0)) & 01) mysts = iosb.sts; ! 438: (void) sys$dassgn ( ! 439: _kbhitChan_); ! 440: _kbhitChan_ = 0; ! 441: if (!(mysts & 01)) { ! 442: fprintf(stderr,"\nFailed to reset terminal characteristics!"); ! 443: (void) lib$signal(mysts); ! 444: } ! 445: } ! 446: ! 447: ! 448: unsigned int exsts; ! 449: ! 450: static struct { ! 451: int link; ! 452: void *rtn; ! 453: int argcnt; ! 454: int *stsaddr; ! 455: } exhblk = { 0, &(kbhit_handler), 1, &(exsts)}; ! 456: ! 457: /* ! 458: * **-kbhit-Find out if a key has been pressed ! 459: * ! 460: * Description: ! 461: * ! 462: * Make the terminal noecho and sense the characters coming in by looking at ! 463: * the typeahead count. ! 464: */ ! 465: int kbhit() ! 466: { ! 467: int sts = 1; ! 468: ! 469: struct { ! 470: unsigned short TypAhdCnt; ! 471: char FirstChar; ! 472: char Reserved[5]; ! 473: } TypCharBuf; ! 474: ! 475: if (_kbhitChan_ == 0) { ! 476: if ((sts = sys$assign ( ! 477: &kbdev_desc, ! 478: &_kbhitChan_, ! 479: 0, ! 480: 0)) & 1 == 0) lib$stop(sts); ! 481: if ((sts = sys$qiow ( ! 482: 0, ! 483: _kbhitChan_, ! 484: IO$_SENSEMODE, ! 485: &iosb, ! 486: 0, ! 487: 0, ! 488: &CharBuf, ! 489: 12, ! 490: 0, ! 491: 0, ! 492: 0, ! 493: 0)) & 01) sts = iosb.sts; ! 494: if (sts & 01) { ! 495: if (!(CharBuf.Class & DC$_TERM)) { ! 496: fprintf(stderr,"\nNot running on a terminal"); ! 497: exitPGP(1); ! 498: } else { ! 499: OldCharBuf.Mode = CharBuf.Mode; ! 500: OldCharBuf.ExtChar = CharBuf.ExtChar; ! 501: CharBuf.Mode |= TT$M_NOECHO; ! 502: CharBuf.ExtChar |= TT2$M_PASTHRU; ! 503: if ((sts = sys$qiow ( ! 504: 0, ! 505: _kbhitChan_, ! 506: IO$_SETMODE, ! 507: &iosb, ! 508: 0, ! 509: 0, ! 510: &CharBuf, ! 511: 12, ! 512: 0, ! 513: 0, ! 514: 0, ! 515: 0)) & 01) sts = iosb.sts; ! 516: if (sts & 01) { ! 517: /* ! 518: ** Declare Exit Handler ! 519: */ ! 520: (void) sys$dclexh (&exhblk); ! 521: } else { ! 522: fprintf(stderr,"\nFailed to set terminal characteristics!"); ! 523: (void) lib$signal(sts); ! 524: exitPGP(1); ! 525: } ! 526: } ! 527: } ! 528: } ! 529: /* ! 530: ** Get typeahead count ! 531: */ ! 532: if ((sts = sys$qiow ( ! 533: 0, ! 534: _kbhitChan_, ! 535: IO$_SENSEMODE | IO$M_TYPEAHDCNT, ! 536: &iosb, ! 537: 0, ! 538: 0, ! 539: &TypCharBuf, ! 540: 8, ! 541: 0, ! 542: 0, ! 543: 0, ! 544: 0)) & 01) sts = iosb.sts; ! 545: if (sts & 01) return(TypCharBuf.TypAhdCnt>0); ! 546: (void) lib$signal(sts); ! 547: exitPGP(1); ! 548: } ! 549: ! 550: /* ! 551: * **-getch-Get a character and return it ! 552: * ! 553: * Description: ! 554: * ! 555: * Get a character from the keyboard and return it. ! 556: */ ! 557: int getch() ! 558: { ! 559: unsigned int sts; ! 560: volatile char CharBuf; ! 561: ! 562: if ((sts = sys$qiow ( ! 563: 0, ! 564: _kbhitChan_, ! 565: IO$_READVBLK, ! 566: &iosb, ! 567: 0, ! 568: 0, ! 569: &CharBuf, ! 570: 1, ! 571: 0, ! 572: 0, ! 573: 0, ! 574: 0)) & 01) sts = iosb.sts; ! 575: if (sts & 01) return ((int) CharBuf); ! 576: fprintf(stderr,"\nFailed to get character"); ! 577: (void) lib$signal(sts); ! 578: } ! 579: ! 580: ttynorm() ! 581: { ! 582: int sts; ! 583: ! 584: if (_kbhitChan_ != 0) { ! 585: (void) SYS$CANEXH(&exhblk); ! 586: kbhit_handler(&sts); ! 587: } ! 588: } ! 589: ! 590: void ttycbreak () ! 591: { ! 592: ttynorm(); ! 593: } ! 594: ! 595: unsigned long vms_clock_bits[2]; /* VMS Hardware Clock */ ! 596: const long vms_ticks_per_update = 100000L; /* Clock update int. */ ! 597: ! 598: /* ! 599: * FDL Stuff For Getting & Setting File Characteristics ! 600: * This code was derived (loosely!) from the module LZVIO.C in the public ! 601: * domain LZW compress routine as found on the DECUS VAX SIG tapes (no author ! 602: * given, so no credits!) ! 603: */ ! 604: ! 605: /* ! 606: * **-fdl_generate-Generate An FDL ! 607: * ! 608: * Description: ! 609: * ! 610: * This procedure takes the name of an existing file as input and creates ! 611: * an fdl. The FDL is retuned by pointer and length. The FDL space should be ! 612: * released after use with a call to free(); ! 613: */ ! 614: int fdl_generate(char *in_file, char **fdl, short *len) ! 615: /* ! 616: * Arguments: ! 617: * ! 618: * in_file char* Filename of file to examine (Zero terminated). ! 619: * ! 620: * fdl char* Pointer to FDL that was created. ! 621: * ! 622: * len short Length of FDL created. ! 623: * ! 624: * Status Returns: ! 625: * ! 626: * VMS style. lower bit set means success. ! 627: */ ! 628: { ! 629: ! 630: struct dsc$descriptor fdl_descr = { 0, ! 631: DSC$K_DTYPE_T, ! 632: DSC$K_CLASS_D, ! 633: 0}; ! 634: struct FAB fab, *fab_addr; ! 635: struct RAB rab, *rab_addr; ! 636: struct NAM nam; ! 637: struct XABFHC xab; ! 638: int sts; ! 639: int badblk; ! 640: ! 641: /* ! 642: * Build FDL Descriptor ! 643: */ ! 644: if (!(sts = str$get1_dx(&FDLSIZE,&fdl_descr)) & 01) return(0); ! 645: /* ! 646: * Build RMS Data Structures ! 647: */ ! 648: fab = cc$rms_fab; ! 649: fab_addr = &fab; ! 650: nam = cc$rms_nam; ! 651: rab = cc$rms_rab; ! 652: rab_addr = &rab; ! 653: xab = cc$rms_xabfhc; ! 654: fab.fab$l_nam = &nam; ! 655: fab.fab$l_xab = &xab; ! 656: fab.fab$l_fna = in_file; ! 657: fab.fab$b_fns = strlen(in_file); ! 658: rab.rab$l_fab = &fab; ! 659: fab.fab$b_fac = FAB$M_GET | FAB$M_BIO; /* This open block mode only */ ! 660: /* ! 661: * Attempt to Open File ! 662: */ ! 663: if (!((sts = sys$open(&fab)) & 01)) { ! 664: if (verbose) { ! 665: fprintf(stderr,"\n(SYSTEM) Failed to $OPEN %s\n",in_file); ! 666: (void) lib$signal(fab.fab$l_sts,fab.fab$l_stv); ! 667: } ! 668: return(sts); ! 669: } ! 670: if (fab.fab$l_dev & DEV$M_REC) { ! 671: fprintf(stderr,"\n(SYSTEM) Attempt to read from output only device\n"); ! 672: sts = 0; ! 673: } else { ! 674: rab.rab$l_rop = RAB$M_BIO; ! 675: if (!((sts = sys$connect(&rab)) & 01)) { ! 676: if (verbose) { ! 677: fprintf(stderr,"\n(SYSTEM) Failed to $CONNECT %s\n",in_file); ! 678: (void) lib$signal(fab.fab$l_sts,fab.fab$l_stv); ! 679: } ! 680: } else { ! 681: if (!((sts = fdl$generate( ! 682: &flags, ! 683: &fab_addr, ! 684: &rab_addr, ! 685: NULL,NULL, ! 686: &fdl_descr, ! 687: &badblk, ! 688: len)) & 01)) { ! 689: if (verbose) ! 690: fprintf(stderr,"\n(SYSTEM) Failed to generate FDL\n",in_file); ! 691: free(fdl); ! 692: } else { ! 693: if (!(*fdl = malloc(*len))) return(0); ! 694: memcpy(*fdl,fdl_descr.dsc$a_pointer,*len); ! 695: } ! 696: (void) str$free1_dx(&fdl_descr); ! 697: } ! 698: sys$close(&fab); ! 699: } ! 700: return(sts); ! 701: } ! 702: ! 703: /* ! 704: * **-fdl_close-Closes files created by fdl_generate ! 705: * ! 706: * Description: ! 707: * ! 708: * This procedure is invoked to close the file and release the data structures ! 709: * allocated by fdl$parse. ! 710: */ ! 711: void fdl_close(void* rab) ! 712: /* ! 713: * Arguments: ! 714: * ! 715: * rab void * Pointer to RAB (voided to avoid problems for caller). ! 716: * ! 717: * Returns: ! 718: * ! 719: * None. ! 720: */ ! 721: { ! 722: struct FAB *fab; ! 723: ! 724: fab = ((struct RAB *) rab)->rab$l_fab; ! 725: if (fab) { /* Close file if not already closed */ ! 726: if (fab->fab$w_ifi) sys$close(fab); ! 727: } ! 728: fdl$release( NULL, &rab); ! 729: } ! 730: ! 731: /* ! 732: * **-fdl_create-Create A File Using the recorded FDL (hope we get it right!) ! 733: * ! 734: * Description: ! 735: * ! 736: * This procedure accepts an FDL and uses it create a file. Unfortunately ! 737: * there is no way we can easily patch into the back of the VAX C I/O ! 738: * subsystem. ! 739: */ ! 740: void * fdl_create( char *fdl, short len, char *outfile, char *preserved_name) ! 741: /* ! 742: * Arguments: ! 743: * ! 744: * fdl char* FDL string descriptor. ! 745: * ! 746: * len short Returned string length. ! 747: * ! 748: * outfile char* Output filename. ! 749: * ! 750: * preserved_name char* Name from FDL. ! 751: * ! 752: * Returns: ! 753: * ! 754: * 0 in case of error, or otherwise the RAB pointer. ! 755: */ ! 756: { ! 757: void *sts; ! 758: int sts2; ! 759: struct FAB *fab; ! 760: struct RAB *rab; ! 761: struct NAM nam; ! 762: int badblk; ! 763: char *resnam; ! 764: ! 765: struct dsc$descriptor fdl_descr = { ! 766: len, ! 767: DSC$K_DTYPE_T, ! 768: DSC$K_CLASS_S, ! 769: fdl ! 770: }; ! 771: ! 772: sts = NULL; ! 773: /* ! 774: * Initialize RMS NAM Block ! 775: */ ! 776: nam = cc$rms_nam; ! 777: nam.nam$b_rss = NAM$C_MAXRSS; ! 778: nam.nam$b_ess = NAM$C_MAXRSS; ! 779: if (!(resnam = nam.nam$l_esa = malloc(NAM$C_MAXRSS+1))) { ! 780: fprintf(stderr,"\n(FDL_CREATE) Out of memory!\n"); ! 781: return(NULL); ! 782: } ! 783: /* ! 784: * Parse FDL ! 785: */ ! 786: if (!((sts2 = fdl$parse( &fdl_descr, ! 787: &fab, ! 788: &rab, ! 789: &flags)) & 01)) { ! 790: fprintf(stderr,"\nCreating (fdl$parse)\n"); ! 791: (void) lib$signal(sts2); ! 792: } else { ! 793: /* ! 794: * Extract & Return Name of FDL Supplied Filename ! 795: */ ! 796: memcpy (preserved_name,fab->fab$l_fna,fab->fab$b_fns); ! 797: preserved_name[fab->fab$b_fns] = '\0'; ! 798: /* ! 799: * Set Name Of Temporary File ! 800: */ ! 801: fab->fab$l_fna = outfile; ! 802: fab->fab$b_fns = strlen(outfile); ! 803: /* ! 804: * Connect NAM Block ! 805: */ ! 806: fab->fab$l_nam = &nam; ! 807: fab->fab$l_fop |= FAB$M_NAM | FAB$M_CIF; ! 808: fab->fab$b_fac |= FAB$M_BIO | FAB$M_PUT; ! 809: /* ! 810: * Create File ! 811: */ ! 812: if (!(sys$create(fab) & 01)) { ! 813: fprintf(stderr,"\nCreating (RMS)\n"); ! 814: (void) lib$signal(fab->fab$l_sts,fab->fab$l_stv); ! 815: fdl_close(rab); ! 816: } else { ! 817: if (verbose) { ! 818: resnam[nam.nam$b_esl+1] = '\0'; ! 819: fprintf(stderr,"\nCreated %s successfully\n",resnam); ! 820: } ! 821: rab->rab$l_rop = RAB$M_BIO; ! 822: if (!(sys$connect(rab) & 01)) { ! 823: fprintf(stderr,"\nConnecting (RMS)\n"); ! 824: (void) lib$signal(rab->rab$l_sts,rab->rab$l_stv); ! 825: fdl_close(rab); ! 826: } else sts = rab; ! 827: } ! 828: fab->fab$l_nam = 0; /* I allocated NAM block, so I must deallocate it! */ ! 829: } ! 830: free(resnam); ! 831: return(sts); ! 832: } ! 833: ! 834: /* ! 835: * **-fdl_copyfile2bin-Copies the input file to a 'binary' output file ! 836: * ! 837: * Description: ! 838: * ! 839: * This procedure is invoked to copy from an opened file f to a file opened ! 840: * directly through RMS. This allows us to make a block copy into one of the ! 841: * many esoteric RMS file types thus preserving characteristics without blowing ! 842: * up the C RTL. This code is based directly on copyfile from FILEIO.C. ! 843: * ! 844: * Calling Sequence: ! 845: */ ! 846: int fdl_copyfile2bin( FILE *f, void *rab, word32 longcount) ! 847: /* ! 848: * Arguments: ! 849: * ! 850: * f FILE* Pointer to input file ! 851: * ! 852: * rab RAB* Pointer to output file RAB ! 853: * ! 854: * longcount word32 Size of file ! 855: * ! 856: * Returns: ! 857: * ! 858: * 0 If we were successful. ! 859: * -1 We had an error on the input file (VAXCRTL). ! 860: * +1 We had an error on the output file (direct RMS). ! 861: */ ! 862: { ! 863: int status = 0; ! 864: word32 count; ! 865: ((struct RAB *) rab)->rab$l_rbf = &textbuf; ! 866: ((struct RAB *) rab)->rab$l_bkt = 0; ! 867: do { /* Read and write longcount bytes */ ! 868: if (longcount < (word32) DISKBUFSIZE) ! 869: count = longcount; ! 870: else ! 871: count = DISKBUFSIZE; ! 872: count = fread(textbuf,1,count,f); ! 873: if (count > 0) { ! 874: /* ! 875: * No byte order conversion required, source and target system are both VMS so have ! 876: * the same byte ordering. ! 877: */ ! 878: ((struct RAB *) rab)->rab$w_rsz = (unsigned short) count; ! 879: if (!(sys$write ( ! 880: rab, ! 881: NULL, ! 882: NULL) & 01)) { ! 883: lib$signal(((struct RAB *) rab)->rab$l_sts,((struct RAB *) rab)->rab$l_stv); ! 884: status = 1; ! 885: break; ! 886: } ! 887: longcount -= count; ! 888: } ! 889: } while (count==DISKBUFSIZE); ! 890: burn(textbuf); ! 891: return(status); ! 892: } ! 893: #endif /* VMS */ ! 894: ! 895: ! 896: /*========================================================================*/ ! 897: /* ! 898: * AMIGA ! 899: */ ! 900: ! 901: #ifdef AMIGA /* Amiga-specific stuff */ ! 902: ! 903: #include <exec/types.h> ! 904: #include <exec/memory.h> ! 905: #include <exec/ports.h> ! 906: #include <libraries/dosextens.h> ! 907: #ifdef LATTICE ! 908: #include <proto/exec.h> ! 909: #include <proto/dos.h> ! 910: #endif /* LATTICE */ ! 911: extern FILE *pgpout; ! 912: extern int aecho; ! 913: ! 914: ! 915: /* amiga version of getch() ! 916: Cor Bosman , jul-22-92 ! 917: */ ! 918: ! 919: ! 920: sendpacket(struct MsgPort *rec,LONG action,LONG arg1) ! 921: { ! 922: struct StandardPacket *pkt; ! 923: struct msgPort *rp; ! 924: LONG res1 = 0L; ! 925: ! 926: if (rp = (struct MsgPort *)CreatePort(NULL,0L)) { ! 927: if (pkt = (struct StandardPacket *)\ ! 928: AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) { ! 929: pkt->sp_Msg.mn_Node.ln_Name = (BYTE *)&pkt->sp_Pkt; ! 930: pkt->sp_Pkt.dp_Link = &pkt->sp_Msg; ! 931: pkt->sp_Pkt.dp_Port = rp; ! 932: pkt->sp_Pkt.dp_Type = action; ! 933: pkt->sp_Pkt.dp_Arg1 = arg1; ! 934: PutMsg(rec,&pkt->sp_Msg); ! 935: WaitPort(rp); ! 936: GetMsg(rp); ! 937: res1 = pkt->sp_Pkt.dp_Res1; ! 938: FreeMem((UBYTE*)pkt,sizeof(struct StandardPacket)); ! 939: } ! 940: DeletePort(rp); ! 941: } ! 942: return(res1); ! 943: ! 944: } ! 945: ! 946: /* ttycbreak for amiga. ! 947: * Cor Bosman , jul-30-92 ! 948: */ ! 949: ! 950: void ttycbreak() ! 951: { ! 952: BPTR in,out; ! 953: char buf[128]; ! 954: struct MsgPort *ch; ! 955: ! 956: in=Input(); ! 957: out=Output(); ! 958: ch = ((struct FileHandle *)BADDR(in))->fh_Type; ! 959: sendpacket(ch,ACTION_SCREEN_MODE,-1L); ! 960: } ! 961: ! 962: /* ttynorm for amiga ! 963: * Cor Bosman , jul-30-92 ! 964: */ ! 965: ! 966: void ttynorm() ! 967: { ! 968: ! 969: BPTR in,out; ! 970: char buf[128]; ! 971: struct MsgPort *ch; ! 972: ! 973: in=Input(); ! 974: out=Output(); ! 975: ch = ((struct FileHandle *)BADDR(in))->fh_Type; ! 976: sendpacket(ch,ACTION_SCREEN_MODE,0L); ! 977: } ! 978: ! 979: char getch(void) ! 980: { ! 981: char buf[128]; ! 982: BPTR in,out; ! 983: ! 984: in = Input(); ! 985: out = Output(); ! 986: Read(in,buf,1); ! 987: if (aecho) ! 988: Write(out, buf, 1); ! 989: return(buf[0]); ! 990: } ! 991: ! 992: /* kbhit() function for amiga. ! 993: * Cor Bosman , jul-30-92 ! 994: */ ! 995: ! 996: int kbhit() ! 997: { ! 998: if(WaitForChar(Input(), 1)) return 1; ! 999: return 0; ! 1000: } ! 1001: ! 1002: #ifdef LATTICE ! 1003: ! 1004: /* ! 1005: * Lattice-C ^C-Handler ! 1006: */ ! 1007: ! 1008: int CXBRK() ! 1009: { ! 1010: BPTR in,out; ! 1011: struct MsgPort *ch; ! 1012: in=Input(); ! 1013: out=Output(); ! 1014: ! 1015: /* it might happen we catch a ^C while in cbreak mode. ! 1016: * so always set the screen to the normal mode. ! 1017: */ ! 1018: ! 1019: ch = ((struct FileHandle *)BADDR(in))->fh_Type; ! 1020: sendpacket(ch, ACTION_SCREEN_MODE, 0L); ! 1021: ! 1022: ! 1023: fprintf(pgpout, "\n*** Program Aborted.\n"); ! 1024: exitPGP(6); /* INTERRUPT */ ! 1025: } ! 1026: #endif ! 1027: ! 1028: /*------------------------------------------------------------------------ ! 1029: * clock.c -- time in microseconds since first call of clock() ! 1030: * ! 1031: * RP: this function is missing from SAS/C library. ! 1032: */ ! 1033: ! 1034: #include <time.h> ! 1035: ! 1036: long clock() ! 1037: { ! 1038: static unsigned long oldms = -1; ! 1039: unsigned long cl[2],ms; ! 1040: ! 1041: timer(cl); ! 1042: ms = cl[0] * 1000000 + cl[1] % 1000000; ! 1043: if(oldms == -1) { ! 1044: oldms = ms; ! 1045: return 0; ! 1046: } else { ! 1047: return ((long)(ms-oldms)); ! 1048: } ! 1049: } ! 1050: ! 1051: ! 1052: #endif /* AMIGA */ ! 1053: ! 1054: ! 1055: ! 1056: /*===========================================================================*/ ! 1057: /* ! 1058: * other stuff for non-MSDOS systems ! 1059: */ ! 1060: ! 1061: #ifdef ATARI ! 1062: #include <string.h> ! 1063: #endif ! 1064: ! 1065: #if !defined(MSDOS) && !defined(ATARI) ! 1066: #include <ctype.h> ! 1067: char *strlwr(char *s) ! 1068: { /* ! 1069: ** Turns string s into lower case. ! 1070: */ ! 1071: int c; ! 1072: char *p = s; ! 1073: while (c = *p) ! 1074: *p++ = to_lower(c); ! 1075: return(s); ! 1076: } ! 1077: #endif /* !MSDOS && !ATARI */ ! 1078: ! 1079: ! 1080: #ifdef strstr ! 1081: #undef strstr ! 1082: /* Not implemented on some systems - return first instance of s2 in s1 */ ! 1083: char *mystrstr (char *s1, char *s2) ! 1084: { int i; ! 1085: char *strchr(); ! 1086: ! 1087: if (!s2 || !*s2) ! 1088: return s1; ! 1089: for ( ; ; ) ! 1090: { if (!(s1 = strchr (s1, *s2))) ! 1091: return s1; ! 1092: for (i=1; s2[i] && (s1[i]==s2[i]); ++i) ! 1093: ; ! 1094: if (!s2[i]) ! 1095: return s1; ! 1096: ++s1; ! 1097: } ! 1098: } ! 1099: #endif /* strstr */ ! 1100: ! 1101: ! 1102: #ifdef fopen ! 1103: #undef fopen ! 1104: ! 1105: #ifdef ATARI ! 1106: #define F_BUF_SIZE 8192 /* seems to be a good value ... */ ! 1107: ! 1108: FILE *myfopen(const char *filename, const char *mode) ! 1109: /* Open streams with larger buffer to increase disk I/O speed. */ ! 1110: /* Adjust F_BUF_SIZE to change buffer size. */ ! 1111: { ! 1112: FILE *f; ! 1113: ! 1114: if ( (f = fopen(filename, mode)) != NULL ) ! 1115: if (setvbuf(f, NULL, _IOFBF, F_BUF_SIZE)) /* no memory? */ ! 1116: { ! 1117: fclose(f); /* then close it again */ ! 1118: f = fopen(filename, mode); /* and try again in normal mode */ ! 1119: } ! 1120: return(f); /* return either handle or NULL */ ! 1121: } ! 1122: ! 1123: #else /* ATARI */ ! 1124: ! 1125: /* Remove "b" from 2nd arg */ ! 1126: FILE *myfopen(char *filename, char *type) ! 1127: { char buf[10]; ! 1128: ! 1129: buf[0] = *type++; ! 1130: if (*type=='b') ! 1131: ++type; ! 1132: strcpy(buf+1,type); ! 1133: return fopen(filename, buf); ! 1134: } ! 1135: #endif /* not ATARI */ ! 1136: #endif /* fopen */ ! 1137: ! 1138: ! 1139: #ifndef MSDOS ! 1140: #ifdef OS2 ! 1141: ! 1142: static int chr = -1; ! 1143: ! 1144: int kbhit(void) ! 1145: { ! 1146: if (chr == -1) ! 1147: chr = _read_kbd(0, 0, 0); ! 1148: return (chr != -1); ! 1149: } ! 1150: ! 1151: int getch(void) ! 1152: { ! 1153: int c; ! 1154: ! 1155: if (chr >= 0) { ! 1156: c = chr; ! 1157: chr = -1; ! 1158: } else ! 1159: c = _read_kbd(0, 1, 0); ! 1160: ! 1161: return c; ! 1162: } ! 1163: ! 1164: #endif /* OS2 */ ! 1165: #endif /* MSDOS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.