/*
Auto:		sc <file> LINK NODEBUG NOSTRCONS OPT SINT NOSTACKCHECK DATA=NEAR STARTUP=cres PARM=REGISTER UTILLIB NOSTKCHK
*/

/* $Revision Header built automatically *************** (do not edit) ************
**
** © Copyright by GuntherSoft
**
** File             : SnakeSYS:CPrgs/Utils/Touch.c
** Created on       : Monday, 26.07.93 22:15:08
** Created by       : Kai Iske
** Current revision : V1.0
**
**
** Purpose
** -------
**   - Small touch command which will create a file, if it doesn`s
**     exists yet.
**
** Revision V1.0
** --------------
** created on Monday, 26.07.93 22:15:08  by  Kai Iske.   LogMessage :
**     --- Initial release ---
**
*********************************************************************************/
#define REVISION "1.0"
#define REVDATE  "26.07.93"
#define REVTIME  "22:15:08"
#define AUTHOR   "Kai Iske"
#define VERNUM   1
#define REVNUM   0


#include	<string.h>
#include	<stdlib.h>
#include	<exec/types.h>
#include	<exec/memory.h>
#include	<dos/dos.h>
#include	<dos/exall.h>
#include	<proto/exec.h>
#include	<proto/dos.h>


extern struct WBStartUp *_WBenchMsg;


/**********************************************************************/
/*                           Version String                           */
/**********************************************************************/
static char *MyVer	= "$VER: Touch "REVISION" ("REVDATE")\0";


/**********************************************************************/
/*                  Template for Commandline Parsing                  */
/**********************************************************************/
static char *Template	= "FILES/M/A";
enum	{FILE_ARG, LAST_ARG};


/**********************************************************************/
/*                       The small main program                       */
/**********************************************************************/
void main(void)
{
	struct	RDArgs		*RDArgs	= NULL;
	struct	ExAllControl	*EAC	= NULL;
	struct	ExAllData	*EAD;
	struct	DateStamp	DS;
	APTR	*EAB			= NULL,
		*Args;
	BPTR	OutHandle,
		TouchFile;
	char	**FileNameList		= NULL,
		FileName[512],
		Pattern[512],
		TouchName[512];
	WORD	FileNameType;
	BOOL	GoOn;

		// Not available from Workbench

	if(_WBenchMsg)
		exit(0);

		// Get handle to Output

	OutHandle = Output();

		// Get current DateStamp

	DateStamp(&DS);

		// Get Buffer for arguments

	if((Args = AllocVec((LAST_ARG * sizeof(ULONG)), MEMF_CLEAR)))
	{
			// Parse Commandline

		if((RDArgs = ReadArgs(Template, (ULONG *)Args, NULL)))
		{
				// Get buffer for ExAll

			if((EAB = AllocVec((sizeof(struct ExAllData) * 20), MEMF_CLEAR)))
			{
					// Get ExAllControl Structure

				if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
				{
						// Get pointers to FileNames passed

					FileNameList = Args[FILE_ARG];

						// Loop for all filenames

					while(FileNameList && *FileNameList)
					{
							// Copy current filename

						strcpy(FileName, *FileNameList);

							// Create pattern

						if((FileNameType = ParsePatternNoCase(FilePart(FileName), Pattern, 512)) != -1)
						{
								// Check pattern type

							if(FileNameType)
							{
									// Real pattern. Remove trailing name

								*(PathPart(FileName)) = '\0';

									// Try to get lock to directory

								if((TouchFile = Lock(FileName, ACCESS_READ)))
								{
										// Set up ExAllControl

									EAC->eac_LastKey	= 0;
									EAC->eac_MatchString	= Pattern;
									EAC->eac_MatchFunc	= NULL;

									do
									{
											// Loop directory

										GoOn = ExAll(TouchFile, (struct ExAllData *)EAB, (108*20), ED_NAME, EAC);

											// Error occured ???

										if((!GoOn) && (IoErr() != ERROR_NO_MORE_ENTRIES))
											PrintFault(IoErr(), "Man ");

											// End of dir reached ;

										if(EAC->eac_Entries == 0)
											GoOn = FALSE;
										else
										{
												// Get buffer to ExAll Buffer

											EAD = (struct ExAllData *)EAB;

											do
											{
													// Clear Touchname and create new one

												TouchName[0]	= '\0';
												AddPart(TouchName, FileName, 512);
												AddPart(TouchName, EAD->ed_Name, 512);

													// Set new date

												SetFileDate(TouchName, &DS);

													// Loop for entries

												EAD = EAD->ed_Next;
											} while(EAD);
										}

									} while(GoOn);

										// UnLock directory

									UnLock(TouchFile);
								}
							}
							else
							{
									// File to be touched there ???

								if((TouchFile = Lock(FileName, ACCESS_READ)))
								{
										// Unlock it

									UnLock(TouchFile);

										// ... and set filedate

									SetFileDate(FileName, &DS);
								}
									// Otherwise create new file

								else if((TouchFile = Open(FileName, MODE_NEWFILE)))
									Close(TouchFile);
							}
						}
						else
						{
							PrintFault(IoErr(), "Touch ");
							FileNameList = NULL;
						}
							// Loop for files

						FileNameList++;
					}
				}
				else
					PrintFault(IoErr(), "Touch ");
			}
			else
				FPuts(OutHandle, "Touch : Buffer for Directory Scan could not be allocated\n");
		}
		else
			PrintFault(IoErr(), "Touch ");
	}
	else
		FPuts(OutHandle, "Touch : Buffer for Commandline could not be allocated\n");


	if(EAC)
		FreeDosObject(DOS_EXALLCONTROL, EAC);

	if(EAB)
		FreeVec(EAB);

	if(RDArgs)
		FreeArgs(RDArgs);

	if(Args)
		FreeVec(Args);

	if(FileNameList)
		exit(0);
	else
		exit(10);
}