/* $Revision Header * Header built automatically - do not edit! *************
 *
 *	(C) Copyright 1991 by Olaf 'Olsen' Barthel & MXM
 *
 *	Name .....: UpdateConfig.c
 *	Created ..: Saturday 23-Mar-91 22:07
 *	Revision .: 0
 *
 *	Date            Author          Comment
 *	=========       ========        ====================
 *	23-Mar-91       Olsen           Created this file!
 *
 * $Revision Header ********************************************************/

struct TermInfo
{
	UWORD	Version;
	UWORD	Revision;
};

extern LONG TermVersion,TermRevision;
extern UBYTE TermName[],TermDate[],TermString[];

struct Configuration
{
	/* Serial Preferences. */

	ULONG	BaudRate;
	BYTE	BitsPerChar;
	BYTE	Parity;
	BYTE	StopBits;
	BYTE	Handshaking;
	BYTE	Duplex;
	BYTE	HighSpeed;
	ULONG	BreakLength;
	UBYTE	SerialDevice[40];
	LONG	UnitNumber;

	/* Modem Preferences. */

	UBYTE	ModemInit[80];
	UBYTE 	ModemExit[80];
	UBYTE	DialPrefix[80];
	LONG	RedialDelay;
	LONG	DialRetries;
	LONG	DialTimeout;
	BYTE	ConnectAutoBaud;
	UBYTE	NoCarrier[16];
	UBYTE	Connect[16];
	UBYTE	Error[16];
	UBYTE	Voice[16];
	UBYTE	Ring[16];
	UBYTE	Busy[16];
	UBYTE	Okay[16];

	/* Transfer Preferences. */

	UBYTE	Protocol[40];

	/* Startup macro. */

	UBYTE	StartupMacro[256];

	/* Macro Preferences. */

	UBYTE	MacroFile[256];

	/* Screen Preferences. */

	ULONG	DisplayMode;
	UWORD	Colours[16];
	BYTE	MakeScreenPublic;
	BYTE	ShanghaiWindows;

	/* Terminal Preferences. */

	BYTE	CaptureFilter;
	BYTE	DestructiveBackspace;
	BYTE	AudibleBell;
	BYTE	VisibleBell;
	BYTE	EightyColumns;
	BYTE	SendCR;
	BYTE	SendLF;
	BYTE	ColourMode;
	BYTE	Emulation;
	BYTE	Font;
};

	/* A phone book entry. */

struct PhoneEntry
{
	UBYTE			Name[40];
	UBYTE			Number[40];
	UBYTE			Password[40];

	LONG			PayPerUnit;
	LONG			MinPerUnit;

	struct Configuration	Config;
};

struct NewConfiguration
{
	/* Serial Preferences. */

	ULONG	BaudRate;
	BYTE	BitsPerChar;
	BYTE	Parity;
	BYTE	StopBits;
	BYTE	Handshaking;
	BYTE	Duplex;
	BYTE	HighSpeed;
	ULONG	BreakLength;
	UBYTE	SerialDevice[40];
	LONG	UnitNumber;

	/* Modem Preferences. */

	UBYTE	ModemInit[80];
	UBYTE 	ModemExit[80];
	UBYTE 	ModemHangup[80];
	UBYTE	DialPrefix[80];
	LONG	RedialDelay;
	LONG	DialRetries;
	LONG	DialTimeout;
	BYTE	ConnectAutoCapture;
	BYTE	ConnectAutoBaud;
	BYTE	LogActions;
	UBYTE	NoCarrier[16];
	UBYTE	Connect[16];
	UBYTE	Voice[16];
	UBYTE	Ring[16];
	UBYTE	Busy[16];

	/* Transfer Preferences. */

	UBYTE	Protocol[40];

	/* Startup macro. */

	UBYTE	StartupMacro[256];

	/* Macro Preferences. */

	UBYTE	MacroFile[256];

	/* Screen Preferences. */

	ULONG	DisplayMode;
	UWORD	Colours[16];
	BYTE	MakeScreenPublic;
	BYTE	ShanghaiWindows;

	/* Terminal Preferences. */

	BYTE	CaptureFilter;
	BYTE	DestructiveBackspace;
	BYTE	AudibleBell;
	BYTE	VisibleBell;
	BYTE	EightyColumns;
	BYTE	DisableBlinking;
	BYTE	SendCR;
	BYTE	SendLF;
	BYTE	ColourMode;
	BYTE	Emulation;
	BYTE	Font;

	/* Emulation control. */

	BYTE	CursorApp;
	BYTE	FontScale;
	BYTE	JumpScroll;
	BYTE	AutoWrap;
	BYTE	CursorWrap;
	BYTE	NewLine;
	BYTE	InsertChar;
	BYTE	NumApp;

	/* Path Preferences. */

	UBYTE	DefaultStorage[256];

	UBYTE	TextUploadPath[256];
	UBYTE	TextDownloadPath[256];

	UBYTE	ASCIIUploadPath[256];
	UBYTE	ASCIIDownloadPath[256];

	UBYTE	BinaryUploadPath[256];
	UBYTE	BinaryDownloadPath[256];

	UBYTE	CapturePath[256];
	UBYTE	LogFile[256];
	UBYTE	Editor[256];
	UBYTE	BeepSound[256];
};

LONG __saveds			Main(VOID);
BYTE				WriteIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type);
BYTE				ReadIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type);
struct NewConfiguration *	Convert(struct Configuration *Src);

struct ExecBase		*SysBase;
struct DosLibrary	*DOSBase;
struct Library		*IFFParseBase;

LONG __saveds
Main()
{
	SysBase = *(struct ExecBase **)4;

	if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36))
	{
		if(IFFParseBase = (struct Library *)OpenLibrary("iffparse.library",0))
		{
			UBYTE **ArgArray;

			if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *),MEMF_PUBLIC | MEMF_CLEAR))
			{
				struct RDArgs *ArgsPtr;

				if(ArgsPtr = (struct RDArgs *)ReadArgs("File",(LONG *)ArgArray,NULL))
				{
					if(ArgArray[0])
					{
						struct Configuration Config;

						if(ReadIFFData(ArgArray[0],&Config,sizeof(struct Configuration),'PREF'))
						{
							if(!WriteIFFData(ArgArray[0],Convert(&Config),sizeof(struct NewConfiguration),'PREF'))
								Printf("\33[1mUpdateConfig:\33[0m Couldn't save file \"%s\"!\a\n",ArgArray[0]);
						}
						else
							Printf("\33[1mUpdateConfig:\33[0m Couldn't load file \"%s\"!\a\n",ArgArray[0]);
					}

					FreeArgs(ArgsPtr);
				}

				FreeVec(ArgArray);
			}

			CloseLibrary(IFFParseBase);
		}

		CloseLibrary(DOSBase);
	}

	return(RETURN_OK);
}

	/* WriteIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type):
	 *
	 *	Write data to an IFF file (via iffparse.library).
	 */

BYTE
WriteIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type)
{
	struct IFFHandle	*Handle;
	BYTE			 Success = FALSE;

		/* Allocate a handle. */

	if(Handle = AllocIFF())
	{
			/* Open an output stream. */

		if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
		{
				/* Tell iffparse that this is
				 * a DOS handle.
				 */

			InitIFFasDOS(Handle);

				/* Open the handle for writing. */

			if(!OpenIFF(Handle,IFFF_WRITE))
			{
					/* Push outmost chunk onto stack. */

				if(!PushChunk(Handle,'TERM','FORM',IFFSIZE_UNKNOWN))
				{
						/* Add a version identifier. */

					if(!PushChunk(Handle,0,'VERS',IFFSIZE_UNKNOWN))
					{
						struct TermInfo TermInfo;

						TermInfo . Version	= TermVersion;
						TermInfo . Revision	= TermRevision;

							/* Write the version data. */

						if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
						{
								/* Pop the version chunk, i.e. write it to the file. */

							if(PopChunk(Handle))
								Success = FALSE;
							else
							{
									/* Push the real data chunk on the stack. */

								if(!PushChunk(Handle,0,Type,IFFSIZE_UNKNOWN))
								{
										/* Write the data. */

									if(WriteChunkBytes(Handle,Data,Size) == Size)
										Success = TRUE;

											/* Pop the data chunk. */

									if(PopChunk(Handle))
										Success = FALSE;
								}
								else
									Success = FALSE;
							}
						}
						else
							Success = FALSE;
					}

						/* Seems that we're done, now try to pop the FORM chunk
						 * and return.
						 */

					if(PopChunk(Handle))
						Success = FALSE;
				}

					/* Close the handle (flush any pending data). */

				CloseIFF(Handle);
			}

				/* Close the DOS handle itself. */

			Close(Handle -> iff_Stream);
		}

			/* And free the IFF handle. */

		FreeIFF(Handle);
	}

	if(Success)
		SetProtection(Name,FIBF_EXECUTE);

	return(Success);
}

	/* ReadIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type):
	 *
	 *	Read data from a `TERM' FORM chunk contained in an IFF file.
	 */

BYTE
ReadIFFData(UBYTE *Name,APTR Data,LONG Size,ULONG Type)
{
	struct IFFHandle	*Handle;
	BYTE			 Success = FALSE;

	if(Handle = AllocIFF())
	{
		if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
		{
			InitIFFasDOS(Handle);

			if(!OpenIFF(Handle,IFFF_READ))
			{
					/* The following line tells iffparse to stop at the
					 * very beginning of a `Type' chunk contained in a
					 * `TERM' FORM chunk.
					 */

				if(!StopChunk(Handle,'TERM',Type))
				{
						/* Parse the file... */

					if(!ParseIFF(Handle,IFFPARSE_SCAN))
					{
							/* The file read pointer is positioned
							 * just in front of the first data
							 * to be read, so let's don't disappoint
							 * iffparse and read it.
							 */

						if(ReadChunkBytes(Handle,Data,Size) == Size)
							Success = TRUE;
					}
				}

				CloseIFF(Handle);
			}

			Close(Handle -> iff_Stream);
		}

		FreeIFF(Handle);
	}

	return(Success);
}

	/* Convert(struct PhoneEntry *Src):
	 *
	 *	Convert a phonebook entry.
	 */

struct NewConfiguration *
Convert(struct Configuration *Src)
{
	STATIC struct NewConfiguration Dst;

	Dst . BaudRate			= Src -> BaudRate;
	Dst . BitsPerChar		= Src -> BitsPerChar;
	Dst . Parity			= Src -> Parity;
	Dst . StopBits			= Src -> StopBits;
	Dst . Handshaking		= Src -> Handshaking;
	Dst . Duplex			= Src -> Duplex;
	Dst . HighSpeed			= Src -> HighSpeed;
	Dst . BreakLength		= Src -> BreakLength;

	strcpy(Dst . SerialDevice,Src -> SerialDevice);

	Dst . UnitNumber			= Src -> UnitNumber;

	strcpy(Dst . ModemInit,Src -> ModemInit);
	strcpy(Dst . ModemExit,Src -> ModemExit);
	strcpy(Dst . ModemHangup,"~~~~~~+++~~ATH0\\r");
	strcpy(Dst . DialPrefix,Src -> DialPrefix);

	Dst . RedialDelay		= Src -> RedialDelay;
	Dst . DialRetries		= Src -> DialRetries;
	Dst . DialTimeout		= Src -> DialTimeout;
	Dst . ConnectAutoBaud		= Src -> ConnectAutoBaud;

	strcpy(Dst . NoCarrier,Src -> NoCarrier);
	strcpy(Dst . Connect,Src -> Connect);
	strcpy(Dst . Voice,Src -> Voice);
	strcpy(Dst . Ring,Src -> Ring);
	strcpy(Dst . Busy,Src -> Busy);

	strcpy(Dst . Protocol,Src -> Protocol);

	strcpy(Dst . StartupMacro,Src -> StartupMacro);

	strcpy(Dst . MacroFile,Src -> MacroFile);

	Dst . DisplayMode		= Src -> DisplayMode;

	CopyMem(Src -> Colours,Dst . Colours,sizeof(UWORD) * 16);

	Dst . MakeScreenPublic		= Src -> MakeScreenPublic;
	Dst . ShanghaiWindows		= Src -> ShanghaiWindows;

	Dst . CaptureFilter		= Src -> CaptureFilter;
	Dst . DestructiveBackspace	= Src -> DestructiveBackspace;
	Dst . AudibleBell		= Src -> AudibleBell;
	Dst . VisibleBell		= Src -> VisibleBell;
	Dst . EightyColumns		= Src -> EightyColumns;
	Dst . SendCR			= Src -> SendCR;
	Dst . SendLF			= Src -> SendLF;
	Dst . ColourMode		= Src -> ColourMode;
	Dst . Emulation			= Src -> Emulation;
	Dst . Font			= Src -> Font;

	strcpy(Dst . DefaultStorage,"ENVARC:sys");

	return(&Dst);
}
