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