/************************************************************
* 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 <dos/datetime.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 quick,
									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,QUICK/S",
						 argarray, NULL);
	if (!args)
		error = IoErr();
	else
		if (info = muAllocUserInfo()) {
			if (!argarray[0] && !argarray[1] && !argarray[2] && !argarray[3] &&
				 !argarray[4]) {
				if (!argarray[5])
					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]) {
				if (!argarray[5])
					PutStr("Dumping information for all users...\n\n");
				if (muGetUserInfo(info, muKeyType_First)) {
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					while (muGetUserInfo(info, muKeyType_Next) &&
							 !CheckSignal(SIGBREAKF_CTRL_C)) {
						if (!argarray[5])
							PutStr("\n");
						DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					}
				} else
					PutStr("No information\n");
				goto Done;
			}

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

			if (argarray[2]) {
				if (!argarray[5])
					VPrintf("Dumping information for user %ld\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]) {
				if (!argarray[5])
					VPrintf("Dumping information for group %ld\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) &&
							 !CheckSignal(SIGBREAKF_CTRL_C)) {
						if (!argarray[5])
							PutStr("\n");
						DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					}
				} else
					PutStr("No information\n");
				goto Done;
			}

			if (argarray[4]) {
				if (!argarray[5])
					VPrintf("Dumping information for user '%s'\n\n", &argarray[4]);
				strncpy(info->UserName, (char *)argarray[4], muUSERNAMESIZE);
				if (muGetUserInfo(info, muKeyType_WUserName)) {
					DumpUserInfo(info, argarray[5], DOSBase, SysBase);
					while (muGetUserInfo(info, muKeyType_WUserNameNext) &&
							 !CheckSignal(SIGBREAKF_CTRL_C)) {
						if (!argarray[5])
							PutStr("\n");
						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 quick,
									struct DosLibrary *DOSBase,
									struct ExecBase *SysBase)
{
	LONG stream[5];
	BPTR dir, file;
	char buffer[256];
	BOOL neverloggedin = TRUE;
	int i;

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

	if (quick)
		VPrintf("%s\n", stream);
	else {
		VPrintf("User '%s' (uid %04lx, gid %04lx)\n"
				  "In real life '%s'\n"
				  "Home Directory '%s'\n", stream);

		if (dir = Lock((char *)stream[4], SHARED_LOCK)) {
			dir = CurrentDir(dir);
			if (file = Open(muLastLogin_FileName, MODE_OLDFILE)) {
				if (FGets(file, buffer, 3*LEN_DATSTRING+2))
					neverloggedin = FALSE;
				Close(file);
			}
			if (neverloggedin)
				PutStr("Never logged in.\n");
			else {
				stream[0] = (LONG)buffer;
				stream[1] = (LONG)"";
				stream[2] = (LONG)"";
				for (i = 0; buffer[i] && (buffer[i] != ' '); i++);
				if (buffer[i]) {
					buffer[i] = '\0';
					stream[1] = (LONG)&buffer[++i];
					while (buffer[i] && (buffer[i] != ' '))
						i++;
					if (buffer[i]) {
						buffer[i] = '\0';
						stream[2] = (LONG)&buffer[++i];
						while (buffer[i] && (buffer[i] != ' ') &&
								 (buffer[i] != '\n'))
							i++;
						buffer[i] = '\0';
					}
				}
				VPrintf("Last login on %s, %s at %s.\n", stream);
			}
			if (file = Open(".plan", MODE_OLDFILE)) {
				PutStr("Plan:\n");
				while (!CheckSignal(SIGBREAKF_CTRL_C) && FGets(file, buffer, 255))
																				 /* V39: use 256 */
					PutStr(buffer);
				Close(file);
			} else
				PutStr("No plan.\n");
			UnLock(CurrentDir(dir));
		}
	}
}
