|
|
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.