[sword-svn] r3760 - in trunk: include lib/bcppmake src/mgr src/utilfuns

scribe at crosswire.org scribe at crosswire.org
Sat Jul 25 08:10:46 EDT 2020


Author: scribe
Date: 2020-07-25 08:10:46 -0400 (Sat, 25 Jul 2020)
New Revision: 3760

Modified:
   trunk/include/filemgr.h
   trunk/include/swbuf.h
   trunk/lib/bcppmake/libsword.bpr
   trunk/src/mgr/curlftpt.cpp
   trunk/src/mgr/curlhttpt.cpp
   trunk/src/mgr/filemgr.cpp
   trunk/src/mgr/installmgr.cpp
   trunk/src/mgr/swmgr.cpp
   trunk/src/utilfuns/utilstr.cpp
Log:
First cut at better isolation of FileIO to FileMgr and providing a WIN32 impl with works with wchar_t

Modified: trunk/include/filemgr.h
===================================================================
--- trunk/include/filemgr.h	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/include/filemgr.h	2020-07-25 12:10:46 UTC (rev 3760)
@@ -29,6 +29,7 @@
 #include <defs.h>
 #include <swcacher.h>
 #include <swbuf.h>
+#include <vector>
 
 SWORD_NAMESPACE_START
 
@@ -81,7 +82,7 @@
 	* filemgr will open.  Adjust for tuning.
 	*/
 	int maxFiles;
-	
+
 	static FileMgr *getSystemFileMgr();
 	static void setSystemFileMgr(FileMgr *newFileMgr);
 
@@ -125,6 +126,22 @@
 	virtual void flush();
 	virtual long resourceConsumption();
 
+     /** Get an environment variable from the OS
+     * @param variableName
+     *
+     * @return variable value from the OS
+     */
+     static SWBuf getEnvValue(const char *variableName);
+
+     /** Check if a path can be access with supplied permissions
+     * @param path Path to the resource
+     * @param mode Desired access mode
+     *
+     * @return whether or not the resource can be accessed with the requested
+     *	mode
+     */
+     static bool hasAccess(const char *path, int mode);
+
 	/** Checks for the existence and readability of a file.
 	* @param ipath Path to file.
 	* @param ifileName Name of file to check for.
@@ -137,6 +154,18 @@
 	*/
 	static signed char existsDir(const char *ipath, const char *idirName = 0);
 
+     /** Given a directory path, returns contents of directory
+     * @param dirPath Path to directory
+     * @param includeSize Optimization flag to allow passing false
+     *	to skip file size lookup (true forces both size and directory lookup)
+     * @param includeIsDirectory Optimization flag to allow passing false
+     *	to skip isDirectory lookup
+     *
+     * @return a container of DirEntry records describing contents
+     */
+     static std::vector<struct DirEntry> getDirList(const char *dirPath, bool includeSize = false, bool includeIsDirectory = true);
+
+
 	/** Truncate a file at its current position
 	* leaving byte at current possition intact deleting everything afterward.
 	* @param file The file to operate on.
@@ -144,6 +173,7 @@
 	signed char trunc(FileDesc *file);
 
 	static char isDirectory(const char *path);
+	static long getFileSize(const char *path);
 	static int createParent(const char *pName);
 	static int createPathAndFile(const char *fName);
 
@@ -151,7 +181,9 @@
 	 * @param fName filename to open
 	 * @return fd; < 0 = error
 	 */
+	static int openFile(const char *fName, int mode, int perms);
 	static int openFileReadOnly(const char *fName);
+     
 	static int copyFile(const char *srcFile, const char *destFile);
 	static int copyDir(const char *srcDir, const char *destDir);
 	static int removeDir(const char *targetDir);

Modified: trunk/include/swbuf.h
===================================================================
--- trunk/include/swbuf.h	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/include/swbuf.h	2020-07-25 12:10:46 UTC (rev 3760)
@@ -199,12 +199,10 @@
 	* @param newVal the value to set this buffer to. 
 	*/
 	inline void set(const SWBuf &newVal) {
-		unsigned long len = newVal.length() + 1;
+		unsigned long len = newVal.allocSize;
 		assureSize(len);
-//		const char *n = newVal.c_str();
-//		for (end = buf;len;len--) *end++ = *n++;
 		memcpy(buf, newVal.c_str(), len);
-		end = buf + (len - 1);
+		end = buf + (newVal.length());
 	}
 
 	/**
@@ -309,7 +307,7 @@
 	}
 
 	/**
-	* SWBuf::append - appends a wide charachter value to the current value of this SWBuf
+	* SWBuf::append - appends a wide character value to the current value of this SWBuf
 	* If the allocated memory is not enough, it will be resized accordingly.
 	* NOTE: This is dangerous, as wchar_t is currently different sizes on different
 	* platforms (stupid windoze; stupid c++ spec for not mandating 4byte).

Modified: trunk/lib/bcppmake/libsword.bpr
===================================================================
--- trunk/lib/bcppmake/libsword.bpr	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/lib/bcppmake/libsword.bpr	2020-07-25 12:10:46 UTC (rev 3760)
@@ -146,7 +146,7 @@
     <PATHRC value=".;"/>
     <PATHASM value=".;"/>
     <LINKER value="TLib"/>
-    <USERDEFINES value="UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;EXCLUDEXZ;EXCLUDEBZIP2"/>
+    <USERDEFINES value="UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;EXCLUDEXZ;EXCLUDEBZIP2;_DEBUG"/>
     <SYSDEFINES value="NO_STRICT"/>
     <MAINSOURCE value="libsword.bpf"/>
     <INCLUDEPATH value="..\..\src\modules\comments\zcom4;..\..\src\modules\texts\ztext4;..\..\src\modules\comments\rawcom4;..\..\src\modules\texts\rawtext4;..\..\src\modules\tests;..\..\src\utilfuns\zlib;..\..\src\modules\lexdict\zld;..\..\src\modules\lexdict\rawld4;..\..\src\modules\comments\zcom;..\..\src\modules\genbook\rawgenbook;..\..\src\modules\genbook;..\..\src\modules\texts\ztext;..\..\src\modules\texts\rawtext;..\..\src\modules\texts;..\..\src\modules\lexdict\rawld;..\..\src\modules\lexdict;..\..\src\modules\filters;..\..\src\modules\common;..\..\src\modules\comments\rawfiles;..\..\src\modules\comments\rawcom;..\..\src\modules\comments\hrefcom;..\..\src\modules\comments;..\..\src\modules;..\..\src\frontend;..\..\src\utilfuns;..\..\src\mgr;..\..\src\keys;..\..\..\icu-sword\source\common;..\..\apps\windoze\CBuilder5\InstallMgr\curl\include;..\..\include;..\..\include\internal\regex;$(BCB)\include;$(BCB)\include\vcl;..\..\..\icu-sword\source\i18n;..\..\..\biblecs\clucene\src;..\..\..\biblecs\apps\InstallMgr\curl\include"/>
@@ -174,9 +174,9 @@
       -D_ICU_ -D_ICUSWORD_ -DUSBINARY -DU_HAVE_PLACEMENT_NEW=0 -DUSELUCENE 
       -D_WIN32 -D_CL_DISABLE_MULTITHREADING -DCURLAVAILABLE 
       -DLUCENE_ENABLE_REFCOUNT -no_tie -boa"/>
-    <CFLAG1 value="-O2 -Vx -X- -a8 -4 -b- -k- -vi -c -tW -tWM"/>
-    <PFLAGS value="-$Y- -$L- -$D- -v -JPHNE -M"/>
-    <AFLAGS value="/mx /w2 /zn"/>
+    <CFLAG1 value="-Od -Vx -X- -r- -a8 -4 -b- -k -y -v -vi- -c -tW -tWM"/>
+    <PFLAGS value="-$Y+ -$W -$O- -v -JPHNE -M"/>
+    <AFLAGS value="/mx /w2 /zi"/>
     <LFLAGS value="/P1024"/>
   </OPTIONS>
   <LINKER>
@@ -254,33 +254,34 @@
 Item0=$(BCB)\source\vcl
 
 [HistoryLists\hlConditionals]
-Count=26
-Item0=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;EXCLUDEXZ;EXCLUDEBZIP2
-Item1=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT
-Item2=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;_DEBUG
-Item3=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE
-Item4=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
-Item5=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;_DEBUG
-Item6=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
-Item7=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;UNICODE
-Item8=_UCS2;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
-Item9=_ASCII;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
-Item10=__ASCII;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
-Item11=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT
-Item12=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT;_DEBUG
-Item13=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT
-Item14=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG;USELUCENE
-Item15=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG
-Item16=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0
-Item17=_ICU_;_ICUSWORD_;USBINARY;_DEBUG;U_HAVE_PLACEMENT_NEW=0
-Item18=_ICU_;_ICUSWORD_;USBINARY;_DEBUG
-Item19=_ICU_;_ICUSWORD_;USBINARY
-Item20=_ICU_;_ICUSWORD_;USBINARY;CURLAVAILABLE;_DEBUG
-Item21=_ICU_;_ICUSWORD_;USBINARY;CURLAVAILABLE
-Item22=;USBINARY;_DEBUG
-Item23=_ICU_;_ICUSWORD_
-Item24=_ICU_;_ICUSWORD_;_DEBUG
-Item25=_DEBUG
+Count=27
+Item0=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;EXCLUDEXZ;EXCLUDEBZIP2;_DEBUG
+Item1=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;EXCLUDEXZ;EXCLUDEBZIP2
+Item2=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT
+Item3=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE;LUCENE_ENABLE_REFCOUNT;_DEBUG
+Item4=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;CURLAVAILABLE
+Item5=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
+Item6=UNICODE;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;_DEBUG
+Item7=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
+Item8=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING;UNICODE
+Item9=_UCS2;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
+Item10=_ASCII;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
+Item11=__ASCII;_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;_WIN32;_CL_DISABLE_MULTITHREADING
+Item12=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT
+Item13=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT;_DEBUG
+Item14=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG;USELUCENE;LUCENE_DISABLE_MULTITHREADING;_WIN32;HAVE_DIRENT
+Item15=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG;USELUCENE
+Item16=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0;_DEBUG
+Item17=_ICU_;_ICUSWORD_;USBINARY;U_HAVE_PLACEMENT_NEW=0
+Item18=_ICU_;_ICUSWORD_;USBINARY;_DEBUG;U_HAVE_PLACEMENT_NEW=0
+Item19=_ICU_;_ICUSWORD_;USBINARY;_DEBUG
+Item20=_ICU_;_ICUSWORD_;USBINARY
+Item21=_ICU_;_ICUSWORD_;USBINARY;CURLAVAILABLE;_DEBUG
+Item22=_ICU_;_ICUSWORD_;USBINARY;CURLAVAILABLE
+Item23=;USBINARY;_DEBUG
+Item24=_ICU_;_ICUSWORD_
+Item25=_ICU_;_ICUSWORD_;_DEBUG
+Item26=_DEBUG
 
 [HistoryLists\hlFinalOutputDir]
 Count=3

Modified: trunk/src/mgr/curlftpt.cpp
===================================================================
--- trunk/src/mgr/curlftpt.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/mgr/curlftpt.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -22,7 +22,7 @@
 
 #include <curlftpt.h>
 
-#include <fcntl.h>
+#include <filemgr.h>
 
 #include <curl/curl.h>
 #include <curl/easy.h>
@@ -36,7 +36,7 @@
 
 	struct FtpFile {
 		const char *filename;
-		FILE *stream;
+		FileDesc *stream;
 		SWBuf *destBuf;
 	};
 
@@ -58,8 +58,8 @@
 		struct FtpFile *out=(struct FtpFile *)stream;
 		if (out && !out->stream && !out->destBuf) {
 			/* open file for writing */
-			out->stream=fopen(out->filename, "wb");
-			if (!out->stream)
+			out->stream=FileMgr::getSystemFileMgr()->open(out->filename, FileMgr::CREAT|FileMgr::WRONLY);
+			if (!out->stream || out->stream->getFd() < 0)
 				return -1; /* failure, can't open file to write */
 		}
 		if (out->destBuf) {
@@ -68,7 +68,7 @@
 			memcpy(out->destBuf->getRawData()+s, buffer, size*nmemb);
 			return (int)nmemb;
 		}
-		return (int)fwrite(buffer, size, nmemb, out->stream);
+		return (int)out->stream->write(buffer, size *nmemb);
 	}
 
 
@@ -162,7 +162,7 @@
 		/* Switch on full protocol/debug output */
 		curl_easy_setopt(session, CURLOPT_VERBOSE, true);
 		curl_easy_setopt(session, CURLOPT_CONNECTTIMEOUT, 45);
-		
+
 		/* FTP connection settings */
 
 #if (LIBCURL_VERSION_MAJOR > 7) || \
@@ -176,7 +176,7 @@
 		SWLog::getSystemLog()->logDebug("***** using CURLOPT_FTP_USE_EPRT\n");
 #endif
 
-		
+
 		SWLog::getSystemLog()->logDebug("***** About to perform curl easy action. \n");
 		SWLog::getSystemLog()->logDebug("***** destPath: %s \n", destPath);
 		SWLog::getSystemLog()->logDebug("***** sourceURL: %s \n", sourceURL);
@@ -192,7 +192,7 @@
 	}
 
 	if (ftpfile.stream)
-		fclose(ftpfile.stream); /* close the local file */
+		FileMgr::getSystemFileMgr()->close(ftpfile.stream); /* close the local file */
 
 	return retVal;
 }

Modified: trunk/src/mgr/curlhttpt.cpp
===================================================================
--- trunk/src/mgr/curlhttpt.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/mgr/curlhttpt.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -20,8 +20,6 @@
  *
  */
 
-#include <fcntl.h>
-
 #include <vector>
 #include <cctype>
 
@@ -41,7 +39,7 @@
 
 	struct FtpFile {
 		const char *filename;
-		FILE *stream;
+		FileDesc *stream;
 		SWBuf *destBuf;
 	};
 
@@ -50,8 +48,8 @@
 		struct FtpFile *out=(struct FtpFile *)stream;
 		if (out && !out->stream && !out->destBuf) {
 			/* open file for writing */
-			out->stream=fopen(out->filename, "wb");
-			if (!out->stream)
+			out->stream=FileMgr::getSystemFileMgr()->open(out->filename, FileMgr::CREAT|FileMgr::WRONLY);
+			if (!out->stream || out->stream->getFd() < 0)
 				return -1; /* failure, can't open file to write */
 		}
 		if (out->destBuf) {
@@ -60,7 +58,7 @@
 			memcpy(out->destBuf->getRawData()+s, buffer, size*nmemb);
 			return (int)nmemb;
 		}
-		return (int)fwrite(buffer, size, nmemb, out->stream);
+		return (int)out->stream->write(buffer, size *nmemb);
 	}
 
 
@@ -171,7 +169,7 @@
 	}
 
 	if (ftpfile.stream)
-		fclose(ftpfile.stream); /* close the local file */
+		FileMgr::getSystemFileMgr()->close(ftpfile.stream); /* close the local file */
 
 	return retVal;
 }

Modified: trunk/src/mgr/filemgr.cpp
===================================================================
--- trunk/src/mgr/filemgr.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/mgr/filemgr.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -125,8 +125,8 @@
 
 FileDesc::~FileDesc() {
 	if (fd > 0)
-		close(fd);
-		
+		::close(fd);
+
 	if (path)
 		delete [] path;
 }
@@ -155,7 +155,7 @@
 
 FileMgr::~FileMgr() {
 	FileDesc *tmp;
-	
+
 	while(files) {
 		tmp = files->next;
 		delete files;
@@ -171,7 +171,7 @@
 
 FileDesc *FileMgr::open(const char *path, int mode, int perms, bool tryDowngrade) {
 	FileDesc **tmp, *tmp2;
-	
+
 	for (tmp = &files; *tmp; tmp = &((*tmp)->next)) {
 		if ((*tmp)->fd < 0)		// insert as first non-system_open file
 			break;
@@ -180,14 +180,14 @@
 	tmp2 = new FileDesc(this, path, mode, perms, tryDowngrade);
 	tmp2->next = *tmp;
 	*tmp = tmp2;
-	
+
 	return tmp2;
 }
 
 
 void FileMgr::close(FileDesc *file) {
 	FileDesc **loop;
-	
+
 	for (loop = &files; *loop; loop = &((*loop)->next)) {
 		if (*loop == file) {
 			*loop = (*loop)->next;
@@ -201,7 +201,7 @@
 int FileMgr::sysOpen(FileDesc *file) {
 	FileDesc **loop;
 	int openCount = 1;		// because we are presently opening 1 file, and we need to be sure to close files to accomodate, if necessary
-	
+
 	for (loop = &files; *loop; loop = &((*loop)->next)) {
 
 		if ((*loop)->fd > 0) {
@@ -218,15 +218,14 @@
 				file->next = files;
 				files = file;
 			}
-			if ((!access(file->path, 04)) || ((file->mode & O_CREAT) == O_CREAT)) {	// check for at least file exists / read access before we try to open
+			if ((hasAccess(file->path, 04)) || ((file->mode & O_CREAT) == O_CREAT)) {	// check for at least file exists / read access before we try to open
 				char tries = (((file->mode & O_RDWR) == O_RDWR) && (file->tryDowngrade)) ? 2 : 1;  // try read/write if possible
 				for (int i = 0; i < tries; i++) {
 					if (i > 0) {
 						file->mode = (file->mode & ~O_RDWR);	// remove write access
 						file->mode = (file->mode | O_RDONLY);// add read access
 					}
-					file->fd = ::open(file->path, file->mode|O_BINARY, file->perms);
-
+					file->fd = openFile(file->path, file->mode|O_BINARY, file->perms);
 					if (file->fd >= 0)
 						break;
 				}
@@ -268,32 +267,32 @@
 		if (i == 9999)
 			return -2;
 
-		int fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
-		if (fd < 0)
+          FileDesc *fd = open(buf, CREAT|RDWR);
+		if (!fd || fd->getFd() < 0)
 			return -3;
-	
+
 		file->seek(0, SEEK_SET);
-		while (size > 0) {	 
+		while (size > 0) {
 			bytes = (int)file->read(nibble, 32767);
 			bytes = (bytes < size)?bytes:(int)size;
-			if (write(fd, nibble, bytes) != bytes) { break; }
+			if (fd->write(nibble, bytes) != bytes) { break; }
 			size -= bytes;
 		}
 		if (size < 1) {
 			// zero out the file
 			::close(file->fd);
-			file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
+			file->fd = openFile(file->path, O_TRUNC, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
 			::close(file->fd);
 			file->fd = -77;	// force file open by filemgr
 			// copy tmp file back (dumb, but must preserve file permissions)
-			lseek(fd, 0, SEEK_SET);
+			fd->seek(0, SEEK_SET);
 			do {
-				bytes = (int)read(fd, nibble, 32767);
+				bytes = fd->read(nibble, 32767);
 				file->write(nibble, bytes);
 			} while (bytes == 32767);
 		}
-		
-		::close(fd);
+
+		close(fd);
 		::close(file->fd);
 		removeFile(buf);		// remove our tmp file
 		file->fd = -77;	// causes file to be swapped out forcing open on next call to getFd()
@@ -306,21 +305,42 @@
 }
 
 
+SWBuf FileMgr::getEnvValue(const char *variableName) {
+	return
+#ifdef WIN32
+		wcharToUTF8(_wgetenv((const wchar_t *)utf8ToWChar(variableName).getRawData()));
+#else
+		getenv(variableName);
+#endif
+
+}
+
+
+bool FileMgr::hasAccess(const char *path, int mode) {
+	return
+#ifdef WIN32
+		!_waccess((const wchar_t *)utf8ToWChar(path).getRawData(), 04);
+#else
+		!access(path, 04);
+#endif
+}
+
+
 signed char FileMgr::existsFile(const char *ipath, const char *ifileName)
 {
 	int len = (int)strlen(ipath) + ((ifileName)?strlen(ifileName):0) + 3;
 	char *ch;
 	char *path = new char [ len ];
 	strcpy(path, ipath);
-	
+
 	if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
 		path[strlen(path)-1] = 0;
-	
+
 	if (ifileName) {
 		ch = path + strlen(path);
 		sprintf(ch, "/%s", ifileName);
 	}
-	signed char retVal = !access(path, 04);
+	signed char retVal = hasAccess(path, 04) ? 1 : 0;
 	delete [] path;
 	return retVal;
 }
@@ -334,24 +354,68 @@
 		len +=  strlen(idirName);
 	char *path = new char [ len ];
 	strcpy(path, ipath);
-	
+
 	if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
 		path[strlen(path)-1] = 0;
-	
+
 	if (idirName) {
 		ch = path + strlen(path);
 		sprintf(ch, "/%s", idirName);
 	}
-	signed char retVal = !access(path, 04);
+	signed char retVal = hasAccess(path, 04) ? 1 : 0;
 	delete [] path;
 	return retVal;
 }
 
 
+std::vector<struct DirEntry> FileMgr::getDirList(const char *dirPath, bool includeSize, bool includeIsDirectory) {
+	std::vector<struct DirEntry> dirList;
+	SWBuf basePath = dirPath;
+	if (!basePath.endsWith("/") && !basePath.endsWith("\\")) basePath += "/";
+
+#ifndef WIN32
+	DIR *dir;
+	struct dirent *ent;
+	if ((dir = opendir(dirPath))) {
+		rewinddir(dir);
+		while ((ent = readdir(dir))) {
+			if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
+				struct DirEntry i;
+				i.name = ent->d_name;
+				if (includeIsDirectory || includeSize) i.isDirectory = FileMgr::isDirectory(basePath + ent->d_name);
+				if (!i.isDirectory && includeSize) i.size = FileMgr::getFileSize(basePath + ent->d_name);
+				dirList.push_back(i);
+			}
+		}
+		closedir(dir);
+	}
+
+#else
+	// Crappy Windows-specific code because well... They can't be conformant
+	WIN32_FIND_DATAW fileData;
+     SWBuf wcharBuf = utf8ToWChar(basePath+"*");
+     const wchar_t *wcharPath = (const wchar_t *)wcharBuf.getRawData();
+	HANDLE findIterator = FindFirstFileW(wcharPath, &fileData);
+	if (findIterator != INVALID_HANDLE_VALUE) {
+		do {
+			struct DirEntry i;
+			i.name = wcharToUTF8(fileData.cFileName);
+			i.isDirectory = fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+			i.size = FileMgr::getFileSize(basePath + i.name);
+			dirList.push_back(i);
+		} while (FindNextFile(findIterator, &fileData) != 0);
+		FindClose(findIterator);
+	}
+#endif
+
+	return dirList;
+}
+
+
 int FileMgr::createParent(const char *pName) {
 	char *buf = new char [ strlen(pName) + 1 ];
 	int retCode = 0;
-	
+
 	strcpy(buf, pName);
 	int end = (int)strlen(buf) - 1;
 	while (end) {
@@ -361,18 +425,21 @@
 	}
 	buf[end] = 0;
 	if (strlen(buf)>0) {
-		if (access(buf, 02)) {  // not exists with write access?
-			if ((retCode = mkdir(buf
+		if (!hasAccess(buf, 02)) {  // not exists with write access?
+			retCode =
 #ifndef WIN32
-					, 0755
+				mkdir(buf, 0755);
+#else
+				_wmkdir((const wchar_t *)utf8ToWChar(buf).getRawData());
 #endif
-					))) {
+			if (retCode) {
 				createParent(buf);
-				retCode = mkdir(buf
+				retCode =
 #ifndef WIN32
-					, 0755
+					mkdir(buf, 0755);
+#else
+					_wmkdir((const wchar_t *)utf8ToWChar(buf).getRawData());
 #endif
-					);
 			}
 		}
 	}
@@ -380,21 +447,31 @@
 	delete [] buf;
 	return retCode;
 }
-	
 
-int FileMgr::openFileReadOnly(const char *fName) {
-	int fd = ::open(fName, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
+
+int FileMgr::openFile(const char *fName, int mode, int perms) {
+	int fd =
+#ifndef WIN32
+	     ::open(fName, mode, perms);
+#else
+		::_wopen((const wchar_t *)utf8ToWChar(fName).getRawData(), mode, perms);
+#endif
 	return fd;
 }
 
 
+int FileMgr::openFileReadOnly(const char *fName) {
+	return openFile(fName, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
+}
+
+
 int FileMgr::createPathAndFile(const char *fName) {
 	int fd;
-	
-	fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
+
+	fd = openFile(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
 	if (fd < 1) {
 		createParent(fName);
-		fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
+		fd = openFile(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
 	}
 	return fd;
 }
@@ -404,7 +481,7 @@
 	int sfd, dfd, len;
 	char buf[4096];
 
-	if ((sfd = ::open(sourceFile, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) < 1)
+	if ((sfd = openFile(sourceFile, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) < 1)
 		return -1;
 	if ((dfd = createPathAndFile(targetFile)) < 1)
 		return -1;
@@ -413,18 +490,24 @@
 		len = (int)read(sfd, buf, 4096);
 		if (write(dfd, buf, len) != len) break;
 	}
-	while(len == 4096);	
+	while(len == 4096);
 	::close(dfd);
 	::close(sfd);
-	
+
 	return 0;
 }
 
 
 int FileMgr::removeFile(const char *fName) {
-	return ::remove(fName);
+	return
+#ifndef WIN32
+     ::remove(fName);
+#else
+	::_wremove((const wchar_t *)utf8ToWChar(fName).getRawData());
+#endif
 }
 
+
 char FileMgr::getLine(FileDesc *fDesc, SWBuf &line) {
 	int len;
 	bool more = true;
@@ -457,7 +540,7 @@
 		// find the end
 		int end;
 		for (end = start; ((end < (len-1)) && (chunk[end] != 10)); end++);
-	
+
 		if ((chunk[end] != 10) && (len == 254)) {
 			more = true;
 		}
@@ -478,7 +561,7 @@
 				}
 			}
 		}
-		
+
 		int size = (end - start) + 1;
 
 		if (size > 0) {
@@ -491,69 +574,73 @@
 
 
 char FileMgr::isDirectory(const char *path) {
+#ifndef WIN32
 	struct stat stats;
-	if (stat(path, &stats))
-		return 0;
+	int error = stat(path, &stats);
+#else
+	struct _stat stats;
+	int error = _wstat((const wchar_t *)utf8ToWChar(path).getRawData(), &stats);
+#endif
+     if (error) return 0;
 	return ((stats.st_mode & S_IFDIR) == S_IFDIR);
 }
 
 
+long FileMgr::getFileSize(const char *path) {
+#ifndef WIN32
+	struct stat stats;
+	int error = stat(path, &stats);
+#else
+	struct _stat stats;
+	int error = _wstat((const wchar_t *)utf8ToWChar(path).getRawData(), &stats);
+#endif
+     if (error) return 0;
+	return stats.st_size;
+}
+
+
 int FileMgr::copyDir(const char *srcDir, const char *destDir) {
-	DIR *dir;
-	struct dirent *ent;
+	SWBuf baseSrcPath = srcDir;
+	if (!baseSrcPath.endsWith("/") && !baseSrcPath.endsWith("\\")) baseSrcPath += "/";
+	SWBuf baseDestPath = destDir;
+	if (!baseDestPath.endsWith("/") && !baseDestPath.endsWith("\\")) baseDestPath += "/";
 	int retVal = 0;
-	if ((dir = opendir(srcDir))) {
-		rewinddir(dir);
-		while ((ent = readdir(dir)) && !retVal) {
-			if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
-				SWBuf srcPath  = (SWBuf)srcDir  + (SWBuf)"/" + ent->d_name;
-				SWBuf destPath = (SWBuf)destDir + (SWBuf)"/" + ent->d_name;
-				if (!isDirectory(srcPath.c_str())) {
-					retVal = copyFile(srcPath.c_str(), destPath.c_str());
-				}
-				else {
-					retVal = copyDir(srcPath.c_str(), destPath.c_str());
-				}
-			}
+	std::vector<DirEntry> dirList = getDirList(srcDir);
+	for (unsigned int i = 0; i < dirList.size() && !retVal; ++i) {
+		SWBuf srcPath  = baseSrcPath  + dirList[i].name;
+		SWBuf destPath = baseDestPath + dirList[i].name;
+		if (!dirList[i].isDirectory) {
+			retVal = copyFile(srcPath.c_str(), destPath.c_str());
 		}
-		closedir(dir);
+		else {
+			retVal = copyDir(srcPath.c_str(), destPath.c_str());
+		}
 	}
 	return retVal;
 }
 
 
 int FileMgr::removeDir(const char *targetDir) {
-	DIR *dir = opendir(targetDir);
-	struct dirent *ent;
-	if (dir) {
-		rewinddir(dir);
-		while ((ent = readdir(dir))) {
-			if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
-				SWBuf targetPath = (SWBuf)targetDir + (SWBuf)"/" + ent->d_name;
-				if (!isDirectory(targetPath.c_str())) {
-					FileMgr::removeFile(targetPath.c_str());
-				}
-				else {
-					FileMgr::removeDir(targetPath.c_str());
-				}
-			}
+	SWBuf basePath = targetDir;
+	if (!basePath.endsWith("/") && !basePath.endsWith("\\")) basePath += "/";
+	std::vector<DirEntry> dirList = getDirList(targetDir);
+	for (unsigned int i = 0; i < dirList.size(); ++i) {
+		SWBuf targetPath = basePath + dirList[i].name;
+		if (!dirList[i].isDirectory) {
+			FileMgr::removeFile(targetPath.c_str());
 		}
-		closedir(dir);
-		FileMgr::removeFile(targetDir);
-/*
-		int status = FileMgr::removeFile(targetDir);
-          int stuff = errno;
-          char *err = strerror(errno);
-          int x = stuff;
-*/
+		else {
+			FileMgr::removeDir(targetPath.c_str());
+		}
 	}
+	FileMgr::removeFile(targetDir);
 	return 0;
 }
 
 
 void FileMgr::flush() {
 	FileDesc **loop;
-	
+
 	for (loop = &files; *loop; loop = &((*loop)->next)) {
 		if ((*loop)->fd > 0) {
 			(*loop)->offset = lseek((*loop)->fd, 0, SEEK_CUR);
@@ -578,10 +665,10 @@
 SWBuf FileMgr::getHomeDir() {
 
 	// figure out 'home' directory for app data
-	SWBuf homeDir = getenv("HOME");
+	SWBuf homeDir = getEnvValue("HOME");
 	if (!homeDir.length()) {
 		// silly windows
-		homeDir = getenv("APPDATA");
+		homeDir = getEnvValue("APPDATA");
 	}
 	if (homeDir.length()) {
 		if ((homeDir[homeDir.length()-1] != '\\') && (homeDir[homeDir.length()-1] != '/')) {
@@ -594,3 +681,5 @@
 
 
 SWORD_NAMESPACE_END
+
+

Modified: trunk/src/mgr/installmgr.cpp
===================================================================
--- trunk/src/mgr/installmgr.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/mgr/installmgr.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -273,30 +273,22 @@
 			}
 		}
 		else {	//remove all files in DataPath directory
-
-			DIR *dir;
-			struct dirent *ent;
 			ConfigEntMap::iterator entry;
-
 			FileMgr::removeDir(modDir.c_str());
-
-			if ((dir = opendir(manager->configPath))) {	// find and remove .conf file
-				rewinddir(dir);
-				while ((ent = readdir(dir))) {
-					if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
-						modFile = manager->configPath;
-						removeTrailingSlash(modFile);
-						modFile += "/";
-						modFile += ent->d_name;
-						SWConfig *config = new SWConfig(modFile.c_str());
-						if (config->getSections().find(modName) != config->getSections().end()) {
-							delete config;
-							FileMgr::removeFile(modFile.c_str());
-						}
-						else	delete config;
+			std::vector<DirEntry> dirList = FileMgr::getDirList(manager->configPath);
+			for (int i = 0; i < dirList.size(); ++i) {
+               	if (dirList[i].name.endsWith(".conf")) {
+					modFile = manager->configPath;
+					removeTrailingSlash(modFile);
+					modFile += "/";
+					modFile += dirList[i].name;
+					SWConfig *config = new SWConfig(modFile.c_str());
+					if (config->getSections().find(modName) != config->getSections().end()) {
+						delete config;
+						FileMgr::removeFile(modFile.c_str());
 					}
+					else	delete config;
 				}
-				closedir(dir);
 			}
 		}
 		return 0;
@@ -522,35 +514,32 @@
 		}
 		if (!aborted) {
 			SWBuf confDir = sourceDir + "mods.d/";
-			if ((dir = opendir(confDir.c_str()))) {	// find and copy .conf file
-				rewinddir(dir);
-				while ((ent = readdir(dir)) && !retVal) {
-					if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
-						modFile = confDir;
-						modFile += ent->d_name;
-						SWConfig *config = new SWConfig(modFile.c_str());
-						if (config->getSections().find(modName) != config->getSections().end()) {
-							SWBuf targetFile = destMgr->configPath; //"./mods.d/";
-							removeTrailingSlash(targetFile);
-							targetFile += "/";
-							targetFile += ent->d_name;
-							retVal = FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
-							if (cipher) {
-								if (getCipherCode(modName, config)) {
-									SWMgr newDest(destMgr->prefixPath);
-									removeModule(&newDest, modName);
-									aborted = true;
-								}
-								else {
-									config->save();
-									retVal = FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
-								}
+			std::vector<DirEntry> dirList = FileMgr::getDirList(confDir);
+               for (int i = 0; i < dirList.size() && !retVal; ++i) {
+               	if (dirList[i].name.endsWith(".conf")) {
+					modFile = confDir;
+					modFile += dirList[i].name;
+					SWConfig *config = new SWConfig(modFile);
+					if (config->getSections().find(modName) != config->getSections().end()) {
+						SWBuf targetFile = destMgr->configPath; //"./mods.d/";
+						removeTrailingSlash(targetFile);
+						targetFile += "/";
+						targetFile += dirList[i].name;
+						retVal = FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
+						if (cipher) {
+							if (getCipherCode(modName, config)) {
+								SWMgr newDest(destMgr->prefixPath);
+								removeModule(&newDest, modName);
+								aborted = true;
 							}
+							else {
+								config->save();
+								retVal = FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
+							}
 						}
-						delete config;
 					}
+					delete config;
 				}
-				closedir(dir);
 			}
 		}
 		return (aborted) ? -9 : retVal;

Modified: trunk/src/mgr/swmgr.cpp
===================================================================
--- trunk/src/mgr/swmgr.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/mgr/swmgr.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -144,7 +144,8 @@
 			}
 		}
 		if (logLevelString.length()) {
-			int logLevel =  logLevelString == "ERROR"     ? SWLog::LOG_ERROR:
+			int logLevel =
+					logLevelString == "ERROR"     ? SWLog::LOG_ERROR:
 					logLevelString == "WARN"      ? SWLog::LOG_WARN:
 					logLevelString == "INFO"      ? SWLog::LOG_INFO:
 					logLevelString == "TIMEDINFO" ? SWLog::LOG_TIMEDINFO:
@@ -451,7 +452,7 @@
 	ConfigEntMap::iterator lastEntry;
 
 	if (!setLogLevel) {
-		SWBuf envLogLevel = getenv("SWORD_LOGLEVEL");
+		SWBuf envLogLevel = FileMgr::getEnvValue("SWORD_LOGLEVEL");
 		if (envLogLevel.length()) {
 			setSystemLogLevel(0, envLogLevel);
 			setLogLevel = true;
@@ -524,7 +525,7 @@
 			// check environment variable SWORD_PATH
 			SWLog::getSystemLog()->logDebug("Checking $SWORD_PATH...");
 
-			SWBuf envsworddir = getenv("SWORD_PATH");
+			SWBuf envsworddir = FileMgr::getEnvValue("SWORD_PATH");
 			if (envsworddir.length()) {
 				
 				SWLog::getSystemLog()->logDebug("found (%s).", envsworddir.c_str());
@@ -657,7 +658,7 @@
 
 	SWLog::getSystemLog()->logDebug("Checking $ALLUSERSPROFILE/Application Data/sword/...");
 
-	SWBuf envallusersdir  = getenv("ALLUSERSPROFILE");
+	SWBuf envallusersdir = FileMgr::getEnvValue("ALLUSERSPROFILE");
 	if (envallusersdir.length()) {
 		SWLog::getSystemLog()->logDebug("found (%s).", envallusersdir.c_str());
 		path = envallusersdir;
@@ -743,45 +744,36 @@
 
 void SWMgr::loadConfigDir(const char *ipath)
 {
-	DIR *dir;
-	struct dirent *ent;
-	SWBuf newmodfile;
- 
-	if ((dir = opendir(ipath))) {
-		rewinddir(dir);
-		while ((ent = readdir(dir))) {
-			//check whether it ends with .conf, if it doesn't skip it!
-			if (!ent->d_name || (strlen(ent->d_name) <= 5) || strncmp(".conf", (ent->d_name + strlen(ent->d_name) - 5), 5 )) {
-				continue;
-			}
-			
-			newmodfile = ipath;
-			if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
-				newmodfile += "/";
-			newmodfile += ent->d_name;
-			if (config) {
-				SWConfig tmpConfig(newmodfile.c_str());
-				*config += tmpConfig;
-			}
-			else	config = myconfig = new SWConfig(newmodfile.c_str());
+	SWBuf basePath = ipath;
+	if (!basePath.endsWith("/") && !basePath.endsWith("\\")) basePath += "/";
+
+	SWBuf newModFile;
+
+	std::vector<DirEntry> dirList = FileMgr::getDirList(ipath);
+	for (int i = 0; i < dirList.size(); ++i) {
+		//check whether it ends with .conf, if it doesn't skip it!
+		if (!dirList[i].name.endsWith(".conf")) {
+			continue;
 		}
-		closedir(dir);
-		
-		if (!config) {	// if no .conf file exist yet, create a default
-			newmodfile = ipath;
-			if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
-				newmodfile += "/";
-			newmodfile += "globals.conf";
-			config = myconfig = new SWConfig(newmodfile.c_str());
+
+		newModFile = basePath + dirList[i].name;
+		if (config) {
+			SWConfig tmpConfig(newModFile);
+			config->augment(tmpConfig);
 		}
+		else	config = myconfig = new SWConfig(newModFile);
 	}
+
+	if (!config) {	// if no .conf file exist yet, create a default
+		newModFile = basePath + "globals.conf";
+		config = myconfig = new SWConfig(newModFile);
+	}
 }
 
 
 void SWMgr::augmentModules(const char *ipath, bool multiMod) {
 	SWBuf path = ipath;
-	if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
-		path += "/";
+	if (!path.endsWith("/") && !path.endsWith("\\")) path += "/";
 	if (FileMgr::existsDir(path.c_str(), "mods.d")) {
 		char *savePrefixPath = 0;
 		char *saveConfigPath = 0;
@@ -1051,20 +1043,20 @@
 		newmod = new HREFCom(datapath.c_str(), misc1.c_str(), name, description.c_str());
 	}
 
-        int pos = 0;  //used for position of final / in AbsoluteDataPath, but also set to 1 for modules types that need to strip module name
+	int pos = 0;  //used for position of final / in AbsoluteDataPath, but also set to 1 for modules types that need to strip module name
 	if (!stricmp(driver, "RawLD")) {
 		bool caseSensitive = ((entry = section.find("CaseSensitiveKeys")) != section.end()) ? (*entry).second == "true": false;
 		bool strongsPadding = ((entry = section.find("StrongsPadding")) != section.end()) ? (*entry).second == "true": true;
 		newmod = new RawLD(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), caseSensitive, strongsPadding);
-                pos = 1;
-        }
+		pos = 1;
+	}
 
 	if (!stricmp(driver, "RawLD4")) {
 		bool caseSensitive = ((entry = section.find("CaseSensitiveKeys")) != section.end()) ? (*entry).second == "true": false;
 		bool strongsPadding = ((entry = section.find("StrongsPadding")) != section.end()) ? (*entry).second == "true": true;
 		newmod = new RawLD4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), caseSensitive, strongsPadding);
-                pos = 1;
-        }
+		pos = 1;
+	}
 
 	if (!stricmp(driver, "zLD")) {
 		SWCompress *compress = 0;
@@ -1330,54 +1322,44 @@
 
 void SWMgr::InstallScan(const char *dirname)
 {
-   DIR *dir;
-   struct dirent *ent;
-   FileDesc *conffd = 0;
-   SWBuf newmodfile;
-   SWBuf targetName;
- 
-	if (FileMgr::existsDir(dirname)) {
-		if ((dir = opendir(dirname))) {
-			rewinddir(dir);
-			while ((ent = readdir(dir))) {
-				if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
-					newmodfile = dirname;
-					if ((dirname[strlen(dirname)-1] != '\\') && (dirname[strlen(dirname)-1] != '/'))
-						newmodfile += "/";
-					newmodfile += ent->d_name;
+	FileDesc *conffd = 0;
+	SWBuf newModFile;
+	SWBuf targetName;
+	SWBuf basePath = dirname;
+	if (!basePath.endsWith("/") && !basePath.endsWith("\\")) basePath += "/";
 
-					// mods.d
-					if (configType) {
-						if (conffd)
-							FileMgr::getSystemFileMgr()->close(conffd);
-						targetName = configPath;
-						if ((configPath[strlen(configPath)-1] != '\\') && (configPath[strlen(configPath)-1] != '/'))
-							targetName += "/";
-						targetName += ent->d_name;
-						conffd = FileMgr::getSystemFileMgr()->open(targetName.c_str(), FileMgr::WRONLY|FileMgr::CREAT, FileMgr::IREAD|FileMgr::IWRITE);
-					}
+	std::vector<DirEntry> dirList = FileMgr::getDirList(dirname);
+	for (int i = 0; i < dirList.size(); ++i) {
+		newModFile = basePath + dirList[i].name;
 
-					// mods.conf
-					else {
-						if (!conffd) {
-							conffd = FileMgr::getSystemFileMgr()->open(config->getFileName().c_str(), FileMgr::WRONLY|FileMgr::APPEND);
-							if (conffd && conffd->getFd() >= 0)
-								conffd->seek(0L, SEEK_END);
-							else {
-								FileMgr::getSystemFileMgr()->close(conffd);
-								conffd = 0;
-							}
-						}
-					}
-					addModToConfig(conffd, newmodfile.c_str());
-					FileMgr::removeFile(newmodfile.c_str());
-				}
-			}
+		// mods.d
+		if (configType) {
 			if (conffd)
 				FileMgr::getSystemFileMgr()->close(conffd);
-			closedir(dir);
+			targetName = configPath;
+			if ((configPath[strlen(configPath)-1] != '\\') && (configPath[strlen(configPath)-1] != '/'))
+				targetName += "/";
+			targetName += dirList[i].name;
+			conffd = FileMgr::getSystemFileMgr()->open(targetName.c_str(), FileMgr::WRONLY|FileMgr::CREAT, FileMgr::IREAD|FileMgr::IWRITE);
 		}
+
+		// mods.conf
+		else {
+			if (!conffd) {
+				conffd = FileMgr::getSystemFileMgr()->open(config->getFileName().c_str(), FileMgr::WRONLY|FileMgr::APPEND);
+				if (conffd && conffd->getFd() >= 0)
+					conffd->seek(0L, SEEK_END);
+				else {
+					FileMgr::getSystemFileMgr()->close(conffd);
+					conffd = 0;
+				}
+			}
+		}
+		addModToConfig(conffd, newModFile.c_str());
+		FileMgr::removeFile(newModFile.c_str());
 	}
+	if (conffd)
+		FileMgr::getSystemFileMgr()->close(conffd);
 }
 
 

Modified: trunk/src/utilfuns/utilstr.cpp
===================================================================
--- trunk/src/utilfuns/utilstr.cpp	2020-07-25 06:15:10 UTC (rev 3759)
+++ trunk/src/utilfuns/utilstr.cpp	2020-07-25 12:10:46 UTC (rev 3760)
@@ -263,8 +263,10 @@
 SWBuf wcharToUTF8(const wchar_t *buf) {
 
 	SWBuf utf8Buf;
-	while (*buf) {
-		getUTF8FromUniChar(*buf++, &utf8Buf);
+     if (buf) {
+		while (*buf) {
+			getUTF8FromUniChar(*buf++, &utf8Buf);
+		}
 	}
 	return utf8Buf;
 }



More information about the sword-cvs mailing list