/*
 * $VER: WBInfo.c 42.3 (13.9.95)
 * by Bruce M. Simpson
 *
 * doesn't bother checking for root / volume case
 *
 * NOT FINISHED - AND YES, THERE ARE BUGS IN HERE
 *
 * The bugs are usually caused by the CurrentDir() code. They don't seem to
 * do any harm though. No memory leakage, but haven't tested under Mungwall.
 *
 * Doesn't bother calling Examine(), and just uses PathPart()/AddPart(), so
 * you may have to type in the full path of an object. I'm working on this
 * though.
 *
 * Won't back out correctly if you try to obtain information on a
 * non-filesystem device, no memory lost, but funny lock behaviour.
 * Doesn't seem to harm the system though - but 'TurboList' generates
 * spurious bad block errors when run. I 'CD' back and it's fine - it seems
 * to have CD'd to SYS: ...
 *
 *
 * todo:
 *	multiple arguments using pattern matching
 *	handle 'disk.info' case for root directory
 *
 */

#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/alerts.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/wb.h>

#define NAMEBUFSIZE 256
static const TEXT verstag[] = "\0$VER: WBInfo 42.3 (13.9.95)";
static const TEXT ProgName[] = "WBInfo";
static const TEXT cmdtemplate[] = "OBJECT/A";


ULONG   main(void)
{
	struct ExecBase *SysBase = (*((struct ExecBase **) 4L));
	struct Process *MyTask;
	struct DosLibrary *DOSBase;
	struct IntuitionBase *IntuitionBase;
	struct Library *WorkbenchBase;
	struct Screen *screen;
	struct RDArgs *rdargs;
	BPTR    objlock;
	BPTR    parentlock;
	BPTR    olddir;
	TEXT    name[NAMEBUFSIZE];	/* 256 char buffer */
	ULONG   rc = RETURN_FAIL;
	STRPTR  arg_name;

	MyTask = (struct Process *) FindTask(NULL);

	if (DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L))
	{
		if (IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37L))
		{
			if (WorkbenchBase = OpenLibrary("workbench.library", 39L))
			{
				if (rdargs = ReadArgs(cmdtemplate, (LONG *) &arg_name, NULL))
				{
					if (*((TEXT *)arg_name))
					{
						/* insert pattern matching code here */
						/* insert public screen option code here */

						if (screen = LockPubScreen(NULL))
						{
							register ULONG size;

							if (size = PathPart(arg_name) - arg_name)
							{
								CopyMem(arg_name, &name, size);
								name[((UWORD) size)] = '\0';

								parentlock = Lock(name, ACCESS_READ);
								olddir = CurrentDir(parentlock);
							}
							else
							{
								/* object is in current directory - fake a CD
								 * to simplify cleanup operations
								 */
								parentlock = DupLock(MyTask->pr_CurrentDir);
								olddir = CurrentDir(MyTask->pr_CurrentDir);
							}

							/* sanity check on parentlock here, please */
							if (parentlock)
							{
								if (objlock = Lock(FilePart(arg_name), ACCESS_READ))
								{
									/* insert device / volume check here */
									if (NameFromLock(objlock, name, NAMEBUFSIZE))
									{
										WBInfo(parentlock, FilePart(name), screen);
										rc = RETURN_OK;
									}
									else
										/* NameFromLock failed */
										PrintFault(IoErr(), ProgName);

									UnLock(objlock);
								}
								else
									/* Lock on the object failed */
									PrintFault(IoErr(), ProgName);

								/* CD back to old current dir and free parent object lock */
								CurrentDir(olddir);
								UnLock(parentlock);
							}
							else
								/* Lock on parent directory of object failed */
								PrintFault(IoErr(), ProgName);

							UnlockPubScreen(NULL, screen);
						}
						else
						{
							/* no screen found */
							SetIoErr(ERROR_OBJECT_NOT_FOUND);
							PrintFault(ERROR_OBJECT_NOT_FOUND, ProgName);
						}
					}
					else
					{
						/* we were given a null string as input argument */
						SetIoErr(ERROR_REQUIRED_ARG_MISSING);
						PrintFault(ERROR_REQUIRED_ARG_MISSING, ProgName);
						rc = RETURN_ERROR;
					}
					FreeArgs(rdargs);
				}
				else
				{
					/* ReadArgs failed */
					PrintFault(IoErr(), ProgName);
					rc = RETURN_ERROR;
				}
				CloseLibrary(WorkbenchBase);
			}
			else
			{
				/* no workbench library */
				Alert(AG_OpenLib | AO_Workbench);
				SetIoErr(ERROR_INVALID_RESIDENT_LIBRARY);
				PrintFault(ERROR_INVALID_RESIDENT_LIBRARY, ProgName);
			}
			CloseLibrary((struct Library *) IntuitionBase);
		}
		else
		{
			/* no intuition library */
			Alert(AG_OpenLib | AO_Intuition);
			SetIoErr(ERROR_INVALID_RESIDENT_LIBRARY);
			PrintFault(ERROR_INVALID_RESIDENT_LIBRARY, ProgName);
		}
		CloseLibrary((struct Library *) DOSBase);
	}
	else
		/* no dos library */
		Alert(AG_OpenLib | AO_DOSLib);

	return (rc);
}
