home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / TTYIO.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  7KB  |  284 lines

  1. /* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
  2.  *
  3.  * $Revision: 2.0.0.3 $
  4.  *
  5.  * ttyio.c - Terminal/Console I/O functions for all archive interfaces
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    These routines provide a consistent, general purpose interface to
  10.  *    the user via the users terminal, if it is available to the
  11.  *    process.
  12.  *
  13.  * AUTHOR
  14.  *
  15.  *     Mark H. Colburn, Open Systems Architects, Inc. (mark@minnetech.mn.org)
  16.  *
  17.  * COPYRIGHT
  18.  *
  19.  *    Copyright (c) 1989 Mark H. Colburn.  All rights reserved.
  20.  *
  21.  *    Redistribution and use in source and binary forms are permitted
  22.  *    provided that the above copyright notice and this paragraph are
  23.  *    duplicated in all such forms and that any documentation,
  24.  *    advertising materials, and other materials related to such
  25.  *    distribution and use acknowledge that the software was developed
  26.  *    by Mark H. Colburn.
  27.  *
  28.  *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  29.  *    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  30.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  31.  *
  32.  * $Log:    ttyio.c,v $
  33.  * Revision 2.0.0.3  89/10/13  02:36:00  mark
  34.  * Beta Test Freeze
  35.  *
  36.  */
  37.  
  38. #ifndef lint
  39. static char        *ident = "$Id: ttyio.c,v 2.0.0.3 89/10/13 02:36:00 mark Exp Locker: mark $";
  40. static char        *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  41. #endif /* ! lint */
  42.  
  43.  
  44. /* Headers */
  45.  
  46. #include "pax.h"
  47.  
  48.  
  49. /* open_tty - open the terminal for interactive queries
  50.  *
  51.  * DESCRIPTION
  52.  *
  53.  *     Assumes that background processes ignore interrupts and that the
  54.  *    open() or the isatty() will fail for processes which are not
  55.  *    attached to terminals. Returns a file descriptor or -1 if
  56.  *    unsuccessful.
  57.  *
  58.  * RETURNS
  59.  *
  60.  *    Returns a file descriptor which can be used to read and write
  61.  *    directly to the user's terminal, or -1 on failure.
  62.  *
  63.  * ERRORS
  64.  *
  65.  *    If SIGINT cannot be ignored, or the open fails, or the newly opened
  66.  *    terminal device is not a tty, then open_tty will return a -1 to the
  67.  *    caller.
  68.  */
  69.  
  70. #ifdef __STDC__
  71.  
  72. int
  73. open_tty(void)
  74.  
  75. #else
  76.  
  77. int
  78. open_tty()
  79.  
  80. #endif
  81. {
  82.     int                 fd;    /* file descriptor for terminal */
  83.  
  84. #ifdef VOIDSIG
  85.     void                (*intr) ();    /* used to restore interupts */
  86. #else
  87.     int                 (*intr) ();
  88. #endif
  89.  
  90.     DBUG_ENTER("open_tty");
  91.     if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
  92.     DBUG_RETURN(-1);
  93.     }
  94.     signal(SIGINT, intr);
  95.     if ((fd = open(TTY, O_RDWR)) < 0) {
  96.     DBUG_RETURN(-1);
  97.     }
  98.  
  99. #ifdef MSDOS
  100.     setmode(fd, O_TEXT);
  101. #endif /* MSDOS */
  102.  
  103.     if (isatty(fd)) {
  104.     DBUG_RETURN(fd);
  105.     }
  106.     /* FIXME: do error checking here */
  107.     close(fd);
  108.     DBUG_RETURN(-1);
  109. }
  110.  
  111.  
  112. /* nextask - ask a question and get a response
  113.  *
  114.  * DESCRIPTION
  115.  *
  116.  *    Give the user a prompt and wait for their response.  The prompt,
  117.  *    located in "msg" is printed, then the user is allowed to type
  118.  *    a response to the message.  The first "limit" characters of the
  119.  *    user response is stored in "answer".
  120.  *
  121.  *    Nextask ignores spaces and tabs.
  122.  *
  123.  * PARAMETERS
  124.  *
  125.  *    char *msg    - Message to display for user
  126.  *    char *answer    - Pointer to user's response to question
  127.  *    int limit    - Limit of length for user's response
  128.  *
  129.  * RETURNS
  130.  *
  131.  *    Returns the number of characters in the user response to the
  132.  *    calling function.  If an EOF was encountered, a -1 is returned to
  133.  *    the calling function.  If an error occured which causes the read
  134.  *    to return with a value of -1, then the function will return a
  135.  *    non-zero return status to the calling process, and abort
  136.  *    execution.
  137.  */
  138.  
  139. #ifdef __STDC__
  140.  
  141. int
  142. nextask(char *msg, char *answer, int limit)
  143.  
  144. #else
  145.  
  146. int
  147. nextask(msg, answer, limit)
  148.     char               *msg;    /* message to display for user */
  149.     char               *answer;    /* pointer to user's response to question */
  150.     int                 limit;    /* limit of length for user's response */
  151.  
  152. #endif
  153. {
  154.     int                 idx;    /* index into answer for character input */
  155.     int                 got;    /* number of characters read */
  156.     char                c;    /* character read */
  157.  
  158.     DBUG_ENTER("nextask");
  159.     if (ttyf < 0) {
  160.     fatal("/dev/tty Unavailable");
  161.     }
  162.     write(ttyf, msg, (uint) strlen(msg));
  163.     idx = 0;
  164.     while ((got = read(ttyf, &c, 1)) == 1) {
  165.     if (c == '\n') {
  166.         break;
  167.     } else if (c == ' ' || c == '\t') {
  168.         continue;
  169.     } else if (idx < limit - 1) {
  170.         answer[idx++] = c;
  171.     }
  172.     }
  173.     write(ttyf, "\r\n", 2);
  174.     if (got == 0) {        /* got an EOF */
  175.     DBUG_RETURN(-1);
  176.     }
  177.     if (got < 0) {
  178.     fatal(strerror());
  179.     }
  180.     answer[idx] = '\0';
  181.     DBUG_RETURN(0);
  182. }
  183.  
  184.  
  185. /* lineget - get a line from a given stream
  186.  *
  187.  * DESCRIPTION
  188.  *
  189.  *    Get a line of input for the stream named by "stream".  The data on
  190.  *    the stream is put into the buffer "buf".
  191.  *
  192.  * PARAMETERS
  193.  *
  194.  *    FILE *stream        - Stream to get input from
  195.  *    char *buf        - Buffer to put input into
  196.  *
  197.  * RETURNS
  198.  *
  199.  *     Returns 0 if successful, -1 at EOF.
  200.  */
  201.  
  202. #ifdef __STDC__
  203.  
  204. int
  205. lineget(FILE * stream, char *buf)
  206.  
  207. #else
  208.  
  209. int
  210. lineget(stream, buf)
  211.     FILE               *stream;    /* stream to get input from */
  212.     char               *buf;    /* buffer to put input into */
  213.  
  214. #endif
  215. {
  216.     int                 c;
  217.  
  218.     DBUG_ENTER("lineget");
  219.     for (;;) {
  220.     if ((c = getc(stream)) == EOF) {
  221.         DBUG_RETURN(-1);
  222.     }
  223.     if (c == '\n') {
  224.         break;
  225.     }
  226.     *buf++ = c;
  227.     }
  228.     *buf = '\0';
  229.     DBUG_RETURN(0);
  230. }
  231.  
  232.  
  233. /* next - Advance to the next archive volume.
  234.  *
  235.  * DESCRIPTION
  236.  *
  237.  *    Prompts the user to replace the backup medium with a new volume
  238.  *    when the old one is full.  There are some cases, such as when
  239.  *    archiving to a file on a hard disk, that the message can be a
  240.  *    little surprising.  Assumes that background processes ignore
  241.  *    interrupts and that the open() or the isatty() will fail for
  242.  *    processes which are not attached to terminals. Returns a file
  243.  *    descriptor or -1 if unsuccessful.
  244.  *
  245.  * PARAMETERS
  246.  *
  247.  *    int mode    - mode of archive (READ, WRITE, PASS)
  248.  */
  249.  
  250. #ifdef __STDC__
  251.  
  252. void
  253. next(int mode)
  254.  
  255. #else
  256.  
  257. void
  258. next(mode)
  259.     int                 mode;    /* mode of archive (READ, WRITE, PASS) */
  260.  
  261. #endif
  262. {
  263.     char                msg[200];    /* buffer for message display */
  264.     char                answer[20];    /* buffer for user's answer */
  265.     int                 ret;
  266.  
  267.     DBUG_ENTER("next");
  268.     close_archive();
  269.  
  270.     sprintf(msg, "%s: Ready for volume %u\n%s: Type \"go\" when ready to proceed (or \"quit\" to abort): \007",
  271.         myname, arvolume + 1, myname);
  272.     for (;;) {
  273.     ret = nextask(msg, answer, sizeof(answer));
  274.     if (ret == -1 || stricmp(answer, "quit") == 0) {
  275.         fatal("Aborted");
  276.     }
  277.     if (stricmp(answer, "go") == 0 && open_archive(mode) == 0) {
  278.         break;
  279.     }
  280.     }
  281.     warnarch("Continuing", (OFFSET) 0);
  282.     DBUG_VOID_RETURN;
  283. }
  284.