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