core/systems/LibrarySys.cpp
author Borja Ferrer <faluco@alliedmods.net>
Sun Jan 07 01:30:28 2007 +0000 (2007-01-07)
changeset 274 959c85596341
parent 252 ce166c465bad
child 317 e5342c8a0cf4
permissions -rw-r--r--
Added a bunch of new file natives.
Fixed possible corruption in snprintf when input buffer was bigger than output buffer and relaying on its retval.
Fixed all cases when the above situation happened.
Fixed _PrintToHL2Log not taking va_list in.
     1 #include <stdio.h>
     2 #include "LibrarySys.h"
     3 
     4 LibrarySystem g_LibSys;
     5 
     6 CLibrary::~CLibrary()
     7 {
     8 	if (m_lib)
     9 	{
    10 #if defined PLATFORM_WINDOWS
    11 		FreeLibrary(m_lib);
    12 #else if defined PLATFORM_POSIX
    13 		dlclose(m_lib);
    14 #endif
    15 		m_lib = NULL;
    16 	}
    17 }
    18 
    19 CLibrary::CLibrary(LibraryHandle me)
    20 {
    21 	m_lib = me;
    22 }
    23 
    24 void CLibrary::CloseLibrary()
    25 {
    26 	delete this;
    27 }
    28 
    29 void *CLibrary::GetSymbolAddress(const char *symname)
    30 {
    31 #if defined PLATFORM_WINDOWS
    32 	return GetProcAddress(m_lib, symname);
    33 #else if defined PLATFORM_POSIX
    34 	return dlsym(m_lib, symname);
    35 #endif
    36 }
    37 
    38 
    39 /********************
    40  ** Directory Code **
    41  ********************/
    42 
    43 
    44 CDirectory::CDirectory(const char *path)
    45 {
    46 #if defined PLATFORM_WINDOWS
    47 	char newpath[PLATFORM_MAX_PATH];
    48 	snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
    49 	m_dir = FindFirstFileA(newpath, &m_fd);
    50 	if (!IsValid())
    51 	{
    52 		m_fd.cFileName[0] = '\0';
    53 	}
    54 #else if defined PLATFORM_POSIX
    55 	m_dir = opendir(path);
    56 	if (IsValid())
    57 	{
    58 		/* :TODO: we need to read past "." and ".."! */
    59 		ep = readdir(dp);
    60 		snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
    61 	} else {
    62 		ep = NULL;
    63 	}
    64 #endif
    65 }
    66 
    67 CDirectory::~CDirectory()
    68 {
    69 	if (IsValid())
    70 	{
    71 #if defined PLATFORM_WINDOWS
    72 		FindClose(m_dir);
    73 #else if defined PLATFORM_POSIX
    74 		closedir(m_dir);
    75 #endif
    76 	}
    77 }
    78 
    79 void CDirectory::NextEntry()
    80 {
    81 #if defined PLATFORM_WINDOWS
    82 	if (FindNextFile(m_dir, &m_fd) == 0)
    83 	{
    84 		FindClose(m_dir);
    85 		m_dir = INVALID_HANDLE_VALUE;
    86 	}
    87 #else if defined PLATFORM_POSIX
    88 	if ((ep=readdir(m_dir) == NULL)
    89 	{
    90 		closedir(m_dir);
    91 		m_dir = NULL;
    92 	}
    93 #endif
    94 }
    95 
    96 bool CDirectory::IsEntryValid()
    97 {
    98 	return IsValid();
    99 }
   100 
   101 bool CDirectory::IsEntryDirectory()
   102 {
   103 #if defined PLATFORM_WINDOWS
   104 	return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
   105 #else if defined PLATFORM_LINUX
   106 	char temppath[PLATFORM_MAX_PATH];
   107 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   108 	return g_LibrarySys.IsPathDirectory(temppath);
   109 #endif
   110 }
   111 
   112 bool CDirectory::IsEntryFile()
   113 {
   114 #if defined PLATFORM_WINDOWS
   115 	return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
   116 #else if defined PLATFORM_POSIX
   117 	char temppath[PLATFORM_MAX_PATH];
   118 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   119 	return g_LibrarySys.IsPathFile(temppath);
   120 #endif
   121 }
   122 
   123 const char *CDirectory::GetEntryName()
   124 {
   125 #if defined PLATFORM_WINDOWS
   126 	return m_fd.cFileName;
   127 #else if defined PLATFORM_LINUX
   128 	return ep ? ep->d_name : "";
   129 #endif
   130 }
   131 
   132 bool CDirectory::MoreFiles()
   133 {
   134 	return IsValid();
   135 }
   136 
   137 bool CDirectory::IsValid()
   138 {
   139 #if defined PLATFORM_WINDOWS
   140 	return (m_dir != INVALID_HANDLE_VALUE);
   141 #else if defined PLATFORM_LINUX
   142 	return (m_dir != NULL);
   143 #endif
   144 }
   145 
   146 
   147 /*************************
   148  ** Library System Code **
   149  *************************/
   150 
   151 
   152 bool LibrarySystem::PathExists(const char *path)
   153 {
   154 #if defined PLATFORM_WINDOWS
   155 	DWORD attr = GetFileAttributesA(path);
   156 
   157 	return (attr != INVALID_FILE_ATTRIBUTES);
   158 #else if defined PLATFORM_POSIX
   159 	struct stat s;
   160 
   161 	return (stat(path, &s) == 0);
   162 #endif
   163 }
   164 
   165 bool LibrarySystem::IsPathFile(const char *path)
   166 {
   167 #if defined PLATFORM_WINDOWS
   168 	DWORD attr = GetFileAttributes(path);
   169 
   170 	if (attr == INVALID_FILE_ATTRIBUTES)
   171 	{
   172 		return false;
   173 	}
   174 
   175 	if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
   176 	{
   177 		return false;
   178 	}
   179 
   180 	return true;
   181 #else if defined PLATFORM_LINUX
   182 	struct stat s;
   183 
   184 	if (stat(path, &s) != 0)
   185 	{
   186 		return false;
   187 	}
   188 
   189 	return S_ISREG(s.st_mode) ? true : false;
   190 #endif
   191 }
   192 
   193 bool LibrarySystem::IsPathDirectory(const char *path)
   194 {
   195 #if defined PLATFORM_WINDOWS
   196 	DWORD attr = GetFileAttributes(path);
   197 
   198 	if (attr == INVALID_FILE_ATTRIBUTES)
   199 	{
   200 		return false;
   201 	}
   202 
   203 	if (attr & FILE_ATTRIBUTE_DIRECTORY)
   204 	{
   205 		return true;
   206 	}
   207 
   208 #else if defined PLATFORM_LINUX
   209 	struct stat s;
   210 
   211 	if (stat(path, &s) != 0)
   212 	{
   213 		return false;
   214 	}
   215 
   216 	if (S_ISDIR(s.st_mode))
   217 	{
   218 		return true;
   219 	}
   220 #endif
   221 
   222 	return false;
   223 }
   224 
   225 IDirectory *LibrarySystem::OpenDirectory(const char *path)
   226 {
   227 	CDirectory *dir = new CDirectory(path);
   228 
   229 	if (!dir->IsValid())
   230 	{
   231 		delete dir;
   232 		return NULL;
   233 	}
   234 
   235 	return dir;
   236 }
   237 
   238 void LibrarySystem::GetPlatformError(char *error, size_t err_max)
   239 {
   240 	if (error && err_max)
   241 	{
   242 #if defined PLATFORM_WINDOWS
   243 		DWORD dw = GetLastError();
   244 		FormatMessageA(
   245 			FORMAT_MESSAGE_FROM_SYSTEM,
   246 			NULL,
   247 			dw,
   248 			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   249 			(LPSTR)error,
   250 			err_max,
   251 			NULL);
   252 #else if defined PLATFORM_POSIX
   253 		snprintf(error, err_max, "%s", strerror(errno));
   254 #endif
   255 	}
   256 }
   257 
   258 void LibrarySystem::CloseDirectory(IDirectory *dir)
   259 {
   260 	delete dir;
   261 }
   262 
   263 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t err_max)
   264 {
   265 	LibraryHandle lib;
   266 #if defined PLATFORM_WINDOWS
   267 	lib = LoadLibraryA(path);
   268 	if (!lib)
   269 	{
   270 		GetPlatformError(error, err_max);
   271 		return false;
   272 	}
   273 #else if defined PLATFORM_POSIX
   274 	lib = dlopen(path, RTLD_NOW);
   275 	if (!lib)
   276 	{
   277 		GetPlatformError(error, err_max);
   278 		return false;
   279 	}
   280 #endif
   281 
   282 	return new CLibrary(lib);
   283 }
   284 
   285 void LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
   286 {
   287 	va_list ap;
   288 	va_start(ap,fmt);
   289 	size_t mylen = vsnprintf(buffer, len, fmt, ap);
   290 	va_end(ap);
   291 
   292 	mylen = (mylen >= len) ? (len - 1) : mylen;
   293 
   294 	for (size_t i=0; i<mylen; i++)
   295 	{
   296 		if (buffer[i] == PLATFORM_SEP_ALTCHAR)
   297 		{
   298 			buffer[i] = PLATFORM_SEP_CHAR;
   299 		}
   300 	}
   301 }