/************************************************************
* MultiUser - MultiUser Task/File Support System				*
* ---------------------------------------------------------	*
* Get Information about one or more Users							*
* ---------------------------------------------------------	*
* © Copyright 1993 by Geert Uytterhoeven							*
* All Rights Reserved.													*
************************************************************/


#include <exec/types.h>
#include	<exec/memory.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include <libraries/multiuser.h>
#include <proto/multiuser.h>

#include "UserInfo_rev.h"


char __VersTag__[] = VERSTAG;


void __regargs DumpUserInfo(struct muUserInfo *info, BOOL plan,
										struct DosLibrary *DOSBase, struct ExecBase *SysBase);

int __saveds Start(char *arg)
{
	struct ExecBase *SysBase;
	struct DosLibrary *DOSBase;
	struct muBase *muBase = NULL;
	struct RDArgs *args;
	LONG argarray[] = {
		NULL, NULL, NULL, NULL, NULL, NULL
	};
	struct muUserInfo *info;
	LONG error = NULL;
	int rc = RETURN_OK;

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

	args = ReadArgs("ALL/S,USERID,UID/K/N,GID/K/N,NAME/K,PLAN/S", argarray, NULL);
	if (!args)
		error = IoErr();
	else
		if (info = muAllocUserInfo()) {
			if (!argarray[0] && !argarray[1] && !argarray[2] && !argarray[3] &&
				 !argarray[4]) {
				PutStr("Dumping information for this user\n\n");
				info->uid = muGetTaskOwner(NULL)>>16;
				if (muGetUserInfo(info, muKeyType_uid))
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
				else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[0]) {
				PutStr("Dumping information for all users...\n\n");
				if (muGetUserInfo(info, muKeyType_First)) {
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					while (muGetUserInfo(info, muKeyType_Next)) {
						PutStr("\n");
						DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					}
				} else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[1]) {
				VPrintf("Dumping information for user '%s'\n\n", &argarray[1]);
				strncpy(info->UserID, (char *)argarray[1], muUSERIDSIZE);
				if (muGetUserInfo(info, muKeyType_UserID))
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
				else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[2]) {
				VPrintf("Dumping information for user 0x%04lx\n\n", (LONG *)argarray[2]);
				info->uid = (UWORD)*(LONG *)argarray[2];
				if (muGetUserInfo(info, muKeyType_uid))
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
				else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[3]) {
				VPrintf("Dumping information for group 0x%04lx\n\n", (LONG *)argarray[3]);
				info->gid = (UWORD)*(LONG *)argarray[3];
				if (muGetUserInfo(info, muKeyType_gid)) {
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					while (muGetUserInfo(info, muKeyType_gidNext)) {
						PutStr("\n");
						DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					}
				} else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[4]) {
				VPrintf("Dumping information for user '%s'\n\n", &argarray[4]);
				strncpy(info->UserName, (char *)argarray[4], muUSERNAMESIZE);
				if (muGetUserInfo(info, muKeyType_UserName))
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
				else
					PutStr("No information\n");
				goto Done;
			}

Done:		muFreeUserInfo(info);
		} else
			error = IoErr();
	FreeArgs(args);
	if (error) {
		PrintFault(error, NULL);
		rc = RETURN_ERROR;
	}

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

	return(rc);
}	


	/*
	 *		Dump User Information
	 */

void __regargs DumpUserInfo(struct muUserInfo *info, BOOL plan,
									struct DosLibrary *DOSBase, struct ExecBase *SysBase)
{
	LONG stream[5];
	BPTR planfile;
	BPTR out;
	char *buf;
	ULONG l;
	BPTR dir1, dir2;

	stream[0] = (LONG)info->UserID;
	stream[1] = info->uid;
	stream[2] = info->gid;
	stream[3] = (LONG)info->UserName;
	stream[4] = (LONG)info->HomeDir;

	out = Output();
	VFPrintf(out,"User '%s' (uid %04lx, gid %04lx)\n"
			  "In real life '%s'\n"
			  "Home Directory '%s'\n", stream);

	if (plan)
		if (dir1 = Lock((char *)stream[4], SHARED_LOCK)) {
			dir2 = CurrentDir(dir1);
			if (planfile = Open(".plan", MODE_OLDFILE)) {
				if (buf = AllocVec(8192, MEMF_PUBLIC)) {
					VFPrintf(out, "\n   ------- Plan of %s -------\n\n", stream);
					Flush(out);
					while (l = Read(planfile, buf, 8192))
						Write(out, buf, l);
					Flush(out);
					VFPrintf(out, "\n\n  ---- End of plan of %s ----\n", stream);
					FreeVec(buf);
				}
				Close(planfile);
			}
			CurrentDir(dir2);
			UnLock(dir1);
		}

	Flush(out);
}
