/************************************************************
* MultiUser - MultiUser Task/File Support System				*
* ---------------------------------------------------------	*
* Change Password															*
* ---------------------------------------------------------	*
* © Copyright 1993-1994 Geert Uytterhoeven						*
* All Rights Reserved.													*
************************************************************/


#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <utility/tagitem.h>
#include <proto/reqtools.h>
#include <libraries/reqtools.h>
#include <string.h>
#include <libraries/multiuser.h>
#include <proto/multiuser.h>

#include "Passwd_rev.h"

#include "Locale.h"

char __VersTag__[] = VERSTAG;


static void __regargs myputs(char *str, struct DosLibrary *DOSBase);
static void __regargs mygets(char *str, struct DosLibrary *DOSBase);


int __saveds Start(char *arg)
{
	struct ExecBase *SysBase;
	struct DosLibrary *DOSBase;
	struct muBase *muBase = NULL;
	struct ReqToolsBase *ReqToolsBase = NULL;
	char oldpwd[muPASSWORDSIZE];
	char newpwd1[muPASSWORDSIZE];
	char newpwd2[muPASSWORDSIZE];
	struct RDArgs *rdargs;
	LONG args[] = {
#define argGUI	0
		NULL
	};
	static struct TagItem allwaystags[] = {
		RT_ReqPos, REQPOS_CENTERSCR,
		RT_LockWindow, TRUE,
		TAG_DONE
	};
	struct TagItem infotags[] = {
		RTEZ_Flags, EZREQF_CENTERTEXT,
		TAG_MORE, (LONG)allwaystags
	};
	struct TagItem pwdtags[] = {
		RTGS_TextFmt, NULL,
		RTGS_Invisible, TRUE,
		RTGS_AllowEmpty, TRUE,
		RTGS_Flags, GSREQF_CENTERTEXT,
		RTGS_GadFmt, (LONG)"OK",
		TAG_MORE, (LONG)allwaystags
	};
	BOOL gui;
	int rc = RETURN_ERROR;
	struct LocaleInfo li;

	SysBase = *(struct ExecBase **)4;
	
	if ((!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) ||
		 (!(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39))) ||
		 (!(ReqToolsBase = (struct ReqToolsBase *)OpenLibrary("reqtools.library", 38)))) {
		rc = ERROR_INVALID_RESIDENT_LIBRARY;
		goto Exit;
	}

	OpenLoc(&li);

	rdargs = ReadArgs("GUI/S", args, NULL);
	if (!rdargs)
		PrintFault(IoErr(), NULL);
	else {
		gui = args[argGUI] &&
				(((struct Process *)SysBase->ThisTask)->pr_WindowPtr != (APTR)-1);
		if (gui) {
			memset(oldpwd, '\0', sizeof(oldpwd));
			memset(newpwd1, '\0', sizeof(newpwd1));
			memset(newpwd2, '\0', sizeof(newpwd2));
			pwdtags[0].ti_Data = (LONG)GetLocS(&li,MSG_ENTEROLDPWD_GUI);
			rtGetStringA(oldpwd, muPASSWORDSIZE-1, GetLocS(&li,MSG_PASSWDREQ_GUI),
							 NULL, pwdtags);
			pwdtags[0].ti_Data = (LONG)GetLocS(&li,MSG_ENTERNEWPWD_GUI);
			rtGetStringA(newpwd1, muPASSWORDSIZE-1, GetLocS(&li,MSG_PASSWDREQ_GUI),
							 NULL, pwdtags);
			pwdtags[0].ti_Data = (LONG)GetLocS(&li,MSG_RETYPEPWD_GUI);
			rtGetStringA(newpwd2, muPASSWORDSIZE-1, GetLocS(&li,MSG_PASSWDREQ_GUI),
							 NULL, pwdtags);
		} else {
			myputs(GetLocS(&li,MSG_ENTEROLDPWD_CON), DOSBase);
			myputs(" [8m", DOSBase);
			mygets(oldpwd, DOSBase);
			myputs("[28m\n", DOSBase);
			myputs(GetLocS(&li,MSG_ENTERNEWPWD_CON), DOSBase);
			myputs(" [8m", DOSBase);
			mygets(newpwd1, DOSBase);
			myputs("[28m\n", DOSBase);
			myputs(GetLocS(&li,MSG_RETYPEPWD_CON), DOSBase);
			myputs(" [8m", DOSBase);
			mygets(newpwd2, DOSBase);
			myputs("[28m\n\n", DOSBase);
		};

		if (strcmp(newpwd1, newpwd2))
			if (gui)
				rtEZRequestA(GetLocS(&li,MSG_RETYPEERROR_GUI), GetLocS(&li,MSG_OK), NULL, NULL, infotags);
			else
				myputs(GetLocS(&li,MSG_RETYPEERROR_CON), DOSBase);
		else
			if (muPasswd(oldpwd, newpwd1)) {
				if (gui)
					rtEZRequestA(GetLocS(&li,MSG_PWDCHANGEOK_GUI), GetLocS(&li,MSG_OK), NULL, NULL, infotags);
				else
					myputs(GetLocS(&li,MSG_PWDCHANGEOK_CON), DOSBase);
				rc = RETURN_OK;
			} else
				if (gui)
					rtEZRequestA(GetLocS(&li,MSG_PWDCHANGEFAIL_GUI), GetLocS(&li,MSG_OK), NULL, NULL, infotags);
				else
					myputs(GetLocS(&li,MSG_PWDCHANGEFAIL_CON), DOSBase);
	}
	FreeArgs(rdargs);

	CloseLoc(&li);

Exit:
	CloseLibrary((struct Library *)ReqToolsBase);
	CloseLibrary((struct Library *)muBase);
	CloseLibrary((struct Library *)DOSBase);

	return(rc);
}	


static void __regargs myputs(char *str, struct DosLibrary *DOSBase)
{
	Write(Output(), str, strlen(str));
}


static void __regargs mygets(char *str, struct DosLibrary *DOSBase)
{
	LONG len = 0;
	char buf;
	BOOL done = FALSE;
	BPTR in, out;

	in = Input();
	out = Output();
	SetMode(in, 1);
	do {
		Read(in, &buf, 1);
		switch(buf) {
			case	'\b':
				if (len) {
					FPutC(out, '\b');
					Flush(out);
					len--;
				}
				break;
	
			case	'\n':
			case	'\r':
				done = TRUE;
				break;
	
			default:
				if ((len < muPASSWORDSIZE-1) && ((buf & 0x7f) > 31)
					 && (buf != 127)) {
					FPutC(out, ' ');
					str[len++] = buf;
				} else
					FPutC(out, 7);
				Flush(out);
				break;
		}
	} while (!done);
	str[len] = 0;
	SetMode(in, 0);
	FPutC(out, '\r');
	Flush(out);
}
