// --------------------------------------------------------------------
// o u t b o u n d . c p p
//
// Fido messages tracker
// work with outbound directory
// --------------------------------------------------------------------
// Copyright (c) 1998,99 by Fyodor Ustinov
// FIDONet 2:5020/79
//
// All rights reserved.
// --------------------------------------------------------------------
#ifndef __GNUC__
#include <io.h>
#include <direct.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "constant.hpp"
#include "help.hpp"
#include "utils.hpp"
#include "vars.hpp"
#include "configure.hpp"
#include "parsetpl.hpp"
#include "fidoaddr.h"
#include "msg.hpp"
#include "msgbase.hpp"
#include "pktbase.hpp"
#include "attach.hpp"
#include "aka.hpp"
#include "passwd.hpp"
#include "outbound.hpp"
#include "ufmtypes.h"
#include <smapi/msgapi.h>
#include <smapi/progprot.h>
#include "tpkt.hpp"
#ifdef _AIX
#include "aix_conv.hpp"
#endif
// --------------------------------------------------------------------
typedef struct {
word c0002;
word FromNode;
word ToNode;
word FromNet;
word ToNet;
word Attr;
word Cost;
char DateTime[20];
} tPMSG;
char *LoFile = NULL;
// --------------------------------------------------------------------
void LogTraffic(cMSG &m, FA &ToAddr) {
FILE *fh;
char Buff[128];
time_t t;
Template *tpl;
if (TrafficLog == NULL) {
return;
}
if (TrafficLogTpl == NULL) {
fh = fopen(TrafficLog,"a+t");
if (fh == NULL) {
Log.Level(LOGE) << "Unable to open file '" << TrafficLog << "'" << EOL;
return;
}
t = time(NULL);
strftime(Buff,128,"-------------------- Packed on %d %b %Y %H:%M:%S --------------------\n",localtime(&t));
fputs(Buff,fh);
fprintf(fh,"From : %s, %s\n",m._FromName,(char *)(Str)m._FromAddr);
fprintf(fh,"To : %s, %s\n",m._ToName,(char *)(Str)m._ToAddr);
fprintf(fh,"Subj : %s\n",m._Subject);
fprintf(fh,"Date : %s\n",FromTime(m._Time));
fprintf(fh,"Size : %d\n",(int)(m.Body() != NULL ? strlen(m.Body()) : 0));
fprintf(fh,"Via : %s\n",(char *)(Str)ToAddr);
fputs("------------------------------------------------------------------------\n",fh);
fclose(fh);
} else {
tpl = new Template();
if (tpl->Set(TrafficLogTpl) != TRUE) {
Log.Level(LOGE) << "Unable to open trafficlog template file '" << TrafficLogTpl << "'." << EOL;
return;
}
tpl->SetMsg(m);
if (tpl->Parse()) {
tpl->Save(TrafficLog,2);
}
tpl->Clean();
delete tpl;
}
}
// --------------------------------------------------------------------
char *MakePktName(FA &f) {
static char Buff[1024];
strcpy(Buff,Outbound);
if (UseASO) {
if (Buff[strlen(Buff)-1] != PATHDELIMC) {
strcat(Buff,PATHDELIMS);
}
sprintf(Buff+strlen(Buff),"%u.%u.%u.%u",
(word)(f.Zone() & 0xffff),
(word)(f.Net() & 0xffff),
(word)(f.Node() & 0xffff),
(word)(f.Point() & 0xffff));
} else {
if (Buff[strlen(Buff)-1] == PATHDELIMC) {
Buff[strlen(Buff)-1] = '\0';
}
if ((MyAddr.Zone() & 0xffff) != (f.Zone() & 0xffff)) {
sprintf(Buff+strlen(Buff),".%03x",(word)(f.Zone() & 0xffff));
}
strcat(Buff,PATHDELIMS);
sprintf(Buff+strlen(Buff),"%04x%04x",(word)(f.Net() & 0xffff),(word)(f.Node() & 0xffff));
if ((f.Point() & 0xffff) != 0) {
strcat(Buff,PntExtension""PATHDELIMS"0000");
sprintf(Buff+strlen(Buff),"%04x",(word)(f.Point() & 0xffff));
}
}
return Buff;
}
// --------------------------------------------------------------------
char *MakeAPktName(void) {
static char Buff[1024];
char *tmt;
strcpy(Buff,APktDir);
if (Buff[strlen(Buff)-1] == PATHDELIMC) {
Buff[strlen(Buff)-1] = '\0';
}
tmt = Buff+strlen(Buff);
do {
sprintf(tmt,PATHDELIMS"%08lx"PktExtension,MsgID());
} while (access(Buff,F_OK) == 0);
return Buff;
}
// --------------------------------------------------------------------
int AddToLo(char *Txt) {
int ind;
ind = 0;
while (LoFile[ind] != 0) {
if (stricmp(&LoFile[ind],Txt) == 0) {
return TRUE;
}
while (LoFile[ind]) ind++;
ind++;
}
LoFile = (char *) realloc(LoFile,ind + 1 + strlen(Txt) + 1);
CheckMem(LoFile);
strcpy(LoFile+ind,Txt);
ind += strlen(Txt);
LoFile[ind++] = '\0';
LoFile[ind] = '\0';
return TRUE;
}
int DelFromLo(char *Txt) {
int ind;
int rc;
if (LogLevel >= 5) {
Log.Level(LOGD) << "Delete " << Txt << " from ?lo" << EOL;
}
ind = 0;
while (LoFile[ind] != 0) {
if (LoFile[ind] == '^' || LoFile[ind] == '#') {
rc = stricmp(&LoFile[ind+1],Txt);
} else {
rc = stricmp(&LoFile[ind],Txt);
}
if (rc == 0) {
LoFile[ind] = '~';
}
while(LoFile[ind] != '\0') {
ind++;
}
ind++;
}
if (LogLevel >= 5) {
Log.Level(LOGD) << "Done" << EOL;
}
return TRUE;
}
int ReadLoFile(char *Name) {
char TmtName[1024];
char *tmt2;
int ind;
#if 0
fpos_t LoSize;
#endif
FILE *fh;
strcpy(TmtName,Name);
tmt2 = TmtName + strlen(TmtName) - 2;
tmt2[0] = 'l';
tmt2[1] = 'o';
LoFile = (char *) malloc(2);
CheckMem(LoFile);
memset(LoFile,0,2);
ind = 0;
if (access(TmtName,F_OK) != 0) {
return TRUE;
}
fh = fopen(TmtName,"rt");
if (fh == NULL) {
free(LoFile);
LoFile = NULL;
return FALSE;
}
#if 0
if (fseek(fh,0L,SEEK_END) != 0) {
free(LoFile);
LoFile = NULL;
fclose(fh);
return FALSE;
}
if (fgetpos(fh,&LoSize) != 0) {
free(LoFile);
LoFile = NULL;
fclose(fh);
return FALSE;
}
if (fseek(fh,0L,SEEK_SET) != 0) {
free(LoFile);
LoFile = NULL;
fclose(fh);
return FALSE;
}
#endif
while (fgets(TmtName,1023,fh) != NULL) {
if ((tmt2 = strchr(TmtName,'\n')) != NULL) {
*tmt2 = '\0';
}
AddToLo(TmtName);
}
if (!feof(fh)) {
free(LoFile);
LoFile = NULL;
fclose(fh);
return FALSE;
}
fclose(fh);
return TRUE;
}
int ReadLoFile(FA &f, PKTMode m) {
char TmtName[1024];
strcpy(TmtName,MakePktName(f));
switch (m) {
case F_DIRECT: strcat(TmtName,".dlo"); break;
case F_CRASH: strcat(TmtName,".clo"); break;
case F_HOLD: strcat(TmtName,".hlo"); break;
case F_NORMAL: strcat(TmtName,".flo"); break;
case F_ATTACH: break;
}
return ReadLoFile(TmtName);
}
int SaveLoFile(char *Name) {
char TmtName[1024];
char *tmt2;
int ind;
FILE *fh;
if (LoFile[0] == '\0') {
free (LoFile);
LoFile = NULL;
return TRUE;
}
strcpy(TmtName,Name);
tmt2 = TmtName + strlen(TmtName) - 2;
tmt2[0] = 'l';
tmt2[1] = 'o';
fh = fcopen(TmtName,"wt");
if (fh == NULL) {
free(LoFile);
LoFile = NULL;
return FALSE;
}
ind = 0;
while (LoFile[ind] != 0) {
if (LoFile[ind] != '~') {
fprintf(fh,"%s\n",&LoFile[ind]);
}
while(LoFile[ind] != '\0') ind++;
ind++;
}
free(LoFile);
if (ftell(fh) == 0) {
fclose(fh);
unlink(TmtName);
} else {
fclose(fh);
}
LoFile = NULL;
return TRUE;
}
int SaveLoFile(FA &f, PKTMode m) {
char TmtName[1024];
strcpy(TmtName,MakePktName(f));
switch (m) {
case F_DIRECT: strcat(TmtName,".dlo"); break;
case F_CRASH: strcat(TmtName,".clo"); break;
case F_HOLD: strcat(TmtName,".hlo"); break;
case F_NORMAL: strcat(TmtName,".flo"); break;
case F_ATTACH: break;
}
return SaveLoFile(TmtName);
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
PKT::PKT() {
BsyFile = NULL;
fh = NULL;
Addr.Clean();
}
PKT::~PKT() {
Clean();
}
// --------------------------------------------------------------------
int PKT::Clean(void) {
if (fh != NULL) {
fclose(fh);
fh = NULL;
}
DelBsy();
Addr.Clean();
return TRUE;
}
// --------------------------------------------------------------------
void PKT::DelBsy(void) {
if (IgnoreBSY) return;
if (BsyFile != NULL) {
unlink(BsyFile);
free(BsyFile);
BsyFile = NULL;
}
}
// --------------------------------------------------------------------
int PKT::Set(FA &f) {
Clean();
if (!f.Valid() || f.Masked()) {
return FALSE;
}
Addr = f;
return TRUE;
}
// --------------------------------------------------------------------
int PKT::Bsy(void) {
char TmtName[1024];
char BsyName[1024];
FILE *fh;
int bfh;
if (IgnoreBSY) return TRUE;
if (BsyFile != NULL) {
return TRUE;
}
strcpy(TmtName,MakePktName(Addr));
strcpy(BsyName,TmtName);
strcat(TmtName,".ftr");
strcat(BsyName,BsyExtension);
// Create temp file name. Just for make directory, if need...
fh = fcopen(TmtName,"wb");
if (fh == NULL) return FALSE;
fclose (fh);
unlink(TmtName);
bfh = open(BsyName,O_CREAT | O_EXCL | O_RDWR,S_IREAD | S_IWRITE);
if (bfh == -1) {
return FALSE;
}
close(bfh);
BsyFile = strdup(BsyName);
return TRUE;
}
// --------------------------------------------------------------------
static char _PKTName[1024];
PKTrc PKT::Open(PKTMode m) {
long PktSize;
if (!Addr.Valid()) {
return PKTERROR;
}
Mode = m;
if (!Bsy()) {
return BSY;
}
if (Mode == F_ATTACH) {
strcpy(_PKTName,MakeAPktName());
} else {
strcpy(_PKTName,MakePktName(Addr));
switch (Mode) {
case F_DIRECT: strcat(_PKTName,".dut"); break;
case F_CRASH: strcat(_PKTName,".cut"); break;
case F_HOLD: strcat(_PKTName,".hut"); break;
case F_NORMAL: strcat(_PKTName,".out"); break;
case F_ATTACH: break;
}
}
if (access(_PKTName,F_OK) != 0) {
fh = fopen(_PKTName,"w+b");
if (fh == NULL) {
DelBsy();
return PKTERROR;
}
return NEWPKT;
} else {
fh = fopen(_PKTName,"r+b");
}
if (fh == NULL) {
DelBsy();
return PKTERROR;
}
if (fseek(fh,0L,SEEK_END) != 0) {
DelBsy();
fclose(fh);
return PKTERROR;
}
if ((PktSize = ftell(fh)) == -1) {
DelBsy();
fclose(fh);
return PKTERROR;
}
if (PktSize == 0 && Mode == F_ATTACH) {
return NEWPKT;
}
if (PktSize == 0) {
if (!AddToNullPkt) {
DelBsy();
fclose(fh);
return NULLPKT;
} else {
return NEWPKT;
}
}
if (PktSize < (long) (sizeof(tPKTH) + 2)) {
DelBsy();
fclose(fh);
return BADPKT;
}
if (fseek(fh,0,SEEK_SET) != 0) {
DelBsy();
fclose(fh);
return PKTERROR;
}
return PKTOK;
}
PKTrc PKT::AddMsg(cMSG &m, PKTMode mod) {
PKTrc rc;
int NewPkt;
tPKTH p;
tPMSG pm;
struct tm *tp;
char *tmt;
time_t ltime;
if (!Bsy()) {
return BSY;
}
if (m.fFileAttach && APktDir != NULL) {
if (!ReadLoFile(Addr,mod)) {
Clean();
return ATTERROR;
}
AddAttachToLo(m);
rc = Open(F_ATTACH);
switch (rc) {
case PKTOK:
case NEWPKT:
break;
default: Clean(); return (rc);
}
NewPkt = TRUE;
Mode = mod;
} else {
NewPkt = FALSE;
rc = Open(mod);
switch (rc) {
case PKTOK: break;
case NEWPKT: NewPkt = TRUE; break;
default: Clean(); return (rc);
}
}
memset(&p,0,sizeof(tPKTH));
p.FromZone = GetMyAka(Addr).Zone();
p.FromZone2 = GetMyAka(Addr).Zone();
p.FromNet = GetMyAka(Addr).Net();
p.FromNode = GetMyAka(Addr).Node();
// FSC-0048
// if (GetMyAka(Addr).Point() & 0xffff) {
// p.FromPoint = GetMyAka(Addr).Point() & 0xffff;
// p.AuxNet = p.FromNet;
// p.FromNet = -1;
// }
p.FromPoint = GetMyAka(Addr).Point() & 0xffff;
if ((tmt = GetPasswd(Addr)) != NULL) {
strncpy(p.Passwd,tmt,8);
}
p.ToZone = Addr.Zone();
p.ToZone2 = Addr.Zone();
p.ToNet = Addr.Net();
p.ToNode = Addr.Node();
p.ToPoint = Addr.Point();
p.c0002 = 2;
p.c0001 = 1;
p.c0100 = 256;
p.ProductCodeL = FTrackProductLo;
p.ProductCodeH = FTrackProductHi;
p.Baud = 2400;
p.RevisionH = RevisionHI;
p.RevisionL = RevisionLO;
ltime = time(NULL);
tp = localtime(<ime);
p.Year = tp->tm_year + 1900;
p.Month = tp->tm_mon;
p.Day = tp->tm_mday;
p.Hour = tp->tm_hour;
p.Minute = tp->tm_min;
p.Second = tp->tm_sec;
#ifdef _AIX
AIXConvPKTH(p);
#endif
if (fwrite(&p,sizeof(tPKTH),1,fh) != 1) {
Clean();
return PKTERROR;
}
if (!NewPkt) {
if (fseek(fh,-2,SEEK_END) != 0) {
Clean();
return PKTERROR;
}
}
memset(&pm,0,sizeof(tPMSG));
pm.c0002 = 2;
pm.FromNode = m._FromAddr.Node();
pm.ToNode = m._ToAddr.Node();
pm.FromNet = m._FromAddr.Net();
pm.ToNet = m._ToAddr.Net();
pm.Cost = m._Cost;
strncpy(pm.DateTime,FromTime(m._Time),20);
SetMsgAttr(m,pm.Attr);
#ifdef _AIX
pm.ToNode=RotateShort(pm.ToNode);
pm.FromNode=RotateShort(pm.FromNode);
pm.ToNet=RotateShort(pm.ToNet);
pm.FromNet=RotateShort(pm.FromNet);
pm.Attr=RotateShort(pm.Attr);
pm.Cost=RotateShort(pm.Cost);
pm.c0002=RotateShort(pm.c0002);
#endif
if (fwrite(&pm,sizeof(tPMSG),1,fh) != 1) {
Clean();
return PKTERROR;
}
if (strlen(m._ToName) != 0) {
if (fwrite(m._ToName,strlen(m._ToName),1,fh) != 1) {
Clean();
return PKTERROR;
}
}
if (fwrite("\0",1,1,fh) != 1) {
Clean();
return PKTERROR;
}
if (strlen(m._FromName) != 0) {
if (fwrite(m._FromName,strlen(m._FromName),1,fh) != 1) {
Clean();
return PKTERROR;
}
}
if (fwrite("\0",1,1,fh) != 1) {
Clean();
return PKTERROR;
}
if (strlen(m._Subject) != 0) {
if (fwrite(m._Subject,strlen(m._Subject),1,fh) != 1) {
Clean();
return PKTERROR;
}
}
if (fwrite("\0",1,1,fh) != 1) {
Clean();
return PKTERROR;
}
if (!WriteMsgBody(m,fh)) {
Clean();
return PKTERROR;
}
if (fwrite("\0\0",2,1,fh) != 1) {
Clean();
return PKTERROR;
}
fclose (fh);
fh = NULL;
if (m.fFileAttach && APktDir != NULL) {
memmove(_PKTName+1,_PKTName,strlen(_PKTName)+1);
_PKTName[0] = '^';
AddToLo(_PKTName);
if (!SaveLoFile(Addr,Mode)) {
Clean();
return ATTERROR;
}
}
if (m.fFileAttach && APktDir == NULL) {
if (!ReadLoFile(Addr,Mode)) {
Clean();
return ATTERROR;
}
AddAttachToLo(m);
if (!SaveLoFile(Addr,Mode)) {
Clean();
return ATTERROR;
}
}
Clean();
return PKTOK;
}
// --------------------------------------------------------------------
PKTrc PKT::Poll(PKTMode mod) {
char TmtName[1024];
int i;
strcpy(TmtName,MakePktName(Addr));
switch (mod) {
case F_DIRECT: strcat(TmtName,".dlo"); break;
case F_CRASH: strcat(TmtName,".clo"); break;
case F_HOLD: strcat(TmtName,".hlo"); break;
case F_NORMAL: strcat(TmtName,".flo"); break;
case F_ATTACH: break;
}
if (!Bsy()) {
return BSY;
}
fh = fopen(TmtName,"ab");
i = errno;
if (fh == NULL) {
Clean();
Log.Level(LOGD) << "PKT.Poll: Unbale to create/open '" << TmtName << "', Errno: " << i << EOL;
return PKTERROR;
}
fclose(fh);
Clean();
return PKTOK;
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
int UnpackOneMsg(char *&tmt) {
cMSG m;
tPMSG *p;
int LoOpened;
m.Clear();
p =(tPMSG *)tmt;
tmt += sizeof(tPMSG);
if (p->c0002 != 2) {
Log.Level(LOGE) << " Error: Destroyed packet." << EOL;
return FALSE;
}
m._FromAddr.Node(p->FromNode);
m._ToAddr.Node(p->ToNode);
m._FromAddr.Net(p->FromNet);
m._ToAddr.Net(p->ToNet);
m._Cost = p->Cost;
m._Time = ToTime(p->DateTime);
SetMsgAttr(p->Attr,m);
strncpy(m._ToName,tmt,36);
while (*tmt++ != '\0');
strncpy(m._FromName,tmt,36);
while (*tmt++ != '\0');
strncpy(m._Subject,tmt,72);
while (*tmt++ != '\0');
m.ParseMem(tmt);
m.DelLastOurVia();
if (!TempMail->WriteNewMsg(m)) {
Log.Level(LOGE) << " Unable to write message to base " << TempMail->BaseName() << EOL;
return FALSE;
}
if (m.fFileAttach) {
LoOpened = FALSE;
if (LoFile != NULL) LoOpened = TRUE;
if (!LoOpened && !ReadLoFile(_PKTName)) {
return FALSE;
}
DelAttachFromLo(m);
if (!LoOpened && !SaveLoFile(_PKTName)) {
return FALSE;
}
}
while (*tmt != '\0') tmt++;
tmt++;
return TRUE;
}
int DoRepackFile(char *Name) {
char *tmt,*tmt2;
FILE *fh;
long PktSize;
fh = fopen(Name,"rb");
if (fh == NULL) {
Log.Level(LOGE) << "Unable to open " << Name << EOL;
return TRUE;
}
if (fseek(fh,0,SEEK_END) != 0) {
Log.Level(LOGE) << "Error reading " << Name << EOL;
fclose(fh);
return TRUE;
}
if ((PktSize = ftell(fh)) == 0) {
Log.Level(LOGW) << "Packet " << Name << " have null size. Skipped." << EOL;
fclose(fh);
return TRUE;
}
if (PktSize < (long) (sizeof(tPKTH) + 2)) {
Log.Level(LOGE) << "Packet " << Name << " is wrong." << EOL;
fclose(fh);
return TRUE;
}
if (fseek(fh,0,SEEK_SET) != 0) {
Log.Level(LOGE) << "Error reading " << Name << EOL;
fclose(fh);
return TRUE;
}
Log.Level(LOGI) << "Unpack " << Name << EOL;
tmt = (char *) malloc(PktSize);
CheckMem(tmt);
tmt2 = tmt;
if (fread(tmt,PktSize,1,fh) != 1) {
free (tmt2);
Log.Level(LOGE) << "Error reading " << Name << EOL;
fclose(fh);
return TRUE;
}
fclose(fh);
tmt += sizeof(tPKTH);
while (*tmt == '\2') {
if (!UnpackOneMsg(tmt)) {
free (tmt2);
return TRUE;
}
}
unlink(Name);
free (tmt2);
return TRUE;
}
static int _FileInAPKT(char *FName) {
char Buff[1024];
char *tmt;
Log.Level(LOGD) << "_FileInAPKT: Check '" << FName << "' in APKT dir?" << EOL;
strcpy(Buff,FName);
tmt = strrchr(Buff,PATHDELIMC);
if (tmt != NULL) *tmt = '\0';
if (stricmp(Buff,APktDir) != 0) return FALSE;
Log.Level(LOGD) << "_FileInAPKT: Check '" << FName << "' is a PKT?" << EOL;
if (tmt != NULL) *tmt = PATHDELIMC;
tmt = strrchr(Buff,'.');
if (tmt == NULL || fsCompareName(tmt,".[Pp][Kk][Tt]") != 0) {
return FALSE;
}
Log.Level(LOGD) << "_FileInAPKT: Ok. '" << FName << "' is a PKT." << EOL;
return TRUE;
}
int DoRepackAPKT(char *Name) {
int ind;
Log.Level(LOGD) << "Unpack APkt " << Name << EOL;
if (APktDir == NULL) return TRUE;
if (!ReadLoFile(Name)) {
Log.Level(LOGE) << "Unable to read ?lo file" << EOL;
Log.Level(LOGD) << "Name == " << Name << EOL;
return TRUE;
}
ind = 0;
while (LoFile[ind] != 0) {
if (LoFile[ind] != '~') {
if (LoFile[ind] == '^' || LoFile[ind] == '#') ind++;
if (_FileInAPKT(&LoFile[ind])) {
if (!DoRepackFile(&LoFile[ind])) {
free(LoFile);
return TRUE;
}
DelFromLo(&LoFile[ind]);
}
}
while(LoFile[ind] != '\0') ind++;
ind++;
}
if (!SaveLoFile(Name)) {
Log.Level(LOGE) << "Unable to save ?lo file" << EOL;
Log.Level(LOGD) << "Name == " << Name << EOL;
return TRUE;
}
return TRUE;
}
int DoRepackBundle(char *Name) {
char Buff[1024];
char TmtName[1024];
char *tmt;
FILE *fh;
int bfh;
Log.Level(LOGD) << "DoRepackBundle.Name == " << Name << EOL;
strcpy(Buff,Name);
tmt = strrchr(Buff,'.');
if (tmt == NULL) {
return TRUE;
}
*tmt = '\0';
tmt++;
if (strchr("fcdohFCDOH",*tmt) == NULL) {
return TRUE;
}
strcpy(_PKTName,Name);
strcpy(TmtName,Buff);
strcat(TmtName,".ftr");
strcat(Buff,BsyExtension);
fh = fcopen(TmtName,"wb");
if (fh == NULL) {
Log.Level(LOGW) << "Unable to create temp file '" << Name << "'" << EOL;
return TRUE;
}
fclose (fh);
unlink(TmtName);
bfh = open(Buff,O_CREAT | O_EXCL | O_RDWR,S_IREAD | S_IWRITE);
if (bfh == -1) {
Log.Level(LOGW) << "Packet " << Name << " is locked." << EOL;
return TRUE;
}
close(bfh);
if (toupper((uchar)Name[strlen(Name)-1]) == 'T') {
if (!DoRepackFile(Name)) {
unlink(Buff);
return TRUE;
}
}
if (!DoRepackAPKT(Name)) {
unlink(Buff);
return TRUE;
}
unlink(Buff);
return TRUE;
}
int DoRepackDir(char *Name);
int DoRepackPoints(char *Dir) {
char fdir[1024];
DIR *dd;
struct dirent *ff;
struct stat statb;
dd = opendir(dirslashbug(Dir));
if (dd == NULL) {
return TRUE;
}
while ((ff = readdir(dd)) != NULL) {
if (fsCompareName(ff->d_name,"*.[pP][nN][tT]") != 0) {
strcpy(fdir,Dir);
strcat(fdir,ff->d_name);
strcat(fdir,PATHDELIMS);
if (stat(dirslashbug(fdir),&statb) == 0 && S_ISDIR(statb.st_mode)) {
DoRepackDir(fdir);
}
}
}
closedir(dd);
return TRUE;
}
int DoRepackDir(char *Name) {
char fdir[1024];
char *tmt;
DIR *dd;
struct dirent *ff;
struct stat statb;
Log.Level(LOGD) << "DoRepackDir: " << Name << EOL;
if (strlen(Name) == 0) return TRUE;
strcpy(fdir,Name);
if (fdir[strlen(fdir)-1] == PATHDELIMC) fdir[strlen(fdir)-1] = '\0';
tmt = strrchr(fdir,'.');
if (tmt != NULL) {
if (strrchr(tmt,PATHDELIMC) != NULL) {
tmt = NULL;
} else {
tmt = tmt - fdir + Name;
}
}
if (tmt != NULL) {
tmt++;
strncpy(fdir,tmt,3);
fdir[3] = '\0';
if (fdir[2] == PATHDELIMC) fdir[2] = '\0';
if (fdir[1] == PATHDELIMC) fdir[1] = '\0';
if (!StrIsXNum(fdir) && stricmp(fdir,"pnt") != 0) {
return TRUE;
}
}
if (tmt == NULL || stricmp(tmt,"pnt"PATHDELIMS) != 0) {
DoRepackPoints(Name);
}
Log.Level(LOGD) << "Unpack dir " << Name << " by mask *.?ut" << EOL;
dd = opendir(dirslashbug(Name));
if (dd != NULL) {
while ((ff = readdir(dd)) != NULL) {
if(fsCompareName(ff->d_name,"*.?[Uu][Tt]") != 0) {
strcpy(fdir,Name);
strcat(fdir,ff->d_name);
if (stat(fdir,&statb) == 0 && S_ISREG(statb.st_mode)) {
DoRepackBundle(fdir);
}
}
}
closedir(dd);
}
if (APktDir == NULL) return TRUE;
Log.Level(LOGD) << "Unpack dir " << Name << " by mask *.?lo" << EOL;
dd = opendir(dirslashbug(Name));
if (dd == NULL) {
return TRUE;
}
while ((ff = readdir(dd)) != NULL) {
if (fsCompareName(ff->d_name,"*.?[Ll][Oo]") != 0) {
strcpy(fdir,Name);
strcat(fdir,ff->d_name);
if (stat(fdir,&statb) == 0 && S_ISREG(statb.st_mode)) {
DoRepackBundle(fdir);
}
}
}
closedir(dd);
return TRUE;
}
int DoRepack(void) {
char Buff[1024];
char fname[1024];
char fdir[1024];
DIR *dd;
struct dirent *ff;
struct stat statb;
int rc;
Log.Level(LOGD) << "--==( DoRepack )==--" << EOL;
Log.Level(LOGD) << "DoRepack started. Outbound directory: '" << Outbound << "'." << EOL;
TempMail->Rewind();
strcpy(Buff,Outbound);
if (Buff[strlen(Buff)-1] == PATHDELIMC) {
Buff[strlen(Buff)-1] = '\0';
}
GetFilePath(fdir,Buff);
GetFileName(fname,Buff);
strcat(fname,".*");
rc = stat(dirslashbug(Outbound),&statb);
if ( rc == 0 && S_ISDIR(statb.st_mode)) {
DoRepackDir(Outbound);
} else {
Log.Level(LOGD) << "DoRepack: Outbound is not a directory???" << EOL;
Log.Level(LOGD) << " rc == " << rc << EOL;
Log.Level(LOGD) << " statb.st_mode == " << statb.st_mode << EOL;
}
dd = opendir(dirslashbug(fdir));
if (dd == NULL) {
Log.Level(LOGD) << "DoRepack: Unable to open '" << fdir << "', exit." << EOL;
Log.Level(LOGD) << "--==( End DoRepack )==--" << EOL;
return TRUE;
}
while ((ff = readdir(dd)) != NULL) {
if (fsCompareName(ff->d_name,fname) != 0) {
strcpy(Buff,fdir);
strcat(Buff,ff->d_name);
strcat(Buff,PATHDELIMS);
if (stat(dirslashbug(Buff),&statb) == 0 && S_ISDIR(statb.st_mode)) {
DoRepackDir(Buff);
}
}
}
closedir(dd);
Log.Level(LOGD) << "--==( End DoRepack )==--" << EOL;
return TRUE;
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
int SetAddToNullPkt(void){
if (AddToNullPkt) {
yyerror("AddToNullPkt is already set.");
return (-1);
}
AddToNullPkt = TRUE;
return (0);
}
int SetOutbound(char *tmt){
if (Outbound != NULL) {
yyerror("Outbound directory already defined.");
return (-1);
}
if (strlen(tmt) == 0) {
yyerror("Missed parameter: Outbound directory name.");
return (-1);
}
if (APktDir != NULL && stricmp(APktDir,tmt) == 0) {
yyerror("APKT directory and Outbound directory should be in different place.");
return (-1);
}
Outbound = (char *) malloc(strlen(tmt) + 2);
CheckMem(Outbound);
strcpy(Outbound,tmt);
if (Outbound[strlen(Outbound)-1] != PATHDELIMC) {
strcat(Outbound,PATHDELIMS);
}
return 0;
}
int SetTrafficLog(char *tmt){
if (TrafficLog != NULL) {
yyerror("Traffic log already defined.");
return (-1);
}
if (strlen(tmt) == 0) {
yyerror("Missed parameter: Traffic log file name.");
return (-1);
}
TrafficLog = strdup(tmt);
return 0;
}
int SetTempMail(char *tmt){
if (TempMail != NULL) {
yyerror("Directory for TempMail already defined.");
return (-1);
}
if (strlen(tmt) == 0) {
yyerror("Missed parameter: TempMail base name.");
return (-1);
}
TempMail = MakeBase(tmt);
if (TempMail == NULL) {
return (-1);
}
if (!TempMail->Set(tmt,BASE_OUT)) {
yyerror("Unable to open TempMail base.");
return (-1);
}
if (!TempMail->CheckOut()) return (-1);
return 0;
}
int SetKillRoutedMessages(KillModeT kmode){
KillMode = kmode;
return 0;
}
int InitOutbound(void) {
if (UnpackNeed) {
if (Outbound == NULL) {
Log.Level(LOGE) << "Outbound directory not specified." << EOL;
return FALSE;
}
if (TempMail == NULL) {
Log.Level(LOGE) << "TempMail base not specified." << EOL;
return FALSE;
}
}
return TRUE;
}
// ---------------------------- END --------------------------------------
syntax highlighted by Code2HTML, v. 0.9.1