[Box Backup-commit] COMMIT r1130 - box/trunk/lib/win32

boxbackup-dev at fluffy.co.uk boxbackup-dev at fluffy.co.uk
Fri Oct 27 20:24:26 BST 2006


Author: chris
Date: 2006-10-27 20:24:26 +0100 (Fri, 27 Oct 2006)
New Revision: 1130

Modified:
   box/trunk/lib/win32/emu.cpp
   box/trunk/lib/win32/emu.h
Log:
Added emulated utimes, chmod, readv and writev.

Added useful utility functions ConvertFileTimeToTime_t and
ConvertTime_tToFileTime.

Added prototypes for new emulated functions emu_utimes, readv and writev.



Modified: box/trunk/lib/win32/emu.cpp
===================================================================
--- box/trunk/lib/win32/emu.cpp	2006-10-27 19:22:34 UTC (rev 1129)
+++ box/trunk/lib/win32/emu.cpp	2006-10-27 19:24:26 UTC (rev 1130)
@@ -826,6 +826,115 @@
 // --------------------------------------------------------------------------
 //
 // Function
+//		Name:    emu_utimes
+//		Purpose: replacement for the POSIX utimes() function,
+//			works with unicode filenames supplied in utf8 format,
+//			sets creation time instead of last access time.
+//		Created: 25th July 2006
+//
+// --------------------------------------------------------------------------
+int emu_utimes(const char * pName, const struct timeval times[])
+{
+	FILETIME creationTime;
+	if (!ConvertTime_tToFileTime(times[0].tv_sec, &creationTime))
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	FILETIME modificationTime;
+	if (!ConvertTime_tToFileTime(times[1].tv_sec, &modificationTime))
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	HANDLE handle = OpenFileByNameUtf8(pName, FILE_WRITE_ATTRIBUTES);
+
+	if (handle == NULL)
+	{
+		// errno already set and error logged by OpenFileByNameUtf8()
+		return -1;
+	}
+
+	if (!SetFileTime(handle, &creationTime, NULL, &modificationTime))
+	{
+		::syslog(LOG_ERR, "Failed to set times on '%s': error %d",
+			pName, GetLastError());
+		CloseHandle(handle);
+		return 1;
+	}
+
+	CloseHandle(handle);
+	return 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    emu_chmod
+//		Purpose: replacement for the POSIX chmod function,
+//			works with unicode filenames supplied in utf8 format
+//		Created: 26th July 2006
+//
+// --------------------------------------------------------------------------
+int emu_chmod(const char * pName, mode_t mode)
+{
+	std::string AbsPathWithUnicode = 
+		ConvertPathToAbsoluteUnicode(pName);
+	
+	if (AbsPathWithUnicode.size() == 0)
+	{
+		// error already logged by ConvertPathToAbsoluteUnicode()
+		return -1;
+	}
+	
+	WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
+	// We are responsible for freeing pBuffer
+	
+	if (pBuffer == NULL)
+	{
+		// error already logged by ConvertUtf8ToWideString()
+		free(pBuffer);
+		return -1;
+	}
+
+	DWORD attribs = GetFileAttributesW(pBuffer);
+	if (attribs == INVALID_FILE_ATTRIBUTES)
+	{
+		::syslog(LOG_ERR, "Failed to get file attributes of '%s': "
+			"error %d", pName, GetLastError());
+		errno = EACCES;
+		free(pBuffer);
+		return -1;
+	}
+
+	if (mode & S_IWRITE)
+	{
+		attribs &= ~FILE_ATTRIBUTE_READONLY;
+	}
+	else
+	{
+		attribs |= FILE_ATTRIBUTE_READONLY;
+	}
+
+	if (!SetFileAttributesW(pBuffer, attribs))
+	{
+		::syslog(LOG_ERR, "Failed to set file attributes of '%s': "
+			"error %d", pName, GetLastError());
+		errno = EACCES;
+		free(pBuffer);
+		return -1;
+	}
+
+	free(pBuffer);
+	return 0;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
 //		Name:    opendir
 //		Purpose: replacement for unix function, uses win32 findfirst routines
 //		Created: 25th October 2004
@@ -1263,4 +1372,96 @@
 	return strlen(pBuffer);
 }
 
+int readv (int filedes, const struct iovec *vector, size_t count)
+{
+	int bytes = 0;
+	
+	for (size_t i = 0; i < count; i++)
+	{
+		int result = read(filedes, vector[i].iov_base, 
+			vector[i].iov_len);
+		if (result < 0)
+		{
+			return result;
+		}
+		bytes += result;
+	}
+
+	return bytes;
+}
+
+int writev(int filedes, const struct iovec *vector, size_t count)
+{
+	int bytes = 0;
+	
+	for (size_t i = 0; i < count; i++)
+	{
+		int result = write(filedes, vector[i].iov_base, 
+			vector[i].iov_len);
+		if (result < 0)
+		{
+			return result;
+		}
+		bytes += result;
+	}
+
+	return bytes;
+}
+
+// need this for conversions
+time_t ConvertFileTimeToTime_t(FILETIME *fileTime)
+{
+	SYSTEMTIME stUTC;
+	struct tm timeinfo;
+
+	// Convert the last-write time to local time.
+	FileTimeToSystemTime(fileTime, &stUTC);
+
+	memset(&timeinfo, 0, sizeof(timeinfo));	
+	timeinfo.tm_sec = stUTC.wSecond;
+	timeinfo.tm_min = stUTC.wMinute;
+	timeinfo.tm_hour = stUTC.wHour;
+	timeinfo.tm_mday = stUTC.wDay;
+	timeinfo.tm_wday = stUTC.wDayOfWeek;
+	timeinfo.tm_mon = stUTC.wMonth - 1;
+	// timeinfo.tm_yday = ...;
+	timeinfo.tm_year = stUTC.wYear - 1900;
+
+	time_t retVal = mktime(&timeinfo) - _timezone;
+	return retVal;
+}
+
+bool ConvertTime_tToFileTime(const time_t from, FILETIME *pTo)
+{
+	time_t adjusted = from + _timezone;
+	struct tm *time_breakdown = gmtime(&adjusted);
+	if (time_breakdown == NULL)
+	{
+		::syslog(LOG_ERR, "Error: failed to convert time format: "
+			"%d is not a valid time\n", from);
+		return false;
+	}
+
+	SYSTEMTIME stUTC;
+	stUTC.wSecond       = time_breakdown->tm_sec;
+	stUTC.wMinute       = time_breakdown->tm_min;
+	stUTC.wHour         = time_breakdown->tm_hour;
+	stUTC.wDay          = time_breakdown->tm_mday;
+	stUTC.wDayOfWeek    = time_breakdown->tm_wday;
+	stUTC.wMonth        = time_breakdown->tm_mon  + 1;
+	stUTC.wYear         = time_breakdown->tm_year + 1900;
+	stUTC.wMilliseconds = 0;
+
+	// Convert the last-write time to local time.
+	if (!SystemTimeToFileTime(&stUTC, pTo))
+	{
+		syslog(LOG_ERR, "Failed to convert between time formats: "
+			"error %d", GetLastError());
+		return false;
+	}
+
+	return true;
+}
+
+
 #endif // WIN32

Modified: box/trunk/lib/win32/emu.h
===================================================================
--- box/trunk/lib/win32/emu.h	2006-10-27 19:22:34 UTC (rev 1129)
+++ box/trunk/lib/win32/emu.h	2006-10-27 19:24:26 UTC (rev 1130)
@@ -132,14 +132,6 @@
 	#define S_ISDIR(x) (S_IFDIR & x)
 #endif
 
-inline int utimes(const char * Filename, timeval[])
-{
-	//again I am guessing this is quite important to
-	//be functioning, as large restores would be a problem
-
-	//indicate success
-	return 0;
-}
 inline int chown(const char * Filename, u_int32_t uid, u_int32_t gid)
 {
 	//important - this needs implementing
@@ -159,23 +151,20 @@
 int   emu_chdir (const char* pDirName);
 int   emu_unlink(const char* pFileName);
 char* emu_getcwd(char* pBuffer, int BufSize);
+int   emu_utimes(const char* pName, const struct timeval[]);
+int   emu_chmod (const char* pName, mode_t mode);
 
-#ifdef _MSC_VER
-	inline int emu_chmod(const char * Filename, int mode)
-	{
-		// indicate success
-		return 0;
-	}
+#define utimes(buffer, times) emu_utimes(buffer, times)
 
-	#define chmod(file, mode)    emu_chmod(file, mode)
-	#define chdir(directory)     emu_chdir(directory)
-	#define unlink(file)         emu_unlink(file)
-	#define getcwd(buffer, size) emu_getcwd(buffer, size)
+#ifdef _MSC_VER
+	#define chmod(file, mode)     emu_chmod(file, mode)
+	#define chdir(directory)      emu_chdir(directory)
+	#define unlink(file)          emu_unlink(file)
+	#define getcwd(buffer, size)  emu_getcwd(buffer, size)
 #else
-	inline int chmod(const char * Filename, int mode)
+	inline int chmod(const char * pName, mode_t mode)
 	{
-		// indicate success
-		return 0;
+		return emu_chmod(pName, mode);
 	}
 
 	inline int chdir(const char* pDirName)
@@ -503,4 +492,12 @@
 // replacement for _cgetws which requires a relatively recent C runtime lib
 int console_read(char* pBuffer, size_t BufferSize);
 
+struct iovec {
+	void *iov_base;   /* Starting address */
+	size_t iov_len;   /* Number of bytes */
+};
+
+int readv (int filedes, const struct iovec *vector, size_t count);
+int writev(int filedes, const struct iovec *vector, size_t count);
+
 #endif // !EMU_INCLUDE && WIN32




More information about the Boxbackup-commit mailing list