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 s

⟦a1b8e03c9⟧ TextFile

    Length: 4488 (0x1188)
    Types: TextFile
    Names: »special.c«

Derivation

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

TextFile

#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*/
}