|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)tty.c 5.11 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * Mail -- a mail program ! 26: * ! 27: * Generally useful tty stuff. ! 28: */ ! 29: ! 30: #include "rcv.h" ! 31: ! 32: static int c_erase; /* Current erase char */ ! 33: static int c_kill; /* Current kill char */ ! 34: static jmp_buf rewrite; /* Place to go when continued */ ! 35: static jmp_buf intjmp; /* Place to go when interrupted */ ! 36: #ifndef TIOCSTI ! 37: static int ttyset; /* We must now do erase/kill */ ! 38: #endif ! 39: ! 40: /* ! 41: * Read all relevant header fields. ! 42: */ ! 43: ! 44: grabh(hp, gflags) ! 45: struct header *hp; ! 46: { ! 47: struct sgttyb ttybuf; ! 48: sig_t saveint; ! 49: #ifndef TIOCSTI ! 50: sig_t savequit; ! 51: #endif ! 52: sig_t savetstp; ! 53: sig_t savettou; ! 54: sig_t savettin; ! 55: int errs; ! 56: int ttyint(); ! 57: ! 58: savetstp = signal(SIGTSTP, SIG_DFL); ! 59: savettou = signal(SIGTTOU, SIG_DFL); ! 60: savettin = signal(SIGTTIN, SIG_DFL); ! 61: errs = 0; ! 62: #ifndef TIOCSTI ! 63: ttyset = 0; ! 64: #endif ! 65: if (ioctl(fileno(stdin), TIOCGETP, &ttybuf) < 0) { ! 66: perror("gtty"); ! 67: return(-1); ! 68: } ! 69: c_erase = ttybuf.sg_erase; ! 70: c_kill = ttybuf.sg_kill; ! 71: #ifndef TIOCSTI ! 72: ttybuf.sg_erase = 0; ! 73: ttybuf.sg_kill = 0; ! 74: if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) ! 75: signal(SIGINT, SIG_DFL); ! 76: if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) ! 77: signal(SIGQUIT, SIG_DFL); ! 78: #else ! 79: if (setjmp(intjmp)) ! 80: goto out; ! 81: saveint = signal(SIGINT, ttyint); ! 82: #endif ! 83: if (gflags & GTO) { ! 84: #ifndef TIOCSTI ! 85: if (!ttyset && hp->h_to != NIL) ! 86: ttyset++, stty(fileno(stdin), &ttybuf); ! 87: #endif ! 88: hp->h_to = ! 89: extract(readtty("To: ", detract(hp->h_to, 0)), GTO); ! 90: } ! 91: if (gflags & GSUBJECT) { ! 92: #ifndef TIOCSTI ! 93: if (!ttyset && hp->h_subject != NOSTR) ! 94: ttyset++, stty(fileno(stdin), &ttybuf); ! 95: #endif ! 96: hp->h_subject = readtty("Subject: ", hp->h_subject); ! 97: } ! 98: if (gflags & GCC) { ! 99: #ifndef TIOCSTI ! 100: if (!ttyset && hp->h_cc != NIL) ! 101: ttyset++, stty(fileno(stdin), &ttybuf); ! 102: #endif ! 103: hp->h_cc = ! 104: extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC); ! 105: } ! 106: if (gflags & GBCC) { ! 107: #ifndef TIOCSTI ! 108: if (!ttyset && hp->h_bcc != NIL) ! 109: ttyset++, stty(fileno(stdin), &ttybuf); ! 110: #endif ! 111: hp->h_bcc = ! 112: extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC); ! 113: } ! 114: out: ! 115: signal(SIGTSTP, savetstp); ! 116: signal(SIGTTOU, savettou); ! 117: signal(SIGTTIN, savettin); ! 118: #ifndef TIOCSTI ! 119: ttybuf.sg_erase = c_erase; ! 120: ttybuf.sg_kill = c_kill; ! 121: if (ttyset) ! 122: stty(fileno(stdin), &ttybuf); ! 123: signal(SIGQUIT, savequit); ! 124: #endif ! 125: signal(SIGINT, saveint); ! 126: return(errs); ! 127: } ! 128: ! 129: /* ! 130: * Read up a header from standard input. ! 131: * The source string has the preliminary contents to ! 132: * be read. ! 133: * ! 134: */ ! 135: ! 136: char * ! 137: readtty(pr, src) ! 138: char pr[], src[]; ! 139: { ! 140: char ch, canonb[BUFSIZ]; ! 141: int c; ! 142: register char *cp, *cp2; ! 143: int ttystop(); ! 144: ! 145: fputs(pr, stdout); ! 146: fflush(stdout); ! 147: if (src != NOSTR && strlen(src) > BUFSIZ - 2) { ! 148: printf("too long to edit\n"); ! 149: return(src); ! 150: } ! 151: #ifndef TIOCSTI ! 152: if (src != NOSTR) ! 153: cp = copy(src, canonb); ! 154: else ! 155: cp = copy("", canonb); ! 156: fputs(canonb, stdout); ! 157: fflush(stdout); ! 158: #else ! 159: cp = src == NOSTR ? "" : src; ! 160: while (c = *cp++) { ! 161: if (c == c_erase || c == c_kill) { ! 162: ch = '\\'; ! 163: ioctl(0, TIOCSTI, &ch); ! 164: } ! 165: ch = c; ! 166: ioctl(0, TIOCSTI, &ch); ! 167: } ! 168: cp = canonb; ! 169: *cp = 0; ! 170: #endif ! 171: cp2 = cp; ! 172: while (cp2 < canonb + BUFSIZ) ! 173: *cp2++ = 0; ! 174: cp2 = cp; ! 175: if (setjmp(rewrite)) ! 176: goto redo; ! 177: signal(SIGTSTP, ttystop); ! 178: signal(SIGTTOU, ttystop); ! 179: signal(SIGTTIN, ttystop); ! 180: clearerr(stdin); ! 181: while (cp2 < canonb + BUFSIZ) { ! 182: c = getc(stdin); ! 183: if (c == EOF || c == '\n') ! 184: break; ! 185: *cp2++ = c; ! 186: } ! 187: *cp2 = 0; ! 188: signal(SIGTSTP, SIG_DFL); ! 189: signal(SIGTTOU, SIG_DFL); ! 190: signal(SIGTTIN, SIG_DFL); ! 191: if (c == EOF && ferror(stdin)) { ! 192: redo: ! 193: cp = strlen(canonb) > 0 ? canonb : NOSTR; ! 194: clearerr(stdin); ! 195: return(readtty(pr, cp)); ! 196: } ! 197: #ifndef TIOCSTI ! 198: if (cp == NOSTR || *cp == '\0') ! 199: return(src); ! 200: cp2 = cp; ! 201: if (!ttyset) ! 202: return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); ! 203: while (*cp != '\0') { ! 204: c = *cp++; ! 205: if (c == c_erase) { ! 206: if (cp2 == canonb) ! 207: continue; ! 208: if (cp2[-1] == '\\') { ! 209: cp2[-1] = c; ! 210: continue; ! 211: } ! 212: cp2--; ! 213: continue; ! 214: } ! 215: if (c == c_kill) { ! 216: if (cp2 == canonb) ! 217: continue; ! 218: if (cp2[-1] == '\\') { ! 219: cp2[-1] = c; ! 220: continue; ! 221: } ! 222: cp2 = canonb; ! 223: continue; ! 224: } ! 225: *cp2++ = c; ! 226: } ! 227: *cp2 = '\0'; ! 228: #endif ! 229: if (equal("", canonb)) ! 230: return(NOSTR); ! 231: return(savestr(canonb)); ! 232: } ! 233: ! 234: /* ! 235: * Receipt continuation. ! 236: */ ! 237: ttystop(s) ! 238: { ! 239: sig_t old_action = signal(s, SIG_DFL); ! 240: ! 241: sigsetmask(sigblock(0) & ~sigmask(s)); ! 242: kill(0, s); ! 243: sigblock(sigmask(s)); ! 244: signal(s, old_action); ! 245: longjmp(rewrite, 1); ! 246: } ! 247: ! 248: /*ARGSUSED*/ ! 249: ttyint(s) ! 250: { ! 251: ! 252: longjmp(intjmp, 1); ! 253: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.