|
|
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 - metrics - downloadIndex: T s
Length: 4488 (0x1188)
Types: TextFile
Names: »special.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/news/misc/undig/special.c«
#include "undig.h"
#include <signal.h>
/* The following routines assume that the message is contained in
bp[0], bp[1], ..., bp[nblocks-1], and that bp[0] is the header. */
char *mailer= "Rnmail -h %s %s";
/* Save, write, pipe to command. */
bool
saveetc(bp, nblocks)
struct block *bp;
int nblocks;
{
char *cp;
FILE *fp;
int i;
bool pipe= lastcmd == '|';
bool noheaders= lastcmd == 'w';
int (*oldhandler)();
cp= cmdarg;
while (*cp != EOS && isspace(*cp))
++cp;
if (*cp == EOS)
return NO;
if (!pipe && *cp == '|') {
pipe= YES;
++cp;
}
if (pipe)
fp= popen(cp, "w");
else
fp= fopen(cp, "a");
if (fp == NULL) {
perror(cp);
return NO;
}
if (pipe)
oldhandler= signal(SIGPIPE, SIG_IGN);
/* Avoid dying of broken pipe */
if (!pipe && ftell(fp) > 0)
printf("Appending\n");
i= 0 + noheaders;
for (; i < nblocks; ++i) {
int j;
struct line *p;
if (i > 0) {
for (j= bp[i].lead; --j >= 0; )
putc('\n', fp);
}
for (p= bp[i].top; p != NULL; p= p->next)
putline(p, fp);
}
/* Append two blank lines, like rn does (why, though?) */
putc('\n', fp);
putc('\n', fp);
fflush(fp);
if (pipe) {
pclose(fp);
signal(SIGPIPE, oldhandler);
}
else
fclose(fp);
return YES;
}
/* Reply and follow up. */
bool
replyetc(bp, nblocks)
struct block *bp;
int nblocks;
{
char header[20];
char command[100];
FILE *fp;
if (lastcmd == 'f' ||lastcmd == 'F') {
printf("Sorry, follow up not implemented\n");
return YES;
}
strcpy(cmdarg, "/tmp/@undigXXXXXX");
mktemp(cmdarg);
lastcmd= 's';
if (!saveetc(bp, nblocks)) {
unlink(cmdarg);
return NO;
}
strcpy(header, "/tmp/@undigXXXXXX");
mktemp(header);
fp= fopen(header, "w");
if (fp == NULL) {
perror(header);
unlink(cmdarg);
return NO;
}
replyheader(bp->top, fp);
fclose(fp);
sprintf(command, mailer, header, cmdarg);
printf("Executing: %s\n", command);
shell(command);
unlink(cmdarg);
unlink(header);
return YES;
}
/* Header manipulation stuff */
#define IsSubject(s) (strncmp(s, "Subject:", 8) == 0)
#define IsFrom(s) (strncmp(s, "From:", 5) == 0)
#define IsReplyTo(s) (strncmp(s, "Reply-To:", 9) == 0)
#define IsRe(s) (strncmp(s, "Re:", 3) == 0)
char *
strip(s)
char *s;
{
while (*s != ':') {
if (*s == EOS)
return s;
++s;
}
++s;
while (*s != EOS && !isspace(*s))
++s;
return s;
}
/* Construct a header suitable for a reply. */
replyheader(p, fp)
struct line *p;
FILE *fp;
{
char *subject= NULL;
char *from= NULL;
char *replyto= NULL;
struct line *q;
for (q= p; q != NULL; q= q->next) {
if (q->indent != 0)
continue;
if (IsSubject(q->text))
subject= q->text;
else if (IsFrom(q->text))
from= q->text;
else if (IsReplyTo(q->text))
replyto= q->text;
}
fprintf(fp, "To: ");
if (replyto == NULL)
replyto= from;
if (replyto != NULL)
fprintf(fp, "%s", strip(replyto));
fprintf(fp, "\nSubject: ");
if (subject != NULL) {
subject= strip(subject);
if (IsRe(subject))
subject= strip(subject);
fprintf(fp, "Re: %s", subject);
}
fprintf(fp, "\n\n\n");
}
/* String search. */
char pattern[256];
search(list, pnlist, pcur)
struct block *list;
int *pnlist;
int *pcur;
{
int nlist= *pnlist;
int cur= *pcur;
bool reverse= (lastcmd == '?');
struct line *p, *found;
char *cp;
cp= cmdarg + strlen(cmdarg);
if (cp > cmdarg && cp[-1] == lastcmd)
*--cp= EOS;
if (cmdarg[0] != EOS)
strcpy(pattern, cmdarg);
else if (pattern[0] == EOS) {
printf("No previous search string\n");
return NO;
}
if (list[cur].class == EOF) {
if (reverse)
--cur;
else
return NO;
}
for (;;) {
found= NULL;
for (p= list[cur].top; p != NULL; p= p->next) {
if (match(p->text)) {
found= p;
if (!reverse)
break;
}
}
if (found != NULL)
break;
if (reverse) {
if (--cur == 0)
return NO;
}
else {
if (++cur >= nlist) {
getblock(&list[cur= *pnlist= nlist++]);
if (list[cur].class == EOF)
return NO;
}
}
}
*pcur= cur;
for (p= found; p != NULL; p= p->next) {
if (!pageline(p))
return NO;
}
return YES;
}
/* String matcher, slow but secure.
Line is case-folded; pattern is assumed to be all lower case. */
bool
match(line)
char *line;
{
char *p, *q;
char c1, c2;
for (;; ++line) {
for (p= line, q= pattern;; ++p, ++q) {
c1= *p;
c2= *q;
if (c2 == EOS)
return YES;
if (c1 == EOS)
return NO;
if (c1 == c2 || isupper(c1) && tolower(c1) == c2)
continue;
break;
}
}
/*NOTREACHED*/
}