|
|
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 this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifdef notdef ! 14: static char sccsid[] = "@(#)tty.c 5.5 (Berkeley) 2/18/88"; ! 15: #endif /* notdef */ ! 16: ! 17: /* ! 18: * Mail -- a mail program ! 19: * ! 20: * Generally useful tty stuff. ! 21: */ ! 22: ! 23: #include "rcv.h" ! 24: ! 25: static int c_erase; /* Current erase char */ ! 26: static int c_kill; /* Current kill char */ ! 27: static int hadcont; /* Saw continue signal */ ! 28: static jmp_buf rewrite; /* Place to go when continued */ ! 29: #ifndef TIOCSTI ! 30: static int ttyset; /* We must now do erase/kill */ ! 31: #endif ! 32: ! 33: /* ! 34: * Read all relevant header fields. ! 35: */ ! 36: ! 37: grabh(hp, gflags) ! 38: struct header *hp; ! 39: { ! 40: struct sgttyb ttybuf; ! 41: #ifndef TIOCSTI ! 42: int (*saveint)(), (*savequit)(); ! 43: #endif ! 44: int (*savecont)(); ! 45: int errs; ! 46: ! 47: savecont = signal(SIGCONT, SIG_DFL); ! 48: errs = 0; ! 49: #ifndef TIOCSTI ! 50: ttyset = 0; ! 51: #endif ! 52: if (gtty(fileno(stdin), &ttybuf) < 0) { ! 53: perror("gtty"); ! 54: return(-1); ! 55: } ! 56: c_erase = ttybuf.sg_erase; ! 57: c_kill = ttybuf.sg_kill; ! 58: #ifndef TIOCSTI ! 59: ttybuf.sg_erase = 0; ! 60: ttybuf.sg_kill = 0; ! 61: if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) ! 62: signal(SIGINT, SIG_DFL); ! 63: if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) ! 64: signal(SIGQUIT, SIG_DFL); ! 65: #endif ! 66: if (gflags & GTO) { ! 67: #ifndef TIOCSTI ! 68: if (!ttyset && hp->h_to != NOSTR) ! 69: ttyset++, stty(fileno(stdin), &ttybuf); ! 70: #endif ! 71: hp->h_to = readtty("To: ", hp->h_to); ! 72: if (hp->h_to != NOSTR) ! 73: hp->h_seq++; ! 74: } ! 75: if (gflags & GSUBJECT) { ! 76: #ifndef TIOCSTI ! 77: if (!ttyset && hp->h_subject != NOSTR) ! 78: ttyset++, stty(fileno(stdin), &ttybuf); ! 79: #endif ! 80: hp->h_subject = readtty("Subject: ", hp->h_subject); ! 81: if (hp->h_subject != NOSTR) ! 82: hp->h_seq++; ! 83: } ! 84: if (gflags & GCC) { ! 85: #ifndef TIOCSTI ! 86: if (!ttyset && hp->h_cc != NOSTR) ! 87: ttyset++, stty(fileno(stdin), &ttybuf); ! 88: #endif ! 89: hp->h_cc = readtty("Cc: ", hp->h_cc); ! 90: if (hp->h_cc != NOSTR) ! 91: hp->h_seq++; ! 92: } ! 93: if (gflags & GBCC) { ! 94: #ifndef TIOCSTI ! 95: if (!ttyset && hp->h_bcc != NOSTR) ! 96: ttyset++, stty(fileno(stdin), &ttybuf); ! 97: #endif ! 98: hp->h_bcc = readtty("Bcc: ", hp->h_bcc); ! 99: if (hp->h_bcc != NOSTR) ! 100: hp->h_seq++; ! 101: } ! 102: signal(SIGCONT, savecont); ! 103: #ifndef TIOCSTI ! 104: ttybuf.sg_erase = c_erase; ! 105: ttybuf.sg_kill = c_kill; ! 106: if (ttyset) ! 107: stty(fileno(stdin), &ttybuf); ! 108: signal(SIGINT, saveint); ! 109: signal(SIGQUIT, savequit); ! 110: #endif ! 111: return(errs); ! 112: } ! 113: ! 114: /* ! 115: * Read up a header from standard input. ! 116: * The source string has the preliminary contents to ! 117: * be read. ! 118: * ! 119: */ ! 120: ! 121: char * ! 122: readtty(pr, src) ! 123: char pr[], src[]; ! 124: { ! 125: char ch, canonb[BUFSIZ]; ! 126: int c; ! 127: register char *cp, *cp2; ! 128: int ttycont(); ! 129: ! 130: fputs(pr, stdout); ! 131: fflush(stdout); ! 132: if (src != NOSTR && strlen(src) > BUFSIZ - 2) { ! 133: printf("too long to edit\n"); ! 134: return(src); ! 135: } ! 136: #ifndef TIOCSTI ! 137: if (src != NOSTR) ! 138: cp = copy(src, canonb); ! 139: else ! 140: cp = copy("", canonb); ! 141: fputs(canonb, stdout); ! 142: fflush(stdout); ! 143: #else ! 144: cp = src == NOSTR ? "" : src; ! 145: while (c = *cp++) { ! 146: if (c == c_erase || c == c_kill) { ! 147: ch = '\\'; ! 148: ioctl(0, TIOCSTI, &ch); ! 149: } ! 150: ch = c; ! 151: ioctl(0, TIOCSTI, &ch); ! 152: } ! 153: cp = canonb; ! 154: *cp = 0; ! 155: #endif ! 156: cp2 = cp; ! 157: while (cp2 < canonb + BUFSIZ) ! 158: *cp2++ = 0; ! 159: cp2 = cp; ! 160: if (setjmp(rewrite)) ! 161: goto redo; ! 162: signal(SIGCONT, ttycont); ! 163: clearerr(stdin); ! 164: while (cp2 < canonb + BUFSIZ) { ! 165: c = getc(stdin); ! 166: if (c == EOF || c == '\n') ! 167: break; ! 168: *cp2++ = c; ! 169: } ! 170: *cp2 = 0; ! 171: signal(SIGCONT, SIG_DFL); ! 172: if (c == EOF && ferror(stdin) && hadcont) { ! 173: redo: ! 174: hadcont = 0; ! 175: cp = strlen(canonb) > 0 ? canonb : NOSTR; ! 176: clearerr(stdin); ! 177: return(readtty(pr, cp)); ! 178: } ! 179: #ifndef TIOCSTI ! 180: if (cp == NOSTR || *cp == '\0') ! 181: return(src); ! 182: cp2 = cp; ! 183: if (!ttyset) ! 184: return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); ! 185: while (*cp != '\0') { ! 186: c = *cp++; ! 187: if (c == c_erase) { ! 188: if (cp2 == canonb) ! 189: continue; ! 190: if (cp2[-1] == '\\') { ! 191: cp2[-1] = c; ! 192: continue; ! 193: } ! 194: cp2--; ! 195: continue; ! 196: } ! 197: if (c == c_kill) { ! 198: if (cp2 == canonb) ! 199: continue; ! 200: if (cp2[-1] == '\\') { ! 201: cp2[-1] = c; ! 202: continue; ! 203: } ! 204: cp2 = canonb; ! 205: continue; ! 206: } ! 207: *cp2++ = c; ! 208: } ! 209: *cp2 = '\0'; ! 210: #endif ! 211: if (equal("", canonb)) ! 212: return(NOSTR); ! 213: return(savestr(canonb)); ! 214: } ! 215: ! 216: /* ! 217: * Receipt continuation. ! 218: */ ! 219: /*ARGSUSED*/ ! 220: ttycont(s) ! 221: { ! 222: hadcont++; ! 223: longjmp(rewrite, 1); ! 224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.