3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
18 #include <sm_platform.h>
19 #include "sm_stringutil.h"
20 #include "LibrarySys.h"
22 LibrarySystem g_LibSys;
28 #if defined PLATFORM_WINDOWS
30 #elif defined PLATFORM_POSIX
37 CLibrary::CLibrary(LibraryHandle me)
42 void CLibrary::CloseLibrary()
47 void *CLibrary::GetSymbolAddress(const char *symname)
49 #if defined PLATFORM_WINDOWS
50 return GetProcAddress(m_lib, symname);
51 #elif defined PLATFORM_POSIX
52 return dlsym(m_lib, symname);
62 CDirectory::CDirectory(const char *path)
64 #if defined PLATFORM_WINDOWS
65 char newpath[PLATFORM_MAX_PATH];
66 snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
67 m_dir = FindFirstFileA(newpath, &m_fd);
70 m_fd.cFileName[0] = '\0';
72 #elif defined PLATFORM_POSIX
73 m_dir = opendir(path);
76 /* :TODO: we need to read past "." and ".."! */
78 snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
85 CDirectory::~CDirectory()
89 #if defined PLATFORM_WINDOWS
91 #elif defined PLATFORM_POSIX
97 void CDirectory::NextEntry()
99 #if defined PLATFORM_WINDOWS
100 if (FindNextFile(m_dir, &m_fd) == 0)
103 m_dir = INVALID_HANDLE_VALUE;
105 #elif defined PLATFORM_POSIX
106 if ((ep=readdir(m_dir)) == NULL)
114 bool CDirectory::IsEntryValid()
119 bool CDirectory::IsEntryDirectory()
121 #if defined PLATFORM_WINDOWS
122 return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
123 #elif defined PLATFORM_LINUX
124 char temppath[PLATFORM_MAX_PATH];
125 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
126 return g_LibSys.IsPathDirectory(temppath);
130 bool CDirectory::IsEntryFile()
132 #if defined PLATFORM_WINDOWS
133 return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
134 #elif defined PLATFORM_POSIX
135 char temppath[PLATFORM_MAX_PATH];
136 snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
137 return g_LibSys.IsPathFile(temppath);
141 const char *CDirectory::GetEntryName()
143 #if defined PLATFORM_WINDOWS
144 return m_fd.cFileName;
145 #elif defined PLATFORM_LINUX
146 return ep ? ep->d_name : "";
150 bool CDirectory::MoreFiles()
155 bool CDirectory::IsValid()
157 #if defined PLATFORM_WINDOWS
158 return (m_dir != INVALID_HANDLE_VALUE);
159 #elif defined PLATFORM_LINUX
160 return (m_dir != NULL);
165 /*************************
166 ** Library System Code **
167 *************************/
170 bool LibrarySystem::PathExists(const char *path)
172 #if defined PLATFORM_WINDOWS
173 DWORD attr = GetFileAttributesA(path);
175 return (attr != INVALID_FILE_ATTRIBUTES);
176 #elif defined PLATFORM_POSIX
179 return (stat(path, &s) == 0);
183 bool LibrarySystem::IsPathFile(const char *path)
185 #if defined PLATFORM_WINDOWS
186 DWORD attr = GetFileAttributes(path);
188 if (attr == INVALID_FILE_ATTRIBUTES)
193 if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
199 #elif defined PLATFORM_LINUX
202 if (stat(path, &s) != 0)
207 return S_ISREG(s.st_mode) ? true : false;
211 bool LibrarySystem::IsPathDirectory(const char *path)
213 #if defined PLATFORM_WINDOWS
214 DWORD attr = GetFileAttributes(path);
216 if (attr == INVALID_FILE_ATTRIBUTES)
221 if (attr & FILE_ATTRIBUTE_DIRECTORY)
226 #elif defined PLATFORM_LINUX
229 if (stat(path, &s) != 0)
234 if (S_ISDIR(s.st_mode))
243 IDirectory *LibrarySystem::OpenDirectory(const char *path)
245 CDirectory *dir = new CDirectory(path);
256 void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
258 if (error && maxlength)
260 #if defined PLATFORM_WINDOWS
261 DWORD dw = GetLastError();
263 FORMAT_MESSAGE_FROM_SYSTEM,
266 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
270 #elif defined PLATFORM_POSIX
271 snprintf(error, maxlength, "%s", strerror(errno));
276 void LibrarySystem::CloseDirectory(IDirectory *dir)
281 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
284 #if defined PLATFORM_WINDOWS
285 lib = LoadLibraryA(path);
288 GetPlatformError(error, maxlength);
291 #elif defined PLATFORM_POSIX
292 lib = dlopen(path, RTLD_NOW);
295 GetPlatformError(error, maxlength);
300 return new CLibrary(lib);
303 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
307 size_t mylen = vsnprintf(buffer, len, fmt, ap);
313 buffer[mylen] = '\0';
316 for (size_t i=0; i<mylen; i++)
318 if (buffer[i] == PLATFORM_SEP_ALTCHAR)
320 buffer[i] = PLATFORM_SEP_CHAR;
327 const char *LibrarySystem::GetFileExtension(const char *filename)
329 size_t end = strlen(filename) - 1;
331 for (size_t i = end; i >= 0; i--)
338 if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
343 if (filename[i] == '.' && i != end)
345 return &filename[++i];
352 bool LibrarySystem::CreateDirectory(const char *path)
354 #if defined PLATFORM_WINDOWS
355 return (mkdir(path) != -1);
356 #elif defined PLATFORM_POSIX
357 return (mkdir(path, 0775) != -1);
361 size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char *path)
363 size_t length = strlen(path);
365 for (size_t i = length - 1;
366 i >= 0 && i <= length - 1;
370 #if defined PLATFORM_WINDOWS
375 return UTIL_Format(buffer, maxlength, "%s", &path[i+1]);
379 /* We scanned and found no path separator */
380 return UTIL_Format(buffer, maxlength, "%s", path);