built-in pager for readnews
borman at stolaf.UUCP
borman at stolaf.UUCP
Tue Jun 28 11:59:46 AEST 1983
I've had many requests for the mods to build a pager into readnews,
so here it is. (Note that in pager.c there are ifdefs for MOD_NTTY.
These are for our local ttydriver, which has an ioctl for resetting
^O. This allows people to ^O an article, and wonder of wonders, it gets
reset just in time to print the next header... very handy. If you
have such an ioctl on your system, just change the ioctl's as needed
and define MOD_NTTY.(there are many other places that this can be
put in, if you'd like a list of all the places, drop me a line))
These are the diffs to implement the built-in pager into readnews.
The files modified are digest.c, readr.c and rfuncs.c. You also
have to change PAGE, the default pager listed in defs.h, to "My Own".
(If you don't like that, pick something unique and change all the
appropriate references to it) Besides implementing the pager, this
also makes the 'w' and 's' different, in that 's' puts on the header
when saving the article, and 'w' doesn't.
The main thrust of writing this pager has been to keep anything from
scrolling off the screen before you get a chance to read it. It does
an awfully good job at it. It knows if a new newsgroup is following,
and allows for the longer header. It looks at line lengths for long
lines that would cause the line count to be incorrect.
The biggest kludge about this is how it is implemented with the 'D'
option for decrypting things.
Things to note:
The pager gives you the options of using +'s and -'s to look
at various pages of the article, BUT... you can only skip around
on pages that you have already seen. (e.g, you can's skip the
first 5 pages by giving the command +++++, but if you've read the
first 5 pages, you can use ---- to skip back 4 pages, and then
+++ to skip forward 3 pages, etc.) This could probably be changed,
but it would involve looking at the whole article before presenting
it, which it doesn't do right now.
You can probably disable the ':' "feature" if you implement this pager.
It should be fairly easy to install, just make the following changes and
add pager.o to the ROBJECTS line in the makefile. If you have any questions,
comments or improvements, I'd be glad to see them.
-Dave Borman, St. Olaf College
{ihnp4, harpo}!stolaf!borman
*** ../vanilla/src/digest.c Wed May 25 12:58:25 1983
--- digest.c Fri Jun 3 16:38:37 1983
***************
*** 324,329
FILE *pfp, *popen();
if (art && arts[art].a_blen > 23-arts[art+1].a_hlen && *PAGER) {
if (!index(PAGER, FMETA)) {
if ((pfp = popen(PAGER, "w"))==NULL)
(void) dprinta(art, ifp, ofp);
--- 327,338 -----
FILE *pfp, *popen();
if (art && arts[art].a_blen > 23-arts[art+1].a_hlen && *PAGER) {
+ #ifdef MOD_PAGE
+ if (strncmp(PAGER, "My Own") == 0) {
+ fseek(ifp, arts[art].a_bod, 0);
+ pprint(ifp, ofp, NULL, arts[art+1].a_hdr, art);
+ } else
+ #endif MOD_PAGE
if (!index(PAGER, FMETA)) {
if ((pfp = popen(PAGER, "w"))==NULL)
(void) dprinta(art, ifp, ofp);
--- readr.c Mon Jun 27 19:30:22 1983
***************
*** 204,209
if (!bptr[-1] && rfq)
return;
readmode = NEXT;
showtail(fp);
clear(bit);
saveart;
--- 210,219 -----
if (!bptr[-1] && rfq)
return;
readmode = NEXT;
+ #ifdef MOD_PAGE
+ if (showtail(fp))
+ return;
+ #else
showtail(fp);
#endif MOD_PAGE
clear(bit);
***************
*** 205,210
return;
readmode = NEXT;
showtail(fp);
clear(bit);
saveart;
nextbit();
--- 215,221 -----
return;
#else
showtail(fp);
+ #endif MOD_PAGE
clear(bit);
saveart;
nextbit();
***************
*** 273,278
case 'w':
{
char *grn = groupdir;
tfilename = filename;
if (*bptr == '-') {
bptr++;
--- 293,301 -----
case 'w':
{
char *grn = groupdir;
+ #ifdef MOD_PAGE
+ i = bptr[-1] == 's';
+ #endif MOD_PAGE
tfilename = filename;
if (*bptr == '-') {
bptr++;
***************
*** 306,311
else
strcat(bptr, "Articles");
}
fwait(fsubr(save, tfilename, bptr));
}
break;
--- 329,337 -----
else
strcat(bptr, "Articles");
}
+ #ifdef MOD_PAGE
+ rsave(tfilename, bptr, i);
+ #else
fwait(fsubr(save, tfilename, bptr));
#endif MOD_PAGE
}
***************
*** 307,312
strcat(bptr, "Articles");
}
fwait(fsubr(save, tfilename, bptr));
}
break;
--- 333,339 -----
rsave(tfilename, bptr, i);
#else
fwait(fsubr(save, tfilename, bptr));
+ #endif MOD_PAGE
}
break;
***************
*** 895,900
char temp[100];
char *pp = bptr;
FILE *pfp, *popen();
fprintf(stderr, "Caesar decoding:\n");
strcpy(temp, CAESAR);
--- 956,966 -----
char temp[100];
char *pp = bptr;
FILE *pfp, *popen();
+ #ifdef MOD_PAGE
+ FILE *pifp, *fdopen();
+ register int ttt;
+ int p[2];
+ #endif MOD_PAGE
fprintf(stderr, "Caesar decoding:\n");
strcpy(temp, CAESAR);
***************
*** 902,907
strcat(temp, " ");
strcat(temp, bptr);
}
if (NLINES(h, fp) > LNCNT && *PAGER) {
strcat(temp, " | ");
strcat(temp, PAGER);
--- 968,1008 -----
strcat(temp, " ");
strcat(temp, bptr);
}
+ #ifdef MOD_PAGE
+ if (NLINES(h, fp) > (((rflag && bit < 1) || (bit > ngsize))? 12 : 17)
+ && *PAGER) {
+ if (strcmp(PAGER, "My Own") == 0) {
+ pipe(p);
+ ttt = dup(1);
+ dup2(p[1], 1);
+ close(p[1]);
+ pifp = fdopen(p[0], "r");
+ pfp = popen(temp, "w");
+ dup2(ttt, 1);
+ close(ttt);
+ /* fsubr only takes function with 2 args, */
+ /* so and we need 3... */
+ while ((ttt = fork()) == -1)
+ sleep(1);
+ if (ttt == 0) {
+ tprint(fp, pfp, FALSE);
+ exit(0);
+ }
+ pclose(pfp);
+ pprint(pifp, ofp, &h, 0L, 0);
+ fclose(pifp);
+ fwait(ttt);
+ } else {
+ strcat(temp, " | ");
+ strcat(temp, PAGER);
+ pfp = popen(temp, "w");
+ tprint(fp, pfp, FALSE);
+ }
+ } else {
+ pfp = popen(temp, "w");
+ tprint(fp, pfp, FALSE);
+ }
+ #else MOD_PAGE
if (NLINES(h, fp) > LNCNT && *PAGER) {
strcat(temp, " | ");
strcat(temp, PAGER);
***************
*** 908,913
}
pfp = popen(temp, "w");
tprint(fp, pfp, FALSE);
itsbeenseen(h.ident);
fclose(fp);
fp = NULL;
--- 1009,1015 -----
}
pfp = popen(temp, "w");
tprint(fp, pfp, FALSE);
+ #endif MOD_PAGE
itsbeenseen(h.ident);
fclose(fp);
fp = NULL;
***************
*** 923,928
FILE *fd;
{
if (fd == NULL)
return;
if (dgest) {
--- 1025,1033 -----
FILE *fd;
{
if (fd == NULL)
+ #ifdef MOD_PAGE
+ return(0);
+ #else
return;
#endif MOD_PAGE
***************
*** 924,929
{
if (fd == NULL)
return;
if (dgest) {
digest(fd, ofp, &h);
--- 1029,1035 -----
return(0);
#else
return;
+ #endif MOD_PAGE
if (dgest) {
digest(fd, ofp, &h);
***************
*** 930,935
} else if (!lflag && !pflag && !eflag) {
#ifdef PAGE
/* Filter the tail of long messages through PAGER. */
if (NLINES(h, fd) > LNCNT && *PAGER) {
if (!index(PAGER, FMETA)) {
FILE *pfp, *popen();
--- 1036,1042 -----
} else if (!lflag && !pflag && !eflag) {
#ifdef PAGE
/* Filter the tail of long messages through PAGER. */
+ #ifndef MOD_PAGE
if (NLINES(h, fd) > LNCNT && *PAGER) {
#else MOD_PAGE
if (NLINES(h, fd) >
***************
*** 931,936
#ifdef PAGE
/* Filter the tail of long messages through PAGER. */
if (NLINES(h, fd) > LNCNT && *PAGER) {
if (!index(PAGER, FMETA)) {
FILE *pfp, *popen();
int cnt;
--- 1038,1049 -----
/* Filter the tail of long messages through PAGER. */
#ifndef MOD_PAGE
if (NLINES(h, fd) > LNCNT && *PAGER) {
+ #else MOD_PAGE
+ if (NLINES(h, fd) >
+ (((rflag && bit < 1) || (bit > ngsize))? LNCNT - 5 : LNCNT)
+ && *PAGER) {
+ if ( strcmp(PAGER, "My Own") != 0 ) {
+ #endif MOD_PAGE
if (!index(PAGER, FMETA)) {
FILE *pfp, *popen();
int cnt;
***************
*** 951,958
else
pout(ofp);
holdup = TRUE;
}
else
#endif
--- 1064,1077 -----
else
pout(ofp);
holdup = TRUE;
+ #ifdef MOD_PAGE
+ } else
+ /* PAGER == "My Own" */
+ if (pprint(fd, ofp, &h, 0L, 0)) {
+ fclose(fd);
+ return(1);
+ }
+ #endif MOD_PAGE
}
else
#endif
***************
*** 959,964
tprint(fd, ofp, FALSE), itsbeenseen(h.ident);
}
fclose(fd);
}
/*
--- 1078,1086 -----
tprint(fd, ofp, FALSE), itsbeenseen(h.ident);
}
fclose(fd);
+ #ifdef MOD_PAGE
+ return(0);
+ #endif MOD_PAGE
}
/*
*** ../vanilla/src/rfuncs2.c Wed May 25 12:58:00 1983
--- rfuncs2.c Sun Jun 5 18:20:48 1983
***************
*** 64,69
}
/*
* Save the news item in the user's file.
* Fri Mar 12 20:04:43 EST 1982: (ittvax!swatt)
--- 64,70 -----
}
+ #ifndef MOD_PAGE
/*
* Save the news item in the user's file.
* Fri Mar 12 20:04:43 EST 1982: (ittvax!swatt)
***************
*** 138,143
if (!isprogram)
printf("%s: %s\n", to, isnew ? "New file" : "Appended");
}
/*
--- 139,145 -----
if (!isprogram)
printf("%s: %s\n", to, isnew ? "New file" : "Appended");
}
+ #endif MOD_PAGE
/*
****** THE REST OF THIS ARTICLE IS THE FILE PAGER.C *******
#ifdef MOD_PAGE
/*
* This pager was originally written by Alan Hastings while system manager
* at St. Olaf College, for version 2.3 of Bnews. It has been enhanced and
* updated to run under successive versions of Bnews (currently 2.10) by
* Dave Borman at St. Olaf.
*
*/
#include "rparams.h"
#define TABSIZE 8
#define COL 80
pprint(ifp, ofp, h, end, art)
register FILE *ifp, *ofp;
struct hbuf *h;
long end;
int art;
{
char ppbuf[BUFLEN], resbuf[BUFLEN];
char *respons;
long pgoffs[BUFLEN];
long begin;
int curpg = 0,
lastpg = 0;
register int i = 0;
int isnew;
begin = pgoffs[0] = ftell(ifp);
pgoffs[1] = 0L;
while (fgets(ppbuf, sizeof(ppbuf), ifp)) {
if (end && (ftell(ifp) > end))
break;
if (sigtrap) {
qfflush(ofp);
break;
}
i += num_lines(ppbuf);
if (i > 23) {
i = 1;
if (++curpg > lastpg)
lastpg = curpg;
if (pgoffs[lastpg]==0L) {
pgoffs[lastpg] = ftell(ifp);
pgoffs[lastpg+1] = 0L;
}
getmore:
#ifdef MOD_NTTY
fflush(ofp);
ioctl(fileno(ofp), TIOXRESO, 0);
#endif MOD_NTTY
fprintf(ofp, "Page %d -- Press return for more-- [ynq] ", curpg);
fflush(ofp);
fgets(resbuf, sizeof(resbuf), stdin);
respons = resbuf;
nstrip(respons);
while(*respons == ' ' || *respons == '\t')
respons++;
switch (*respons) {
default:
fprintf(ofp, "? for pager commands\n");
goto getmore;
case 'y':
case 'Y':
case '\0':
case '\n':
break;
case 'n':
sigtrap = FALSE;
fprintf(ofp, "\n");
return(0);
case 'h':
if (art)
dhprint(art, ifp, ofp);
else
hprint(h, ofp, !cflag);
goto getmore;
case 'q':
return(1);
case '+':
case '-': {
int n = 1, nn;
char *r = respons;
while (*++r==respons[0])
n++;
nn = atoi(r);
if (respons[0]=='-')
curpg -= (nn==0) ? n+1 : n+nn;
else
curpg += (nn==0) ? n-1 : n+nn-2;
curpg = (curpg < 0) ? 0 :
(curpg > lastpg) ? lastpg : curpg;
fseek(ifp, pgoffs[curpg], 0);
fgets(ppbuf, sizeof(ppbuf), ifp);
break;
}
case '!':
fwait(fsubr(ushell, &respons[1], (char *)NULL));
fprintf(ofp, "!\n");
goto getmore;
case 'p':
fseek(ifp, pgoffs[--curpg], 0);
fgets(ppbuf, sizeof(ppbuf), ifp);
break;
case 'l':
curpg = lastpg;
fseek(ifp, pgoffs[curpg], 0);
fgets(ppbuf, sizeof(ppbuf), ifp);
break;
case '#':
fprintf(ofp, "%d more lines\n",
(end ? plinecnt(ifp, end) : linecnt(ifp))+1);
goto getmore;
case 's':
case 'w':
{
char *rp = &respons[1];
if (*rp != '\0' && *rp != ' ' && *rp != ' ') {
fprintf(ofp, "Bad file name.\n");
break;
}
while (*rp==' ' || *rp=='\t')
rp++;
if(*rp != '|' && *rp != '/') {
char hetyped[BUFLEN];
char *boxptr;
strcpy(hetyped,rp);
if(boxptr = getenv("NEWSBOX"))
if (index(boxptr, '%'))
sprintf(rp,boxptr,groupdir);
else
strcpy(rp, boxptr);
else if (hetyped[0]=='~' && hetyped[1]=='/') {
strcpy(hetyped, rp+2);
strcpy(rp, userhome);
} else
strcpy(rp, ".");
strcat(rp,"/");
if(hetyped[0] != '\0')
strcat(rp, hetyped);
#ifdef MOD_SAVE
else {
char *ART = getenv("ARTICLES");
strcpy(rp,ART?ART:"articles");
}
#else
else
strcat(rp, "Articles");
#endif MOD_SAVE
}
isnew = access( rp, 2 );
if (art)
dsaveart(art, ifp, ofp, rp);
else if( psave(ifp, rp, *respons=='s' ? 1:0) == 1 )
printf("%s: %s\n",
rp, isnew ? "New file": "Appended");
goto getmore;
}
case '?':
fprintf(ofp,
"(p)rint again, (n)ext article, (q)uit, (l)ast page, -n, +n, (y)et another page\n");
fprintf(ofp,
"(#) of lines left, (s)ave, (w)rite, (h)eader\n");
goto getmore;
}
}
fprintf(ofp, "%s", ppbuf);
}
fflush(ofp);
if (sigtrap)
printf(ofp, "\n\n");
else
/* if new newsgroup header follows, allow five extra lines */
if (i > (((rflag && bit < 1) || (bit>ngsize)) ? LNCNT - 5 : LNCNT)) {
while (i++ < 23)
putc('\n', ofp);
#ifdef MOD_NTTY
ioctl(fileno(ofp), TIOXRESO, 0);
#endif MOD_NTTY
fprintf(ofp, "-- Press return --");
fflush(ofp);
fgets(resbuf, sizeof(resbuf), stdin);
} else
fprintf(ofp, "\n");
fflush(ofp);
sigtrap = FALSE;
return(0);
}
plinecnt(fp, end)
FILE *fp;
long end;
{
long curpos;
long count;
register int nlines = 0;
register int c;
if (!end)
return(linecnt(fp));
if (fp == NULL)
return(0);
curpos = ftell(fp);
count = end - curpos;
while (((c = getc(fp)) != EOF) && (--count >= 0))
if (c == '\n')
nlines++;
fseek(fp, curpos, 0);
return(nlines);
}
num_lines(line)
char *line;
{
register int count = 0;
register char *p;
for( p = line; *p != NULL; p++ )
switch( *p ){
case '\t':
count += TABSIZE - count%TABSIZE;break;
default:
count++;
}
return( (count + COL - 1)/COL ); /* COL-1: linelength minus newline */
}
psave(ifp, fnm, flg)
char *fnm;
{
long savpos = ftell(ifp);
FILE *ofp;
int isprogram = 0;
struct hbuf savh;
if (ifp == NULL)
return ( NULL );
if (*fnm == '|'){
if ((ofp = popen (&fnm[1], "w")) == NULL) {
printf ("Cannot execute %s\n", &fnm[1]);
return (NULL);
}
isprogram++;
} else
if ((ofp = fopen(fnm, "a")) == NULL) {
printf("Cannot append to %s\n", fnm);
return (NULL);
}
fseek(ifp, 0, 0); /* back to beginning */
if (hread(&savh, ifp, TRUE) == NULL) { /* grab header */
printf("Article is garbled.\n");
return (NULL);
}
#ifdef V7MAIL
savh.subtime = cgtdate(savh.subdate);
fprintf(ofp, "From %s %s",
#ifdef INTERNET
savh.from,
#else
savh.path,
#endif INTERNET
ctime(&savh.subtime));
#endif V7MAIL
if (flg)
hprint(&savh, ofp, 1);
#ifdef V7MAIL
putc('\n', ofp); /* force blank line before article */
tprint(ifp, ofp, TRUE);
putc('\n', ofp); /* force blank line at end (ugh) */
#else
tprint(ifp, ofp, FALSE);
#endif V7MAIL
if (isprogram)
pclose(ofp);
else
fclose(ofp);
fseek(ifp, savpos, 0);
return(!isprogram);
}
rsave(ifnm, fnm, flg)
char *ifnm, *fnm;
{
FILE *ifp = fopen(ifnm, "r");
int isnew;
if( ifp == NULL ){
printf("Can't get Article.\n");
return;
}
isnew = access( fnm, 2 );
if( psave(ifp, fnm, flg) == 1 )
printf("%s: %s\n", fnm, isnew ? "New file" : "Appended");
fclose(ifp);
}
#endif MOD_PAGE
More information about the Comp.sources.unix
mailing list