1 /* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
5 * ttyio.c - Terminal/Console I/O functions for all archive interfaces
9 * These routines provide a consistent, general purpose interface to
10 * the user via the users terminal, if it is available to the
15 * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
17 * Sponsored by The USENIX Association for public distribution.
19 * Copyright (c) 1989 Mark H. Colburn.
20 * All rights reserved.
22 * Redistribution and use in source and binary forms are permitted
23 * provided that the above copyright notice is duplicated in all such
24 * forms and that any documentation, advertising materials, and other
25 * materials related to such distribution and use acknowledge that the
26 * software was developed * by Mark H. Colburn and sponsored by The
29 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
34 * Revision 1.2 89/02/12 10:06:11 mark
37 * Revision 1.1 88/12/23 18:02:39 mark
43 static char *ident = "$Id: ttyio.c,v 1.2 89/02/12 10:06:11 mark Exp $";
44 static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
53 /* open_tty - open the terminal for interactive queries
57 * Assumes that background processes ignore interrupts and that the
58 * open() or the isatty() will fail for processes which are not
59 * attached to terminals. Returns a file descriptor or -1 if
64 * Returns a file descriptor which can be used to read and write
65 * directly to the user's terminal, or -1 on failure.
69 * If SIGINT cannot be ignored, or the open fails, or the newly opened
70 * terminal device is not a tty, then open_tty will return a -1 to the
84 int fd; /* file descriptor for terminal */
85 SIG_T (*intr)(); /* used to restore interupts if signal fails */
87 if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
91 if ((fd = open(TTY, O_RDWR)) < 0) {
102 /* nextask - ask a question and get a response
106 * Give the user a prompt and wait for their response. The prompt,
107 * located in "msg" is printed, then the user is allowed to type
108 * a response to the message. The first "limit" characters of the
109 * user response is stored in "answer".
111 * Nextask ignores spaces and tabs.
115 * char *msg - Message to display for user
116 * char *answer - Pointer to user's response to question
117 * int limit - Limit of length for user's response
121 * Returns the number of characters in the user response to the
122 * calling function. If an EOF was encountered, a -1 is returned to
123 * the calling function. If an error occured which causes the read
124 * to return with a value of -1, then the function will return a
125 * non-zero return status to the calling process, and abort
131 int nextask(char *msg, char *answer, int limit)
135 int nextask(msg, answer, limit)
136 char *msg; /* message to display for user */
137 char *answer; /* pointer to user's response to question */
138 int limit; /* limit of length for user's response */
142 int idx; /* index into answer for character input */
143 int got; /* number of characters read */
144 char c; /* character read */
147 fatal("/dev/tty Unavailable");
149 write(ttyf, msg, (uint) strlen(msg));
151 while ((got = read(ttyf, &c, 1)) == 1) {
154 } else if (c == ' ' || c == '\t') {
156 } else if (idx < limit - 1) {
160 if (got == 0) { /* got an EOF */
171 /* lineget - get a line from a given stream
175 * Get a line of input for the stream named by "stream". The data on
176 * the stream is put into the buffer "buf".
180 * FILE *stream - Stream to get input from
181 * char *buf - Buffer to put input into
185 * Returns 0 if successful, -1 at EOF.
190 int lineget(FILE *stream, char *buf)
194 int lineget(stream, buf)
195 FILE *stream; /* stream to get input from */
196 char *buf; /* buffer to put input into */
203 if ((c = getc(stream)) == EOF) {
216 /* next - Advance to the next archive volume.
220 * Prompts the user to replace the backup medium with a new volume
221 * when the old one is full. There are some cases, such as when
222 * archiving to a file on a hard disk, that the message can be a
223 * little surprising. Assumes that background processes ignore
224 * interrupts and that the open() or the isatty() will fail for
225 * processes which are not attached to terminals. Returns a file
226 * descriptor or -1 if unsuccessful.
230 * int mode - mode of archive (READ, WRITE, PASS)
240 int mode; /* mode of archive (READ, WRITE, PASS) */
244 char msg[200]; /* buffer for message display */
245 char answer[20]; /* buffer for user's answer */
250 sprintf(msg, "%s: Ready for volume %u\n%s: Type \"go\" when ready to proceed (or \"quit\" to abort): \07",
251 myname, arvolume + 1, myname);
253 ret = nextask(msg, answer, sizeof(answer));
254 if (ret == -1 || strcmp(answer, "quit") == 0) {
257 if (strcmp(answer, "go") == 0 && open_archive(mode) == 0) {
261 warnarch("Continuing", (OFFSET) 0);