| 
							- /*
 -   Copyright (c) 1990-2008 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
 - 
 - #if (defined(__ATHEOS__) || defined(__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>
 -      /* Workaround for broken header files of older DECC distributions
 -       * that are incompatible with the /NAMES=AS_IS qualifier. */
 - #    define sys$assign SYS$ASSIGN
 - #    define sys$dassgn SYS$DASSGN
 - #    define sys$qiow SYS$QIOW
 - #    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
 - 
 - 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}; */
 - 
 - /*
 -  * 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))
 - 
 - #ifdef ATH_BEO_UNX
 - #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;
 - {
 -     struct winsize wsz;
 - #ifdef DEBUG_WINSZ
 -     static int firsttime = TRUE;
 - #endif
 - 
 -     /* see termio(4) under, e.g., SunOS */
 -     if (ioctl(1, TIOCGWINSZ, &wsz) == 0) {
 - #ifdef DEBUG_WINSZ
 -         if (firsttime) {
 -             firsttime = FALSE;
 -             fprintf(stderr, "ttyio.c screensize():  ws_row = %d\n",
 -               wsz.ws_row);
 -             fprintf(stderr, "ttyio.c screensize():  ws_col = %d\n",
 -               wsz.ws_col);
 -         }
 - #endif
 -         /* number of rows */
 -         if (tt_rows != NULL)
 -             *tt_rows = (int)((wsz.ws_row > 0) ? wsz.ws_row : 24);
 -         /* number of columns */
 -         if (tt_cols != NULL)
 -             *tt_cols = (int)((wsz.ws_col > 0) ? wsz.ws_col : 80);
 -         return 0;    /* signal success */
 -     } else {         /* this happens when piping to more(1), for example */
 - #ifdef DEBUG_WINSZ
 -         if (firsttime) {
 -             firsttime = FALSE;
 -             fprintf(stderr,
 -               "ttyio.c screensize():  ioctl(TIOCGWINSZ) failed\n"));
 -         }
 - #endif
 -         /* VT-100 assumed to be minimal hardware */
 -         if (tt_rows != NULL)
 -             *tt_rows = 24;
 -         if (tt_cols != NULL)
 -             *tt_cols = 80;
 -         return 1;       /* signal failure */
 -     }
 - }
 - 
 - #else /* !TIOCGWINSZ: service not available, fall back to semi-bogus method */
 - 
 - int screensize(tt_rows, tt_cols)
 -     int *tt_rows;
 -     int *tt_cols;
 - {
 -     char *envptr, *getenv();
 -     int n;
 -     int errstat = 0;
 - 
 -     /* GRR:  this is overly simplistic, but don't have access to stty/gtty
 -      * system anymore
 -      */
 -     if (tt_rows != NULL) {
 -         envptr = getenv("LINES");
 -         if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
 -             /* VT-100 assumed to be minimal hardware */
 -             *tt_rows = 24;
 -             errstat = 1;    /* signal failure */
 -         } else {
 -             *tt_rows = n;
 -         }
 -     }
 -     if (tt_cols != NULL) {
 -         envptr = getenv("COLUMNS");
 -         if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
 -             *tt_cols = 80;
 -             errstat = 1;    /* signal failure */
 -         } else {
 -             *tt_cols = n;
 -         }
 -     }
 -     return errstat;
 - }
 - 
 - #endif /* ?(TIOCGWINSZ && !M_UNIX) */
 - #endif /* MORE */
 - 
 - 
 - /*
 -  * Get a character from the given file descriptor without echo or newline.
 -  */
 - int zgetch(__G__ f)
 -     __GDEF
 -     int f;                      /* file descriptor from which to read */
 - {
 - #if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
 -     char oldmin, oldtim;
 - #endif
 -     char c;
 -     struct sgttyb sg;           /* tty device structure */
 - 
 -     GTTY(f, &sg);               /* get settings */
 - #if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
 -     oldmin = sg.c_cc[VMIN];     /* save old values */
 -     oldtim = sg.c_cc[VTIME];
 -     sg.c_cc[VMIN] = 1;          /* need only one char to return read() */
 -     sg.c_cc[VTIME] = 0;         /* no timeout */
 -     sg.sg_flags &= ~ICANON;     /* canonical mode off */
 - #else
 -     sg.sg_flags |= CBREAK;      /* cbreak mode on */
 - #endif
 -     sg.sg_flags &= ~ECHO;       /* turn echo off, too */
 -     STTY(f, &sg);               /* set cbreak mode */
 -     GLOBAL(echofd) = f;         /* in case ^C hit (not perfect: still CBREAK) */
 - 
 -     read(f, &c, 1);             /* read our character */
 - 
 - #if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
 -     sg.c_cc[VMIN] = oldmin;     /* restore old values */
 -     sg.c_cc[VTIME] = oldtim;
 -     sg.sg_flags |= ICANON;      /* canonical mode on */
 - #else
 -     sg.sg_flags &= ~CBREAK;     /* cbreak mode off */
 - #endif
 -     sg.sg_flags |= ECHO;        /* turn echo on */
 -     STTY(f, &sg);               /* restore canonical mode */
 -     GLOBAL(echofd) = -1;
 - 
 -     return (int)(uch)c;
 - }
 - 
 - 
 - #else /* !ATH_BEO_UNX */
 - #ifndef VMS     /* VMS supplies its own variant of getch() */
 - 
 - 
 - int zgetch(__G__ f)
 -     __GDEF
 -     int f;    /* file descriptor from which to read (must be open already) */
 - {
 -     char c, c2;
 - 
 - /*---------------------------------------------------------------------------
 -     Get a character from the given file descriptor without echo; can't fake
 -     CBREAK mode (i.e., newline required), but can get rid of all chars up to
 -     and including newline.
 -   ---------------------------------------------------------------------------*/
 - 
 -     echoff(f);
 -     read(f, &c, 1);
 -     if (c != '\n')
 -         do {
 -             read(f, &c2, 1);   /* throw away all other chars up thru newline */
 -         } while (c2 != '\n');
 -     echon();
 -     return (int)c;
 - }
 - 
 - #endif /* !VMS */
 - #endif /* ?ATH_BEO_UNX */
 - 
 - #endif /* UNZIP && !FUNZIP */
 - #endif /* !HAVE_WORKING_GETCH */
 - 
 - 
 - #if CRYPT                       /* getp() is only used with full encryption */
 - 
 - /*
 -  * Simple compile-time check for source compatibility between
 -  * zcrypt and ttyio:
 -  */
 - #if (!defined(CR_MAJORVER) || (CR_MAJORVER < 2) || (CR_MINORVER < 7))
 -    error:  This Info-ZIP tool requires zcrypt 2.7 or later.
 - #endif
 - 
 - /*
 -  * Get a password of length n-1 or less into *p using the prompt *m.
 -  * The entered password is not echoed.
 -  */
 - 
 - #ifdef HAVE_WORKING_GETCH
 - /*
 -  * For the AMIGA, getch() is defined as Agetch(), which is in
 -  * amiga/filedate.c; SAS/C 6.x provides a getch(), but since Agetch()
 -  * uses the infrastructure that is already in place in filedate.c, it is
 -  * smaller.  With this function, echoff() and echon() are not needed.
 -  *
 -  * For the MAC, a non-echo macgetch() function is defined in the MacOS
 -  * specific sources which uses the event handling mechanism of the
 -  * desktop window manager to get a character from the keyboard.
 -  *
 -  * For the other systems in this section, a non-echo getch() function
 -  * is either contained the C runtime library (conio package), or getch()
 -  * is defined as an alias for a similar system specific RTL function.
 -  */
 - 
 - #ifndef WINDLL   /* WINDLL does not support a console interface */
 - #ifndef QDOS     /* QDOS supplies a variant of this function */
 - 
 - /* This is the getp() function for all systems (with TTY type user interface)
 -  * that supply a working `non-echo' getch() function for "raw" console input.
 -  */
 - char *getp(__G__ m, p, n)
 -     __GDEF
 -     ZCONST char *m;             /* prompt for password */
 -     char *p;                    /* return value: line input */
 -     int n;                      /* bytes available in p[] */
 - {
 -     char c;                     /* one-byte buffer for read() to use */
 -     int i;                      /* number of characters input */
 -     char *w;                    /* warning on retry */
 - 
 -     /* get password */
 -     w = "";
 -     do {
 -         fputs(w, stderr);       /* warning if back again */
 -         fputs(m, stderr);       /* display prompt and flush */
 -         fflush(stderr);
 -         i = 0;
 -         do {                    /* read line, keeping first n characters */
 -             if ((c = (char)getch()) == '\r')
 -                 c = '\n';       /* until user hits CR */
 -             if (c == 8 || c == 127) {
 -                 if (i > 0) i--; /* the `backspace' and `del' keys works */
 -             }
 -             else if (i < n)
 -                 p[i++] = c;     /* truncate past n */
 -         } while (c != '\n');
 -         PUTC('\n', stderr);  fflush(stderr);
 -         w = "(line too long--try again)\n";
 -     } while (p[i-1] != '\n');
 -     p[i-1] = 0;                 /* terminate at newline */
 - 
 -     return p;                   /* return pointer to password */
 - 
 - } /* end function getp() */
 - 
 - #endif /* !QDOS */
 - #endif /* !WINDLL */
 - 
 - 
 - #else /* !HAVE_WORKING_GETCH */
 - 
 - 
 - #if (defined(ATH_BEO_UNX) || defined(__MINT__))
 - 
 - #ifndef _PATH_TTY
 - #  ifdef __MINT__
 - #    define _PATH_TTY ttyname(2)
 - #  else
 - #    define _PATH_TTY "/dev/tty"
 - #  endif
 - #endif
 - 
 - char *getp(__G__ m, p, n)
 -     __GDEF
 -     ZCONST char *m;             /* prompt for password */
 -     char *p;                    /* return value: line input */
 -     int n;                      /* bytes available in p[] */
 - {
 -     char c;                     /* one-byte buffer for read() to use */
 -     int i;                      /* number of characters input */
 -     char *w;                    /* warning on retry */
 -     int f;                      /* file descriptor for tty device */
 - 
 - #ifdef PASSWD_FROM_STDIN
 -     /* Read from stdin. This is unsafe if the password is stored on disk. */
 -     f = 0;
 - #else
 -     /* turn off echo on tty */
 - 
 -     if ((f = open(_PATH_TTY, 0)) == -1)
 -         return NULL;
 - #endif
 -     /* get password */
 -     w = "";
 -     do {
 -         fputs(w, stderr);       /* warning if back again */
 -         fputs(m, stderr);       /* prompt */
 -         fflush(stderr);
 -         i = 0;
 -         echoff(f);
 -         do {                    /* read line, keeping n */
 -             read(f, &c, 1);
 -             if (i < n)
 -                 p[i++] = c;
 -         } while (c != '\n');
 -         echon();
 -         PUTC('\n', stderr);  fflush(stderr);
 -         w = "(line too long--try again)\n";
 -     } while (p[i-1] != '\n');
 -     p[i-1] = 0;                 /* terminate at newline */
 - 
 - #ifndef PASSWD_FROM_STDIN
 -     close(f);
 - #endif
 - 
 -     return p;                   /* return pointer to password */
 - 
 - } /* end function getp() */
 - 
 - #endif /* ATH_BEO_UNX || __MINT__ */
 - 
 - 
 - 
 - #if (defined(VMS) || defined(CMS_MVS))
 - 
 - char *getp(__G__ m, p, n)
 -     __GDEF
 -     ZCONST char *m;             /* prompt for password */
 -     char *p;                    /* return value: line input */
 -     int n;                      /* bytes available in p[] */
 - {
 -     char c;                     /* one-byte buffer for read() to use */
 -     int i;                      /* number of characters input */
 -     char *w;                    /* warning on retry */
 -     FILE *f;                    /* file structure for SYS$COMMAND device */
 - 
 - #ifdef PASSWD_FROM_STDIN
 -     f = stdin;
 - #else
 -     if ((f = fopen(ctermid(NULL), "r")) == NULL)
 -         return NULL;
 - #endif
 - 
 -     /* get password */
 -     fflush(stdout);
 -     w = "";
 -     do {
 -         if (*w)                 /* bug: VMS apparently adds \n to NULL fputs */
 -             fputs(w, stderr);   /* warning if back again */
 -         fputs(m, stderr);       /* prompt */
 -         fflush(stderr);
 -         i = 0;
 -         echoff(f);
 -         do {                    /* read line, keeping n */
 -             if ((c = (char)getc(f)) == '\r')
 -                 c = '\n';
 -             if (i < n)
 -                 p[i++] = c;
 -         } while (c != '\n');
 -         echon();
 -         PUTC('\n', stderr);  fflush(stderr);
 -         w = "(line too long--try again)\n";
 -     } while (p[i-1] != '\n');
 -     p[i-1] = 0;                 /* terminate at newline */
 - #ifndef PASSWD_FROM_STDIN
 -     fclose(f);
 - #endif
 - 
 -     return p;                   /* return pointer to password */
 - 
 - } /* end function getp() */
 - 
 - #endif /* VMS || CMS_MVS */
 - #endif /* ?HAVE_WORKING_GETCH */
 - #endif /* CRYPT */
 - #endif /* CRYPT || (UNZIP && !FUNZIP) */
 
 
  |