/*
** LastXCallers
** by Kelly Cochran
** Last Updated: Sat Sep 20 15:35:55 1997
*/

#define DATAFILE   "SysData:LT.dat"

#include "lt.h"

/* should really make the datafile a struct defined setup */

const char *version = "\0$VER: LT "VERTAG" "__AMIGADATE__;

void            CallHost( UBYTE c );
void            ShutDown( char *spawn );
void            GetOut( void );
void            LoadError( void );


struct MsgPort         *replyp; /* Some communication details ...       */
struct CPort           *cport;
struct CMessage        cmess;
struct MainPort        *myp;            /* Pointer to CNet port--ALL info!      */
struct PortData        *z;
char                     **bm;
struct Library         *CNetBase = NULL;
struct Library         *CNet4Base = NULL;
struct SignalSemaphore *SEM;

void do_print(struct LT *Last, int hide)
{
   char logon [ 7 ];
   char date  [ 7 ];
   char spec = ' ';

   CNetPrintDate(&Last->logon,logon,NULL,"HH:MMa");
   CNetPrintDate(&Last->logon,date ,NULL,"dd mmm");

   if(hide == 1)
      spec = 'h';

   if(Last->calls == 1)
      spec = '-';

   sprintf(z->ABuffer,"c2|c6%2dc2|%cc7%-17.17sc2|c3%-13.13sc2|c5"
           "%6.6sc2|c1%6.6s-  %3d c2|c3%4dc2|%4d|c4%3.3sc2|c7%c%c"
           "%c%c%c%cc2|q1\n",
           Last->port,
           spec,
           myp->Key[Last->id-1].Handle,
           Last->from,
           date,
           logon,
           Last->timeon,
           Last->calls,
           Last->baud,
           myp->FirstTT->mm[myp->FirstTT->menustart[30]+Last->ctype],
           Last->flags & RESP  ? 'R' : '.',
           Last->flags & ULOAD ? 'U' : '.',
           Last->flags & DLOAD ? 'D' : '.',
           Last->flags & PFILE ? 'P' : '.',
           Last->flags & GFILE ? 'G' : '.',
           Last->flags & MAIL  ? 'M' : '.');
   PutA();
}

void do_display(int num)
{
   int i;
   int amt;

   BPTR fp;

   struct LT Last;

   if(fp = Open(DATAFILE,MODE_OLDFILE))
   {
      for(i = 0;i < num;i++)
      {
         if(!(amt = Read(fp,&Last,sizeof(struct LT))))
            break;
         if(Last.flags & HIDE)
         {
            if(z->user1.MyPrivs.ABits & CONFCON_FLAG)
            {
               do_print(&Last,1);
               continue;
            }
            else
            {
               i--;
               continue;
            }
         }
         do_print(&Last,0);
      }
      Close(fp);
   }
}

void do_header(void)
{
   PutText("c2ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
   PutText("³ -- bbs name goes here                                                       ³\n");
   PutText("ÆÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÑÍÍÍÍÑÍÍÍÑÍÍÍÍÍÍµ\n");
   PutText("ca³cePtca³*cfHandle/Name      ca³c3Origin       ca³cd Date ca³c9Logon - Mins ca³c3#Clsca³caBaudca³ccCmpca³ceActionca³\n");
   PutText("ÆÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍØÍÍÍÍØÍÍÍØÍÍÍÍÍÍµ\n");
}

void do_footer(void)
{
   PutText("Footer\n");
}

void write_log(struct LT Last)
{
   BPTR fp;

   if(fp = OpenAppend(DATAFILE))
   {
      Write(fp,&Last,sizeof(struct LT));
      Close(fp);
   }
}

void log_call(void)
{
   struct LT Last;

   memset(&Last,0,sizeof(struct LT));

   Last.id     = z->id;
   Last.port   = z->InPort;
   Last.calls  = z->user1.TotalCalls;
   Last.baud   = z->user1.BaudRate/10;
   Last.ctype  = z->user1.CompType;
   Last.logon  = z->user1.ConnectDate;
   strcpy(Last.from,z->user1.CityState);
   Last.timeon = z->TimeOnLine/10;
   Last.flags  = ((z->SAMNow[ 0] + z->SAMNow[ 1] + z->SAMNow[ 2]) > 0) * MAIL +
                 ((z->SAMNow[ 3] + z->SAMNow[ 4]) > 0) * RESP +
                 ((z->SAMNow[ 5]) > 0) * GFILE +
                 ((z->SAMNow[ 6]) > 0) * PFILE +
                 ((z->SAMNow[ 8]) > 0) * ULOAD +
                 ((z->SAMNow[10]) > 0) * DLOAD +
                  (z->HideAll)         * HIDE;

   write_log(Last);
}

void main( int argc, char **argv )
{

        Forbid();
        if(argc > 1)
                cport = (struct CPort *)FindPort( argv[1] );
        Permit();

        if( argc<2 || !(cport) ) {
                Printf("This is a CNet C program.\n");
                exit(0);
                }

        if( !(replyp = CreatePort( 0,0 )))
                exit(0);

        cmess.cn_Message.mn_ReplyPort   = replyp;
        cmess.cn_Message.mn_Length      = sizeof( struct CMessage );
        cmess.cn_Message.mn_Node.ln_Name= "cstuff";

        if( cport->ack != 40 )      // Replace the code above with this
                if( cport->ack != 30 )   // to support both 3.x and 4.x systems
                        {
                        cport->ack = 1;
                        LoadError();
                        }

        cport->ack = 0;

        z    = cport->zp;
        myp  = cport->myp;
        SEM  = myp->SEM;
        bm   = z->bm;

        if( !(CNetBase = OpenLibrary( "cnet.library", 4 )) ) // <- NOTE version 4 - can be changed to 3 to make compatible with older CNet releases!
                LoadError();
        if( !(CNet4Base = OpenLibrary( "cnet4.library", 4 )) )
                LoadError();

/************************************************************************
 *           End of CNet setup - YOUR CUSTOM CODE STARTS HERE           *
 ************************************************************************/

        do_header();

/*        if (strcmp(argv[2],"LOG"))*/
           log_call();

        if (strcmp(argv[2],"DISPLAY") | (argv[2] == NULL))
        {
           if (z->pitem[1] == NULL)
              do_display(10);
           else
              do_display(atoi(z->pitem[1]));
        }

        do_footer();

        /* exit back to CNet - always call GetOut() to exit back to CNet! */
        GetOut();
}

void GetOut( void )
{
   if(CNetBase)
   {
      CloseLibrary(CNetBase);
      if(CNet4Base)
      {
         CloseLibrary(CNet4Base);
      }
   }
   ShutDown( NULL );
   DeletePort( replyp );
   exit(0);
}
