#include "struct.c"

#define Fail(s) Printf("%s File %s Line %ld\n", s, __FILE__, __LINE__);

#define PatternLength  100
#define BufferLength  1024

#define ArgDir  0
#define ArgPat  1
#define ArgCmd  2
#define ArgExec 3
#define NumArgs 4

char   Version[]  = "$VER: ForAll 1.0 "__DATE__" "__TIME__;
char   Template[] = "DIR,PAT,CMD,EXEC/S";

char DefPattern[] = "#?";
char DefCommand[] = "";

struct DosLibrary  *DOSBase;
       char         Pattern[PatternLength], Command[255];
       ULONG        ArgArray[NumArgs];
       BOOL         Break = FALSE;

void ProcessOne(char *);


void __saveds main(void)
{
  struct RDArgs *rd;
  char          *Dir;
 
  if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
    {
      ArgArray[ArgDir] = (ULONG)"";
      ArgArray[ArgPat] = (ULONG)DefPattern;
      ArgArray[ArgCmd] = (ULONG)DefCommand;
      ArgArray[ArgExec] = FALSE;

      rd = ReadArgs(Template, ArgArray, NULL);
      Dir = (char *)ArgArray[ArgDir];
      if (ParsePatternNoCase((char *)ArgArray[ArgPat], Pattern, PatternLength) != -1)
	  {
	    ProcessOne(Dir);
	    if (Break) Printf("<Break>\n",NULL);
	  }
      else
	  Printf("Error in Pattern\n", NULL);
  
      if (rd) FreeArgs(rd);
      CloseLibrary(DOSBase);
    }
}

void ProcessOne(char *DirName)
{
  struct ExAllControl *eac;
  struct ExAllData    *ead;
  BPTR          lock, olddir;
  void         *Buffer;
  BOOL          more;

  Break |= SetSignal(0, 0) & SIGBREAKF_CTRL_C;
  if (lock = Lock(DirName, ACCESS_READ))
    {
      olddir = CurrentDir(lock);
      if (eac = AllocDosObject(DOS_EXALLCONTROL,NULL))
	{
	  eac->eac_LastKey = 0;
	  if (Buffer = AllocVec(BufferLength, NULL))
	    {
	      do
		{
		  more = ExAll(lock, Buffer, 1024, ED_TYPE, eac);
		  if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES)) break;
		  if (eac->eac_Entries == 0) continue;
		  ead = (struct ExAllData *)Buffer;
		  do 
		    {
		      Break |= SetSignal(0, 0) & SIGBREAKF_CTRL_C;
		      switch (ead->ed_Type)
			{
			case ST_USERDIR :
			  ProcessOne(ead->ed_Name);
			  break;
			case ST_FILE :
			  if (MatchPatternNoCase(Pattern, ead->ed_Name))
			    {
			      sprintf(Command, "%s %s", ArgArray[ArgCmd], ead->ed_Name);
			      if (ArgArray[ArgExec])
				SystemTags(Command,
					   SYS_UserShell, TRUE,
					   TAG_END);
			      else Printf("%s\n", Command);
			    }
			  break;
			default :
			  break;
			}
		      ead = ead->ed_Next;
		    } while (ead && !Break);
		} while (more && !Break);
	      FreeVec(Buffer);
	    }
	  else Fail("Can't get memory for ExAllBuffer!");
	  FreeDosObject(DOS_EXALLCONTROL, eac);
	}
      else Fail("Can't get ExAllControl!");
      CurrentDir(olddir);
      UnLock(lock);
    } else Fail("Can't get lock on dir!");
}

