|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T u ┃
Length: 5891 (0x1703) Types: TextFile Names: »undig.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/news/misc/undig/undig.c«
/* 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; } }