Add magimail (crashmail2 fork) to repo

This commit is contained in:
Andrew Pamment
2017-03-18 23:04:38 +10:00
parent 8fad85affc
commit 807574ccf4
98 changed files with 23583 additions and 7 deletions

View File

@@ -0,0 +1,358 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <oslib/os.h>
#include <oslib/osfile.h>
#include <oslib/osmisc.h>
#include <shared/types.h>
#include <shared/jbstrcpy.h>
#include <shared/parseargs.h>
#include <shared/node4d.h>
#include <magimail/version.h>
#ifdef PLATFORM_AMIGA
char *ver="$VER: CrashExport " VERSION " " __AMIGADATE__;
#endif
bool diskfull;
char cfgbuf[4000];
#define AREATYPE_NETMAIL 1
#define AREATYPE_ECHOMAIL 2
#define AREATYPE_DEFAULT 3
#define AREATYPE_BAD 4
#define AREATYPE_LOCAL 5
char tagname[100],desc[100],msgbase[10],path[100],export[1000],aka[50];
char group,areatype;
bool unconfirmed;
#define ARG_PREFSFILE 0
#define ARG_OUTFILE 1
#define ARG_FORMAT 2
#define ARG_GROUP 3
struct argument args[] =
{ { ARGTYPE_STRING, "PREFSFILE", ARGFLAG_AUTO | ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "OUTFILE", ARGFLAG_AUTO | ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "FORMAT", ARGFLAG_AUTO | ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "GROUP", 0, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
#define FORMAT_AREASBBS 0
#define FORMAT_FORWARD 1
#define FORMAT_FORWARDNODESC 2
#define FORMAT_GOLDED 3
#define FORMAT_TIMED 4
int format;
bool CheckFlags(char group,char *node)
{
int c;
for(c=0;c<strlen(node);c++)
{
if(toupper(group)==toupper(node[c]))
return(TRUE);
}
return(FALSE);
}
void writearea(osFile fh)
{
int c;
char escdesc[100];
char *gedmsgbase,*gedtype,*gedflags;
char gedgroupbuf[10];
char *timflags,*timkeyword;
/* Never write unconfirmed areas to output file */
if(unconfirmed)
return;
/* Never write default areas to output file */
if(areatype == AREATYPE_DEFAULT)
return;
/* Only write if in the right group */
if(args[ARG_GROUP].data && !CheckFlags(group,args[ARG_GROUP].data))
return;
/* Escape description */
strcpy(escdesc,desc);
for(c=0;escdesc[c];c++) /* Desc can't contain " */
if(escdesc[c] == '\"') escdesc[c]='\'';
switch(format)
{
case FORMAT_AREASBBS:
if(areatype != AREATYPE_NETMAIL && areatype != AREATYPE_LOCAL) /* Don't write netmail areas */
{
if(stricmp(msgbase,"MSG")==0) osFPrintf(fh,"%s %s %s\n",path,tagname,export);
else if(stricmp(msgbase,"JAM")==0) osFPrintf(fh,"!%s %s %s\n",path,tagname,export);
else if(stricmp(msgbase,"")==0) osFPrintf(fh,"#%s %s %s\n",tagname,tagname,export);
else osFPrintf(fh,"%s:%s %s %s\n",msgbase,path,tagname,export);
}
break;
case FORMAT_FORWARD: /* Don't write netmail, local or BAD areas */
if(areatype == AREATYPE_ECHOMAIL)
{
if(desc[0]) osFPrintf(fh,"%s %s\n",tagname,desc);
else osFPrintf(fh,"%s\n",tagname);
}
break;
case FORMAT_FORWARDNODESC: /* Don't write netmail or BAD areas */
if(areatype == AREATYPE_ECHOMAIL)
{
osFPrintf(fh,"%s\n",tagname);
}
break;
case FORMAT_GOLDED:
if(path[0]) /* Don't write pass-through areas */
{
if(stricmp(msgbase,"MSG")==0) gedmsgbase="FTS1";
else if(stricmp(msgbase,"JAM")==0) gedmsgbase="JAM";
else return;
if(areatype == AREATYPE_NETMAIL) gedtype="NET";
else if(areatype == AREATYPE_LOCAL) gedtype="LOCAL";
else gedtype="ECHO";
if(areatype == AREATYPE_NETMAIL) gedflags="(Loc Pvt)";
else gedflags="(Loc)";
if(group) sprintf(gedgroupbuf,"%c",group);
else strcpy(gedgroupbuf,"0");
osFPrintf(fh,"AREADEF %s \"%s\" %s %s %s %s %s %s\n",tagname,escdesc,gedgroupbuf,gedtype,gedmsgbase,path,aka,gedflags);
}
break;
case FORMAT_TIMED:
if(path[0]) /* Don't write pass-through areas */
{
if(stricmp(msgbase,"MSG")==0) timflags="";
else if(stricmp(msgbase,"JAM")==0) timflags=" -J";
else return;
if(areatype == AREATYPE_NETMAIL) timkeyword="NetArea";
else if(areatype == AREATYPE_LOCAL) timkeyword="LocalArea";
else timkeyword="EchoArea";
osFPrintf(fh,"%s \"%s\" %s %s -P%s%s\n",timkeyword,escdesc,tagname,path,aka,timflags);
}
break;
}
}
int main(int argc, char **argv)
{
osFile ifh,ofh;
char sysopname[100],cfgword[30],buf[100];
uint32_t jbcpos;
time_t t;
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
if(stricmp((char *)args[ARG_FORMAT].data,"areasbbs")==0)
{
format=FORMAT_AREASBBS;
}
else if(stricmp((char *)args[ARG_FORMAT].data,"forward")==0)
{
format=FORMAT_FORWARD;
}
else if(stricmp((char *)args[ARG_FORMAT].data,"forwardnodesc")==0)
{
format=FORMAT_FORWARDNODESC;
}
else if(stricmp((char *)args[ARG_FORMAT].data,"golded")==0)
{
format=FORMAT_GOLDED;
}
else if(stricmp((char *)args[ARG_FORMAT].data,"timed")==0)
{
format=FORMAT_TIMED;
}
else
{
printf("Unknown format \"%s\"\n",(char *)args[ARG_FORMAT].data);
osEnd();
exit(OS_EXIT_ERROR);
}
if(!(ifh=osOpen(args[ARG_PREFSFILE].data,MODE_OLDFILE)))
{
uint32_t err=osError();
printf("Failed to open %s for reading\n",(char *)args[ARG_PREFSFILE].data);
printf("Error: %s",osErrorMsg(err));
osEnd();
exit(OS_EXIT_ERROR);
}
if(!(ofh=osOpen(args[ARG_OUTFILE].data,MODE_NEWFILE)))
{
uint32_t err=osError();
printf("Failed to open %s for writing\n",(char *)args[ARG_OUTFILE].data);
printf("Error: %s",osErrorMsg(err));
osClose(ifh);
osEnd();
exit(OS_EXIT_ERROR);
}
time(&t);
osFPrintf(ofh,"; Generated by CrashExport %s\n; %s\n",VERSION,ctime(&t));
if(format == FORMAT_AREASBBS)
{
/* Get default origin and sysop name for areas.bbs */
strcpy(sysopname,"Sysop");
while(osFGets(ifh,cfgbuf,4000))
{
jbcpos=0;
jbstrcpy(cfgword,cfgbuf,30,&jbcpos);
if(stricmp(cfgword,"SYSOP")==0)
jbstrcpy(sysopname,cfgbuf,100,&jbcpos);
}
osFPrintf(ofh,"%s ! %s\n","Default origin",sysopname);
osSeek(ifh,0,OFFSET_BEGINNING);
}
while(osFGets(ifh,cfgbuf,4000))
{
jbcpos=0;
jbstrcpy(cfgword,cfgbuf,30,&jbcpos);
if(stricmp(cfgword,"AREA")==0 || stricmp(cfgword,"NETMAIL")==0 || stricmp(cfgword,"LOCALAREA")==0)
{
if(tagname[0])
writearea(ofh);
group=0;
unconfirmed=FALSE;
export[0]=0;
desc[0]=0;
jbstrcpy(tagname,cfgbuf,100,&jbcpos);
jbstrcpy(aka,cfgbuf,50,&jbcpos);
jbstrcpy(msgbase,cfgbuf,10,&jbcpos);
jbstrcpy(path,cfgbuf,100,&jbcpos);
if(stricmp(cfgword,"NETMAIL")==0)
areatype=AREATYPE_NETMAIL;
else if(stricmp(cfgword,"LOCALAREA")==0)
areatype=AREATYPE_LOCAL;
else if(stricmp(tagname,"BAD")==0)
areatype=AREATYPE_BAD;
else if(stricmp(tagname,"DEFAULT")==0 || strnicmp(tagname,"DEFAULT_",8)==0)
areatype=AREATYPE_DEFAULT;
else
areatype=AREATYPE_ECHOMAIL;
}
if(stricmp(cfgword,"EXPORT")==0)
{
struct Node4D tpl4d,tmp4d;
tpl4d.Zone=0;
tpl4d.Net=0;
tpl4d.Node=0;
tpl4d.Point=0;
while(jbstrcpy(buf,cfgbuf,100,&jbcpos))
{
if(buf[0]=='!' || buf[0]=='%' || buf[0]=='@')
strcpy(buf,&buf[1]);
if(Parse4DTemplate(buf,&tmp4d,&tpl4d))
{
Copy4D(&tpl4d,&tmp4d);
tpl4d.Point=0;
Print4D(&tmp4d,buf);
if(strlen(export) < sizeof(export)-20)
{
if(export[0]) strcat(export," ");
strcat(export,buf);
}
}
}
}
if(stricmp(cfgword,"UNCONFIRMED")==0)
{
unconfirmed=TRUE;
}
if(stricmp(cfgword,"DESCRIPTION")==0)
{
jbstrcpy(desc,cfgbuf,100,&jbcpos);
}
if(stricmp(cfgword,"GROUP")==0)
{
if(jbstrcpy(buf,cfgbuf,100,&jbcpos))
group=buf[0];
}
}
if(tagname[0])
writearea(ofh);
osClose(ofh);
osClose(ifh);
osEnd();
exit(OS_EXIT_OK);
}

View File

@@ -0,0 +1,156 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oslib/os.h>
#include <oslib/osfile.h>
#include <shared/parseargs.h>
#include <shared/node4d.h>
#include <cmnllib/cmnllib.h>
#include <magimail/version.h>
#ifdef PLATFORM_AMIGA
char *ver="$VER: CrashCompileNL " VERSION " " __AMIGADATE__;
#endif
#define ARG_NODE 0
#define ARG_DIRECTORY 1
struct argument args[] =
{ { ARGTYPE_STRING, "NODE", ARGFLAG_AUTO | ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "DIRECTORY", ARGFLAG_AUTO, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
bool nomem,diskfull;
void strip(char *str)
{ int c;
for(c=strlen(str)-1;str[c] < 33 && c>=0;c--) str[c]=0;
}
int main(int argc, char **argv)
{
osFile fh;
char line[200],*dir,*buf;
struct Node4D n4d;
struct cmnlIdx idx;
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
if(args[ARG_DIRECTORY].data)
dir=(char *)args[ARG_DIRECTORY].data;
else
dir=getenv("CMNODELISTDIR");
if(!dir)
{
printf("No directory specified and CMNODELISTDIR not set\n");
osEnd();
exit(OS_EXIT_ERROR);
}
if(!Parse4D((char *)args[ARG_NODE].data,&n4d))
{
printf("Invalid node %s\n",(char *)args[ARG_NODE].data);
exit(OS_EXIT_ERROR);
}
if(!(fh=cmnlOpenNL(dir)))
{
printf("%s\n",cmnlLastError());
exit(OS_EXIT_ERROR);
}
idx.zone=n4d.Zone;
idx.net=n4d.Net;
idx.node=n4d.Node;
idx.point=n4d.Point;
if(!cmnlFindNL(fh,dir,&idx,line,200))
{
cmnlCloseNL(fh);
printf("%s\n",cmnlLastError());
exit(OS_EXIT_ERROR);
}
cmnlCloseNL(fh);
printf("Node %d:%d/%d.%d\n",idx.zone,idx.net,idx.node,idx.point);
printf("Region %d, Hub %d\n",idx.region,idx.hub);
strip(line);
if(line[0]==',')
{
buf="Node";
strtok(line,","); /* Skip number */
}
else
{
buf=strtok(line,",");
if(!buf) buf="";
strtok(NULL,","); /* Skip number */
}
printf("Node is listed as a %s\n",buf);
if((buf=strtok(NULL,",")))
{
printf("Name: %s\n",buf);
}
if((buf=strtok(NULL,",")))
{
printf("Location: %s\n",buf);
}
if((buf=strtok(NULL,",")))
{
printf("Sysop: %s\n",buf);
}
if((buf=strtok(NULL,",")))
{
printf("Phone: %s\n",buf);
}
if((buf=strtok(NULL,",")))
{
printf("Baud: %s\n",buf);
}
if((buf=strtok(NULL,"")))
{
printf("Flags: %s\n",buf);
}
osEnd();
exit(OS_EXIT_OK);
}

View File

@@ -0,0 +1,341 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <shared/types.h>
#include <shared/jbstrcpy.h>
#include <shared/parseargs.h>
#include <shared/jblist.h>
#include <shared/path.h>
#include <shared/mystrncpy.h>
#include <oslib/os.h>
#include <oslib/osmem.h>
#include <oslib/osfile.h>
#include <oslib/osdir.h>
#include <oslib/osmisc.h>
#include <magimail/version.h>
#ifdef PLATFORM_AMIGA
char *ver="$VER: CrashList " VERSION " " __AMIGADATE__;
#endif
#define ARG_DIRECTORY 0
struct argument args[] =
{ { ARGTYPE_STRING, "DIRECTORY", ARGFLAG_AUTO, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
struct idx
{
uint16_t zone,net,node,point,region,hub;
uint32_t offset;
};
bool nomem,diskfull;
void putuword(char *buf,uint32_t offset,uint16_t num)
{
buf[offset]=num%256;
buf[offset+1]=num/256;
}
void putulong(char *buf,uint32_t offset,uint32_t num)
{
buf[offset]=num%256;
buf[offset+1]=(num / 256) % 256;
buf[offset+2]=(num / 256 / 256) % 256;
buf[offset+3]=(num / 256 / 256 / 256) % 256;
}
void WriteIdx(osFile fh,struct idx *idx)
{
char binbuf[16];
putuword(binbuf,0,idx->zone);
putuword(binbuf,2,idx->net);
putuword(binbuf,4,idx->node);
putuword(binbuf,6,idx->point);
putuword(binbuf,8,idx->region);
putuword(binbuf,10,idx->hub);
putulong(binbuf,12,idx->offset);
osWrite(fh,binbuf,sizeof(binbuf));
}
char nlname[100];
char *findfile,*finddir;
time_t newest;
bool isnodelistending(char *name)
{
if(strlen(name)<4) return(FALSE);
if(name[strlen(name)-4]!='.') return(FALSE);
if(!isdigit(name[strlen(name)-3])) return(FALSE);
if(!isdigit(name[strlen(name)-2])) return(FALSE);
if(!isdigit(name[strlen(name)-1])) return(FALSE);
return(TRUE);
}
void scandirfunc(char *file)
{
char buf[500];
struct osFileEntry *fe;
if(isnodelistending(file))
{
if(strnicmp(file,findfile,strlen(file)-4)==0)
{
MakeFullPath(finddir,file,buf,500);
if((fe=osGetFileEntry(buf)))
{
if(nlname[0]==0 || newest < fe->Date)
{
mystrncpy(nlname,fe->Name,100);
newest=fe->Date;
}
osFree(fe);
}
}
}
}
bool FindList(char *dir,char *file,char *dest)
{
MakeFullPath(dir,file,dest,500);
if(osExists(dest))
return(TRUE);
nlname[0]=0;
newest=0;
findfile=file;
finddir=dir;
if(!osScanDir(dir,scandirfunc))
{
uint32_t err=osError();
printf("Failed to scan directory %s\n",dir);
printf("Error: %s\n",osErrorMsg(err));
return(FALSE);
}
if(nlname[0]==0)
{
printf("Found no nodelist matching %s in %s\n",file,dir);
return(FALSE);
}
MakeFullPath(dir,nlname,dest,500);
return(TRUE);
}
void ProcessList(char *dir,char *file,osFile ifh,uint16_t defzone)
{
struct idx idx;
char buf[500];
osFile nfh;
if(!FindList(dir,file,buf))
return;
if(!(nfh=osOpen(buf,MODE_OLDFILE)))
{
uint32_t err=osError();
printf("Failed to read %s\n",buf);
printf("Error: %s\n",osErrorMsg(err));
return;
}
strcpy(buf,(char *)GetFilePart(buf));
printf("Processing nodelist %s...\n",buf);
osWrite(ifh,buf,100);
idx.zone=defzone;
idx.net=0;
idx.node=0;
idx.point=0;
idx.region=0;
idx.hub=0;
idx.offset=0;
idx.offset=osFTell(nfh);
while(osFGets(nfh,buf,500))
{
if(strnicmp(buf,"Zone,",5)==0)
{
idx.zone=atoi(&buf[5]);
idx.region=0;
idx.net=idx.zone;
idx.hub=0;
idx.node=0;
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Region,",7)==0)
{
idx.region=atoi(&buf[7]);
idx.net=idx.region;
idx.hub=0;
idx.node=0;
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Host,",5)==0)
{
idx.net=atoi(&buf[5]);
idx.hub=0;
idx.node=0;
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Hub,",4)==0)
{
idx.hub=atoi(&buf[4]);
idx.node=idx.hub;
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Pvt,",4)==0)
{
idx.node=atoi(&buf[4]);
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Hold,",5)==0)
{
idx.node=atoi(&buf[5]);
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,",",1)==0)
{
idx.node=atoi(&buf[1]);
idx.point=0;
WriteIdx(ifh,&idx);
}
if(strnicmp(buf,"Point,",6)==0)
{
idx.point=atoi(&buf[6]);
WriteIdx(ifh,&idx);
}
idx.offset=osFTell(nfh);
}
idx.zone=0;
idx.region=0;
idx.net=0;
idx.hub=0;
idx.node=0;
idx.point=0;
idx.offset=0xffffffff;
WriteIdx(ifh,&idx);
}
int main(int argc, char **argv)
{
osFile lfh,ifh;
char *dir,buf[200],cfgbuf[200],file[100];
uint32_t jbcpos,zone;
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
dir=OS_CURRENT_DIR;
if(args[ARG_DIRECTORY].data)
dir=(char *)args[ARG_DIRECTORY].data;
MakeFullPath(dir,"cmnodelist.prefs",buf,200);
if(!(lfh=osOpen(buf,MODE_OLDFILE)))
{
uint32_t err=osError();
printf("Failed to open %s for reading\n",buf);
printf("Error: %s\n",osErrorMsg(err));
osEnd();
exit(OS_EXIT_ERROR);
}
MakeFullPath(dir,"cmnodelist.index",buf,200);
if(!(ifh=osOpen(buf,MODE_NEWFILE)))
{
uint32_t err=osError();
printf("Failed to open %s for writing (nodelist in use?)\n",buf);
printf("Error: %s\n",osErrorMsg(err));
osClose(lfh);
osEnd();
exit(OS_EXIT_ERROR);
}
osWrite(ifh,"CNL1",4);
while(osFGets(lfh,cfgbuf,200))
{
if(cfgbuf[0]!=';')
{
jbcpos=0;
if(jbstrcpy(file,cfgbuf,100,&jbcpos))
{
zone=0;
if(jbstrcpy(buf,cfgbuf,10,&jbcpos))
zone=atoi(buf);
ProcessList(dir,file,ifh,zone);
}
}
}
osClose(lfh);
osClose(ifh);
osEnd();
exit(OS_EXIT_OK);
}
/* Hitta r<>tt nodelista */

View File

@@ -0,0 +1,726 @@
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <shared/types.h>
#include <shared/mystrncpy.h>
#include <shared/path.h>
#include <shared/parseargs.h>
#include <shared/jblist.h>
#include <shared/node4d.h>
#include <oslib/os.h>
#include <oslib/osmem.h>
#include <oslib/osfile.h>
#include <oslib/osdir.h>
#include <oslib/osmisc.h>
#include <magimail/version.h>
#define NET(x) (x >> 16)
#define NODE(x) (x & 0xFFFF)
#define TYPE_CRASH 0
#define TYPE_DIRECT 1
#define TYPE_NORMAL 2
#define TYPE_HOLD 3
#define TYPE_REQUEST 4
char *type_names[] = { "Crash", "Direct", "Normal", "Hold", "Request" };
uint32_t TotalFiles=0;
uint32_t TotalBytes=0;
uint32_t TotalRequests=0;
struct fileentry
{
struct fileentry *Next;
struct Node4D Node;
char file[100];
char dir[100];
uint32_t size;
time_t date;
uint32_t type;
bool flow;
};
struct Node4DPat
{
char Zone[10];
char Net[10];
char Node[10];
char Point[10];
};
char *cfg_Dir;
uint32_t cfg_Zone;
struct Node4DPat cfg_Pattern;
bool cfg_Verbose;
#define ARG_DIRECTORY 0
#define ARG_ZONE 1
#define ARG_PATTERN 2
#define ARG_VERBOSE 3
struct argument args[] =
{ { ARGTYPE_STRING, "DIRECTORY", ARGFLAG_AUTO, NULL },
{ ARGTYPE_STRING, "ZONE", ARGFLAG_AUTO, NULL },
{ ARGTYPE_STRING, "PATTERN", ARGFLAG_AUTO, NULL },
{ ARGTYPE_BOOL, "VERBOSE", 0, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
struct jbList list;
/* Some stuff for node pattern (taken from MagiMail) */
bool Parse4DPat(char *buf, struct Node4DPat *node)
{
uint32_t c=0,tempc=0;
char temp[10];
bool GotZone=FALSE,GotNet=FALSE,GotNode=FALSE;
strcpy(node->Zone,"*");
strcpy(node->Net,"*");
strcpy(node->Node,"*");
strcpy(node->Point,"*");
if(strcmp(buf,"*")==0)
return(TRUE);
for(c=0;c<strlen(buf);c++)
{
if(buf[c]==':')
{
if(GotZone || GotNet || GotNode) return(FALSE);
strcpy(node->Zone,temp);
GotZone=TRUE;
tempc=0;
}
else if(buf[c]=='/')
{
if(GotNet || GotNode) return(FALSE);
strcpy(node->Net,temp);
GotNet=TRUE;
tempc=0;
}
else if(buf[c]=='.')
{
if(GotNode) return(FALSE);
strcpy(node->Node,temp);
node->Point[0]=0;
GotNode=TRUE;
tempc=0;
}
else if((buf[c]>='0' && buf[c]<='9') || buf[c]=='*' || buf[c]=='?')
{
if(tempc<9)
{
temp[tempc++]=buf[c];
temp[tempc]=0;
}
}
else return(FALSE);
}
if(GotZone && !GotNet)
{
strcpy(node->Net,temp);
}
else if(GotNode)
{
strcpy(node->Point,temp);
}
else
{
strcpy(node->Node,temp);
strcpy(node->Point,"0");
}
return(TRUE);
}
int NodeCompare(char *pat,uint16_t num)
{
char buf[10];
uint8_t c;
sprintf(buf,"%u",num);
if(pat[0]==0) return(0);
for(c=0;c<strlen(pat);c++)
{
if(pat[c]=='*') return(0);
if(pat[c]!=buf[c] && pat[c]!='?') return(1);
}
if(buf[c]!=0)
return(1);
return(0);
}
int Compare4DPat(struct Node4DPat *nodepat,struct Node4D *node)
{
if(node->Zone!=0)
if(NodeCompare(nodepat->Zone, node->Zone )!=0) return(1);
if(NodeCompare(nodepat->Net, node->Net )!=0) return(1);
if(NodeCompare(nodepat->Node, node->Node )!=0) return(1);
if(NodeCompare(nodepat->Point,node->Point)!=0) return(1);
return(0);
}
/* Some other functions from MagiMail */
char *unit(uint32_t i)
{
static char buf[20];
if ((i>10000000)||(i<-10000000)) sprintf(buf,"%uM",i/(1024*1024));
else if ((i>10000)||(i<-10000)) sprintf(buf,"%uK",i/1024);
else sprintf(buf,"%u",i);
return buf;
}
unsigned long hextodec(char *hex)
{
char *hextab="0123456789abcdef";
int c=0,c2=0;
unsigned long result=0;
for(;;)
{
for(c2=0;c2<16;c2++)
if(tolower(hex[c]) == hextab[c2]) break;
if(c2 == 16)
return(result); /* End of correct hex number */
result *= 16;
result += c2;
c++;
}
}
void strip(char *str)
{
int c;
for(c=strlen(str)-1;str[c] < 33 && c>=0;c--)
str[c]=0;
}
/* Display entries in the list */
char *PrintNode(struct Node4D *node)
{
static char buf[50];
Print4D(node,buf);
return(buf);
}
char *PrintDate(time_t date)
{
static char buf[50];
struct tm *tp;
char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","???"};
tp=localtime(&date);
sprintf(buf,"%02d-%s-%02d %02d:%02d",
tp->tm_mday,
monthnames[tp->tm_mon],
tp->tm_year % 100,
tp->tm_hour,
tp->tm_min);
return(buf);
}
char *PrintFlowSize(struct fileentry *fe)
{
static char buf[50];
char fullfile[200],line[200];
osFile os;
struct osFileEntry *osfe;
uint32_t files,bytes;
files=0;
bytes=0;
MakeFullPath(cfg_Dir,fe->file,fullfile,200);
if(!(os=osOpen(fullfile,MODE_OLDFILE)))
{
sprintf(buf,"?/?");
return(buf);
}
while(osFGets(os,line,200))
{
strip(line);
if(line[0])
{
if(line[0] == '#' || line[0] == '^' || line[0] == '-')
strcpy(line,&line[1]);
if(stricmp(GetFilePart(line),line) == 0)
{
/* No path specified */
MakeFullPath(fe->dir,line,fullfile,200);
osfe=osGetFileEntry(fullfile);
}
else
{
osfe=osGetFileEntry(line);
}
if(osfe)
{
files++;
bytes+=osfe->Size;
TotalFiles++;
TotalBytes+=osfe->Size;
osFree(osfe);
}
}
}
osClose(os);
sprintf(buf,"%s/%u",unit(bytes),files);
return(buf);
}
void DisplayFlowContents(struct fileentry *fe)
{
char size[40],*todo;
char fullfile[200],line[200];
osFile os;
struct osFileEntry *osfe;
MakeFullPath(cfg_Dir,fe->file,fullfile,200);
if(!(os=osOpen(fullfile,MODE_OLDFILE)))
{
printf("Failed to open file\n");
}
else
{
while(osFGets(os,line,200))
{
strip(line);
if(line[0])
{
todo="";
if(line[0] == '#' || line[0] == '^') todo="(To be truncated)";
if(line[0] == '-') todo="(To be deleted)";
if(line[0] == '#' || line[0] == '^' || line[0] == '-')
strcpy(line,&line[1]);
if(stricmp(GetFilePart(line),line) == 0)
{
/* No path specified */
MakeFullPath(fe->dir,line,fullfile,200);
osfe=osGetFileEntry(fullfile);
}
else
{
osfe=osGetFileEntry(line);
}
strcpy(size,"Not found");
if(osfe)
{
sprintf(size, "%s", unit(osfe->Size));
osFree(osfe);
}
printf(" %-39.39s %10s %s\n",line,size,todo);
}
}
osClose(os);
}
printf("\n");
}
char *PrintReqNums(struct fileentry *fe)
{
static char buf[50];
char fullfile[200],line[200];
osFile os;
uint32_t reqs;
reqs=0;
MakeFullPath(cfg_Dir,fe->file,fullfile,200);
if(!(os=osOpen(fullfile,MODE_OLDFILE)))
{
sprintf(buf,"?/?");
return(buf);
}
while(osFGets(os,line,200))
{
strip(line);
if(line[0])
{
reqs++;
TotalRequests++;
}
}
sprintf(buf,"-/%u",reqs);
return(buf);
}
void DisplayReqContents(struct fileentry *fe)
{
char fullfile[200],line[200];
osFile os;
MakeFullPath(cfg_Dir,fe->file,fullfile,200);
if(!(os=osOpen(fullfile,MODE_OLDFILE)))
{
printf("Failed to open file\n");
}
else
{
while(osFGets(os,line,200))
{
strip(line);
if(line[0])
printf(" %s\n",line);
}
osClose(os);
}
printf("\n");
}
void DisplayFlow(struct fileentry *fe)
{
printf("%-8.8s %-17.17s %-16.16s %7.7s %s\n",
type_names[fe->type],PrintNode(&fe->Node),PrintDate(fe->date),PrintFlowSize(fe),fe->file);
if(cfg_Verbose)
DisplayFlowContents(fe);
}
void DisplayPkt(struct fileentry *fe)
{
char buf[100];
sprintf(buf,"%s/1",unit(fe->size));
printf("%-8.8s %-17.17s %-16.16s %7.7s %s\n",
type_names[fe->type],PrintNode(&fe->Node),PrintDate(fe->date),buf,fe->file);
if(cfg_Verbose)
printf("\n");
}
void DisplayReq(struct fileentry *fe)
{
printf("%-8.8s %-17.17s %-16.16s %7.7s %s\n",
type_names[fe->type],PrintNode(&fe->Node),PrintDate(fe->date),PrintReqNums(fe),fe->file);
if(cfg_Verbose)
DisplayReqContents(fe);
}
int sortcompare(const void *f1, const void *f2)
{
struct fileentry *e1,*e2;
e1=*(struct fileentry **)f1;
e2=*(struct fileentry **)f2;
return Compare4D(&e1->Node,&e2->Node);
}
void sortlist(struct jbList *list)
{
struct jbNode *jb,**buf,**work;
uint32_t count=0;
for(jb=list->First;jb;jb=jb->Next)
count++;
if(count < 2)
return;
if(!(buf=(struct jbNode **)osAlloc(count * sizeof(struct jbNode *))))
return;
work=buf;
for(jb=list->First;jb;jb=jb->Next)
*work++=jb;
qsort(buf,(size_t)count,(size_t)sizeof(struct jbNode *),sortcompare);
jbNewList(list);
for(work=buf;count--;)
jbAddNode(list,*work++);
osFree(buf);
}
void addentry(char *dir,char *file,uint32_t type,struct Node4D *boss,bool flow)
{
struct osFileEntry *fe;
struct fileentry *entry;
struct Node4D n4d;
char buf[200];
char buf2[200];
uint32_t hex;
hex=hextodec(file);
if(boss)
{
Copy4D(&n4d,boss);
n4d.Point = hex;
}
else
{
n4d.Zone = cfg_Zone;
n4d.Net = NET(hex);
n4d.Node = NODE(hex);
n4d.Point = 0;
}
if(Compare4DPat(&cfg_Pattern,&n4d)!=0)
return;
if(dir) MakeFullPath(dir,file,buf,200);
else mystrncpy(buf,file,200);
MakeFullPath(cfg_Dir,buf,buf2,200);
if(!(fe=osGetFileEntry(buf2)))
{
return;
}
if(!(entry=osAlloc(sizeof(struct fileentry))))
{
osFree(fe);
return;
}
Copy4D(&entry->Node,&n4d);
if(dir)
{
MakeFullPath(dir,file,entry->file,100);
MakeFullPath(cfg_Dir,dir,entry->dir,100);
}
else
{
mystrncpy(entry->file,file,100);
mystrncpy(entry->dir,cfg_Dir,100);
}
mystrncpy(entry->file,buf,100);
entry->size=fe->Size;
entry->date=fe->Date;
entry->type=type;
entry->flow=flow;
jbAddNode(&list,(struct jbNode *)entry);
osFree(fe);
}
struct Node4D *scandir_boss;
char *scandir_dir;
void scandirfunc(char *file)
{
char *extptr;
uint32_t hex;
if(strlen(file) != 12)
return;
extptr=&file[strlen(file)-4];
if(stricmp(extptr,".PNT")==0 && !scandir_boss)
{
char buf[200];
struct Node4D n4d;
hex=hextodec(file);
n4d.Zone = cfg_Zone;
n4d.Net = NET(hex);
n4d.Node = NODE(hex);
n4d.Point = 0;
scandir_dir = file;
scandir_boss = &n4d;
MakeFullPath(cfg_Dir,file,buf,200);
osScanDir(buf,scandirfunc);
scandir_dir = NULL;
scandir_boss = NULL;
}
if(!stricmp(extptr,".REQ")) addentry(scandir_dir,file,TYPE_REQUEST,scandir_boss,TRUE);
if(!stricmp(extptr,".CLO")) addentry(scandir_dir,file,TYPE_CRASH,scandir_boss,TRUE);
if(!stricmp(extptr,".DLO")) addentry(scandir_dir,file,TYPE_DIRECT,scandir_boss,TRUE);
if(!stricmp(extptr,".FLO")) addentry(scandir_dir,file,TYPE_NORMAL,scandir_boss,TRUE);
if(!stricmp(extptr,".HLO")) addentry(scandir_dir,file,TYPE_HOLD,scandir_boss,TRUE);
if(!stricmp(extptr,".CUT")) addentry(scandir_dir,file,TYPE_CRASH,scandir_boss,FALSE);
if(!stricmp(extptr,".DUT")) addentry(scandir_dir,file,TYPE_DIRECT,scandir_boss,FALSE);
if(!stricmp(extptr,".OUT")) addentry(scandir_dir,file,TYPE_NORMAL,scandir_boss,FALSE);
if(!stricmp(extptr,".HUT")) addentry(scandir_dir,file,TYPE_HOLD,scandir_boss,FALSE);
}
int main(int argc, char **argv)
{
char *var;
struct fileentry *fe;
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
jbNewList(&list);
/* get outbound dir */
if((var=getenv("CMOUTBOUND")))
cfg_Dir=var;
else
cfg_Dir=OS_CURRENT_DIR;
if(args[ARG_DIRECTORY].data)
cfg_Dir=(char *)args[ARG_DIRECTORY].data;
/* Get zone */
if((var=getenv("CMOUTBOUNDZONE")))
cfg_Zone=atoi(var);
else
cfg_Zone=2;
if(args[ARG_ZONE].data)
cfg_Zone=atoi((char *)args[ARG_ZONE].data);
/* Get pattern */
strcpy(cfg_Pattern.Zone,"*");
strcpy(cfg_Pattern.Net,"*");
strcpy(cfg_Pattern.Node,"*");
strcpy(cfg_Pattern.Point,"*");
if(args[ARG_PATTERN].data)
{
if(!Parse4DPat((char *)args[ARG_PATTERN].data,&cfg_Pattern))
{
printf("Invalid node pattern \"%s\"\n",(char *)args[ARG_PATTERN].data);
osEnd();
exit(OS_EXIT_ERROR);
}
}
/* Get verbose flag */
cfg_Verbose=FALSE;
if(args[ARG_VERBOSE].data)
cfg_Verbose=TRUE;
/* Real program starts here */
printf("CrashListOut " VERSION "\n\n");
scandir_dir = NULL;
scandir_boss = NULL;
if(!osScanDir(cfg_Dir,scandirfunc))
{
uint32_t err=osError();
printf("Failed to scan directory %s\n",cfg_Dir);
printf("Error: %s",osErrorMsg(err));
return(FALSE);
}
sortlist(&list);
printf("%-8.8s %-17.17s %-16.16s %7.7s %s\n\n",
"Type","Node","Last Change","B/F","File");
if(list.First)
{
for(fe=(struct fileentry *)list.First;fe;fe=fe->Next)
{
if(fe->type == TYPE_REQUEST) DisplayReq(fe);
else if(fe->flow) DisplayFlow(fe);
else DisplayPkt(fe);
}
if(!cfg_Verbose) printf("\n");
printf("Totally %s bytes in %u files to send, %u requests.\n",unit(TotalBytes),TotalFiles,TotalRequests);
}
else
{
printf("Outbound directory is empty.\n");
}
jbFreeList(&list);
exit(OS_EXIT_OK);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,707 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <signal.h>
#include <ctype.h>
#include <shared/types.h>
#include <shared/jblist.h>
#include <shared/parseargs.h>
#include <shared/node4d.h>
#include <oslib/os.h>
#include <oslib/osmem.h>
#include <oslib/osfile.h>
#include <oslib/osmisc.h>
#include <magimail/version.h>
#define COPYRIGHT "1998,2013"
#ifdef PLATFORM_AMIGA
char *ver="$VER: CrashStats "VERSION" ("__COMMODORE_DATE__")";
#endif
#define STATS_IDENTIFIER "CST3"
static size_t ptrsize = sizeof(void *);
struct DiskAreaStats
{
char Tagname[80];
struct Node4D Aka;
char Group;
char fill_to_make_even; /* Just ignore this one */
uint32_t TotalTexts;
uint16_t Last8Days[8];
uint32_t Dupes;
time_t FirstTime;
time_t LastTime;
};
struct DiskNodeStats
{
struct Node4D Node;
uint32_t GotNetmails;
uint32_t GotNetmailBytes;
uint32_t SentNetmails;
uint32_t SentNetmailBytes;
uint32_t GotEchomails;
uint32_t GotEchomailBytes;
uint32_t SentEchomails;
uint32_t SentEchomailBytes;
uint32_t Dupes;
time_t FirstTime;
};
struct StatsNode
{
struct StatsNode *Next;
char Tagname[80];
uint32_t Average;
uint32_t Total;
uint32_t Dupes;
time_t FirstTime;
time_t LastTime;
uint16_t Last8Days[8];
};
struct NodeStatsNode
{
struct NodeStatsNode *Next;
struct Node4D Node;
uint32_t GotNetmails;
uint32_t GotNetmailBytes;
uint32_t SentNetmails;
uint32_t SentNetmailBytes;
uint32_t GotEchomails;
uint32_t GotEchomailBytes;
uint32_t SentEchomails;
uint32_t SentEchomailBytes;
uint32_t Dupes;
uint32_t Days;
time_t FirstTime;
};
#define ARG_FILE 0
#define ARG_SORT 1
#define ARG_LAST7 2
#define ARG_NOAREAS 3
#define ARG_NONODES 4
#define ARG_GROUP 5
struct argument args[] =
{ { ARGTYPE_STRING, "FILE", ARGFLAG_AUTO | ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "SORT", 0, NULL },
{ ARGTYPE_BOOL, "LAST7", 0, NULL },
{ ARGTYPE_BOOL, "NOAREAS", 0, NULL },
{ ARGTYPE_BOOL, "NONODES", 0, NULL },
{ ARGTYPE_STRING, "GROUP", 0, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
bool diskfull;
int CompareAlpha(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
return(stricmp((*s1)->Tagname,(*s2)->Tagname));
}
int CompareTotal(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
if((*s1)->Total < (*s2)->Total) return(1);
if((*s1)->Total > (*s2)->Total) return(-1);
return(0);
}
int CompareDupes(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
if((*s1)->Dupes < (*s2)->Dupes) return(1);
if((*s1)->Dupes > (*s2)->Dupes) return(-1);
return(0);
}
int CompareMsgsDay(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
if((*s1)->Average < (*s2)->Average) return(1);
if((*s1)->Average > (*s2)->Average) return(-1);
return(0);
}
int CompareFirstTime(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
if((*s1)->FirstTime < (*s2)->FirstTime) return(1);
if((*s1)->FirstTime > (*s2)->FirstTime) return(-1);
return(0);
}
int CompareLastTime(const void *a1,const void *a2)
{
struct StatsNode **s1,**s2;
s1=(struct StatsNode **)a1;
s2=(struct StatsNode **)a2;
if((*s1)->LastTime < (*s2)->LastTime) return(1);
if((*s1)->LastTime > (*s2)->LastTime) return(-1);
return(0);
}
bool Sort(struct jbList *list,char sortmode)
{
uint32_t nc;
struct StatsNode *sn,**buf,**work;
nc=0;
for(sn=(struct StatsNode *)list->First;sn;sn=sn->Next)
nc++;
if(nc==0)
return(TRUE); /* Nothing to sort */
if(!(buf=(struct StatsNode **)osAlloc(nc*sizeof(struct StatsNode *))))
return(FALSE);
work=buf;
for(sn=(struct StatsNode *)list->First;sn;sn=sn->Next)
*work++=sn;
switch(sortmode)
{
case 'a': qsort(buf,nc,ptrsize,CompareAlpha);
break;
case 't': qsort(buf,nc,ptrsize,CompareTotal);
break;
case 'm': qsort(buf,nc,ptrsize,CompareMsgsDay);
break;
case 'd': qsort(buf,nc,ptrsize,CompareFirstTime);
break;
case 'l': qsort(buf,nc,ptrsize,CompareLastTime);
break;
case 'u': qsort(buf,nc,ptrsize,CompareDupes);
break;
}
jbNewList(list);
for(work=buf;nc--;)
jbAddNode(list,(struct jbNode *)*work++);
osFree(buf);
return(TRUE);
}
int CompareNodes(const void *a1,const void *a2)
{
struct NodeStatsNode **s1,**s2;
s1=(struct NodeStatsNode **)a1;
s2=(struct NodeStatsNode **)a2;
return(Compare4D(&(*s1)->Node,&(*s2)->Node));
}
bool SortNodes(struct jbList *list)
{
struct NodeStatsNode *sn,**buf,**work;
uint32_t nc;
nc=0;
for(sn=(struct NodeStatsNode *)list->First;sn;sn=sn->Next)
nc++;
if(nc==0)
return(TRUE); /* Nothing to sort */
if(!(buf=(struct NodeStatsNode **)osAlloc(nc*sizeof(struct NodeStatsNode *))))
return(FALSE);
work=buf;
for(sn=(struct NodeStatsNode *)list->First;sn;sn=sn->Next)
*work++=sn;
qsort(buf,nc,ptrsize,CompareNodes);
jbNewList(list);
for(work=buf;nc--;)
jbAddNode(list,(struct jbNode *)*work++);
osFree(buf);
return(TRUE);
}
char *unit(uint32_t i)
{
static char buf[40];
if ((i>10000000)||(i<-10000000)) sprintf(buf,"%d MB",i/(1024*1024));
else if ((i>10000)||(i<-10000)) sprintf(buf,"%d KB",i/1024);
else sprintf(buf,"%d bytes",i);
return buf;
}
bool CheckFlags(char group,char *node)
{
int c;
for(c=0;c<strlen(node);c++)
{
if(toupper(group)==toupper(node[c]))
return(TRUE);
}
return(FALSE);
}
uint32_t CalculateAverage(uint16_t *last8array,uint32_t total,uint32_t daystatswritten,time_t firstday)
{
uint16_t days,c;
uint32_t sum;
if(daystatswritten == 0 || firstday == 0)
return(0);
days=daystatswritten-firstday;
if(days > 7) days=7;
sum=0;
for(c=1;c<days+1;c++)
sum+=last8array[c];
if(days == 0) days=1;
if(sum == 0 && total!=0)
{
days=daystatswritten-firstday;
if(days==0) days=1;
return(total/days);
}
return(sum/days);
}
bool ctrlc;
void breakfunc(int x)
{
ctrlc=TRUE;
}
int main(int argc, char **argv)
{
osFile fh;
uint32_t total,areas,totaldupes;
time_t firsttime,t;
uint32_t DayStatsWritten;
char buf[200],date[30],date2[30];
struct DiskAreaStats dastat;
struct DiskNodeStats dnstat;
struct StatsNode *sn;
struct NodeStatsNode *nsn;
struct jbList StatsList;
struct jbList NodesList;
uint32_t c,num,tot;
uint16_t total8days[8];
char sortmode;
struct tm *tp;
char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","???"};
signal(SIGINT,breakfunc);
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
sortmode='a';
if(args[ARG_SORT].data)
sortmode=tolower(((char *)args[ARG_SORT].data)[0]);
if(!strchr("amtdlu",sortmode))
{
printf("Unknown sort mode %c\n",sortmode);
osEnd();
exit(OS_EXIT_ERROR);
}
if(args[ARG_NOAREAS].data && args[ARG_NONODES].data)
{
printf("Nothing to do\n");
osEnd();
exit(OS_EXIT_ERROR);
}
printf("CrashStats "VERSION" <20> " COPYRIGHT " Johan Billing & Robert James Clay\n");
if(!(fh=osOpen(args[ARG_FILE].data,MODE_OLDFILE)))
{
uint32_t err=osError();
printf("Error opening %s\n",(char *)args[ARG_FILE].data);
printf("Error: %s\n",osErrorMsg(err));
osEnd();
exit(OS_EXIT_ERROR);
}
osRead(fh,buf,4);
buf[4]=0;
if(strcmp(buf,STATS_IDENTIFIER)!=0)
{
printf("Unknown format of stats file\n");
osClose(fh);
osEnd();
exit(OS_EXIT_ERROR);
}
osRead(fh,&DayStatsWritten,sizeof(uint32_t));
total=0;
totaldupes=0;
firsttime=0;
areas=0;
for(c=0;c<8;c++)
total8days[c]=0;
jbNewList(&StatsList);
jbNewList(&NodesList);
osRead(fh,&num,sizeof(uint32_t));
c=0;
if(!args[ARG_NOAREAS].data)
{
while(c<num && osRead(fh,&dastat,sizeof(struct DiskAreaStats))==sizeof(struct DiskAreaStats))
{
if(!args[ARG_GROUP].data || CheckFlags(dastat.Group,args[ARG_GROUP].data))
{
if(!(sn=osAlloc(sizeof(struct StatsNode))))
{
printf("Out of memory\n");
jbFreeList(&StatsList);
osClose(fh);
osEnd();
exit(OS_EXIT_ERROR);
}
jbAddNode(&StatsList,(struct jbNode *)sn);
strcpy(sn->Tagname,dastat.Tagname);
sn->Dupes=dastat.Dupes;
sn->Total=dastat.TotalTexts;
sn->FirstTime=dastat.FirstTime;
sn->LastTime=dastat.LastTime;
memcpy(&sn->Last8Days[0],&dastat.Last8Days[0],8*sizeof(uint16_t));
sn->Average=CalculateAverage(&dastat.Last8Days[0],dastat.TotalTexts,DayStatsWritten,sn->FirstTime / (24*60*60));
}
if(dastat.FirstTime!=0)
if(firsttime==0 || firsttime > dastat.FirstTime)
firsttime=dastat.FirstTime;
c++;
}
}
else
{
while(c<num && osRead(fh,&dastat,sizeof(struct DiskAreaStats))==sizeof(struct DiskAreaStats))
c++;
}
osRead(fh,&num,sizeof(uint32_t));
c=0;
if(!args[ARG_NONODES].data)
{
while(c<num && osRead(fh,&dnstat,sizeof(struct DiskNodeStats))==sizeof(struct DiskNodeStats))
{
if(!(nsn=osAlloc(sizeof(struct NodeStatsNode))))
{
printf("Out of memory\n");
jbFreeList(&NodesList);
jbFreeList(&StatsList);
osClose(fh);
osEnd();
exit(OS_EXIT_ERROR);
}
jbAddNode(&NodesList,(struct jbNode *)nsn);
Copy4D(&nsn->Node,&dnstat.Node);
nsn->GotNetmails=dnstat.GotNetmails;
nsn->GotNetmailBytes=dnstat.GotNetmailBytes;
nsn->SentNetmails=dnstat.SentNetmails;
nsn->SentNetmailBytes=dnstat.SentNetmailBytes;
nsn->GotEchomails=dnstat.GotEchomails;
nsn->GotEchomailBytes=dnstat.GotEchomailBytes;
nsn->SentEchomails=dnstat.SentEchomails;
nsn->SentEchomailBytes=dnstat.SentEchomailBytes;
nsn->Dupes=dnstat.Dupes;
nsn->Days=DayStatsWritten-dnstat.FirstTime % (24*60*60);
if(nsn->Days==0) nsn->Days=1;
nsn->FirstTime=dnstat.FirstTime;
if(dnstat.FirstTime!=0)
if(firsttime==0 || firsttime > dnstat.FirstTime)
firsttime=dnstat.FirstTime;
c++;
}
}
else
{
while(c<num && osRead(fh,&dnstat,sizeof(struct DiskNodeStats))==sizeof(struct DiskNodeStats))
c++;
}
osClose(fh);
t=(time_t)DayStatsWritten * 24*60*60;
tp=localtime(&firsttime);
sprintf(date,"%02d-%s-%02d",tp->tm_mday,monthnames[tp->tm_mon],tp->tm_year%100);
tp=localtime(&t);
sprintf(date2,"%02d-%s-%02d",tp->tm_mday,monthnames[tp->tm_mon],tp->tm_year%100);
printf("\nStatistics from %s to %s\n",date,date2);
if(!ctrlc && !args[ARG_NOAREAS].data)
{
Sort(&StatsList,'a');
Sort(&StatsList,sortmode);
printf("\n");
if(args[ARG_LAST7].data)
{
printf("Area ");
for(c=1;c<8;c++)
{
t=(DayStatsWritten-c)*24*60*60;
tp=localtime(&t);
printf(" %02d",tp->tm_mday);
}
printf(" Total\n============================================================================\n");
if(!ctrlc)
{
for(sn=(struct StatsNode *)StatsList.First;sn && !ctrlc;sn=sn->Next)
{
tot=0;
for(c=1;c<8;c++)
tot+=sn->Last8Days[c];
printf("%-33.33s %4d %4d %4d %4d %4d %4d %4d : %5d\n",
sn->Tagname,
sn->Last8Days[1],
sn->Last8Days[2],
sn->Last8Days[3],
sn->Last8Days[4],
sn->Last8Days[5],
sn->Last8Days[6],
sn->Last8Days[7],
tot);
for(c=1;c<8;c++)
total8days[c]+=sn->Last8Days[c];
areas++;
}
if(!ctrlc)
{
tot=0;
for(c=1;c<8;c++)
tot+=total8days[c];
printf("=============================================================================\n");
sprintf(buf,"Totally in all %u areas",areas);
printf("%-33.33s %4d %4d %4d %4d %4d %4d %4d : %5d\n",
buf,
total8days[1],
total8days[2],
total8days[3],
total8days[4],
total8days[5],
total8days[6],
total8days[7],
tot);
}
}
}
else
{
printf("Area First Last Msgs Msgs/day Dupes\n");
printf("============================================================================\n");
if(!ctrlc)
{
for(sn=(struct StatsNode *)StatsList.First;sn && !ctrlc;sn=sn->Next)
{
if(sn->LastTime==0)
{
strcpy(date2,"<Never>");
}
else
{
tp=localtime(&sn->LastTime);
sprintf(date2,"%02d-%s-%02d",tp->tm_mday,monthnames[tp->tm_mon],tp->tm_year%100);
}
if(sn->FirstTime==0)
{
strcpy(date,"<Never>");
}
else
{
tp=localtime(&sn->FirstTime);
sprintf(date,"%02d-%s-%02d",tp->tm_mday,monthnames[tp->tm_mon],tp->tm_year%100);
}
for(c=0;c<8;c++)
total8days[c]+=sn->Last8Days[c];
total+=sn->Total;
totaldupes+=sn->Dupes;
areas++;
printf("%-29.30s %-9.9s %-9.9s %7d %7d %7d\n",sn->Tagname,date,date2,sn->Total,sn->Average,sn->Dupes);
}
}
if(!ctrlc)
{
printf("============================================================================\n");
sprintf(buf,"Totally in all %u areas",areas);
printf("%-42s %7d %7d %7d\n",
buf,
total,
CalculateAverage(&total8days[0],total,DayStatsWritten,firsttime / (24*60*60)),
totaldupes);
}
}
}
if(!ctrlc && !args[ARG_NONODES].data)
{
SortNodes(&NodesList);
printf("\n");
printf("Nodes statistics\n");
printf("================\n");
for(nsn=(struct NodeStatsNode *)NodesList.First;nsn && !ctrlc;nsn=nsn->Next)
{
if(nsn->FirstTime==0)
{
strcpy(date,"<Never>");
}
else
{
tp=localtime(&nsn->FirstTime);
sprintf(date,"%0d-%s-%0d",tp->tm_mday,monthnames[tp->tm_mon],tp->tm_year%100);
}
sprintf(buf,"%u:%u/%u.%u",nsn->Node.Zone,nsn->Node.Net,nsn->Node.Node,nsn->Node.Point);
printf("%-30.40s Statistics since: %s\n\n",buf,date);
printf(" Sent netmails: %u/%s\n",nsn->SentNetmails,unit(nsn->SentNetmailBytes));
printf(" Received netmails: %u/%s\n",nsn->GotNetmails,unit(nsn->GotNetmailBytes));
printf(" Sent echomails: %u/%s\n",nsn->SentEchomails,unit(nsn->SentEchomailBytes));
printf(" Received echomails: %u/%s\n",nsn->GotEchomails,unit(nsn->GotEchomailBytes));
printf(" Dupes: %u\n",nsn->Dupes);
printf("\n");
}
}
if(ctrlc)
{
printf("*** Break\n");
}
else
{
printf("\n");
}
jbFreeList(&StatsList);
jbFreeList(&NodesList);
osEnd();
exit(OS_EXIT_OK);
}

View File

@@ -0,0 +1,359 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <shared/parseargs.h>
#include <shared/jbstrcpy.h>
#include <shared/path.h>
#include <shared/mystrncpy.h>
#include <shared/node4d.h>
#include <oslib/os.h>
#include <oslib/osfile.h>
#include <oslib/osmisc.h>
#include <shared/fidonet.h>
#include <magimail/version.h>
#ifdef PLATFORM_AMIGA
char *ver="$VER: CrashWrite "VERSION" ("__COMMODORE_DATE__")";
#endif
#define DEFAULT_TONAME "All"
#define DEFAULT_FROMNAME "CrashWrite"
#define DEFAULT_SUBJECT "Information"
#define DEFAULT_ORIGIN "Another user of MagiMail"
#define ARG_FROMNAME 0
#define ARG_FROMADDR 1
#define ARG_TONAME 2
#define ARG_TOADDR 3
#define ARG_SUBJECT 4
#define ARG_AREA 5
#define ARG_ORIGIN 6
#define ARG_DIR 7
#define ARG_TEXT 8
#define ARG_NOMSGID 9
#define ARG_FILEATTACH 10
#define ARG_PKTFROMADDR 11
#define ARG_PKTTOADDR 12
#define ARG_PASSWORD 13
struct argument args[] =
{ { ARGTYPE_STRING, "FROMNAME", 0, NULL },
{ ARGTYPE_STRING, "FROMADDR", 0, NULL },
{ ARGTYPE_STRING, "TONAME", 0, NULL },
{ ARGTYPE_STRING, "TOADDR", 0, NULL },
{ ARGTYPE_STRING, "SUBJECT", 0, NULL },
{ ARGTYPE_STRING, "AREA", 0, NULL },
{ ARGTYPE_STRING, "ORIGIN", 0, NULL },
{ ARGTYPE_STRING, "DIR", ARGFLAG_MANDATORY, NULL },
{ ARGTYPE_STRING, "TEXT", 0, NULL },
{ ARGTYPE_BOOL, "NOMSGID", 0, NULL },
{ ARGTYPE_BOOL, "FILEATTACH", 0, NULL },
{ ARGTYPE_STRING, "PKTFROMADDR", 0, NULL },
{ ARGTYPE_STRING, "PKTTOADDR", 0, NULL },
{ ARGTYPE_STRING, "PASSWORD", 0, NULL },
{ ARGTYPE_END, NULL, 0, 0 } };
char PktMsgHeader[SIZE_PKTMSGHEADER];
char PktHeader[SIZE_PKTHEADER];
bool nomem,diskfull;
uint16_t getuword(char *buf,uint32_t offset)
{
return (uint16_t)(buf[offset]+256*buf[offset+1]);
}
void putuword(char *buf,uint32_t offset,uint16_t num)
{
buf[offset]=num%256;
buf[offset+1]=num/256;
}
void MakeFidoDate(time_t tim,char *dest)
{
struct tm *tp;
time_t t;
char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","???"};
t=tim;
tp=localtime(&t);
sprintf(dest,"%02d %s %02d %02d:%02d:%02d",
tp->tm_mday,
monthnames[tp->tm_mon],
tp->tm_year % 100,
tp->tm_hour,
tp->tm_min,
tp->tm_sec);
}
void WriteNull(osFile ofh,char *str)
{
osWrite(ofh,str,(uint32_t)(strlen(str)+1));
}
int main(int argc, char **argv)
{
struct Node4D from4d,to4d,pktfrom4d,pktto4d;
osFile ifh,ofh;
time_t t;
struct tm *tp;
uint32_t pktnum,c,serial;
uint16_t attr;
char fromname[36],toname[36],subject[72],datetime[20],origin[80];
char pktname[30],fullname[200],readbuf[100];
int i;
from4d.Zone=0;
from4d.Net=0;
from4d.Node=0;
from4d.Point=0;
to4d.Zone=0;
to4d.Net=0;
to4d.Node=0;
to4d.Point=0;
if(!osInit())
exit(OS_EXIT_ERROR);
if(argc > 1 &&
(strcmp(argv[1],"?")==0 ||
strcmp(argv[1],"-h")==0 ||
strcmp(argv[1],"--help")==0 ||
strcmp(argv[1],"help")==0 ||
strcmp(argv[1],"/h")==0 ||
strcmp(argv[1],"/?")==0 ))
{
printargs(args);
osEnd();
exit(OS_EXIT_OK);
}
if(!parseargs(args,argc,argv))
{
osEnd();
exit(OS_EXIT_ERROR);
}
if(args[ARG_FROMADDR].data)
{
if(!(Parse4D((char *)args[ARG_FROMADDR].data,&from4d)))
{
printf("Invalid address \"%s\"\n",(char *)args[ARG_FROMADDR].data);
osEnd();
exit(OS_EXIT_ERROR);
}
}
if(args[ARG_TOADDR].data)
{
if(!(Parse4D((char *)args[ARG_TOADDR].data,&to4d)))
{
printf("Invalid address \"%s\"\n",(char *)args[ARG_TOADDR].data);
osEnd();
exit(OS_EXIT_ERROR);
}
}
Copy4D(&pktfrom4d,&from4d);
Copy4D(&pktto4d,&to4d);
if(args[ARG_PKTFROMADDR].data)
{
if(!(Parse4D((char *)args[ARG_PKTFROMADDR].data,&pktfrom4d)))
{
printf("Invalid address \"%s\"\n",(char *)args[ARG_PKTFROMADDR].data);
osEnd();
exit(OS_EXIT_ERROR);
}
}
if(args[ARG_PKTTOADDR].data)
{
if(!(Parse4D((char *)args[ARG_PKTTOADDR].data,&pktto4d)))
{
printf("Invalid address \"%s\"\n",(char *)args[ARG_PKTTOADDR].data);
osEnd();
exit(OS_EXIT_ERROR);
}
}
time(&t);
tp=localtime(&t);
/* Create packet header */
putuword(PktHeader,PKTHEADER_ORIGNODE,pktfrom4d.Node);
putuword(PktHeader,PKTHEADER_DESTNODE,pktto4d.Node);
putuword(PktHeader,PKTHEADER_DAY,tp->tm_mday);
putuword(PktHeader,PKTHEADER_MONTH,tp->tm_mon);
putuword(PktHeader,PKTHEADER_YEAR,tp->tm_year+1900);
putuword(PktHeader,PKTHEADER_HOUR,tp->tm_hour);
putuword(PktHeader,PKTHEADER_MINUTE,tp->tm_min);
putuword(PktHeader,PKTHEADER_SECOND,tp->tm_sec);
putuword(PktHeader,PKTHEADER_BAUD,0);
putuword(PktHeader,PKTHEADER_PKTTYPE,2);
putuword(PktHeader,PKTHEADER_ORIGNET,pktfrom4d.Net);
putuword(PktHeader,PKTHEADER_DESTNET,pktto4d.Net);
PktHeader[PKTHEADER_PRODCODELOW]=0xfe;
PktHeader[PKTHEADER_REVMAJOR]=VERSION_MAJOR;
putuword(PktHeader,PKTHEADER_QORIGZONE,pktfrom4d.Zone);
putuword(PktHeader,PKTHEADER_QDESTZONE,pktto4d.Zone);
putuword(PktHeader,PKTHEADER_AUXNET,0);
putuword(PktHeader,PKTHEADER_CWVALIDCOPY,0x0100);
PktHeader[PKTHEADER_PRODCODEHIGH]=0;
PktHeader[PKTHEADER_REVMINOR]=VERSION_MINOR;
putuword(PktHeader,PKTHEADER_CAPABILWORD,0x0001);
putuword(PktHeader,PKTHEADER_ORIGZONE,pktfrom4d.Zone);
putuword(PktHeader,PKTHEADER_DESTZONE,pktto4d.Zone);
putuword(PktHeader,PKTHEADER_ORIGPOINT,pktfrom4d.Point);
putuword(PktHeader,PKTHEADER_DESTPOINT,pktto4d.Point);
PktHeader[PKTHEADER_PRODDATA]=0;
PktHeader[PKTHEADER_PRODDATA+1]=0;
PktHeader[PKTHEADER_PRODDATA+2]=0;
PktHeader[PKTHEADER_PRODDATA+3]=0;
for(c=0;c<8;c++)
PktHeader[PKTHEADER_PASSWORD+c]=0;
if(args[ARG_PASSWORD].data)
strncpy(&PktHeader[PKTHEADER_PASSWORD],args[ARG_PASSWORD].data,8);
/* Create message header */
attr=0;
if(!args[ARG_AREA].data)
attr|=FLAG_PVT;
if(args[ARG_FILEATTACH].data)
attr|=FLAG_FILEATTACH;
putuword(PktMsgHeader,PKTMSGHEADER_PKTTYPE,0x0002);
putuword(PktMsgHeader,PKTMSGHEADER_ORIGNODE,from4d.Node);
putuword(PktMsgHeader,PKTMSGHEADER_DESTNODE,to4d.Node);
putuword(PktMsgHeader,PKTMSGHEADER_ORIGNET,from4d.Net);
putuword(PktMsgHeader,PKTMSGHEADER_DESTNET,to4d.Net);
putuword(PktMsgHeader,PKTMSGHEADER_ATTR,attr);
putuword(PktMsgHeader,PKTMSGHEADER_COST,0);
mystrncpy(fromname,DEFAULT_FROMNAME,36);
mystrncpy(toname,DEFAULT_TONAME,36);
mystrncpy(subject,DEFAULT_SUBJECT,72);
mystrncpy(origin,DEFAULT_ORIGIN,80);
if(args[ARG_FROMNAME].data) mystrncpy(fromname,(char *)args[ARG_FROMNAME].data,36);
if(args[ARG_TONAME].data) mystrncpy(toname,(char *)args[ARG_TONAME].data,36);
if(args[ARG_SUBJECT].data) mystrncpy(subject,(char *)args[ARG_SUBJECT].data,72);
if(args[ARG_ORIGIN].data) mystrncpy(origin,(char *)args[ARG_ORIGIN].data,80);
MakeFidoDate(t,datetime);
/* Create pkt file */
serial=0;
do
{
t=time(NULL);
pktnum = (t<<8) + serial;
serial++;
sprintf(pktname,"%08x.pkt",pktnum);
MakeFullPath(args[ARG_DIR].data,pktname,fullname,200);
} while(osExists(fullname));
if(!(ofh=osOpen(fullname,MODE_NEWFILE)))
{
uint32_t err=osError();
printf("Unable to create packet %s\n",fullname);
printf("Error: %s\n",osErrorMsg(err));
osEnd();
exit(OS_EXIT_ERROR);
}
printf("Writing...\n");
printf(" From: %-36s (%u:%u/%u.%u)\n",fromname,from4d.Zone,from4d.Net,from4d.Node,from4d.Point);
printf(" To: %-36s (%u:%u/%u.%u)\n",toname,to4d.Zone,to4d.Net,to4d.Node,to4d.Point);
printf(" Subj: %s\n",subject);
printf(" Date: %s\n",datetime);
osWrite(ofh,PktHeader,SIZE_PKTHEADER);
osWrite(ofh,PktMsgHeader,SIZE_PKTMSGHEADER);
WriteNull(ofh,datetime);
WriteNull(ofh,toname);
WriteNull(ofh,fromname);
WriteNull(ofh,subject);
if(args[ARG_AREA].data)
{
osFPrintf(ofh,"AREA:%s\x0d",args[ARG_AREA].data);
}
else
{
if(from4d.Point)
osFPrintf(ofh,"\x01" "FMPT %d\x0d",from4d.Point);
if(to4d.Point)
osFPrintf(ofh,"\x01" "TOPT %d\x0d",to4d.Point);
osFPrintf(ofh,"\x01" "INTL %u:%u/%u %u:%u/%u\x0d",to4d.Zone,to4d.Net,to4d.Node,
from4d.Zone,from4d.Net,from4d.Node);
}
if(!args[ARG_NOMSGID].data)
{
osFPrintf(ofh,"\x01" "MSGID: %u:%u/%u.%u %08x\x0d",
from4d.Zone,from4d.Net,from4d.Node,from4d.Point,pktnum);
}
if(args[ARG_TEXT].data)
{
printf("Appending %s...\n",(char *)args[ARG_TEXT].data);
if(!(ifh=osOpen((char *)args[ARG_TEXT].data,MODE_OLDFILE)))
{
uint32_t err=osError();
printf("Unable to open \"%s\" for reading\n",(char *)args[ARG_TEXT].data);
printf("Error: %s\n",osErrorMsg(err));
osClose(ofh);
osDelete(fullname);
exit(OS_EXIT_ERROR);
}
while(osFGets(ifh,readbuf,100))
{
for(i=0;readbuf[i];i++)
if(readbuf[i] == '\n') readbuf[i]=0x0d;
osFPrintf(ofh,"%s",readbuf);
}
osClose(ifh);
}
if(args[ARG_AREA].data)
{
osFPrintf(ofh,"--- CrashWrite II/" OS_PLATFORM_NAME " " VERSION "\x0d");
osFPrintf(ofh," * Origin: %s (%u:%u/%u.%u)\x0d",origin,from4d.Zone,from4d.Net,from4d.Node,from4d.Point);
}
osWrite(ofh,"",1);
osWrite(ofh,"",1);
osWrite(ofh,"",1);
osClose(ofh);
osEnd();
exit(OS_EXIT_OK);
}