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