


// Besispiel an mainpartport text senden! (Derrow) -> SERVER_DirStringToNd








#include <stdio.h>
#include <strings.h>
#include <proto/exec.h>
#include <FAME/FAME.h>

char *VerStr={"$VER: SentBy 1.2 "__AMIGADATE__};

#define FILE_ID_STRUCT_SIZE 114 // Size of the structure
#define FILE_ID_SENTBY_LINE 32  // Offset to the SentBy line
#define FILE_ID_SENTBY_LEN  23  // SentBy line length without 0-byte

/* Extern the real ProgramName to use it instead of PROGDIR:Server
 * _ProgramName contains the real name as the Server is named on start.
 */

extern char	*_ProgramName;

/* Prototypes.
 */

int AccessFile(char *InStr);
void SPrintf(char *Buffer,char *ctl, ...);
LONG GetFileSize(char *FileName);
STRPTR MyTime(long longs, char InStr[]);
void ShutDown(long);

/* Variables for ReadArgs and Template.
 */

char 	ArgStr[]="NODENR/K/N/A,USERSLOT/K/N/A,USERNAME/K/A,FILETYPE/K/A,FILEID/K/A,CONFPATH/K/A";
char	FilePath[256],
			FileIdPath[256],
			UserName[256],
			ConfLocation[102],
			WorkStr[256];
long	ArgArray[]={0L,0L,0L,0L,0L,0L};
long	NodeNr,
			UserSlot;
BPTR	MyLock=NULL;

struct Library	*IconBase		= NULL;
struct FAMEBase	*FAMEBase		= NULL;

void main(int argc, char *argv[])
{
	struct  RDArgs      *rda  = NULL;
	struct	DiskObject	*dobj	=	NULL;

	Printf("\nSentBy v1.2 "__AMIGADATE__" by Strider (tRSi/F-iNNOVATiON)\n\nSentBy adds to fileids the for ByteAndi's FileId Door typical Sentby line.\nSentBy uses for this the Sent.dat file from ByteAndi/tRSi's FileId Door.\n");
	Printf("SentBy is used for FAMEFileChecker background processing and must be\nstarted from FAMEFileChecker.\nJust copy SentBy and it's icon to: FAME:FileCheckers/FILEID/SentBy !\n\n");

	if( ! (IconBase = (struct Library *) OpenLibrary("icon.library",0L)))
		ShutDown(4);

	if( ! (FAMEBase = (struct FAMEBase *) OpenLibrary(FAMENAME,FAMEVERSION)))
		ShutDown(9);

	WorkStr[0] = '\0';

	/* Use ReadArgs() for arguments.
	 */

	if(rda = ReadArgs(ArgStr,ArgArray,NULL)) {

		/* Node number.
		 */

		if(ArgArray[0]) {

			long *LDummy = (long *)ArgArray[0];
			NodeNr = (*LDummy);

		} else
			ShutDown(1);

		/* User slot number.
		 */

		if(ArgArray[1]) {

			long *LDummy = (long *)ArgArray[1];
			UserSlot = (*LDummy);

		} else
			ShutDown(1);

		/* User name (not needed).
		 */

		if(ArgArray[2]) {

			STRPTR MyUNPtr = (STRPTR)ArgArray[2];

			if(strlen(MyUNPtr) > 30)
				MyUNPtr[30] = '\0';
			strcpy(UserName,MyUNPtr);
		} else
			ShutDown(1);

		/* Path of the file id.
		 */

		if(ArgArray[4])
			strcpy(FilePath,(STRPTR)ArgArray[4]);
		else
			ShutDown(1);

		/* Path of the Conference.
		 */

		if(ArgArray[5])
			strcpy(ConfLocation,(STRPTR)ArgArray[5]);
		else
			ShutDown(1);

		FreeArgs(rda);
	} else
		ShutDown(1);

	/* Read the icon informations.
	 */

	if(dobj = GetDiskObject( _ProgramName )) {

		char		**oldtooltypes;
		STRPTR	TempStr;

		oldtooltypes = dobj->do_ToolTypes;

		/* Location of ByteAndi's FILEID - door.
		 */

		if(TempStr = FindToolType(oldtooltypes,"FILEIDLOCATION")) {

			if(strlen(TempStr) > 255)
				TempStr[255] = '\0';
			strcpy(FileIdPath,TempStr);
		} else {

			FreeDiskObject(dobj);
			ShutDown(3);
		}

		FreeDiskObject(dobj);
	} else
		ShutDown(2);

	/* FileId Path ok ?
	 */

	if(AccessFile(FileIdPath))
		ShutDown(5);

	/* Add the Sent.dat filename.
	 */

	if(AddPart(FileIdPath,"Sent.dat",255) == DOSFALSE)
		ShutDown(6);

	/* FileId Path + Sent.dat ok ?
	 */

	if(AccessFile(FileIdPath))
		ShutDown(7);

	/* Space for user in Sent.dat ?
	 */

	if(UserSlot > (GetFileSize(FileIdPath) / FILE_ID_STRUCT_SIZE))
		WorkStr[0] = '\0';
	else {

		/* Ok, let's get the SentBy.
		 */

		if(MyLock = Open(FileIdPath,MODE_OLDFILE)) {

			Seek(MyLock,(FILE_ID_STRUCT_SIZE * (UserSlot - 1)) + FILE_ID_SENTBY_LINE,OFFSET_BEGINNING);
			Read(MyLock,WorkStr,FILE_ID_SENTBY_LEN + 1);
			Close(MyLock);
		} else
			ShutDown(8);
	}

	/* If WorkStr is empty we have to build our own SentBy line.
	 */

	if(WorkStr[0] == '\0') {

		STRPTR MyStrPtr;

		/* Cut user name length down to FILE_ID_SENTBY_LEN chars.
		 */

		if(strlen(UserName) > FILE_ID_SENTBY_LEN)
			UserName[FILE_ID_SENTBY_LEN] = '\0';

		/* Fill up our buffer with FILE_ID_SENTBY_LEN spaces.
		 */

		FAMEStrFil(WorkStr,' ',FILE_ID_SENTBY_LEN);

		/* Take a pointer and set it to our now counted position.
		 */

		MyStrPtr = WorkStr + ((FILE_ID_SENTBY_LEN - strlen(UserName)) / 2);

		/* Copy the user name to this position.
		 */

		strcpy(MyStrPtr,UserName);

		/* Overwrite the 0-byte created by strcpy().
		 */

		if(strlen(WorkStr) < FILE_ID_SENTBY_LEN)
			WorkStr[strlen(WorkStr)] = ' ';

		/* Just set on our FILE_ID_SENTBY_LEN position a new 0-byte.
		 */

		WorkStr[FILE_ID_SENTBY_LEN] = '\0';
	}

	/* Ok, we now always have a centered or the users configured SentBy string.
	 * Let's add the rest and that's it.
	 */

	strcpy(UserName,WorkStr);
	SPrintf(WorkStr,"[35m[[34mNode [m%2.2ld[35m] [36m%23.23s [35m[%s[35m][m\n",NodeNr,UserName,MyTime(time(NULL),FileIdPath));

	/* Ok, add it.
	 */

	if(MyLock = Open(FilePath,MODE_READWRITE)) {

		Seek(MyLock,0,OFFSET_END);
		Write(MyLock,WorkStr,strlen(WorkStr));
		Close(MyLock);
	} else
		ShutDown(10);

	Printf("Everything done !\n");

	ShutDown(0);
}

int AccessFile(char InStr[])
{
	BPTR lock = NULL;

	if(lock = Lock(InStr,SHARED_LOCK)) {

		UnLock(lock);
		return(0);
	} else if(IoErr() == ERROR_OBJECT_IN_USE)
		return(0);

	return(1);
}

/* SPrintf via RawDoFmt:
 *
 * Note that you have to uses long aligned values means instead of only
 * using %d you have to use %ld! Also %lc ...
 */

void SPrintf(char *Buffer,char *ctl, ...)
	{RawDoFmt(ctl, (long *)(&ctl + 1), (void (*))"\x16\xc0\x4e\x75",Buffer);}

LONG GetFileSize(char *FileName)
{
	struct FileInfoBlock	*FileInfo=NULL;
	LONG			 Size;

	if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE)) {

		BPTR	FileLock;
		if(FileLock = Lock(FileName,ACCESS_READ)) {

			if(Examine(FileLock,FileInfo)) {

				if(FileInfo -> fib_DirEntryType < 0)
					Size = FileInfo -> fib_Size;
			}
			UnLock(FileLock);
		}
		FreeDosObject(DOS_FIB,FileInfo);
	}

	return(Size);
}

STRPTR MyTime(long longs, char InStr[])
{
  struct tm *ut = NULL;
  char merk[31];

  ut = localtime(&longs);

  if(ut->tm_hour < 10)
		SPrintf(InStr,"[32m0%ld",ut->tm_hour);
  else
		SPrintf(InStr,"[32m%ld",ut->tm_hour);

	strcat(InStr,"[m:[32m");

  if(ut->tm_min < 10)
		SPrintf(merk,"0%ld",ut->tm_min);
  else
		SPrintf(merk,"%ld",ut->tm_min);

  strcat(InStr,merk);
	strcat(InStr,"[m:[32m");

  if(ut->tm_sec < 10)
		SPrintf(merk,"0%ld",ut->tm_sec);
  else
		SPrintf(merk,"%ld",ut->tm_sec);

  strcat(InStr,merk);

	return(InStr);
}

void ShutDown(long error)
{
	long TheIoErr = 0L;

	if(FAMEBase)
		CloseLibrary((struct Library *)FAMEBase);

	if(IconBase)
		CloseLibrary((struct Library *)IconBase);

	switch(error)
	{
		case 1:
			Printf("Argument error !\n");

			TheIoErr	= ERROR_REQUIRED_ARG_MISSING ;
			error			= RETURN_ERROR;
		break;
		case 2:
			Printf("Icon not found !\n");

			TheIoErr	= ERROR_OBJECT_NOT_FOUND ;
			error			= RETURN_ERROR;
		break;
		case 3:
			Printf("ToolType FILEIDLOCATION not found !\n");

			TheIoErr	= ERROR_OBJECT_NOT_FOUND ;
			error			= RETURN_ERROR;
		break;
		case 4:
			Printf("Can't open icon.library !\n");

			TheIoErr	= ERROR_INVALID_RESIDENT_LIBRARY ;
			error			= RETURN_FAIL;
		break;
		case 5:
			Printf("Can't find FileId path !\n");

			TheIoErr	= ERROR_DIR_NOT_FOUND ;
			error			= RETURN_ERROR;
		break;
		case 6:
			Printf("Error creating path !\n");

			TheIoErr	= 0L;
			error			= RETURN_ERROR;
		break;
		case 7:
			Printf("Can't find FileId Sent.dat file !\n");

			TheIoErr	= ERROR_OBJECT_NOT_FOUND ;
			error			= RETURN_ERROR;
		break;
		case 8:
			Printf("Can't open FileId Sent.dat file !\n");

			TheIoErr	= ERROR_OBJECT_WRONG_TYPE ;
			error			= RETURN_ERROR;
		break;
		case 9:
			Printf("Can't open FAME.library !\n");

			TheIoErr	= ERROR_INVALID_RESIDENT_LIBRARY ;
			error			= RETURN_FAIL;
		break;
		case 10:
			Printf("Can't add SentBy line to file !\n");

			TheIoErr	= ERROR_OBJECT_WRONG_TYPE ;
			error			= RETURN_ERROR;
		break;
		default:
			TheIoErr	= 0L;
			error			= RETURN_OK;
		break;
	}

	Printf("\n");

	SetIoErr( TheIoErr );

	exit(error);
}
