Annotation of 43BSD/contrib/nntp/rrn/term.c, revision 1.1

1.1     ! root        1: /* $Header: term.c,v 4.3.1.2 85/05/16 16:45:35 lwall Exp $
        !             2:  *
        !             3:  * $Log:       term.c,v $
        !             4:  * Revision 4.3.1.2  85/05/16  16:45:35  lwall
        !             5:  * Forced \r to \n on input.
        !             6:  * Fix for terminfo braindamage regarding bc emulation.
        !             7:  * 
        !             8:  * Revision 4.3.1.1  85/05/10  11:41:03  lwall
        !             9:  * Branch for patches.
        !            10:  * 
        !            11:  * Revision 4.3  85/05/01  11:51:10  lwall
        !            12:  * Baseline for release with 4.3bsd.
        !            13:  * 
        !            14:  */
        !            15: 
        !            16: #include "EXTERN.h"
        !            17: #include "common.h"
        !            18: #include "util.h"
        !            19: #include "final.h"
        !            20: #include "help.h"
        !            21: #include "cheat.h"
        !            22: #include "intrp.h"
        !            23: #include "INTERN.h"
        !            24: #include "term.h"
        !            25: 
        !            26: char ERASECH;          /* rubout character */
        !            27: char KILLCH;           /* line delete character */
        !            28: char tcarea[TCSIZE];   /* area for "compiled" termcap strings */
        !            29: 
        !            30: /* guarantee capability pointer != Nullch */
        !            31: /* (I believe terminfo will ignore the &tmpaddr argument.) */
        !            32: 
        !            33: #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
        !            34: 
        !            35: #ifdef PUSHBACK
        !            36: struct keymap {
        !            37:     char km_type[128];
        !            38:     union km_union {
        !            39:        struct keymap *km_km;
        !            40:        char *km_str;
        !            41:     } km_ptr[128];
        !            42: };
        !            43: 
        !            44: #define KM_NOTHIN 0
        !            45: #define KM_STRING 1
        !            46: #define KM_KEYMAP 2
        !            47: #define KM_BOGUS 3
        !            48: 
        !            49: #define KM_TMASK 3
        !            50: #define KM_GSHIFT 4
        !            51: #define KM_GMASK 7
        !            52: 
        !            53: typedef struct keymap KEYMAP;
        !            54: 
        !            55: KEYMAP *topmap INIT(Null(KEYMAP*));
        !            56: 
        !            57: void mac_init();
        !            58: KEYMAP *newkeymap();
        !            59: void show_keymap();
        !            60: void pushstring();
        !            61: #endif
        !            62: 
        !            63: /* terminal initialization */
        !            64: 
        !            65: void
        !            66: term_init()
        !            67: {
        !            68:     savetty();                         /* remember current tty state */
        !            69: 
        !            70: #ifdef TERMIO
        !            71:     ospeed = _tty.c_cflag & CBAUD;     /* for tputs() */
        !            72:     ERASECH = _tty.c_cc[VERASE];       /* for finish_command() */
        !            73:     KILLCH = _tty.c_cc[VKILL];         /* for finish_command() */
        !            74: #else
        !            75:     ospeed = _tty.sg_ospeed;           /* for tputs() */
        !            76:     ERASECH = _tty.sg_erase;           /* for finish_command() */
        !            77:     KILLCH = _tty.sg_kill;             /* for finish_command() */
        !            78: #endif
        !            79: 
        !            80:     /* The following could be a table but I can't be sure that there isn't */
        !            81:     /* some degree of sparsity out there in the world. */
        !            82: 
        !            83:     switch (ospeed) {                  /* 1 second of padding */
        !            84: #ifdef BEXTA
        !            85:         case BEXTA:  just_a_sec = 1920; break;
        !            86: #else
        !            87: #ifdef B19200
        !            88:         case B19200: just_a_sec = 1920; break;
        !            89: #endif
        !            90: #endif
        !            91:         case B9600:  just_a_sec =  960; break;
        !            92:         case B4800:  just_a_sec =  480; break;
        !            93:         case B2400:  just_a_sec =  240; break;
        !            94:         case B1800:  just_a_sec =  180; break;
        !            95:         case B1200:  just_a_sec =  120; break;
        !            96:         case B600:   just_a_sec =   60; break;
        !            97:        case B300:   just_a_sec =   30; break;
        !            98:        /* do I really have to type the rest of this??? */
        !            99:         case B200:   just_a_sec =   20; break;
        !           100:         case B150:   just_a_sec =   15; break;
        !           101:         case B134:   just_a_sec =   13; break;
        !           102:         case B110:   just_a_sec =   11; break;
        !           103:         case B75:    just_a_sec =    8; break;
        !           104:         case B50:    just_a_sec =    5; break;
        !           105:         default:     just_a_sec =  960; break;
        !           106:                                        /* if we are running detached I */
        !           107:     }                                  /*  don't want to know about it! */
        !           108: }
        !           109: 
        !           110: /* set terminal characteristics */
        !           111: 
        !           112: void
        !           113: term_set(tcbuf)
        !           114: char *tcbuf;           /* temp area for "uncompiled" termcap entry */
        !           115: {
        !           116:     char *tmpaddr;                     /* must not be register */
        !           117:     register char *tmpstr;
        !           118:     char *tgetstr();
        !           119:     char *s;
        !           120:     int status;
        !           121: 
        !           122: #ifdef PENDING
        !           123: #ifndef FIONREAD
        !           124:     /* do no delay reads on something that always gets closed on exit */
        !           125: 
        !           126:     devtty = open("/dev/tty",0);
        !           127:     if (devtty < 0) {
        !           128:        printf(cantopen,"/dev/tty") FLUSH;
        !           129:        finalize(1);
        !           130:     }
        !           131:     fcntl(devtty,F_SETFL,O_NDELAY);
        !           132: #endif
        !           133: #endif
        !           134:     
        !           135:     /* get all that good termcap stuff */
        !           136: 
        !           137: #ifdef HAVETERMLIB
        !           138:     status = tgetent(tcbuf,getenv("TERM"));    /* get termcap entry */
        !           139:     if (status < 1) {
        !           140: #ifdef VERBOSE
        !           141:        printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
        !           142: #else
        !           143:        fputs("Termcap botch\n",stdout) FLUSH
        !           144: #endif
        !           145:        finalize(1);
        !           146:     }
        !           147:     tmpaddr = tcarea;                  /* set up strange tgetstr pointer */
        !           148:     s = Tgetstr("pc");                 /* get pad character */
        !           149:     PC = *s;                           /* get it where tputs wants it */
        !           150:     if (!tgetflag("bs")) {             /* is backspace not used? */
        !           151:        BC = Tgetstr("bc");             /* find out what is */
        !           152:        if (BC == nullstr)              /* terminfo grok's 'bs' but not 'bc' */
        !           153:            BC = Tgetstr("le");
        !           154:     } else
        !           155:        BC = "\b";                      /* make a backspace handy */
        !           156:     UP = Tgetstr("up");                        /* move up a line */
        !           157:     if (!*UP)                          /* no UP string? */
        !           158:        marking = 0;                    /* disable any marking */
        !           159:     if (muck_up_clear)                 /* this is for weird HPs */
        !           160:        CL = "\n\n\n\n";
        !           161:     else
        !           162:        CL = Tgetstr("cl");             /* get clear string */
        !           163:     CE = Tgetstr("ce");                        /* clear to end of line string */
        !           164: #ifdef CLEAREOL
        !           165:     CM = Tgetstr("cm");                        /* cursor motion - PWP */
        !           166:     HO = Tgetstr("ho");                        /* home cursor if no CM - PWP */
        !           167:     CD = Tgetstr("cd");                        /* clear to end of display - PWP */
        !           168:     if (!*CE || !*CD || (!*CM && !*HO))        /* can we CE, CD, and home? */
        !           169:        can_home_clear = FALSE;         /*  no, so disable use of clear eol */
        !           170: #endif CLEAREOL
        !           171:     SO = Tgetstr("so");                        /* begin standout */
        !           172:     SE = Tgetstr("se");                        /* end standout */
        !           173:     if ((SG = tgetnum("sg"))<0)
        !           174:        SG = 0;                         /* blanks left by SG, SE */
        !           175:     US = Tgetstr("us");                        /* start underline */
        !           176:     UE = Tgetstr("ue");                        /* end underline */
        !           177:     if ((UG = tgetnum("ug"))<0)
        !           178:        UG = 0;                         /* blanks left by US, UE */
        !           179:     if (*US)
        !           180:        UC = nullstr;                   /* UC must not be NULL */
        !           181:     else
        !           182:        UC = Tgetstr("uc");             /* underline a character */
        !           183:     if (!*US && !*UC) {                        /* no underline mode? */
        !           184:        US = SO;                        /* substitute standout mode */
        !           185:        UE = SE;
        !           186:        UG = SG;
        !           187:     }
        !           188:     LINES = tgetnum("li");             /* lines per page */
        !           189:     COLS = tgetnum("co");              /* columns on page */
        !           190:     AM = tgetflag("am");               /* terminal wraps automatically? */
        !           191:     XN = tgetflag("xn");               /* then eats next newline? */
        !           192:     VB = Tgetstr("vb");
        !           193:     if (!*VB)
        !           194:        VB = "\007";
        !           195:     CR = Tgetstr("cr");
        !           196:     if (!*CR) {
        !           197:        if (tgetflag("nc") && *UP) {
        !           198:            CR = safemalloc((MEM_SIZE)strlen(UP)+2);
        !           199:            sprintf(CR,"%s\r",UP);
        !           200:        }
        !           201:        else
        !           202:            CR = "\r";
        !           203:     }
        !           204: #else
        !           205:     ??????                             /* Roll your own... */
        !           206: #endif
        !           207:     if (LINES > 0) {                   /* is this a crt? */
        !           208:        if (!initlines)                 /* no -i? */
        !           209:            if (ospeed >= B9600)        /* whole page at >= 9600 baud */
        !           210:                initlines = LINES;
        !           211:            else if (ospeed >= B4800)   /* 16 lines at 4800 */
        !           212:                initlines = 16;
        !           213:            else                        /* otherwise just header */
        !           214:                initlines = 8;
        !           215:     }
        !           216:     else {                             /* not a crt */
        !           217:        LINES = 30000;                  /* so don't page */
        !           218:        CL = "\n\n";                    /* put a couple of lines between */
        !           219:        if (!initlines)                 /* make initlines reasonable */
        !           220:            initlines = 8;
        !           221:     }
        !           222:     if (COLS <= 0)
        !           223:        COLS = 80;
        !           224:     noecho();                          /* turn off echo */
        !           225:     crmode();                          /* enter cbreak mode */
        !           226: 
        !           227: #ifdef PUSHBACK
        !           228:     mac_init(tcbuf);
        !           229: #endif
        !           230: }
        !           231: 
        !           232: #ifdef PUSHBACK
        !           233: void
        !           234: mac_init(tcbuf)
        !           235: char *tcbuf;
        !           236: {
        !           237:     char tmpbuf[1024];
        !           238: 
        !           239:     tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
        !           240:     if (tmpfp != Nullfp) {
        !           241:        while (fgets(tcbuf,1024,tmpfp) != Nullch) {
        !           242:            mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
        !           243:        }
        !           244:        fclose(tmpfp);
        !           245:     }
        !           246: }
        !           247: 
        !           248: void
        !           249: mac_line(line,tmpbuf,tbsize)
        !           250: char *line;
        !           251: char *tmpbuf;
        !           252: int tbsize;
        !           253: {
        !           254:     register char *s, *m;
        !           255:     register KEYMAP *curmap;
        !           256:     register int ch;
        !           257:     register int garbage = 0;
        !           258:     static char override[] = "\nkeymap overrides string\n";
        !           259: 
        !           260:     if (topmap == Null(KEYMAP*))
        !           261:        topmap = newkeymap();
        !           262:     if (*line == '#' || *line == '\n')
        !           263:        return;
        !           264:     if (line[ch = strlen(line)-1] == '\n')
        !           265:        line[ch] = '\0';
        !           266:     m = dointerp(tmpbuf,tbsize,line," \t");
        !           267:     if (!*m)
        !           268:        return;
        !           269:     while (*m == ' ' || *m == '\t') m++;
        !           270:     for (s=tmpbuf,curmap=topmap; *s; s++) {
        !           271:        ch = *s & 0177;
        !           272:        if (s[1] == '+' && isdigit(s[2])) {
        !           273:            s += 2;
        !           274:            garbage = (*s & KM_GMASK) << KM_GSHIFT;
        !           275:        }
        !           276:        else
        !           277:            garbage = 0;
        !           278:        if (s[1]) {
        !           279:            if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
        !           280:                puts(override,stdout) FLUSH;
        !           281:                free(curmap->km_ptr[ch].km_str);
        !           282:                curmap->km_ptr[ch].km_str = Nullch;
        !           283:            }
        !           284:            curmap->km_type[ch] = KM_KEYMAP + garbage;
        !           285:            if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
        !           286:                curmap->km_ptr[ch].km_km = newkeymap();
        !           287:            curmap = curmap->km_ptr[ch].km_km;
        !           288:        }
        !           289:        else {
        !           290:            if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
        !           291:                puts(override,stdout) FLUSH;
        !           292:            else {
        !           293:                curmap->km_type[ch] = KM_STRING + garbage;
        !           294:                curmap->km_ptr[ch].km_str = savestr(m);
        !           295:            }
        !           296:        }
        !           297:     }
        !           298: }
        !           299: 
        !           300: KEYMAP*
        !           301: newkeymap()
        !           302: {
        !           303:     register int i;
        !           304:     register KEYMAP *map;
        !           305: 
        !           306: #ifndef lint
        !           307:     map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
        !           308: #else
        !           309:     map = Null(KEYMAP*);
        !           310: #endif lint
        !           311:     for (i=127; i>=0; --i) {
        !           312:        map->km_ptr[i].km_km = Null(KEYMAP*);
        !           313:        map->km_type[i] = KM_NOTHIN;
        !           314:     }
        !           315:     return map;
        !           316: }
        !           317: 
        !           318: void
        !           319: show_macros()
        !           320: {
        !           321:     char prebuf[64];
        !           322: 
        !           323:     if (topmap != Null(KEYMAP*)) {
        !           324:        print_lines("Macros:\n",STANDOUT);
        !           325:        *prebuf = '\0';
        !           326:        show_keymap(topmap,prebuf);
        !           327:     }
        !           328: }
        !           329: 
        !           330: void
        !           331: show_keymap(curmap,prefix)
        !           332: register KEYMAP *curmap;
        !           333: char *prefix;
        !           334: {
        !           335:     register int i;
        !           336:     register char *next = prefix + strlen(prefix);
        !           337:     register int kt;
        !           338: 
        !           339:     for (i=0; i<128; i++) {
        !           340:        if (kt = curmap->km_type[i]) {
        !           341:            if (i < ' ')
        !           342:                sprintf(next,"^%c",i+64);
        !           343:            else if (i == ' ')
        !           344:                strcpy(next,"\\040");
        !           345:            else if (i == 127)
        !           346:                strcpy(next,"^?");
        !           347:            else
        !           348:                sprintf(next,"%c",i);
        !           349:            if ((kt >> KM_GSHIFT) & KM_GMASK) {
        !           350:                sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
        !           351:                strcat(next,cmd_buf);
        !           352:            }
        !           353:            switch (kt & KM_TMASK) {
        !           354:            case KM_NOTHIN:
        !           355:                sprintf(cmd_buf,"%s     %c\n",prefix,i);
        !           356:                print_lines(cmd_buf,NOMARKING);
        !           357:                break;
        !           358:            case KM_KEYMAP:
        !           359:                show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
        !           360:                break;
        !           361:            case KM_STRING:
        !           362:                sprintf(cmd_buf,"%s     %s\n",prefix,curmap->km_ptr[i].km_str);
        !           363:                print_lines(cmd_buf,NOMARKING);
        !           364:                break;
        !           365:            case KM_BOGUS:
        !           366:                sprintf(cmd_buf,"%s     BOGUS\n",prefix);
        !           367:                print_lines(cmd_buf,STANDOUT);
        !           368:                break;
        !           369:            }
        !           370:        }
        !           371:     }
        !           372: }
        !           373: 
        !           374: #endif
        !           375: 
        !           376: /* routine to pass to tputs */
        !           377: 
        !           378: char
        !           379: putchr(ch)
        !           380: register char ch;
        !           381: {
        !           382:     putchar(ch);
        !           383: #ifdef lint
        !           384:     ch = Null(char);
        !           385:     ch = ch;
        !           386: #endif
        !           387: }
        !           388: 
        !           389: /* input the 2nd and succeeding characters of a multi-character command */
        !           390: /* returns TRUE if command finished, FALSE if they rubbed out first character */
        !           391: 
        !           392: bool
        !           393: finish_command(donewline)
        !           394: int donewline;
        !           395: {
        !           396:     register char *s;
        !           397:     register bool quoteone = FALSE;
        !           398: 
        !           399:     s = buf;
        !           400:     if (s[1] != FINISHCMD)             /* someone faking up a command? */
        !           401:        return TRUE;
        !           402:     do {
        !           403:       top:
        !           404:        if (*s < ' ') {
        !           405:            putchar('^');
        !           406:            putchar(*s | 64);
        !           407:        }
        !           408:        else if (*s == '\177') {
        !           409:            putchar('^');
        !           410:            putchar('?');
        !           411:        }
        !           412:        else
        !           413:            putchar(*s);                /* echo previous character */
        !           414:        s++;
        !           415: re_read:
        !           416:        fflush(stdout);
        !           417:        getcmd(s);
        !           418:        if (quoteone) {
        !           419:            quoteone = FALSE;
        !           420:            continue;
        !           421:        }
        !           422:        if (errno || *s == Ctl('l')) {
        !           423:            *s = Ctl('r');              /* force rewrite on CONT */
        !           424:        }
        !           425:        if (*s == '\033') {             /* substitution desired? */
        !           426: #ifdef ESCSUBS
        !           427:            char tmpbuf[4], *cpybuf;
        !           428: 
        !           429:            tmpbuf[0] = '%';
        !           430:            read_tty(&tmpbuf[1],1);
        !           431: #ifdef RAWONLY
        !           432:            tmpbuf[1] &= 0177;
        !           433: #endif
        !           434:            tmpbuf[2] = '\0';
        !           435:            if (tmpbuf[1] == 'h') {
        !           436:                (void) help_subs();
        !           437:                *s = '\0';
        !           438:                reprint();
        !           439:                goto re_read;
        !           440:            }
        !           441:            else if (tmpbuf[1] == '\033') {
        !           442:                *s = '\0';
        !           443:                cpybuf = savestr(buf);
        !           444:                interp(buf, (sizeof buf), cpybuf);
        !           445:                free(cpybuf);
        !           446:                s = buf + strlen(buf);
        !           447:                reprint();
        !           448:                goto re_read;
        !           449:            }
        !           450:            else {
        !           451:                interp(s,(sizeof buf) - (s-buf),tmpbuf);
        !           452:                fputs(s,stdout);
        !           453:                s += strlen(s);
        !           454:            }
        !           455:            goto re_read;
        !           456: #else
        !           457:            notincl("^[");
        !           458:            *s = '\0';
        !           459:            reprint();
        !           460:            goto re_read;
        !           461: #endif
        !           462:        }
        !           463:        else if (*s == ERASECH) {       /* they want to rubout a char? */
        !           464:            rubout();
        !           465:            s--;                        /* discount the char rubbed out */
        !           466:            if (*s < ' ' || *s == '\177')
        !           467:                rubout();
        !           468:            if (s == buf) {             /* entire string gone? */
        !           469:                fflush(stdout);         /* return to single char command mode */
        !           470:                return FALSE;
        !           471:            }
        !           472:            else
        !           473:                goto re_read;
        !           474:        }
        !           475:        else if (*s == KILLCH) {        /* wipe out the whole line? */
        !           476:            while (s-- != buf) {        /* emulate that many ERASEs */
        !           477:                rubout();
        !           478:                if (*s < ' ' || *s == '\177')
        !           479:                    rubout();
        !           480:            }
        !           481:            fflush(stdout);
        !           482:            return FALSE;               /* return to single char mode */
        !           483:        }
        !           484: #ifdef WORDERASE
        !           485:        else if (*s == Ctl('w')) {      /* wipe out one word? */
        !           486:            *s-- = ' ';
        !           487:            while (!isspace(*s) || isspace(s[1])) {
        !           488:                rubout();
        !           489:                if (s-- == buf) {
        !           490:                    fflush(stdout);
        !           491:                    return FALSE;       /* return to single char mode */
        !           492:                }
        !           493:                if (*s < ' ' || *s == '\177')
        !           494:                    rubout();
        !           495:            }
        !           496:            s++;
        !           497:            goto re_read;
        !           498:        }
        !           499: #endif
        !           500:        else if (*s == Ctl('r')) {
        !           501:            *s = '\0';
        !           502:            reprint();
        !           503:            goto re_read;
        !           504:        }
        !           505:        else if (*s == Ctl('v')) {
        !           506:            putchar('^');
        !           507:            backspace();
        !           508:            fflush(stdout);
        !           509:            getcmd(s);
        !           510:            goto top;
        !           511:        }
        !           512:        else if (*s == '\\') {
        !           513:            quoteone = TRUE;
        !           514:        }
        !           515:     } while (*s != '\n');              /* till a newline (not echoed) */
        !           516:     *s = '\0';                         /* terminate the string nicely */
        !           517:     if (donewline)
        !           518:        putchar('\n') FLUSH;
        !           519:     return TRUE;                       /* say we succeeded */
        !           520: }
        !           521: 
        !           522: /* discard any characters typed ahead */
        !           523: 
        !           524: void
        !           525: eat_typeahead()
        !           526: {
        !           527: #ifdef PUSHBACK
        !           528:     if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
        !           529: #else
        !           530:     if (!typeahead)
        !           531: #endif
        !           532:     {
        !           533: #ifdef PENDING
        !           534:        while (input_pending())
        !           535:            read_tty(buf,sizeof(buf));
        !           536: #else /* this is probably v7 */
        !           537:        ioctl(_tty_ch,TIOCSETP,&_tty);
        !           538: #endif
        !           539:     }
        !           540: }
        !           541: 
        !           542: void
        !           543: settle_down()
        !           544: {
        !           545:     dingaling();
        !           546:     fflush(stdout);
        !           547:     sleep(1);
        !           548: #ifdef PUSHBACK
        !           549:     nextout = nextin;                  /* empty circlebuf */
        !           550: #endif
        !           551:     eat_typeahead();
        !           552: }
        !           553: 
        !           554: #ifdef PUSHBACK
        !           555: /* read a character from the terminal, with multi-character pushback */
        !           556: 
        !           557: int
        !           558: read_tty(addr,size)
        !           559: char *addr;
        !           560: int size;
        !           561: {
        !           562:     if (nextout != nextin) {
        !           563:        *addr = circlebuf[nextout++];
        !           564:        nextout %= PUSHSIZE;
        !           565:        return 1;
        !           566:     }
        !           567:     else {
        !           568:        size = read(0,addr,size);
        !           569: #ifdef RAWONLY
        !           570:        *addr &= 0177;
        !           571: #endif
        !           572:        return size;
        !           573:     }
        !           574: }
        !           575: 
        !           576: #ifdef PENDING
        !           577: #ifndef FIONREAD
        !           578: int
        !           579: circfill()
        !           580: {
        !           581:     register int howmany = read(devtty,circlebuf+nextin,1);
        !           582: 
        !           583:     if (howmany) {
        !           584:        nextin += howmany;
        !           585:        nextin %= PUSHSIZE;
        !           586:     }
        !           587:     return howmany;
        !           588: }
        !           589: #endif PENDING
        !           590: #endif FIONREAD
        !           591: 
        !           592: void
        !           593: pushchar(c)
        !           594: char c;
        !           595: {
        !           596:     nextout--;
        !           597:     if (nextout < 0)
        !           598:        nextout = PUSHSIZE - 1;
        !           599:     if (nextout == nextin) {
        !           600:        fputs("\npushback buffer overflow\n",stdout) FLUSH;
        !           601:        sig_catcher(0);
        !           602:     }
        !           603:     circlebuf[nextout] = c;
        !           604: }
        !           605: 
        !           606: #else PUSHBACK
        !           607: #ifndef read_tty
        !           608: /* read a character from the terminal, with hacks for O_NDELAY reads */
        !           609: 
        !           610: int
        !           611: read_tty(addr,size)
        !           612: char *addr;
        !           613: int size;
        !           614: {
        !           615:     if (is_input) {
        !           616:        *addr = pending_ch;
        !           617:        is_input = FALSE;
        !           618:        return 1;
        !           619:     }
        !           620:     else {
        !           621:        size = read(0,addr,size)
        !           622: #ifdef RAWONLY
        !           623:        *addr &= 0177;
        !           624: #endif
        !           625:        return size;
        !           626:     }
        !           627: }
        !           628: #endif read_tty
        !           629: #endif PUSHBACK
        !           630: 
        !           631: /* print an underlined string, one way or another */
        !           632: 
        !           633: void
        !           634: underprint(s)
        !           635: register char *s;
        !           636: {
        !           637:     assert(UC);
        !           638:     if (*UC) {         /* char by char underline? */
        !           639:        while (*s) {
        !           640:            if (*s < ' ') {
        !           641:                putchar('^');
        !           642:                backspace();/* back up over it */
        !           643:                underchar();/* and do the underline */
        !           644:                putchar(*s+64);
        !           645:                backspace();/* back up over it */
        !           646:                underchar();/* and do the underline */
        !           647:            }
        !           648:            else {
        !           649:                putchar(*s);
        !           650:                backspace();/* back up over it */
        !           651:                underchar();/* and do the underline */
        !           652:            }
        !           653:            s++;
        !           654:        }
        !           655:     }
        !           656:     else {             /* start and stop underline */
        !           657:        underline();    /* start underlining */
        !           658:        while (*s) {
        !           659:            if (*s < ' ') {
        !           660:                putchar('^');
        !           661:                putchar(*s+64);
        !           662:            }
        !           663:            else
        !           664:                putchar(*s);
        !           665:            s++;
        !           666:        }
        !           667:        un_underline(); /* stop underlining */
        !           668:     }
        !           669: }
        !           670: 
        !           671: /* keep screen from flashing strangely on magic cookie terminals */
        !           672: 
        !           673: #ifdef NOFIREWORKS
        !           674: void
        !           675: no_sofire()
        !           676: {
        !           677:     if (*UP && *SE) {          /* should we disable fireworks? */
        !           678:        putchar('\n');
        !           679:        un_standout();
        !           680:        up_line();
        !           681:        carriage_return();
        !           682:     }
        !           683: }
        !           684: 
        !           685: void
        !           686: no_ulfire()
        !           687: {
        !           688:     if (*UP && *US) {          /* should we disable fireworks? */
        !           689:        putchar('\n');
        !           690:        un_underline();
        !           691:        up_line();
        !           692:        carriage_return();
        !           693:     }
        !           694: }
        !           695: #endif
        !           696: 
        !           697: /* get a character into a buffer */
        !           698: 
        !           699: void
        !           700: getcmd(whatbuf)
        !           701: register char *whatbuf;
        !           702: {
        !           703: #ifdef PUSHBACK
        !           704:     register KEYMAP *curmap;
        !           705:     register int i;
        !           706:     bool no_macros; 
        !           707:     int times = 0;                     /* loop detector */
        !           708:     char scrchar;
        !           709: 
        !           710: tryagain:
        !           711:     curmap = topmap;
        !           712:     no_macros = (whatbuf != buf && nextin == nextout); 
        !           713: #endif
        !           714:     for (;;) {
        !           715:        int_count = 0;
        !           716:        errno = 0;
        !           717:        if (read_tty(whatbuf,1) < 0 && !errno)
        !           718:            errno = EINTR;
        !           719:        if (errno && errno != EINTR) {
        !           720:            perror(readerr);
        !           721:            sig_catcher(0);
        !           722:        }
        !           723: #ifdef PUSHBACK
        !           724:        if (*whatbuf & 0200 || no_macros) {
        !           725:            *whatbuf &= 0177;
        !           726:            goto got_canonical;
        !           727:        }
        !           728:        if (curmap == Null(KEYMAP*))
        !           729:            goto got_canonical;
        !           730:        for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
        !           731:            read_tty(&scrchar,1);
        !           732:        }
        !           733:        switch (curmap->km_type[*whatbuf] & KM_TMASK) {
        !           734:        case KM_NOTHIN:                 /* no entry? */
        !           735:            if (curmap == topmap)       /* unmapped canonical */
        !           736:                goto got_canonical;
        !           737:            settle_down();
        !           738:            goto tryagain;
        !           739:        case KM_KEYMAP:                 /* another keymap? */
        !           740:            curmap = curmap->km_ptr[*whatbuf].km_km;
        !           741:            assert(curmap != Null(KEYMAP*));
        !           742:            break;
        !           743:        case KM_STRING:                 /* a string? */
        !           744:            pushstring(curmap->km_ptr[*whatbuf].km_str);
        !           745:            if (++times > 20) {         /* loop? */
        !           746:                fputs("\nmacro loop?\n",stdout);
        !           747:                settle_down();
        !           748:            }
        !           749:            no_macros = FALSE;
        !           750:            goto tryagain;
        !           751:        }
        !           752: #else
        !           753: #ifdef RAWONLY
        !           754:        *whatbuf &= 0177;
        !           755: #endif
        !           756:        break;
        !           757: #endif
        !           758:     }
        !           759: 
        !           760: got_canonical:
        !           761: #ifndef TERMIO
        !           762:     if (*whatbuf == '\r')
        !           763:        *whatbuf = '\n';
        !           764: #endif
        !           765:     if (whatbuf == buf)
        !           766:        whatbuf[1] = FINISHCMD;         /* tell finish_command to work */
        !           767: }
        !           768: 
        !           769: #ifdef PUSHBACK
        !           770: void
        !           771: pushstring(str)
        !           772: char *str;
        !           773: {
        !           774:     register int i;
        !           775:     char tmpbuf[PUSHSIZE];
        !           776:     register char *s = tmpbuf;
        !           777: 
        !           778:     assert(str != Nullch);
        !           779:     interp(s,PUSHSIZE,str);
        !           780:     for (i = strlen(s)-1; i >= 0; --i) {
        !           781:        s[i] ^= 0200; 
        !           782:        pushchar(s[i]);
        !           783:     }
        !           784: }
        !           785: #endif
        !           786: 
        !           787: int
        !           788: get_anything()
        !           789: {
        !           790:     char tmpbuf[2];
        !           791: 
        !           792: reask_anything:
        !           793:     unflush_output();                  /* disable any ^O in effect */
        !           794:     standout();
        !           795: #ifdef VERBOSE
        !           796:     IF(verbose)
        !           797:        fputs("[Type space to continue] ",stdout);
        !           798:     ELSE
        !           799: #endif
        !           800: #ifdef TERSE
        !           801:        fputs("[MORE] ",stdout);
        !           802: #endif
        !           803:     un_standout();
        !           804:     fflush(stdout);
        !           805:     eat_typeahead();
        !           806:     if (int_count) {
        !           807:        return -1;
        !           808:     }
        !           809:     collect_subjects();                        /* loads subject cache until */
        !           810:                                        /* input is pending */
        !           811:     getcmd(tmpbuf);
        !           812:     if (errno || *tmpbuf == '\f') {
        !           813:        putchar('\n') FLUSH;            /* if return from stop signal */
        !           814:        goto reask_anything;            /* give them a prompt again */
        !           815:     }
        !           816:     if (*tmpbuf == 'h') {
        !           817: #ifdef VERBOSE
        !           818:        IF(verbose)
        !           819:            fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
        !           820:        ELSE
        !           821: #endif
        !           822: #ifdef TERSE
        !           823:            fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
        !           824: #endif
        !           825:        goto reask_anything;
        !           826:     }
        !           827:     else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
        !           828:        carriage_return();
        !           829:        erase_eol();    /* erase the prompt */
        !           830:        return *tmpbuf == 'q' ? -1 : *tmpbuf;
        !           831:     }
        !           832:     if (*tmpbuf == '\n') {
        !           833:        page_line = LINES - 1;
        !           834:        carriage_return();
        !           835:        erase_eol();
        !           836:     }
        !           837:     else {
        !           838:        page_line = 1;
        !           839:        if (erase_screen)               /* -e? */
        !           840:            clear();                    /* clear screen */
        !           841:        else {
        !           842:            carriage_return();
        !           843:            erase_eol();                /* erase the prompt */
        !           844:        }
        !           845:     }
        !           846:     return 0;
        !           847: }
        !           848: 
        !           849: void
        !           850: in_char(prompt)
        !           851: char *prompt;
        !           852: {
        !           853:     char oldmode = mode;
        !           854: 
        !           855: reask_in_char:
        !           856:     unflush_output();                  /* disable any ^O in effect */
        !           857:     fputs(prompt,stdout);
        !           858:     fflush(stdout);
        !           859:     eat_typeahead();
        !           860:     mode = 'm';
        !           861:     getcmd(buf);
        !           862:     if (errno || *buf == '\f') {
        !           863:        putchar('\n') FLUSH;            /* if return from stop signal */
        !           864:        goto reask_in_char;             /* give them a prompt again */
        !           865:     }
        !           866:     mode = oldmode;
        !           867: }
        !           868: 
        !           869: int
        !           870: print_lines(what_to_print,hilite)
        !           871: char *what_to_print;
        !           872: int hilite;
        !           873: {
        !           874:     register char *s;
        !           875:     register int i;
        !           876: 
        !           877:     if (page_line < 0)                 /* they do not want to see this? */
        !           878:        return -1;
        !           879:     for (s=what_to_print; *s; ) {
        !           880:        if (page_line >= LINES || int_count) {
        !           881:            if (i = -1, int_count || (i = get_anything())) {
        !           882:                page_line = -1;         /* disable further print_lines */
        !           883:                return i;
        !           884:            }
        !           885:        }
        !           886:        page_line++;
        !           887:        if (hilite == STANDOUT) {
        !           888: #ifdef NOFIREWORKS
        !           889:            if (erase_screen)
        !           890:                no_sofire();
        !           891: #endif
        !           892:            standout();
        !           893:        }
        !           894:        else if (hilite == UNDERLINE) {
        !           895: #ifdef NOFIREWORKS
        !           896:            if (erase_screen)
        !           897:                no_ulfire();
        !           898: #endif
        !           899:            underline();
        !           900:        }
        !           901:        for (i=0; i<COLS; i++) {
        !           902:            if (!*s)
        !           903:                break;
        !           904:            if (*s >= ' ')
        !           905:                putchar(*s);
        !           906:            else if (*s == '\t') {
        !           907:                putchar(*s);
        !           908:                i = ((i+8) & ~7) - 1; 
        !           909:            }
        !           910:            else if (*s == '\n') {
        !           911:                i = 32000;
        !           912:            }
        !           913:            else {
        !           914:                i++;
        !           915:                putchar('^');
        !           916:                putchar(*s + 64);
        !           917:            }
        !           918:            s++;
        !           919:        }
        !           920:        if (i) {
        !           921:            if (hilite == STANDOUT)
        !           922:                un_standout();
        !           923:            else if (hilite == UNDERLINE)
        !           924:                un_underline();
        !           925:            if (AM && i == COLS)
        !           926:                fflush(stdout);
        !           927:            else
        !           928:                putchar('\n') FLUSH;
        !           929:        }
        !           930:     }
        !           931:     return 0;
        !           932: }
        !           933: 
        !           934: void
        !           935: page_init()
        !           936: {
        !           937:     page_line = 1;
        !           938:     if (erase_screen)
        !           939:        clear();
        !           940:     else
        !           941:        putchar('\n') FLUSH;
        !           942: }
        !           943: 
        !           944: void
        !           945: pad(num)
        !           946: int num;
        !           947: {
        !           948:     register int i;
        !           949: 
        !           950:     for (i = num; i; --i)
        !           951:        putchar(PC);
        !           952:     fflush(stdout);
        !           953: }
        !           954: 
        !           955: /* echo the command just typed */
        !           956: 
        !           957: #ifdef VERIFY
        !           958: void
        !           959: printcmd()
        !           960: {
        !           961:     if (verify && buf[1] == FINISHCMD) {
        !           962:        if (*buf < ' ') {
        !           963:            putchar('^');
        !           964:            putchar(*buf | 64);
        !           965:            backspace();
        !           966:            backspace();
        !           967:        }
        !           968:        else {
        !           969:            putchar(*buf);
        !           970:            backspace();
        !           971:        }
        !           972:        fflush(stdout);
        !           973:     }
        !           974: }
        !           975: #endif
        !           976: 
        !           977: void
        !           978: rubout()
        !           979: {
        !           980:     backspace();                       /* do the old backspace, */
        !           981:     putchar(' ');                      /*   space, */
        !           982:     backspace();                       /*     backspace trick */
        !           983: }
        !           984: 
        !           985: void
        !           986: reprint()
        !           987: {
        !           988:     register char *s;
        !           989: 
        !           990:     fputs("^R\n",stdout) FLUSH;
        !           991:     for (s = buf; *s; s++) {
        !           992:        if (*s < ' ') {
        !           993:            putchar('^');
        !           994:            putchar(*s | 64);
        !           995:        }
        !           996:        else
        !           997:            putchar(*s);
        !           998:     }
        !           999: }
        !          1000: 
        !          1001: #ifdef CLEAREOL
        !          1002: /* start of additions by Paul Placeway (PWP) */
        !          1003: 
        !          1004: void
        !          1005: home_cursor()
        !          1006: {
        !          1007:     char *tgoto();
        !          1008: 
        !          1009:     if (!*HO) {                        /* no home sequence? */
        !          1010:        if (!*CM) {             /* no cursor motion either? */
        !          1011:            fputs ("\n\n\n", stdout);
        !          1012:            return;             /* forget it. */
        !          1013:        }
        !          1014:        tputs (tgoto (CM, 0, 0), 1, putchr);    /* go to home via CM */
        !          1015:        return;
        !          1016:     }
        !          1017:     else {                     /* we have home sequence */
        !          1018:        tputs (HO, 1, putchr);  /* home via HO */
        !          1019:     }
        !          1020: }
        !          1021: #endif CLEAREOL

unix.superglobalmegacorp.com

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