1 # 2 3 /* 4 * Mail -- a mail program 5 * 6 * Generally useful tty stuff. 7 */ 8 9 #include "rcv.h" 10 #include <sgtty.h> 11 12 static char *SccsId = "@(#)tty.c 1.1 10/08/80"; 13 14 static int c_erase; /* Current erase char */ 15 static int c_kill; /* Current kill char */ 16 #ifndef TIOCSTI 17 static int ttyset; /* We must now do erase/kill */ 18 #endif 19 20 /* 21 * Read all relevant header fields. 22 */ 23 24 grabh(hp, gflags) 25 struct header *hp; 26 { 27 struct sgttyb ttybuf; 28 #ifndef TIOCSTI 29 int (*savesigs[2])(); 30 #endif 31 register int s; 32 int errs; 33 34 errs = 0; 35 #ifndef TIOCSTI 36 ttyset = 0; 37 #endif 38 if (gtty(fileno(stdin), &ttybuf) < 0) { 39 perror("gtty"); 40 return(-1); 41 } 42 c_erase = ttybuf.sg_erase; 43 c_kill = ttybuf.sg_kill; 44 #ifndef TIOCSTI 45 ttybuf.sg_erase = 0; 46 ttybuf.sg_kill = 0; 47 for (s = SIGINT; s <= SIGQUIT; s++) 48 if ((savesigs[s-SIGINT] = signal(s, SIG_IGN)) == SIG_DFL) 49 signal(s, SIG_DFL); 50 #endif 51 if (gflags & GTO) { 52 #ifndef TIOCSTI 53 if (!ttyset && hp->h_to != NOSTR) 54 ttyset++, stty(fileno(stdin), &ttybuf); 55 #endif 56 hp->h_to = readtty("To: ", hp->h_to); 57 if (hp->h_to != NOSTR) 58 hp->h_seq++; 59 } 60 if (gflags & GSUBJECT) { 61 #ifndef TIOCSTI 62 if (!ttyset && hp->h_subject != NOSTR) 63 ttyset++, stty(fileno(stdin), &ttybuf); 64 #endif 65 hp->h_subject = readtty("Subject: ", hp->h_subject); 66 if (hp->h_subject != NOSTR) 67 hp->h_seq++; 68 } 69 if (gflags & GCC) { 70 #ifndef TIOCSTI 71 if (!ttyset && hp->h_cc != NOSTR) 72 ttyset++, stty(fileno(stdin), &ttybuf); 73 #endif 74 hp->h_cc = readtty("Cc: ", hp->h_cc); 75 if (hp->h_cc != NOSTR) 76 hp->h_seq++; 77 } 78 if (gflags & GBCC) { 79 #ifndef TIOCSTI 80 if (!ttyset && hp->h_bcc != NOSTR) 81 ttyset++, stty(fileno(stdin), &ttybuf); 82 #endif 83 hp->h_bcc = readtty("Bcc: ", hp->h_bcc); 84 if (hp->h_bcc != NOSTR) 85 hp->h_seq++; 86 } 87 #ifndef TIOCSTI 88 ttybuf.sg_erase = c_erase; 89 ttybuf.sg_kill = c_kill; 90 if (ttyset) 91 stty(fileno(stdin), &ttybuf); 92 for (s = SIGINT; s <= SIGQUIT; s++) 93 signal(s, savesigs[s-SIGINT]); 94 #endif 95 return(errs); 96 } 97 98 /* 99 * Read up a header from standard input. 100 * The source string has the preliminary contents to 101 * be read. 102 * 103 */ 104 105 char * 106 readtty(pr, src) 107 char pr[], src[]; 108 { 109 char canonb[BUFSIZ]; 110 int c, ch; 111 register char *cp, *cp2; 112 113 fputs(pr, stdout); fflush(stdout); 114 if (src != NOSTR && strlen(src) > BUFSIZ - 2) { 115 printf("too long to edit\n"); 116 return(src); 117 } 118 #ifndef TIOCSTI 119 if (src != NOSTR) 120 cp = copy(src, canonb); 121 else 122 cp = copy("", canonb); 123 fputs(canonb, stdout); 124 fflush(stdout); 125 #else 126 for (cp = src; c = *cp; cp++) { 127 if (c == c_erase || c == c_kill) { 128 ch = '\\'; 129 ioctl(0, TIOCSTI, &ch); 130 } 131 ioctl(0, TIOCSTI, &c); 132 } 133 cp = canonb; 134 #endif 135 cp2 = fgets(cp, BUFSIZ - (cp - canonb), stdin); 136 canonb[strlen(canonb) - 1] = '\0'; 137 #ifndef TIOCSTI 138 if (cp2 == NOSTR || *cp2 == '\0') 139 return(src); 140 cp = cp2; 141 if (!ttyset) 142 return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); 143 while (*cp != '\0') { 144 c = *cp++; 145 if (c == c_erase) { 146 if (cp2 == canonb) 147 continue; 148 if (cp2[-1] == '\\') { 149 cp2[-1] = c; 150 continue; 151 } 152 cp2--; 153 continue; 154 } 155 if (c == c_kill) { 156 if (cp2 == canonb) 157 continue; 158 if (cp2[-1] == '\\') { 159 cp2[-1] = c; 160 continue; 161 } 162 cp2 = canonb; 163 continue; 164 } 165 *cp2++ = c; 166 } 167 *cp2 = '\0'; 168 #endif 169 if (equal("", canonb)) 170 return(NOSTR); 171 return(savestr(canonb)); 172 } 173