📄 ttyio.c
字号:
/*--------------------------------------------------------------------------- ttyio.c This file contains routines for doing console input/output, including code for non-echoing input. It is used by the encryption/decryption code but does not contain any restricted code itself. This file is shared between Info-ZIP's Zip and UnZip. Contains: echo() (VMS only) Echon() (Unix only) Echoff() (Unix only) screenlines() (Unix only) zgetch() (Unix and non-Unix versions) getp() ("PC," Unix/Atari/Be, VMS/VMCMS/MVS) ---------------------------------------------------------------------------*/#include "zip.h"#include "crypt.h"#if (CRYPT || (defined(UNZIP) && !defined(FUNZIP)))/* Non-echo console/keyboard input is needed for (en/de)cryption's password * entry, and for UnZip(SFX)'s MORE and Pause features. * (The corresponding #endif is found at the end of this module.) */#include "ttyio.h"#ifndef PUTC# define PUTC putc#endif#ifdef ZIP# ifdef GLOBAL /* used in Amiga system headers, maybe others too */# undef GLOBAL# endif# define GLOBAL(g) g#else# define GLOBAL(g) G.g#endif#ifdef __BEOS__ /* why yes, we do */# define HAVE_TERMIOS_H#endif#ifdef _POSIX_VERSION# ifndef USE_POSIX_TERMIOS# define USE_POSIX_TERMIOS /* use POSIX style termio (termios) */# endif# ifndef HAVE_TERMIOS_H# define HAVE_TERMIOS_H /* POSIX termios.h */# endif#endif /* _POSIX_VERSION */#ifdef UNZIP /* Zip handles this with the unix/configure script */# ifndef _POSIX_VERSION# if (defined(SYSV) || defined(CRAY)) && !defined(__MINT__)# ifndef USE_SYSV_TERMIO# define USE_SYSV_TERMIO# endif# ifdef COHERENT# ifndef HAVE_TERMIO_H# define HAVE_TERMIO_H# endif# ifdef HAVE_SYS_TERMIO_H# undef HAVE_SYS_TERMIO_H# endif# else /* !COHERENT */# ifdef HAVE_TERMIO_H# undef HAVE_TERMIO_H# endif# ifndef HAVE_SYS_TERMIO_H# define HAVE_SYS_TERMIO_H# endif# endif /* ?COHERENT */# endif /* (SYSV || CRAY) && !__MINT__ */# endif /* !_POSIX_VERSION */# if !(defined(BSD4_4) || defined(SYSV) || defined(__convexc__))# ifndef NO_FCNTL_H# define NO_FCNTL_H# endif# endif /* !(BSD4_4 || SYSV || __convexc__) */#endif /* UNZIP */#ifdef HAVE_TERMIOS_H# ifndef USE_POSIX_TERMIOS# define USE_POSIX_TERMIOS# endif#endif#if (defined(HAVE_TERMIO_H) || defined(HAVE_SYS_TERMIO_H))# ifndef USE_SYSV_TERMIO# define USE_SYSV_TERMIO# endif#endif#if (defined(UNZIP) && !defined(FUNZIP) && defined(UNIX) && defined(MORE))# include <sys/ioctl.h># define GOT_IOCTL_H /* int ioctl OF((int, int, zvoid *)); GRR: may need for some systems */#endif#ifndef HAVE_WORKING_GETCH /* include system support for switching of console echo */# ifdef VMS# include <descrip.h># include <iodef.h># include <ttdef.h># include <starlet.h># include <ssdef.h># else /* !VMS */# ifdef HAVE_TERMIOS_H# include <termios.h># define sgttyb termios# define sg_flags c_lflag# define GTTY(f, s) tcgetattr(f, (zvoid *) s)# define STTY(f, s) tcsetattr(f, TCSAFLUSH, (zvoid *) s)# else /* !HAVE_TERMIOS_H */# ifdef USE_SYSV_TERMIO /* Amdahl, Cray, all SysV? */# ifdef HAVE_TERMIO_H# include <termio.h># endif# ifdef HAVE_SYS_TERMIO_H# include <sys/termio.h># endif# ifdef NEED_PTEM# include <sys/stream.h># include <sys/ptem.h># endif# define sgttyb termio# define sg_flags c_lflag# define GTTY(f,s) ioctl(f,TCGETA,(zvoid *)s)# define STTY(f,s) ioctl(f,TCSETAW,(zvoid *)s)# else /* !USE_SYSV_TERMIO */# ifndef CMS_MVS# if (!defined(MINIX) && !defined(GOT_IOCTL_H))# include <sys/ioctl.h># endif# include <sgtty.h># define GTTY gtty# define STTY stty# ifdef UNZIP /* * XXX : Are these declarations needed at all ???? */ /* * GRR: let's find out... Hmmm, appears not... int gtty OF((int, struct sgttyb *)); int stty OF((int, struct sgttyb *)); */# endif# endif /* !CMS_MVS */# endif /* ?USE_SYSV_TERMIO */# endif /* ?HAVE_TERMIOS_H */# ifndef NO_FCNTL_H# ifndef UNZIP# include <fcntl.h># endif# else char *ttyname OF((int));# endif# endif /* ?VMS */#endif /* !HAVE_WORKING_GETCH */#ifndef HAVE_WORKING_GETCH#ifdef VMS/* * Turn keyboard echoing on or off (VMS). Loosely based on VMSmunch.c * and hence on Joe Meadows' file.c code. */int echo(opt) int opt;{ /* * For VMS v5.x: * IO$_SENSEMODE/SETMODE info: Programming, Vol. 7A, System Programming, * I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6 * sys$assign(), sys$qio() info: Programming, Vol. 4B, System Services, * System Services Reference Manual, pp. sys-23, sys-379 * fixed-length descriptor info: Programming, Vol. 3, System Services, * Intro to System Routines, sec. 2.9.2 * Greg Roelofs, 15 Aug 91 */ /* SKM: make global? */ static struct dsc$descriptor_s DevDesc = {11, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$COMMAND"}; /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */ static short DevChan, iosb[4]; static long status; static unsigned long oldmode[2], newmode[2]; /* each = 8 bytes */ /* assign a channel to standard input */ status = sys$assign(&DevDesc, &DevChan, 0, 0); if (!(status & 1)) return status; /* use sys$qio and the IO$_SENSEMODE function to determine the current * tty status (for password reading, could use IO$_READVBLK function * instead, but echo on/off will be more general) */ status = sys$qiow(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0, oldmode, 8, 0, 0, 0, 0); if (!(status & 1)) return status; status = iosb[0]; if (!(status & 1)) return status; /* copy old mode into new-mode buffer, then modify to be either NOECHO or * ECHO (depending on function argument opt) */ newmode[0] = oldmode[0]; newmode[1] = oldmode[1]; if (opt == 0) /* off */ newmode[1] |= TT$M_NOECHO; /* set NOECHO bit */ else newmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */ /* use the IO$_SETMODE function to change the tty status */ status = sys$qiow(0, DevChan, IO$_SETMODE, &iosb, 0, 0, newmode, 8, 0, 0, 0, 0); if (!(status & 1)) return status; status = iosb[0]; if (!(status & 1)) return status; /* deassign the sys$input channel by way of clean-up */ status = sys$dassgn(DevChan); if (!(status & 1)) return status; return SS$_NORMAL; /* we be happy */} /* end function echo() */#else /* !VMS: basically Unix *//* For VM/CMS and MVS, non-echo terminal input is not (yet?) supported. */#ifndef CMS_MVS#ifdef ZIP /* moved to globals.h for UnZip */ static int echofd=(-1); /* file descriptor whose echo is off */#endif/* * Turn echo off for file descriptor f. Assumes that f is a tty device. */void Echoff(__G__ f) __GDEF int f; /* file descriptor for which to turn echo off */{ struct sgttyb sg; /* tty device structure */ GLOBAL(echofd) = f; GTTY(f, &sg); /* get settings */ sg.sg_flags &= ~ECHO; /* turn echo off */ STTY(f, &sg);}/* * Turn echo back on for file descriptor echofd. */void Echon(__G) __GDEF{ struct sgttyb sg; /* tty device structure */ if (GLOBAL(echofd) != -1) { GTTY(GLOBAL(echofd), &sg); /* get settings */ sg.sg_flags |= ECHO; /* turn echo on */ STTY(GLOBAL(echofd), &sg); GLOBAL(echofd) = -1; }}#endif /* !CMS_MVS */#endif /* ?VMS */#if (defined(UNZIP) && !defined(FUNZIP))#if (defined(UNIX) || defined(__BEOS__))#ifdef MORE/* * Get the number of lines on the output terminal. SCO Unix apparently * defines TIOCGWINSZ but doesn't support it (!M_UNIX). * * GRR: will need to know width of terminal someday, too, to account for * line-wrapping. */#if (defined(TIOCGWINSZ) && !defined(M_UNIX))int screenlines(){ struct winsize wsz;#ifdef DEBUG_WINSZ static int firsttime = TRUE;#endif /* see termio(4) under, e.g., SunOS */ if (ioctl(1, TIOCGWINSZ, &wsz) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -