/*
================================================================================
 PROGRAM: Updater
 VERSION: v1.2
COMPILER: Lattice C v5.10b
    DATE: Oct 25 1992
================================================================================
*/
//**********************
//*****  Includes  *****
//**********************

#include <proto/all.h>
#include <stdio.h>
#include <time.h>

#include <string.h>
#include <tempest/headers.h>
#include <tempest/skel-data.h>
#include <tempest/skel-current.h>

void __regargs __chkabort(void);
void __regargs __chkabort(void)
{
}
char *Myctime(long *secs);
BPTR LockCurrentData(VOID);

//*********************
//*****  Structs  *****
//*********************

char *mon[]={ "Jan","Feb","Mar","Apr","May","Jun",
              "Jul","Aug","Sep","Oct","Nov","Dec" };

struct Current Current;
struct SKEL SKEL;

struct User    User;
struct Today   Today;

//**********************
//*****  Globals  ******
//**********************

char DateString[15];
int  Day,Test=0,NODES,TodayUFiles,TodayDFiles,TodayNewUsers,
     TotalUsers,TodayCalls,TodayMessages,TodayBusy,TodayNewUsers;
long TotalCalls,TotalMessages,TotalDL,TotalUL,TodayULBytes,TodayDLBytes,
     TotalULKB,TotalDLKB;

BPTR curlock=NULL;

//******************
//*****  Main  *****
//******************

void main(int argc,char *argv[])
{
 int i=1,m=1;
 int  Month,Year,UserDay,stat,fd;
 char namen[80],string[255],string1[50],RMonth[50],Outname[255];

 struct tm *zt;
 time_t just;
 time(&just);                 /* Get Accurate Current Time */
 zt   = gmtime(&just);
 Day  = zt->tm_mday;
 Month= zt->tm_mon + 1;
 Year = zt->tm_year;
 strcpy(RMonth,mon[Month-1]);
 sprintf(DateString,"%2d%2d%d",Day,Month,Year);
 if(argc!=3)
  {
   PutStr("\n[m[1m    _______ _________\n");
   PutStr("   / ___/ [4m/[m[1m/ / ___/ /    [[32mSKEL-UPDATER v3.51[m[1m] - [3m[MASTER] Updater[m\n");
   PutStr("[1m  [4m/[m[1m__  /   _/ ___/ [4m/[m[1m__\n");
   PutStr("[1m [4m/[m[1m____[4m/[m[1m_/\\_[4m)[m[1m____[4m/[m[1m____/   For Tempest BBS - [Programmer: Michael Bockert]\n");
   PutStr("\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"[m\n");
   PutStr("   USAGE: SKEL-Updater [#Nodes] [SETUP DIR]\n");
   PutStr(" EXAMPLE: SKEL-Updater 5 TEMPEST:\n\n");
   PutStr("  [#Nodes] # of Nodes\n");
   PutStr("[SetupDir] Path to Setup Dir\n\n");
   exit(0);
  }
 NODES=atoi(argv[1]);

//*************************************
//*****  Load Skel-Current.Data  ******
//*************************************

 if(!(curlock=LockCurrentData()))
  {
   PutStr("ERROR: Unable to Lock S:SKEL-CURRENT.LOCK\n");
   exit(0);
  }
 fd=Open("S:Skel-Current.Data",MODE_OLDFILE);
 if(fd==0)
  {
   setmem(&Current,sizeof(struct Current),NULL);
   Test = 1;
  }
 else
  {
   Read(fd,(char *)&Current, sizeof(struct Current));
   Close(fd);
  }
 if(curlock) UnLock(curlock);

//**************************************
//*****  Load Runtime.Data Files  ******
//**************************************

 do
  {
   sprintf(namen,"%sSetup/Runtime-%d.data",argv[2],i);
   fd=Open(namen,MODE_OLDFILE);
   if(fd!=0)
    {
     Read(fd,(char *)&Today, sizeof(struct Today));
     Close(fd);
     TodayBusy     += Today.Busy;
     TodayNewUsers += Today.New;
     TotalCalls    += Today.Total;
    }
   else PutStr("\nA Runtime.Data file was not found!\n");
   i++;
  }
 while(i<NODES+1);

//********************************
//*****  Load Accounts.Data  *****
//********************************

 sprintf(Outname,"%sAccounts.Data",argv[2]);
 fd=Open(Outname,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nAccounts.data not found!\n");
   exit(0);
  }
 Read(fd,(char *)&User, sizeof(struct User));
 do
  {
   if(User.Slot_Number != 0)
    {
     if(Test == 1)
      {
       TotalMessages += User.Total_Posts;
       TotalUL   += User.Total_ULFiles;
       TotalDL   += User.Total_DLFiles;
       TotalULKB += ((User.Total_ULBytes + 1L) / 1024L);
       TotalDLKB += ((User.Total_DLBytes + 1L) / 1024L);
      }
     TotalUsers++;
     strcpy(string,Myctime(&User.Time_Last_Connect));
     strmid(string,string1,9,2);
     UserDay=atoi(string1);
     strmid(string,string1,5,3);
     if( (strcmp(string1,RMonth)==0) && (UserDay == Day) )
      {
       TodayCalls    += User.Period_Calls;
       TodayMessages += User.Period_Posts;
       TodayUFiles   += User.Period_ULFiles;
       TodayULBytes  += User.Period_ULBytes;
       TodayDFiles   += User.Period_DLFiles;
       TodayDLBytes  += User.Period_DLBytes;
      }
    }
   stat=Read(fd,(char *)&User, sizeof(struct User));
  }
 while(stat > 0);
 Close(fd);

//***********************************
//*****  The Heart Of The Util  *****
//***********************************

 if(Test == 1)
  {
   CurrentDay();
   NewDay(argv[2]);
   PutStr("\nRemember! Some stats are creaetd after midnight tonight!\n");
  }
 else
  {
   if(Day == Current.Day)
    {
     CurrentDay();
    }
   else
    {
     NewDay(argv[2]);
     CurrentDay();
    }
  }
 PutStr("\nSKEL-UPDATER Done!\n");
 exit(0);
}

//***************************
//***************************
//*****  Current Day!  ******
//***************************
//***************************

CurrentDay()
{
 int fd;

 Current.Calls      = TodayCalls;
 Current.Messages   = TodayMessages;
 Current.Busy       = TodayBusy;
 Current.NewUsers   = TodayNewUsers;
 Current.UL         = TodayUFiles;
 Current.ULKB       = ((TodayULBytes + 1L) / 1024L);
 Current.DL         = TodayDFiles;
 Current.DLKB       = ((TodayDLBytes + 1L) / 1024L);
 Current.Users      = TotalUsers;
 Current.Nodes      = NODES;
 Current.Day        = Day;
 strcpy(Current.Date,DateString);

//**************************************
//*****  Write Skel-Current.Data  ******
//**************************************

 if(!(curlock=LockCurrentData()))
  {
   PutStr("ERROR: Unable to Lock S:SKEL-CURRENT.LOCK\n");
   exit(0);
  }
 fd=Open("S:Skel-Current.Data",MODE_NEWFILE);
 if(fd==0)
  {
   PutStr("Error writing S:Skel-Current.Data!\n");
   exit(0);
  }
 Write(fd,(char *)&Current, sizeof(struct Current));
 Close(fd);
 if(curlock) UnLock(curlock);
 return(0);
}

//***********************
//***********************
//*****  New Day!  ******
//***********************
//***********************

NewDay(char setuppath[])
{
 int i=1,j,fd;
 char Outname[255];

 if(Test != 1)
  {
//**************************************
//*****  Load Skel-Data.Data  **********
//**************************************
   sprintf(Outname,"%sSetup/Skel-Data.Data",setuppath);
   fd=Open(Outname,MODE_OLDFILE);
   if(fd!=0)
    {
     Read(fd,(char *)&SKEL, sizeof(struct SKEL));
     Close(fd);
    }
//*******************************
//*****  Get History Data  ******
//*******************************
   i = 29;
   j = 30;
   do
    {
     SKEL.HCalls[j]     = SKEL.HCalls[i];
     SKEL.HMessages[j]  = SKEL.HMessages[i];
     SKEL.HBusy[j]      = SKEL.HBusy[i];
     SKEL.HNewUsers[j]  = SKEL.HNewUsers[i];
     SKEL.HUL[j]        = SKEL.HUL[i];
     SKEL.HULKB[j]      = SKEL.HULKB[i];
     SKEL.HDL[j]        = SKEL.HDL[i];
     SKEL.HDLKB[j]      = SKEL.HDLKB[i];
     strcpy(SKEL.HDate[j],SKEL.HDate[i]);
     i--;
     j--;
    }
   while(i > 0);

//***********************************
//*****  Get Yesterday's Data  ******
//***********************************

   SKEL.HCalls[1]     = Current.Calls;
   SKEL.HMessages[1]  = Current.Messages;
   SKEL.HBusy[1]      = Current.Busy;
   SKEL.HNewUsers[1]  = Current.NewUsers;
   SKEL.HUL[1]        = Current.UL;
   SKEL.HULKB[1]      = Current.ULKB;
   SKEL.HDL[1]        = Current.DL;
   SKEL.HDLKB[1]      = Current.DLKB;
   strcpy(SKEL.HDate[1],Current.Date);

//******************************
//*****  Get New Records  ******
//******************************

   if(SKEL.HCalls[1] > SKEL.RCalls)
    {
     SKEL.RCalls = SKEL.HCalls[1];
     strcpy(SKEL.RDates[1],SKEL.HDate[1]);
    }
   if(SKEL.HMessages[1] > SKEL.RMessages)
    {
     SKEL.RMessages = SKEL.HMessages[1];
     strcpy(SKEL.RDates[2],SKEL.HDate[1]);
    }
   if(SKEL.HBusy[1] > SKEL.RBusy)
    {
     SKEL.RBusy = SKEL.HBusy[1];
     strcpy(SKEL.RDates[3],SKEL.HDate[1]);
    }
   if(SKEL.HNewUsers[1] > SKEL.RNewUsers)
    {
     SKEL.RNewUsers = SKEL.HNewUsers[1];
     strcpy(SKEL.RDates[4],SKEL.HDate[1]);
    }
   if(SKEL.HUL[1] > SKEL.RUL)
    {
     SKEL.RUL = SKEL.HUL[1];
     strcpy(SKEL.RDates[5],SKEL.HDate[1]);
    }
   if(SKEL.HULKB[1] > SKEL.RULKB)
    {
     SKEL.RULKB = SKEL.HULKB[1];
     strcpy(SKEL.RDates[6],SKEL.HDate[1]);
    }
   if(SKEL.HDL[1] > SKEL.RDL)
    {
     SKEL.RDL = SKEL.HDL[1];
     strcpy(SKEL.RDates[7],SKEL.HDate[1]);
    }
   if(SKEL.HDLKB[1] > SKEL.RDLKB)
    {
     SKEL.RDLKB = SKEL.HDLKB[1];
     strcpy(SKEL.RDates[8],SKEL.HDate[1]);
    }
//******************************
//*****  Get Totals Data  ******
//******************************
   SKEL.TotalCalls    += Current.Calls;
   SKEL.TotalMessages += Current.Messages;
   SKEL.TotalUL       += Current.UL;
   SKEL.TotalDL       += Current.DL;
   SKEL.TotalULKB     += Current.ULKB;
   SKEL.TotalDLKB     += Current.DLKB;
  }
 else
  {
   SKEL.TotalCalls     = TotalCalls;
   SKEL.TotalMessages  = TotalMessages;
   SKEL.TotalUL        = TotalUL;
   SKEL.TotalDL        = TotalDL;
   SKEL.TotalULKB      = TotalULKB;
   SKEL.TotalDLKB      = TotalDLKB;
  }
 SKEL.TotalUsers       = TotalUsers;

//***********************************
//*****  Write Skel-Data.Data  ******
//***********************************

 fd=Open(Outname,MODE_NEWFILE);
 if(fd==0)
  {
   PutStr("Error writing Skel-Data.Data!\n");
   exit(0);
  }
 Write(fd,(char *)&SKEL, sizeof(struct SKEL));
 Close(fd);
 return(0);
}

//===========================* Beginning of Module *===========================
char *Myctime(long *secs)
{
 struct tm *tm;
 tm=gmtime(secs);
// tm->tm_isdst=0;
 return(asctime(tm));
}

//*******************************
//*****  Lock Current Data  *****
//*******************************
BPTR LockCurrentData(VOID)
{
 BPTR lock;
 UWORD loop=0;
 LONG error;
 BPTR file;
 char filename[100];

 strcpy(filename,"S:SKEL-CURRENT.LOCK");
 do
  {
   if(!(lock=Lock(filename,ACCESS_WRITE)))
    {
     error=IoErr();
     if(error==205)
      {
       file=Open(filename,MODE_NEWFILE);
       Close(file);
      }
     Delay(120L);
    }
  }
 while(!lock&&loop++<30);
 if(!lock) lock=NULL;
 return(lock);
}
