3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
35 #include <sm_platform.h>
36 #include "sm_stringutil.h"
37 #include "LibrarySys.h"
39 LibrarySystem g_LibSys;
45 #if defined PLATFORM_WINDOWS
47 #elif defined PLATFORM_POSIX
54 CLibrary::CLibrary(LibraryHandle me)
59 void CLibrary::CloseLibrary()
64 void *CLibrary::GetSymbolAddress(const char *symname)
66 #if defined PLATFORM_WINDOWS
67 return GetProcAddress(m_lib, symname);
68 #elif defined PLATFORM_POSIX
69 return dlsym(m_lib, symname);
79 CDirectory::CDirectory(const char *path)
81 #if defined PLATFORM_WINDOWS
82 char newpath[PLATFORM_MAX_PATH];
83 snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
84 m_dir = FindFirstFileA(newpath, &m_fd);
87 m_fd.cFileName[0] = '\0';
89 #elif defined PLATFORM_POSIX
90 m_dir = opendir(path);
93 /* :TODO: we need to read past "." and ".."! */
95 snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
102 CDirectory::~CDirectory()
106 #if defined PLATFORM_WINDOWS
108 #elif defined PLATFORM_POSIX
114 void CDirectory::NextEntry()
116 #if defined PLATFORM_WINDOWS
117 if (FindNextFile(m_dir, &m_fd) == 0)
120 m_dir = INVALID_HANDLE_VALUE;
122 #elif defined PLATFORM_POSIX
123 if ((ep=readdir(m_dir)) == NULL)
131 bool CDirectory::IsEntryValid()
136 bool CDirectory::IsEntryDirectory()
138 #if defined PLATFORM_WINDOWS
139 return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
140 #elif defined PLATFORM_LINUX
141 char temppath[PLATFORM_MAX_PATH];
142 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
143 return g_LibSys.IsPathDirectory(temppath);
147 bool CDirectory::IsEntryFile()
149 #if defined PLATFORM_WINDOWS
150 return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
151 #elif defined PLATFORM_POSIX
152 char temppath[PLATFORM_MAX_PATH];
153 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
154 return g_LibSys.IsPathFile(temppath);
158 const char *CDirectory::GetEntryName()
160 #if defined PLATFORM_WINDOWS
161 return m_fd.cFileName;
162 #elif defined PLATFORM_LINUX
163 return ep ? ep->d_name : "";
167 bool CDirectory::MoreFiles()
172 bool CDirectory::IsValid()
174 #if defined PLATFORM_WINDOWS
175 return (m_dir != INVALID_HANDLE_VALUE);
176 #elif defined PLATFORM_LINUX
177 return (m_dir != NULL);
182 /*************************
183 ** Library System Code **
184 *************************/
187 bool LibrarySystem::PathExists(const char *path)
189 #if defined PLATFORM_WINDOWS
190 DWORD attr = GetFileAttributesA(path);
192 return (attr != INVALID_FILE_ATTRIBUTES);
193 #elif defined PLATFORM_POSIX
196 return (stat(path, &s) == 0);
200 bool LibrarySystem::IsPathFile(const char *path)
202 #if defined PLATFORM_WINDOWS
203 DWORD attr = GetFileAttributes(path);
205 if (attr == INVALID_FILE_ATTRIBUTES)
210 if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
216 #elif defined PLATFORM_LINUX
219 if (stat(path, &s) != 0)
224 return S_ISREG(s.st_mode) ? true : false;
228 bool LibrarySystem::IsPathDirectory(const char *path)
230 #if defined PLATFORM_WINDOWS
231 DWORD attr = GetFileAttributes(path);
233 if (attr == INVALID_FILE_ATTRIBUTES)
238 if (attr & FILE_ATTRIBUTE_DIRECTORY)
243 #elif defined PLATFORM_LINUX
246 if (stat(path, &s) != 0)
251 if (S_ISDIR(s.st_mode))
260 IDirectory *LibrarySystem::OpenDirectory(const char *path)
262 CDirectory *dir = new CDirectory(path);
273 void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
275 if (error && maxlength)
277 #if defined PLATFORM_WINDOWS
278 DWORD dw = GetLastError();
280 FORMAT_MESSAGE_FROM_SYSTEM,
283 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
287 #elif defined PLATFORM_POSIX
288 snprintf(error, maxlength, "%s", strerror(errno));
293 void LibrarySystem::CloseDirectory(IDirectory *dir)
298 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
301 #if defined PLATFORM_WINDOWS
302 lib = LoadLibraryA(path);
305 GetPlatformError(error, maxlength);
308 #elif defined PLATFORM_POSIX
309 lib = dlopen(path, RTLD_NOW);
312 GetPlatformError(error, maxlength);
317 return new CLibrary(lib);
320 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
324 size_t mylen = vsnprintf(buffer, len, fmt, ap);
330 buffer[mylen] = '\0';
333 for (size_t i=0; i<mylen; i++)
335 if (buffer[i] == PLATFORM_SEP_ALTCHAR)
337 buffer[i] = PLATFORM_SEP_CHAR;
344 const char *LibrarySystem::GetFileExtension(const char *filename)
346 size_t end = strlen(filename) - 1;
348 for (size_t i = end; i >= 0; i--)
355 if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
360 if (filename[i] == '.' && i != end)
362 return &filename[++i];
369 bool LibrarySystem::CreateFolder(const char *path)
371 #if defined PLATFORM_WINDOWS
372 return (mkdir(path) != -1);
373 #elif defined PLATFORM_POSIX
374 return (mkdir(path, 0775) != -1);
378 size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char *path)
380 size_t length = strlen(path);
382 for (size_t i = length - 1;
383 i >= 0 && i <= length - 1;
387 #if defined PLATFORM_WINDOWS
392 return UTIL_Format(buffer, maxlength, "%s", &path[i+1]);
396 /* We scanned and found no path separator */
397 return UTIL_Format(buffer, maxlength, "%s", path);