/******************************************************************************
* FIDOCONFIG --- library for fidonet configs
******************************************************************************
* afixcmn.c : common areafix functions
*
* Compiled from hpt/areafix hpt/toss hpt/pkt
* by Max Chernogor <mihz@mail.ru>, 2:464/108@fidonet
*
* This file is part of FIDOCONFIG library (part of the Husky FIDOnet
* software project)
*
* This 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.
*
* FIDOCONFIG library 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 FIDOCONFIG library; see the file COPYING. If not, write
* to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA
* or visit http://www.gnu.org
*****************************************************************************
* $Id: afixcmn.c,v 1.10.2.2 2002/07/24 20:27:03 stas Exp $
*/
/*
* This subroutine makes up an ascending unique ^aMSGID stamp
* taken from Su.FidoTech.FAQ [2/3]
*/
#include <string.h>
#include <stdlib.h>
#if !(defined (_MSC_VER) && (_MSC_VER >= 1200))
#include <unistd.h>
#endif
#include "fidoconf.h"
#include "xstr.h"
#include "common.h"
#include "log.h"
#include "afixcmd.h"
#include <smapi/progprot.h>
/*
static ULONG DoMakeMSGIDStamp(void)
{
static ULONG lStampPrev;
ULONG lStamp, lSecs, lHund, lSecStart = (ULONG) time(NULL);
// Make up time stamp out of number of seconds since Jan 1, 1970
// shifted 7 bits to the left OR'ed with current system clock and
// loop untill we get a new stamp
do {
lSecs = (ULONG) time(NULL);
lHund = (ULONG) clock();
lStamp = (lSecs << 7) | (lHund & 0x07f);
} while ((lStampPrev >= lStamp) && ((ULONG) time(NULL) < lSecStart + 5));
// Check if we finally have unique ascending ^aMSGID kludge stamp and
// if not, use incremented largest stamp value
if (lStampPrev >= lStamp) lStamp = lStampPrev + 1;
return lStampPrev = lStamp;
}
*/
char *createKludges(int disableTID, const char *area, const s_addr *ourAka,
const s_addr *destAka, const char* versionStr)
{
char *buff = NULL;
ULONG msgid = 0;
if (area) xscatprintf(&buff, "AREA:%s\r", area);
else {
xscatprintf(&buff, "\001INTL %u:%u/%u %u:%u/%u\r",
destAka->zone, destAka->net, destAka->node,
ourAka->zone, ourAka->net, ourAka->node);
if (ourAka->point) xscatprintf(&buff, "\001FMPT %d\r", ourAka->point);
if (destAka->point) xscatprintf(&buff, "\001TOPT %d\r", destAka->point);
}
sleep(1);
msgid = time(NULL);
if (ourAka->point)
xscatprintf(&buff, "\001MSGID: %u:%u/%u.%u %08lx\r",
ourAka->zone,ourAka->net,ourAka->node,ourAka->point,msgid);
else
xscatprintf(&buff, "\001MSGID: %u:%u/%u %08lx\r",
ourAka->zone,ourAka->net,ourAka->node,msgid);
if (!disableTID) xscatprintf(&buff, "\001TID: %s\r", versionStr);
return buff;
}
s_message *makeMessage (s_addr *origAddr, s_addr *destAddr,
char *fromName, char *toName, char *subject,
int netmail, int killreport)
{
// netmail == 0 - echomail
// netmail == 1 - netmail
time_t time_cur;
s_message *msg;
if (toName == NULL) toName = "sysop";
time_cur = time(NULL);
msg = (s_message*) scalloc(1,sizeof(s_message));
msg->origAddr.zone = origAddr->zone;
msg->origAddr.net = origAddr->net;
msg->origAddr.node = origAddr->node;
msg->origAddr.point = origAddr->point;
msg->destAddr.zone = destAddr->zone;
msg->destAddr.net = destAddr->net;
msg->destAddr.node = destAddr->node;
msg->destAddr.point = destAddr->point;
xstrcat(&(msg->fromUserName), fromName);
xstrcat(&(msg->toUserName), toName);
xstrcat(&(msg->subjectLine), subject);
msg->attributes |= MSGLOCAL;
if (netmail) {
msg->attributes |= MSGPRIVATE;
msg->netMail = 1;
}
if (killreport) msg->attributes |= MSGKILL;
fts_time((char*)msg->datetime, localtime(&time_cur));
return msg;
}
XMSG createXMSG(ps_fidoconfig config, s_message *msg, const s_pktHeader *header,
dword forceattr, char* tossDir)
{
char **outbounds[4];
XMSG msgHeader;
struct tm *date;
time_t currentTime;
union stamp_combo dosdate;
unsigned int i;
char *subject=NULL, *newSubj=NULL, *token=NULL, *running=NULL, *p=NULL;
unsigned char intl=1,topt=1;
//init outbounds
outbounds[0] = &tossDir;
outbounds[1] = &config->protInbound;
outbounds[2] = &config->inbound;
outbounds[3] = NULL;
// clear msgheader
memset(&msgHeader, '\0', sizeof(XMSG));
// attributes of netmail must be fixed
msgHeader.attr = msg->attributes;
if (msg->netMail == 1) {
// Check if we must remap
for (i=0;i<config->remapCount;i++)
if ((config->remaps[i].toname==NULL ||
stricmp(config->remaps[i].toname,msg->toUserName)==0) &&
(config->remaps[i].oldaddr.zone==0 ||
addrComp(config->remaps[i].oldaddr,msg->destAddr)==0) )
{ w_log( LL_NETMAIL,"Remap destination %u:%u/%u.%u to %s",
msg->destAddr.zone, msg->destAddr.net,
msg->destAddr.node, msg->destAddr.point,
aka2str(config->remaps[i].newaddr) );
msg->destAddr.zone =config->remaps[i].newaddr.zone;
msg->destAddr.net =config->remaps[i].newaddr.net;
msg->destAddr.node =config->remaps[i].newaddr.node;
msg->destAddr.point=config->remaps[i].newaddr.point;
if( !msg->destAddr.point ) topt=0;
/* synchronize 'INTL' kludge with new dest address */
for( running=msg->text; (p=strchr(running,'\r'))!=NULL; running=++p ){
*p = '\0';
if( intl && strlen(running)>5 && !memcmp(running, "\001INTL ",6) ) {
/*replace INTL to new*/
xscatprintf( &token, "\001INTL %u:%u/%u %u:%u/%u\r",
msg->destAddr.zone, msg->destAddr.net, msg->destAddr.node,
msg->origAddr.zone, msg->origAddr.net, msg->origAddr.node );
intl=0;
} else if( topt && strlen(running)>5 && !memcmp(running, "\00TOPT ",6) ) {
/*replace IOPT to new*/
xstrscat( &token, "\001TOPT %u\r", msg->destAddr.point, NULL );
topt=0;
} else { /* copy kludge or line */
xscatprintf( &token, "%s\r", running );
}
if ( !(intl || topt) ) { /* both kludge changed */
xstrcat( &token, ++p ); /* copy rest text */
break; /*for(running...)*/
}
}
xscatprintf( &token, "\001Replace destaddr %s",
aka2str(config->remaps[i].oldaddr) );
xscatprintf( &token, " with %s", aka2str(msg->destAddr) );
xscatprintf( &token, " by %s", aka2str(config->addr[0]) );
msg->textLength = strlen(token);
nfree(msg->text);
msg->text = token;
token = p = NULL;
break;
}
//if (to_us(msg->destAddr)==0) {
if (isOurAka(config,msg->destAddr)) {
// kill these flags
msgHeader.attr &= ~(MSGREAD | MSGKILL | MSGFRQ | MSGSCANNED | MSGLOCKED | MSGFWD);
// set this flags
msgHeader.attr |= MSGPRIVATE;
} else
if (header!=NULL) {
// set TRS flag, if the mail is not to us(default)
if ( config->keepTrsMail ) msgHeader.attr &= ~(MSGKILL | MSGFWD);
else msgHeader.attr |= MSGFWD;
}
} else
// kill these flags on echomail messages
msgHeader.attr &= ~(MSGREAD | MSGKILL | MSGFRQ | MSGSCANNED | MSGLOCKED);
// always kill crash, hold, sent & local flags on netmail & echomail
msgHeader.attr &= ~(MSGCRASH | MSGHOLD | MSGSENT | MSGLOCAL);
/* FORCED ATTRIBUTES !!! */
msgHeader.attr |= forceattr;
strcpy((char *) msgHeader.from,msg->fromUserName);
strcpy((char *) msgHeader.to, msg->toUserName);
if (((msgHeader.attr & MSGFILE) == MSGFILE)
&& (msg->netMail==1)
&& !strchr(msg->subjectLine, PATH_DELIM)) {
running = msg->subjectLine;
token = strseparate(&running, " \t");
while (token != NULL) {
for (i=0;i<4;i++) {
nfree(subject);
if (outbounds[i] && *outbounds[i]) xstrcat(&subject, *outbounds[i]);
xstrcat (&subject, token);
if (fexist(subject)) break;
#if defined(__linux__) || defined(UNIX)
subject = strLower(subject);
if (fexist(subject)) break;
#endif
}
if (newSubj) xstrcat(&newSubj, " ");
xstrcat (&newSubj, subject);
token = strseparate(&running, " \t");
} // end while
nfree(subject);
}
if (newSubj) {
if (strlen(newSubj) < XMSG_SUBJ_SIZE)
strcpy((char *) msgHeader.subj, newSubj);
else {
strncpy((char *) msgHeader.subj, newSubj, XMSG_SUBJ_SIZE-1);
w_log('9',
"Long subjectLine! Some files will be not routed.");
}
nfree(newSubj);
} else strcpy((char *) msgHeader.subj, msg->subjectLine);
msgHeader.orig.zone = (word) msg->origAddr.zone;
msgHeader.orig.node = (word) msg->origAddr.node;
msgHeader.orig.net = (word) msg->origAddr.net;
msgHeader.orig.point = (word) msg->origAddr.point;
msgHeader.dest.zone = (word) msg->destAddr.zone;
msgHeader.dest.node = (word) msg->destAddr.node;
msgHeader.dest.net = (word) msg->destAddr.net;
msgHeader.dest.point = (word) msg->destAddr.point;
strcpy((char *) msgHeader.__ftsc_date, (char *)msg->datetime);
ASCII_Date_To_Binary((char *)msg->datetime, (union stamp_combo *) &(msgHeader.date_written));
currentTime = time(NULL);
date = localtime(¤tTime);
TmDate_to_DosDate(date, &dosdate);
msgHeader.date_arrived = dosdate.msg_st;
return msgHeader;
}
void freeMsgBuffers(s_message *msg)
{
nfree(msg->text);
nfree(msg->subjectLine);
nfree(msg->toUserName);
nfree(msg->fromUserName);
// if (msg->destAddr.domain) free(msg->destAddr.domain);
// do not free the domains of the adresses of the message, because they
// come from fidoconfig structures and are needed more than once.
}
syntax highlighted by Code2HTML, v. 0.9.1