/***************************************************************************** * * File ..................: mbmail/message.c * Purpose ...............: MBSE BBS Mail Gate * Last modification date : 27-Jul-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/common.h" #include "../lib/clcomm.h" #include "../lib/dbcfg.h" #include "../lib/dbuser.h" /* ### Modified by P.Saratxaga on 7 Aug 1995 ### * - Newsgroups: line is now gated if there is more than one newsgroup * - Added support for X-FTN-To and X-FTN-From generated by other gates * - modified removemime to kludgerise lines if charset != us-ascii * - creation of ^aACUPDATE kludges from Supersedes: and cancel's * - added charset support (see Changelog for details) * - added recognition of X-Fsc- * - added support to dequote MIME quoted printable messages. Code by T.Tanaka * - added removemsgid and removeinreply */ #include "bread.h" #include "bwrite.h" #include "hash.h" #include "mkftnhdr.h" #include "tracker.h" #include "viadate.h" #include "storenet.h" #define MAXHDRSIZE 2048 #define MAXSEEN 70 #define MAXPATH 73 extern time_t now; extern char *replyaddr; extern faddr *bestaka; extern int pgpsigned; extern int net_bad; extern int net_out; extern char *ftnmsgidstyle; char *subj; char *localdomain=NULL; static int removemime; static int removeorg; static int removemsgid; static int removeref; static int removeinreply; static int removesupersedes; static int removeapproved; static int removefrom; static int removereplyto; static int removereturnto; static int ftnorigin; void StatAdd(statcnt *S, unsigned long V) { S->total += V; S->tweek += V; S->tdow[Diw] += V; S->month[Miy] += V; } int needputrfc(rfcmsg *msg) { faddr *ta; /* 0-junk, 1-kludge, 2-pass */ if (!strcasecmp(msg->key,"X-UUCP-From")) return 0; if (!strcasecmp(msg->key,"X-Body-Start")) return 0; if (!strncasecmp(msg->key,".",1)) return 0; if (!strncasecmp(msg->key,"X-FTN-",6)) return 0; if (!strncasecmp(msg->key,"X-Fsc-",6)) return 0; if (!strncasecmp(msg->key,"X-ZC-",5)) return 0; if (!strcasecmp(msg->key,"X-Gateway")) return 0; if (!strcasecmp(msg->key,"Path")) return 0; if (!strcasecmp(msg->key,"Newsgroups")) { if ((hdr((char *)"X-Origin-Newsgroups",msg))) return 0; else return 1; } if (!strcasecmp(msg->key,"X-Origin-Newsgroups")) { return 1; } if (!strcasecmp(msg->key,"Control")) { if (CFG.allowcontrol) { if (strstr(msg->val,"cancel")) return 1; else return 0; } else return 0; } if (!strcasecmp(msg->key,"Return-Path")) return 1; if (!strcasecmp(msg->key,"Xref")) return 0; if (!strcasecmp(msg->key,"Approved")) return removeapproved ?0:2; if (!strcasecmp(msg->key,"X-URL")) return 0; if (!strcasecmp(msg->key,"Return-Receipt-To")) return removereturnto ?0:1; if (!strcasecmp(msg->key,"Notice-Requested-Upon-Delivery-To")) return 0; if (!strcasecmp(msg->key,"Received")) { return ftnorigin ?0:1; } if (!strcasecmp(msg->key,"From")) { if ((ta=parsefaddr(msg->val))) { tidy_faddr(ta); return 0; } else return removefrom ?0:2; } if (!strcasecmp(msg->key,"To")) { if ((ta=parsefaddr(msg->val))) { tidy_faddr(ta); return 0; } else return 2; } if (!strcasecmp(msg->key,"Cc")) return 2; if (!strcasecmp(msg->key,"Bcc")) return 0; if (!strcasecmp(msg->key,"Reply-To")) { if ((ta=parsefaddr(msg->val))) { tidy_faddr(ta); return 0; } else return removereplyto ?0:2; } if (!strcasecmp(msg->key,"Lines")) return 0; if (!strcasecmp(msg->key,"Date")) return 0; if (!strcasecmp(msg->key,"Subject")) { if ((msg->val) && (strlen(msg->val) > MAXSUBJ)) return 2; else return 0; } if (!strcasecmp(msg->key,"Organization")) return removeorg ?0:1; if (!strcasecmp(msg->key,"Comment-To")) return 0; if (!strcasecmp(msg->key,"X-Comment-To")) return 0; if (!strcasecmp(msg->key,"X-Apparently-To")) return 0; if (!strcasecmp(msg->key,"Apparently-To")) return 0; if (!strcasecmp(msg->key,"X-Fidonet-Comment-To")) return 0; if (!strcasecmp(msg->key,"Keywords")) return 2; if (!strcasecmp(msg->key,"Summary")) return 2; if (!strcasecmp(msg->key,"MIME-Version")) return removemime ?0:1; if (!strcasecmp(msg->key,"Content-Type")) return removemime ?0:1; if (!strcasecmp(msg->key,"Content-Length")) return removemime ?0:1; if (!strcasecmp(msg->key,"Content-Transfer-Encoding")) return removemime ?0:1; if (!strcasecmp(msg->key,"Content-Name")) return 2; if (!strcasecmp(msg->key,"Content-Description")) return 2; if (!strcasecmp(msg->key,"Message-ID")) return removemsgid ?0:1; if (!strcasecmp(msg->key,"References")) return removeref ?0:1; if (!strcasecmp(msg->key,"In-Reply-To")) return removeinreply ?0:1; if (!strcasecmp(msg->key,"Supersedes")) return removesupersedes ?0:1; if (!strcasecmp(msg->key,"Distribution")) return 0; if (!strcasecmp(msg->key,"X-Newsreader")) return 0; if (!strcasecmp(msg->key,"X-Mailer")) return 0; if (!strcasecmp(msg->key,"User-Agent")) return 0; if (!strncasecmp(msg->key,"NNTP-",5)) return 0; if (!strncasecmp(msg->key,"X-Trace",7)) return 0; if (!strncasecmp(msg->key,"X-Complaints",12)) return 0; if (!strncasecmp(msg->key,"X-MSMail",9)) return 0; if (!strncasecmp(msg->key,"X-MimeOLE",9)) return 0; if (!strncasecmp(msg->key,"X-MIME-Autoconverted",20)) return 0; if (!strcasecmp(msg->key,"X-Origin-Date")) return 0; if (!strncasecmp(msg->key,"X-PGP-",6)) return 0; if (!strncasecmp(msg->key,"Resent-",7)) return 0; if (!strcasecmp(msg->key,"X-Mailing-List")) return 0; if (!strcasecmp(msg->key,"X-Loop")) return 0; if (!strcasecmp(msg->key,"Precedence")) return 0; /*if (!strcasecmp(msg->key,"")) return ;*/ return 1; } int putmessage(rfcmsg *msg, ftnmsg *fmsg, FILE *fp, faddr *route, char flavor,fa_list **sbl, int incode, int outcode) { char buf[BUFSIZ],*p,*q,newsubj[4 * (MAXSUBJ+1)],*oldsubj; rfcmsg *tmp; int rfcheaders, postlocal; int needsplit,hdrsize,datasize,splitpart,forbidsplit; int sot_kludge, eot_kludge; int qp_or_base64; /* 0=plain text, 1=quoted-printable, 2=base64 */ int html_message; int tinyorigin=0; fa_list *ptl=NULL; faddr *ta; int i; FILE *pkt; fidoaddr Dest, Route, *dest; time_t Now; Syslog('m', "putmessage from %s",ascfnode(fmsg->from,0x7f)); Syslog('m', "putmessage to %s",ascfnode(fmsg->to,0x7f)); Syslog('m', "putmessage subj %s",MBSE_SS(fmsg->subj)); Syslog('m', "putmessage flags %04x",fmsg->flags); Syslog('m', "putmessage msgid %s %lx",MBSE_SS(fmsg->msgid_a),fmsg->msgid_n); Syslog('m', "putmessage reply %s %lx",MBSE_SS(fmsg->reply_a),fmsg->reply_n); Syslog('m', "putmessage date %s",ftndate(fmsg->date)); removemime = FALSE; removeorg = FALSE; removemsgid = FALSE; removeref = FALSE; removeinreply = FALSE; removesupersedes = FALSE; removeapproved = FALSE; removefrom = TRUE; removereplyto = TRUE; removereturnto = TRUE; ftnorigin=fmsg->ftnorigin; sot_kludge = 0; eot_kludge = 0; qp_or_base64 = 0; html_message = 0; if ((hdr((char *)"X-PGP-Signed",msg))) pgpsigned = TRUE; Syslog('m', "pgpsigned = %s", pgpsigned ? "True":"False"); q = hdr((char *)"Content-Transfer-Encoding",msg); if (q) while (*q && isspace(*q)) q++; if (!(q)) q = (char *)"8bit"; if ((p = hdr((char *)"Content-Type",msg))) { while (*p && isspace(*p)) p++; /* * turn the quoted-printable decode mode on; remember FTN is virtually 8-bit clean */ if ((strncasecmp(p, "text/plain", 10) == 0) && (strncasecmp(q, "quoted-printable", 16) == 0)) qp_or_base64 = 1; /* * turn the base64 decode mode on */ else if ((strncasecmp(p, "text/plain", 10) == 0) && (strncasecmp(q, "base64", 6) == 0)) qp_or_base64 = 2; /* * text/html support from FSC-HTML 001 proposal of Odinn Sorensen (2:236/77) */ if (strncasecmp(p, "text/html", 9) == 0) html_message = TRUE; for (tmp=msg;tmp;tmp=tmp->next) if (((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0) && (strcasecmp(tmp->val,"FSCHTML") == 0)) || (strcasecmp(tmp->key,"X-FTN-HTML") == 0)) html_message = FALSE; if ((readcharset(p) != CHRS_NOTSET ) && ((q == NULL) || (strncasecmp(q,"7bit",4) == 0) || ((!pgpsigned) && (qp_or_base64==1)) || ((!pgpsigned) && (qp_or_base64==2)) || (strncasecmp(q,"8bit",4) == 0))) removemime = TRUE; /* no need in MIME headers */ /* * some old MUA puts "text" instead of "text/plain; charset=..." */ else if ((strcasecmp(p,"text\n") == 0)) removemime = TRUE; } Syslog('m', "removemime=%s, qp_or_base64 = %d, html_message=%s", removemime ? "True":"False", qp_or_base64, html_message ? "True":"False"); if ((p = hdr((char *)"Message-ID",msg))) { if (!removemsgid) removemsgid = chkftnmsgid(p); } Syslog('m', "removemsgid = %s", removemsgid ? "True":"False"); if ((p = hdr((char *)"In-Reply-To",msg))) { p = xstrcpy(p); q = strtok(p," \t\n"); if ((q) && (strtok(NULL," \t\n") == NULL)) removeinreply = chkftnmsgid(q); free(p); } Syslog('m', "removeinreply = %s", removeinreply ? "True":"False"); if ((p = hdr((char *)"Reply-To",msg))) { removereplyto = FALSE; if ((!removereplyto) && (q = hdr((char *)"From",msg))) { char *r; r = xstrcpy(p); p = r; while(*p && isspace(*p)) p++; if (p[strlen(p)-1] == '\n') p[strlen(p)-1]='\0'; if (strcasestr(q,p)) removereplyto = TRUE; free(r); } } Syslog('m', "removereplyto = %s", removereplyto ? "True":"False"); if ((p = hdr((char *)"Return-Receipt-To",msg))) { removereturnto = FALSE; if ((!removereturnto) && (q=hdr((char *)"From",msg))) { char *r; r = xstrcpy(p); p = r; while(*p && isspace(*p)) p++; if (p[strlen(p)-1] == '\n') p[strlen(p)-1]='\0'; if (strcasestr(q,p)) removereturnto = TRUE; // free(r); } } Syslog('m', "removereturnto = %s", removereturnto ? "True":"False"); p = ascfnode(fmsg->from,0x1f); i = 79-11-3-strlen(p); if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) { /* This is a kludge... I don't like it too much. But well, if this is a message of FTN origin, the original origin (:) line MUST have been short enough to fit in 79 chars... So we give it a try. Probably it would be better to keep the information about the address format from the origin line in a special X-FTN-... header, but this seems even less elegant. Any _good_ ideas, anyone? */ /* OK, I am keeping this, though if should never be used al long as X-FTN-Origin is used now */ p = ascfnode(fmsg->from,0x0f); i = 79-11-3-strlen(p); tinyorigin = TRUE; } Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False"); if ((fmsg->origin) && (strlen(fmsg->origin) > i)) fmsg->origin[i]='\0'; forbidsplit=(ftnorigin || (hdr((char *)"X-FTN-Split",msg))); needsplit = 0; splitpart = 0; hdrsize = 20; hdrsize += (fmsg->subj)?strlen(fmsg->subj):0; if (fmsg->from) hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0; if (fmsg->to) hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0; do { Syslog('m', "split loop, splitpart = %d", splitpart); datasize=0; if (splitpart) { sprintf(newsubj,"[part %d] ",splitpart+1); strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj)); } else { strncpy(newsubj,fmsg->subj,MAXSUBJ); } strcpy(newsubj, hdrnconv(newsubj, incode, outcode, MAXSUBJ)); newsubj[MAXSUBJ]='\0'; if (splitpart) { hash_update_n(&fmsg->msgid_n,splitpart); } oldsubj=fmsg->subj; fmsg->subj=newsubj; /* * We got the routing address from the mailer which was given by our Host's sendmail. * This is probably our address so we need to get the address for the next hop. */ dest = faddr2fido(fmsg->to); memcpy(&Dest, dest, sizeof(fidoaddr)); free(dest); if (TrackMail(Dest, &Route) == R_LOCAL) { /* * Mail for our local system. Instead of adding the message to a .pkt create * a temporary file which later will be send via the storenet function. */ postlocal = TRUE; pkt = tmpfile(); } else { /* * New outbound route. */ route = fido2faddr(Route); postlocal = FALSE; if ((pkt = ftnmsghdr(fmsg, NULL, route, flavor, (char *)"MBSE-FIDO")) == NULL) { return 1; } } fmsg->subj=oldsubj; Syslog('m', "replyaddr=%s removereplyto=%s removefrom=%s", printable(replyaddr, 0), removereplyto?"True":"False", removefrom?"True":"False"); /* * Add FTN MSGID: and REPLY: if needed. */ Now = time(NULL) - (gmt_offset((time_t)0) * 60); if (postlocal) { fprintf(pkt, "\001MSGID: %s %08lx\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n); if (fmsg->reply_s) fprintf(pkt, "\1REPLY: %s\n", fmsg->reply_s); else if (fmsg->reply_a) fprintf(pkt, "\1REPLY: %s %08lx\n", fmsg->reply_a, fmsg->reply_n); fprintf(pkt, "\001TZUTC: %s\n", gmtoffset(Now)); } else { fprintf(pkt, "\001MSGID: %s %08lx\r", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n); if (fmsg->reply_s) fprintf(pkt, "\1REPLY: %s\r", fmsg->reply_s); else if (fmsg->reply_a) fprintf(pkt, "\1REPLY: %s %08lx\r", fmsg->reply_a, fmsg->reply_n); fprintf(pkt, "\001TZUTC: %s\r", gmtoffset(Now)); } if ((p=hdr((char *)"X-FTN-REPLYADDR",msg))) { hdrsize += 10+strlen(p); fprintf(pkt,"\1REPLYADDR:"); kwrite(p,pkt,postlocal); } else if ((replyaddr) && ((!removereplyto) || (!removefrom))) { hdrsize += 10+strlen(replyaddr); fprintf(pkt,"\1REPLYADDR: "); kwrite(replyaddr,pkt,postlocal); } if ((p=hdr((char *)"X-FTN-REPLYTO",msg))) { hdrsize += 8+strlen(p); fprintf(pkt,"\1REPLYTO:"); kwrite(p,pkt,postlocal); } else if ((replyaddr) && ((!removereplyto) || (!removefrom))) { hdrsize += 15; if (postlocal) fprintf(pkt,"\1REPLYTO: %s UUCP\n", ascfnode(bestaka,0x1f)); else fprintf(pkt,"\1REPLYTO: %s UUCP\r", ascfnode(bestaka,0x1f)); } else if ((p=hdr((char *)"Reply-To",msg))) { if ((ta=parsefaddr(p))) { if ((q=hdr((char *)"From",msg))) { if (!strcasestr(q,p)) { if (postlocal) fprintf(pkt,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name); else fprintf(pkt,"\1REPLYTO: %s %s\r", ascfnode(ta,0x1f), ta->name); } tidy_faddr(ta); } } /* Added 15-Apr-2001 MB. Add UUCP reply info if there is nothing. */ } else if ((p=hdr((char *)"X-UUCP-From",msg)) && (q=hdr((char *)"From",msg))) { hdrsize += 15; Striplf(q); if (postlocal) { fprintf(pkt,"\1REPLYADDR: %s\n", q); fprintf(pkt,"\1REPLYTO: %s UUCP\n", ascfnode(bestaka,0x1f)); } else { fprintf(pkt,"\1REPLYADDR: %s\r", q); fprintf(pkt,"\1REPLYTO: %s UUCP\r", ascfnode(bestaka,0x1f)); } } if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) { hdrsize += 15; if (postlocal) fprintf(pkt,"\1FLAGS:%s\n",p); else fprintf(pkt,"\1FLAGS:%s\r",p); free(p); } if (!hdr((char *)"X-FTN-PID", msg)) { p = hdr((char *)"User-Agent", msg); if (p == NULL) p = hdr((char *)"X-Newsreader", msg); if (p == NULL) p = hdr((char *)"X-Mailer", msg); if (p) { hdrsize += 4 + strlen(p); fprintf(pkt, "\1PID:"); kwrite(p, pkt, postlocal); } else { if (postlocal) fprintf(pkt, "\001PID: MBSE-MAIL %s\n", VERSION); else fprintf(pkt, "\001PID: MBSE-MAIL %s\r", VERSION); } } hdrsize += 15; if (postlocal) writechrs(outcode,pkt,3); else writechrs(outcode,pkt,1); if (html_message) { hdrsize += 9; if (postlocal) fprintf(pkt, "\1HTML: 5\n"); else fprintf(pkt, "\1HTML: 5\r"); } #ifdef FSC_0070 /* FSC-0070 */ if ((p = hdr((char *)"Message-ID", msg)) && !(hdr((char *)"X-FTN-RFCID", msg))) { q = strdup(p); fprintf(pkt,"\1RFCID:"); if ((l = strrchr(q, '<')) && (r = strchr(q, '>')) && (l < r)) { *l++ = ' '; while(*l && isspace(*l)) l++; l--; /* leading ' ' */ *r-- = '\0'; while(*r && isspace(*r)) *r-- = '\0'; } else l = q; kwrite(l, pkt, postlocal); hdrsize += 6 + strlen(l); free(q); } #endif /* FSC_0070 */ if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) { sprintf(buf, " mbmail %s", VERSION); hdrsize += 4 + strlen(buf); fprintf(pkt, "\1TID:"); kwrite(buf, pkt, postlocal); } if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) { for (tmp=msg;tmp;tmp=tmp->next) if ((!strncmp(tmp->key,"X-Fsc-",6)) || (!strncmp(tmp->key,"X-FTN-",6) && strcasecmp(tmp->key,"X-FTN-Tearline") && strcasecmp(tmp->key,"X-FTN-Origin") && strcasecmp(tmp->key,"X-FTN-Sender") && strcasecmp(tmp->key,"X-FTN-Split") && strcasecmp(tmp->key,"X-FTN-FLAGS") && strcasecmp(tmp->key,"X-FTN-AREA") && strcasecmp(tmp->key,"X-FTN-MSGID") && strcasecmp(tmp->key,"X-FTN-REPLY") && strcasecmp(tmp->key,"X-FTN-SEEN-BY") && strcasecmp(tmp->key,"X-FTN-PATH") && strcasecmp(tmp->key,"X-FTN-REPLYADDR") && strcasecmp(tmp->key,"X-FTN-REPLYTO") && strcasecmp(tmp->key,"X-FTN-To") && strcasecmp(tmp->key,"X-FTN-From") && strcasecmp(tmp->key,"X-FTN-CHARSET") && strcasecmp(tmp->key,"X-FTN-CHRS") && strcasecmp(tmp->key,"X-FTN-CODEPAGE") && strcasecmp(tmp->key,"X-FTN-ORIGCHRS") && strcasecmp(tmp->key,"X-FTN-SOT") && strcasecmp(tmp->key,"X-FTN-EOT") && strcasecmp(tmp->key,"X-FTN-Via"))) { if (strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0) { if (!strcasecmp(tmp->val," SOT:\n")) sot_kludge = 1; else if (!strcasecmp(tmp->val," EOT:\n")) eot_kludge = 1; else { hdrsize += strlen(tmp->val); fprintf(pkt,"\1"); /* we should have restored the original string here... */ kwrite((tmp->val)+1, pkt, postlocal); } } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt,"\1%s:",tmp->key+6); kwrite(tmp->val, pkt, postlocal); } } /* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */ for (tmp=msg;tmp;tmp=tmp->next) if ((!strncmp(tmp->key,"X-ZC-",5))) { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt, "\1%s:", tmp->key+2); kwrite(tmp->val, pkt, postlocal); } /* mondo.org gateway uses ".MSGID: ..." in usenet */ for (tmp=msg;tmp;tmp=tmp->next) if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt,"\1%s:",tmp->key+1); kwrite(tmp->val, pkt, postlocal); } rfcheaders = 0; for (tmp=msg;tmp;tmp=tmp->next) if ((needputrfc(tmp) == 1)) { if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) { hdrsize += 10+strlen(tmp->val); fprintf(pkt,"\1RFC-Newsgroups:"); } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt,"\1RFC-%s:",tmp->key); } kwrite(hdrconv(tmp->val, incode, outcode),pkt, postlocal); } for (tmp=msg;tmp;tmp=tmp->next) if ((needputrfc(tmp) > 1)) { rfcheaders++; if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) { hdrsize += 10+strlen(tmp->val); fprintf(pkt,"Newsgroups:"); } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt,"%s:",tmp->key); } cwrite(hdrconv(tmp->val, incode, outcode),pkt,postlocal); } if (rfcheaders) cwrite((char *)"\n",pkt, postlocal); if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge)) { if (postlocal) fprintf(pkt,"\1SOT:\n"); else fprintf(pkt,"\1SOT:\r"); } if ((splitpart == 0) && (hdr((char *)"X-PGP-Signed",msg))) { if (postlocal) fprintf(pkt,PGP_SIGNED_BEGIN"\n"); else fprintf(pkt,PGP_SIGNED_BEGIN"\r"); } } if (replyaddr) { // free(replyaddr); /* Gives SIGSEGV */ replyaddr=NULL; } if (needsplit) { if (postlocal) fprintf(pkt," * Continuation %d of a split message *\n\n", splitpart); else fprintf(pkt," * Continuation %d of a split message *\r\r", splitpart); needsplit=0; } else if ((p=hdr((char *)"X-Body-Start",msg))) { datasize += strlen(p); if (qp_or_base64==1) cwrite(strkconv(qp_decode(p), incode, outcode), pkt, postlocal); else if (qp_or_base64==2) cwrite(strkconv(b64_decode(p), incode, outcode), pkt, postlocal); else cwrite(strkconv(p, incode, outcode), pkt, postlocal); } while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) || (!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(buf,sizeof(buf)-1,fp))) { // Syslog('m', "putmessage body %s",buf); datasize += strlen(buf); if (qp_or_base64==1) cwrite(strkconv(qp_decode(buf), incode, outcode), pkt, postlocal); else if (qp_or_base64==2) cwrite(strkconv(b64_decode(buf), incode, outcode), pkt, postlocal); else cwrite(strkconv(buf, incode, outcode), pkt, postlocal); } if (needsplit) { if (postlocal) fprintf(pkt,"\n * Message split, to be continued *\n"); else fprintf(pkt,"\r * Message split, to be continued *\r"); splitpart++; } else if ((p=hdr((char *)"X-PGP-Signed",msg))) { if (postlocal) fprintf(pkt,PGP_SIG_BEGIN"\n"); else fprintf(pkt,PGP_SIG_BEGIN"\r"); if ((q=hdr((char *)"X-PGP-Version",msg))) { fprintf(pkt,"Version:"); cwrite(q,pkt, postlocal); } if ((q=hdr((char *)"X-PGP-Charset",msg))) { fprintf(pkt,"Charset:"); cwrite(q,pkt, postlocal); } if ((q=hdr((char *)"X-PGP-Comment",msg))) { fprintf(pkt,"Comment:"); cwrite(q,pkt, postlocal); } if (postlocal) fprintf(pkt,"\n"); else fprintf(pkt,"\r"); p=xstrcpy(p); q=strtok(p," \t\n"); if (postlocal) fprintf(pkt,"%s\n",q); else fprintf(pkt,"%s\r",q); while ((q=(strtok(NULL," \t\n")))) { if (postlocal) fprintf(pkt,"%s\n",q); else fprintf(pkt,"%s\r",q); } if (postlocal) fprintf(pkt,PGP_SIG_END"\n"); else fprintf(pkt,PGP_SIG_END"\r"); } if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge)) { if (postlocal) fprintf(pkt,"\1EOT:\n"); else fprintf(pkt,"\1EOT:\r"); } if ((p=hdr((char *)"X-FTN-Tearline",msg))) { fprintf(pkt,"---"); if (strcasecmp(p," (none)\n") == 0) cwrite((char *)"\n",pkt,postlocal); else cwrite(p,pkt,postlocal); } else { if (postlocal) fprintf(pkt,"--- MBSE BBSv.%s\n",VERSION); else fprintf(pkt,"--- MBSE BBSv.%s\r",VERSION); } if ((p=hdr((char *)"X-FTN-Origin",msg))) { if (*(q=p+strlen(p)-1) == '\n') *q='\0'; fprintf(pkt," * Origin:"); cwrite(hdrconv(p, incode, outcode),pkt, postlocal); if (postlocal) fprintf(pkt, "\n"); else fprintf(pkt,"\r"); } else { fprintf(pkt," * Origin: "); if (fmsg->origin) cwrite(hdrconv(fmsg->origin, incode, outcode), pkt, postlocal); else fprintf(pkt, "%s", CFG.origin); if (postlocal) fprintf(pkt, " (%s)\n", ascfnode(fmsg->from,tinyorigin?0x0f:0x1f)); else fprintf(pkt, " (%s)\r", ascfnode(fmsg->from,tinyorigin?0x0f:0x1f)); } for (tmp = msg; tmp; tmp = tmp->next) if (!strcasecmp(tmp->key,"X-FTN-Via")) { datasize += strlen(tmp->key)+strlen(tmp->val); fprintf(pkt,"\1Via"); kwrite(tmp->val,pkt, postlocal); } /* * @Via mbmail 2:293/2219@fidonet, Wed Jan 3 1996 at 07:49 (2.8c) */ if (postlocal) fprintf(pkt,"\1Via mbmail %s, %s (%s)\n", ascfnode(bestaka,0x1f), viadate(),VERSION); else fprintf(pkt,"\1Via mbmail %s, %s (%s)\r", ascfnode(bestaka,0x1f), viadate(),VERSION); if (postlocal) { subj = xstrcpy(fmsg->subj); /* * Check userlist real names, handles, unix names. * Import if one fits. */ if (!SearchUser(fmsg->to->name)) { Syslog('+', " \"%s\" is not a known BBS user", fmsg->to->name); /* * Unknown, readdress it to the sysop. */ net_bad++; Syslog('+', " Readdress from %s to %s", fmsg->to->name, CFG.sysop_name); fmsg->to->name = xstrcpy(CFG.sysop_name); } if (SearchUser(fmsg->to->name)) { Syslog('m', "storenet(%s, %s, %s, %04x)", ascfnode(fmsg->from,0x7f), ascfnode(fmsg->to,0x7f), ftndate(fmsg->date), fmsg->flags); if (storenet(fmsg->from, fmsg->to, fmsg->date, fmsg->flags, fmsg->subj, fmsg->msgid_a, fmsg->reply_a, pkt)) return 2; } else { WriteError("Unknown bbs user"); return 2; } } else { awrite((char *)"",pkt); /* trailing zero byte */ if (ferror(pkt)) { WriteError("$error writing to ftn packet"); return 1; } net_out++; } tidy_falist(&ptl); } while (needsplit); Syslog('m', "putmessage exiting..."); return 0; }