/***************************************************************************/
/*									   */
/*			Itzz						   */
/*									   */
/***************************************************************************/
/*									   */
/* This magnificient piece of software is Freeware, so you do not need to  */
/* send any money to me, but I would like to receive some good sourcecodes */
/* especially for OS2.0 [ amiga, of course ;-) ]			   */
/*									   */
/***************************************************************************/
/*									   */
/* This program makes it possible to use wildcards with all programs, even */
/* if they do not support wildcards by themself.			   */
/* Please read the docs for more information and some examples !	   */
/*									   */
/***************************************************************************/
/*									   */
/* This program was written, conceived and compiled by			   */
/*									   */
/*	Michael Illgner 						   */
/*	Theodorstr. 27  						   */
/*	W-4790 Paderborn						   */
/*	Germany 							   */
/*	Tel.: 05251/26488 or 05251/60-2331				   */
/*									   */
/*	email: fillg1@uni-paderborn.de  				   */
/*									   */
/***************************************************************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dostags.h>
#include <proto/dos.h>
#include <proto/exec.h>

#include <string.h>

#define ExecFlag ArgArray[2]
#define AllFlag  ArgArray[3]

char  Version[]  = "$VER: For 1.6 "__DATE__" "__TIME__; /* Version string */
char  Template[] = "FILE,CMD,EXEC/S,ALL/S";             /* Template for command line */
char  DefPath[]  = "#?";	                        /* default wildcard, use all files */
char  DefArg[]   = "%s";	                        /* default command, filename only */

/* taglist for Dos.System(), I'm using a UserShell */

/* size of various buffers, should be enough for most cases. Be carefull, no checking !*/
#define BUF_SIZE 255

/* no startup-code, no link-library */
void __saveds main(void)
{
  struct Library *DOSBase;
  
  /* used for argument parsing, thanks to DOS 2.0 */
  ULONG 		    ArgArray[4];
  struct RDArgs     *rd;
  struct AnchorPath  *ap;
  BOOL		    error;
 
  /* memory for command and pathname */
  char		    Buffer[BUF_SIZE+1], Pathname[BUF_SIZE];
  /* flag %f, %b, %p etc */
  BOOL		    Special;
  char		    *s, *s1, *t;
  
  /* no startup, I've to open DOS myself ! */
  if (DOSBase = OpenLibrary("dos.library", 37))
    {
      if (ap = AllocVec(sizeof(struct AnchorPath), MEMF_CLEAR))
	{
	  /* setup the argument parser */
	  ArgArray[0] = (ULONG)DefPath;
	  ArgArray[1] = (ULONG)DefArg;
	  ArgArray[2] = FALSE;
	  ArgArray[3] = FALSE;
   
	  rd = ReadArgs(Template, ArgArray, NULL);
  
	  /* treat all matching files */
	  error = MatchFirst((UBYTE *)ArgArray[0], ap);
	  while (!(error || (SetSignal(0, 0) & SIGBREAKF_CTRL_C)))
	    {
	      if (ap->ap_Info.fib_DirEntryType > 0)
		{
		  if (!(ap->ap_Flags & APF_DIDDIR) && AllFlag) ap->ap_Flags |= APF_DODIR;
		  ap->ap_Flags &= ~APF_DIDDIR;
		}
	      else
		{
		  /* build the command string, copy and insert */
		  s = (char *)ArgArray[1]; t = Buffer; Special = FALSE;
		  while (*s)
		    {
		      if (*s == '%') Special = TRUE;
		      else if (Special)
			{
			  switch (*s)
			    {
			    case '%' : /* %% is a single % */
			      *t++ = '%';
			      break;
			    case 'b' :
			    case 'B' : /* insert the base filename, up to the first '.' */
			      s1 = ap->ap_Info.fib_FileName;
			      while ((*s1) && (*s1 != '.')) *t++ = *s1++;
			      break;
			    case 'f' :
			    case 'F' : /* insert the whole filename including path */
			      NameFromLock(ap->ap_Current->an_Lock, Pathname, sizeof(Pathname));
			      AddPart(Pathname, ap->ap_Info.fib_FileName, sizeof(Pathname));
			      s1 = Pathname;
			      *t++ = '"';
			      while (*s1) *t++ = *s1++;
			      *t++ = '"';
			      break;
			    case 's' :
			    case 'S' : /* insert the filename */
			      s1 = ap->ap_Info.fib_FileName;
			      while (*s1) *t++ = *s1++;
			      break;
			    case 'p' :
			    case 'P' : /* insert the pathname. caution : no trailing '/' */
			      NameFromLock(ap->ap_Current->an_Lock, Pathname, sizeof(Pathname));
			      s1 = Pathname;
			      while (*s1) *t++ = *s1++;
			      break;
			    }
			  Special = FALSE;
			}
		      else *t++ = *s; /* simple normal character */
		      s++;
		    }
		  if (ExecFlag)
		    {
		      /* end string, execute it ! */
		      *t = '\0';
		      SystemTags(Buffer,
				 SYS_UserShell, TRUE,
				 TAG_END);
		    }
		  else
		    {
		      /* append newline, print it ! */
		      *t++ = '\n'; *t = '\0';
		      Write(Output(), Buffer, strlen(Buffer));
		    }
		}
	      error = MatchNext(ap);
	    }
	  MatchEnd(ap);
	  
	  if (rd) FreeArgs(rd);
	  FreeVec(ap);
	}
      CloseLibrary(DOSBase);
      /* I'm off ! */
    }
}



