/* GadMGet.c  by Jeremy Friesner -- jfriesne@ucsd.edu  
   Version 1.6, released 29 October 1994 */

#ifndef MGET_C
#define MGET_C

#define INTUI_V36_NAMES_ONLY
#define MAXFILELINELENGTH 300
#define CHAR_SPACE 32
#define INVALID 666

#define FIND_REQUESTTYPE 		 		 0
#define LINELENGTH_REQUESTTYPE 		 1
#define OUTPUTFILE_REQUESTTYPE 		 2

#define SIZEUNITPOS 35		/* position of the ?, K, M in the Aminet line */
	
#define SORTBYDIR  1
#define DIRNAMESIZE 10
#define DIRNAMEPOS 21      /* position of first char of directory on Aminet line */

#define SORTBYNAME 2
#define NAMESIZE 20
#define NAMEPOS 0

#define SORTBYDESC 3
#define DESCSIZE 42
#define DESCPOS 37

#define SORTBYSIZE 4
#define SIZEPOS 31
#define SIZESIZE 5

#include "GadMget.h"

extern UWORD lastcode;
extern ULONG appwinsig;
extern struct NewGadget mgetNGad[];
extern struct NewMenu mgetNewMenu[];
extern struct Window *findwindow;
extern struct AppMessage *amsg;
extern struct MsgPort *awport;
extern struct AppWindow *appwin;
extern struct TextAttr listfont;

FILE *fpOut = stdout;
int IntuitionBase; 
ULONG winopenerror, lockscrnerror;
ULONG handlereturn;
BOOL done=FALSE,BStartedFromWB=FALSE;
char windowtitle[95] = "Loading...";
char sListFontName[36] = "";
int nListFontSize = 0;  /* Default to a bad value */
char version[] = "$VER: GadMget V1.6";
char template[] = "Template:  GadMGet FILE/A,OUTPUT/K,LINELENGTH/K,TOP/K,LEFT/K,\
WIDTH/K,HEIGHT/K,PUBSCREEN/K,WBSCREEN/S,DEFPUBSCREEN/S,NOFILES/S,GETREADMES/S,\
NOPARSE/S,CASESENSITIVE/S,NOCOMMAND/S,NOSPLIT/S,NOAPPWINDOW/S,COMMAND/K,\
NOSIMPLEPATHS/S,NOCD/S,HEADER/K,FOOTER/K,FONT/K,FONTSIZE/K,KEEPBLANKLINES/S,\
KEEPGETSORT/S,KEEPFILESORT/S,FILESORT/K,GETSORT/K\n";
char pnamestring[20],searchstring[MAXFILELINELENGTH];
char szPubScreenName[40],*pubscreenname = NULL,defDir[200],defFile[40];
char szCommandString[40] = "mget";
char inputfile[300]="ram:RECENT";
char sOutFileName[300]="";
char szHeaderFile[300];
char szFooterFile[300];
int nTopListTop, nTopListHeight;
int nSortType[2] = {SORTBYDIR, SORTBYDIR};
int nKeepSorted[2] = {0,0};

/* default flags */
int screentype 			= USE_CUSTOMSCREEN,	
	 getreadmes				= 0, 
	 filesflag  			= 1, 							/* get .lha files */
	 index 					= 0, 							/* start find at top */
	 filelist_length 		= 0, 							/* no files loaded */
	 simplepaths 			= 1, 							/* don't use ncftp style mgets */
	 casesensitive			= 0,					
	 maxoutputlinelength = 254, 						/* shell's limit */
	 requesttype 	      = FIND_REQUESTTYPE,     /* subwindow is for string searches */
	 appwindow 				= 1,							/* = YES */
	 added_bytes 			= 0,							/* used for debugging-- tracks */
	 															/* the # of bytes allocated */
	 files_selected 		= 0, 							/* no files selected */
	 screenisopen 			= 0, 							/* = NO */
	 windowisopen 			= 0,							/* = NO */
	 noparse 				= 0, 							/* = yes, parse */
	 nocommand				= 0, 							/* = yes, generate command */
	 nosplit 				= 0,	 						/* = yes, split */
	 nocd						= 0,							/* = generate CD commands */
	 mgetNGad_height 		= 248,						/* default first listview height */
	 keepblanklines		= 0;                    /* = don't show blank lines */

ULONG kbytes_selected = 0;								
	 
UWORD windowwidth 	= 99999,							/* window will be sized to fill */
		windowheight 	= 99999,							/* screen unless these are */
		windowtop 		= 0, 								/* overridden by parameters */
		windowleft 		= 0;
		

void *findvi = NULL;

struct Library *Intuitionbase			= NULL;
struct GfxBase *GraphicsBase			= NULL;
struct Library *GadToolsBase			= NULL;
struct Library *UtilityBase			= NULL;
struct Library *AslBase					= NULL;
struct Library *IconBase				= NULL;
struct Library *WorkbenchBase			= NULL;
struct WBArg *argptr = NULL;

struct IntuiMessage *message 				= NULL;
struct List *filelist 						= NULL, 
				*getlist 						= NULL;
struct Node *search_current 				= NULL;
struct Gadget *findgadlist 				= NULL;
struct TextFont *listfontdata = NULL;

__chip UWORD waitPointer[] =
	{
	0x0000, 0x0000,
	0x0400, 0x07c0,
	0x0000, 0x07c0,
	0x0100, 0x0380,
	0x0000, 0x07e0,
	0x07c0, 0x1ff8,
	0x1ff0, 0x3fec,
	0x3ff8, 0x7fde,
	0x3ff8, 0x7fbe,
	0x7ffc, 0xff7f,
	0x7efc, 0xffff,
	0x7ffc, 0xffff,
	0x3ff8, 0x7ffe,
	0x3ff8, 0x7ffe,
	0x1ff0, 0x3ffc,
	0x07c0, 0x1ff8,
	0x0000, 0x07e0,
	0x0000, 0x0000};
	

void debug(int a)
{
fprintf(fpOut,"debug  %i\n",a);
Delay(80);
}






int listviewgadgetClicked (VOID)
{
int i;
struct Node *current = filelist->lh_Head;
struct Gadget *toplist = mgetGadgets[0];
struct Gadget *botlist = mgetGadgets[1];
char *dataline = NULL;
int minlinelength = 1,oktosend = 1;

 if (keepblanklines == 1) minlinelength = 0;
 
 for (i=0; i<lastcode; i++) current = current->ln_Succ;

 if (current != NULL)
	{
	/* check to make sure string is a valid file line */
	dataline = current->ln_Name;
	if (dataline == NULL) oktosend = 0;
	if (strlen(current->ln_Name) < minlinelength) oktosend = 0;
		
	if (!noparse)
		{
		if ((dataline[0] < '0')||(dataline[0] > 'z')) oktosend = 0;
		if ((dataline[35] != 'K')&&(dataline[35] != 'M')&&(dataline[35] != '?')) oktosend = 0;
		if (dataline[21] < '0') oktosend = 0;
		if ((filesflag == 0)&&(dataline[36] != '+')) oktosend = 0;
		}	
	if (oktosend)
		{
		UpdateByteCount(dataline,1);
		/* Take it out of filelist */
		GT_SetGadgetAttrs(toplist, mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
		Remove(current);
		GT_SetGadgetAttrs(toplist, mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
	
		if (search_current == current) search_current = current->ln_Succ;
		
		current->ln_Succ = NULL;		/* Clear now invalid field */
		
		/* And insert it in getlist */
		/* first detach list to modify it */
		GT_SetGadgetAttrs(botlist, mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
		if ((nKeepSorted[1] == 1)&&(!noparse))
		{
			SmartAdd(getlist,current,nSortType[1]);
		}
		else
		{
			AddTail(getlist,current);
		}
		GT_SetGadgetAttrs(botlist, mgetWnd, NULL, GTLV_Labels, getlist, TAG_END);
		
		
		files_selected++;
		filelist_length--;
		index--;				/* Is this the best thing, short of a search through the */
		if (index<0) index = 0;	/* Whole list for the index of current?  */
		
		ChangeWindowTitle();
		}
	}
	
}








int list2Clicked (VOID)
{
/* This function will move a clicked item from the lower list to the upper one */

int i;
struct Node *current = getlist->lh_Head;
struct Gadget *toplist = mgetGadgets[0];
struct Gadget *botlist = mgetGadgets[1];

 for (i=0; i<lastcode; i++)
	{
	current = current->ln_Succ;
	}

UpdateByteCount(current->ln_Name,-1);

/* Take it out of getlist */
GT_SetGadgetAttrs(botlist, mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
Remove(current);
GT_SetGadgetAttrs(botlist, mgetWnd, NULL, GTLV_Labels, getlist, TAG_END);

current->ln_Succ = NULL;		/* Clear now invalid field */

/* And insert it in filelist */
GT_SetGadgetAttrs(toplist, mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
 if ((nKeepSorted[0] == 1)&&(!noparse))
 {	
 	SmartAdd(filelist,current,nSortType[0]);
 }
else
{
	AddTail(filelist,current);
}

GT_SetGadgetAttrs(toplist, mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
/* and that's it! */
files_selected--;
filelist_length++;

ChangeWindowTitle();
}






int AreAminetNames(char *sString1, char *sString2)
{
/* checks to see if the appropriate chars K, M, or ? are in the file size
   position */
   
  /* Should I check the string size to make sure i'm not reading memory 
     after the end of the string?  I can, but it'll probably be really
     expensive!  So we'll try it without... */
  if (((sString1[SIZEUNITPOS] == 'K')||(sString1[SIZEUNITPOS] == 'M')||(sString1[SIZEUNITPOS] == '?'))
     &&((sString2[SIZEUNITPOS] == 'K')||(sString2[SIZEUNITPOS] == 'M')||(sString2[SIZEUNITPOS] == '?')))
			return(1);
 return(0);
}







int AminetFileSize(char *sString)
{
/* Returns file size, in kilobytes, of the given Aminet line */
int multiplier = INVALID;
int filesize = 0, wholenum;
int outputlength = -1;
int tenthofmultiplier = 0;

if (sString == NULL) {return(0);}
if (sString[SIZEUNITPOS] == 'M') 
	{
	multiplier = 1024;   /* 1024 k in a M */
	tenthofmultiplier = 102;
	}
if (sString[SIZEUNITPOS] == 'K') multiplier = 1;	 /* 1 k in a k */
if (sString[SIZEUNITPOS] == '?') multiplier = 0;

if (multiplier == INVALID) {return(0);}    /* If we don't know M or K, abort */

 if (sString[SIZEUNITPOS-2] == '.')		/* for when it's like:  3.5M */
	{
	/* figure out kilobytes */
	wholenum = (int) (sString[SIZEUNITPOS-3] - '0');
	
	if ((wholenum >= 0)&&(wholenum <= 9))
		{
		filesize = filesize + (multiplier * wholenum);
		}
	wholenum = (int) (sString[SIZEUNITPOS-1] - '0');
	if ((wholenum >= 0)&&(wholenum <= 9))
		{
		filesize = filesize + (tenthofmultiplier * wholenum);
		}
	}
	else
	{
	wholenum = (int) (sString[SIZEUNITPOS-3] - '0');
	if ((wholenum >= 0)&&(wholenum <= 9))
		{
		filesize = filesize + (100 * multiplier * wholenum);
		}		
	wholenum = (int) (sString[SIZEUNITPOS-2] - '0');
		if ((wholenum >= 0)&&(wholenum <= 9))
		{
		filesize = filesize + ( 10 * multiplier * wholenum);
		}
	wholenum = (int) (sString[SIZEUNITPOS-1] - '0');
	if ((wholenum >= 0)&&(wholenum <= 9))
		{
		filesize = filesize + (      multiplier * wholenum);
		}
	}
return(filesize);
}
 

 
void SmartAdd(struct List *thislist, struct Node *addme, int nThisSortType)
{
/* a simple add into the correct order of the list */
struct Node *current, *past;
char sBuffer1[43], sBuffer2[43];

current = thislist->lh_Head;
past = NULL;

if ((addme == NULL)||(addme->ln_Name == NULL)) 
{
	printf("Tell Jeremy--bug #5!\n");
	return();
}

while (current != NULL)			
		{
			/* Only sort if this is an Aminet file line, or not an Aminet Sort */	
			if ((current->ln_Name != NULL)&&(AreAminetNames(current->ln_Name, addme->ln_Name)))
			{
				switch(nThisSortType)
				{
					case SORTBYDIR:
						strncpy(sBuffer1,addme->ln_Name+DIRNAMEPOS,DIRNAMESIZE);
						strncpy(sBuffer2,current->ln_Name+DIRNAMEPOS,DIRNAMESIZE);
						if ((strchr(sBuffer1,'/') != NULL)&&
				    		 (strchr(sBuffer2,'/') != NULL)&&
					 		 (strncmp(sBuffer1,sBuffer2,DIRNAMESIZE) < 0))
						{
							Insert(thislist, addme, past);	/* and put it back in after current */
							return();
						}
					break;
				
					case SORTBYDESC:
						if (strncmp(addme->ln_Name+DESCPOS,current->ln_Name+DESCPOS,DESCSIZE) < 0)
						{
							Insert(thislist, addme, past);	/* and put it back in after current */
							return();
						}
					break;
					
					case SORTBYNAME:
						memset(sBuffer1,NUL,NAMESIZE);  /* sort sometimes goes into infinite loops if you don't have this??? */
						memset(sBuffer2,NUL,NAMESIZE);  /* It shouldn't, though, because strncpy terminates everything right? */
						strncpy(sBuffer1,addme->ln_Name+NAMEPOS,NAMESIZE);
						strncpy(sBuffer2,current->ln_Name+NAMEPOS,NAMESIZE);	
						if (strncmp(sBuffer1,sBuffer2,NAMESIZE) < 0)
						{
							Insert(thislist, addme, past);	/* and put it back in after current */		
							return();
						}
					break;
					
					case SORTBYSIZE:
						if (AminetFileSize(addme->ln_Name) < AminetFileSize(current->ln_Name))
						{
							Insert(thislist, addme, past);	/* and put it back in after current */
							return();
						}
					break;
				}
			}	
			past = current;				/* step to next in list */
			current = current->ln_Succ;
		}
		
	AddTail(thislist,addme);		/* If we've got to the end without returning, add it to the end */
	return();
}







void SortList(struct List *thislist, int nThisSortType)
{
	/* a simple swap-sort */
	int nSwappedThisPass = 1, nUpdateTitle = 0, nUpdateCount = 0;
	struct Node *current, *past;
	char sBuffer1[43], sBuffer2[43],sSortWinString[20]; 
	char sSortTypeString[25] = "Sorting by \0";
	
	/* Generate Window title prompt */
	switch(nThisSortType)
	{
		case SORTBYDIR:
			strcat(sSortTypeString,"Directory");
		break;
		
		case SORTBYSIZE:
			strcat(sSortTypeString,"Size");
		break;
		
		case SORTBYDESC:
			strcat(sSortTypeString,"Description");
		break;

		case SORTBYNAME:
			strcat(sSortTypeString,"FileName");
		break;
	}
	
	if (thislist == NULL)
	{
		return;
	}
	
	/* Remove list from ListView if necessary  */
 	if (windowisopen)
 	{
 	 	if (thislist == filelist) GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
 		if (thislist ==  getlist) GT_SetGadgetAttrs(mgetGadgets[1], mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
		SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);
	}

	while (nSwappedThisPass > 0)
	{
		/* start a pass */
		past = thislist->lh_Head;
		if (past == NULL)
		{
			/* empty list ! */
			if (windowisopen)
			{
				/* Replace list into ListView */
				if (thislist == filelist) GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
				if (thislist ==  getlist) GT_SetGadgetAttrs(mgetGadgets[1], mgetWnd, NULL, GTLV_Labels,  getlist, TAG_END);
				ChangeWindowTitle();
				ClearPointer(mgetWnd);
			}
			return;
		}
		current = past->ln_Succ;
		nSwappedThisPass = 0;		/* start with none recorded */

		while (current != NULL)			
		{
			/* Only sort if this is an Aminet file line, or not an Aminet Sort */	
			if ((current->ln_Name != NULL)&&(past->ln_Name != NULL)&&
			    (AreAminetNames(current->ln_Name, past->ln_Name)))
			{
				switch(nThisSortType)
				{
					case SORTBYDIR:
						strncpy(sBuffer1,past->ln_Name+DIRNAMEPOS,DIRNAMESIZE);
						strncpy(sBuffer2,current->ln_Name+DIRNAMEPOS,DIRNAMESIZE);
						if ((strchr(sBuffer1,'/') != NULL)&&
				    		 (strchr(sBuffer2,'/') != NULL)&&
					 		 (strncmp(sBuffer1,sBuffer2,DIRNAMESIZE) > 0))
						{
							/* Swap the two nodes */
							Remove(past);							/* take previous out of list */
							Insert(thislist, past, current);	/* and put it back in after current */
							nSwappedThisPass++;
						}
					break;
				
					case SORTBYDESC:
						if (strncmp(past->ln_Name+DESCPOS,current->ln_Name+DESCPOS,DESCSIZE) > 0)
						{
							/* Swap the two nodes */
							Remove(past);							/* take previous out of list */
							Insert(thislist, past, current);	/* and put it back in after current */
							nSwappedThisPass++;
						}
					break;
					
					case SORTBYNAME:
						strncpy(sBuffer1,past->ln_Name+NAMEPOS,NAMESIZE);
						strncpy(sBuffer2,current->ln_Name+NAMEPOS,NAMESIZE);	
						if (strncmp(sBuffer1,sBuffer2,NAMESIZE) > 0)
						{
							/* Swap the two nodes */
							Remove(past);							/* take previous out of list */
							Insert(thislist, past, current);	/* and put it back in after current */
							nSwappedThisPass++;
						}
					break;
					
					case SORTBYSIZE:
						if (AminetFileSize(past->ln_Name) > AminetFileSize(current->ln_Name))
						{
						/* Swap the two nodes */
							Remove(past);							/* take previous out of list */
							Insert(thislist, past, current);	/* and put it back in after current */
							nSwappedThisPass++;
						}
					break;
				}
			}	
			past = current;
			current = current->ln_Succ;
		}
		
		if (windowisopen)
		{
			sprintf(sSortWinString,"%s, please be patient:  %i",sSortTypeString,nUpdateCount);
			SetWindowTitles(mgetWnd, sSortWinString, (char *) ~0);
			nUpdateCount++; 
 		}  			
	}
		
	if (windowisopen)
	{
		/* Replace list into ListView */
		if (thislist == filelist) GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
		if (thislist ==  getlist) GT_SetGadgetAttrs(mgetGadgets[1], mgetWnd, NULL, GTLV_Labels,  getlist, TAG_END);
		ClearPointer(mgetWnd);
	}
	ChangeWindowTitle();
	return;
}
		
		


int OutputList(struct List *thislist)
{
#define LASTDIRBUFSIZE 30

 char *j, *j2, *p;
 int k,l,z,next_bytes,putnameOK = 0,putcommandOK = 1; 
 int printed_bytes = maxoutputlinelength - 1, printreturnfirst = 0;
 char outname[MAXFILELINELENGTH],szLastDir[LASTDIRBUFSIZE];
 struct Node *current;

 memset(szLastDir,NUL,LASTDIRBUFSIZE);
 
 /* Get any readme files first, so user can browse them while d/l'ing the rest */
 if (getreadmes)
	{
	current = thislist->lh_Head;
 	while (current != NULL)
 	     {
		/* watch out for empty nodes! */
		if (current->ln_Name != NULL) 
			{
			z = strlen(current->ln_Name);
			/* Extra filtering code, borrowed from mgetlistviewclicked()... */
			if ((current->ln_Name[0] < '0')||(current->ln_Name [0] > 'z')) z = 0;
			if ((current->ln_Name[35] != 'K')&&(current->ln_Name[35] != 'M')&&(current->ln_Name[35] != '?')) z = 0;
			if (current->ln_Name[21] < '0') z = 0;
			if ((filesflag == 0)&&(current->ln_Name[36] != '+')) z = 0;
			/* end code from mgetlistviewclicked() ... */
			}
			else z=0;
		
		
		
		if (z>21)
			{
			j = strchr(current->ln_Name,32);   	/* address of first space after filename */
			k = j - current->ln_Name;           	/* length of filename */
			j2 = strchr(current->ln_Name+21,32);	/* address of directory of file */
			l = j2 - (current->ln_Name) - 21;		/* length of directory */
	
			if ((k<22)&&(k>0)&&(l<12)&&(l>2))
				{
				memset(outname,NUL,MAXFILELINELENGTH);
				strncat(outname,current->ln_Name+21,l);
				
				/* Here we have the directory name--see if it's different, generate cd */
				if ((current->ln_Name[36] == '+')&&
				    (nocd == 0)&&
				    (simplepaths == 1)&&
				    (strncmp(szLastDir,outname,LASTDIRBUFSIZE) != 0)) 
				{
					memset(szLastDir,NUL,LASTDIRBUFSIZE);
					GenerateCDCommand(&printreturnfirst, &printed_bytes, szLastDir, outname);
					putnameOK = 1;
					putcommandOK = 0;
				}
				
				if (simplepaths == 1)
				{	
					/* remove path so it won't be printed again in the mget command */
					memset(outname,NUL,sizeof(outname));
				}
				else
				{
					strncat(outname,"/",1);
				}
				
				strncat(outname,current->ln_Name,k);
				outname[79]=0;	/* just in case, we'll reterminate the string */			
			
				if (current->ln_Name[36] == '+')
					{	
					/* find the last '.' in outname, and change whatever's after it to 'readme'! */
					p = strrchr(outname,'.');
					
					/* and if there is no "." ? */
					if (p == NULL)
					{
						strcat(outname,".");
						p = strrchr(outname,'.');
					}
					
					strcpy(p+1,"readme");
					
					next_bytes = strlen(outname) + 1;	/* + 1 for the space */
					if ((next_bytes>3)&&(next_bytes<39))
						{
						if ((putcommandOK == 1)&&(!nosplit)&&((printed_bytes + next_bytes) > maxoutputlinelength))
							{
							PrintCommandString(&printreturnfirst, &printed_bytes);			
							putnameOK = 1;
							}			
						fprintf(fpOut,"%s ",outname);
						printed_bytes = printed_bytes + next_bytes;
						putcommandOK = 1;
						}
					}
				}
			}
		current = current->ln_Succ;	
		}
	}		

 if (filesflag)
 {	
 current = thislist->lh_Head;	
	while (current != NULL)
	{
		/* watch out for empty nodes! */
		if (current->ln_Name != NULL)
			{
			z = strlen(current->ln_Name);
			/* Extra filtering code, borrowed from mgetlistviewclicked()... */
			if ((current->ln_Name[0] < '0')||(current->ln_Name [0] > 'z')) z = 0;
			if ((current->ln_Name[35] != 'K')&&(current->ln_Name[35] != 'M')&&(current->ln_Name[35] != '?')) z = 0;
			if (current->ln_Name[21] < '0') z = 0;
			if ((filesflag == 0)&&(current->ln_Name[36] != '+')) z = 0;
			/* end code from mgetlistviewclicked() ... */
			}
			else
			{
			z=0;
			}
		
		if (z>21)
			{
			j = strchr(current->ln_Name,32);   /* address of first space after filename */
			k = j - current->ln_Name;           /* length of filename */
			j2 = strchr(current->ln_Name+21,32);   /* address of directory of file */
			l = j2 - (current->ln_Name) - 21;		/* length of directory */
	
			if ((k<22)&&(k>0)&&(l<12)&&(l>2))
				{
				memset(outname,NUL,MAXFILELINELENGTH);
				strncat(outname,current->ln_Name+21,l);

				/* Here we have the directory name--see if it's different, generate cd */
				if ((nocd == 0)&&
					 (simplepaths == 1)&&
					 (strncmp(szLastDir,outname,LASTDIRBUFSIZE) != 0)) 
				{
					memset(szLastDir,NUL,LASTDIRBUFSIZE);
					GenerateCDCommand(&printreturnfirst, &printed_bytes, szLastDir, outname);
					putcommandOK = 0;
					putnameOK = 1;
				}
				
				if (simplepaths == 1)
				{	
					/* remove path so it won't be printed again in the mget command */
					memset(outname,NUL,sizeof(outname));
				}
				else
				{
					strncat(outname,"/",1);
				}
				
				
				strncat(outname,current->ln_Name,k);
				outname[79]=0;	/* just in case, we'll reterminate the string */			
				if (filesflag)
					{	
					next_bytes = strlen(outname) + 1;	/* + 1 for the space */
					if ((next_bytes>3)&&(next_bytes<33))
						{
						if ((putcommandOK == 1)&&(!nosplit)&&((printed_bytes + next_bytes) > maxoutputlinelength))
							{
							PrintCommandString(&printreturnfirst, &printed_bytes);	
							putnameOK = 1;
							}			
						fprintf(fpOut,"%s ",outname);
						putcommandOK = 1;
						printed_bytes = printed_bytes + next_bytes;
						}
					}
				}
			}	
		current = current->ln_Succ;	
		}
	}
return(1);
}




void PrintCommandString(int *printreturnfirst, int *printed_bytes)
{
	if (*printreturnfirst) fprintf(fpOut,"\r\n"); 
	*printreturnfirst = 1;
		
	if (nocommand) 
	{
		*printed_bytes = 0;
	}
	else
	{
		fprintf(fpOut,"%s ",szCommandString);
		*printreturnfirst = 1;
		*printed_bytes = strlen(szCommandString) + 1;	/* reset counter for next batch */
	}
	return;
}




void GenerateCDCommand(int *printreturnfirst, int *printed_bytes, char *szLastDir, char *outname)
{
	if (*printreturnfirst) fprintf(fpOut,"\r\n");
	fprintf(fpOut,"cd ");
				
	/* On the first item, we will be starting at the aminet root
	   directory, so we won't need to print the ../.. .  After that,
		though, we will.  printreturnfirst serves nicely to tell
		whether or not we're in the first iteration. */   
	
	if (*printreturnfirst == 1) fprintf(fpOut,"../../");
			
	fprintf(fpOut,"%s",outname);
	*printreturnfirst = 1;
	PrintCommandString(printreturnfirst, printed_bytes);

	/* update buffer */	
	strncpy(szLastDir,outname,30);	

	return;
}			



int RawOutputList(struct List *thislist)
{
struct Node *current = thislist->lh_Head;
int minlinelength = 1;

 if (keepblanklines == 1) minlinelength = 0;
  	
 while (current != NULL)
	{	
	if ((current->ln_Name != NULL)&&(current->ln_Name[0] < 128)&&(strlen(current->ln_Name) >= minlinelength))
		{
			if (current->ln_Name[0] < 14) 
			{
				fprintf(fpOut,"\n",current->ln_Name);
			}
			else
			{
				fprintf(fpOut,"%.300s\n",current->ln_Name);
			}
		}
	current = current->ln_Succ;
	}
return(1);
}









int MakeReq(char *sText, char *sTitle, char *sGadgets)
{
struct EasyStruct myreq;
LONG number = 0L;
int nResult;
char sDefaultTitle[] = "GadMGet Error";

if (sTitle == NULL) sTitle = sDefaultTitle;
if (sText == NULL) sText = sDefaultTitle;
if (sGadgets == NULL) sGadgets = "OK";

myreq.es_TextFormat   = sText;
myreq.es_Title        = sTitle;
myreq.es_GadgetFormat = sGadgets;

if (mgetWnd != NULL) SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);
nResult = EasyRequest(mgetWnd, &myreq, NULL, NULL, number);
if (mgetWnd != NULL) ClearPointer(mgetWnd);

return(nResult);
}












int mgetabout (VOID)
{
char sAboutText[100];

strcpy(sAboutText,pnamestring);
strcat(sAboutText,"\n%s\n\nby Jeremy Friesner\njfriesne@ucsd.edu\n");
MakeReq(sAboutText,"About GadMGet","Hey, Cool!");
return(1);
}








int mgetquit (VOID)
{
done=TRUE;
}






int mgetcase (VOID)
{
if (casesensitive == 0) casesensitive = 1; else casesensitive = 0;
SetMenuValues();
}




int mgetCD (VOID)
{
if (simplepaths == 0) simplepaths = 1; else simplepaths = 0;
SetMenuValues();
}




int mgetfind (VOID)
{
ULONG winsig, signals;
int done = 0, found = 0;
int fwindowwidth = 450, fwindowheight = 35 + Scr->RastPort.TxHeight;
int fwindowleft = (mgetLeft + (windowwidth/2) - (fwindowwidth/2));
int fwindowtop  = (mgetTop  + (windowheight/2)- (fwindowheight/2));
struct NewGadget stringGad;
struct IntuiMessage *imsg;
struct Gadget *newgad = NULL;
char numstring[100], *ss = searchstring, sTempOutString[300];
char *wp = NULL,windowtitlestring0[] = "Search Window", 
                windowtitlestring1[] = "Line Length Window",
                windowtitlestring2[] = "Output File Change Window";
FILE *fpTemp = NULL;
	
index = 0;		/* start searching at top again! */

findvi  = GetVisualInfo(Scr, TAG_END);
if (findvi == NULL) return(0);
if (findwindow != NULL) return(0);


if (fwindowleft < 0) fwindowleft = mgetLeft;
if (fwindowheight < 0) fwindowtop = mgetTop;

 newgad = CreateContext(&findgadlist);
 if (newgad == 0)
	{
	MakeReq("Couldn't create findwindow gad context!\n",NULL,"Dammit!");
	return(0);
	}

 if (newgad == NULL) return(0);

stringGad.ng_TextAttr	 = &topaz8;	/* Cant figure out how to get system default into a TextAttr!  No name string available! */
stringGad.ng_VisualInfo  = findvi;
stringGad.ng_LeftEdge	 = 5;
stringGad.ng_TopEdge   	 = 18 + Scr->RastPort.TxHeight;
stringGad.ng_Width		 = (fwindowwidth-10);
stringGad.ng_Height		 = 13;
stringGad.ng_GadgetText  = "Please enter search string.";
stringGad.ng_GadgetID	 = 35;	
stringGad.ng_Flags		 = PLACETEXT_ABOVE;

 if (requesttype == FIND_REQUESTTYPE) 
  {
    wp = windowtitlestring0;
  }

 if (requesttype == LINELENGTH_REQUESTTYPE)
  {
 	wp = windowtitlestring1;
 	stringGad.ng_GadgetText = "Please enter new maximum line length.";
 	sprintf(numstring,"%i\0",maxoutputlinelength);	
 	ss = numstring;
  }
 if (requesttype == OUTPUTFILE_REQUESTTYPE)
  {
 	wp = windowtitlestring2;
 	stringGad.ng_GadgetText = "Please enter new output file path/device.";
 	sprintf(numstring,"%s",sOutFileName);
 	strncpy(sTempOutString,sOutFileName,sizeof(sTempOutString));
 	ss = sTempOutString;
  }
 

 newgad = CreateGadget(STRING_KIND, newgad, &stringGad, 
				  GTST_String, ss, 
				  STRINGA_Justification, GACT_STRINGCENTER, 
				  GA_Immediate, TRUE,
				  TAG_END);  

 if (newgad == NULL) 
	{
	FreeGadgets(findgadlist);
	FreeVisualInfo(findvi);
	return(0);
	}

 if (GadToolsBase->lib_Version == 37)
	{
	/* Only do it the "illegal" way under v37.  GA_Immediate in the CreateGadget
	   line, above, won't work under v37 but will on later releases. */
	newgad->Activation |= GACT_IMMEDIATE; 
	}	

 switch (screentype)
	{
	case USE_PUBSCREEN:
		findwindow = OpenWindowTags(NULL,
				WA_Left,		fwindowleft,
				WA_Top,		fwindowtop,
				WA_Width,	     fwindowwidth,
				WA_Height,	fwindowheight,
				WA_PubScreen,	Scr,
				WA_PubScreenFallBack, TRUE,
				WA_IDCMP,		STRINGIDCMP|IDCMP_CLOSEWINDOW|
							IDCMP_REFRESHWINDOW|IDCMP_ACTIVEWINDOW,
				WA_Flags,		WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE,
				WA_Gadgets,	findgadlist,
				WA_Title,	     wp,
				WA_ScreenTitle,	pnamestring,
				TAG_DONE );
		break;
	case USE_CUSTOMSCREEN:
		findwindow = OpenWindowTags(NULL,
				WA_Left,		fwindowleft,
				WA_Top,		fwindowtop,
				WA_Width,	     fwindowwidth,
				WA_Height,	fwindowheight,
				WA_CustomScreen, Scr,
				WA_IDCMP,		STRINGIDCMP|IDCMP_CLOSEWINDOW|
							IDCMP_REFRESHWINDOW|IDCMP_ACTIVEWINDOW,
				WA_Flags,		WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE,
				WA_Gadgets,	findgadlist,
				WA_Title,	     wp,
				WA_ScreenTitle,	pnamestring,
				WA_CustomScreen,	Scr,
				TAG_DONE );
		break;
	case USE_WBSCREEN:
		findwindow = OpenWindowTags(NULL,
				WA_Left,		fwindowleft,
				WA_Top,		fwindowtop,
				WA_Width,	     fwindowwidth,
				WA_Height,	fwindowheight,
				WA_IDCMP,		STRINGIDCMP|IDCMP_CLOSEWINDOW|
							IDCMP_REFRESHWINDOW|IDCMP_ACTIVEWINDOW,
				WA_Flags,		WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE,
				WA_Gadgets,	findgadlist,
				WA_Title,	     wp,
				WA_ScreenTitle,	pnamestring,
				TAG_DONE );
		break;
	}

if (findwindow == NULL) return(0);
GT_RefreshWindow(findwindow, NULL); 

SetWindowTitles(mgetWnd, "MGet window inactive--close daughter window to continue", (char *) ~0); 
SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);

winsig = 1 << findwindow->UserPort->mp_SigBit;

 while (!done)
	{
	signals = Wait(winsig);
	if (signals&winsig)
		{
		while ((!done) && (imsg = GT_GetIMsg(findwindow->UserPort)))
			{
			
			switch(imsg->Class)
				{			
				case IDCMP_ACTIVEWINDOW:
					ActivateGadget(newgad,findwindow,NULL);
					break;
						
				case IDCMP_GADGETUP:
					strncpy(ss,((struct StringInfo*)newgad->SpecialInfo)->Buffer,sizeof(searchstring));
					done = 1;
					break;
		
				case IDCMP_CLOSEWINDOW:
					done = 2;
					break;
					
				case IDCMP_REFRESHWINDOW:
					GT_BeginRefresh(findwindow);
					GT_EndRefresh(findwindow, TRUE);
					break;
				}
			GT_ReplyIMsg(imsg);
			}
		}
	}
	
CloseWindow(findwindow);
FreeGadgets(findgadlist);
FreeVisualInfo(findvi); 
findwindow = NULL;

ClearPointer(mgetWnd);

 if (requesttype == LINELENGTH_REQUESTTYPE) 
	{
	ChangeWindowTitle();	
	return(atoi(ss));
	}
 if (requesttype == OUTPUTFILE_REQUESTTYPE)
	{
		if (strlen(sTempOutString) == 0)
		{
			if (BStartedFromWB == FALSE)
			{
				fpOut = stdout;
				*sOutFileName = '\0';	/* blank out filename string */
			}
			else
			{
				strncpy(sTempOutString,"ram:GadMget.output",sizeof(sOutFileName));
			}
		}
		else
		{
			fpTemp = fopen(sTempOutString,"w");
			if (fpTemp == NULL)
			{
				MakeReq("Couldn't open output file!\n",NULL,"Ok");
			}
			else
			{
				fpOut = fpTemp;
				strncpy(sOutFileName,sTempOutString,sizeof(sOutFileName));
				fclose(fpTemp);
			}
		}
	ChangeWindowTitle();
	return(0);
	}
	
 if ((done == 2)||(strlen(searchstring) == 0))
	{
	ChangeWindowTitle();
	return(0);	/* can use searchstring now instead of ss */
	}			/* because we're no longer worried about the nums */

/* Now find it in the filelist */
search_current = (char *) filelist->lh_Head;
if (SearchList(searchstring) == -1) DisplayBeep(Scr); else findgadgoto(index,3);
return(1);
}











int mgetfindnext (VOID)
{
/* bump to next node */
if (search_current == NULL) {DisplayBeep(Scr); return(0);}
search_current = search_current->ln_Succ;
if (search_current == NULL) {DisplayBeep(Scr); return(0);}
index++;
if (SearchList(searchstring) == -1) DisplayBeep(Scr); else findgadgoto(index,2);
return(1);
}




int mgetfilesbydir (void)
{
nSortType[0] = SORTBYDIR;

SortList(filelist,nSortType[0]);
}


int mgetfilesbysize (void)
{
nSortType[0] = SORTBYSIZE;

SortList(filelist,nSortType[0]);
}


int mgetfilesbyname (void)
{
nSortType[0] = SORTBYNAME;

SortList(filelist,nSortType[0]);
}


int mgetfilesbydesc (void)
{
nSortType[0] = SORTBYDESC;

SortList(filelist,nSortType[0]);
}

int mgetfileskeep (void)
{
if (nKeepSorted[0] == 1) 
	{
		nKeepSorted[0] = 0;
	}
	else
	{
		nKeepSorted[0] = 1;
		SortList(filelist,nSortType[0]);
	}
}


int mgetgetbydir (void)
{
nSortType[1] = SORTBYDIR;

SortList(getlist,nSortType[1]);
}


int mgetgetbysize (void)
{
nSortType[1] = SORTBYSIZE;

SortList(getlist,nSortType[1]);
}


int mgetgetbyname (void)
{
nSortType[1] = SORTBYNAME;

SortList(getlist,nSortType[1]);
}


int mgetgetbydesc (void)
{
nSortType[1] = SORTBYDESC;

SortList(getlist,nSortType[1]);
}


int mgetgetkeep (void)
{
if (nKeepSorted[1] == 1) 
	{
		nKeepSorted[1] = 0;
	}
	else
	{
		nKeepSorted[1] = 1;
		SortList(getlist,nSortType[1]);
	}
}



int SearchList(char *key)
{
int found = 0;
char sUpperBuffer[MAXFILELINELENGTH], sUppersearchstring[MAXFILELINELENGTH];

SetWindowTitles(mgetWnd, "Searching...", (char *) ~0); 
SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);

if (casesensitive)	
	{
	while ((search_current != NULL)&&(found == 0))
		{
		if ((search_current->ln_Name != NULL)&&(strstr(search_current->ln_Name,searchstring) != 0))
				found = 1;
				else
				{
				search_current = search_current->ln_Succ; 
				index++;
				}
		}
	}
	else
	{
	strncpy(sUppersearchstring,key,sizeof(sUppersearchstring));
	UpperCase(sUppersearchstring);
	while ((search_current != NULL)&&(found == 0))
		{
		if (search_current->ln_Name != NULL)
			{
			strncpy(sUpperBuffer,search_current->ln_Name,sizeof(sUpperBuffer)-1);
			UpperCase(sUpperBuffer);
			if (strstr(sUpperBuffer,sUppersearchstring) != 0)
				found = 1;
			}
		if (found == 0)
			{
			search_current = search_current->ln_Succ; 
			index++;
			}
		}
	}
	
ChangeWindowTitle();
ClearPointer(mgetWnd);

if (found == 1) return(index); else return(-1);
}











void findgadgoto (int index, int numberofflashes)
{
int i, xmin, ymin, xmax, ymax, ystep, midscreen;
int WindowHeightLines = nTopListHeight/(listfont.ta_YSize);

 midscreen = index-(WindowHeightLines/2);
 if (midscreen < 0) midscreen = 0;

 if (filelist_length > WindowHeightLines)
 		GT_SetGadgetAttrs((struct Gadget *) mgetGadgets[0], mgetWnd, NULL, GTLV_Top, midscreen, TAG_END);

 ystep = WindowHeightLines/2;			/* default, for middle of list */	 							
 if ((filelist_length-index) < (WindowHeightLines/2))
 		ystep = index - (filelist_length - WindowHeightLines);
 if ((index < (WindowHeightLines/2))||
 	  (filelist_length <= WindowHeightLines)) ystep = index;	/* if at top */ 
 
 xmin = Scr->WBorLeft + 4;
 ymin = (nTopListTop + ((listfont.ta_YSize) *ystep) + 2);
 xmax = windowwidth - Scr->WBorLeft - 20;
 ymax = ymin + (listfont.ta_YSize) - 1;

 SetDrMd(mgetWnd->RPort, 50); 
 for (i=0;i<numberofflashes;i++)
 	{
 	RectFill(mgetWnd->RPort,xmin,ymin,xmax,ymax);
 	Delay(5);
 	RectFill(mgetWnd->RPort,xmin,ymin,xmax,ymax);
 	if (i<(numberofflashes-1)) Delay(5);
 	}
}











int mgetnoparse (void)
{
if (noparse) 
	{
	noparse = 0; 
	if (nKeepSorted[0] == 1) SortList(filelist,nSortType[0]);
	if (nKeepSorted[1] == 1) SortList(getlist, nSortType[0]);
	SetMenuValues();
	}
	else 
	{
	noparse = 1;		
	SetMenuValues();
	}
}








int mgetfiles (void)
{
if (filesflag) 
	{
	filesflag = 0;
	getreadmes = 1;
	SetMenuValues();	 
	}
	else 
	filesflag = 1;
}







int mgetreadmes (void)
{
if (getreadmes) 
	{getreadmes = 0; 
	 filesflag = 1;
	 SetMenuValues();
	}
	else 
	getreadmes = 1;
}






int mgetsplit (void)
{
if (nosplit) nosplit = 0; else nosplit = 1;
SetMenuValues();	
}






int mgetlinelength (void)
{
int lin;

requesttype = LINELENGTH_REQUESTTYPE;	/* This is a HORRIBLE way to program, but I don't want  */
lin = mgetfind();								/* to try to change the parameters since it might screw */
requesttype = FIND_REQUESTTYPE;			/* up the mget_listview2 functions...				 */

if (lin >  0) maxoutputlinelength = lin;
}




int mgetoutputfile (void)
{
int lin;

requesttype = OUTPUTFILE_REQUESTTYPE;	/* This is a HORRIBLE way to program, but I don't want  */
lin = mgetfind();								/* to try to change the parameters since it might screw */
requesttype = FIND_REQUESTTYPE;			/* up the mget_listview2 functions...				        */

}






void PrintList(struct List *thislist)
{
struct Node *nodecurrent = thislist->lh_Head;

fprintf(fpOut,"thislist = %p\n",thislist);

 while (nodecurrent != NULL)
	{
	if (nodecurrent->ln_Name == NULL) 
		{
		fprintf(fpOut,"[ <NULL> ]\n"); 
		}
		else
		{
		fprintf(fpOut,"[%s]\n",nodecurrent->ln_Name);
		}
	nodecurrent = nodecurrent->ln_Succ;
	}
	
return();
}








int mgetopenfile (void)
{
FILE *test = NULL;

 memset(inputfile,NUL,sizeof(inputfile));

 SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);

 while (test == NULL) 
	{
	if (RequestAFile(inputfile) == 0) 
		{
		ClearPointer(mgetWnd);
		return(0);
		}
	test = fopen(inputfile,"r");
	}

 fclose(test);
 SetReqDefaults(inputfile);
 
 GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
 FreeFileNodes(filelist); 
 FreeMem(filelist,sizeof(struct List));
 added_bytes -= sizeof(struct List);
 ClearPointer(mgetWnd);
 
 if (!(filelist = AllocMem(sizeof(struct List),MEMF_CLEAR)) )
	{
	MakeReq("mgetOpen : Couldn't create filelist!  Out of memory?\n",NULL,"Uh-oh");
	return(0);
	}
 added_bytes += sizeof(struct List);
		
 /* These are all dependant on a given filelist, so RESET! */
 filelist_length = 0;
 search_current = NULL;
 index = 0;

 NewList(filelist);	  
 ReadmyFile();
 if ((nKeepSorted[0] == 1)&&(!noparse)) SortList(filelist,nSortType[0]);  /* keep sorted if that is selected! */
 GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
return(1);
}








int mgetappend(void)
{
int returnme = 0;

memset(inputfile,NUL,sizeof(inputfile));

GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
returnme = ReadmyFile();
if ((nKeepSorted[0] == 1)&&(!noparse)) SortList(filelist,nSortType[0]);  /* keep sorted if that is selected! */
GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
return(returnme);
}






int mgetCloseWindow (void)
{
done=TRUE;
}









void SetMenuValues (void)
{
struct Menu *currentMenu = mgetMenus;
struct MenuItem *currentItem, *currentSub;

 if (currentMenu == NULL)
	{
	MakeReq("SetMenuValues:  error, mgetMenus is NULL!",NULL,"Huh?");
	return;
	}
	
 if (mgetWnd != NULL) ClearMenuStrip(mgetWnd);

 /* Make sure the CaseSensitive item in the second menu is checked correctly. */	
 currentMenu = currentMenu->NextMenu;
 currentItem = currentMenu->FirstItem;		/* #1 : Find */
 
 currentItem = currentItem->NextItem;		/* #2 : Next */
 
 currentItem = currentItem->NextItem;		/* #3 : Case Sensitive. */
 
 if (casesensitive)  currentItem->Flags |= CHECKED; 
		    else  mgetNewMenu[9].nm_Flags &= ~(CHECKED);	

 /* next we do the Sort menu. */
 currentMenu = currentMenu->NextMenu;
 if (noparse) currentMenu->Flags &= ~(MENUENABLED);
	   else currentMenu->Flags |= MENUENABLED;

 currentItem = currentMenu->FirstItem;	/* #1: Files List */
 currentSub = currentItem->SubItem;    /* #1.1 : By Directory */
 
 currentSub = currentSub->NextItem;    /* #1.2 : By Size */
 
 currentSub = currentSub->NextItem;    /* #1.3 : By FileName */
 currentSub = currentSub->NextItem;    /* #1.4 : By Description */
 currentSub = currentSub->NextItem;		/* #1.5 : Keep Sorted */
 if (nKeepSorted[0] == 0) currentSub->Flags &= ~(CHECKED);
	   					else currentSub->Flags |= CHECKED;

 currentItem = currentMenu->FirstItem;	/* #1: Files List */
 currentItem = currentItem->NextItem;	/* #2: Get List */
 currentSub = currentItem->SubItem;    /* #2.1 : By Directory */
 currentSub = currentSub->NextItem;    /* #2.2 : By Size */
 currentSub = currentSub->NextItem;    /* #2.3 : By FileName */
 currentSub = currentSub->NextItem;    /* #2.4 : By Description */
 currentSub = currentSub->NextItem;		/* #2.5 : Keep Sorted */
 if (nKeepSorted[1] == 0) currentSub->Flags &= ~(CHECKED);
	   					else currentSub->Flags |= CHECKED;

 /* now the toughie-- the Output menu. */
 currentMenu = currentMenu->NextMenu;
 
 currentItem = currentMenu->FirstItem;		/* #1: Aminet Parse */
 
 if (noparse) currentItem->Flags &= ~(CHECKED);
	   else currentItem->Flags |= CHECKED;
	   
	   
 currentItem = currentItem->NextItem;		/* #2: Get Files */
 
 if (noparse) currentItem->Flags &= ~(ITEMENABLED);
	   else currentItem->Flags |= ITEMENABLED;
 if (filesflag) currentItem->Flags |= CHECKED;
	  	else currentItem->Flags &= ~(CHECKED);
	  	
 currentItem = currentItem->NextItem;		/* #3: Get Readmes */
 if (noparse) currentItem->Flags &= ~(ITEMENABLED);
	   else currentItem->Flags |= ITEMENABLED;
 if (getreadmes) currentItem->Flags |= CHECKED;
	  	 else currentItem->Flags &= ~(CHECKED);
	
 currentItem = currentItem->NextItem;		/* #4: Split Commands */
 
 if (noparse) currentItem->Flags &= ~(ITEMENABLED);
	   else currentItem->Flags |= ITEMENABLED;
 if (nosplit) currentItem->Flags &= ~(CHECKED);
	  	 else currentItem->Flags |= CHECKED;
	  	 
 
 currentItem = currentItem->NextItem;		/* #5: Use CD's */
 if (noparse) currentItem->Flags &= ~(ITEMENABLED);
	   else currentItem->Flags |= ITEMENABLED;
 if (simplepaths) currentItem->Flags |= CHECKED;
	  	 else currentItem->Flags &= ~(CHECKED);
	  	 
 currentItem = currentItem->NextItem;		/* #6: Line length */
 if ((noparse)||(nosplit)) currentItem->Flags &= ~(ITEMENABLED);
	   else currentItem->Flags |= ITEMENABLED;

 ResetMenuStrip( mgetWnd, mgetMenus );                 
}






/* Turns all \n's in input string into <space><newline>'s */
void FindReturns(char *mystring)
{
char *thischar=mystring, *prevchar=mystring;

 while (*thischar != NULL)
	{
	
	if ( (*prevchar  ==   92) &&						/* any '/'s ? */
	     ((*thischar ==   78)||(*thischar == 110)) &&      /* N's or n's */
	     (prevchar   !=  NULL) &&						/* Sanity chk */
	     (thischar   !=  NULL))
		
		{
		*prevchar = 32;   /* set this to a space--easier than shortening string */
		*thischar = 10;   /* and end this line with a newline char */
		}
	
	prevchar = thischar;
	thischar++;
	}
}









int AddFile(struct List *mylist, char *newstring)
{
struct Node *newnode;
char *newname, *i, returnchar = 10, spacechar = 32;
UBYTE diff=MAXFILELINELENGTH;
int minlinelength = 1;

 if (keepblanklines == 1) minlinelength = 0;
 if (newstring == NULL) return(0);
 if (strlen(newstring) < minlinelength) return(0); 

 if (!( newnode = AllocMem(sizeof(struct Node),MEMF_CLEAR) ))
	{
	MakeReq("AddFile: Couldn't allocate Memory for Node!",NULL,"Uh-oh");
	return(0);
	}
 added_bytes += sizeof(struct Node);
	
 i = strchr(newstring, (char) returnchar);
 if (i != NULL) diff = i-newstring;  /* number of chars into the string where newline is! */

 if (!( newname = AllocMem(diff+1,MEMF_CLEAR) ))
	{
	MakeReq("AddFile: Couldn't allocate memory for Node String!",NULL,"D-oh!");
	return(0);
	}
  added_bytes += diff+1;
	
strncpy(newname,newstring,diff);   /* copy over the bytes */

newnode->ln_Pri = diff - 126;		/* store string length in unused field */
							/* really bad style, isn't it? */

newnode->ln_Name=newname;      	/* and set ze pointer! */

AddTail(mylist, newnode);
return(1);
}



/* Prints out a file.  Makes sure there is a \r\n after the end of every line */
int PrintFile(char *szFileName, int PrintReturnFirst)
{
	FILE *input_file = fopen(szFileName,"r");
	char inputline[MAXFILELINELENGTH], *a, *b;
	int nLen;

 	if (input_file == NULL) 
 	{
		return(0);
 	}

 	if (PrintReturnFirst == 1)
 	{
 		fprintf(fpOut,"\r\n");
 		
 	}
 		
	/* Read until we get a line-end */
	while(!feof(input_file))
	{
		memset(inputline,NUL,MAXFILELINELENGTH);
		fgets(inputline,MAXFILELINELENGTH,input_file);  /* Read up to MAXFILELINELENGTH chars from inputfile */
		
		nLen = strlen(inputline);
		
		if (nLen >= 2)
		{
			/* make sure that it ends in a \r\n */
			a = &inputline[strlen(inputline)-2];
			b = &inputline[strlen(inputline)-1];
			
			if ((*a == '\r')&&(*b == '\n')) /* the easy case */
			{
				fprintf(fpOut,"%s",inputline);
			}
			else
			{
				if ((*a != '\r')&&(*b == '\n'))  /* the normal case, for Amigas */
				{
				/* make the newline a return, and then append a newline */
					*b = '\r';
					fprintf(fpOut,"%s\n",inputline);
				}
				else
				{
				if ((*a == '\r')&&(*b != '\n'))	/* the abnormal case */
					{
						*b = '\n';
						fprintf(fpOut,"%s",inputline);
					}
					else
					{
						/* *a != \r, *b != \n */
						fprintf(fpOut,"%s\r\n",inputline);
					}
				}
			}
		}
		else
		if (nLen == 1) fprintf(fpOut,"\r\n");
	}	
	fclose(input_file);
	return(1);
}


 
/* returns the number of lines successfully parsed and added to the list */
int ReadmyFile(void)
{
FILE *input_file = NULL;
char inputline[MAXFILELINELENGTH];
char *firstnull;
int nullpos = 0, okline = 0, nUpdate = 50;
int filelength = 0, failed_lines = 0;
int minlinelength = 1;

if (keepblanklines == 1) minlinelength = 0;

SetPointer(mgetWnd, waitPointer, 16, 16, -6, 0);

 while (input_file == NULL) 
	{
	input_file = fopen(inputfile,"r");
	if ((input_file == NULL)&&(RequestAFile(inputfile) == 0)) 
		{
		ClearPointer(mgetWnd);
		return(0);
		}
	}
	
 SetReqDefaults(inputfile);

 while (!feof(input_file))
	{
	filelength++;		
	okline=0;  
	/* Read until we get a line-end */
	while((okline==0)&&(!feof(input_file)))
		{
		memset(inputline,NUL,MAXFILELINELENGTH);
		fgets(inputline,MAXFILELINELENGTH,input_file);  /* Read up to MAXFILELINELENGTH chars from inputfile */
		firstnull = strchr(inputline,(char) 10); /* Find address of carriage return */
		nullpos = firstnull - inputline;  		 /* Subtract to get return pos */
		if ((nullpos >= minlinelength)&&(nullpos < MAXFILELINELENGTH)) okline=1;
		}
	
	if ((nullpos < MAXFILELINELENGTH)||(noparse))
	      {
	      	if (AddFile(filelist, inputline) == 1)
      		{
	      		filelist_length++;

					if (nUpdate == 0)
					{
						sprintf(windowtitle,"Loading: %i",filelist_length);   
						SetWindowTitles(mgetWnd, windowtitle , (char *) ~0); 	      		
						nUpdate = 50;
					}
					else
					{
						nUpdate--;
					}
	     		}
	      	else
	      	{
	      		failed_lines++;
	      	}
	      }
	      else
	      {
	      	failed_lines++;
	      }
	      	
	}

fclose(input_file);
ClearPointer(mgetWnd);	
return(filelist_length);
}












VOID FreeFileNodes(struct List *mylist)
{
struct Node *nextnode,*worknode = mylist->lh_Head;  
int nodesize = sizeof(struct Node);

 while (nextnode = (worknode->ln_Succ))
	{
	if (worknode->ln_Name != NULL)
		{
		FreeMem(worknode->ln_Name,worknode->ln_Pri+127);
		added_bytes -= worknode->ln_Pri+127;
		}		
	FreeMem(worknode,nodesize);
	worknode = nextnode;
	added_bytes -= nodesize;
	}
}











void ChangeWindowTitle(void)
{
char *fstring = inputfile, *f2;
char sSubString[60];
int charlength = (windowwidth-81)/8 - 40;

if (charlength <= 0) 
	{
	fstring = sSubString;
	fstring[0] = NUL;
	}
	else
	if (strlen(fstring) > charlength)
		{
		f2 = inputfile + strlen(inputfile) - charlength - 1;	
		if (f2 > inputfile)
			{
			fstring = sSubString;
			strcpy(fstring,f2);
			}
		}	
sprintf(windowtitle,"(%s) %i files, %u kilobytes selected.",fstring, files_selected, kbytes_selected);   
SetWindowTitles(mgetWnd, windowtitle , (char *) ~0); 
return();
}











VOID UpdateByteCount(char *mystring, int addorsub)
{
kbytes_selected = kbytes_selected + (AminetFileSize(mystring) * addorsub);
return();
}











VOID Cleanup(void)
{

if ((fpOut != stdout)&&(fpOut != NULL)) fclose(fpOut);

if (listfontdata)  CloseFont(listfontdata);
if (windowisopen)  ClosemgetWindow();
if (screenisopen)  CloseDownScreen();
if (filelist)	    
				{
			    FreeFileNodes(filelist); 
			    FreeMem(filelist,sizeof(struct List));
			    added_bytes -= sizeof(struct List);
			   }
if (getlist) 
		      {
			    FreeFileNodes(getlist);
			    FreeMem(getlist,sizeof(struct List));
			    added_bytes -= sizeof(struct List);
			   }
if (WorkbenchBase) CloseLibrary((struct Library *)WorkbenchBase);
if (IconBase)		 CloseLibrary((struct Library *)IconBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
if (AslBase)	    CloseLibrary((struct Library *)AslBase);
if (UtilityBase)   CloseLibrary((struct Library *)UtilityBase);
if (GraphicsBase)  CloseLibrary((struct GraphicsLib *)GraphicsBase);
if (GadToolsBase)  CloseLibrary((struct Library *)GadToolsBase);
return();
}











int RequestAFile(char *szBuffer)
{
int rvalue = 1;

if (strlen(defDir) == 0) strcpy(defDir,"ram:");
if (strlen(defFile)== 0) strcpy(defFile,"RECENT");

struct TagItem frtags[] =
{
	ASL_Hail,		(ULONG)"Select a text file to browse.",
	ASL_Height,	350,
	ASL_Width,	320,
	ASL_LeftEdge,	50,
	ASL_TopEdge,	35,
	ASL_OKText,	(ULONG)"Okay",
	ASL_CancelText,(ULONG)"Cancel",
	ASL_File,		defFile,
	ASL_Dir,	 	defDir,
	ASL_Window,	mgetWnd,
	TAG_DONE
};

struct FileRequester *fr;

fr = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, frtags);

if (fr == NULL) 
	{
	rvalue = 0 ;
	}

 if ((rvalue)&&(AslRequest(fr, NULL)))
	{
	strcpy(szBuffer,fr->rf_Dir);
	strncpy(defDir,fr->rf_Dir,sizeof(defDir));
	strncpy(defFile,fr->rf_File,sizeof(defFile));
	if ((defDir[strlen(defDir)-1] != '/')&&
	    (defDir[strlen(defDir)-1] != ':')) strcat(szBuffer,"/");
	strcat(szBuffer,fr->rf_File);
	}
	else
	rvalue = 0;
	
if (fr != NULL) FreeAslRequest(fr);

return(rvalue);
}









void TurnOnAllMenuItems(struct Menu *myMenu)
{
struct MenuItem *mItem;

 while (myMenu != NULL)
	{
	mItem = myMenu->FirstItem;
	while (mItem != NULL)
		{
		mItem->Flags |= ITEMENABLED;
		mItem = mItem->NextItem;
		}
	myMenu = myMenu->NextMenu;
	}
return;
}










VOID SetReqDefaults(char *szFilePath)
{
char *sFileStart;

 sFileStart = strrchr(szFilePath,'/');
 if (sFileStart == NULL)
 	{
 	sFileStart = strrchr(szFilePath,':');
 	if (sFileStart == NULL)
 		{
 		sFileStart = szFilePath;
 		}
 	}
 
 if (sFileStart != NULL) strncpy(defFile,sFileStart+(sFileStart != szFilePath),sizeof(defFile));
 if ((sFileStart != NULL)&&(sFileStart != szFilePath)) strncpy(defDir,szFilePath,(sFileStart - szFilePath) + 1);
 return();
}

 









VOID UpperCase(char *sOldString)
{
char *i = sOldString;
int diff = 'a' - 'A';

 if (sOldString == NULL) return();

 while (*i != '\0')
	{
	if ((*i >= 'a')&&(*i <= 'z')) *i = *i - diff;
	i++;
	}

return();
}


VOID LowerCase(char *sOldString)
{
char *i = sOldString;
int diff = 'a' - 'A';

 if (sOldString == NULL) return();

 while (*i != '\0')
	{
	if ((*i >= 'A')&&(*i <= 'Z')) *i = *i + diff;
	i++;
	}

return();
}






int mgetoutput(void)
{
FILE *fpTemp = NULL;

		if (files_selected > 0) 
		{
			/* If no output name given, do default output... */
 			if (strlen(sOutFileName) == 0)
 			{
 				/* for Workbench, absolute default is ram:GadMget.output */
 				if (BStartedFromWB == TRUE)
 				{
 					fpTemp = fopen("ram:Gadmget.Output","w");
 					if (fpTemp == NULL) 
 					{
 					   MakeReq("Error:  Couldn't open ram:GadMget.output for writing!",NULL,"Ok");
						Cleanup();
						exit(10);
 					}
 				}
 				else
 				{	/* for the CLI, default is stdout */
 					fpTemp = stdout;
 				}
 			}
 			else
 			{
	 			/* open requested output file for writing */
	 			fpTemp = fopen(sOutFileName,"w");
	 			if (fpTemp == NULL)
	 			{
	 				MakeReq("Error:  Couldn't open output file!",NULL,"Ok");
	 			}
	 		}
	 		
 			fpOut = fpTemp;
			PrintFile(szHeaderFile,0);
			if (noparse) RawOutputList(getlist);
					   else OutputList(getlist); 
			PrintFile(szFooterFile,1);
			if (fpOut != stdout) fclose(fpOut);			
		}
return(0);
}



VOID ParseCliArgs(int argc, char *argv[])
{
 int nextpasslookfor = 0;
 FILE *fpTemp = NULL;

 memset(defDir,NUL,sizeof(defDir));
 memset(defFile,NUL,sizeof(defFile));
 memset(szHeaderFile,NUL,sizeof(szHeaderFile));
 memset(szFooterFile,NUL,sizeof(szFooterFile));
 memset(inputfile,NUL,sizeof(inputfile));
 
 if (argc > 1) 
 	{
 	strncpy(inputfile,argv[1],sizeof(inputfile));
 	SetReqDefaults(inputfile);
 	}
 		
 if (*inputfile == '?')
	{
	fprintf(fpOut,"%s",template);
	Cleanup();
	exit(0);
	}

 
 for (int i=2; i<=argc; i++)
	{
	if (nextpasslookfor == 2)
		{
		strncpy(szPubScreenName,argv[i-1],sizeof(szPubScreenName));
		pubscreenname = szPubScreenName;
		screentype = USE_PUBSCREEN;
		continue;			/* skip to next loop */
		}
   if (nextpasslookfor == 7) 		/* FILE PARAMETER */
 		{
 		strncpy(inputfile,argv[i-1],sizeof(inputfile));
 		SetReqDefaults(inputfile);
 		}
	if (nextpasslookfor == 9)		/* COMMAND PARAMETER */
		{
		strncpy(szCommandString,argv[i-1],sizeof(szCommandString));
		}
	
	UpperCase(argv[i-1]);

	switch(nextpasslookfor)
	{	
	case(1):
		if (atoi(argv[i-1]) > 0)  maxoutputlinelength = atoi(argv[i-1]);
		break;
		
	/* case 2 is up above, before the Upper() command */
	
	case(3):		/* WIDTH PARAMETER */
		if (atoi(argv[i-1]) > 0)  windowwidth = 155;	/* min level */
		if (atoi(argv[i-1]) > 155) windowwidth = atoi(argv[i-1]);
		break;
	case(4):		/* HEIGHT PARAMETER */
		if (atoi(argv[i-1]) > 0) windowheight = 167;	/* min level */
		if (atoi(argv[i-1]) > 167) windowheight = atoi(argv[i-1]);
		break;
	case(5):		/* TOP PARAMETER */
		if (atoi(argv[i-1]) > 0) windowtop = atoi(argv[i-1]);
		break;
	case(6):		/* LEFT PARAMETER */
		if (atoi(argv[i-1]) > 0) windowleft = atoi(argv[i-1]);
		break;
		
	/* Case 7 is up above, before the Upper() command */
	
	case(8):		/* OUTPUT PARAMETER */
		strncpy(sOutFileName,argv[i-1],sizeof(sOutFileName));
		break;
	
	/* Case 9 is up above, before the Upper() command */
	
	case(10):		/* HEADER PARAMETER */
		strncpy(szHeaderFile,argv[i-1],sizeof(szHeaderFile));
		break;
		
	case(11):		/* FOOTER PARAMETER */
		strncpy(szFooterFile,argv[i-1],sizeof(szFooterFile));
		break;

	case(12):		/* FONT PARAMETER */
		strncpy(sListFontName,argv[i-1],sizeof(sListFontName));
		LowerCase(sListFontName);
		if (strstr(sListFontName,".font") == NULL) strncat(sListFontName,".font",sizeof(sListFontName));
		break;
		
	case(13):		/* FONTSIZE PARAMETER */
		if (atoi(argv[i-1]) > 0) nListFontSize = atoi(argv[i-1]);
		break;
	
	case(14):		/* FILESORT PARAMETER */
		LowerCase(argv[i-1]);
		if (strcmp(argv[i-1],"directory") == 0)   nSortType[0] = SORTBYDIR;
		if (strcmp(argv[i-1],"filename") == 0)    nSortType[0] = SORTBYNAME;
		if (strcmp(argv[i-1],"size") == 0)        nSortType[0] = SORTBYSIZE;
		if (strcmp(argv[i-1],"description") == 0) nSortType[0] = SORTBYDESC;
		break;
			
	case(15):		/* GETSORT PARAMETER */
		LowerCase(argv[i-1]);
		if (strcmp(argv[i-1],"directory") == 0)   nSortType[1] = SORTBYDIR;
		if (strcmp(argv[i-1],"filename") == 0)    nSortType[1] = SORTBYNAME;
		if (strcmp(argv[i-1],"size") == 0)        nSortType[1] = SORTBYSIZE;
		if (strcmp(argv[i-1],"description") == 0) nSortType[1] = SORTBYDESC;
		break;
	
	default:
		/* nothing */
		break;		
	}
	nextpasslookfor = 0;
	
	
	
	if (strcmp(argv[i-1],"NOAPPWINDOW") == 0) appwindow 		= 0;
	if (strcmp(argv[i-1],"CASESENSITIVE") == 0) casesensitive= 1;	
	if (strcmp(argv[i-1],"NOPARSE") == 0) 		noparse 			= 1;
	if (strcmp(argv[i-1],"NOCOMMAND") == 0) 	nocommand		= 1;
	if (strcmp(argv[i-1],"NOSPLIT") == 0) 		nosplit 			= 1;
	if (strcmp(argv[i-1],"GETREADMES") == 0) 	getreadmes 		= 1;	
	if (strcmp(argv[i-1],"NOCD") == 0)			nocd				= 1;
   if (strcmp(argv[i-1],"NOFILES") == 0) 	
    										{
    										filesflag 	= 0;
    										getreadmes  = 1;
    										}
 	if (strcmp(argv[i-1],"LINELENGTH") == 0)		   nextpasslookfor= 1;
 	if (strcmp(argv[i-1],"PUBSCREEN") == 0)		   nextpasslookfor= 2;
	if (strcmp(argv[i-1],"DEFPUBSCREEN") == 0)	   screentype = USE_PUBSCREEN; 	
	if ((strcmp(argv[i-1],"WBSCREEN") == 0)||
	    (strcmp(argv[i-1],"WORKBENCHSCREEN") == 0)) screentype = USE_WBSCREEN;
	if (strcmp(argv[i-1],"NOSIMPLEPATHS") == 0)	   simplepaths  = 0;	
	if (strcmp(argv[i-1],"KEEPBLANKLINES") == 0)    keepblanklines = 1;
	if (strcmp(argv[i-1],"KEEPFILESSORT") == 0)   nKeepSorted[0] = 1;
	if (strcmp(argv[i-1],"KEEPGETSORT") == 0)     nKeepSorted[1] = 1;
																					
	if (strcmp(argv[i-1],"WIDTH") == 0)			nextpasslookfor = 3;
	if (strcmp(argv[i-1],"HEIGHT") == 0)		nextpasslookfor = 4;
	if (strcmp(argv[i-1],"TOP") == 0)			nextpasslookfor = 5;
	if (strcmp(argv[i-1],"LEFT") == 0)			nextpasslookfor = 6;
	if (strcmp(argv[i-1],"FILE") == 0)			nextpasslookfor = 7;
	if (strcmp(argv[i-1],"OUTPUT") == 0)		nextpasslookfor = 8;
	if (strcmp(argv[i-1],"COMMAND") == 0)		nextpasslookfor = 9;
	if (strcmp(argv[i-1],"HEADER") == 0)		nextpasslookfor = 10;
	if (strcmp(argv[i-1],"FOOTER") == 0)		nextpasslookfor = 11;
	if (strcmp(argv[i-1],"FONT") == 0)        nextpasslookfor = 12;
	if (strcmp(argv[i-1],"FONTSIZE") == 0)    nextpasslookfor = 13;
	if (strcmp(argv[i-1],"SIZE") == 0)        nextpasslookfor = 13;
	if (strcmp(argv[i-1],"FILESORT") == 0)    nextpasslookfor = 14;
	if (strcmp(argv[i-1],"GETSORT") == 0)     nextpasslookfor = 15;
	}

	return();
}










VOID wbmain(struct WBStartup *argv)
{
BStartedFromWB = TRUE;
IconBase = OpenLibrary("icon.library",33);
if (IconBase == NULL)
 	{
 	exit(2);
 	}
ParseWBArgs(argv);
main(0,argv);
}








VOID ParseWBArgs(struct WBStartup *argv)
{
struct WBArg *wb_arg = argv->sm_ArgList;
struct DiskObject *dobj;
char **toolarray, *sTemp;
FILE *fpTemp = NULL;


memset(defDir,NUL,sizeof(defDir));
memset(defFile,NUL,sizeof(defFile));
memset(szHeaderFile,NUL,sizeof(szHeaderFile));
memset(szFooterFile,NUL,sizeof(szFooterFile));


/* Parse the tooltypes from the program file */
dobj = GetDiskObject(wb_arg->wa_Name);

if (dobj != NULL)
 {
 	toolarray = (char **) dobj->do_ToolTypes;
	if (toolarray != NULL)
	{
	
		if (sTemp = (char *) FindToolType(toolarray,"OUTPUT")) 
		{
		  strncpy(sOutFileName,sTemp,sizeof(sOutFileName));
		}
											
		if (sTemp = (char *) FindToolType(toolarray,"FILE")) 
				{
				strncpy(inputfile,sTemp,sizeof(inputfile));
				SetReqDefaults(inputfile);
				}
		if (sTemp = (char *) FindToolType(toolarray,"NOPARSE"))   	noparse     = 1;
		if (sTemp = (char *) FindToolType(toolarray,"NOCOMMAND"))  	nocommand   = 1;
   	if (sTemp = (char *) FindToolType(toolarray,"NOSPLIT"))   	nosplit     = 1;	
   	if (sTemp = (char *) FindToolType(toolarray,"GETREADMES"))  getreadmes  = 1;
		if (sTemp = (char *) FindToolType(toolarray,"NOFILES"))
 															{
   	 													filesflag 	= 0;
   	 													getreadmes  = 1;
   	 													}
   	if (sTemp = (char *) FindToolType(toolarray,"LINELENGTH"))
   				{
   				if (atoi(sTemp) > 0)  maxoutputlinelength = atoi(sTemp); 
   				}
  				
  		if (sTemp = (char *) FindToolType(toolarray,"PUBSCREEN"))   
  					{
  					strcpy(szPubScreenName,sTemp);
  					pubscreenname = szPubScreenName;
  					screentype = USE_PUBSCREEN;
  					}
  		
  		if (sTemp = (char *) FindToolType(toolarray,"NOSIMPLEPATHS"))	 simplepaths = 0;		
  		if (sTemp = (char *) FindToolType(toolarray,"NOPARSE"))   noparse = 1;		
		if (sTemp = (char *) FindToolType(toolarray,"NOAPPWINDOW")) appwindow = 0;
		if (sTemp = (char *) FindToolType(toolarray,"WBSCREEN"))  		 screentype = USE_WBSCREEN;
		if (sTemp = (char *) FindToolType(toolarray,"WORKBENCHSCREEN")) screentype = USE_WBSCREEN;								
		if (sTemp = (char *) FindToolType(toolarray,"NOCD"))				 nocd = 1;
		if (sTemp = (char *) FindToolType(toolarray,"KEEPBLANKLINES")) keepblanklines = 1;
		if (sTemp = (char *) FindToolType(toolarray,"KEEPFILESORT")) nKeepSorted[0] = 1;
		if (sTemp = (char *) FindToolType(toolarray,"KEEPGETSORT")) nKeepSorted[1] = 1;
		
		if (sTemp = (char *) FindToolType(toolarray,"WIDTH")) 							
						{
						if (atoi(sTemp) > 0)  windowwidth = 155;	/* min level */
						if (atoi(sTemp) > 155) windowwidth = atoi(sTemp);
						}
		if (sTemp = (char *) FindToolType(toolarray,"HEIGHT")) 	
						{						
						if (atoi(sTemp) > 0) windowheight = 167;	/* min level */
						if (atoi(sTemp) > 167) windowheight = atoi(sTemp);
						}
		if (sTemp = (char *) FindToolType(toolarray,"TOP")) 							
						{
						if (atoi(sTemp) > 0) windowtop = atoi(sTemp);
						}
		if (sTemp = (char *) FindToolType(toolarray,"LEFT")) 							
						{
						if (atoi(sTemp) > 0) windowleft = atoi(sTemp);
						}					
		if (sTemp = (char *) FindToolType(toolarray,"CASESENSITIVE")) 							
						{
						casesensitive = 1;
						}
		if (sTemp = (char *) FindToolType(toolarray,"COMMAND"))
						{
						strncpy(szCommandString,sTemp,sizeof(szCommandString));
						}
		if (sTemp = (char *) FindToolType(toolarray,"HEADER"))
						{
						strncpy(szHeaderFile,sTemp,sizeof(szHeaderFile));
						}
		if (sTemp = (char *) FindToolType(toolarray,"FOOTER"))
						{
						strncpy(szFooterFile,sTemp,sizeof(szFooterFile));
						}
		if (sTemp = (char *) FindToolType(toolarray,"FONT"))
						{
						strncpy(sListFontName,sTemp,sizeof(sListFontName));
						LowerCase(sListFontName);
						if (strstr(sListFontName,".font") == NULL) strncat(sListFontName,".font",sizeof(sListFontName));
						}
		if (sTemp = (char *) FindToolType(toolarray,"FONTSIZE"))
						{
						if (atoi(sTemp) > 0) nListFontSize = atoi(sTemp);
						}
		if (sTemp = (char *) FindToolType(toolarray,"SIZE"))
						{
						if (atoi(sTemp) > 0) nListFontSize = atoi(sTemp);
						}
		if (sTemp = (char *) FindToolType(toolarray,"FILESORT"))
						{
						LowerCase(sTemp);
						if (strcmp(sTemp,"directory") == 0)   nSortType[0] = SORTBYDIR;
						if (strcmp(sTemp,"filename") == 0)    nSortType[0] = SORTBYNAME;
						if (strcmp(sTemp,"size") == 0)        nSortType[0] = SORTBYSIZE;
						if (strcmp(sTemp,"description") == 0) nSortType[0] = SORTBYDESC;
						}
		if (sTemp = (char *) FindToolType(toolarray,"GETSORT"))
						{
						LowerCase(sTemp);
						if (strcmp(sTemp,"directory") == 0)   nSortType[1] = SORTBYDIR;
						if (strcmp(sTemp,"filename") == 0)    nSortType[1] = SORTBYNAME;
						if (strcmp(sTemp,"size") == 0)        nSortType[1] = SORTBYSIZE;
						if (strcmp(sTemp,"description") == 0) nSortType[1] = SORTBYDESC;
						}	
	}		 			
 FreeDiskObject(dobj);
 }
 
 /* Get the name of the file extended_clicked, if there is one */
 if (argv->sm_NumArgs > 1) 
	{
	wb_arg++;	/* The first name is the programs name, the 2nd is the proj. icon */
	if (wb_arg->wa_Name != NULL) 
		{
		strncpy(inputfile,wb_arg->wa_Name,sizeof(inputfile));
		CurrentDir(wb_arg->wa_Lock);
		}
	}
	
return();
}










/********/
/* MAIN */
/********/
VOID main(int argc, char *argv[])
{
FILE *test = NULL;
ULONG winsig,signals;
BPTR olddir;

GraphicsBase = OpenLibrary("graphics.library",37);
 if (GraphicsBase==NULL)
	{
	fprintf(fpOut,"couldn't open Graphics.library v37!");
	Cleanup();
	return;
	}
UtilityBase = OpenLibrary("utility.library",37);
 if (UtilityBase==NULL)
	{
	fprintf(fpOut,"couldn't open utility.library v37!");
	Cleanup();
	return;
	}
GadToolsBase = OpenLibrary("gadtools.library",37);
 if (GadToolsBase==NULL)
	{
	fprintf(fpOut,"couldn't open gadtools.library v37!\n");
	Cleanup();
	return;
	}
AslBase = OpenLibrary("asl.library", 37L);
 if (AslBase == NULL)
	{
	fprintf(fpOut,"couldn't open asl.library v37!\n");
	Cleanup();
	return;
	}
IntuitionBase = OpenLibrary("intuition.library",37);
 if (IntuitionBase == NULL)
 	{
 	fprintf(fpOut,"Couldn't open intuition.library!\n");
 	Cleanup();
 	return;
 	}
WorkbenchBase = OpenLibrary("workbench.library",37);
 if (WorkbenchBase == NULL)
 	{
 	fprintf(fpOut,"Couldn't open workbench.library!\n");
 	Cleanup();
 	return;
 	}

/* construct program name from version string */
memset(pnamestring,NUL,20);
strcpy(pnamestring,version+6);

memset(searchstring,NUL,sizeof(searchstring));

if (argc>1) ParseCliArgs(argc,argv);
 	
/* Now add data to listView */
/* First, initialize List filelist */
	
 if (!(filelist = AllocMem(sizeof(struct List),MEMF_CLEAR)) )
	{
	MakeReq("Couldn't create filelist!  Out of memory?",NULL,"Oh, Dear");
	Cleanup();
	return();
	}
 added_bytes += sizeof(struct List);
	
 if (!(getlist = AllocMem(sizeof(struct List),MEMF_CLEAR)) )
	{
	MakeReq("Couldn't create getlist!  Out of memory?",NULL,"Oh, Dear");
	Cleanup();
	return();
	}
 added_bytes += sizeof(struct List);
	
 NewList(filelist);
 NewList(getlist);
 

 lockscrnerror = SetupScreen();
 if (lockscrnerror)
	{
	MakeReq("Couldn't open screen!",NULL,"Sigh");
	Cleanup();
	return();
	}

 screenisopen = 1;
	
 winopenerror = OpenmgetWindow();
 if (winopenerror)
	{
	MakeReq("Couldn't open window!",NULL,"Sigh");
	Cleanup();
	return();
	}
 windowisopen = 1;
 
 if (ReadmyFile() > 0)
	{
		/* Sort if need be */
		if ((nKeepSorted[0] == 1)&&(!noparse)) SortList(filelist,nSortType[0]);
		
		/* First, make sure all the menus are enabled. */
		TurnOnAllMenuItems(mgetMenus);
		
		SetMenuValues();
	
    	GT_SetGadgetAttrs((struct Gadget *) mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END); 
		files_selected = 0;
	
		if (noparse) SetWindowTitles(mgetWnd, "Please select desired lines now." , (char *) ~0); 
				   else ChangeWindowTitle();
		
		winsig = 1L << mgetWnd->UserPort->mp_SigBit;
		while (done==FALSE)
			{
			signals = Wait(winsig|appwinsig);
			if (signals&winsig) handlereturn = HandlemgetIDCMP();
			if (signals&appwinsig) 
				{
				while (amsg = (struct AppMessage *) GetMsg(awport))
					{
					argptr = amsg->am_ArgList;
					if (argptr->wa_Name != NULL)
						{
						strcpy(inputfile,argptr->wa_Name);
						if (argptr->wa_Lock != NULL) 
							{
							olddir = CurrentDir(argptr->wa_Lock);
							SetReqDefaults(inputfile);
 							test = fopen(inputfile,"r");
 							if (test != NULL)
 								{
 								fclose(test);
 								GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, ~0, TAG_END);
								FreeFileNodes(filelist); 
	 							FreeMem(filelist,sizeof(struct List));
	 							added_bytes -= sizeof(struct List);
	 							ClearPointer(mgetWnd);
	 	
	 							if (!(filelist = AllocMem(sizeof(struct List),MEMF_CLEAR)) )
									{
									MakeReq("AppOpen : Couldn't create filelist!  Out of memory?",NULL,"Ok");
									return;
									}
	 							added_bytes += sizeof(struct List);
					
 								filelist_length = 0;
	 							search_current = NULL;
	 							index = 0;
	 							
	 						   NewList(filelist);
	 							ReadmyFile();
	 							GT_SetGadgetAttrs(mgetGadgets[0], mgetWnd, NULL, GTLV_Labels, filelist, TAG_END);
								CurrentDir(olddir);
								}
								else
								DisplayBeep(Scr);
							}
						}
					ReplyMsg((struct Message *) amsg);
					}
				}
			}
		if (windowisopen)  ClosemgetWindow();
		if (screenisopen)  CloseDownScreen();
	
		mgetoutput();
	}
Cleanup();
		
exit(0);	
}

#endif


	
