|
|
1.1 ! root 1: /* $Source: /newbits/usr/bin/pax/shipping/ttyio.c,v $ ! 2: * ! 3: * $Revision: 1.1 $ ! 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: /newbits/usr/bin/pax/shipping/ttyio.c,v $ ! 34: * Revision 1.1 91/02/05 11:59:39 bin ! 35: * Initial revision ! 36: * ! 37: * Revision 1.2 89/02/12 10:06:11 mark ! 38: * 1.2 release fixes ! 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 89/02/12 10:06:11 mark Exp $"; ! 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: ! 95: if ((fd = open(TTY, 2)) < 0) ! 96: return (-1); ! 97: ! 98: if (isatty(fd)) ! 99: return (fd); ! 100: ! 101: close(fd); ! 102: return (-1); ! 103: } ! 104: ! 105: ! 106: /* nextask - ask a question and get a response ! 107: * ! 108: * DESCRIPTION ! 109: * ! 110: * Give the user a prompt and wait for their response. The prompt, ! 111: * located in "msg" is printed, then the user is allowed to type ! 112: * a response to the message. The first "limit" characters of the ! 113: * user response is stored in "answer". ! 114: * ! 115: * Nextask ignores spaces and tabs. ! 116: * ! 117: * PARAMETERS ! 118: * ! 119: * char *msg - Message to display for user ! 120: * char *answer - Pointer to user's response to question ! 121: * int limit - Limit of length for user's response ! 122: * ! 123: * RETURNS ! 124: * ! 125: * Returns the number of characters in the user response to the ! 126: * calling function. If an EOF was encountered, a -1 is returned to ! 127: * the calling function. If an error occured which causes the read ! 128: * to return with a value of -1, then the function will return a ! 129: * non-zero return status to the calling process, and abort ! 130: * execution. ! 131: */ ! 132: ! 133: #if __STDC__ ! 134: ! 135: int nextask(char *msg, char *answer, int limit) ! 136: ! 137: #else ! 138: ! 139: int nextask(msg, answer, limit) ! 140: char *msg; /* message to display for user */ ! 141: char *answer; /* pointer to user's response to question */ ! 142: int limit; /* limit of length for user's response */ ! 143: ! 144: #endif ! 145: { ! 146: int idx; /* index into answer for character input */ ! 147: int got; /* number of characters read */ ! 148: char c; /* character read */ ! 149: ! 150: if (ttyf < 0) { ! 151: fatal("/dev/tty Unavailable"); ! 152: } ! 153: write(ttyf, msg, (uint) strlen(msg)); ! 154: idx = 0; ! 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 msg[200]; /* buffer for message display */ ! 249: char answer[20]; /* buffer for user's answer */ ! 250: int ret; ! 251: ! 252: close_archive(); ! 253: sprintf(msg, "%s: Ready for volume %u\n%s: Type \"device\/name\" when ready to proceed (or \"quit\" to abort): \07", ! 254: myname, arvolume + 1, myname); ! 255: for (;;) { ! 256: ret = nextask(msg, answer, sizeof(answer)); ! 257: if (ret == -1 || strcmp(answer, "quit") == 0) { ! 258: fatal("Aborted"); ! 259: } ! 260: ar_file = answer; /* next bug was fixed */ ! 261: ! 262: if (ret != -1 && open_archive(mode) == 0) { ! 263: break; ! 264: } ! 265: } ! 266: warnarch("Continuing", (OFFSET) 0); ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.