--- pgp/src/more.c 2018/04/24 16:40:45 1.1.1.5 +++ pgp/src/more.c 2018/04/24 16:45:13 1.1.1.8 @@ -1,23 +1,23 @@ -/* more.c - Unix-style "more" paging output for PGP. - PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. +/* more.c - Unix-style "more" paging output for PGP. + PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. - (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. - The author assumes no liability for damages resulting from the use - of this software, even if the damage results from defects in this - software. No warranty is expressed or implied. - - Note that while most PGP source modules bear Philip Zimmermann's - copyright notice, many of them have been revised or entirely written - by contributors who frequently failed to put their names in their - code. Code that has been incorporated into PGP from other authors - was either originally published in the public domain or is used with - permission from the various authors. - - PGP is available for free to the public under certain restrictions. - See the PGP User's Guide (included in the release package) for - important information about licensing, patent restrictions on - certain algorithms, trademarks, copyrights, and export controls. -*/ + (c) Copyright 1990-1996 by Philip Zimmermann. All rights reserved. + The author assumes no liability for damages resulting from the use + of this software, even if the damage results from defects in this + software. No warranty is expressed or implied. + + Note that while most PGP source modules bear Philip Zimmermann's + copyright notice, many of them have been revised or entirely written + by contributors who frequently failed to put their names in their + code. Code that has been incorporated into PGP from other authors + was either originally published in the public domain or is used with + permission from the various authors. + + PGP is available for free to the public under certain restrictions. + See the PGP User's Guide (included in the release package) for + important information about licensing, patent restrictions on + certain algorithms, trademarks, copyrights, and export controls. + */ #include #include @@ -39,21 +39,30 @@ FILE *popen(); #include "more.h" #include "charset.h" -#ifdef MSDOS +#ifdef MACTC5 +#include "Macutil3.h" +#include "MacPGP.h" +#define DEFAULT_LINES 23 +#define DEFAULT_COLUMNS 77 +#else +#if defined(MSDOS) || defined(WIN32) #ifndef __GO32__ #include #endif #define DEFAULT_LINES 25 /* MSDOS actually has a 25-line screen */ #else #define DEFAULT_LINES 24 -#endif /* MSDOS */ +#endif /* MSDOS */ #define DEFAULT_COLUMNS 80 +#endif /* MACTC5 */ static int screen_lines = DEFAULT_LINES, screen_columns = DEFAULT_COLUMNS; -#define TAB 0x09 /* ASCII tab char */ -#define CR '\r' /* Carriage return char */ -#define LF '\n' /* Linefeed */ +#ifndef EBCDIC /* already defined in usuals.h */ +#define TAB 0x09 /* ASCII tab char */ +#define CR '\r' /* Carriage return char */ +#define LF '\n' /* Linefeed */ +#endif /* Get the screen size for 'more'. The environment variables $LINES and $COLUMNS will be used if they exist. If not, then the TIOCGWINSZ call to @@ -86,7 +95,7 @@ static int screen_lines = DEFAULT_LINES, #define UNKNOWN_TERM "unknown" #define DUMB_TERMBUF "dumb:co#80:hc:" - extern int tgetent(), tgetnum(); +extern int tgetent(), tgetnum(); #endif /* Try to get TIOCGWINSZ from termios.h, then from sys/ioctl.h */ @@ -95,127 +104,135 @@ static int screen_lines = DEFAULT_LINES, #include #else #include -#endif /* SVR2 */ +#endif /* SVR2 */ #endif +#ifdef __FreeBSD__ +#include /* for ioctl() prototype too */ +#else #ifndef SVR2 #ifndef TIOCGWINSZ #ifndef TIOCGSIZE #ifndef WIOCGETD #include -#endif /* not WIOCGETD */ -#endif /* not TIOCGSIZE */ -#endif /* not TIOCGWINSZ */ +#endif /* not WIOCGETD */ +#endif /* not TIOCGSIZE */ +#endif /* not TIOCGWINSZ */ +#endif /* If we still dont have TIOCGWINSZ (or TIOCGSIZE) try for WIOCGETD */ #ifndef TIOCGWINSZ #ifndef TIOCGSIZE #ifndef WIOCGETD #include -#endif /* not WIOCGETD */ -#endif /* not TIOCGSIZE */ -#endif /* not TIOCGWINSZ */ -#endif /* not SVR2 */ -#endif /* UNIX */ +#endif /* not WIOCGETD */ +#endif /* not TIOCGSIZE */ +#endif /* not TIOCGWINSZ */ +#endif /* not SVR2 */ +#endif /* UNIX */ +#ifdef __PUREC__ +#include +#endif -static void getScreenSize(void) /* Rot bilong kargo */ -/* Return the screen size */ -{ - char *envLines, *envColumns; - long rowTemp = 0, colTemp = 0; +static void getScreenSize(void) +{ /* Rot bilong kargo */ + /* Return the screen size */ + char *envLines, *envColumns; + long rowTemp = 0, colTemp = 0; #ifdef UNIX #ifdef USE_TERMCAP - char termBuffer[TERMBUFSIZ], *termInfo; + char termBuffer[TERMBUFSIZ], *termInfo; #endif #ifdef TIOCGWINSZ - struct winsize windowInfo; + struct winsize windowInfo; #else #ifdef TIOCGSIZE - struct ttysize windowInfo; + struct ttysize windowInfo; #else #ifdef WIOCGETD - struct uwdata windowInfo; -#endif /* WIOCGETD */ -#endif /* TIOCGSIZE */ -#endif /* TIOCGWINSZ */ - - /* Make sure that we're outputting to a terminal */ - if (!isatty(fileno(stderr))) { - screen_lines = DEFAULT_LINES; - screen_columns = DEFAULT_COLUMNS; - return; - } - screen_lines = screen_columns = 0; -#endif /* UNIX */ - - /* LINES & COLUMNS environment variables override everything else */ - envLines = getenv("LINES"); - if (envLines != NULL && (rowTemp = atol(envLines)) > 0 ) - screen_lines = (int)rowTemp; - - envColumns = getenv("COLUMNS"); - if (envColumns != NULL && (colTemp = atol(envColumns)) > 0 ) - screen_columns = (int)colTemp; + struct uwdata windowInfo; +#endif /* WIOCGETD */ +#endif /* TIOCGSIZE */ +#endif /* TIOCGWINSZ */ + + /* Make sure that we're outputting to a terminal */ + if (!isatty(fileno(stderr))) { + screen_lines = DEFAULT_LINES; + screen_columns = DEFAULT_COLUMNS; + return; + } + screen_lines = screen_columns = 0; +#endif /* UNIX */ + + /* LINES & COLUMNS environment variables override everything else */ + envLines = getenv("LINES"); + if (envLines != NULL && (rowTemp = atol(envLines)) > 0) + screen_lines = (int) rowTemp; + + envColumns = getenv("COLUMNS"); + if (envColumns != NULL && (colTemp = atol(envColumns)) > 0) + screen_columns = (int) colTemp; #ifdef UNIX #ifdef TIOCGWINSZ - /* See what ioctl() has to say (overrides terminfo & termcap) */ - if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),TIOCGWINSZ,&windowInfo) != -1) - { - if (!screen_lines && windowInfo.ws_row > 0) - screen_lines = (int)windowInfo.ws_row; - - if (!screen_columns && windowInfo.ws_col > 0 ) - screen_columns = (int)windowInfo.ws_col; - } + /* See what ioctl() has to say (overrides terminfo & termcap) */ + if ((!screen_lines || !screen_columns) && + ioctl(fileno(stderr), TIOCGWINSZ, &windowInfo) + != -1) { + if (!screen_lines && windowInfo.ws_row > 0) + screen_lines = (int) windowInfo.ws_row; + + if (!screen_columns && windowInfo.ws_col > 0) + screen_columns = (int) windowInfo.ws_col; + } #else #ifdef TIOCGSIZE - /* See what ioctl() has to say (overrides terminfo & termcap) */ - if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),TIOCGSIZE,&windowInfo) != -1) - { - if (!screen_lines && windowInfo.ts_lines > 0) - screen_lines = (int)windowInfo.ts_lines; - - if (!screen_columns && windowInfo.ts_cols > 0) - screen_columns = (int)windowInfo.ts_cols; - } + /* See what ioctl() has to say (overrides terminfo & termcap) */ + if ((!screen_lines || !screen_columns) && + ioctl(fileno(stderr), TIOCGSIZE, &windowInfo) != -1) { + if (!screen_lines && windowInfo.ts_lines > 0) + screen_lines = (int) windowInfo.ts_lines; + + if (!screen_columns && windowInfo.ts_cols > 0) + screen_columns = (int) windowInfo.ts_cols; + } #else #ifdef WIOCGETD - /* See what ioctl() has to say (overrides terminfo & termcap) */ - if ((!screen_lines || !screen_columns) && ioctl(fileno(stderr),WIOCGETD,&windowInfo) != -1) - { - if (!screen_lines && windowInfo.uw_height > 0) - screen_lines = (int)(windowInfo.uw_height / windowInfo.uw_vs); - - if (!screen_columns && windowInfo.uw_width > 0) - screen_columns = (int)(windowInfo.uw_width / windowInfo.uw_hs); - } /* You are in a twisty maze of standards, all different */ + /* See what ioctl() has to say (overrides terminfo & termcap) */ + if ((!screen_lines || !screen_columns) && + ioctl(fileno(stderr), WIOCGETD, &windowInfo) != -1) { + if (!screen_lines && windowInfo.uw_height > 0) + screen_lines = (int) (windowInfo.uw_height / windowInfo.uw_vs); + + if (!screen_columns && windowInfo.uw_width > 0) + screen_columns = (int) (windowInfo.uw_width / windowInfo.uw_hs); + } /* You are in a twisty maze of standards, + all different */ #endif #endif #endif #ifdef USE_TERMCAP - /* See what terminfo/termcap has to say */ - if (!screen_lines || !screen_columns) - { - if ((termInfo = getenv("TERM")) == (char *)NULL) - termInfo = UNKNOWN_TERM; - - if ((tgetent(termBuffer, termInfo) <= 0)) - strcpy(termBuffer,DUMB_TERMBUF); - - if (!screen_lines && (rowTemp = tgetnum("li")) > 0) - screen_lines = (int)rowTemp; - - if (!screen_columns && (colTemp = tgetnum("co")) > 0) - screen_columns = (int)colTemp; - } -#endif - if (screen_lines == 0) /* nothing worked, use defaults */ - screen_lines = DEFAULT_LINES; - if (screen_columns == 0) - screen_columns = DEFAULT_COLUMNS; -#endif /* UNIX */ + /* See what terminfo/termcap has to say */ + if (!screen_lines || !screen_columns) { + if ((termInfo = getenv("TERM")) == (char *) NULL) + termInfo = UNKNOWN_TERM; + + if ((tgetent(termBuffer, termInfo) <= 0)) + strcpy(termBuffer, DUMB_TERMBUF); + + if (!screen_lines && (rowTemp = tgetnum("li")) > 0) + screen_lines = (int) rowTemp; + + if (!screen_columns && (colTemp = tgetnum("co")) > 0) + screen_columns = (int) colTemp; + } +#endif + if (screen_lines == 0) /* nothing worked, use defaults */ + screen_lines = DEFAULT_LINES; + if (screen_columns == 0) + screen_columns = DEFAULT_COLUMNS; +#endif /* UNIX */ } #ifdef ATARI @@ -229,171 +246,176 @@ static void getScreenSize(void) /* Rot b #ifdef VMS char pager[80] = "Type/Page"; /* default pager for VMS */ -#else /* not VMS */ +#else /* not VMS */ char pager[80] = ""; -#endif /* not VMS */ - +#endif /* not VMS */ -int more_file(char *fileName) /* Blort a file to the screen with page breaks, intelligent handling of line terminators, truncation of overly long lines, and zapping of illegal chars */ +int more_file(char *fileName, boolean eyes_only) { - FILE *inFile; - int lines = 0,ch,i,chars = 0, c; - long fileLen; - char cmd[MAX_PATH]; - char buf[16]; - int lineno; - char *p; - - if ((inFile = fopen(fileName,FOPRBIN)) == NULL) - /* Can't see how this could fail since we just created the file */ - return -1; - - fread(buf, 1, 16, inFile); - if (compressSignature( (byte *) buf) >= 0) - { - fprintf(pgpout, LANG("\n\007File '%s' is not a text file; cannot display.\n"), - fileName); - return -1; - } - - /* PAGER set in config.txt overrides environment variable, - set PAGER in config.txt to 'pgp' to use builtin pager */ - if (pager[0] == '\0') { - if ((p = getenv("PAGER")) != NULL) - strncpy(pager, p, sizeof(pager) - 1); - } - if (strcmp(pager, "cat") == 0) { - fclose(inFile); - writePhantomOutput(fileName); - return 0; - } - - /* Use built-in pager if PAGER is not set or if this is for your eyes only, - this currently doesn't work, the _CONSOLE filename isn't used as the real - filename anymore */ - if ((strcmp(fileName,CONSOLE_FILENAME) != 0) - && (strlen(pager) != 0) && strcmp("pgp", pager)) - { - fclose(inFile); + FILE *inFile; + int lines = 0, ch, i, chars = 0, c; + long fileLen; + char cmd[MAX_PATH]; + char buf[16]; + int lineno; + char *p; + + if ((inFile = fopen(fileName, FOPRBIN)) == NULL) + /* Can't see how this could fail since we just created the file */ + return -1; + + fread(buf, 1, 16, inFile); + if (compressSignature((byte *) buf) >= 0) { + fprintf(pgpout, + LANG("\n\007File '%s' is not a text file; cannot display.\n"), + fileName); + return -1; + } + /* PAGER set in config.txt overrides environment variable, + set PAGER in config.txt to 'pgp' to use builtin pager */ + if (pager[0] == '\0') { + if ((p = getenv("PAGER")) != NULL) + strncpy(pager, p, sizeof(pager) - 1); + } + if (strcmp(pager, "cat") == 0) { + fclose(inFile); + writePhantomOutput(fileName); + return 0; + } + /* Use built-in pager if PAGER is not set or if the message + is for your eyes only */ + if (!eyes_only && (strlen(pager) != 0) && strcmp("pgp", pager)) { + fclose(inFile); #ifdef UNIX - if (strchr(fileName, '\'') != NULL) - return -1; - sprintf(cmd, "%s '%s'", pager, fileName); -#else - sprintf(cmd, "%s %s", pager, fileName); -#ifdef MSDOS - for (p = cmd; *p; ++p) - if (*p == '/') - *p = '\\'; + if (strchr(fileName, '\'') != NULL) + return -1; + sprintf(cmd, "%s '%s'", pager, fileName); +#else + sprintf(cmd, "%s %s", pager, fileName); +#if defined(MSDOS) || defined(WIN32) + for (p = cmd; *p; ++p) + if (*p == '/') + *p = '\\'; #endif #endif - fflush(pgpout); - return system(cmd); - } - + fflush(pgpout); +#ifdef MACTC5 + return 0; +#else + return system(cmd); +#endif + } #ifdef UNIX - if (!isatty(fileno(stdout))) { - fclose(inFile); - writePhantomOutput(fileName); - return 0; - } -#endif /* UNIX */ - - getScreenSize(); - - /* Get file length */ - fseek(inFile,0L,SEEK_END); - fileLen = ftell(inFile); - rewind(inFile); - lineno = 1; - - ttycbreak(); - - putchar('\n'); - for (;;) { - ch = getc(inFile); - if (ch == LF) { - lines++; - putchar('\n'); - chars = 0; - ++lineno; - } else if (ch == CR) { - lines++; - putchar('\n'); - chars = 0; - ++lineno; - - /* Skip following LF if there is one */ - if ((ch = getc(inFile)) != LF && ch != EOF) - ungetc(ch,inFile); - } else if (((unsigned char) ch >= ' ' && ch != EOF) || ch == TAB) - { - /* Legal char or tab, print it */ - putchar(ch); - chars += (ch == TAB) ? 8 : 1; - } + if (!isatty(fileno(stdout))) { + fclose(inFile); + writePhantomOutput(fileName); + return 0; + } +#endif /* UNIX */ - /* If we've reach the max.no of columns we can handle, skip the - rest of the line */ - if (chars == screen_columns - 1) { - chars = 0; - while ((ch = getc(inFile)) != CR && ch != LF && ch != EOF ) - ; - if (ch != EOF) - ungetc(ch,inFile); - } + getScreenSize(); - /* If we've reached the max.no of rows we can handle, wait for the - user to hit a key */ - while (ch == EOF || lines == screen_lines - 1) { - /* Print prompt at end of screen */ - reverse_attr(); - if (ch == EOF) - printf(LANG("\nDone...hit any key\r")); - else - printf(LANG("More -- %d%% -- Hit space for next screen, Enter for new line, 'Q' to quit --\r"), - ( 100 * ftell( inFile ) ) / fileLen ); - norm_attr(); - fflush(stdout); - c = getch(); - c = to_upper(c); - - /* Blank out prompt */ - for (i=0; i<79; i++) - putchar(' '); - putchar('\r'); - fflush(stdout); - if (c == 'B' && lineno > screen_lines) { - /* go Back a page */ - int seek_line = lineno - 2*screen_lines + 3; - lineno = 1; - rewind(inFile); - if (seek_line > 1) { - printf("...skipping\n"); - while ((ch = getc(inFile)) != EOF) - if (ch == '\n') - if (++lineno == seek_line) - break; - } - ch = '\0'; - lines = 0; - } else { - if (c == 'Q' || ch == EOF) - goto done; - if (c == ' ' || c == '\n' || c == '\r' || c == 'J') - lines -= (c == ' ') ? screen_lines - 2 : 1; /* Do n more lines */ - } + /* Get file length */ + fseek(inFile, 0L, SEEK_END); + fileLen = ftell(inFile); + rewind(inFile); + lineno = 1; + + ttycbreak(); + + putchar('\n'); + for (;;) { + ch = getc(inFile); + if (ch == LF) { + lines++; + putchar('\n'); + chars = 0; + ++lineno; + } else if (ch == CR) { + lines++; + putchar('\n'); + chars = 0; + ++lineno; + + /* Skip following LF if there is one */ + if ((ch = getc(inFile)) != LF && ch != EOF) + ungetc(ch, inFile); + } else if (((unsigned char) ch >= ' ' && ch != EOF) || ch == TAB) { + /* Legal char or tab, print it */ + putchar(ch); + chars += (ch == TAB) ? 8 : 1; + } + /* If we've reach the max.no of columns we can handle, skip the + rest of the line */ + if (chars == screen_columns - 1) { + chars = 0; + while ((ch = getc(inFile)) != CR && ch != LF && ch != EOF); + if (ch != EOF) + ungetc(ch, inFile); + } + /* If we've reached the max.no of rows we can handle, wait for the + user to hit a key */ + while (ch == EOF || lines == screen_lines - 1) { + /* Print prompt at end of screen */ + reverse_attr(); + if (ch == EOF) + printf(LANG("\nDone...hit any key\r")); + else +#ifdef MACTC5 /* 203a : ftell() tells us nothing useful */ + printf(LANG("-- More -- Space: next screen, Enter: next line\ +, 'B': back, 'Q': quit --\r")); +#else + printf( +LANG("More -- %d%% -- Space: next screen, Enter: next line\ +, 'B': back, 'Q': quit --\r"), + (100 * ftell(inFile)) / fileLen); +#endif /* MACTC5 */ + norm_attr(); + fflush(stdout); + c = getch(); + c = toupper(c); + + /* Blank out prompt */ + for (i = 0; i < 79; i++) + putchar(' '); + putchar('\r'); + fflush(stdout); + if (c == 'B' && lineno > screen_lines) { + /* go Back a page */ + int seek_line = lineno - 2 * screen_lines + 3; + lineno = 1; + rewind(inFile); + if (seek_line > 1) { + printf("...skipping\n"); + while ((ch = getc(inFile)) != EOF) + if (ch == '\n') + if (++lineno == seek_line) + break; } - } -done: - ttynorm(); - - fclose(inFile); - return 0; -} /* more_file */ + ch = '\0'; + lines = 0; + } else { +#if defined(MSDOS) || defined(__MSDOS__) + if (c == 'Q' || c == 0x1B || ch == EOF) +#else + if (c == 'Q' || ch == EOF) +#endif + goto done; + if (c == ' ' || c == '\n' || c == '\r' || c == 'J') + lines -= (c == ' ') ? screen_lines - 2 : 1; /* Do n more + lines */ + } + } + } + done: + ttynorm(); + + fclose(inFile); + return 0; +} /* more_file */ /* @@ -406,66 +428,63 @@ static boolean piping = FALSE; static FILE *savepgpout; -int -open_more(void) +int open_more(void) { #ifdef UNIX - char *p; + char *p; #endif - if (mfile || piping) - close_more(); + if (mfile || piping) + close_more(); - savepgpout = pgpout; + savepgpout = pgpout; #ifdef UNIX - fflush(pgpout); - if (pager[0] == '\0') { - if ((p = getenv("PAGER")) != NULL) - strncpy(pager, p, sizeof(pager) - 1); - } - /* Use built-in pager if PAGER is not set or set to "pgp" */ - if ((strlen(pager) != 0) && strcmp("pgp", pager)) { - if ((pgpout = popen(pager, "w")) != NULL) { - piping = TRUE; - return 0; - } - perror("popen"); - pgpout = savepgpout; + fflush(pgpout); + if (pager[0] == '\0') { + if ((p = getenv("PAGER")) != NULL) + strncpy(pager, p, sizeof(pager) - 1); + } + /* Use built-in pager if PAGER is not set or set to "pgp" */ + if ((strlen(pager) != 0) && strcmp("pgp", pager)) { + if ((pgpout = popen(pager, "w")) != NULL) { + piping = TRUE; + return 0; } + perror("popen"); + pgpout = savepgpout; + } #endif - if ((mfile = tempfile(TMP_TMPDIR|TMP_WIPE)) == NULL) - return -1; - if ((pgpout = fopen(mfile, FOPWTXT)) == NULL) { - pgpout = savepgpout; - rmtemp(mfile); - return -1; - } - /* user will not see anything until close_more() is called */ - fprintf(savepgpout,LANG("Just a moment...")); - fflush(savepgpout); - return 0; + if ((mfile = tempfile(TMP_TMPDIR | TMP_WIPE)) == NULL) + return -1; + if ((pgpout = fopen(mfile, FOPWTXT)) == NULL) { + pgpout = savepgpout; + rmtemp(mfile); + return -1; + } + /* user will not see anything until close_more() is called */ + fprintf(savepgpout, LANG("Just a moment...")); + fflush(savepgpout); + return 0; } -int -close_more(void) +int close_more(void) { - if (!mfile && !piping) - return 0; + if (!mfile && !piping) + return 0; #ifdef UNIX - if (piping) - pclose(pgpout); - else -#endif - fclose(pgpout); - pgpout = savepgpout; - if (mfile) - { - fprintf(pgpout,"\n"); - more_file(mfile); - rmtemp(mfile); - mfile = NULL; - } - piping = FALSE; - return 0; + if (piping) + pclose(pgpout); + else +#endif + fclose(pgpout); + pgpout = savepgpout; + if (mfile) { + fprintf(pgpout, "\n"); + more_file(mfile, FALSE); + rmtemp(mfile); + mfile = NULL; + } + piping = FALSE; + return 0; }