3 * ================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ================================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License,
10 * version 3.0, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to
21 * link the code of this program (as well as its derivative works) to
22 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
23 * Game MODs that run on software by the Valve Corporation. You must
24 * obey the GNU General Public License in all respects for all other
25 * code used. Additionally, AlliedModders LLC grants this exception
26 * to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version
28 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
36 #include <sm_platform.h>
37 #include "sm_stringutil.h"
38 #include "LibrarySys.h"
40 LibrarySystem g_LibSys;
46 #if defined PLATFORM_WINDOWS
48 #elif defined PLATFORM_POSIX
55 CLibrary::CLibrary(LibraryHandle me)
60 void CLibrary::CloseLibrary()
65 void *CLibrary::GetSymbolAddress(const char *symname)
67 #if defined PLATFORM_WINDOWS
68 return GetProcAddress(m_lib, symname);
69 #elif defined PLATFORM_POSIX
70 return dlsym(m_lib, symname);
80 CDirectory::CDirectory(const char *path)
82 #if defined PLATFORM_WINDOWS
83 char newpath[PLATFORM_MAX_PATH];
84 snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
85 m_dir = FindFirstFileA(newpath, &m_fd);
88 m_fd.cFileName[0] = '\0';
90 #elif defined PLATFORM_POSIX
91 m_dir = opendir(path);
94 /* :TODO: we need to read past "." and ".."! */
96 snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
103 CDirectory::~CDirectory()
107 #if defined PLATFORM_WINDOWS
109 #elif defined PLATFORM_POSIX
115 void CDirectory::NextEntry()
117 #if defined PLATFORM_WINDOWS
118 if (FindNextFile(m_dir, &m_fd) == 0)
121 m_dir = INVALID_HANDLE_VALUE;
123 #elif defined PLATFORM_POSIX
124 if ((ep=readdir(m_dir)) == NULL)
132 bool CDirectory::IsEntryValid()
137 bool CDirectory::IsEntryDirectory()
139 #if defined PLATFORM_WINDOWS
140 return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
141 #elif defined PLATFORM_LINUX
142 char temppath[PLATFORM_MAX_PATH];
143 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
144 return g_LibSys.IsPathDirectory(temppath);
148 bool CDirectory::IsEntryFile()
150 #if defined PLATFORM_WINDOWS
151 return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
152 #elif defined PLATFORM_POSIX
153 char temppath[PLATFORM_MAX_PATH];
154 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
155 return g_LibSys.IsPathFile(temppath);
159 const char *CDirectory::GetEntryName()
161 #if defined PLATFORM_WINDOWS
162 return m_fd.cFileName;
163 #elif defined PLATFORM_LINUX
164 return ep ? ep->d_name : "";
168 bool CDirectory::MoreFiles()
173 bool CDirectory::IsValid()
175 #if defined PLATFORM_WINDOWS
176 return (m_dir != INVALID_HANDLE_VALUE);
177 #elif defined PLATFORM_LINUX
178 return (m_dir != NULL);
183 /*************************
184 ** Library System Code **
185 *************************/
188 bool LibrarySystem::PathExists(const char *path)
190 #if defined PLATFORM_WINDOWS
191 DWORD attr = GetFileAttributesA(path);
193 return (attr != INVALID_FILE_ATTRIBUTES);
194 #elif defined PLATFORM_POSIX
197 return (stat(path, &s) == 0);
201 bool LibrarySystem::IsPathFile(const char *path)
203 #if defined PLATFORM_WINDOWS
204 DWORD attr = GetFileAttributes(path);
206 if (attr == INVALID_FILE_ATTRIBUTES)
211 if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
217 #elif defined PLATFORM_LINUX
220 if (stat(path, &s) != 0)
225 return S_ISREG(s.st_mode) ? true : false;
229 bool LibrarySystem::IsPathDirectory(const char *path)
231 #if defined PLATFORM_WINDOWS
232 DWORD attr = GetFileAttributes(path);
234 if (attr == INVALID_FILE_ATTRIBUTES)
239 if (attr & FILE_ATTRIBUTE_DIRECTORY)
244 #elif defined PLATFORM_LINUX
247 if (stat(path, &s) != 0)
252 if (S_ISDIR(s.st_mode))
261 IDirectory *LibrarySystem::OpenDirectory(const char *path)
263 CDirectory *dir = new CDirectory(path);
274 void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
276 if (error && maxlength)
278 #if defined PLATFORM_WINDOWS
279 DWORD dw = GetLastError();
281 FORMAT_MESSAGE_FROM_SYSTEM,
284 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
288 #elif defined PLATFORM_POSIX
289 snprintf(error, maxlength, "%s", strerror(errno));
294 void LibrarySystem::CloseDirectory(IDirectory *dir)
299 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
302 #if defined PLATFORM_WINDOWS
303 lib = LoadLibraryA(path);
306 GetPlatformError(error, maxlength);
309 #elif defined PLATFORM_POSIX
310 lib = dlopen(path, RTLD_NOW);
313 GetPlatformError(error, maxlength);
318 return new CLibrary(lib);
321 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
325 size_t mylen = vsnprintf(buffer, len, fmt, ap);
331 buffer[mylen] = '\0';
334 for (size_t i=0; i<mylen; i++)
336 if (buffer[i] == PLATFORM_SEP_ALTCHAR)
338 buffer[i] = PLATFORM_SEP_CHAR;
345 const char *LibrarySystem::GetFileExtension(const char *filename)
347 size_t end = strlen(filename) - 1;
349 for (size_t i = end; i >= 0; i--)
356 if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
361 if (filename[i] == '.' && i != end)
363 return &filename[++i];
370 bool LibrarySystem::CreateFolder(const char *path)
372 #if defined PLATFORM_WINDOWS
373 return (mkdir(path) != -1);
374 #elif defined PLATFORM_POSIX
375 return (mkdir(path, 0775) != -1);
379 size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char *path)
381 size_t length = strlen(path);
383 for (size_t i = length - 1;
384 i >= 0 && i <= length - 1;
388 #if defined PLATFORM_WINDOWS
393 return UTIL_Format(buffer, maxlength, "%s", &path[i+1]);
397 /* We scanned and found no path separator */
398 return UTIL_Format(buffer, maxlength, "%s", path);