/*****************************************************************************
* HPT --- FTN NetMail/EchoMail Tosser
*****************************************************************************
* Copyright (C) 1997-1999
*
* Matthias Tichy
*
* Fido: 2:2433/1245 2:2433/1247 2:2432/605.14
* Internet: mtt@tichy.de
*
* Grimmestr. 12 Buchholzer Weg 4
* 33098 Paderborn 40472 Duesseldorf
* Germany Germany
*
* Copyright (c) 1999-2001
* Max Levenkov, sackett@mail.ru
*
* This file is part of HPT.
*
* HPT 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.
*
* HPT 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 HPT; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************
* $Id: scanarea.c,v 1.97.2.4 2004/11/14 20:58:09 d_sergienko Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <smapi/compiler.h>
#include <smapi/msgapi.h>
#include <smapi/stamp.h>
#include <smapi/typedefs.h>
#include <smapi/progprot.h>
#include <fidoconf/fidoconf.h>
#include <fidoconf/common.h>
#include <fidoconf/xstr.h>
#include <fidoconf/afixcmd.h>
#include <fidoconf/log.h>
#include <fidoconf/recode.h>
#include <pkt.h>
#include <scan.h>
#include <seenby.h>
#include <global.h>
#include <version.h>
#include <toss.h>
#include <hpt.h>
#include <dupe.h>
#ifdef DO_PERL
#include <hptperl.h>
#endif
void makeMsg(HMSG hmsg, XMSG xmsg, s_message *msg, s_area *echo, int action)
{
/* action == 0 - scan area */
/* action == 1 - rescan area */
/* action == 2 - rescan badarea */
char *kludgeLines = NULL, *seenByPath = NULL;
UCHAR *msgtid = NULL;
UCHAR *ctrlBuff = NULL;
UINT32 ctrlLen;
UCHAR tid[]= "TID";
memset(msg, '\0', sizeof(s_message));
msg->origAddr.zone = xmsg.orig.zone;
msg->origAddr.net = xmsg.orig.net;
msg->origAddr.node = xmsg.orig.node;
msg->origAddr.point = xmsg.orig.point;
msg->destAddr.zone = xmsg.dest.zone;
msg->destAddr.net = xmsg.dest.net;
msg->destAddr.node = xmsg.dest.node;
msg->destAddr.point = xmsg.dest.point;
msg->attributes = xmsg.attr & ~MSGLOCAL; /* msg should not have MSGLOCAL bit set */
sc_time((union stamp_combo *) &(xmsg.date_written), (char *)msg->datetime);
xstrcat(&msg->toUserName, (char*)xmsg.to);
xstrcat(&msg->fromUserName, (char*)xmsg.from);
xstrcat(&msg->subjectLine, (char*)xmsg.subj);
/* make msgtext */
/* convert kludgeLines */
ctrlLen = MsgGetCtrlLen(hmsg);
ctrlBuff = (UCHAR *) safe_malloc(ctrlLen+1);
MsgReadMsg(hmsg, NULL, 0, 0, NULL, ctrlLen, ctrlBuff);
/* MsgReadMsg does not do zero termination! */
ctrlBuff[ctrlLen] = '\0';
if (action == 0 && config->disableTID == 0)
{
while ((msgtid = GetCtrlToken(ctrlBuff, tid)) != NULL)
MsgRemoveToken(ctrlBuff, tid);
xstrscat((char **) &ctrlBuff, "\001TID: ", versionStr, NULL);
}
/* add '\r' after each kludge */
kludgeLines = (char *) CvtCtrlToKludge(ctrlBuff);
nfree(ctrlBuff);
if (action == 0)
xstrcat(&seenByPath, "SEEN-BY: "); /* 9 bytes */
/* create text */
msg->textLength = MsgGetTextLen(hmsg); /* with trailing \0 */
msg->text=NULL;
if (action!=2) {
xscatprintf(&(msg->text),"AREA:%s\r",echo->areaName);
strUpper(msg->text+5);
}
xstrcat(&(msg->text), kludgeLines);
nfree(kludgeLines);
ctrlLen = strlen(msg->text);
xstralloc(&(msg->text), ctrlLen + msg->textLength);
MsgReadMsg(hmsg, NULL, (dword) 0, (dword) msg->textLength,
(byte *)(msg->text+ctrlLen), (dword) 0, (byte *)NULL);
msg->text[msg->textLength + ctrlLen]='\0';
msg->textLength += ctrlLen-1;
/* if origin has no ending \r add it */
if (msg->text[msg->textLength-1] != '\r') {
xstrcat(&(msg->text), "\r");
msg->textLength++;
}
if (action == 0) {
xstrcat(&(msg->text), seenByPath);
msg->textLength += 9; /* strlen(seenByPath) */
}
/* recoding from internal to transport charSet */
if (config->outtab != NULL && action != 2) {
recodeToTransportCharset((CHAR*)msg->fromUserName);
recodeToTransportCharset((CHAR*)msg->toUserName);
recodeToTransportCharset((CHAR*)msg->subjectLine);
recodeToTransportCharset((CHAR*)msg->text);
} else msg->recode |= (REC_HDR|REC_TXT);
nfree(seenByPath);
}
void packEMMsg(HMSG hmsg, XMSG *xmsg, s_area *echo)
{
s_message msg;
s_message* messCC;
makeMsg(hmsg, *xmsg, &msg, echo, 0);
/* msg is dupe -- return */
if (dupeDetection(echo, msg)!=1) return;
#ifdef DO_PERL
if (perlscanmsg(echo->areaName, &msg))
{ freeMsgBuffers(&msg);
return;
}
#endif
messCC = MessForCC(&msg); /* make copy of original message*/
/* export msg to downlinks */
forwardMsgToLinks(echo, &msg, *echo->useAka);
/* process carbon copy */
if (config->carbonOut) carbonCopy(messCC, xmsg, echo);
/* mark msg as sent and scanned */
xmsg->attr |= MSGSENT;
xmsg->attr |= MSGSCANNED;
MsgWriteMsg(hmsg, 0, xmsg, NULL, 0, 0, 0, NULL);
freeMsgBuffers(&msg);
freeMsgBuffers(messCC);
nfree(messCC);
statScan.exported++;
echo->scn++;
}
void scanEMArea(s_area *echo)
{
HAREA area;
HMSG hmsg;
XMSG xmsg;
dword highestMsg, i;
if (echo->scn) return;
area = MsgOpenArea((UCHAR *) echo->fileName, MSGAREA_NORMAL, (word)(echo->msgbType | MSGTYPE_ECHO));
if (area != NULL) {
statScan.areas++;
echo->scn++;
w_log(LL_START, "Scanning area: %s", echo->areaName);
i = (noHighWaters) ? 0 : MsgGetHighWater(area);
highestMsg = MsgGetNumMsg(area);
while (i < highestMsg) {
hmsg = MsgOpenMsg(area, MOPEN_RW, ++i);
if (hmsg == NULL) continue; /* msg# does not exist */
statScan.msgs++;
MsgReadMsg(hmsg, &xmsg, 0, 0, NULL, 0, NULL);
if (((xmsg.attr & MSGSENT) != MSGSENT) &&
((xmsg.attr & MSGLOCKED) != MSGLOCKED) &&
((xmsg.attr & MSGLOCAL) == MSGLOCAL)) {
packEMMsg(hmsg, &xmsg, echo);
}
MsgCloseMsg(hmsg);
/* kill msg */
if ((xmsg.attr & MSGKILL) == MSGKILL) {
MsgKillMsg(area, i);
i--;
}
}
if (i < highestMsg)
MsgSetHighWater(area, i);
closeOpenedPkt();
MsgCloseArea(area);
} else {
w_log(LL_START, "Could not open %s", echo->fileName);
} /* endif */
}
/* rescan functions taken from areafix.c */
int repackEMMsg(HMSG hmsg, XMSG xmsg, s_area *echo, s_arealink *arealink)
{
s_message msg;
UINT32 j=0;
s_seenBy *seenBys = NULL, *path = NULL;
UINT16 seenByCount = 0, pathCount = 0;
char *tempbefore, *addrstr, *tempafter;
makeMsg(hmsg, xmsg, &msg, echo, 1);
/* translating name of the area to uppercase */
while (msg.text[j] != '\r') {msg.text[j]=(char)toupper(msg.text[j]);j++;}
if (strncmp(msg.text+j+1,"NOECHO",6)==0) {
freeMsgBuffers(&msg);
return 0;
}
/* d_sergienko: Following FSC-0057 ... */
tempbefore = (char *) scalloc(j+1, 1);
tempbefore = (char *)strncpy(tempbefore, msg.text, j);
tempafter = (char *)sstrdup(msg.text+j+1);
nfree(msg.text);
xstrscat((char **) &msg.text, tempbefore, "\r\001RESCANNED ",
(addrstr=aka2str5d(*arealink->link->ourAka)), "\r", tempafter,
NULL);
nfree(tempbefore);
nfree(tempafter);
nfree(addrstr);
createSeenByArrayFromMsg(&msg, &seenBys, &seenByCount);
createPathArrayFromMsg(&msg, &path, &pathCount);
forwardMsgToLink(&msg, echo, arealink->link, seenBys, seenByCount, path, pathCount);
#if 0
/* mark msg as sent and scanned */
xmsg.attr |= MSGSENT;
xmsg.attr |= MSGSCANNED;
MsgWriteMsg(hmsg, 0, &xmsg, NULL, 0, 0, 0, NULL);
#endif
freeMsgBuffers(&msg);
nfree(seenBys);
nfree(path);
return 1;
}
int rescanEMArea(s_area *echo, s_arealink *arealink, long rescanCount)
{
HAREA area;
HMSG hmsg;
XMSG xmsg;
dword highestMsg, i;
unsigned int rc=0;
area = MsgOpenArea((UCHAR *) echo->fileName, MSGAREA_NORMAL, /*echo -> fperm,
echo -> uid, echo -> gid,*/ (word)(echo->msgbType | MSGTYPE_ECHO));
if (area != NULL) {
/* i = highWaterMark = MsgGetHighWater(area); */
i = 0;
highestMsg = MsgGetHighMsg(area);
/* if rescanCount == -1 all mails should be rescanned */
if ((rescanCount == -1) || (rescanCount > (long)highestMsg))
rescanCount = highestMsg;
while (i <= highestMsg) {
if (i > highestMsg - rescanCount) { /* honour rescanCount paramater */
hmsg = MsgOpenMsg(area, MOPEN_RW, i);
if (hmsg != NULL) { /* msg# does not exist */
MsgReadMsg(hmsg, &xmsg, 0, 0, NULL, 0, NULL);
rc += repackEMMsg(hmsg, xmsg, echo, arealink);
MsgCloseMsg(hmsg);
}
}
i++;
}
MsgSetHighWater(area, i);
MsgCloseArea(area);
closeOpenedPkt();
} else w_log(LL_ERR, "Could not open %s: %s", echo->fileName, strerror(errno));
return rc;
}
syntax highlighted by Code2HTML, v. 0.9.1