|
|
1.1 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: #include <stdio.h>
10: #include "pgp.h"
11:
12:
13: /*===========================================================================*/
14: /*
15: * UNIX
16: */
17:
18: #ifdef UNIX
19: /*
20: * Define USE_SELECT to use the select() system call to check if
21: * keyboard input is available. Define USE_NBIO to use non-blocking
22: * read(). If you don't define anything the FIONREAD ioctl() command
23: * will be used.
24: *
25: * Define NOTERMIO if you don't have the termios stuff
26: */
27: #include <sys/types.h>
28: #include <fcntl.h>
29: #ifndef NeXT
30: #include <unistd.h>
31: #endif
32:
33: #ifndef NOTERMIO
34: #ifndef M_XENIX
35: #include <termios.h>
36: #else
37: #include <termio.h>
38: #endif /* not M_XENIX */
39: #else
40: #include <sgtty.h>
41: #endif
42:
43: #ifdef USE_SELECT
44: #include <sys/time.h>
45: #else
46: #ifndef USE_NBIO
47: #include <sys/ioctl.h> /* for FIONREAD */
48: #ifndef FIONREAD
49: #define FIONREAD TIOCINQ
50: #endif
51: #endif
52: #endif
53: #include <signal.h>
54:
55: static void setsigs(void);
56: static void rmsigs(void);
57: static void sig1(int);
58: static void sig2(int);
59: void breakHandler(int);
60: static int ttyfd= -1;
61: #ifndef M_XENIX
62: static void (*savesig)(int);
63: #else
64: static int (*savesig)(int);
65: #endif
66:
67: void ttycbreak(void);
68: void ttynorm(void);
69:
70:
71: #ifndef NOTERMIO
72: #ifndef M_XENIX
73: static struct termios itio, tio;
74: #else
75: static struct termio itio, tio;
76: #endif /* not M_XENIX */
77: #else
78: static struct sgttyb isg, sg;
79: #endif
80:
81: #ifdef USE_NBIO
82: static int kbuf= -1; /* buffer to store char read by kbhit() */
83: static int fflags;
84: #endif
85:
86: static int gottio = 0;
87:
88: void ttycbreak(void)
89: {
90: if (ttyfd == -1) {
91: if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) {
92: fprintf(stderr, "cannot open tty, using stdin\n");
93: ttyfd = 0;
94: }
95: }
96: #ifndef NOTERMIO
97: #ifndef M_XENIX
98: if (tcgetattr(ttyfd, &tio) < 0)
99: #else
100: if (ioctl(ttyfd, TCGETA, &tio) < 0)
101: #endif /* not M_XENIX */
102: { fprintf (stderr, "\nUnable to get terminal characteristics: ");
103: perror("ioctl");
104: exitPGP(1);
105: }
106: itio = tio;
107: setsigs();
108: gottio = 1;
109: #ifdef USE_NBIO
110: tio.c_cc[VMIN] = 0;
111: #else
112: tio.c_cc[VMIN] = 1;
113: #endif
114: tio.c_cc[VTIME] = 0;
115: tio.c_lflag &= ~(ECHO|ICANON);
116: #ifndef M_XENIX
117: tcsetattr (ttyfd, TCSAFLUSH, &tio);
118: #else
119: ioctl(ttyfd, TCSETAW, &tio);
120: #endif /* not M_XENIX */
121: #else
122: if (ioctl(ttyfd, TIOCGETP, &sg) < 0)
123: { fprintf (stderr, "\nUnable to get terminal characteristics: ");
124: perror("ioctl");
125: exitPGP(1);
126: }
127: isg = sg;
128: setsigs();
129: gottio = 1;
130: sg.sg_flags |= CBREAK;
131: sg.sg_flags &= ~ECHO;
132: ioctl(ttyfd, TIOCSETP, &sg);
133: #endif /* !NOTERMIO */
134: #ifdef USE_NBIO
135: if ((fflags = fcntl(ttyfd, F_GETFL)) != -1)
136: fcntl(ttyfd, F_SETFL, fflags|O_NDELAY);
137: #endif
138: }
139:
140:
141: void ttynorm(void)
142: { gottio = 0;
143: #ifdef USE_NBIO
144: if (fcntl(ttyfd, F_SETFL, fflags) == -1)
145: perror("fcntl");
146: #endif
147: #ifndef NOTERMIO
148: #ifndef M_XENIX
149: tcsetattr (ttyfd, TCSAFLUSH, &itio);
150: #else
151: ioctl(ttyfd, TCSETAW, &itio);
152: #endif /* not M_XENIX */
153: #else
154: ioctl(ttyfd, TIOCSETP, &isg);
155: #endif
156: rmsigs();
157: }
158:
159: static void sig1 (int sig)
160: {
161: #ifndef NOTERMIO
162: #ifndef M_XENIX
163: tcsetattr (ttyfd, TCSANOW, &itio);
164: #else
165: ioctl(ttyfd, TCSETAW, &itio);
166: #endif /* not M_XENIX */
167: #else
168: ioctl(ttyfd, TIOCSETP, &isg);
169: #endif
170: signal (sig, SIG_DFL);
171: if (sig == SIGINT)
172: breakHandler(SIGINT);
173: kill (getpid(), sig);
174: }
175:
176: static void sig2 (int sig)
177: { if (gottio)
178: ttycbreak();
179: else
180: setsigs();
181: }
182:
183: static void setsigs(void)
184: { savesig = signal (SIGINT, sig1);
185: #ifdef SIGTSTP
186: signal (SIGCONT, sig2);
187: signal (SIGTSTP, sig1);
188: #endif
189: }
190:
191: static void rmsigs(void)
192: { signal (SIGINT, savesig);
193: #ifdef SIGTSTP
194: signal (SIGCONT, SIG_DFL);
195: signal (SIGTSTP, SIG_DFL);
196: #endif
197: }
198:
199: #ifndef CRUDE
200: int kbhit(void)
201: /* Return TRUE if there is a key to be read */
202: {
203: #ifdef USE_SELECT /* use select() system call */
204: struct timeval t;
205: fd_set n;
206: int r;
207:
208: timerclear(&t);
209: FD_ZERO(&n);
210: FD_SET(ttyfd, &n);
211: r = select(32, &n, NULL, NULL, &t);
212: if (r == -1) {
213: perror("select");
214: exitPGP(1);
215: }
216: return r > 0;
217: #else
218: #ifdef USE_NBIO /* use non-blocking read() */
219: unsigned char ch;
220: if (kbuf >= 0)
221: return(1);
222: if (read(ttyfd, &ch, 1) == 1) {
223: kbuf = ch;
224: return(1);
225: }
226: return(0);
227: #else
228: long lf;
229: if (ioctl(ttyfd, FIONREAD, &lf) == -1) {
230: perror("ioctl: FIONREAD");
231: exitPGP(1);
232: }
233: return(lf);
234: #endif
235: #endif
236: }
237: #endif /* !CRUDE */
238:
239: int getch(void)
240: {
241: char c;
242: #ifdef USE_NBIO
243: while (!kbhit()); /* kbhit() does the reading */
244: c = kbuf;
245: kbuf = -1;
246: #else
247: read(ttyfd, &c, 1);
248: #endif
249: return(c);
250: }
251:
252: #ifdef BSD_OLD
253: void *memset(s, c, n)
254: void *s;
255: register int c, n;
256: {
257: register char *p = s;
258: ++n;
259: while (--n)
260: *p++ = c;
261: return(s);
262: }
263: int memcmp(s1, s2, n)
264: register unsigned char *s1, *s2;
265: register int n;
266: {
267: if (!n)
268: return(0);
269: while (--n && *s1 == *s2) {
270: ++s1;
271: ++s2;
272: }
273: return(*s1 - *s2);
274: }
275: void *memcpy(s1, s2, n)
276: register char *s1, *s2;
277: register int n;
278: {
279: char *p = s1;
280: ++n;
281: while (--n)
282: *s1++ = *s2++;
283: return(p);
284: }
285: #endif /* BSD_OLD */
286:
287: #ifdef M_XENIX /* XENIX/286 specific stuff */
288: int remove(name)
289: char *name;
290: {
291: return unlink(name);
292: }
293:
294: int rename(old, new)
295: register char *old, *new;
296: {
297: (void) unlink(new);
298: if (link(old, new) < 0)
299: return -1;
300: if (unlink(old) < 0) {
301: (void) unlink(new);
302: return -1;
303: }
304: return 0;
305: }
306: #endif /* M_XENIX */
307: #endif /* UNIX */
308:
309:
310:
311: /*===========================================================================*/
312: /*
313: * VMS
314: */
315:
316: #ifdef VMS /* kbhit()/getch() equivalent */
317:
318: /*
319: * This code defines an equivalent version of kbhit() and getch() for
320: * use under VAX/VMS, together with an exit handler to reset terminal
321: * characteristics.
322: *
323: * This code assumes that kbhit() has been invoked to test that there
324: * are characters in the typeahead buffer before getch() is invoked to
325: * get the answer.
326: */
327:
328: #include <descrip.h>
329: #include <iodef.h>
330: #ifdef VAXC
331: #include <ttdef.h>
332: #include <tt2def.h>
333: #include <dcdef.h>
334: #else /* Probably GNU */
335: #include <vms/$ttdef.h>
336: #include <vms/$tt2def.h>
337: #include <vms/$dcdef.h>
338: #endif /* VAXC */
339: static volatile short _kbhitChan_ = 0;
340:
341: static volatile struct IOSB {
342: unsigned short sts;
343: unsigned short byteCount;
344: unsigned short terminator;
345: unsigned short terminatorSize;
346: } iosb;
347: static $DESCRIPTOR (kbdev_desc, "SYS$COMMAND:");
348:
349: static volatile struct {
350: char Class;
351: char Type;
352: unsigned short BufferSize;
353: unsigned int Mode;
354: int ExtChar;
355: } CharBuf, OldCharBuf;
356:
357: void kbhit_handler(int *sts)
358: {
359: int mysts;
360:
361: CharBuf.Mode = OldCharBuf.Mode;
362: CharBuf.ExtChar = OldCharBuf.ExtChar;
363: CharBuf.Mode &= ~TT$M_NOECHO;
364: CharBuf.ExtChar &= ~TT2$M_PASTHRU;
365: if ((mysts = sys$qiow (
366: 0,
367: _kbhitChan_,
368: IO$_SETMODE,
369: &iosb,
370: 0,
371: 0,
372: &CharBuf,
373: 12,
374: 0,
375: 0,
376: 0,
377: 0)) & 01) mysts = iosb.sts;
378: (void) sys$dassgn (
379: _kbhitChan_);
380: _kbhitChan_ = 0;
381: if (!(mysts & 01)) {
382: fprintf(stderr,"\nFailed to reset terminal characteristics!");
383: (void) lib$signal(mysts);
384: }
385: }
386:
387: unsigned int exsts;
388:
389: static struct {
390: int link;
391: void *rtn;
392: int argcnt;
393: int *stsaddr;
394: } exhblk = { 0, &(kbhit_handler), 1, &(exsts)};
395:
396: int kbhit()
397: {
398: int sts = 1;
399:
400: struct {
401: unsigned short TypAhdCnt;
402: char FirstChar;
403: char Reserved[5];
404: } TypCharBuf;
405:
406: if (_kbhitChan_ == 0) {
407: if ((sts = sys$assign (
408: &kbdev_desc,
409: &_kbhitChan_,
410: 0,
411: 0)) & 1 == 0) lib$stop(sts);
412: if ((sts = sys$qiow (
413: 0,
414: _kbhitChan_,
415: IO$_SENSEMODE,
416: &iosb,
417: 0,
418: 0,
419: &CharBuf,
420: 12,
421: 0,
422: 0,
423: 0,
424: 0)) & 01) sts = iosb.sts;
425: if (sts & 01) {
426: if (!(CharBuf.Class & DC$_TERM)) {
427: fprintf(stderr,"\nNot running on a terminal");
428: exitPGP(1);
429: } else {
430: OldCharBuf.Mode = CharBuf.Mode;
431: OldCharBuf.ExtChar = CharBuf.ExtChar;
432: CharBuf.Mode |= TT$M_NOECHO;
433: CharBuf.ExtChar |= TT2$M_PASTHRU;
434: if ((sts = sys$qiow (
435: 0,
436: _kbhitChan_,
437: IO$_SETMODE,
438: &iosb,
439: 0,
440: 0,
441: &CharBuf,
442: 12,
443: 0,
444: 0,
445: 0,
446: 0)) & 01) sts = iosb.sts;
447: if (sts & 01) {
448: /*
449: ** Declare Exit Handler
450: */
451: (void) sys$dclexh (&exhblk);
452: } else {
453: fprintf(stderr,"\nFailed to set terminal characteristics!");
454: (void) lib$signal(sts);
455: exitPGP(1);
456: }
457: }
458: }
459: }
460: /*
461: ** Get typeahead count
462: */
463: if ((sts = sys$qiow (
464: 0,
465: _kbhitChan_,
466: IO$_SENSEMODE | IO$M_TYPEAHDCNT,
467: &iosb,
468: 0,
469: 0,
470: &TypCharBuf,
471: 8,
472: 0,
473: 0,
474: 0,
475: 0)) & 01) sts = iosb.sts;
476: if (sts & 01) return(TypCharBuf.TypAhdCnt>0);
477: (void) lib$signal(sts);
478: exitPGP(1);
479: }
480:
481: int getch()
482: {
483: unsigned int sts;
484: volatile char CharBuf;
485:
486: if ((sts = sys$qiow (
487: 0,
488: _kbhitChan_,
489: IO$_READVBLK,
490: &iosb,
491: 0,
492: 0,
493: &CharBuf,
494: 1,
495: 0,
496: 0,
497: 0,
498: 0)) & 01) sts = iosb.sts;
499: if (sts & 01) return ((int) CharBuf);
500: fprintf(stderr,"\nFailed to get character");
501: (void) lib$signal(sts);
502: }
503:
504: ttynorm()
505: {
506: int sts;
507:
508: if (_kbhitChan_ != 0) {
509: (void) SYS$CANEXH(&exhblk);
510: kbhit_handler(&sts);
511: }
512: }
513:
514: void ttycbreak ()
515: {
516: ttynorm();
517: }
518:
519: unsigned long vms_clock_bits[2]; /* VMS Hardware Clock */
520: const long vms_ticks_per_update = 100000L; /* Clock update int. */
521:
522: #endif /* VMS */
523:
524:
525:
526: /*========================================================================*/
527: /*
528: * AMIGA
529: */
530:
531: #ifdef AMIGA /* Amiga-specific stuff */
532:
533: #include <exec/types.h>
534: #include <exec/memory.h>
535: #include <exec/ports.h>
536: #include <libraries/dosextens.h>
537: #ifdef LATTICE
538: #include <proto/exec.h>
539: #include <proto/dos.h>
540: #endif /* LATTICE */
541: extern FILE *pgpout;
542: extern int aecho;
543:
544: FILE *tmpfile()
545: {
546: FILE *fp;
547:
548: if ((fp=fopen("tmpfile.tmp","w+b"))==NULL) {
549: perror("tmpfile.tmp");
550: return(NULL);
551: }
552: return(fp);
553:
554: }
555:
556: /* amiga version of getch()
557: Cor Bosman , jul-22-92
558: */
559:
560:
561: sendpacket(struct MsgPort *rec,LONG action,LONG arg1)
562: {
563: struct StandardPacket *pkt;
564: struct msgPort *rp;
565: LONG res1 = 0L;
566:
567: if (rp = (struct MsgPort *)CreatePort(NULL,0L)) {
568: if (pkt = (struct StandardPacket *)\
569: AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
570: pkt->sp_Msg.mn_Node.ln_Name = (BYTE *)&pkt->sp_Pkt;
571: pkt->sp_Pkt.dp_Link = &pkt->sp_Msg;
572: pkt->sp_Pkt.dp_Port = rp;
573: pkt->sp_Pkt.dp_Type = action;
574: pkt->sp_Pkt.dp_Arg1 = arg1;
575: PutMsg(rec,&pkt->sp_Msg);
576: WaitPort(rp);
577: GetMsg(rp);
578: res1 = pkt->sp_Pkt.dp_Res1;
579: FreeMem((UBYTE*)pkt,sizeof(struct StandardPacket));
580: }
581: DeletePort(rp);
582: }
583: return(res1);
584:
585: }
586:
587: /* ttycbreak for amiga.
588: * Cor Bosman , jul-30-92
589: */
590:
591: void ttycbreak()
592: {
593: BPTR in,out;
594: char buf[128];
595: struct MsgPort *ch;
596:
597: in=Input();
598: out=Output();
599: ch = ((struct FileHandle *)BADDR(in))->fh_Type;
600: sendpacket(ch,ACTION_SCREEN_MODE,-1L);
601: }
602:
603: /* ttynorm for amiga
604: * Cor Bosman , jul-30-92
605: */
606:
607: void ttynorm()
608: {
609:
610: BPTR in,out;
611: char buf[128];
612: struct MsgPort *ch;
613:
614: in=Input();
615: out=Output();
616: ch = ((struct FileHandle *)BADDR(in))->fh_Type;
617: sendpacket(ch,ACTION_SCREEN_MODE,0L);
618: }
619:
620: char getch(void)
621: {
622: char buf[128];
623: BPTR in,out;
624:
625: in = Input();
626: out = Output();
627: Read(in,buf,1);
628: if (aecho)
629: Write(out, buf, 1);
630: return(buf[0]);
631: }
632:
633: /* kbhit() function for amiga.
634: * Cor Bosman , jul-30-92
635: */
636:
637: int kbhit()
638: {
639: if(WaitForChar(Input(), 1)) return 1;
640: return 0;
641: }
642:
643: #ifdef LATTICE
644:
645: /*
646: * Lattice-C ^C-Handler
647: */
648:
649: int CXBRK()
650: {
651: BPTR in,out;
652: struct MsgPort *ch;
653: in=Input();
654: out=Output();
655:
656: /* it might happen we catch a ^C while in cbreak mode.
657: * so always set the screen to the normal mode.
658: */
659:
660: ch = ((struct FileHandle *)BADDR(in))->fh_Type;
661: sendpacket(ch, ACTION_SCREEN_MODE, 0L);
662:
663:
664: fprintf(pgpout, "\n*** Program Aborted.\n");
665: exitPGP(6); /* INTERRUPT */
666: }
667: #endif
668:
669: #endif /* AMIGA */
670:
671:
672:
673: /*===========================================================================*/
674: /*
675: * other stuff for non-MSDOS systems
676: */
677:
678: #ifdef ATARI
679: #include <string.h>
680: #endif
681:
682: #if !defined(MSDOS) && !defined(ATARI)
683: #include <ctype.h>
684: char *strlwr(char *s)
685: { /*
686: ** Turns string s into lower case.
687: */
688: int c;
689: char *p = s;
690: while (c = *p)
691: *p++ = tolower(c);
692: return(s);
693: }
694: #endif /* !MSDOS && !ATARI */
695:
696:
697: #ifdef strstr
698: #undef strstr
699: /* Not implemented on some systems - return first instance of s2 in s1 */
700: char *mystrstr (char *s1, char *s2)
701: { int i;
702: char *strchr();
703:
704: if (!s2 || !*s2)
705: return s1;
706: for ( ; ; )
707: { if (!(s1 = strchr (s1, *s2)))
708: return s1;
709: for (i=1; s2[i] && (s1[i]==s2[i]); ++i)
710: ;
711: if (!s2[i])
712: return s1;
713: ++s1;
714: }
715: }
716: #endif /* strstr */
717:
718:
719: #ifdef fopen
720: #undef fopen
721:
722: #ifdef ATARI
723: #define F_BUF_SIZE 8192 /* seems to be a good value ... */
724:
725: FILE *myfopen(const char *filename, const char *mode)
726: /* Open streams with larger buffer to increase disk I/O speed. */
727: /* Adjust F_BUF_SIZE to change buffer size. */
728: {
729: FILE *f;
730:
731: if ( (f = fopen(filename, mode)) != NULL )
732: if (setvbuf(f, NULL, _IOFBF, F_BUF_SIZE)) /* no memory? */
733: {
734: fclose(f); /* then close it again */
735: f = fopen(filename, mode); /* and try again in normal mode */
736: }
737: return(f); /* return either handle or NULL */
738: }
739:
740: #else /* ATARI */
741:
742: /* Remove "b" from 2nd arg */
743: FILE *myfopen(char *filename, char *type)
744: { char buf[10];
745:
746: buf[0] = *type++;
747: if (*type=='b')
748: ++type;
749: strcpy(buf+1,type);
750: return fopen(filename, buf);
751: }
752: #endif /* not ATARI */
753: #endif /* fopen */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.