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