DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T u

⟦6cb83681e⟧ TextFile

    Length: 5891 (0x1703)
    Types: TextFile
    Names: »undig.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/news/misc/undig/undig.c« 

TextFile

/* Undig(estify) -- a pager for digest articles.
   It has some knowledge about digest formats in it,
   and can skip forward and backward sections.
   BUGS:
	- no check on overflow of block list in mainloop!
   	- echoing of control characters in ttygets is dumb
   	- reverse searching findes the same string over and over
   TO DO:
   	- implement follow up?
   	- fix the logic for searching (rearrange main loop again...)
   	- searching should not headers it has skipped
   	- searching should show a few lines before the match
   	- output control characters as ^L etc.
   	- prompt with line number and/or percentage
   	- make more parametrizable (headers to skip, etc.)
   	- maybe add commands to:
   		- summarize subjects (a la '=') ?
   		- go to random messages in the digest ?
   		- change some parameters ?
   	- purge text blocks from memory and reread when necessary
*/

#include "undig.h"

/* Main program. */

main(argc, argv)
	int argc;
	char **argv;
{
	preset();
	getargs(argc, argv);
	mainloop();
	bye(0);
}

/* Process command line arguments.  Must be called before any I/O is done
   on stdin, since it may open another file on file descriptior 0. */

char *progname= "undig";

getargs(argc, argv)
	int argc;
	char **argv;
{
	int c;
	int i;
	
	if (argc > 0 && argv[0] != NULL && argv[0][0] != EOS) {
		progname= rindex(argv[0], '/');
		if (progname == NULL)
			progname= argv[0];
	}
	
	while ((c= getopt(argc, argv, "z:h:s:pPm:")) != EOF) {
		switch (c) {
		
		/* Pager size parameters */
		case 'z':
		case 'h':
		case 's':
			i= atoi(optarg);
			if (i <= 0)
				usage();
			switch (c) {
			case 'z': pagesize= i; break;
			case 'h': halfsize= i; break;
			case 's': startsize= i; break;
			}
			break;
		
		/* Set mailer */
		case 'm':
			mailer= optarg;
			break;
			
		/* Clear/home before new message */
		case 'p':
			messclear= YES;
			break;
			
		case 'P':
			pageclear= YES;
			break;
			
		/* Bad flag */
		default:
			usage();
			
		}
	}

	if (pagesize >= lines)
		pagesize= lines-1;
	if (halfsize > pagesize)
		halfsize= pagesize;
	if (startsize > pagesize)
		startsize= pagesize;
		
	if (optind < argc) {
		if ((infp= fopen(argv[optind], "r")) == NULL) {
			perror(argv[optind]);
			exit(1);
		}
	}
	else {
		int fd= dup(0);
		
		if ((infp= fdopen(fd, "r")) == NULL)
			fatal("can't dup 0");
		close(0);
		if (open("/dev/tty", 0) != 0) {
			perror("/dev/tty");
			fatal("no tty");
		}
	}
}

/* Command line error.  Print usage message and die. */

usage()
{
	fprintf(stderr,
		"usage: %s [-{zhs} size] [-m mailer] [-p] [-P] [file]\n",
		progname);
	exit(2);
}

/* Fatal error.  Print message and die. */

fatal(message)
	char *message;
{
	fprintf(stderr, "%s: fatal error: %s\n", progname, message);
	bye(2);
}

/* Main loop. */

mainloop()
{
	struct block list[1000];
	int nlist= 0;
	int cur= 0;
	int curhead= 0;
	int prevhead= 0;
	int lasthead= 0;
	bool prompt= NO;
	
	getblock(&list[cur= nlist++]);
	if (pageclear)
		needclear= YES;
	for (;;) {
		/* Page one message, until end or until stopped. */
		if (left > startsize)
			left= startsize;
		prevhead= curhead;
		curhead= cur;
		if (curhead > lasthead)
			lasthead= curhead;
		prompt= NO;
		if (messclear)
			needclear= YES;
 horror:
		for (;;) {
			if (list[cur].class != EOF) {
				if (!putblock(&list[cur++]))
					break;
				if (cur >= nlist)
					getblock(&list[cur= nlist++]);
			}
			if (list[cur].class == EOF ||
					list[cur].class == HEADER) {
 again:
				if (list[cur].class == EOF)
					printf("...end of digest...\n");
				else
					printf("...end of message...\n");
				(void) pagecmd();
				prompt= YES;
				if (cur > lasthead)
					lasthead= cur;
				break;
			}
			nospace= NO;
		}
		
		/* Move 'cur' to start of next message. */
		for (;;) {
			if (cur >= nlist)
				getblock(&list[cur= nlist++]);
			if (list[cur].class == EOF ||
					list[cur].class == HEADER)
				break;
			++cur;
		}
		
		/* Process the command that stopped the above loop. */
		switch (lastcmd) {
		
		/* Search for a string. */
		case '/':
		case '?':
			if (search(list, &nlist, &cur))
				goto horror;
			else
				goto again;
		
		/* Save or write message to file. */
		case 's':
		case 'w':
		case '|':
			saveetc(&list[curhead], cur-curhead);
			goto again;
			/* This command and the next differ from others
			   in that they want to stay at the end of the
			   current article.  The solution here is not quite
			   kosher, but it works... */
			
		/* Reply or follow up. */
		case 'r':
		case 'R':
		case 'f':
		case 'F':
			replyetc(&list[curhead], cur-curhead);
			goto again;
			
		/* To start of next message. */
		default: /* All forward paging commands, like SP, CR, ^D. */
		case 'N':
		case CTL('N'):
			if (prompt && list[cur].class == EOF)
				bye(0);
			if (!prompt)
				printf("...skipping...\n");
			break;
			
		/* Backup to begin of message. */
		case CTL('R'):
		case CTL('L'):
		case CTL('B'):
		case 'b':
			if (!prompt)
				printf("...same message...\n");
			cur= curhead;
			break;
			
		/* Backup to previous message. */
		case 'p':
		case 'P':
		case CTL('P'):
			if (curhead == 0) {
				printf("...begin of digest...\n");
				cur= 0;
			}
			else {
				if (!prompt)
					printf("...previous message...\n");
				cur= curhead-1;
				while (cur > 0 && list[cur].class != HEADER)
					--cur;
			}
			break;
			
		/* Quit. */
		case 'q':
		case EOF:
			bye(0);
			
		/* Toggle between current and previous message. */
		case '-':
			cur= prevhead;
			prevhead= curhead;
			curhead= cur;
			if (!prompt)
				printf("...alternate message...\n");
			break;
			
		/* Go to end of messages already seen. */
		case 'n':
			if (!prompt)
				printf("...next unseen message...\n");
			if (lasthead > curhead)
				cur= lasthead;
			break;
			
		/* Go to begin of digest. */
		case '^':
			if (!prompt)
				printf("...first message...\n");
			cur= 0;
			break;
		}
		nospace= YES;
	}
}