/* Zeus LastCaller v1.8 (c)1996 by Rod Schnell
 *
 * Source code first released 14-Mar-96 (v1.4). Do whatever you like with it,
 * just give me credit for the original code and don't blame me if you have
 * problems with it. This code could certainly be made smaller and more
 * efficient.
 *
 *          Rod
 */


#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define	USE_DOORLIB

#include <proto/pipeline.h>
#include <proto/pipeutil.h>
#include <nodes.h>

struct Library *PipelineBase;
long					 LineNumber;
ULONG					 WriteFlags;

int main(int argc, char *argv[])
{
int i;
struct SharedData	*Shared;
struct Line				*le, *TLine;
struct LastCaller *lc;
struct tm ontime, offtime;


BOOL realnames = FALSE, showsysop = FALSE, showlocal = FALSE;

int numcalls, count;

char obuff[2048], location[80], inout[40];
char *day[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};

static UBYTE   *VersTag = "\0$VER: LastCallers 1.8 "__AMIGADATE__;

	if (argc < 2 || !strcmp(argv[1], "?"))
	{
		Printf("Syntax: LastCallers <Line number> [REALNAMES] [SHOWSYSOP] [SHOWLOCAL]");
		exit(RETURN_WARN);
	}

	for(i = 2; i < argc; i++)
	{
		if(!stricmp(argv[i], "REALNAMES")) realnames = TRUE;
		if(!stricmp(argv[i], "SHOWSYSOP")) showsysop = TRUE;
		if(!stricmp(argv[i], "SHOWLOCAL")) showlocal = TRUE;
	}

	if (PipelineBase = OpenLibrary("zeus.library", 0))
	{
		if( Shared = GetShared() )
		{
			LineNumber = atol( argv[1] );
			if( le = GetLine( LineNumber ))
			{
				ULONG save_flags;

				WriteFlags = NULL;

				/* Save user flags (to reset before exiting) and turn screen
				 * clearing on.
				 */
				save_flags = le->le_User->ur_Flags;
				if( !( le->le_User->ur_Flags & UF_CLRSCR))
					le->le_User->ur_Flags = le->le_User->ur_Flags | UF_CLRSCR;

				/* Display Header */

				/* Cannot use ESC[23C here as blue background won't get printed then */

/* old
				LPuts("[2J[H[0;40m[23C[1;37m·  Ö· Ö· ·    Ö· Ö· ·  ·  Ö· Ò· Ö·\n");
				LPuts("[44m                       º  Ö¶ Ó· ×Ä   º  Ö¶ º  º  Ç½ º  Ó·                      \n");
				LPuts("[23C[40mÓÄ ÓÐ Ó½ ÓÄ   Ó½ ÓÐ ÓÄ ÓÄ ÓÄ Ð  Ó½[0m\n");
*/
LPuts("[2J[H[40m                   [1;37m·  ÖÄ· ÖÄ· ÖÒ·    ÖÄ· ÖÄ· ·  ·  ÖÄ· ÒÄ· ÖÄ·\n");
LPuts("[44m                   º  ÇÄ¶ ÓÄ·  º     º   ÇÄ¶ º  º  ÇÄ  º   ÓÄ·                 \n");
LPuts("[40m                   ÓÄ Ð Ð ÓÄ½  Ð     ÓÄ½ Ð Ð ÓÄ ÓÄ ÓÄ½ Ð   ÓÄ½[0m\n");


				LPuts("[1;30mÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
				LPuts("[44m [37mLine  User Name            Called From       Baud         In - Out            \n");
				LPuts("[30;40mÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");

				/* Initialize counting variables */

				count = i = 0;
				numcalls = le->le_User->ur_ScrHeight - 13;
				if( numcalls < 10) numcalls = 10;

				/* Check for online callers first */

				do
				{
					if( count == numcalls ) break;
					if( TLine = GetLine( i ) )
					{
						/* Tline->le_User will be NULL if there's no user online */

						if(TLine->le_User)
						{
							if(showsysop || stricmp(Shared->SysVars->sv_SysOpName, TLine->le_User->ur_Name) || !stricmp(le->le_User->ur_Name, TLine->le_User->ur_Name) )
							{
								if( TLine->le_RealBaud || showlocal || !stricmp(le->le_User->ur_Name, TLine->le_User->ur_Name) )
								{
									GMTime(TLine->le_LogOnTime, &ontime);

									sprintf(location, "%s, %s", TLine->le_User->ur_Town, TLine->le_User->ur_County);
									sprintf(inout, "%3s %2.2d:%2.2d - [31mONLINE        ", day[ontime.tm_wday], ontime.tm_hour, ontime.tm_min);

												if(TLine->le_User->ur_LastBaudRate == 0)
												{
													if(realnames) sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s  [1;36mLOCAL [0;37m%s[1;30m³\n", TLine->le_Number, TLine->le_User->ur_Name, location, inout);
													else sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s  [1;36mLOCAL [0;37m%s[1;30m³\n", TLine->le_Number, TLine->le_User->ur_Alias, location, inout);
												}
												else
												{
													if(realnames) sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s [1;36m%6ld [0;37m%s[1;30m³\n", TLine->le_Number, TLine->le_User->ur_Name, location, TLine->le_RealBaud, inout);
													else sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s [1;36m%6ld [0;37m%s[1;30m³\n", TLine->le_Number, TLine->le_User->ur_Alias, location, TLine->le_RealBaud, inout);
												}
												LPuts(obuff);
									++count;
								}
							}
						}
					}
					i++;
				}	while (i <= Shared->HiLine);

				/* Now walk and display the last callers list kept in memory */

				ObtainSemaphoreShared( Shared->LCSem );
				if ( lc = (struct LastCaller *) GetHead( &(Shared->LastCalls) ) )
				{
					/* lc->Node   lc->Line   lc->Name   lc->LogOn   lc->LogOff   lc->User    */
					/* linkage    linenumber realname   logon time  logoff time  user struct */
					do
					{
						if( count == numcalls ) break;
						if(showsysop || stricmp(Shared->SysVars->sv_SysOpName, lc->Name) )
						{
							if((lc->User.ur_LastBaudRate != 0) || showlocal)
							{
								GMTime(lc->LogOn, &ontime);
								GMTime(lc->LogOff, &offtime);
								sprintf(location, "%s, %s", lc->User.ur_Town, lc->User.ur_County);
								sprintf(inout, "%3s %2.2d:%2.2d - %3s %2.2d:%2.2d     ", day[ontime.tm_wday], ontime.tm_hour, ontime.tm_min, day[offtime.tm_wday], offtime.tm_hour, offtime.tm_min);
								if(lc->User.ur_LastBaudRate == 0)
								{
									if(realnames) sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s  [1;36mLOCAL [0;37m%s[1;30m³\n", lc->Line, lc->Name, location, inout);
									else sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s  [1;36mLOCAL [0;37m%s[1;30m³\n", lc->Line, lc->User.ur_Alias, location, inout);
								}
								else
								{
									if(realnames) sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s [1;36m%6ld [0;37m%s[1;30m³\n", lc->Line, lc->Name, location, lc->User.ur_LastBaudRate, inout);
									else sprintf(obuff, "[1;30m³[0;37m%3d   [1;36m%-20.20s [0;37m%-16.16s [1;36m%6ld [0;37m%s[1;30m³\n", lc->Line, lc->User.ur_Alias, location, lc->User.ur_LastBaudRate, inout);
								}
								LPuts(obuff);
								count++;
							}
						}
					}
					while ( lc = (struct LastCaller *) GetSucc ( (struct Node *) lc ) );
				}
				ReleaseSemaphore( Shared->LCSem );
				/* Display Footer */

				LPuts("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n");
				LPuts("[44m [37mBBS Statistics                          Your Statistics                       \n");
				LPuts("[30;40mÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
				sprintf(obuff, "³ [34mCalls: [37m%4ld [34mToday: [37m%4ld [34mUsers: [37m%4ld [30m³ ³[34mCalls: [37m%4ld [34mToday: [37m%3ld [34mLeft: [37m%4ld [34mMin[30m³\n", Shared->Saved.sd_Calls, Shared->Saved.sd_CallsToday, Shared->Saved.sd_Users, le->le_User->ur_NumCalls, le->le_User->ur_CallsToday, le->le_User->ur_MinsLeft);
				LPuts(obuff);
				LPuts("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n");
				LPuts("[44m [37mVersion 1.8                                     Copyright (c)1996 Rod Schnell [0m\n");

				le->le_User->ur_Flags = save_flags;
			}
			else
			{
				Printf( "Illegal line number!\n\n" );
			}
		}
		else
		{
			Printf( "Cannot get SharedData -- Is Zeus running?\n\n" );
		}
		CloseLibrary(PipelineBase);
	}
	else
	{
		Printf( "Cannot open Zeus Library!\n\n" );
	}
}

