]> git.lizzy.rs Git - plan9front.git/blob - sys/src/ape/cmd/pax/ttyio.c
ape: bring strtod() in line with plan9's libc version
[plan9front.git] / sys / src / ape / cmd / pax / ttyio.c
1 /* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
2  *
3  * $Revision: 1.2 $
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, NAPS International (mark@jhereg.mn.org)
16  *
17  * Sponsored by The USENIX Association for public distribution. 
18  *
19  * Copyright (c) 1989 Mark H. Colburn.
20  * All rights reserved.
21  *
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 
27  * USENIX Association. 
28  *
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.
32  *
33  * $Log:        ttyio.c,v $
34  * Revision 1.2  89/02/12  10:06:11  mark
35  * 1.2 release fixes
36  * 
37  * Revision 1.1  88/12/23  18:02:39  mark
38  * Initial revision
39  * 
40  */
41
42 #ifndef lint
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";
45 #endif /* ! lint */
46
47
48 /* Headers */
49
50 #include "pax.h"
51
52
53 /* open_tty - open the terminal for interactive queries
54  *
55  * DESCRIPTION
56  *
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
60  *      unsuccessful. 
61  *
62  * RETURNS
63  *
64  *      Returns a file descriptor which can be used to read and write
65  *      directly to the user's terminal, or -1 on failure.  
66  *
67  * ERRORS
68  *
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
71  *      caller.
72  */
73
74 #ifdef __STDC__
75
76 int open_tty(void)
77
78 #else
79
80 int open_tty()
81
82 #endif
83 {
84     int             fd;         /* file descriptor for terminal */
85     SIG_T         (*intr)();    /* used to restore interupts if signal fails */
86
87     if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
88         return (-1);
89     }
90     signal(SIGINT, intr);
91     if ((fd = open(TTY, O_RDWR)) < 0) {
92         return (-1);
93     }
94     if (isatty(fd)) {
95         return (fd);
96     }
97     close(fd);
98     return (-1);
99 }
100
101
102 /* nextask - ask a question and get a response
103  *
104  * DESCRIPTION
105  *
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".
110  *
111  *      Nextask ignores spaces and tabs. 
112  *
113  * PARAMETERS
114  *
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
118  *
119  * RETURNS
120  *
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
126  *      execution.
127  */
128
129 #ifdef __STDC__
130
131 int nextask(char *msg, char *answer, int limit)
132
133 #else
134
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 */
139
140 #endif
141 {
142     int             idx;        /* index into answer for character input */
143     int             got;        /* number of characters read */
144     char            c;          /* character read */
145
146     if (ttyf < 0) {
147         fatal("/dev/tty Unavailable");
148     }
149     write(ttyf, msg, (uint) strlen(msg));
150     idx = 0;
151     while ((got = read(ttyf, &c, 1)) == 1) {
152         if (c == '\n') {
153             break;
154         } else if (c == ' ' || c == '\t') {
155             continue;
156         } else if (idx < limit - 1) {
157             answer[idx++] = c;
158         }
159     }
160     if (got == 0) {             /* got an EOF */
161         return(-1);
162     }
163     if (got < 0) {
164         fatal(strerror());
165     }
166     answer[idx] = '\0';
167     return(0);
168 }
169
170
171 /* lineget - get a line from a given stream
172  *
173  * DESCRIPTION
174  * 
175  *      Get a line of input for the stream named by "stream".  The data on
176  *      the stream is put into the buffer "buf".
177  *
178  * PARAMETERS
179  *
180  *      FILE *stream            - Stream to get input from 
181  *      char *buf               - Buffer to put input into
182  *
183  * RETURNS
184  *
185  *      Returns 0 if successful, -1 at EOF. 
186  */
187
188 #ifdef __STDC__
189
190 int lineget(FILE *stream, char *buf)
191
192 #else
193
194 int lineget(stream, buf)
195 FILE           *stream;         /* stream to get input from */
196 char           *buf;            /* buffer to put input into */
197
198 #endif
199 {
200     int             c;
201
202     for (;;) {
203         if ((c = getc(stream)) == EOF) {
204             return (-1);
205         }
206         if (c == '\n') {
207             break;
208         }
209         *buf++ = c;
210     }
211     *buf = '\0';
212     return (0);
213 }
214
215
216 /* next - Advance to the next archive volume. 
217  *
218  * DESCRIPTION
219  *
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. 
227  *
228  * PARAMETERS
229  *
230  *      int mode        - mode of archive (READ, WRITE, PASS) 
231  */
232
233 #ifdef __STDC__
234
235 void next(int mode)
236
237 #else
238
239 void next(mode)
240 int             mode;           /* mode of archive (READ, WRITE, PASS) */
241
242 #endif
243 {
244     char            msg[200];   /* buffer for message display */ 
245     char            answer[20]; /* buffer for user's answer */
246     int             ret;
247
248     close_archive();
249
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);
252     for (;;) {
253         ret = nextask(msg, answer, sizeof(answer));
254         if (ret == -1 || strcmp(answer, "quit") == 0) {
255             fatal("Aborted");
256         }
257         if (strcmp(answer, "go") == 0 && open_archive(mode) == 0) {
258             break;
259         }
260     }
261     warnarch("Continuing", (OFFSET) 0);
262 }