/***************************************************************************** * * File ..................: mbfido/ftn2rfc.c * Purpose ...............: Gate netmail->email or echomail->news * Last modification date : 14-Aug-2001 * ***************************************************************************** * Copyright (C) 1997-2001 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../lib/libs.h" #include "../lib/structs.h" #include "../lib/records.h" #include "../lib/dbftn.h" #include "../lib/dbdupe.h" #include "../lib/dbuser.h" #include "../lib/common.h" #include "../lib/clcomm.h" #include "rollover.h" #include "aliasdb.h" #include "postemail.h" #include "backalias.h" #include "ftn2rfc.h" #define KWDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" #define MAXPATH 73 #define BOUNDARY 79 /* * Global variables */ extern int news_in; /* Total news articles */ extern int news_out; /* News articles posted */ extern int news_bad; /* News articles refused */ extern int defaultrfcchar; /* Default RFC charset */ extern int defaultftnchar; /* Default FTN charset */ int newsopen = FALSE; /* News tempfile status */ FILE *nfp; /* News tempfile */ void fill_rlist(fa_list **, char *); void fill_rlist(fa_list **fap, char *str) { fa_list *tmp; faddr *ta; static unsigned int oldnet; char *buf, *p, *q; if ((str == NULL) || (*str == '\0')) return; Syslog('N' ,"fill_rlist %s",str); buf = xstrcpy(str); for (p = buf, q = strchr(p,'!'); *p; p = q, q = strchr(p,'!')) { if (q) *q++='\0'; else q=p+strlen(p); if ((ta=parsefaddr(p))) { if (ta->net == 0) ta->net=oldnet; else oldnet=ta->net; tmp=(fa_list *)malloc(sizeof(fa_list)); tmp->next=*fap; tmp->addr=ta; *fap=tmp; } } free(buf); for (tmp=*fap;tmp;tmp=tmp->next) Syslog('N', "fill_rlist returns: %s",ascfnode(tmp->addr,0x06)); return; } static char *rbuf; char *rfcmsgid(char *, faddr *); char *rfcmsgid(char *msgid, faddr *bestaka) { char *p, *q, *r; unsigned long id = 0L; faddr *ta = NULL; if (msgid == NULL) return NULL; /* * +40 for the additionnal stuff we need to write, should be enough */ rbuf = malloc(strlen(msgid) + 40); if ((r = strrchr(msgid,'\n'))) *r = '\0'; /* * sometimes there is "^aMSGID: 1:23/45@@domain 152ad589" */ if ((p = strstr(msgid, "@@"))) { *p='\0'; strcat(msgid, p+1); } else if ((p = strstr(msgid,"@ "))) { /* * other times there is "^aMSGID: 1:23/45@ 152ad589" */ *p='\0'; strcat(msgid,p+1); } if ((p=strrchr(msgid,' '))) { /* * here we have a parseable address */ *p = '\0'; sscanf(p+1, "%lx", &id); ta = parsefnode(msgid); *p=' '; } if (id != 0L) { /* if we only check for (ta) a Message-ID like * <123456.7890@internet.domain> will be recognized as * a fidonet one (ta->node=123456, ta->point=7890, * ta->domain="internet", but ta->net=0) which obviously * isn't the case. By cheking also (ta->net) we avoid that */ if ((ta) && (ta->net)) { sprintf(rbuf, "<%lu@%s.ftn>", id, ascinode(ta,0x1f)); } else { p = xstrcpy(msgid); if ((q = strchr(p,' '))) *q = '\0'; /* ### Modified by P.Saratxaga on 18 Aug 1995 */ if (strstr(p, "@")) { /* "mid__" are generated by gigo */ if (!strncmp(p, "mid__<", 6)) { sprintf(rbuf, "%s", p+6); while ((q = strstr(rbuf, ">_<"))) *(q+1) = ' '; } /* "mid__local@domain" are also generated by gigo */ else if (!strncmp(p, "mid__", 5)) sprintf(rbuf, "<%s>", p+5); /* "wgmid$" */ else if (!strncmp(p, "wgmid$<", 7)) sprintf(rbuf, "%s", p+6); /* in case we have "" */ else if (!strncmp(p, "<", 1)) sprintf(rbuf, "%s", p); /* or "local@domain" */ else sprintf(rbuf, "<%s>", p); while ((q = strchr(rbuf, '@')) != strrchr(rbuf, '@')) { /* we (still) have more than one @ */ *q = '%'; } } else { sprintf(rbuf, "<%lu@%s>", id, p); } free(p); } } else { sprintf(rbuf, "<%lu@%s.ftn>", (unsigned long)sequencer(), ascinode(bestaka,0x1f)); } tidy_faddr(ta); if (r) *r='\n'; return rbuf; } /* * check address for localness, substitute alises and replace it *in place* */ void substitude(char *); void substitute(char *buf) { faddr *fa; char *l,*r,*p=NULL; int inquotes,inbrackets; Syslog('m', "to address before subst: \"%s\"",buf); if ((l=strchr(buf,'<')) && (r=strchr(buf,'>')) && (l < r)) { l++; *r='\0'; } else l=buf; while (*l == ' ') l++; for (r=l,inquotes=0,inbrackets=0;*r;r++) switch (*r) { case '"': inquotes=(!inquotes); break; case ',': case ' ': if (!inquotes && !inbrackets) *r='\0'; break; case '(': if (!inquotes) inbrackets++; break; case ')': if (!inquotes && inbrackets) inbrackets--; break; default: break; } if ((fa=parsefaddr(l))) { Syslog('m', "it is an ftn address: %s",ascfnode(fa,0x7f)); if (is_local(fa)) { Syslog('m', "it is local"); sprintf(buf,"%s",fa->name); if (!strchr(buf,'@') && (p=strrchr(buf,'%'))) *p='@'; if (!strchr(buf,'@')) { /* * Lookup the name first in the alias database, then * the userbase and finally check the password file * (gecos->username). If not found it's and error. */ if ((p = lookup(buf))) strcpy(buf, p); else if (SearchUser(buf)) sprintf(buf, "%s@%s", usr.Name, CFG.sysdomain); else if (!strcasecmp(buf,"sysop")) strcpy(buf,"postmaster"); else sprintf(buf,"%s",ascinode(fa,0x7f)); } } else { WriteError("substitute(%s) it is not local, may not happen", buf); sprintf(buf,"%s",ascinode(fa,0x7f)); } tidy_faddr(fa); } else { Syslog('m', "it is not ftn address"); for (r=buf;*l;l++,r++) *r=*l; *r='\0'; } if (buf[0] == '\0') strcpy(buf,"postmaster"); Syslog('m', "to address after subst: \"%s\"",buf); return; } /* * Lines to send, if it is a newsarticle, the Message-Id is checked. */ void Send(int, const char *, ...); void Send(int newsmode, const char *format, ...) { char *outstr, *p; va_list va_ptr; unsigned long crc; outstr = calloc(2048, sizeof(char)); va_start(va_ptr, format); vsprintf(outstr, format, va_ptr); va_end(va_ptr); fwrite(outstr, 1, strlen(outstr), nfp); if (newsmode) { Striplf(outstr); if (strncmp(outstr, (char*)"Message-ID: ", 12) == 0) { /* * The Message-ID that is sent to the newsserver is stored in * the dupes database. The database isn't checked for dupes, this * message is already checked for dupes. The function that will * pull news articles from the news server will check the dupes * database and thus will not fetch this local posted article. */ p = xstrcpy(outstr+12); p = xstrcat(p, msgs.Newsgroup); crc = str_crc32(p); CheckDupe(crc, D_NEWS, CFG.nntpdupes); free(p); } } free(outstr); } /* * Gate FTN style netmail->email or echomail->news. * * 0 - All seems well. * 1 - Something went wrong. * 4 - Unable to open temporary file * */ int ftn2rfc(faddr *f, faddr *t, char *subj, char *origline, time_t mdate, int flags, FILE *pkt) { int rrq, result = 1, modtype = 0; int incode = CHRS_NOTSET, outcode = CHRS_NOTSET; int waskludge = FALSE, badkludge, pgpsigned = FALSE; int bNeedToGetAddressFromMsgid = (int)NULL; int newsmode = 0, lines, pass, count, first; char *newsgroup = NULL, *distribution = NULL, *moderator = NULL; char *temp, *p, *q, *r, *l, *b; char *To = NULL, buf[4096], *charset, c; time_t now; rfcmsg *kmsg = NULL, **tmsg, *qmsg, *msg = NULL; off_t endmsg_off, tear_off, orig_off, via_off; faddr *o, *bestaka, *ta, *tfaddr; FILE *fp; fa_list *rlist, *tfa, *ftnpath = NULL; int dirtyoutcode = CHRS_NOTSET; struct utsname utsbuf; char MailFrom[128], MailTo[128]; temp = calloc(2048, sizeof(char)); tmsg = &kmsg; tear_off = orig_off = via_off = 0L; rbuf = NULL; if ((fp = tmpfile()) == NULL) { WriteError("$Unable to open temporary file"); free(temp); return 4; } Syslog('m', "Message input start ============="); rewind(pkt); while ((fgets(buf, sizeof(buf)-2, pkt)) != NULL) { /* * Simple test to see how large the buffer must be. 2048 bytes has been seen. */ if (strlen(buf) > (sizeof(buf) /2)) Syslog('+', "Possible bufferoverflow: line read %d bytes", strlen(buf)); if (strlen(buf) > 200) { Syslog('m', "Next line should be %d characters", strlen(buf)); Syslogp('m', printable(buf, 200)); // } else { // Syslogp('m', printable(buf, 0)); } if ((buf[0] == '\1') || !strncmp(buf,"AREA:",5) || !strncmp(buf,"SEEN-BY",7)) { /* This is a kluge line */ waskludge = TRUE; badkludge = FALSE; if (buf[0] == '\1') { l = buf+1; if (!strncmp(l,"AREA:",5) || !strncmp(l,"SEEN-BY",7)) badkludge = TRUE; } else l = buf; if (*l == '\n') badkludge = TRUE; else while (isspace(*l)) l++; if (strncmp(l, "RFC-", 4)) for (p = l; *p; p++) if ((*p != '\n') && (((*p)&0x7f) < ' ')) badkludge = TRUE; p = strchr(l,':'); r = strchr(l,' '); if (p && (!r || (r > p))) r = p; else p = r; if (r == NULL) badkludge = TRUE; else if (!*(p+1) || (*(p+1)=='\n')) badkludge = TRUE; else { c = *r; *r = '\0'; if (strspn(l,KWDCHARS) != strlen(l)) badkludge = TRUE; *r = c; } *tmsg = (rfcmsg *)malloc(sizeof(rfcmsg)); (*tmsg)->next = NULL; if (badkludge) { (*tmsg)->key = xstrcpy((char *)"KLUDGE"); p = printable(l,0); r = p+strlen(p)-2; if (strcmp(r,"\\n") == 0) { *r++ = '\n'; *r = '\0'; } (*tmsg)->val = xstrcpy(p); } else { *r++ = '\0'; while (isspace(*r)) r++; (*tmsg)->key = xstrcpy(l); (*tmsg)->val = xstrcpy(r); } tmsg = &((*tmsg)->next); if (!strcmp(l,"Via") && (via_off == 0L)) { via_off = ftell(fp); Syslog('m', "^AVia \"%s\" at offset %ld", printable(buf, 0), (long)via_off); } } else { /* * this is not a kludge line */ if (waskludge && (isspace(buf[0]))) fputs("\n",fp); /* first body line is not RFC hdr */ waskludge=0; if (!strncmp(buf,PGP_SIGNED_BEGIN, strlen(PGP_SIGNED_BEGIN))) pgpsigned = TRUE; else if ((!strncmp(buf,"---",3)) && ((buf[3] == '\r') || (buf[3] == ' ') || (buf[3] == '\n'))) { tear_off=ftell(fp); if ((hdr((char *)"Tearline",kmsg) == NULL)) { *tmsg=(rfcmsg *)malloc(sizeof(rfcmsg)); (*tmsg)->next=NULL; (*tmsg)->key=xstrcpy((char *)"Tearline"); if (strlen(buf+3) == strspn(buf+3," \t\r\n")) (*tmsg)->val=xstrcpy((char *)"(none)\n"); else (*tmsg)->val=xstrcpy(buf+4); tmsg=&((*tmsg)->next); } Syslog('M', "tearline \"%s\" at offset %ld", buf,(long)tear_off); } else if (!strncmp(buf," * Origin:",10)) { orig_off = ftell(fp); *tmsg = (rfcmsg *)malloc(sizeof(rfcmsg)); (*tmsg)->next = NULL; (*tmsg)->key = xstrcpy((char *)"Origin"); (*tmsg)->val = xstrcpy(buf+11); tmsg = &((*tmsg)->next); Syslog('M', "origin \"%s\" at offset %ld", buf,(long)orig_off); p = buf+10; while (*p == ' ') p++; if ((l = strrchr(p,'(')) && (r = strrchr(p,')')) && (l < r)) { /* * Extract origin address from the Origin line. */ *l = '\0'; *r = '\0'; l++; if ((o = parsefnode(l))) { f->point = o->point; f->node = o->node; f->net = o->net; f->zone = o->zone; if (o->domain) f->domain = o->domain; o->domain = NULL; tidy_faddr(o); } } else { bNeedToGetAddressFromMsgid = !NULL; Syslog('+', "Couldn't find address in origin line (%s of %s, [%s])", f->name, ascfnode(f, 0x1f), hdr((char *)"Origin", kmsg)); if (*(l = p+strlen(p)-1) == '\n') *l = '\0'; } for (l = p+strlen(p)-1; *l == ' '; l--) *l = '\0'; origline = xstrcpy(p); } else if (!strncmp(buf," * Message split",16)) { *tmsg = (rfcmsg *)malloc(sizeof(rfcmsg)); (*tmsg)->next = NULL; (*tmsg)->key = xstrcpy((char *)"Split"); (*tmsg)->val = xstrcpy((char *)"already\n"); tmsg=&((*tmsg)->next); Syslog('m', "Split indicator found"); } fputs(buf,fp); } } Syslog('m', "Message input end ==============="); if (bNeedToGetAddressFromMsgid && (p = hdr((char *)"MSGID", kmsg))) { Syslog('m', "Need To Get Address From Msgid start..."); l = p; while(isspace(*l) && *l) l++; r = strchr(l, ' '); if(r) { *r-- = '\0'; while(isspace(*r) && *r) r--; } if (l && r && l > r) { if ((o = parsefnode(l))) { f->point = o->point; f->node = o->node; f->net = o->net; f->zone = o->zone; if (o->domain) f->domain = o->domain; o->domain = NULL; tidy_faddr(o); Syslog('+', "Origin from: %s (src MSGID)", ascfnode(f,0x7f)); } } } endmsg_off=ftell(fp); if ((tear_off) && (tear_off < endmsg_off)) endmsg_off = tear_off; if ((orig_off) && (orig_off < endmsg_off)) endmsg_off = orig_off; if ((via_off) && (via_off < endmsg_off)) endmsg_off = via_off; Syslog('M', "end message offset %ld",(long)endmsg_off); rewind(fp); msg = parsrfc(fp); bestaka = bestaka_s(f); rewind(fp); p = hdr((char *)"CHRS", kmsg); if (p == NULL) p = hdr((char *)"CHARSET", kmsg); if (p == NULL) p = hdr((char *)"CODEPAGE", kmsg); if (p) outcode = readchrs(p); else { p=hdr((char *)"Content-Type",msg); if (p == NULL) p=hdr((char *)"RFC-Content-Type",kmsg); if (p == NULL) p=hdr((char *)"Content-Type",kmsg); if (p) outcode=readcharset(p); else { q = rfcmsgid(hdr((char *)"MSGID",kmsg),bestaka); Syslog('m', "start headers checking 1j"); if ((hdr((char *)"Message-ID",msg)) || (hdr((char *)"RFC-Message-ID",kmsg)) || (hdr((char *)"Message-ID",kmsg)) || (hdr((char *)"RFCID",kmsg)) || (hdr((char *)"ORIGID",kmsg)) || ((hdr((char *)"MSGID",kmsg)) && (!chkftnmsgid(q)))) outcode = defaultrfcchar; else outcode = defaultftnchar; if (q) free(q); q = NULL; } } /* * A hack for TerMail */ p = hdr((char *)"PID", kmsg); if ((p) && (!strncmp(p, "TerMail", 7)) && (outcode == defaultrfcchar)) outcode = defaultftnchar; if (dirtyoutcode != CHRS_NOTSET) outcode = dirtyoutcode; if (pgpsigned) incode = outcode; if (kmsg && !strcmp(kmsg->key,"AREA")) { /* * The msgs record is already loaded. */ newsgroup = xstrcpy(msgs.Newsgroup); if (strlen(msgs.Distribution)) distribution = xstrcpy(msgs.Distribution); if (strlen(msgs.Moderator)) { moderator = xstrcpy(msgs.Moderator); if (msgs.MsgKinds == USEMOD) modtype = 1; } Syslog('m', "newsgroup %s, distribution %s, moderator %s modtype %d", printable(newsgroup, 0), printable(distribution, 0), printable(moderator, 0), modtype); newsmode = TRUE; if ((modtype == 1) && (!hdr((char *)"Approved",msg)) && (!hdr((char *)"RFC-Approved",kmsg)) && (!hdr((char *)"Approved",kmsg))) newsmode = TRUE; } else newsmode = FALSE; Syslog('m', "Got %s message", newsmode?"echo":"netmail"); if ((outcode == CHRS_NOTSET) && (hdr((char *)"MSGID", kmsg))) { p = rfcmsgid(hdr((char *)"MSGID",kmsg),bestaka); if ((hdr((char *)"Message-ID",msg)) || (hdr((char *)"RFC-Message-ID",kmsg)) || (hdr((char *)"Message-ID",kmsg)) || (hdr((char *)"RFCID",kmsg)) || (hdr((char *)"ORIGID",kmsg)) || ((hdr((char *)"MSGID",kmsg)) && (!chkftnmsgid(p)))) outcode = defaultrfcchar; else outcode = defaultftnchar; free(p); } if (pgpsigned) incode = outcode; else if (incode == CHRS_NOTSET) incode = getincode(outcode); /* * fsc-0038 defines "^aDOMAIN: othernet 99:12/34 fidonet 2:293/2219" */ if ((p=hdr((char *)"DOMAIN",kmsg)) && (!strchr(p,'@'))) { strncpy(buf,p,sizeof(buf)-1); buf[sizeof(buf)-1]='\0'; l=strtok(buf," \n"); p=strtok(NULL," \n"); r=strtok(NULL," \n"); q=strtok(NULL," \n"); if ((ta=parsefnode(p))) { t->point=ta->point; t->node=ta->node; t->net=ta->net; t->zone=ta->zone; tidy_faddr(ta); } t->domain=xstrcpy(l); if ((ta=parsefnode(q))) { f->point=ta->point; f->node=ta->node; f->net=ta->net; f->zone=ta->zone; tidy_faddr(ta); } f->domain=xstrcpy(r); } else if ((p=hdr((char *)"INTL",kmsg))) { strncpy(buf,p,sizeof(buf)-1); buf[sizeof(buf)-1]='\0'; l=strtok(buf," \n"); r=strtok(NULL," \n"); if ((ta=parsefnode(l))) { t->point=ta->point; t->node=ta->node; t->net=ta->net; t->zone=ta->zone; if (ta->domain) { if (t->domain) free(t->domain); t->domain=ta->domain; ta->domain=NULL; } tidy_faddr(ta); } if ((ta=parsefnode(r))) { f->point=ta->point; f->node=ta->node; f->net=ta->net; f->zone=ta->zone; if (ta->domain) { if (f->domain) free(f->domain); f->domain=ta->domain; ta->domain=NULL; } tidy_faddr(ta); } } /* * fidogate generates "^aDOMAIN: Z2@fidonet" */ if ((f->domain==NULL) && ((p=hdr((char *)"DOMAIN",kmsg)) && (q=strchr(p,'@')))) { *q='\0'; f->domain=xstrcpy(q+1); *q='@'; } if ((p=hdr((char *)"FMPT",kmsg))) f->point=atoi(p); if ((p=hdr((char *)"TOPT",kmsg))) t->point=atoi(p); Syslog('m', "final from: %s",ascfnode(f,0xff)); Syslog('m', "final to: %s",ascfnode(t,0xff)); if (!newsmode) { p=hdr((char *)"Resent-To",msg); if (p == NULL) p=hdr((char *)"To",msg); if (p == NULL) p=hdr((char *)"RFC-Resent-To",kmsg); if (p == NULL) p=hdr((char *)"RFC-To",kmsg); if (p && is_local(t)) { while (*p == ' ') p++; strncpy(buf, p, sizeof(buf) -1); if (*(p = buf + strlen(buf) -1) == '\n') *p='\0'; } else if (modtype == 1) sprintf(buf,"%s",moderator); else sprintf(buf,"%s",ascinode(t,0x7f)); substitute(buf); Syslog('+', "mail from %s to %s",ascfnode(f,0x7f),buf); To = xstrcpy(buf); } if (!newsmode) { Syslog('m', "Preparing email"); // if (p) // free(p); p = NULL; p = hdr((char *)"Return-Path",msg); if (p == NULL) p=hdr((char *)"RFC-Return-Path",kmsg); if (p == NULL) p=hdr((char *)"Return-Path",kmsg); if (p) sprintf(MailFrom, "%s", p); else sprintf(MailFrom, "%s", ascinode(f,0x7f)); Syslog('m', "MailFrom: %s", MailFrom); if (To) sprintf(MailTo, "%s", To); else sprintf(MailTo, "%s", t->name); Syslog('m', "MailTo: %s", MailTo); /* * Because we need the same stream for news and email * we need to check if the newsfile is already open. */ if (newsopen) { fclose(nfp); newsopen = FALSE; } if ((nfp = tmpfile()) == NULL) { WriteError("$Unable to open temporary file"); return 4; } Syslog('m', "Prepare is ready"); if (modtype == 1) newsmode = TRUE; } if (newsmode) { /* * Open temporary newsfile, append messages if it already exists. */ if (!newsopen) { p = calloc(PATH_MAX, sizeof(char)); sprintf(p, "%s/tmp/newsout", getenv("MBSE_ROOT")); if ((nfp = fopen(p, "a")) == NULL) { WriteError("$Can't open %s", p); free(p); return 2; } free(p); newsopen = TRUE; } if ((p=hdr((char *)"Path",msg)) == NULL) p=hdr((char *)"RFC-Path",kmsg); rlist=NULL; fill_rlist(&rlist, p); for (qmsg = kmsg; qmsg; qmsg = qmsg->next) if (strcasecmp(qmsg->key, "SPTH") == 0) fill_list(&ftnpath, qmsg->val, &rlist); for (qmsg = kmsg; qmsg; qmsg = qmsg->next) if (strcasecmp(qmsg->key, "PATH") == 0) fill_list(&ftnpath, qmsg->val, &rlist); tidy_falist(&rlist); /* * Build Path: headerline */ q = xstrcpy((char *)"Path: "); if (CFG.newsfeed == FEEDUUCP) { /* * If we don't run our own newsserver we have to simulate and * add the UUCP nodename here. */ memset(&utsbuf, 0, sizeof(utsbuf)); if (uname(&utsbuf)) { WriteError("Can't get system nodename"); } else { q = xstrcat(q, utsbuf.nodename); q = xstrcat(q, (char *)"!"); } } tfaddr = fido2faddr(msgs.Aka); q = xstrcat(q, ascinode(tfaddr, 0x07)); tidy_faddr(tfaddr); q = xstrcat(q, (char *)"!"); if (ftnpath) for (tfa=ftnpath->next;tfa;tfa=tfa->next) { /* FIXME: possible memory leak */ q = xstrcat(q, ascinode(tfa->addr,0x1f)); q = xstrcat(q, (char *)"!"); } tidy_falist(&ftnpath); if (p) { while (isspace(*p)) p++; q = xstrcat(q, p); } else q = xstrcat(q, (char *)"not-for-mail"); Send(newsmode, "%s\n", q); if ((p = hdr((char *)"Newsgroups",msg))) { /* * The gate at puddle.fidonet.org put spaces in Newsgroups header */ if ((strstr(p,", "))) { while ((r = strchr(p, ' '))) { *r = '\0'; strcat(p,r+1); } } } if (p == NULL) p=hdr((char *)"RFC-Newsgroups",kmsg); if (p == NULL) p=hdr((char *)"Newsgroups",kmsg); if (p) { while (*p && isspace(*p)) p++; Send(newsmode,"Newsgroups: %s\n",newsgroup); Send(newsmode,"X-Origin-Newsgroups: %s",p); } else Send(newsmode,"Newsgroups: %s\n",newsgroup); if ((p=hdr((char *)"Distribution",msg))) Send(newsmode,"Distribution:%s",p); else if ((p=hdr((char *)"RFC-Distribution",kmsg))) Send(newsmode,"Distribution: %s",p); else if ((p=hdr((char *)"Distribution",kmsg))) Send(newsmode,"Distribution: %s",p); else if (distribution) Send(newsmode,"Distribution: %s\n",distribution); p = hdr((char *)"Comment-To",msg); if (p == NULL) p=hdr((char *)"X-Comment-To",msg); if (p == NULL) p=hdr((char *)"To",msg); if ((p) && (strcasecmp(p,"All\n"))) Send(newsmode,"X-Comment-To:%s",hdrconv(p,outcode,incode)); else { if (p == NULL) p=hdr((char *)"RFC-X-Comment-To",kmsg); if (p == NULL) p=hdr((char *)"RFC-Comment-To",kmsg); if (p == NULL) p=hdr((char *)"RFC-To",kmsg); if ((p) && (strcasecmp(p,"All\n"))) Send(newsmode,"X-Comment-To: %s",hdrconv(p,outcode,incode)); else if ((t) && (t->name) && (strcasecmp(t->name,"All"))) Send(newsmode,"X-Comment-To: %s\n",hdrconv(t->name,outcode,incode)); else Send(newsmode,"X-Comment-To: All\n"); } // for (tmpml=approve;tmpml;tmpml=tmpml->next) { // if ((strncmp(newsgroup,tmpml->prefix, strlen(tmpml->prefix)) == 0)) { // modtype=2; // moderator=xstrcpy(tmpml->address); // break; // } // } if ((p=hdr((char *)"Approved",msg))) Send(newsmode,"Approved:%s",p); else if ((p=hdr((char *)"RFC-Approved",kmsg))) Send(newsmode,"Approved: %s",p); else if ((p=hdr((char *)"Approved",kmsg))) Send(newsmode,"Approved: %s",p); else if (modtype==2) Send(newsmode,"Approved: %s\n",moderator); } else { /* if newsmode */ time(&now); if (CFG.EmailMode == E_NOISP) { /* * Probaly not needed as messages for systems without ISP never get here. * Perhaps only news to moderators. */ Send(FALSE, "From: %s!", ascinode(f,0x3f)); Send(FALSE, "%s %s", ascinode(f,0x40), ctime(&mdate)); } for (qmsg = kmsg; qmsg; qmsg = qmsg->next) if (!strcasecmp(qmsg->key,"RFC-Received")) Send(FALSE, "%s: %s", qmsg->key+4, qmsg->val); for (qmsg = msg; qmsg; qmsg = qmsg->next) if (!strcasecmp(qmsg->key,"Received")) Send(FALSE, "%s:%s", qmsg->key, qmsg->val); if ((p=hdr((char *)"Apparently-To",msg))) Send(FALSE, "Apparently-To: %s\n",p); else if ((p=hdr((char *)"RFC-Apparently-To",kmsg))) Send(FALSE, "Apparently-To: %s\n",p); else if ((p=hdr((char *)"Apparently-To",kmsg))) Send(FALSE, "Apparently-To: %s\n",p); else if ((is_local(t))) Send(FALSE, "Apparently-To: %s\n",buf); if (flags & M_RRQ) rrq=TRUE; else rrq=FALSE; if (rrq && !hdr((char *)"RFC-Return-Receipt-To",kmsg) && !hdr((char *)"Return-Receipt-To",msg) && !hdr((char *)"RFC-Notice-Requested-Upon-Delivery-To",kmsg) && !hdr((char *)"Notice-Requested-Upon-Delivery-To",msg)) { Send(FALSE,"Notice-Requested-Upon-Delivery-To: %s\n",buf); } if (t->name == NULL) t->name=xstrcpy((char *)"Postmaster"); p=hdr((char *)"Resent-To",msg); if (p == NULL) p=hdr((char *)"To",msg); if (p) { Send(FALSE,"To:%s",p); } else { if (p == NULL) p=hdr((char *)"RFC-Resent-To",kmsg); if (p == NULL) p=hdr((char *)"RFC-To",kmsg); if (p) { Syslog('m', "2"); Send(FALSE,"To: %s\n",p); } else if (modtype == 1) Send(FALSE,"To: %s\n",moderator); else if (is_local(t)) { Syslog('m', "3"); Send(FALSE, "To: %s <%s>\n", t->name, buf); } else { Syslog('m', "4"); Send(FALSE,"To: %s\n",ascinode(t,0xff)); } } } if ((p = hdr((char *)"From",msg))) { Send(newsmode, "From:%s", hdrconv(p,outcode,incode)); } else if ((p = hdr((char *)"RFC-From",kmsg))) { Syslog('m', "b"); Send(newsmode, "From: %s", hdrconv(p,outcode,incode)); } else if ((p = hdr((char *)"From\n",kmsg))) { Syslog('m', "c"); Send(newsmode, "From: %s", hdrconv(p,outcode,incode)); } else if ((p = hdr((char *)"X-PcBoard-FROM",msg))) { if (f->name) { while (isspace(*p)) p++; p[strlen(p)-1] = '\0'; Send(newsmode,"From: %s <%s>\n", hdrconv(f->name,outcode,incode), p); } else { Send(newsmode,"From:%s\n", p); } } else if ((hdr((char *)"REPLYADDR",kmsg)) && (p=xstrcpy(hdr((char *)"REPLYADDR",kmsg)))) { if (*(r=p+strlen(p)-1) == '\n') *(r--)='\0'; while (isspace(*r)) *(r--)='\0'; q=xstrcpy(hdr((char *)"X-RealName",msg)); if (q == NULL) q=xstrcpy(hdr((char *)"RealName",msg)); if (q == NULL) q=xstrcpy(hdr((char *)"X-RealName",kmsg)); if (q == NULL) q=xstrcpy(hdr((char *)"RealName",kmsg)); if (q) { if (*(r=q+strlen(q)-1) == '\n') *(r--)='\0'; while (isspace(*r)) *(r--)='\0'; for (l=q; isspace(*l); ) l++; if ((*l == '\"') && (*r == '\"')) { l++; *r--='\0'; } Syslog('m', "d"); Send(newsmode,"From: \"%s\" <%s>\n",hdrconv(l,outcode,incode),p); free(q); } else if (f->name) { Syslog('m', "e"); Send(newsmode,"From: \"%s\" <%s>\n",hdrconv(f->name,outcode,incode),p); } else { Syslog('m', "f"); Send(newsmode,"From: %s\n",p); } free(p); } if (p) Send(newsmode,"X-FTN-Sender: %s\n",hdrconv(ascinode(f,0xff),outcode,incode)); else Send(newsmode,"From: %s\n",hdrconv(ascinode(f,0xff),outcode,incode)); if ((p=hdr((char *)"Reply-To",msg))) Send(newsmode,"Reply-To:%s",p); else if ((p=hdr((char *)"RFC-Reply-To",kmsg))) Send(newsmode,"Reply-To: %s",p); else if ((p=hdr((char *)"Reply-To",kmsg))) Send(newsmode,"Reply-To: %s",p); else if (((p=backalias(f))) && strlen(CFG.sysdomain)) Send(newsmode,"Reply-To: %s@%s\n",p,CFG.sysdomain); else if ((p=hdr((char *)"REPLYADDR",kmsg))) Send(newsmode,"Reply-To: %s",p); else if ((p=hdr((char *)"REPLYTO",kmsg))) Send(newsmode,"Reply-To: %s\n",ascinode(parsefaddr(p),0xff)); if ((p=hdr((char *)"Date",msg))) Send(newsmode,"Date:%s",p); else if ((p=hdr((char *)"RFC-Date",kmsg))) Send(newsmode,"Date: %s",p); else if ((p=hdr((char *)"Date",kmsg))) Send(newsmode,"Date: %s",p); else if (newsmode) { /* * Restamp future postings */ if(mdate > time(&now)) { Syslog('+', "Future posting: %s", rfcdate(mdate)); Send(newsmode,"Date: %s\n", rfcdate(now)); Send(newsmode,"X-Origin-Date: %s\n", rfcdate(mdate)); } else if((mdate < time(&now)-14*24*60*60) && (mdate > time(&now)-RESTAMP_OLD_POSTINGS*24*60*60)) { /* * Restamp old postings */ Syslog('+', "Article too old, restamped: %s", rfcdate(mdate)); Send(newsmode,"Date: %s\n", rfcdate(now)); Send(newsmode,"X-Origin-Date: %s\n", rfcdate(mdate)); } else Send(newsmode,"Date: %s\n",rfcdate(mdate)); } else Send(newsmode,"Date: %s\n",rfcdate(mdate)); if ((p = hdr((char *)"Subject",msg))) Send(newsmode, "Subject:%s", hdrconv(p,outcode,incode)); else if ((p = hdr((char *)"RFC-Subject",kmsg))) Send(newsmode, "Subject: %s", hdrconv(p,outcode,incode)); else if ((p = hdr((char *)"Subject",kmsg))) Send(newsmode, "Subject: %s", hdrconv(p,outcode,incode)); else if ((p = hdr((char *)"X-PcBoard-SUBJECT",msg))) Send(newsmode, "Subject:%s", hdrconv(p,outcode,incode)); else if (subj && (strspn(subj," \t\n\r") != strlen(subj))) Send(newsmode, "Subject: %s\n", hdrconv(subj,outcode,incode)); else Send(newsmode, "Subject: \n"); if ((p=hdr((char *)"Message-ID",msg))) Send(newsmode,"Message-ID:%s",p); else if ((p=hdr((char *)"RFC-Message-ID",kmsg))) Send(newsmode,"Message-ID: %s",p); else if ((p=hdr((char *)"Message-ID",kmsg))) Send(newsmode,"Message-ID: %s",p); else if ((p=hdr((char *)"RFCID",kmsg))) if ((p[0]=='<')) { /* "^aRFCID: " */ if ((p[strlen(p)-2]=='>')) Send(newsmode,"Message-ID: %s",p); /* "^aRFCID: \n",p); } } /* "^aRFCID: local@machine" */ else { p[strlen(p)-1]='\0'; Send(newsmode,"Message-ID: <%s>\n",p); } else if ((p=hdr((char *)"ORIGID",kmsg))) Send(newsmode,"Message-ID: %s",p); else if ((p = hdr((char *)"MSGID",kmsg))) { q = rfcmsgid(p, bestaka); Send(newsmode,"Message-ID: %s\n", q); free(q); } else Send(newsmode,"Message-ID: <%lu@%s.ftn>\n", mdate^(subj?str_crc32(subj):0L), ascinode(f,0x1f)); if (newsmode) { if ((p=hdr((char *)"References",msg))) Send(newsmode,"References:%s",p); else if ((p=hdr((char *)"RFC-References",kmsg))) Send(newsmode,"References: %s",p); else if ((p=hdr((char *)"References",kmsg))) Send(newsmode,"References: %s",p); else if ((p=hdr((char *)"ORIGREF",kmsg))) Send(newsmode,"References: %s",p); else if ((p=hdr((char *)"REPLY",kmsg))) { q = rfcmsgid(p, bestaka); Send(newsmode,"References: %s\n", q); free(q); } } else { if ((p=hdr((char *)"In-Reply-To",msg))) Send(newsmode,"In-Reply-To:%s",p); else if ((p=hdr((char *)"RFC-In-Reply-To",kmsg))) Send(newsmode,"In-Reply-To: %s",p); else if ((p=hdr((char *)"REPLY",kmsg))) { q = rfcmsgid(p,bestaka); Send(newsmode,"In-Reply-To: %s\n", q); free(q); } } if ((p=hdr((char *)"Organization",msg))) Send(newsmode,"Organization:%s",hdrconv(p,outcode,incode)); else if ((p=hdr((char *)"Organisation",msg))) Send(newsmode,"Organization:%s",hdrconv(p,outcode,incode)); else if ((p=hdr((char *)"RFC-Organization",kmsg))) Send(newsmode,"Organization: %s",hdrconv(p,outcode,incode)); else if ((p=hdr((char *)"RFC-Organisation",kmsg))) Send(newsmode,"Organization: %s",hdrconv(p,outcode,incode)); else if ((p=hdr((char *)"Organization",kmsg))) Send(newsmode,"Organization: %s",hdrconv(p,outcode,incode)); else if ((p=hdr((char *)"Organisation",kmsg))) Send(newsmode,"Organization: %s",hdrconv(p,outcode,incode)); else if (origline) Send(newsmode,"Organization: %s\n",hdrconv(origline,outcode,incode)); if ((p=hdr((char *)"Supersedes",msg))) Send(newsmode,"Supersedes:%s",p); else if ((p=hdr((char *)"RFC-Supersedes",kmsg))) Send(newsmode,"Supersedes: %s",p); else if ((p=hdr((char *)"Supersedes",kmsg))) Send(newsmode,"Supersedes: %s",p); else if ((p=hdr((char *)"ACUPDATE",kmsg)) && (strstr(p,"MODIFY"))) { q = rfcmsgid(p+8,bestaka); Send(newsmode,"Supersedes: %s\n", q); free(q); } if (CFG.allowcontrol) { if ((p=hdr((char *)"Control",msg))) Send(newsmode,"Control:%s",p); else if ((p=hdr((char *)"RFC-Control",kmsg))) Send(newsmode,"Control: %s",p); else if ((p=hdr((char *)"Control",kmsg))) Send(newsmode,"Control: %s",p); else if ((p=hdr((char *)"ACUPDATE",kmsg)) && (strstr(p,"DELETE"))) { q = rfcmsgid(p+8,bestaka); Send(newsmode,"Control: cancel %s\n", q); free(q); } } Send(newsmode, "X-FTN-CHRS: %s\n", getchrs(incode)); if (incode != outcode) Send(newsmode, "X-FTN-ORIGCHRS: %s\n", getchrs(outcode)); charset = getcharset(incode); if ((p=hdr((char *)"Mime-Version",msg))) Send(newsmode,(char *)"Mime-Version:%s",p); else if ((p=hdr((char *)"RFC-Mime-Version",kmsg))) Send(newsmode,(char *)"Mime-Version: %s",p); else if ((p=hdr((char *)"Mime-Version",kmsg))) Send(newsmode,(char *)"Mime-Version: %s",p); else if ((charset) && (incode != CHRS_NOTSET)) Send(newsmode,"Mime-Version: 1.0\n"); temp[0] = '\0'; if ((p=hdr((char *)"Content-Type",msg))) Send(newsmode,"Content-Type:%s",p); else if ((p=hdr((char *)"RFC-Content-Type",kmsg))) Send(newsmode,"Content-Type: %s",p); else if ((p=hdr((char *)"Content-Type",kmsg))) Send(newsmode,"Content-Type: %s",p); else if ((charset) && (incode != CHRS_NOTSET)) { if ((p=hdr((char *)"FSCHTML",kmsg)) || (p=hdr((char *)"HTML",kmsg))) Send(newsmode,"Content-Type: text/html; charset=%s\n",charset); else Send(newsmode,"Content-Type: text/plain; charset=%s\n",charset); } if ((p=hdr((char *)"Content-Length",msg))) Send(newsmode,"Content-Length%s",p); else if ((p=hdr((char *)"RFC-Content-Length",kmsg))) Send(newsmode,"Content-Length: %s",p); else if ((p=hdr((char *)"Content-Length",kmsg))) Send(newsmode,"Content-Length: %s",p); temp[0] = '\0'; if ((p=hdr((char *)"Content-Transfer-Encoding",msg))) sprintf(temp,"Content-Transfer-Encoding:%s",p); else if ((p=hdr((char *)"RFC-Content-Transfer-Encoding",kmsg))) sprintf(temp,"Content-Transfer-Encoding: %s",p); else if ((p=hdr((char *)"Content-Transfer-Encoding",kmsg))) sprintf(temp,"Content-Transfer-Encoding: %s",p); else if ((charset) && (incode == CHRS_ISO_8859_1_QP)) sprintf(temp,"Content-Transfer-Encoding: quoted-printable\n"); else if ((charset) && (incode != CHRS_NOTSET)) { if ((incode == CHRS_ASCII || incode == CHRS_UTF_7)) sprintf(temp,"Content-Transfer-Encoding: 7bit\n"); else if (strncasecmp(charset,"iso-2022-",9) == 0) sprintf(temp,"Content-Transfer-Encoding: 7bit\n"); else sprintf(temp,"Content-Transfer-Encoding: 8bit\n"); /* all others are 8 bit */ } if (temp[0]) Send(newsmode, temp); if (newsmode) { if ((p=hdr((char *)"X-Newsreader",msg))) Send(newsmode,"X-Newsreader: %s",p); else if ((p=hdr((char *)"RFC-X-Newsreader",kmsg))) Send(newsmode,"X-Newsreader: %s",p); else if ((p=hdr((char *)"X-Newsreader",kmsg))) Send(newsmode,"X-Newsreader: %s",p); else if ((p=hdr((char *)"PID",kmsg))) Send(newsmode,"X-Newsreader: %s",p); } else { if ((p=hdr((char *)"X-Mailer",msg))) Send(newsmode,"X-Mailer:%s",p); else if ((p=hdr((char *)"RFC-X-Mailer",kmsg))) Send(newsmode,"X-Mailer: %s",p); else if ((p=hdr((char *)"X-Mailer",kmsg))) Send(newsmode,"X-Mailer: %s",p); else if ((p=hdr((char *)"PID",kmsg))) Send(newsmode,"X-Mailer: %s",p); } for (qmsg=msg;qmsg;qmsg=qmsg->next) { if (strcasecmp(qmsg->key,"X-Body-Start") && strcasecmp(qmsg->key,"X-PcBoard-FROM") && strcasecmp(qmsg->key,"X-PcBoard-SUBJECT") && strcasecmp(qmsg->key,"X-PcBoard-PACKOUT") && (strcasecmp(qmsg->key,"Control") || !CFG.allowcontrol) && strcasecmp(qmsg->key,"Supersedes") && strcasecmp(qmsg->key,"Mime-Version") && strcasecmp(qmsg->key,"Content-Type") && strcasecmp(qmsg->key,"Content-Lenght") && strcasecmp(qmsg->key,"Content-Transfer-Encoding") && strcasecmp(qmsg->key,"Lines") && strcasecmp(qmsg->key,"Path") && strcasecmp(qmsg->key,"Received") && strcasecmp(qmsg->key,"From") && strcasecmp(qmsg->key,"To") && strcasecmp(qmsg->key,"Comment-To") && strcasecmp(qmsg->key,"X-Comment-To") && strcasecmp(qmsg->key,"Date") && strcasecmp(qmsg->key,"Subject") && strcasecmp(qmsg->key,"Reply-To") && strcasecmp(qmsg->key,"In-Reply-To") && strcasecmp(qmsg->key,"References") && strcasecmp(qmsg->key,"Organization") && strcasecmp(qmsg->key,"Organisation") && strcasecmp(qmsg->key,"X-Mailer") && strcasecmp(qmsg->key,"X-Newsreader") && (strcasecmp(qmsg->key,"Newsgroups") || !newsmode) && strcasecmp(qmsg->key,"Apparently-To") && strcasecmp(qmsg->key,"Distribution") && strcasecmp(qmsg->key,"Approved") && strcasecmp(qmsg->key,"Message-ID")) Send(newsmode,"%s:%s",qmsg->key,hdrconv(qmsg->val,outcode,incode)); } if ((p=compose_flags(flags,hdr((char *)"FLAGS",kmsg)))) { Send(newsmode,"X-FTN-FLAGS:%s\n",p); free(p); } for (qmsg=kmsg;qmsg;qmsg=qmsg->next) { if (strcasecmp(qmsg->key,"INTL") && strcasecmp(qmsg->key,"FMPT") && strcasecmp(qmsg->key,"TOPT") && strcasecmp(qmsg->key,"FLAGS") && strcasecmp(qmsg->key,"CHARSET") && strcasecmp(qmsg->key,"CHRS") && strcasecmp(qmsg->key,"CODEPAGE") && strcasecmp(qmsg->key,"ORIGCHRS") && /* * RFC: is used by fidogate to tell how completly RFC headers were * gated (0=no headers at all; 1=some headers; 2=all headers) */ strcasecmp(qmsg->key,"RFC") && strcasecmp(qmsg->key,"RFCID") && strcasecmp(qmsg->key,"ORIGID") && strcasecmp(qmsg->key,"ORIGREF") && strcasecmp(qmsg->key,"X-GATEWAY") && strcasecmp(qmsg->key,"Lines") && /* strcmp(qmsg->key,"Path") && */ strcasecmp(qmsg->key,"PATH") && strcasecmp(qmsg->key,"Received") && strcasecmp(qmsg->key,"From") && strcasecmp(qmsg->key,"To") && strcasecmp(qmsg->key,"Comment-To") && strcasecmp(qmsg->key,"X-Comment-To") && strcasecmp(qmsg->key,"Date") && strcasecmp(qmsg->key,"Subject") && strcasecmp(qmsg->key,"Reply-To") && strcasecmp(qmsg->key,"In-Reply-To") && strcasecmp(qmsg->key,"References") && strcasecmp(qmsg->key,"Organization") && strcasecmp(qmsg->key,"Organisation") && strcasecmp(qmsg->key,"X-Mailer") && strcasecmp(qmsg->key,"X-Newsreader") && (strcasecmp(qmsg->key,"Newsgroups") || !newsmode) && strcasecmp(qmsg->key,"Apparently-To") && strcasecmp(qmsg->key,"Message-ID") && strcasecmp(qmsg->key,"Mime-Version") && strcasecmp(qmsg->key,"Content-Type") && strcasecmp(qmsg->key,"Content-Lenght") && strcasecmp(qmsg->key,"Content-Transfer-Encoding") && (strcasecmp(qmsg->key,"RFC-Control") || !CFG.allowcontrol) && strcasecmp(qmsg->key,"RFC-Supersedes") && strcasecmp(qmsg->key,"RFC-Mime-Version") && strcasecmp(qmsg->key,"RFC-Content-Type") && strcasecmp(qmsg->key,"RFC-Content-Lenght") && strcasecmp(qmsg->key,"RFC-Content-Transfer-Encoding") && strcasecmp(qmsg->key,"RFC-Lines") && strcasecmp(qmsg->key,"RFC-Path") && strcasecmp(qmsg->key,"RFC-Received") && strcasecmp(qmsg->key,"RFC-From") && strcasecmp(qmsg->key,"RFC-To") && strcasecmp(qmsg->key,"RFC-Comment-To") && strcasecmp(qmsg->key,"RFC-X-Comment-To") && strcasecmp(qmsg->key,"RFC-Date") && strcasecmp(qmsg->key,"RFC-Subject") && strcasecmp(qmsg->key,"RFC-Reply-To") && strcasecmp(qmsg->key,"RFC-In-Reply-To") && strcasecmp(qmsg->key,"RFC-References") && strcasecmp(qmsg->key,"RFC-Organization") && strcasecmp(qmsg->key,"RFC-X-Mailer") && strcasecmp(qmsg->key,"RFC-X-Newsreader") && (strcasecmp(qmsg->key,"RFC-Newsgroups") || !newsmode) && strcasecmp(qmsg->key,"RFC-Apparently-To") && strcasecmp(qmsg->key,"RFC-Distribution") && strcasecmp(qmsg->key,"RFC-Approved") && strcasecmp(qmsg->key,"RFC-Message-ID")) { if (!strncmp(qmsg->key,"RFC-",4)) Send(newsmode,"%s: %s",qmsg->key+4,hdrconv(qmsg->val,outcode,incode)); else if ((!strncasecmp(qmsg->key,"X-",2)) || (!strncasecmp(qmsg->key,"NNTP-",5))) Send(newsmode,"%s: %s",qmsg->key,hdrconv(qmsg->val,outcode,incode)); else if ((!strncasecmp(qmsg->key,"ZC-",3))) Send(newsmode,"X-%s: %s",qmsg->key,qmsg->val); else if ((!strcasecmp(qmsg->key,"Origin")) || (!strcasecmp(qmsg->key,"MOOD"))) Send(newsmode,"X-FTN-%s: %s",qmsg->key,hdrconv(qmsg->val,outcode,incode)); else Send(newsmode,"X-FTN-%s: %s",qmsg->key,qmsg->val); } } if (newsmode) { fa_list *tmpl,*ptl=NULL; char sbe[16]; int seenlen=0,oldnet; for (qmsg = kmsg; qmsg; qmsg = qmsg->next) if (!strcmp(qmsg->key, "PATH")) { fill_path(&ptl, qmsg->val); } uniq_list(&ptl); /* * ensure it will not match for the first entry */ oldnet = ptl->addr->net-1; q = xstrcpy((char*)"X-FTN-PATH:"); for (tmpl = ptl; tmpl; tmpl = tmpl->next) { if (tmpl->addr->net == oldnet) sprintf(sbe," %u",tmpl->addr->node); else sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node); oldnet=tmpl->addr->net; seenlen+=strlen(sbe); if (seenlen > MAXPATH) { seenlen=0; Send(newsmode, "%s\n", q); free(q); q = xstrcpy((char *)"X-FTN-PATH:"); sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node); seenlen=strlen(sbe); } q = xstrcat(q, sbe); } Send(newsmode,"%s\n", q); free(q); tidy_falist(&ptl); if ((hdr((char *)"X-FTN-SPTH", msg))) Send(newsmode,"X-FTN-SPTH: %s\n", ascfnode(bestaka,0x1f)); } /* * Search past RFC headers. */ while (fgets(buf,sizeof(buf)-1,fp)) { if ((strlen(buf) == 1) && (buf[0] == '\n')) { break; } } /* * Send the message body */ pass=1; count = lines = 0; first = TRUE; Syslog('M', "Start sending message body"); while (fgets(buf,sizeof(buf)-1,fp) && pass) { if (first) { Send(newsmode, (char *)"\n"); first = FALSE; /* FIXME: Maybe scan now for repeating headers and drop them as they will appear in the message text */ if ((p=hdr((char *)"X-Body-Start",msg))) { lines++; Send(newsmode, "%s", strkconv(p, outcode, incode)); } } if (ftell(fp) > endmsg_off) { Syslog('M', "line \"%s\" past message end %ld %ld", buf,(long)endmsg_off, ftell(fp)); pass=0; } if (pass) { p=buf; b=NULL; while ((c=*p++)) { switch (c) { case ' ': b=p-1; break; case '\n': b=NULL; count=0; lines++; break; } if ((count++ > BOUNDARY) && (!pgpsigned)) { if (b) { *b++='\r'; *b = '\n'; p=b+2; b=NULL; lines++; count=0; } } } if (strncmp(buf, ".\r\n", 3)) Send(newsmode, strkconv(buf, outcode, incode)); else Send(newsmode, (char *)" .\n"); } } Syslog('M', "End sending message body"); if ((modtype==1) && (!hdr((char *)"Approved",msg)) && (!hdr((char *)"RFC-Approved",kmsg)) && (!hdr((char *)"Approved",kmsg))) newsmode = FALSE; tidyrfc(msg); fclose(fp); tidyrfc(kmsg); if (!newsmode) { result = postemail(nfp, MailFrom, MailTo); fclose(nfp); } else { news_in++; /* * The newsfile stays open and will be closed later after processing * all echomail. */ fprintf(nfp, ".\n"); } // if (p) Geeft segfault // free(p); if (newsgroup) free(newsgroup); if (distribution) free(distribution); if (moderator) free(moderator); rbuf = NULL; free(temp); return result; }