Category : UNIX Files
Archive   : PC-MAIL2.ZIP
Filename : PAGER.C

 
Output of file : PAGER.C contained in archive : PC-MAIL2.ZIP
/*++
/* NAME
/* pager 3
/* SUMMARY
/* pager for text files
/* PROJECT
/* pc-mail
/* PACKAGE
/* mail
/* SYNOPSIS
/* #include "pager.h"
/*
/* File *open_pager()
/*
/* void close_pager(p)
/* File *p;
/*
/* void set_pager(p)
/* File *p;
/*
/* void app_pager(p,s)
/* File *p;
/* char *s;
/*
/* void del_pager(p)
/* File *p;
/*
/* void mesg_pager(p,m)
/* File *p;
/* char *m[];
/*
/* void sort_pager(p,dir)
/* File *p;
/*
/* int cp_pager(path)
/* char *path;
/*
/* int pr_pager()
/*
/* int rd_pager(p,path)
/* File *p;
/* char *path;
/*
/* char *gets_pager();
/* File *p;
/*
/* void puts_pager(s);
/* char *s;
/*
/* int ds_pager()
/*
/* int pr_pager()
/*
/* int up_pager()
/*
/* int dn_pager()
/*
/* int pu_pager()
/*
/* int pd_pager()
/* DESCRIPTION
/* The pager provides acces to a pager file which is displayed
/* on the screen in the middle window. Some functions operate
/* on what is called the "current" pager file. All functions
/* have access to the contents of the middle screen window only.
/*
/* open_pager() creates a new (empty) pager file. The return value
/* should be used in subsequent accesses to the file. Sets the
/* current file.
/*
/* close_pager() releases storage for a pager file. Sets the
/* current file to none if that is the one being deleted.
/*
/* app_pager() appends a new line of text to the end of a pager file.
/* Sets the current file.
/*
/* del_pager() deletes the line at the current cursor position. Sets the
/* current file.
/*
/* mesg_pager() invokes app_pager() to copy a null-terminated array of
/* strings to a pager file. Since it invokes app_pager(), the current
/* pager file is set as well. Pager files filled by mesg-pager()
/* will not be displayed with an '-- end of display --' line at their end.
/*
/* ins_pager() inserts a line at the current cursor position. Sets the
/* current file.
/*
/* scan_pager() takes similar arguments as scanf(3), reads from the
/* line at the current cursor position and returns the number of
/* successfull conversions done. Does not set the current file.
/*
/* sort_pager() sorts a file alphabetically. Sets the current file.
/* The dir argument selects the direction of sort (FORW_SORT, BACK_SORT).
/*
/* set_pager() sets the current file.
/*
/* gets_pager() returns a pointer to the current line in the
/* current file, or a null pointer is there is none.
/*
/* puts_pager() replaces the current line in the current file.
/*
/* cp_pager() copies the contents of current pager file
/* to a normal (external) file. It returns a nonzero status if
/* an error occurred (bad path, write error,...).
/*
/* pr_pager() copies the current pager file to the printer.
/*
/* rd_pager() appends a permanent file to the current pager file.
/* It returns a nonzero status if an error occurred. Sets the current file.
/* rd_pager() reads through the ascf(3) ascii filter, so that it is
/* suitable for viewing word-processor files.
/*
/* up_pager() moves the cursor one line up, if there is one. The
/* screen is scrolled when the cursor was at the top of the screen.
/*
/* dn_pager moves the cursor one line down, if there is one. The
/* screen is scrolled when the cursor was at the bottom of the screen.
/*
/* pu_pager() displays a page of text that precedes the one on the
/* screen, or as much as there is.
/*
/* pd_pager() displays the next page of text, or as much as there is.
/* FUNCTIONS AND MACROS
/* printcl(), printat(), beep(), propen(), prclose(),ascopen(),
/* ascclose(), ascget()
/* SEE ALSO
/* path(3), window(3), window(5), asc(3)
/* DIAGNOSTICS
/* The buzzer makes noise when attempt is made to move the
/* cursor beyond the beginning or end of the pager file.
/* The program aborts with an error message if references are made
/* to the "current file" or "current line" if there is none.
/* BUGS
/* It looks a lot like an editor, but it isn't.
/*
/* No optimization. It just overwrites the whole middle window.
/* AUTHOR(S)
/* W.Z. Venema
/* Eindhoven University of Technology
/* Department of Mathematics and Computer Science
/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
/* CREATION DATE
/* Fri Apr 3 22:06:00 GMT+1:00 1987
/* LAST MODIFICATION
/* 90/01/22 13:02:21
/* VERSION/RELEASE
/* 2.1
/*--*/

#include

#include "defs.h"
#include "window.h"
#include "pager.h"
#include "path.h"
#include "ascf.h"

hidden File *curfile = NULL; /* head of the current file */

/* open_pager - create pager file and set current file */

public File *open_pager()
{
register File *p = curfile = (File *) myalloc(sizeof(File));

p->top = p->curr = p->head = p->last = NULL;
p->opts = 0;
return (p);
}

/* close_pager - release memory in a pager file */

public void close_pager(p)
register File *p;
{
register Line *q;

if (p) {
for (q = p->head; q; q = q->next) /* release lines */
free((char *) q);
if (curfile == p) /* unset current file */
curfile = 0;
free((char *) p); /* release header */
}
}

/* app_pager - append line at end of file and set current file */

public app_pager(p, s)
register File *p;
char *s;
{
register Line *l = (Line *) myalloc(sizeof(Line) + strlen(s));

if (p->head == 0) { /* first line in the file */
p->head = p->top = p->curr = l;
} else { /* real append */
p->last->next = l;
}
l->next = NULL; /* since it is last */
l->prev = p->last; /* since it is last */
p->last = l; /* since it is last */

strcpy(l->line, s); /* copy the line */

curfile = p; /* set current file */
}

/* del_pager - delete line at cursor and set current file (untested!) */

public void del_pager(p)
register File *p;
{
register Line *l = p->curr;

if (l) {
if (l->prev)
l->prev->next = l->next;
if (l->next)
l->next->prev = l->prev;
if (l == p->head)
p->curr = p->head = l->next;
if (l == p->top)
p->curr = p->top = l->next ? l->next : l->prev;
if (l == p->last)
p->curr = p->last = l->prev;
if (l == p->curr)
p->curr = l->next;
free((char *) l);
}
curfile = p;
}

/* set_pager - set the current file; use with care */

public void set_pager(p)
File *p;
{
curfile = p;
}

/*
* The following functions provide an easy interface to the keyboard
* interpreter routines. The keyboard interpreter just associates a key
* stroke with a function call, does not care what a function does and has
* almost no facility for passing function arguments. Although the keyboard
* interpreter manipulates cursor and page coordinates when the some keys
* are hit, it never knows which keys affect what the user sees on the
* screen. That explains why the following functions rely on the above ones
* for setting the "current file". It may also explain why the above
* routines do not immediately update the terminal screen, whereas the
* routines below do.
*/

/* ds_pager - display a page of the current pager file */

public int ds_pager()
{
static char endline[] = "-- end of display --";

if (curfile && curfile->curr) {
register Line *p;
register int k;

for (p = curfile->top, k = 0; p && k < midwin->size; p = p->next)
k += p->llen = printcl(midwin, p->lineno = k, p->line);
if (k < midwin->size)
printcl(midwin, k++, (curfile->opts & PG_NOEND) ? "" : endline);
while (k < midwin->size)
printcl(midwin, k++, "");
printat(midwin, curfile->curr->lineno, "");
} else {
register int k;

printcl(midwin, 0, (curfile->opts & PG_NOEND) ? "" : endline);
for (k = 1; k < midwin->size; k++)
printcl(midwin, k, "");
printat(midwin, 0, "");
}
return (0); /* screen up-to-date */
}

/* up_pager - up-arrow key hit. check cursor position */

public int up_pager()
{
register Line *p = curfile ? curfile->curr : 0;

if (p == 0 || p->prev == 0) {
beep();
} else {
if (p->lineno == 0)
pu_pager();
printat(midwin, (curfile->curr = p->prev)->lineno, "");
}
return (0);
}

/* dn_pager - down-arrow key hit. check cursor position */

public int dn_pager()
{
register Line *p = curfile ? curfile->curr : 0;

if (p == 0 || p->next == 0) {
beep();
} else {
if (p->lineno + p->llen >= midwin->size)
pd_pager();
printat(midwin, (curfile->curr = p->next)->lineno, "");
}
return (0);
}

/* pu_pager - display preceding page of info */

public int pu_pager()
{
register Line *p;
register int k;

if (curfile && (p = curfile->top) && curfile->top->prev) {
for (k = 0; k < midwin->size && p; k += p->llen, p = p->prev)
curfile->top = p;
curfile->curr = curfile->top;
ds_pager();
} else {
beep();
}
return (0);
}

/* pd_pager - display next page of info */

public int pd_pager()
{
register Line *p = curfile ? curfile->top : 0;
register int k;
register Line *dummy;

for (k = 0; k < midwin->size && p; k += p->llen, p = p->next)
dummy = p;
if (p) {
curfile->curr = curfile->top = dummy;
ds_pager();
} else {
beep();
}
return (0);
}

/*
* The following functions copy external files to pager file and vice-versa.
* There is a limited error detection facility in the form of nonzero return
* values.
*/

/* cp_pager - copy current pager file to permanent file */

public int cp_pager(path)
char *path;
{
register FILE *fp;

if (curfile && (fp = fopen(path, "w"))) {
register Line *pp;
int err;

for (pp = curfile->head; pp; pp = pp->next)
fputs(pp->line, fp), putc('\n', fp);
err = (fflush(fp) || ferror(fp));
fclose(fp);
return (err);
} else {
return (-1);
}
}

/* pr_pager - print pager file on default printer */

public int pr_pager()
{
register FILE *fp;

if (curfile && (fp = propen())) {
register Line *pp;
int err;

for (pp = curfile->head; pp; pp = pp->next)
fputs(pp->line, fp), putc('\n', fp);
err = (fflush(fp) || ferror(fp));
prclose(fp);
return (err);
} else {
return (-1);
}
}

/* rd_pager - copy ordinary file via filter to pager file */

public int rd_pager(p, path)
File *p;
char *path;
{
register FILE *fp;

if (p && (fp = ascopen(path, "r"))) { /* init the filter */
char buf[BUFSIZ];
int err;

while (ascgets(buf, sizeof(buf), fp)) /* copy to pager file */
app_pager(p, buf); /* line by line */

err = ferror(fp); /* check for errors */
ascclose(fp);
return (err);
} else {
return (-1);
}
}

/* fwdcmp, revcmp - compare lexical order of lines */

hidden int fwdcmp(l1, l2)
Line **l1,
**l2;
{
return (strcmp((*l1)->line, (*l2)->line));
}

hidden int revcmp(l1, l2)
Line **l1,
**l2;
{
return (strcmp((*l2)->line, (*l1)->line));
}

/* sort_pager - sort a pager file */

public void sort_pager(pp, dir)
File *pp;
int dir;
{
register Line *l;
register int i;
int lines;
Line **lvec;

/* Build a vector with pointers to line structures. */

for (i = 0, l = pp->head; l; l = l->next) /* count nbr of lines */
i++;
if (i <= 1) /* no work */
return;

lvec = (Line **) myalloc((lines = i) * sizeof(*lvec));

for (i = 0, l = pp->head; l; l = l->next) /* fill vector */
lvec[i++] = l;

/* Sort the vector with pointers to line structures. */

qsort((char *) lvec, lines, sizeof(*lvec),
dir == FORW_SORT ? fwdcmp : revcmp);

/* Restore links between line structures and destroy the sorted vector */

for (i = 0; i < lines - 1; i++) /* fix forward links */
lvec[i]->next = lvec[i + 1];
lvec[i]->next = NULL;

lvec[0]->prev = NULL; /* fix backward links */
for (i = 1; i < lines; i++)
lvec[i]->prev = lvec[i - 1];

pp->head = pp->top = pp->curr = lvec[0]; /* fix file header */
pp->last = lvec[lines - 1];

free((char *) lvec); /* release vector */

curfile = pp; /* set current file */
}

/* gets_pager - return current line in current file */

public char *gets_pager()
{
return (curfile && curfile->curr ? curfile->curr->line : 0);
}

/* puts_pager - replace line (cleanup this mess) */

public void puts_pager(s)
char *s;
{
if (curfile == 0 || curfile->curr == 0) { /* no-no if there is no line */
fatal("puts_pager: no current file");
} else {
register Line *old = curfile->curr; /* get current line */
register Line *new = (Line *) myalloc(sizeof(Line) + strlen(s));

new->prev = old->prev; /* fill it in */
new->next = old->next;
new->lineno = old->lineno;
strcpy(new->line, s);
if (new->next) /* check next line */
new->next->prev = new;
if (new->prev) /* check previous line */
new->prev->next = new;
if (old == curfile->head) /* check file head */
curfile->head = new;
if (old == curfile->top) /* check file display */
curfile->top = new;
if (old == curfile->last) /* check file tail */
curfile->last = new;
free((char *) curfile->curr); /* release old line */
curfile->curr = new; /* set current line */
}
}

/* mesg_pager - copy null-terminated array of strings to pager file */

public void mesg_pager(pp, msg)
register File *pp;
register char **msg;
{
pp->opts |= PG_NOEND; /* suppress end marker */

while (*msg)
app_pager(pp, *msg++);
}


  3 Responses to “Category : UNIX Files
Archive   : PC-MAIL2.ZIP
Filename : PAGER.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/