Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}