Annotation of pgp/src/more.c, revision 1.1.1.2

1.1.1.2 ! root        1: /*     more.c  - Unix-style "more" paging output for PGP.
        !             2:        PGP: Pretty Good(tm) Privacy - public key cryptography for the masses.
        !             3: 
        !             4:        (c) Copyright 1990-1992 by Philip Zimmermann.  All rights reserved.
        !             5:        The author assumes no liability for damages resulting from the use
        !             6:        of this software, even if the damage results from defects in this
        !             7:        software.  No warranty is expressed or implied.
        !             8: 
        !             9:        All the source code Philip Zimmermann wrote for PGP is available for
        !            10:        free under the "Copyleft" General Public License from the Free
        !            11:        Software Foundation.  A copy of that license agreement is included in
        !            12:        the source release package of PGP.  Code developed by others for PGP
        !            13:        is also freely available.  Other code that has been incorporated into
        !            14:        PGP from other sources was either originally published in the public
        !            15:        domain or was used with permission from the various authors.  See the
        !            16:        PGP User's Guide for more complete information about licensing,
        !            17:        patent restrictions on certain algorithms, trademarks, copyrights,
        !            18:        and export controls.  
        !            19: */
        !            20: 
        !            21: #include <ctype.h>
        !            22: #include <stdio.h>
        !            23: #include <stdlib.h>
        !            24: #include <string.h>
        !            25: #ifdef UNIX
        !            26: #include <sys/types.h>
        !            27: #endif
        !            28: #ifdef sco
        !            29: #include <sys/stream.h>
        !            30: #include <sys/ptem.h>
        !            31: #endif
        !            32: #include "mpilib.h"
        !            33: #include "language.h"
        !            34: #include "fileio.h"
        !            35: #include "pgp.h"
        !            36: 
        !            37: /* Prototype for getch() */
        !            38: 
        !            39: int getch( void );
        !            40: 
        !            41: #ifdef MSDOS
        !            42: #define DEFAULT_LINES  25      /* MSDOS actually has a 25-line screen */
        !            43: #else
        !            44: #define DEFAULT_LINES  24
        !            45: #endif /* MSDOS */
        !            46: #define DEFAULT_COLUMNS        80
        !            47: 
        !            48: int screen_lines = DEFAULT_LINES, screen_columns = DEFAULT_COLUMNS;
        !            49: 
        !            50: #define TAB            0x09            /* ASCII tab char */
        !            51: #define CR             '\r'            /* Carriage return char */
        !            52: #define LF             '\n'            /* Linefeed */
        !            53: 
        !            54: /* Get the screen size for 'more'.  The environment variables $LINES and
        !            55:    $COLUMNS will be used if they exist.  If not, then the TIOCGWINSZ call to
        !            56:    ioctl() is used (if it is defined).  If not, then the TIOCGSIZE call to
        !            57:    ioctl() is used (if it is defined).  If not, then the WIOCGETD call to
        !            58:    ioctl() is used (if it is defined).  If not, then get the info from
        !            59:    terminfo/termcap (if it is there).  Otherwise, assume we have a 24x80
        !            60:    model 33.
        !            61: 
        !            62:    That was for Unix.
        !            63: 
        !            64:    For DOS, just assume 24x80. */
        !            65: 
        !            66: #ifdef UNIX
        !            67: /* Try to access terminfo through the termcap-interface in the curses library
        !            68:    (which requires linking with -lcurses) or use termcap directly (which
        !            69:    requires linking with -ltermcap) */
        !            70: 
        !            71: #ifndef USE_TERMCAP
        !            72: #ifdef USE_TERMINFO
        !            73: #define USE_TERMCAP
        !            74: #endif
        !            75: #ifdef USE_CURSES
        !            76: #define USE_TERMCAP
        !            77: #endif
        !            78: #endif
        !            79: 
        !            80: #ifdef USE_TERMCAP
        !            81: #define TERMBUFSIZ    1024
        !            82: #define UNKNOWN_TERM  "unknown"
        !            83: #define DUMB_TERMBUF  "dumb:co#80:hc:"
        !            84: 
        !            85:   extern int  tgetent(), tgetnum();
        !            86: #endif
        !            87: 
        !            88: /* Try to get TIOCGWINSZ from termios.h, then from sys/ioctl.h */
        !            89: #ifndef NOTERMIO
        !            90: #ifdef SVR2
        !            91: #include <termio.h>
        !            92: #else
        !            93: #include <termios.h>
        !            94: #endif /* SVR2 */
        !            95: #endif
        !            96: 
        !            97: #ifndef SVR2
        !            98: #ifndef TIOCGWINSZ
        !            99: #ifndef TIOCGSIZE
        !           100: #ifndef WIOCGETD
        !           101: #include <sys/ioctl.h>
        !           102: #endif /* not WIOCGETD */
        !           103: #endif /* not TIOCGSIZE */
        !           104: #endif /* not TIOCGWINSZ */
        !           105: 
        !           106: /* If we still dont have TIOCGWINSZ (or TIOCGSIZE) try for WIOCGETD */
        !           107: #ifndef TIOCGWINSZ
        !           108: #ifndef TIOCGSIZE
        !           109: #ifndef WIOCGETD
        !           110: #include <sgtty.h>
        !           111: #endif /* not WIOCGETD */
        !           112: #endif /* not TIOCGSIZE */
        !           113: #endif /* not TIOCGWINSZ */
        !           114: #endif /* not SVR2 */
        !           115: #endif /* UNIX */
        !           116: 
        !           117: static void getScreenSize(void)        /* Rot bilong kargo */
        !           118: /* Return the screen size */
        !           119: {
        !           120:        char *envLines, *envColumns;
        !           121:        long rowTemp = 0, colTemp = 0;
        !           122: #ifdef UNIX
        !           123: #ifdef USE_TERMCAP
        !           124:        char termBuffer[TERMBUFSIZ], *termInfo;
        !           125: #endif
        !           126: #ifdef TIOCGWINSZ
        !           127:        struct winsize windowInfo;
        !           128: #else
        !           129: #ifdef TIOCGSIZE
        !           130:        struct ttysize windowInfo;
        !           131: #else
        !           132: #ifdef WIOCGETD
        !           133:          struct uwdata windowInfo;
        !           134: #endif /* WIOCGETD */
        !           135: #endif /* TIOCGSIZE */
        !           136: #endif /* TIOCGWINSZ */
        !           137: 
        !           138:        /* Make sure that we're outputting to a terminal */
        !           139:        if (!isatty(fileno(stderr)))
        !           140:        {
        !           141:                screen_lines = DEFAULT_LINES;
        !           142:                screen_columns = DEFAULT_COLUMNS;
        !           143:                return;
        !           144:        }
        !           145:        screen_lines = screen_columns = 0;
        !           146: #endif /* UNIX */
        !           147: 
        !           148:        /* LINES & COLUMNS environment variables override everything else */
        !           149:        envLines = getenv("LINES");
        !           150:        if (envLines != NULL && (rowTemp = atol(envLines)) > 0 )
        !           151:                screen_lines = (int)rowTemp;
        !           152: 
        !           153:        envColumns = getenv("COLUMNS");
        !           154:        if (envColumns != NULL && (colTemp = atol(envColumns)) > 0 )
        !           155:                screen_columns = (int)colTemp;
        !           156: 
        !           157: #ifdef UNIX
        !           158: #ifdef TIOCGWINSZ
        !           159:        /* See what ioctl() has to say (overrides terminfo & termcap) */
        !           160:        if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),TIOCGWINSZ,&windowInfo) != -1)
        !           161:        {       if (!screen_lines && windowInfo.ws_row > 0)
        !           162:                        screen_lines = (int)windowInfo.ws_row;
        !           163: 
        !           164:                if (!screen_columns && windowInfo.ws_col > 0 )
        !           165:                        screen_columns = (int)windowInfo.ws_col;
        !           166:        }
        !           167: #else
        !           168: #ifdef TIOCGSIZE
        !           169:        /* See what ioctl() has to say (overrides terminfo & termcap) */
        !           170:        if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),TIOCGSIZE,&windowInfo) != -1)
        !           171:        {       if (!screen_lines && windowInfo.ts_lines > 0)
        !           172:                        screen_lines = (int)windowInfo.ts_lines;
        !           173: 
        !           174:                if (!screen_columns && windowInfo.ts_cols > 0)
        !           175:                        screen_columns = (int)windowInfo.ts_cols;
        !           176:        }
        !           177: #else
        !           178: #ifdef WIOCGETD
        !           179:        /* See what ioctl() has to say (overrides terminfo & termcap) */
        !           180:        if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),WIOCGETD,&windowInfo) != -1)
        !           181:        {       if (!screen_lines && windowInfo.uw_height > 0)
        !           182:                        screen_lines = (int)(windowInfo.uw_height / windowInfo.uw_vs);
        !           183: 
        !           184:                if (!screen_columns && windowInfo.uw_width > 0)
        !           185:                        screen_columns = (int)(windowInfo.uw_width / windowInfo.uw_hs);
        !           186:        }       /* You are in a twisty maze of standards, all different */
        !           187: #endif
        !           188: #endif
        !           189: #endif
        !           190: 
        !           191: #ifdef USE_TERMCAP
        !           192:        /* See what terminfo/termcap has to say */
        !           193:        if (!screen_lines || !screen_columns)
        !           194:        {       if ((termInfo = getenv("TERM")) == (char *)NULL)
        !           195:                        termInfo = UNKNOWN_TERM;
        !           196: 
        !           197:                if ((tgetent(termBuffer, termInfo) <= 0))
        !           198:                        strcpy(termBuffer,DUMB_TERMBUF);
        !           199: 
        !           200:                if (!screen_lines && (rowTemp = tgetnum("li")) > 0)
        !           201:                                screen_lines = (int)rowTemp;
        !           202: 
        !           203:                if (!screen_columns && (colTemp = tgetnum("co")) > 0)
        !           204:                                screen_columns = (int)colTemp;
        !           205:        }
        !           206: #endif
        !           207:        if (screen_lines == 0)                  /* nothing worked, use defaults */
        !           208:                screen_lines = DEFAULT_LINES;
        !           209:        if (screen_columns == 0)
        !           210:                screen_columns = DEFAULT_COLUMNS;
        !           211: #endif /* UNIX */
        !           212: }
        !           213: 
        !           214: /* Certain systems need to go into a "break" mode */
        !           215: #ifdef UNIX
        !           216: #define        NEEDBREAK
        !           217: #endif
        !           218: #ifdef AMIGA
        !           219: #define NEEDBREAK
        !           220: #endif
        !           221: #ifdef ATARI
        !           222: #define reverse_attr()         printf("\033p")
        !           223: #define norm_attr()                    printf("\033q")
        !           224: #else
        !           225: #define reverse_attr()
        !           226: #define norm_attr()
        !           227: #endif
        !           228: 
        !           229: 
        !           230: #ifdef VMS
        !           231: char pager[80] = "Type/Page";  /* default pager for VMS */
        !           232: #else  /* not VMS */
        !           233: char pager[80] = "";
        !           234: #endif /* not VMS */
        !           235: 
        !           236: 
        !           237: int more_file(char *fileName)
        !           238: /* Blort a file to the screen with page breaks, intelligent handling of line
        !           239:    terminators, truncation of overly long lines, and zapping of illegal
        !           240:    chars */
        !           241: {
        !           242:        FILE *inFile;
        !           243:        int lines = 0,ch,i,chars = 0, c;
        !           244:        long fileLen;
        !           245:        char cmd[MAX_PATH];
        !           246:        char buf[16];
        !           247:        int lineno;
        !           248:        char *p;
        !           249: 
        !           250:        if ((inFile = fopen(fileName,FOPRBIN)) == NULL)
        !           251:                /* Can't see how this could fail since we just created the file */
        !           252:                return(-1);
        !           253: 
        !           254:        fread(buf, 1, 16, inFile);
        !           255:        if (compressSignature(buf) >= 0)
        !           256:        {       fprintf(pgpout, PSTR("\n\007File '%s' is not a text file; cannot display.\n"),
        !           257:                                        fileName);
        !           258:                return(-1);
        !           259:        }
        !           260: 
        !           261:        /* PAGER set in config.txt overrides environment variable, 
        !           262:                set PAGER in config.txt to 'pgp' to use builtin pager */
        !           263:        if (pager[0] == '\0')
        !           264:        {
        !           265:                if ((p = getenv("PAGER")) != NULL)
        !           266:                        strncpy(pager, p, sizeof(pager) - 1);
        !           267:        }
        !           268:        /* Use built-in pager if PAGER is not set or if this is for your eyes only */
        !           269:        if ((strcmp(fileName,CONSOLE_FILENAME) != 0)
        !           270:                && (strlen(pager) != 0) && strcmp("pgp", pager))
        !           271:        {
        !           272:                fclose(inFile);
        !           273: #ifdef UNIX
        !           274:                if (strchr(fileName, '\'') != NULL)
        !           275:                        return(-1);
        !           276:                sprintf(cmd, "%s '%s'", pager, fileName);
        !           277: #else
        !           278:                sprintf(cmd, "%s %s", pager, fileName);
        !           279: #ifdef MSDOS
        !           280:                for (p = cmd; *p; ++p)
        !           281:                        if (*p == '/')
        !           282:                                *p = '\\';
        !           283: #endif
        !           284: #endif
        !           285:                return(system(cmd));
        !           286:        }
        !           287: 
        !           288: #ifdef UNIX
        !           289:        if (!isatty(fileno(stdout)))
        !           290:        {       fclose(inFile);
        !           291:                writePhantomOutput(fileName);
        !           292:                return 0;
        !           293:        }
        !           294: #endif /* UNIX */
        !           295: 
        !           296:        getScreenSize();
        !           297: 
        !           298:        /* Get file length */
        !           299:        fseek(inFile,0L,SEEK_END);
        !           300:        fileLen = ftell(inFile);
        !           301:        rewind(inFile);
        !           302:        lineno = 1;
        !           303: 
        !           304: #ifdef NEEDBREAK
        !           305:        ttycbreak();
        !           306: #endif
        !           307:        putchar('\n');
        !           308:        while (TRUE)
        !           309:        {   ch = getc(inFile);
        !           310:                if (ch == LF)
        !           311:                {   lines++;
        !           312:                        putchar('\n');
        !           313:                        chars = 0;
        !           314:                        ++lineno;
        !           315:                }
        !           316:                else
        !           317:                        if (ch == CR)
        !           318:                        {   lines++;
        !           319:                                putchar('\n');
        !           320:                                chars = 0;
        !           321:                                ++lineno;
        !           322: 
        !           323:                                /* Skip following LF if there is one */
        !           324:                                if ((ch = getc(inFile)) != LF && ch != EOF)
        !           325:                                        ungetc(ch,inFile);
        !           326:                        }
        !           327:                        else
        !           328:                                if (((unsigned char) ch >= ' ' && ch != EOF) || ch == TAB)
        !           329:                                {   /* Legal char or tab, print it */
        !           330:                                        putchar(ch);
        !           331:                                        chars += (ch == TAB) ? 8 : 1;
        !           332:                                }
        !           333: 
        !           334:                /* If we've reach the max.no of columns we can handle, skip the
        !           335:                   rest of the line */
        !           336:                if (chars == screen_columns - 1)
        !           337:                {       chars = 0;
        !           338:                        while ((ch = getc(inFile)) != CR && ch != LF && ch != EOF );
        !           339:                        if (ch != EOF)
        !           340:                                ungetc(ch,inFile);
        !           341:                }
        !           342: 
        !           343:                /* If we've reached the max.no of rows we can handle, wait for the
        !           344:                   user to hit a key */
        !           345:                while (ch == EOF || lines == screen_lines - 1)
        !           346:                {       /* Print prompt at end of screen */
        !           347:                        reverse_attr();
        !           348:                        if (ch == EOF)
        !           349:                                printf(PSTR("\nDone...hit any key\r"));
        !           350:                        else
        !           351:                                printf(PSTR("More -- %d%% -- Hit space for next screen, Enter for new line, 'Q' to quit --\r"),
        !           352:                                        ( 100 * ftell( inFile ) ) / fileLen );
        !           353:                        norm_attr();
        !           354:                        fflush(stdout);
        !           355:                        c = getch();
        !           356:                        c = to_upper(c);
        !           357: 
        !           358:                        /* Blank out prompt */
        !           359:                        for (i=0; i<79; i++)
        !           360:                                putchar(' ');
        !           361:                        putchar('\r');
        !           362:                        fflush(stdout);
        !           363:                        if (c == 'B' && lineno > screen_lines)          /* go Back a page */
        !           364:                        {       int seek_line = lineno - 2*screen_lines + 3;
        !           365:                                lineno = 1;
        !           366:                                rewind(inFile);
        !           367:                                if (seek_line > 1)
        !           368:                                {       printf("...skipping\n");
        !           369:                                        while ((ch = getc(inFile)) != EOF)
        !           370:                                                if (ch == '\n')
        !           371:                                                        if (++lineno == seek_line)
        !           372:                                                                break;
        !           373:                                }
        !           374:                                ch = '\0';
        !           375:                                lines = 0;
        !           376:                        }
        !           377:                        else
        !           378:                        {       if (c == 'Q' || ch == EOF)
        !           379:                                        goto done;
        !           380:                                if (c == ' ' || c == '\n' || c == '\r' || c == 'J')
        !           381:                                        lines -= (c == ' ') ? screen_lines - 2 : 1;     /* Do n more lines */
        !           382:                        }
        !           383:                }
        !           384:        }
        !           385: done:
        !           386: #ifdef NEEDBREAK
        !           387:        ttynorm();
        !           388: #endif
        !           389:        fclose(inFile);
        !           390:        return(0);
        !           391: } /* more_file */
        !           392: 
        !           393: 
        !           394: /*
        !           395:  * open_more() and close_more() redirect pgpout to the pager.
        !           396:  *
        !           397:  */
        !           398: 
        !           399: static char *mfile = NULL;
        !           400: static boolean piping = FALSE;
        !           401: static FILE *savepgpout;
        !           402: 
        !           403: 
        !           404: int
        !           405: open_more()
        !           406: {
        !           407:        char *p;
        !           408: 
        !           409:        if (mfile || piping)
        !           410:                close_more();
        !           411: 
        !           412:        savepgpout = pgpout;
        !           413: #ifdef UNIX
        !           414:        if (pager[0] == '\0')
        !           415:        {
        !           416:                if ((p = getenv("PAGER")) != NULL)
        !           417:                        strncpy(pager, p, sizeof(pager) - 1);
        !           418:        }
        !           419:        /* Use built-in pager if PAGER is not set or set to "pgp" */
        !           420:        if ((strlen(pager) != 0) && strcmp("pgp", pager))
        !           421:        {
        !           422:                if ((pgpout = popen(pager, "w")) != NULL)
        !           423:                {       piping = TRUE;
        !           424:                        return 0;
        !           425:                }
        !           426:                perror("popen");
        !           427:                pgpout = savepgpout;
        !           428:        }
        !           429: #endif
        !           430:        if ((mfile = tempfile(TMP_TMPDIR|TMP_WIPE)) == NULL)
        !           431:                return -1;
        !           432:        if ((pgpout = fopen(mfile, FOPWTXT)) == NULL)
        !           433:        {
        !           434:                pgpout = savepgpout;
        !           435:                rmtemp(mfile);
        !           436:                return -1;
        !           437:        }
        !           438:        /* user will not see anything until close_more() is called */
        !           439:        fprintf(savepgpout,PSTR("Just a moment..."));
        !           440:        fflush(savepgpout);
        !           441:        return 0;
        !           442: }
        !           443: 
        !           444: int
        !           445: close_more()
        !           446: {
        !           447:        if (!mfile && !piping)
        !           448:                return 0;
        !           449: 
        !           450: #ifdef UNIX
        !           451:        if (piping)
        !           452:                pclose(pgpout);
        !           453:        else
        !           454: #endif
        !           455:                fclose(pgpout);
        !           456:        pgpout = savepgpout;
        !           457:        if (mfile)
        !           458:        {
        !           459:                fprintf(pgpout,"\n");
        !           460:                more_file(mfile);
        !           461:                rmtemp(mfile);
        !           462:                mfile = NULL;
        !           463:        }
        !           464:        piping = FALSE;
        !           465:        return 0;
        !           466: }

unix.superglobalmegacorp.com

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