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

Defined functions

grabh defined in line 58; used 3 times
readtty defined in line 150; used 6 times
ttyint defined in line 264; used 2 times
ttystop defined in line 251; used 4 times

Defined variables

c_erase defined in line 46; used 4 times
c_kill defined in line 47; used 4 times
intjmp defined in line 49; used 2 times
rewrite defined in line 48; used 2 times
sccsid defined in line 35; never used
ttyset defined in line 51; used 11 times
Last modified: 1992-10-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3080
Valid CSS Valid XHTML 1.0 Strict