1.1 --- a/core/smn_filesystem.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,963 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <sys/stat.h>
1.36 -#include "sm_globals.h"
1.37 -#include "HandleSys.h"
1.38 -#include "LibrarySys.h"
1.39 -#include "sm_stringutil.h"
1.40 -#include "Logger.h"
1.41 -#include "PluginSys.h"
1.42 -#include "sourcemm_api.h"
1.43 -#include "ForwardSys.h"
1.44 -
1.45 -SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *);
1.46 -
1.47 -HandleType_t g_FileType;
1.48 -HandleType_t g_DirType;
1.49 -IChangeableForward *g_pLogHook = NULL;
1.50 -
1.51 -class FileNatives :
1.52 - public SMGlobalClass,
1.53 - public IHandleTypeDispatch,
1.54 - public IPluginsListener
1.55 -{
1.56 -public:
1.57 - FileNatives()
1.58 - {
1.59 - m_bIsLoggingHooked = false;
1.60 - }
1.61 - virtual void OnSourceModAllInitialized()
1.62 - {
1.63 - g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
1.64 - g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
1.65 - g_pLogHook = g_Forwards.CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String);
1.66 - g_PluginSys.AddPluginsListener(this);
1.67 - }
1.68 - virtual void OnSourceModShutdown()
1.69 - {
1.70 - g_PluginSys.RemovePluginsListener(this);
1.71 - if (m_bIsLoggingHooked)
1.72 - {
1.73 - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
1.74 - m_bIsLoggingHooked = false;
1.75 - }
1.76 - g_Forwards.ReleaseForward(g_pLogHook);
1.77 - g_HandleSys.RemoveType(g_DirType, g_pCoreIdent);
1.78 - g_HandleSys.RemoveType(g_FileType, g_pCoreIdent);
1.79 - g_DirType = 0;
1.80 - g_FileType = 0;
1.81 - }
1.82 - virtual void OnHandleDestroy(HandleType_t type, void *object)
1.83 - {
1.84 - if (type == g_FileType)
1.85 - {
1.86 - FILE *fp = (FILE *)object;
1.87 - fclose(fp);
1.88 - }
1.89 - else if (type == g_DirType)
1.90 - {
1.91 - IDirectory *pDir = (IDirectory *)object;
1.92 - g_LibSys.CloseDirectory(pDir);
1.93 - }
1.94 - }
1.95 - virtual void OnPluginDestroyed(IPlugin *plugin)
1.96 - {
1.97 - if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0)
1.98 - {
1.99 - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
1.100 - m_bIsLoggingHooked = false;
1.101 - }
1.102 - }
1.103 - virtual void AddLogHook(IPluginFunction *pFunc)
1.104 - {
1.105 - if (!m_bIsLoggingHooked)
1.106 - {
1.107 - SH_ADD_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
1.108 - m_bIsLoggingHooked = true;
1.109 - }
1.110 -
1.111 - g_pLogHook->AddFunction(pFunc);
1.112 - }
1.113 - virtual void RemoveLogHook(IPluginFunction *pFunc)
1.114 - {
1.115 - g_pLogHook->RemoveFunction(pFunc);
1.116 -
1.117 - if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0)
1.118 - {
1.119 - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
1.120 - m_bIsLoggingHooked = false;
1.121 - }
1.122 - }
1.123 - virtual void LogPrint(const char *msg)
1.124 - {
1.125 - cell_t result;
1.126 -
1.127 - result = 0;
1.128 -
1.129 - g_in_game_log_hook = true;
1.130 - g_pLogHook->PushString(msg);
1.131 - g_pLogHook->Execute(&result);
1.132 - g_in_game_log_hook = false;
1.133 -
1.134 - if (result >= Pl_Handled)
1.135 - {
1.136 - RETURN_META(MRES_SUPERCEDE);
1.137 - }
1.138 - }
1.139 -private:
1.140 - bool m_bIsLoggingHooked;
1.141 -} s_FileNatives;
1.142 -
1.143 -static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
1.144 -{
1.145 - char *path;
1.146 - int err;
1.147 - if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE)
1.148 - {
1.149 - pContext->ThrowNativeErrorEx(err, NULL);
1.150 - return 0;
1.151 - }
1.152 -
1.153 - char realpath[PLATFORM_MAX_PATH];
1.154 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
1.155 -
1.156 - IDirectory *pDir = g_LibSys.OpenDirectory(realpath);
1.157 - if (!pDir)
1.158 - {
1.159 - return 0;
1.160 - }
1.161 -
1.162 - return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.163 -}
1.164 -
1.165 -static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
1.166 -{
1.167 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.168 - IDirectory *pDir;
1.169 - HandleError herr;
1.170 - HandleSecurity sec;
1.171 - int err;
1.172 -
1.173 - sec.pOwner = NULL;
1.174 - sec.pIdentity = g_pCoreIdent;
1.175 -
1.176 - if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
1.177 - != HandleError_None)
1.178 - {
1.179 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.180 - }
1.181 -
1.182 - if (!pDir->MoreFiles())
1.183 - {
1.184 - return false;
1.185 - }
1.186 -
1.187 - cell_t *filetype;
1.188 - if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
1.189 - {
1.190 - pContext->ThrowNativeErrorEx(err, NULL);
1.191 - return 0;
1.192 - }
1.193 -
1.194 - if (pDir->IsEntryDirectory())
1.195 - {
1.196 - *filetype = 1;
1.197 - } else if (pDir->IsEntryFile()) {
1.198 - *filetype = 2;
1.199 - } else {
1.200 - *filetype = 0;
1.201 - }
1.202 -
1.203 - const char *path = pDir->GetEntryName();
1.204 - if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
1.205 - != SP_ERROR_NONE)
1.206 - {
1.207 - pContext->ThrowNativeErrorEx(err, NULL);
1.208 - return 0;
1.209 - }
1.210 -
1.211 - pDir->NextEntry();
1.212 -
1.213 - return true;
1.214 -}
1.215 -
1.216 -static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
1.217 -{
1.218 - char *name, *mode;
1.219 - int err;
1.220 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.221 - {
1.222 - pContext->ThrowNativeErrorEx(err, NULL);
1.223 - return 0;
1.224 - }
1.225 - if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE)
1.226 - {
1.227 - pContext->ThrowNativeErrorEx(err, NULL);
1.228 - return 0;
1.229 - }
1.230 -
1.231 - char realpath[PLATFORM_MAX_PATH];
1.232 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.233 -
1.234 - FILE *pFile = fopen(realpath, mode);
1.235 - if (!pFile)
1.236 - {
1.237 - return 0;
1.238 - }
1.239 -
1.240 - return g_HandleSys.CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.241 -}
1.242 -
1.243 -static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
1.244 -{
1.245 - char *name;
1.246 - int err;
1.247 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.248 - {
1.249 - pContext->ThrowNativeErrorEx(err, NULL);
1.250 - return 0;
1.251 - }
1.252 -
1.253 - char realpath[PLATFORM_MAX_PATH];
1.254 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.255 -
1.256 - return (unlink(realpath)) ? 0 : 1;
1.257 -}
1.258 -
1.259 -static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
1.260 -{
1.261 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.262 - HandleError herr;
1.263 - HandleSecurity sec;
1.264 - FILE *pFile;
1.265 - int err;
1.266 -
1.267 - sec.pOwner = NULL;
1.268 - sec.pIdentity = g_pCoreIdent;
1.269 -
1.270 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.271 - != HandleError_None)
1.272 - {
1.273 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.274 - }
1.275 -
1.276 - char *buf;
1.277 - if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE)
1.278 - {
1.279 - pContext->ThrowNativeErrorEx(err, NULL);
1.280 - return 0;
1.281 - }
1.282 -
1.283 - if (fgets(buf, params[3], pFile) == NULL)
1.284 - {
1.285 - return 0;
1.286 - }
1.287 -
1.288 - return 1;
1.289 -}
1.290 -
1.291 -static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
1.292 -{
1.293 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.294 - HandleError herr;
1.295 - HandleSecurity sec;
1.296 - FILE *pFile;
1.297 -
1.298 - sec.pOwner = NULL;
1.299 - sec.pIdentity = g_pCoreIdent;
1.300 -
1.301 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.302 - != HandleError_None)
1.303 - {
1.304 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.305 - }
1.306 -
1.307 - return (feof(pFile)) ? 1 : 0;
1.308 -}
1.309 -
1.310 -static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
1.311 -{
1.312 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.313 - HandleError herr;
1.314 - HandleSecurity sec;
1.315 - FILE *pFile;
1.316 -
1.317 - sec.pOwner = NULL;
1.318 - sec.pIdentity = g_pCoreIdent;
1.319 -
1.320 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.321 - != HandleError_None)
1.322 - {
1.323 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.324 - }
1.325 -
1.326 - fseek(pFile, params[2], params[3]);
1.327 -
1.328 - return 1;
1.329 -}
1.330 -
1.331 -static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params)
1.332 -{
1.333 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.334 - HandleError herr;
1.335 - HandleSecurity sec;
1.336 - FILE *pFile;
1.337 -
1.338 - sec.pOwner = NULL;
1.339 - sec.pIdentity = g_pCoreIdent;
1.340 -
1.341 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.342 - != HandleError_None)
1.343 - {
1.344 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.345 - }
1.346 -
1.347 - return ftell(pFile);
1.348 -}
1.349 -
1.350 -static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
1.351 -{
1.352 - char *name;
1.353 - int err;
1.354 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.355 - {
1.356 - pContext->ThrowNativeErrorEx(err, NULL);
1.357 - return 0;
1.358 - }
1.359 -
1.360 - if (params[0] >= 2 && params[2] == 1)
1.361 - {
1.362 - return basefilesystem->FileExists(name) ? 1 : 0;
1.363 - }
1.364 -
1.365 - char realpath[PLATFORM_MAX_PATH];
1.366 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.367 -#ifdef PLATFORM_WINDOWS
1.368 - struct _stat s;
1.369 - if (_stat(realpath, &s) != 0)
1.370 - {
1.371 - return 0;
1.372 - }
1.373 - if (s.st_mode & S_IFREG)
1.374 - {
1.375 - return 1;
1.376 - }
1.377 - return 0;
1.378 -#elif defined PLATFORM_POSIX
1.379 - struct stat s;
1.380 - if (stat(realpath, &s) != 0)
1.381 - {
1.382 - return 0;
1.383 - }
1.384 - if (S_ISREG(s.st_mode))
1.385 - {
1.386 - return 1;
1.387 - }
1.388 - return 0;
1.389 -#endif
1.390 -}
1.391 -
1.392 -static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
1.393 -{
1.394 - char *newpath, *oldpath;
1.395 - int err;
1.396 - if ((err=pContext->LocalToString(params[1], &newpath)) != SP_ERROR_NONE)
1.397 - {
1.398 - pContext->ThrowNativeErrorEx(err, NULL);
1.399 - return 0;
1.400 - }
1.401 - if ((err=pContext->LocalToString(params[2], &oldpath)) != SP_ERROR_NONE)
1.402 - {
1.403 - pContext->ThrowNativeErrorEx(err, NULL);
1.404 - return 0;
1.405 - }
1.406 -
1.407 - char new_realpath[PLATFORM_MAX_PATH];
1.408 - g_SourceMod.BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath);
1.409 - char old_realpath[PLATFORM_MAX_PATH];
1.410 - g_SourceMod.BuildPath(Path_Game, old_realpath, sizeof(old_realpath), "%s", oldpath);
1.411 -
1.412 -#ifdef PLATFORM_WINDOWS
1.413 - return (MoveFileA(old_realpath, new_realpath)) ? 1 : 0;
1.414 -#elif defined PLATFORM_POSIX
1.415 - return (rename(old_realpath, new_realpath)) ? 0 : 1;
1.416 -#endif
1.417 -}
1.418 -
1.419 -static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
1.420 -{
1.421 - char *name;
1.422 - int err;
1.423 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.424 - {
1.425 - pContext->ThrowNativeErrorEx(err, NULL);
1.426 - return 0;
1.427 - }
1.428 -
1.429 - char realpath[PLATFORM_MAX_PATH];
1.430 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.431 -#ifdef PLATFORM_WINDOWS
1.432 - struct _stat s;
1.433 - if (_stat(realpath, &s) != 0)
1.434 - {
1.435 - return 0;
1.436 - }
1.437 - if (s.st_mode & S_IFDIR)
1.438 - {
1.439 - return 1;
1.440 - }
1.441 - return 0;
1.442 -#elif defined PLATFORM_POSIX
1.443 - struct stat s;
1.444 - if (stat(realpath, &s) != 0)
1.445 - {
1.446 - return 0;
1.447 - }
1.448 - if (S_ISDIR(s.st_mode))
1.449 - {
1.450 - return 1;
1.451 - }
1.452 - return 0;
1.453 -#endif
1.454 -}
1.455 -
1.456 -static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
1.457 -{
1.458 - char *name;
1.459 - int err;
1.460 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.461 - {
1.462 - pContext->ThrowNativeErrorEx(err, NULL);
1.463 - return -1;
1.464 - }
1.465 -
1.466 - char realpath[PLATFORM_MAX_PATH];
1.467 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.468 -#ifdef PLATFORM_WINDOWS
1.469 - struct _stat s;
1.470 - if (_stat(realpath, &s) != 0)
1.471 - {
1.472 - return -1;
1.473 - }
1.474 - if (s.st_mode & S_IFREG)
1.475 - {
1.476 - return static_cast<cell_t>(s.st_size);
1.477 - }
1.478 - return -1;
1.479 -#elif defined PLATFORM_POSIX
1.480 - struct stat s;
1.481 - if (stat(realpath, &s) != 0)
1.482 - {
1.483 - return -1;
1.484 - }
1.485 - if (S_ISREG(s.st_mode))
1.486 - {
1.487 - return static_cast<cell_t>(s.st_size);
1.488 - }
1.489 - return -1;
1.490 -#endif
1.491 -}
1.492 -
1.493 -static cell_t sm_RemoveDir(IPluginContext *pContext, const cell_t *params)
1.494 -{
1.495 - char *name;
1.496 - int err;
1.497 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.498 - {
1.499 - pContext->ThrowNativeErrorEx(err, NULL);
1.500 - return 0;
1.501 - }
1.502 -
1.503 - char realpath[PLATFORM_MAX_PATH];
1.504 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.505 -
1.506 - return (rmdir(realpath)) ? 0 : 1;
1.507 -}
1.508 -
1.509 -static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
1.510 -{
1.511 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.512 - HandleError herr;
1.513 - HandleSecurity sec;
1.514 - FILE *pFile;
1.515 -
1.516 - sec.pOwner = NULL;
1.517 - sec.pIdentity = g_pCoreIdent;
1.518 -
1.519 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.520 - != HandleError_None)
1.521 - {
1.522 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.523 - }
1.524 -
1.525 - char *fmt;
1.526 - int err;
1.527 - if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
1.528 - {
1.529 - pContext->ThrowNativeErrorEx(err, NULL);
1.530 - return 0;
1.531 - }
1.532 -
1.533 - char buffer[2048];
1.534 - int arg = 3;
1.535 - atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
1.536 - fprintf(pFile, "%s\n", buffer);
1.537 -
1.538 - return 1;
1.539 -}
1.540 -
1.541 -static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params)
1.542 -{
1.543 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.544 - HandleError herr;
1.545 - HandleSecurity sec;
1.546 - FILE *pFile;
1.547 -
1.548 - sec.pOwner = NULL;
1.549 - sec.pIdentity = g_pCoreIdent;
1.550 -
1.551 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.552 - != HandleError_None)
1.553 - {
1.554 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.555 - }
1.556 -
1.557 - return (fflush(pFile) == 0) ? 1 : 0;
1.558 -}
1.559 -
1.560 -static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
1.561 -{
1.562 - char path[PLATFORM_MAX_PATH], *fmt, *buffer;
1.563 - int arg = 5;
1.564 - pContext->LocalToString(params[2], &buffer);
1.565 - pContext->LocalToString(params[4], &fmt);
1.566 -
1.567 - atcprintf(path, sizeof(path), fmt, pContext, params, &arg);
1.568 -
1.569 - return g_SourceMod.BuildPath(Path_SM_Rel, buffer, params[3], "%s", path);
1.570 -}
1.571 -
1.572 -static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
1.573 -{
1.574 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.575 -
1.576 - char buffer[1024];
1.577 - size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
1.578 -
1.579 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.580 - {
1.581 - return 0;
1.582 - }
1.583 -
1.584 - if (len >= sizeof(buffer)-2)
1.585 - {
1.586 - buffer[1022] = '\n';
1.587 - buffer[1023] = '\0';
1.588 - } else {
1.589 - buffer[len++] = '\n';
1.590 - buffer[len] = '\0';
1.591 - }
1.592 -
1.593 - Engine_LogPrintWrapper(buffer);
1.594 -
1.595 - return 1;
1.596 -}
1.597 -
1.598 -static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
1.599 -{
1.600 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.601 -
1.602 - char buffer[1024];
1.603 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
1.604 -
1.605 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.606 - {
1.607 - return 0;
1.608 - }
1.609 -
1.610 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.611 - g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer);
1.612 -
1.613 - return 1;
1.614 -}
1.615 -
1.616 -static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
1.617 -{
1.618 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.619 -
1.620 - char buffer[1024];
1.621 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
1.622 -
1.623 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.624 - {
1.625 - return 0;
1.626 - }
1.627 -
1.628 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.629 - g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
1.630 -
1.631 - return 1;
1.632 -}
1.633 -
1.634 -static cell_t sm_GetFileTime(IPluginContext *pContext, const cell_t *params)
1.635 -{
1.636 - char *name;
1.637 - int err;
1.638 - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
1.639 - {
1.640 - pContext->ThrowNativeErrorEx(err, NULL);
1.641 - return 0;
1.642 - }
1.643 -
1.644 - time_t time_val;
1.645 - char realpath[PLATFORM_MAX_PATH];
1.646 - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
1.647 -
1.648 - if (!g_LibSys.FileTime(realpath, (FileTimeType)params[2], &time_val))
1.649 - {
1.650 - return -1;
1.651 - }
1.652 -
1.653 - return (cell_t)time_val;
1.654 -}
1.655 -
1.656 -static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params)
1.657 -{
1.658 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.659 - HandleError herr;
1.660 - HandleSecurity sec;
1.661 - FILE *pFile;
1.662 -
1.663 - sec.pOwner = NULL;
1.664 - sec.pIdentity = g_pCoreIdent;
1.665 -
1.666 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.667 - != HandleError_None)
1.668 - {
1.669 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.670 - }
1.671 -
1.672 - char buffer[2048];
1.673 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.674 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.675 -
1.676 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.677 - {
1.678 - return 0;
1.679 - }
1.680 -
1.681 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.682 - g_Logger.LogToOpenFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer);
1.683 -
1.684 - return 1;
1.685 -}
1.686 -
1.687 -static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
1.688 -{
1.689 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.690 - HandleError herr;
1.691 - HandleSecurity sec;
1.692 - FILE *pFile;
1.693 -
1.694 - sec.pOwner = NULL;
1.695 - sec.pIdentity = g_pCoreIdent;
1.696 -
1.697 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.698 - != HandleError_None)
1.699 - {
1.700 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.701 - }
1.702 -
1.703 - char buffer[2048];
1.704 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.705 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.706 -
1.707 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.708 - {
1.709 - return 0;
1.710 - }
1.711 -
1.712 - g_Logger.LogToOpenFile(pFile, "%s", buffer);
1.713 -
1.714 - return 1;
1.715 -}
1.716 -
1.717 -static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
1.718 -{
1.719 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.720 - HandleError herr;
1.721 - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.722 - FILE *pFile;
1.723 - size_t read = 0;
1.724 -
1.725 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.726 - != HandleError_None)
1.727 - {
1.728 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.729 - }
1.730 -
1.731 - if (params[4] != 1 && params[4] != 2 && params[4] != 4)
1.732 - {
1.733 - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
1.734 - }
1.735 -
1.736 - cell_t *data;
1.737 - pContext->LocalToPhysAddr(params[2], &data);
1.738 -
1.739 - if (params[4] == 4)
1.740 - {
1.741 - read = fread(data, sizeof(cell_t), params[3], pFile);
1.742 - }
1.743 - else if (params[4] == 2)
1.744 - {
1.745 - int16_t val;
1.746 - for (cell_t i = 0; i < params[3]; i++)
1.747 - {
1.748 - if (fread(&val, sizeof(int16_t), 1, pFile) != 1)
1.749 - {
1.750 - break;
1.751 - }
1.752 - data[read++] = val;
1.753 - }
1.754 - }
1.755 - else if (params[4] == 1)
1.756 - {
1.757 - int8_t val;
1.758 - for (cell_t i = 0; i < params[3]; i++)
1.759 - {
1.760 - if (fread(&val, sizeof(int8_t), 1, pFile) != 1)
1.761 - {
1.762 - break;
1.763 - }
1.764 - data[read++] = val;
1.765 - }
1.766 - }
1.767 -
1.768 - if (read != (size_t)params[3] && ferror(pFile) != 0)
1.769 - {
1.770 - return -1;
1.771 - }
1.772 -
1.773 - return read;
1.774 -}
1.775 -
1.776 -static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
1.777 -{
1.778 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.779 - HandleError herr;
1.780 - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.781 - FILE *pFile;
1.782 - cell_t num_read = 0;
1.783 -
1.784 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.785 - != HandleError_None)
1.786 - {
1.787 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.788 - }
1.789 -
1.790 - char *buffer;
1.791 - pContext->LocalToString(params[2], &buffer);
1.792 -
1.793 - char val;
1.794 - while (1)
1.795 - {
1.796 - /* If we're in stop mode, break as soon as the buffer is full. */
1.797 - if (params[4] && (params[3] == 0 || num_read >= params[3] - 1))
1.798 - {
1.799 - break;
1.800 - }
1.801 - if (fread(&val, sizeof(val), 1, pFile) != 1)
1.802 - {
1.803 - if (ferror(pFile))
1.804 - {
1.805 - return -1;
1.806 - }
1.807 - break;
1.808 - }
1.809 - if (val == '\0')
1.810 - {
1.811 - break;
1.812 - }
1.813 - if (params[3] > 0 && num_read < params[3] - 1)
1.814 - {
1.815 - buffer[num_read++] = val;
1.816 - }
1.817 - }
1.818 -
1.819 - if (params[3] > 0)
1.820 - {
1.821 - buffer[num_read] = '\0';
1.822 - }
1.823 -
1.824 - return num_read;
1.825 -}
1.826 -
1.827 -static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
1.828 -{
1.829 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.830 - HandleError herr;
1.831 - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.832 - FILE *pFile;
1.833 -
1.834 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.835 - != HandleError_None)
1.836 - {
1.837 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.838 - }
1.839 -
1.840 - cell_t *data;
1.841 - pContext->LocalToPhysAddr(params[2], &data);
1.842 -
1.843 - if (params[4] != 1 && params[4] != 2 && params[4] != 4)
1.844 - {
1.845 - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
1.846 - }
1.847 -
1.848 - /* :NOTE: This really isn't compatible with big endian but we will never have to worry about that. */
1.849 -
1.850 - if (params[4] == 4)
1.851 - {
1.852 - if (fwrite(data, sizeof(cell_t), params[3], pFile) != (size_t)params[3])
1.853 - {
1.854 - return 0;
1.855 - }
1.856 - }
1.857 - else if (params[4] == 2)
1.858 - {
1.859 - for (cell_t i = 0; i < params[3]; i++)
1.860 - {
1.861 - if (fwrite(&data[i], sizeof(int16_t), 1, pFile) != 1)
1.862 - {
1.863 - return 0;
1.864 - }
1.865 - }
1.866 - }
1.867 - else if (params[4] == 1)
1.868 - {
1.869 - for (cell_t i = 0; i < params[3]; i++)
1.870 - {
1.871 - if (fwrite(&data[i], sizeof(int8_t), 1, pFile) != 1)
1.872 - {
1.873 - return 0;
1.874 - }
1.875 - }
1.876 - }
1.877 -
1.878 - return 1;
1.879 -}
1.880 -
1.881 -static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params)
1.882 -{
1.883 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.884 - HandleError herr;
1.885 - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.886 - FILE *pFile;
1.887 -
1.888 - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
1.889 - != HandleError_None)
1.890 - {
1.891 - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
1.892 - }
1.893 -
1.894 - char *buffer;
1.895 - pContext->LocalToString(params[2], &buffer);
1.896 -
1.897 - size_t len = strlen(buffer);
1.898 -
1.899 - if (params[3])
1.900 - {
1.901 - len++;
1.902 - }
1.903 -
1.904 - return (fwrite(buffer, sizeof(char), len, pFile) == len) ? 1 : 0;
1.905 -}
1.906 -
1.907 -static cell_t sm_AddGameLogHook(IPluginContext *pContext, const cell_t *params)
1.908 -{
1.909 - IPluginFunction *pFunction;
1.910 -
1.911 - if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
1.912 - {
1.913 - return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
1.914 - }
1.915 -
1.916 - s_FileNatives.AddLogHook(pFunction);
1.917 -
1.918 - return 1;
1.919 -}
1.920 -
1.921 -static cell_t sm_RemoveGameLogHook(IPluginContext *pContext, const cell_t *params)
1.922 -{
1.923 - IPluginFunction *pFunction;
1.924 -
1.925 - if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
1.926 - {
1.927 - return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
1.928 - }
1.929 -
1.930 - s_FileNatives.RemoveLogHook(pFunction);
1.931 -
1.932 - return 1;
1.933 -}
1.934 -
1.935 -REGISTER_NATIVES(filesystem)
1.936 -{
1.937 - {"OpenDirectory", sm_OpenDirectory},
1.938 - {"ReadDirEntry", sm_ReadDirEntry},
1.939 - {"OpenFile", sm_OpenFile},
1.940 - {"DeleteFile", sm_DeleteFile},
1.941 - {"ReadFileLine", sm_ReadFileLine},
1.942 - {"IsEndOfFile", sm_IsEndOfFile},
1.943 - {"FileSeek", sm_FileSeek},
1.944 - {"FilePosition", sm_FilePosition},
1.945 - {"FileExists", sm_FileExists},
1.946 - {"RenameFile", sm_RenameFile},
1.947 - {"DirExists", sm_DirExists},
1.948 - {"FileSize", sm_FileSize},
1.949 - {"RemoveDir", sm_RemoveDir},
1.950 - {"WriteFileLine", sm_WriteFileLine},
1.951 - {"BuildPath", sm_BuildPath},
1.952 - {"LogToGame", sm_LogToGame},
1.953 - {"LogMessage", sm_LogMessage},
1.954 - {"LogError", sm_LogError},
1.955 - {"FlushFile", sm_FlushFile},
1.956 - {"GetFileTime", sm_GetFileTime},
1.957 - {"LogToOpenFile", sm_LogToOpenFile},
1.958 - {"LogToOpenFileEx", sm_LogToOpenFileEx},
1.959 - {"ReadFile", sm_ReadFile},
1.960 - {"ReadFileString", sm_ReadFileString},
1.961 - {"WriteFile", sm_WriteFile},
1.962 - {"WriteFileString", sm_WriteFileString},
1.963 - {"AddGameLogHook", sm_AddGameLogHook},
1.964 - {"RemoveGameLogHook", sm_RemoveGameLogHook},
1.965 - {NULL, NULL},
1.966 -};