add touch to copy by Brandon Turner
Modified: trunk/reactos/subsys/system/cmd/copy.c

Modified: trunk/reactos/subsys/system/cmd/copy.c
--- trunk/reactos/subsys/system/cmd/copy.c	2005-07-21 04:38:26 UTC (rev 16675)
+++ trunk/reactos/subsys/system/cmd/copy.c	2005-07-21 10:03:01 UTC (rev 16676)
@@ -25,6 +25,10 @@
  *
  *    13-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
  *        Rewrite to clean up copy and support wildcard.
+ *
+ *    20-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
+ *        Add touch syntax.  "copy arp.exe+,,"
+ *        Copy command is now completed.
  */
  
 #include <precomp.h>
@@ -47,7 +51,7 @@
 #define BUFF_SIZE 16384         /* 16k = max buffer size */
  
  
-int copy (TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], int append, DWORD lpdwFlags)
+int copy (TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
 {
 	TCHAR szMsg[RC_STRING_MAX_SIZE];
 	FILETIME srctime;
@@ -63,10 +67,41 @@
 	TCHAR TempSrc[MAX_PATH];
 	TCHAR * FileName;
  
+
 #ifdef _DEBUG
 	DebugPrintf (_T("checking mode\n"));
 #endif
  
+	if(bTouch)
+	{
+	hFileSrc = CreateFile (source, GENERIC_WRITE, FILE_SHARE_READ,
+		NULL, OPEN_EXISTING, 0, NULL);
+	if (hFileSrc == INVALID_HANDLE_VALUE)
+	{
+		LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE);
+		ConOutPrintf(szMsg, source);
+    nErrorLevel = 1;
+		return 0;
+	}
+
+		FILETIME NewFileTime;
+		SYSTEMTIME CurrentTime;
+
+		GetSystemTime(&CurrentTime);
+		SystemTimeToFileTime(&CurrentTime, &NewFileTime);
+		if(SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime))
+		{
+			CloseHandle(hFileSrc);
+			return 1;
+
+		}
+		else
+		{
+			CloseHandle(hFileSrc);
+			return 0;
+		}
+	}
+
 	dwAttrib = GetFileAttributes (source);
  
 	hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,
@@ -78,7 +113,7 @@
     nErrorLevel = 1;
 		return 0;
 	}
- 
+
 #ifdef _DEBUG
 	DebugPrintf (_T("getting time\n"));
 #endif
@@ -87,7 +122,7 @@
  
 #ifdef _DEBUG
 	DebugPrintf (_T("copy: flags has %s\n"),
-		*lpdwFlags & COPY_ASCII ? "ASCII" : "BINARY");
+		lpdwFlags & COPY_ASCII ? "ASCII" : "BINARY");
 #endif
  
 	/* Check to see if /D or /Z are true, if so we need a middle
@@ -304,6 +339,7 @@
 	BOOL bAppend = FALSE;
 	WIN32_FIND_DATA findBuffer;
 	HANDLE hFile;
+	BOOL bTouch = FALSE;
 	/* Used when something like "copy c*.exe d*.exe" during the process of
 	   figuring out the new name */
 	TCHAR tmpName[MAX_PATH] = _T("");
@@ -318,9 +354,11 @@
 	TCHAR * UseThisName;
 	/* Stores the name( i.e. blah.txt or blah*.txt) which later we might need */
 	TCHAR PreserveName[MAX_PATH];
-  /* for CMDCOPY env */
-  TCHAR *evar;
-  int size;
+   /* for CMDCOPY env */
+   TCHAR *evar;
+   int size;
+	TCHAR * szTouch;
+	BOOL bDone = FALSE;
  
 	
   /*Show help/usage info*/
@@ -491,20 +529,21 @@
 	{
 		/* There is not enough files, there has to be at least 1 */
 		ConOutResPuts(STRING_ERROR_REQ_PARAM_MISSING);
+		freep (arg);
 		return 1;
 	}
  
 	if(nFiles > 2)
 	{
 		/* there is too many file names in command */
-    LoadString(CMD_ModuleHandle, STRING_ERROR_TOO_MANY_PARAMETERS, szMsg, RC_STRING_MAX_SIZE);
-	  ConErrPrintf(szMsg,_T(""));		
-    nErrorLevel = 1;
+      LoadString(CMD_ModuleHandle, STRING_ERROR_TOO_MANY_PARAMETERS, szMsg, RC_STRING_MAX_SIZE);
+	   ConErrPrintf(szMsg,_T(""));		
+      nErrorLevel = 1;
+		freep (arg);
 		return 1;
 	}
  
-	if((nDes != -1) &&
-		((_tcschr (arg[nSrc], _T('+')) != NULL) ||
+	if(((_tcschr (arg[nSrc], _T('+')) != NULL) ||
 		(_tcschr (arg[nSrc], _T('*')) != NULL && _tcschr (arg[nDes], _T('*')) == NULL) ||
 		(IsExistingDirectory (arg[nSrc]) && (_tcschr (arg[nDes], _T('*')) == NULL && !IsExistingDirectory (arg[nDes])))
 		))
@@ -522,7 +561,6 @@
  
 	do
 	{
- 
 	/* Set up the string that is the path to the destination */
 	if(nDes != -1)
 	{
@@ -551,20 +589,42 @@
 		the chars one at a time until it gets too + */
 		while(TRUE)
 		{
- 
 			if(!_tcsncmp (appendPointer,_T("+"),1) || !_tcsncmp (appendPointer,_T("\0"),1))
 			{
 				/* Now that the pointer is on the + we 
 				   need to go to the start of the next filename */
 				if(!_tcsncmp (appendPointer,_T("+"),1))
 				   appendPointer++;
+				else
+					bDone = TRUE;
 				break;
+
 			}
+			
 			_tcsncat(tmpName,appendPointer,1);
 			appendPointer++;
+
 		}
 		/* Finish the string off with a null char */
 		_tcsncat(tmpName,_T("\0"),1);
+			
+		if(_tcschr (arg[nSrc], _T(',')) != NULL)
+			{
+				/* Only time there is a , in the source is when they are using touch
+				   Cant have a destination and can only have on ,, at the end of the string 
+					Cant have more then one file name */
+				szTouch = _tcsstr (arg[nSrc], _T("+"));
+				if(_tcsncmp (szTouch,_T("+,,\0"),4) || nDes != -1)
+				{
+					LoadString(CMD_ModuleHandle, STRING_ERROR_INVALID_PARAM_FORMAT, szMsg, RC_STRING_MAX_SIZE);
+					ConErrPrintf(szMsg,arg[nSrc]);		
+					nErrorLevel = 1;
+					freep (arg);
+					return 1;
+				}
+				bTouch = TRUE;
+				bDone = TRUE;
+			}
 
 		if(_tcslen(tmpName) == 2)
 		{
@@ -580,6 +640,7 @@
 	}
 	else
 	{
+		bDone = TRUE;
 		if(_tcslen(arg[nSrc]) == 2 && arg[nSrc][1] == _T(':'))
 		{
 			GetRootPath(arg[nSrc],szSrcPath,MAX_PATH);
@@ -617,8 +678,8 @@
  
 	/* Get a list of all the files */
 	hFile = FindFirstFile (szSrcPath, &findBuffer);
+	
  
- 
 	/* We need to figure out what the name of the file in the is going to be */
 	if((szDestPath[_tcslen(szDestPath) -  1] == _T('*') && szDestPath[_tcslen(szDestPath) -  2] == _T('\\')) ||
 		szDestPath[_tcslen(szDestPath) -  1] == _T('\\'))
@@ -648,7 +709,6 @@
 		else
 			break;
  
- 
 		do
 		{
 			/* Set the override to yes each new file */
@@ -659,7 +719,7 @@
 			{			
 				ConOutFormatMessage (GetLastError(), szSrcPath);			
 				freep (arg);
-        nErrorLevel = 1;
+				nErrorLevel = 1;
 				return 1;
 			}
  
@@ -677,7 +737,7 @@
 			{
 				ConOutFormatMessage (GetLastError (), szSrcPath);			
 				freep (arg);
-        nErrorLevel = 1;
+				nErrorLevel = 1;
 				return 1;
 			}
 			/* Copy over the destination path name */
@@ -738,25 +798,25 @@
 				}
 			}
  
- 
+
 			/* Build the string path to the source file */
 			_tcscpy(tmpSrcPath,szSrcPath);
 			_tcscat (tmpSrcPath, findBuffer.cFileName);
- 
+
 			/* Check to see if the file is the same file */
-			if(!_tcscmp (tmpSrcPath, tmpDestPath))
+			if(!bTouch && !_tcscmp (tmpSrcPath, tmpDestPath))
 				continue;
- 
+
 			/* Handle any overriding / prompting that needs to be done */
-			if((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT)
+			if(((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT) && !bTouch)
 				nOverwrite = Overwrite(tmpDestPath);
 			if(nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
 				continue;
 			if(nOverwrite == PROMPT_ALL || (nOverwrite == PROMPT_YES && bAppend))
 				dwFlags |= COPY_NO_PROMPT;
- 
+
 			/* Tell weather the copy was successful or not */
-			if(copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags))
+			if(copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch))
 			{
 				nFiles++;
 				/* only print source name when more then one file */
@@ -769,18 +829,19 @@
 				/* print out the error message */
 				LoadString(CMD_ModuleHandle, STRING_COPY_ERROR3, szMsg, RC_STRING_MAX_SIZE);
 				ConOutPrintf(szMsg);
-        nErrorLevel = 1;
+				ConOutFormatMessage (GetLastError(), szSrcPath);
+				nErrorLevel = 1;
 			}
- 
+
 		/* Loop through all wildcard files */
 		}while(FindNextFile (hFile, &findBuffer));
 	/* Loop through all files in src string with a + */
-	}while(_tcsncmp (appendPointer,_T("\0"),1));
- 
+	}while(!bDone);
+
 	/* print out the number of files copied */
 	LoadString(CMD_ModuleHandle, STRING_COPY_FILE, szMsg, RC_STRING_MAX_SIZE);
 	ConOutPrintf(szMsg, nFiles);
- 
+	
 	CloseHandle(hFile);
 	freep (arg);
 	return 0;