?? ttyio.c
字號:
/* Copyright (c) 1990-2001 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//*--------------------------------------------------------------------------- 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) screensize() (Unix only) zgetch() (Unix, VMS, and non-Unix/VMS versions) getp() ("PC," Unix/Atari/Be, VMS/VMCMS/MVS) ---------------------------------------------------------------------------*/#define __TTYIO_C /* identifies this source module */#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 VMSstatic 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}; *//* * 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 */ short DevChan, iosb[4]; long status; unsigned long ttmode[2]; /* space for 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, ttmode, 8, 0, 0, 0, 0); if (!(status & 1)) return status; status = iosb[0]; if (!(status & 1)) return status; /* modify mode buffer to be either NOECHO or ECHO * (depending on function argument opt) */ if (opt == 0) /* off */ ttmode[1] |= TT$M_NOECHO; /* set NOECHO bit */ else ttmode[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, ttmode, 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() *//* * Read a single character from keyboard in non-echoing mode (VMS). * (returns EOF in case of errors) */int tt_getch(){ short DevChan, iosb[4]; long status; char kbbuf[16]; /* input buffer with - some - excess length */ /* assign a channel to standard input */ status = sys$assign(&DevDesc, &DevChan, 0, 0); if (!(status & 1)) return EOF; /* read a single character from SYS$COMMAND (no-echo) and * wait for completion */ status = sys$qiow(0,DevChan, IO$_READVBLK|IO$M_NOECHO|IO$M_NOFILTR, &iosb, 0, 0, &kbbuf, 1, 0, 0, 0, 0); if ((status&1) == 1) status = iosb[0]; /* deassign the sys$input channel by way of clean-up * (for this step, we do not need to check the completion status) */ sys$dassgn(DevChan); /* return the first char read, or EOF in case the read request failed */ return (int)(((status&1) == 1) ? (uch)kbbuf[0] : EOF);} /* end function tt_getch() */#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 screensize(tt_rows, tt_cols) int *tt_rows; int *tt_cols;{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -