diff -r 2e74a46e872e -r 8dfaa3d730b5 core/LibrarySys.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/LibrarySys.cpp Sun Nov 16 16:06:18 2008 -0800
@@ -0,0 +1,441 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "sm_stringutil.h"
+#include "LibrarySys.h"
+
+LibrarySystem g_LibSys;
+
+CLibrary::~CLibrary()
+{
+ if (m_lib)
+ {
+#if defined PLATFORM_WINDOWS
+ FreeLibrary(m_lib);
+#elif defined PLATFORM_POSIX
+ dlclose(m_lib);
+#endif
+ m_lib = NULL;
+ }
+}
+
+CLibrary::CLibrary(LibraryHandle me)
+{
+ m_lib = me;
+}
+
+void CLibrary::CloseLibrary()
+{
+ delete this;
+}
+
+void *CLibrary::GetSymbolAddress(const char *symname)
+{
+#if defined PLATFORM_WINDOWS
+ return GetProcAddress(m_lib, symname);
+#elif defined PLATFORM_POSIX
+ return dlsym(m_lib, symname);
+#endif
+}
+
+
+/********************
+ ** Directory Code **
+ ********************/
+
+
+CDirectory::CDirectory(const char *path)
+{
+#if defined PLATFORM_WINDOWS
+ char newpath[PLATFORM_MAX_PATH];
+ snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
+ m_dir = FindFirstFileA(newpath, &m_fd);
+ if (!IsValid())
+ {
+ m_fd.cFileName[0] = '\0';
+ }
+#elif defined PLATFORM_POSIX
+ m_dir = opendir(path);
+ if (IsValid())
+ {
+ /* :TODO: we need to read past "." and ".."! */
+ ep = readdir(m_dir);
+ snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
+ } else {
+ ep = NULL;
+ }
+#endif
+}
+
+CDirectory::~CDirectory()
+{
+ if (IsValid())
+ {
+#if defined PLATFORM_WINDOWS
+ FindClose(m_dir);
+#elif defined PLATFORM_POSIX
+ closedir(m_dir);
+#endif
+ }
+}
+
+void CDirectory::NextEntry()
+{
+#if defined PLATFORM_WINDOWS
+ if (FindNextFile(m_dir, &m_fd) == 0)
+ {
+ FindClose(m_dir);
+ m_dir = INVALID_HANDLE_VALUE;
+ }
+#elif defined PLATFORM_POSIX
+ if ((ep=readdir(m_dir)) == NULL)
+ {
+ closedir(m_dir);
+ m_dir = NULL;
+ }
+#endif
+}
+
+bool CDirectory::IsEntryValid()
+{
+ return IsValid();
+}
+
+bool CDirectory::IsEntryDirectory()
+{
+#if defined PLATFORM_WINDOWS
+ return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
+#elif defined PLATFORM_LINUX
+ char temppath[PLATFORM_MAX_PATH];
+ snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
+ return g_LibSys.IsPathDirectory(temppath);
+#endif
+}
+
+bool CDirectory::IsEntryFile()
+{
+#if defined PLATFORM_WINDOWS
+ return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
+#elif defined PLATFORM_POSIX
+ char temppath[PLATFORM_MAX_PATH];
+ snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
+ return g_LibSys.IsPathFile(temppath);
+#endif
+}
+
+const char *CDirectory::GetEntryName()
+{
+#if defined PLATFORM_WINDOWS
+ return m_fd.cFileName;
+#elif defined PLATFORM_LINUX
+ return ep ? ep->d_name : "";
+#endif
+}
+
+bool CDirectory::MoreFiles()
+{
+ return IsValid();
+}
+
+bool CDirectory::IsValid()
+{
+#if defined PLATFORM_WINDOWS
+ return (m_dir != INVALID_HANDLE_VALUE);
+#elif defined PLATFORM_LINUX
+ return (m_dir != NULL);
+#endif
+}
+
+
+/*************************
+ ** Library System Code **
+ *************************/
+
+
+bool LibrarySystem::PathExists(const char *path)
+{
+#if defined PLATFORM_WINDOWS
+ DWORD attr = GetFileAttributesA(path);
+
+ return (attr != INVALID_FILE_ATTRIBUTES);
+#elif defined PLATFORM_POSIX
+ struct stat s;
+
+ return (stat(path, &s) == 0);
+#endif
+}
+
+bool LibrarySystem::IsPathFile(const char *path)
+{
+#if defined PLATFORM_WINDOWS
+ DWORD attr = GetFileAttributes(path);
+
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ {
+ return false;
+ }
+
+ if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
+ {
+ return false;
+ }
+
+ return true;
+#elif defined PLATFORM_LINUX
+ struct stat s;
+
+ if (stat(path, &s) != 0)
+ {
+ return false;
+ }
+
+ return S_ISREG(s.st_mode) ? true : false;
+#endif
+}
+
+bool LibrarySystem::IsPathDirectory(const char *path)
+{
+#if defined PLATFORM_WINDOWS
+ DWORD attr = GetFileAttributes(path);
+
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ {
+ return false;
+ }
+
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ return true;
+ }
+
+#elif defined PLATFORM_LINUX
+ struct stat s;
+
+ if (stat(path, &s) != 0)
+ {
+ return false;
+ }
+
+ if (S_ISDIR(s.st_mode))
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+IDirectory *LibrarySystem::OpenDirectory(const char *path)
+{
+ CDirectory *dir = new CDirectory(path);
+
+ if (!dir->IsValid())
+ {
+ delete dir;
+ return NULL;
+ }
+
+ return dir;
+}
+
+void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
+{
+ if (error && maxlength)
+ {
+#if defined PLATFORM_WINDOWS
+ DWORD dw = GetLastError();
+ FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)error,
+ maxlength,
+ NULL);
+#elif defined PLATFORM_POSIX
+ UTIL_Format(error, maxlength, "%s", strerror(errno));
+#endif
+ }
+}
+
+void LibrarySystem::GetLoaderError(char *buffer, size_t maxlength)
+{
+#if defined PLATFORM_WINDOWS
+ GetPlatformError(buffer, maxlength);
+#elif defined PLATFORM_POSIX
+ if (buffer != NULL && maxlength)
+ {
+ strncopy(buffer, dlerror(), maxlength);
+ }
+#endif
+}
+
+void LibrarySystem::CloseDirectory(IDirectory *dir)
+{
+ delete dir;
+}
+
+ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
+{
+ LibraryHandle lib;
+#if defined PLATFORM_WINDOWS
+ lib = LoadLibraryA(path);
+#elif defined PLATFORM_POSIX
+ lib = dlopen(path, RTLD_NOW);
+#endif
+
+ if (lib == NULL)
+ {
+ GetLoaderError(error, maxlength);
+ return NULL;
+ }
+
+ return new CLibrary(lib);
+}
+
+size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ size_t mylen = vsnprintf(buffer, len, fmt, ap);
+ va_end(ap);
+
+ if (mylen >= len)
+ {
+ mylen = len - 1;
+ buffer[mylen] = '\0';
+ }
+
+ for (size_t i=0; i= 0 && i <= length - 1;
+ i--)
+ {
+ if (path[i] == '/'
+#if defined PLATFORM_WINDOWS
+ || path[i] == '\\'
+#endif
+ )
+ {
+ return UTIL_Format(buffer, maxlength, "%s", &path[i+1]);
+ }
+ }
+
+ /* We scanned and found no path separator */
+ return UTIL_Format(buffer, maxlength, "%s", path);
+}
+
+bool LibrarySystem::FileTime(const char *path, FileTimeType type, time_t *pTime)
+{
+#ifdef PLATFORM_WINDOWS
+ struct _stat s;
+ if (_stat(path, &s) != 0)
+#elif defined PLATFORM_POSIX
+ struct stat s;
+ if (stat(path, &s) != 0)
+#endif
+ {
+ return false;
+ }
+
+ if (type == FileTime_LastAccess)
+ {
+ *pTime = s.st_atime;
+ }
+ else if (type == FileTime_Created)
+ {
+ *pTime = s.st_ctime;
+ }
+ else if (type == FileTime_LastChange)
+ {
+ *pTime = s.st_mtime;
+ }
+
+ return true;
+}