/* ** Copyright (C) 1994, Enterprise Integration Technologies Corp. ** All Rights Reserved. ** Kevin Hughes, kevinh@eit.com ** 7/31/94 */ #include "hypermail.h" #include "parse.h" /* Parsing...the heart of Hypermail! ** This loads in the articles from stdin or a mailbox, adding the right ** field variables to the right structures. If readone is set, it will ** think anything it reads in is one article only. */ void loadheaders(mbox, use_stdin, readone) char *mbox; int use_stdin; int readone; { FILE *fp; char name[NAMESTRLEN], email[MAILSTRLEN], date[DATESTRLEN], msgid[MSGDSTRLEN], subject[SUBJSTRLEN], inreply[REPYSTRLEN], line[MAXLINE], tmpfrom[MAXLINE], fromdate[DATESTRLEN], oldline[MAXLINE]; int num, isinheader, hassubject, hasdate, wasinreply; struct body *bp; if (!strcmp(mbox, "NONE") || use_stdin) fp = stdin; else { if ((fp = fopen(mbox, "r")) == NULL) { sprintf(errmsg, "Couldn't open mail archive \"%s\".", mbox); progerr(NULL); } } if (readone) num = bignum; else num = 0; hassubject = 0; hasdate = 0; wasinreply = 0; isinheader = 1; inreply[0] = '\0'; tmpfrom[0] = '\0'; oldline[0] = '\0'; bp = NULL; if (!readone) { replylist = NULL; subjectlist = NULL; authorlist = NULL; datelist = NULL; } if (showprogress && readone) printf("Reading new header...\n"); if (showprogress && !readone) { if (!strcmp(mbox, "NONE") || use_stdin) printf("Loading mailbox... "); else printf("Loading mailbox \"%s\"... ", mbox); } while (fgets(line, MAXLINE, fp) != NULL) { if (isinheader) { if (!strncmp(line, "Received:", 9) || !strncmp(line, "Return-Path:", 12) || !strncmp(line, "Cc:", 3) || !strncmp(line, "X-", 2) || !strncmp(line, "Flags:", 6)) continue; if (!strncmp(line, "From ", 5)) strcpy(fromdate, (char *) getfromdate(line)); else if (!strncmp(line, "Date:", 5)) { bp = (struct body *) addbody(bp, line); strcpy(date, (char *) getmaildate(line)); hasdate = 1; } else if (!strncmp(line, "From:", 5)) { bp = (struct body *) addbody(bp, line); getname(line, name, email); } else if (!strncmp(line, "Message-Id:", 11)) { bp = (struct body *) addbody(bp, line); strcpy(msgid, (char *) getid(line)); } else if (!strncmp(line, "Subject:", 8)) { bp = (struct body *) addbody(bp, line); strcpy(subject, (char *) getsubject(line)); hassubject = 1; } else if (!strncmp(line, "In-Reply-To:", 12)) { bp = (struct body *) addbody(bp, line); strcpy(inreply, (char *) getreply(line)); wasinreply = 1; } else if ((!strncmp(line, " ", 4) || line[0] == '\t') && strchr(line, '<') && strchr(line, '>') && strchr(line, '@') && wasinreply) { bp = (struct body *) addbody(bp, line); strcpy(inreply, (char *) getreply(line)); wasinreply = 0; } else if (!strncmp(line, "To:", 3)) bp = (struct body *) addbody(bp, line); else if (line[0] == '\n') { bp = (struct body *) addbody(bp, line); isinheader = 0; } } else { if (!strncmp(line, "From ", 5)) { if (readone) continue; if (strstr(oldline, "Forwarded message:")) { oldline[0] = '\0'; continue; } isinheader = 1; wasinreply = 0; if (!hassubject) strcpy(subject, NOSUBJECT); else hassubject = 1; if (!hasdate) strcpy(date, NODATE); else hasdate = 1; if (inreply[0] == '\0') oneunre(inreply, subject); while (rmlastlines(bp)); addhash(num, date, name, email, msgid, subject, inreply, fromdate, bp); authorlist = (struct header *) addheader(authorlist, num, name, subject, date, 1); subjectlist = (struct header *) addheader(subjectlist, num, name, unre(subject), date, 0); datelist = (struct header *) addheader(datelist, num, name, subject, fromdate, 2); strcpy(fromdate, (char *) getfromdate(line)); bp = NULL; num++; if (!(num % 10) && showprogress && !readone) { printf("\b\b\b\b%4d", num); fflush(stdout); } inreply[0] = '\0'; } else bp = (struct body *) addbody(bp, line); } strcpy(oldline, line); } if (!isinheader) { if (!hassubject) strcpy(subject, NOSUBJECT); if (!hasdate) strcpy(date, NODATE); if (inreply[0] == '\0') oneunre(inreply, subject); while (rmlastlines(bp)); addhash(num, date, name, email, msgid, subject, inreply, fromdate, bp); authorlist = (struct header *) addheader(authorlist, num, name, subject, date, 1); subjectlist = (struct header *) addheader(subjectlist, num, name, unre(subject), date, 0); datelist = (struct header *) addheader(datelist, num, name, subject, fromdate, 2); num++; } if (showprogress && !readone) printf("\b\b\b\b%4d articles.\n", num); if (!readone) bignum = num - 1; fclose(fp); crossindex(); threadlist = NULL; printedthreadlist = NULL; crossindexthread1(datelist); } /* All this does is get all the relevant header information from the ** comment fields in existing archive files. Everything is loaded into ** structures in the exact same way as if articles were being read from ** stdin or a mailbox. */ void loadoldheaders(dir) char *dir; { FILE *fp; char name[NAMESTRLEN], email[MAILSTRLEN], date[DATESTRLEN], msgid[MSGDSTRLEN], subject[SUBJSTRLEN], inreply[REPYSTRLEN], line[MAXLINE], fromdate[DATESTRLEN], filename[MAXFILELEN]; int num; struct body *bp; num = 0; sprintf(filename, "%s%s%.4d.html", dir, (dir[strlen(dir) - 1] == '/') ? "" : "/", num); bp = NULL; bp = (struct body *) addbody(bp, "\0"); authorlist = subjectlist = datelist = NULL; if (showprogress) printf("Reading old headers... "); while ((fp = fopen(filename, "r")) != NULL) { fgets(line, MAXLINE, fp); strcpy(fromdate, (char *) getvalue(line)); fgets(line, MAXLINE, fp); strcpy(date, (char *) getvalue(line)); fgets(line, MAXLINE, fp); strcpy(name, (char *) getvalue(line)); fgets(line, MAXLINE, fp); strcpy(email, (char *) getvalue(line)); fgets(line, MAXLINE, fp); strcpy(subject, (char *) unconvchars(getvalue(line))); fgets(line, MAXLINE, fp); strcpy(msgid, (char *) getvalue(line)); fgets(line, MAXLINE, fp); strcpy(inreply, (char *) unconvchars(getvalue(line))); fclose(fp); addhash(num, date, name, email, msgid, subject, inreply, fromdate, bp); authorlist = (struct header *) addheader(authorlist, num, name, subject, date, 1); subjectlist = (struct header *) addheader(subjectlist, num, name, unre(subject), date, 0); datelist = (struct header *) addheader(datelist, num, name, subject, fromdate, 2); num++; if (!(num % 10) && showprogress) { printf("\b\b\b\b%4d", num); fflush(stdout); } sprintf(filename, "%s%s%.4d.html", dir, (dir[strlen(dir) - 1] == '/') ? "" : "/", num); } if (showprogress) printf("\b\b\b\b%4d articles.\n", num); if (!num) bignum = 0; else bignum = num; } /* Adds a "Next:" link in the proper article, after the archive has been ** incrementally updated. */ void fixnextheader(dir, num) char *dir; int num; { char filename[MAXFILELEN], line[MAXLINE], name[NAMESTRLEN], email[MAILSTRLEN], subject[SUBJSTRLEN], inreply[REPYSTRLEN], date[DATESTRLEN], fromdate[DATESTRLEN], msgid[MSGDSTRLEN]; struct body *bp, *status; FILE *fp; sprintf(filename, "%s%s%.4d.html", dir, (dir[strlen(dir) - 1] == '/') ? "" : "/", num); bp = NULL; if ((fp = fopen(filename, "r")) != NULL) { while ((fgets(line, MAXLINE, fp)) != NULL) bp = (struct body *) addbody(bp, line); } else return; fclose(fp); if ((fp = fopen(filename, "w+")) != NULL) while (bp != NULL) { fprintf(fp, "%s", bp->line); if (!strncmp(bp->line, "