|
|
1.1 root 1: /* $Source: /src386/usr/bin/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 ([email protected])
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 92/09/04 07:36:33 bin
35: * vlad bug fixes
36: *
37: * Revision 1.1 89/02/14 16:48:50 jep
38: * Initial revision
39: *
40: * Revision 1.1 88/12/23 18:02:39 mark
41: * Initial revision
42: *
43: */
44:
45: #ifndef lint
46: static char *ident = "$Id: ttyio.c,v 1.2 92/09/04 07:36:33 bin Exp Locker: bin $";
47: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
48: #endif /* ! lint */
49:
50:
51: /* Headers */
52:
53: #include "pax.h"
54:
55:
56: /* open_tty - open the terminal for interactive queries
57: *
58: * DESCRIPTION
59: *
60: * Assumes that background processes ignore interrupts and that the
61: * open() or the isatty() will fail for processes which are not
62: * attached to terminals. Returns a file descriptor or -1 if
63: * unsuccessful.
64: *
65: * RETURNS
66: *
67: * Returns a file descriptor which can be used to read and write
68: * directly to the user's terminal, or -1 on failure.
69: *
70: * ERRORS
71: *
72: * If SIGINT cannot be ignored, or the open fails, or the newly opened
73: * terminal device is not a tty, then open_tty will return a -1 to the
74: * caller.
75: */
76:
77: #if __STDC__
78:
79: int open_tty(void)
80:
81: #else
82:
83: int open_tty()
84:
85: #endif
86: {
87: int fd; /* file descriptor for terminal */
88: SIG_T (*intr)(); /* used to restore interupts if signal fails */
89:
90: if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
91: return (-1);
92: }
93: signal(SIGINT, intr);
94: if ((fd = open(TTY, O_RDWR)) < 0) {
95: return (-1);
96: }
97: if (isatty(fd)) {
98: return (fd);
99: }
100: close(fd);
101: return (-1);
102: }
103:
104:
105: /* nextask - ask a question and get a response
106: *
107: * DESCRIPTION
108: *
109: * Give the user a prompt and wait for their response. The prompt,
110: * located in "msg" is printed, then the user is allowed to type
111: * a response to the message. The first "limit" characters of the
112: * user response is stored in "answer".
113: *
114: * Nextask ignores spaces and tabs.
115: *
116: * PARAMETERS
117: *
118: * char *msg - Message to display for user
119: * char *answer - Pointer to user's response to question
120: * int limit - Limit of length for user's response
121: *
122: * RETURNS
123: *
124: * Returns the number of characters in the user response to the
125: * calling function. If an EOF was encountered, a -1 is returned to
126: * the calling function. If an error occured which causes the read
127: * to return with a value of -1, then the function will return a
128: * non-zero return status to the calling process, and abort
129: * execution.
130: */
131:
132: #if __STDC__
133:
134: int nextask(char *msg, char *answer, int limit)
135:
136: #else
137:
138: int nextask(msg, answer, limit)
139: char *msg; /* message to display for user */
140: char *answer; /* pointer to user's response to question */
141: int limit; /* limit of length for user's response */
142:
143: #endif
144: {
145: int idx; /* index into answer for character input */
146: int got; /* number of characters read */
147: char c; /* character read */
148:
149: if (ttyf < 0) {
150: fatal("/dev/tty Unavailable");
151: }
152: write(ttyf, msg, (uint) strlen(msg));
153: idx = 0;
154:
155: while ((got = read(ttyf, &c, 1)) == 1) {
156: if (c == '\n') {
157: break;
158: } else if (c == ' ' || c == '\t') {
159: continue;
160: } else if (idx < limit - 1) {
161: answer[idx++] = c;
162: }
163: }
164: if (got == 0) { /* got an EOF */
165: return(-1);
166: }
167: if (got < 0) {
168: fatal(strerror());
169: }
170: answer[idx] = '\0';
171: return(0);
172: }
173:
174:
175: /* lineget - get a line from a given stream
176: *
177: * DESCRIPTION
178: *
179: * Get a line of input for the stream named by "stream". The data on
180: * the stream is put into the buffer "buf".
181: *
182: * PARAMETERS
183: *
184: * FILE *stream - Stream to get input from
185: * char *buf - Buffer to put input into
186: *
187: * RETURNS
188: *
189: * Returns 0 if successful, -1 at EOF.
190: */
191:
192: #if __STDC__
193:
194: int lineget(FILE *stream, char *buf)
195:
196: #else
197:
198: int lineget(stream, buf)
199: FILE *stream; /* stream to get input from */
200: char *buf; /* buffer to put input into */
201:
202: #endif
203: {
204: int c;
205:
206: for (;;) {
207: if ((c = getc(stream)) == EOF) {
208: return (-1);
209: }
210: if (c == '\n') {
211: break;
212: }
213: *buf++ = c;
214: }
215: *buf = '\0';
216: return (0);
217: }
218:
219:
220: /* next - Advance to the next archive volume.
221: *
222: * DESCRIPTION
223: *
224: * Prompts the user to replace the backup medium with a new volume
225: * when the old one is full. There are some cases, such as when
226: * archiving to a file on a hard disk, that the message can be a
227: * little surprising. Assumes that background processes ignore
228: * interrupts and that the open() or the isatty() will fail for
229: * processes which are not attached to terminals. Returns a file
230: * descriptor or -1 if unsuccessful.
231: *
232: * PARAMETERS
233: *
234: * int mode - mode of archive (READ, WRITE, PASS)
235: */
236:
237: #if __STDC__
238:
239: void next(int mode)
240:
241: #else
242:
243: void next(mode)
244: int mode; /* mode of archive (READ, WRITE, PASS) */
245:
246: #endif
247: {
248: char msggo[200],
249: msgdev[200];/* buffers for message display */
250: char answer[20]; /* buffer for user's answer */
251: static char arfile[20]; /* local buffer for file name Vlad */
252: int ret;
253: static int openflag = 0;/* 1 when open_archive failed */
254:
255: close_archive();
256:
257: sprintf(msgdev, "%s: Ready for volume %u\n%s: Type \"/dev/name\" when"
258: " ready to proceed (or \"quit\" to abort): \07",
259: myname, arvolume + 1, myname);
260: sprintf(msggo, "%s: Ready for volume %u\n%s: Type \"go\" when"
261: " ready to proceed (or \"quit\" to abort): \07",
262: myname, arvolume + 1, myname);
263:
264: if (!strcmp(ar_file, "-"))
265: openflag = 1;
266:
267: for (;;) {
268: if (openflag)
269: ret = nextask(msgdev, answer, sizeof(answer));
270: else
271: ret = nextask(msggo, answer, sizeof(answer));
272:
273: if (ret == -1 || strcmp(answer, "quit") == 0) {
274: fatal("Aborted");
275: }
276:
277: if (strcmp("go", answer) || openflag) {
278: strcpy(arfile, answer);
279: ar_file = arfile;
280: }
281: openflag = 0;
282: if (open_archive(mode) == 0) {
283: break;
284: }
285: openflag = 1;
286: }
287: warnarch("Continuing", (OFFSET) 0);
288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.