Annotation of 43BSDTahoe/games/hack/hack.pager.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
        !             2: /* hack.pager.c - version 1.0.3 */
        !             3: 
        !             4: /* This file contains the command routine dowhatis() and a pager. */
        !             5: /* Also readmail() and doshell(), and generally the things that
        !             6:    contact the outside world. */
        !             7: 
        !             8: #include       <stdio.h>
        !             9: #include       <signal.h>
        !            10: #include "hack.h"
        !            11: extern int CO, LI;     /* usually COLNO and ROWNO+2 */
        !            12: extern char *CD;
        !            13: extern char quitchars[];
        !            14: extern char *getenv(), *getlogin();
        !            15: int done1();
        !            16: 
        !            17: dowhatis()
        !            18: {
        !            19:        FILE *fp;
        !            20:        char bufr[BUFSZ+6];
        !            21:        register char *buf = &bufr[6], *ep, q;
        !            22:        extern char readchar();
        !            23: 
        !            24:        if(!(fp = fopen(DATAFILE, "r")))
        !            25:                pline("Cannot open data file!");
        !            26:        else {
        !            27:                pline("Specify what? ");
        !            28:                q = readchar();
        !            29:                if(q != '\t')
        !            30:                while(fgets(buf,BUFSZ,fp))
        !            31:                    if(*buf == q) {
        !            32:                        ep = index(buf, '\n');
        !            33:                        if(ep) *ep = 0;
        !            34:                        /* else: bad data file */
        !            35:                        /* Expand tab 'by hand' */
        !            36:                        if(buf[1] == '\t'){
        !            37:                                buf = bufr;
        !            38:                                buf[0] = q;
        !            39:                                (void) strncpy(buf+1, "       ", 7);
        !            40:                        }
        !            41:                        pline(buf);
        !            42:                        if(ep[-1] == ';') {
        !            43:                                pline("More info? ");
        !            44:                                if(readchar() == 'y') {
        !            45:                                        page_more(fp,1); /* does fclose() */
        !            46:                                        return(0);
        !            47:                                }
        !            48:                        }
        !            49:                        (void) fclose(fp);      /* kopper@psuvax1 */
        !            50:                        return(0);
        !            51:                    }
        !            52:                pline("I've never heard of such things.");
        !            53:                (void) fclose(fp);
        !            54:        }
        !            55:        return(0);
        !            56: }
        !            57: 
        !            58: /* make the paging of a file interruptible */
        !            59: static int got_intrup;
        !            60: 
        !            61: intruph(){
        !            62:        got_intrup++;
        !            63: }
        !            64: 
        !            65: /* simple pager, also used from dohelp() */
        !            66: page_more(fp,strip)
        !            67: FILE *fp;
        !            68: int strip;     /* nr of chars to be stripped from each line (0 or 1) */
        !            69: {
        !            70:        register char *bufr, *ep;
        !            71:        int (*prevsig)() = signal(SIGINT, intruph);
        !            72: 
        !            73:        set_pager(0);
        !            74:        bufr = (char *) alloc((unsigned) CO);
        !            75:        bufr[CO-1] = 0;
        !            76:        while(fgets(bufr,CO-1,fp) && (!strip || *bufr == '\t') && !got_intrup){
        !            77:                ep = index(bufr, '\n');
        !            78:                if(ep)
        !            79:                        *ep = 0;
        !            80:                if(page_line(bufr+strip)) {
        !            81:                        set_pager(2);
        !            82:                        goto ret;
        !            83:                }
        !            84:        }
        !            85:        set_pager(1);
        !            86: ret:
        !            87:        free(bufr);
        !            88:        (void) fclose(fp);
        !            89:        (void) signal(SIGINT, prevsig);
        !            90:        got_intrup = 0;
        !            91: }
        !            92: 
        !            93: static boolean whole_screen = TRUE;
        !            94: #define        PAGMIN  12      /* minimum # of lines for page below level map */
        !            95: 
        !            96: set_whole_screen() {   /* called in termcap as soon as LI is known */
        !            97:        whole_screen = (LI-ROWNO-2 <= PAGMIN || !CD);
        !            98: }
        !            99: 
        !           100: #ifdef NEWS
        !           101: readnews() {
        !           102:        register int ret;
        !           103: 
        !           104:        whole_screen = TRUE;    /* force a docrt(), our first */
        !           105:        ret = page_file(NEWS, TRUE);
        !           106:        set_whole_screen();
        !           107:        return(ret);            /* report whether we did docrt() */
        !           108: }
        !           109: #endif NEWS
        !           110: 
        !           111: set_pager(mode)
        !           112: register int mode;     /* 0: open  1: wait+close  2: close */
        !           113: {
        !           114:        static boolean so;
        !           115:        if(mode == 0) {
        !           116:                if(!whole_screen) {
        !           117:                        /* clear topline */
        !           118:                        clrlin();
        !           119:                        /* use part of screen below level map */
        !           120:                        curs(1, ROWNO+4);
        !           121:                } else {
        !           122:                        cls();
        !           123:                }
        !           124:                so = flags.standout;
        !           125:                flags.standout = 1;
        !           126:        } else {
        !           127:                if(mode == 1) {
        !           128:                        curs(1, LI);
        !           129:                        more();
        !           130:                }
        !           131:                flags.standout = so;
        !           132:                if(whole_screen)
        !           133:                        docrt();
        !           134:                else {
        !           135:                        curs(1, ROWNO+4);
        !           136:                        cl_eos();
        !           137:                }
        !           138:        }
        !           139: }
        !           140: 
        !           141: page_line(s)           /* returns 1 if we should quit */
        !           142: register char *s;
        !           143: {
        !           144:        extern char morc;
        !           145: 
        !           146:        if(cury == LI-1) {
        !           147:                if(!*s)
        !           148:                        return(0);      /* suppress blank lines at top */
        !           149:                putchar('\n');
        !           150:                cury++;
        !           151:                cmore("q\033");
        !           152:                if(morc) {
        !           153:                        morc = 0;
        !           154:                        return(1);
        !           155:                }
        !           156:                if(whole_screen)
        !           157:                        cls();
        !           158:                else {
        !           159:                        curs(1, ROWNO+4);
        !           160:                        cl_eos();
        !           161:                }
        !           162:        }
        !           163:        puts(s);
        !           164:        cury++;
        !           165:        return(0);
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * Flexible pager: feed it with a number of lines and it will decide
        !           170:  * whether these should be fed to the pager above, or displayed in a
        !           171:  * corner.
        !           172:  * Call:
        !           173:  *     cornline(0, title or 0) : initialize
        !           174:  *     cornline(1, text)       : add text to the chain of texts
        !           175:  *     cornline(2, morcs)      : output everything and cleanup
        !           176:  *     cornline(3, 0)          : cleanup
        !           177:  */
        !           178: 
        !           179: cornline(mode, text)
        !           180: int mode;
        !           181: char *text;
        !           182: {
        !           183:        static struct line {
        !           184:                struct line *next_line;
        !           185:                char *line_text;
        !           186:        } *texthead, *texttail;
        !           187:        static int maxlen;
        !           188:        static int linect;
        !           189:        register struct line *tl;
        !           190: 
        !           191:        if(mode == 0) {
        !           192:                texthead = 0;
        !           193:                maxlen = 0;
        !           194:                linect = 0;
        !           195:                if(text) {
        !           196:                        cornline(1, text);      /* title */
        !           197:                        cornline(1, "");        /* blank line */
        !           198:                }
        !           199:                return;
        !           200:        }
        !           201: 
        !           202:        if(mode == 1) {
        !           203:            register int len;
        !           204: 
        !           205:            if(!text) return;   /* superfluous, just to be sure */
        !           206:            linect++;
        !           207:            len = strlen(text);
        !           208:            if(len > maxlen)
        !           209:                maxlen = len;
        !           210:            tl = (struct line *)
        !           211:                alloc((unsigned)(len + sizeof(struct line) + 1));
        !           212:            tl->next_line = 0;
        !           213:            tl->line_text = (char *)(tl + 1);
        !           214:            (void) strcpy(tl->line_text, text);
        !           215:            if(!texthead)
        !           216:                texthead = tl;
        !           217:            else
        !           218:                texttail->next_line = tl;
        !           219:            texttail = tl;
        !           220:            return;
        !           221:        }
        !           222: 
        !           223:        /* --- now we really do it --- */
        !           224:        if(mode == 2 && linect == 1)                        /* topline only */
        !           225:                pline(texthead->line_text);
        !           226:        else
        !           227:        if(mode == 2) {
        !           228:            register int curline, lth;
        !           229: 
        !           230:            if(flags.toplin == 1) more();       /* ab@unido */
        !           231:            remember_topl();
        !           232: 
        !           233:            lth = CO - maxlen - 2;                 /* Use full screen width */
        !           234:            if (linect < LI && lth >= 10) {                  /* in a corner */
        !           235:                home ();
        !           236:                cl_end ();
        !           237:                flags.toplin = 0;
        !           238:                curline = 1;
        !           239:                for (tl = texthead; tl; tl = tl->next_line) {
        !           240:                    curs (lth, curline);
        !           241:                    if(curline > 1)
        !           242:                        cl_end ();
        !           243:                    putsym(' ');
        !           244:                    putstr (tl->line_text);
        !           245:                    curline++;
        !           246:                }
        !           247:                curs (lth, curline);
        !           248:                cl_end ();
        !           249:                cmore (text);
        !           250:                home ();
        !           251:                cl_end ();
        !           252:                docorner (lth, curline-1);
        !           253:            } else {                                    /* feed to pager */
        !           254:                set_pager(0);
        !           255:                for (tl = texthead; tl; tl = tl->next_line) {
        !           256:                    if (page_line (tl->line_text)) {
        !           257:                        set_pager(2);
        !           258:                        goto cleanup;
        !           259:                    }
        !           260:                }
        !           261:                if(text) {
        !           262:                        cgetret(text);
        !           263:                        set_pager(2);
        !           264:                } else
        !           265:                        set_pager(1);
        !           266:            }
        !           267:        }
        !           268: 
        !           269: cleanup:
        !           270:        while(tl = texthead) {
        !           271:                texthead = tl->next_line;
        !           272:                free((char *) tl);
        !           273:        }
        !           274: }
        !           275: 
        !           276: dohelp()
        !           277: {
        !           278:        char c;
        !           279: 
        !           280:        pline ("Long or short help? ");
        !           281:        while (((c = readchar ()) != 'l') && (c != 's') && !index(quitchars,c))
        !           282:                bell ();
        !           283:        if (!index(quitchars, c))
        !           284:                (void) page_file((c == 'l') ? HELP : SHELP, FALSE);
        !           285:        return(0);
        !           286: }
        !           287: 
        !           288: page_file(fnam, silent)        /* return: 0 - cannot open fnam; 1 - otherwise */
        !           289: register char *fnam;
        !           290: boolean silent;
        !           291: {
        !           292: #ifdef DEF_PAGER                       /* this implies that UNIX is defined */
        !           293:       {
        !           294:        /* use external pager; this may give security problems */
        !           295: 
        !           296:        register int fd = open(fnam, 0);
        !           297: 
        !           298:        if(fd < 0) {
        !           299:                if(!silent) pline("Cannot open %s.", fnam);
        !           300:                return(0);
        !           301:        }
        !           302:        if(child(1)){
        !           303:                extern char *catmore;
        !           304: 
        !           305:                /* Now that child() does a setuid(getuid()) and a chdir(),
        !           306:                   we may not be able to open file fnam anymore, so make
        !           307:                   it stdin. */
        !           308:                (void) close(0);
        !           309:                if(dup(fd)) {
        !           310:                        if(!silent) printf("Cannot open %s as stdin.\n", fnam);
        !           311:                } else {
        !           312:                        execl(catmore, "page", (char *) 0);
        !           313:                        if(!silent) printf("Cannot exec %s.\n", catmore);
        !           314:                }
        !           315:                exit(1);
        !           316:        }
        !           317:        (void) close(fd);
        !           318:       }
        !           319: #else DEF_PAGER
        !           320:       {
        !           321:        FILE *f;                        /* free after Robert Viduya */
        !           322: 
        !           323:        if ((f = fopen (fnam, "r")) == (FILE *) 0) {
        !           324:                if(!silent) {
        !           325:                        home(); perror (fnam); flags.toplin = 1;
        !           326:                        pline ("Cannot open %s.", fnam);
        !           327:                }
        !           328:                return(0);
        !           329:        }
        !           330:        page_more(f, 0);
        !           331:       }
        !           332: #endif DEF_PAGER
        !           333: 
        !           334:        return(1);
        !           335: }
        !           336: 
        !           337: #ifdef UNIX
        !           338: #ifdef SHELL
        !           339: dosh(){
        !           340: register char *str;
        !           341:        if(child(0)) {
        !           342:                if(str = getenv("SHELL"))
        !           343:                        execl(str, str, (char *) 0);
        !           344:                else
        !           345:                        execl("/bin/sh", "sh", (char *) 0);
        !           346:                pline("sh: cannot execute.");
        !           347:                exit(1);
        !           348:        }
        !           349:        return(0);
        !           350: }
        !           351: #endif SHELL
        !           352: 
        !           353: #ifdef NOWAITINCLUDE
        !           354: union wait {           /* used only for the cast  (union wait *) 0  */
        !           355:        int w_status;
        !           356:        struct {
        !           357:                unsigned short w_Termsig:7;
        !           358:                unsigned short w_Coredump:1;
        !           359:                unsigned short w_Retcode:8;
        !           360:        } w_T;
        !           361: };
        !           362: 
        !           363: #else
        !           364: 
        !           365: #ifdef BSD
        !           366: #include       <sys/wait.h>
        !           367: #else
        !           368: #include       <wait.h>
        !           369: #endif BSD
        !           370: #endif NOWAITINCLUDE
        !           371: 
        !           372: child(wt) {
        !           373: register int f = fork();
        !           374:        if(f == 0){             /* child */
        !           375:                settty((char *) 0);             /* also calls end_screen() */
        !           376:                (void) setuid(getuid());
        !           377:                (void) setgid(getgid());
        !           378: #ifdef CHDIR
        !           379:                (void) chdir(getenv("HOME"));
        !           380: #endif CHDIR
        !           381:                return(1);
        !           382:        }
        !           383:        if(f == -1) {   /* cannot fork */
        !           384:                pline("Fork failed. Try again.");
        !           385:                return(0);
        !           386:        }
        !           387:        /* fork succeeded; wait for child to exit */
        !           388:        (void) signal(SIGINT,SIG_IGN);
        !           389:        (void) signal(SIGQUIT,SIG_IGN);
        !           390:        (void) wait((union wait *) 0);
        !           391:        gettty();
        !           392:        setftty();
        !           393:        (void) signal(SIGINT,done1);
        !           394: #ifdef WIZARD
        !           395:        if(wizard) (void) signal(SIGQUIT,SIG_DFL);
        !           396: #endif WIZARD
        !           397:        if(wt) getret();
        !           398:        docrt();
        !           399:        return(0);
        !           400: }
        !           401: #endif UNIX

unix.superglobalmegacorp.com

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