Annotation of 43BSDReno/usr.bin/mail/tty.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.