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