
/******************************************************************************

    MODULE
	VolName.c

    DESCRIPTION
	Get one filename on Commandline
	and write to StdOut its Volumename

    NOTES
	Kickstart 2.0+ required
	compiles w/ SAS/C v6.51

    BUGS
	We may use 'Lock', so VolName fails, if the
	file does't exist or is exclusively locked

    TODO

    EXAMPLES

    SEE ALSO

    INDEX

    HISTORY
	08-02-95 b_noll created
	11-02-95 b_noll enabled 'DEVICE/S', changed 'PHYSICAL' to 'VOLUME'
	20-02-95 b_noll restructured source
	21-02-95 b_noll added version/format-prefix/offset
	20-03-95 b_noll added args diagnostics

    AUTHOR
	Bernd Noll, Brunnenstrasse 55, D-67661 Kaiserslautern
	b_noll@informatik.uni-kl.de

******************************************************************************/

/**************************************
	    Includes
**************************************/

#ifndef   EXEC_LIBRARIES_H
# include <exec/libraries.h>
#endif /* EXEC_LIBRARIES_H */

#ifndef   CLIB_EXEC_PROTOS_H
# include <clib/exec_protos.h>
#endif /* CLIB_EXEC_PROTOS_H */

#ifndef   DOS_DOS_H
# include <dos/dos.h>
#endif /* DOS_DOS_H */

#ifndef   CLIB_DOS_PROTOS_H
# include <clib/dos_protos.h>
#endif /* CLIB_DOS_PROTOS_H */

#include <proto/dos.h>
#include <proto/exec.h>

/**************************************
	 Defines & Structures
**************************************/

#ifndef ABSEXECBASE
#define ABSEXECBASE ((struct ExecBase **)4L)
#endif

struct _arg {
/* ******************** USER FORMAT ******************** */
#define FORMAT "FILE/A,VOLUME/S,DEVICE/S"

    STRPTR file;
    ULONG  volume;
    ULONG  device;

/* ******************** USER FORMAT ******************** */
}; /* struct _argv */

#define MAXPATHLEN 256
#define MAXLINELEN 256

#define VERSIONPREFIX	"\0$VER: "
#define VERSIONOFFSET	0
#define FORMATPREFIX	"\0$ARG: "
#define FORMATOFFSET	7

/**************************************
	    Implementation
**************************************/

#if defined(_DCC)

/* DICE has no '__inline' directive; we must set the support
   function behind the main function, cause the program is
   started w/ the 1st opcode */

long __main(void) { static long _main(void); return _main(); }

#endif

/* only SAS/C and GNU/C have an '__inline' directive */
/* ******************** USER ADDES ******************** */

/*static __inline void DLName2CSTR(BPTR bstr, STRPTR buf, WORD bsize) {
    STRPTR x,y;
    int z;
    x = (STRPTR)BADDR(bstr);
    y = buf;
    z = *(x++);
    if (z >= bsize) z = bsize - 1;
    while (z--) *(y++) = *(x++);
    *(y++) = ':';
    *y	   = 0;
} /* DLName2CSTR */

/* ******************** USER ADDES ******************** */

long _main (void)
{
    const char* version = VERSIONPREFIX "VolName 1.3 " __AMIGADATE__ + VERSIONOFFSET;
    long retval = RETURN_FAIL;
    struct ExecBase*SysBase = *ABSEXECBASE;
    struct Library* DOSBase;

    if (DOSBase = OpenLibrary (DOSNAME, 37)) {
	struct _arg argv = { 0 };
	APTR   args;
	retval	 = RETURN_ERROR;
	if (args = (void*)ReadArgs(FORMATPREFIX FORMAT + FORMATOFFSET, (LONG*)&argv, NULL)) {
/* ******************** USER BODY ******************** */

	    APTR	    processwin;
	    struct Process *process;
	    STRPTR	    filename = argv.file;
	    //UBYTE	    buffer[MAXPATHLEN];
	    BPTR	    out;

	    out = Output();

	    if ((process = (struct Process *)FindTask(NULL))) {
		processwin = process->pr_WindowPtr;
		process->pr_WindowPtr = (APTR)-1;
	    } /* if */

	    if (argv.device || argv.volume || !*filename) {

		BPTR lock;
//dolock:

		if (lock = Lock(filename, SHARED_LOCK)) {
		    struct FileLock *fl;
		    struct DosList  *dl;

		    fl = BADDR(lock);
		    dl = BADDR(fl->fl_Volume);

		    if (argv.device) {
			struct MsgPort	*mp;

			mp = dl->dol_Task;

			dl = LockDosList(LDF_DEVICES|LDF_READ);
			while (dl = NextDosEntry(dl,LDF_DEVICES)) {
			    if (dl->dol_Task == mp) {
				FPrintf(out, "%b:\n", dl->dol_Name);
				out = 0;
				break;
			    } /* if Found */
			} /* while Searching */
			UnLockDosList(LDF_DEVICES|LDF_READ);
		    } else {
			FPrintf(out, "%b:\n", dl->dol_Name);
			out = 0;
		    } /* if (!)Device */

		    UnLock (lock);
		} /* if Lock */
	    } /* if DoLocking */



	    /* ---- Extract the Volumepart */
	    if (out) {
#ifdef ALPHA
		UBYTE buffer[MAXPATHLEN];
		if (SplitName(filename, ':', buffer, 0, MAXPATHLEN) != -1) {
		    FPrintf(out, "%s:\n", buffer);
		    out = 0;
//		  } else if (*filename) {
//		      filename = "";
//		      goto dolock;
		} /* if */
#else
		UBYTE		c, *p;
		for (p = filename; (c = *p) && c != ':'; ++p);
		if (c) {
		    *p = 0;
		    FPrintf(out, "%s:\n", filename);
		    out = 0;
		    *p = ':';
//		  } else if (*filename) {
//		      filename = "";
//		      goto dolock;
		} /* if */
#endif
	    } /* if */
	    //PutStr (":\n");
	    retval = out ? RETURN_WARN : RETURN_OK;


	    if (process != NULL) {
		process->pr_WindowPtr = processwin;
	    } /* if */

/* ******************** USER BODY ******************** */
	    FreeArgs (args);
	} /* if */

	if (retval > RETURN_WARN)
	    PrintFault(IoErr(), "VolName");

	CloseLibrary (DOSBase);
    } /* if */
    return (retval);
} /* _main */


/******************************************************************************
*****  END VolName.c
******************************************************************************/

