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