core/smn_filesystem.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Mon Apr 11 22:30:03 2011 -0400 (2011-04-11)
changeset 3238 fff6e001bf9b
parent 2445 b0cefeafe09a
permissions -rw-r--r--
Removed gEntList failure notify on Windows. (bug 4832, r=fyren).
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@370
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@370
    28
 *
dvander@370
    29
 * Version: $Id$
dvander@370
    30
 */
dvander@370
    31
faluco@274
    32
#include <sys/stat.h>
dvander@252
    33
#include "sm_globals.h"
dvander@252
    34
#include "HandleSys.h"
dvander@252
    35
#include "LibrarySys.h"
faluco@274
    36
#include "sm_stringutil.h"
dvander@592
    37
#include "Logger.h"
dvander@347
    38
#include "PluginSys.h"
dvander@347
    39
#include "sourcemm_api.h"
dvander@1914
    40
#include "ForwardSys.h"
dvander@1914
    41
dvander@1914
    42
SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *);
dvander@252
    43
dvander@252
    44
HandleType_t g_FileType;
dvander@252
    45
HandleType_t g_DirType;
dvander@1914
    46
IChangeableForward *g_pLogHook = NULL;
dvander@252
    47
dvander@252
    48
class FileNatives : 
dvander@252
    49
	public SMGlobalClass,
dvander@1914
    50
	public IHandleTypeDispatch,
dvander@1914
    51
	public IPluginsListener
dvander@252
    52
{
dvander@252
    53
public:
dvander@1914
    54
	FileNatives()
dvander@1914
    55
	{
dvander@1914
    56
		m_bIsLoggingHooked = false;
dvander@1914
    57
	}
dvander@252
    58
	virtual void OnSourceModAllInitialized()
dvander@252
    59
	{
dvander@262
    60
		g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
dvander@262
    61
		g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
dvander@1914
    62
		g_pLogHook = g_Forwards.CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String);
dvander@1914
    63
		g_PluginSys.AddPluginsListener(this);
dvander@252
    64
	}
dvander@252
    65
	virtual void OnSourceModShutdown()
dvander@252
    66
	{
dvander@1914
    67
		g_PluginSys.RemovePluginsListener(this);
dvander@1914
    68
		if (m_bIsLoggingHooked)
dvander@1914
    69
		{
dvander@1914
    70
			SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
dvander@1914
    71
			m_bIsLoggingHooked = false;
dvander@1914
    72
		}
dvander@1914
    73
		g_Forwards.ReleaseForward(g_pLogHook);
dvander@252
    74
		g_HandleSys.RemoveType(g_DirType, g_pCoreIdent);
dvander@252
    75
		g_HandleSys.RemoveType(g_FileType, g_pCoreIdent);
dvander@252
    76
		g_DirType = 0;
dvander@252
    77
		g_FileType = 0;
dvander@252
    78
	}
dvander@252
    79
	virtual void OnHandleDestroy(HandleType_t type, void *object)
dvander@252
    80
	{
dvander@252
    81
		if (type == g_FileType)
dvander@252
    82
		{
dvander@252
    83
			FILE *fp = (FILE *)object;
dvander@252
    84
			fclose(fp);
dvander@1914
    85
		}
dvander@1914
    86
		else if (type == g_DirType)
dvander@1914
    87
		{
dvander@252
    88
			IDirectory *pDir = (IDirectory *)object;
dvander@252
    89
			g_LibSys.CloseDirectory(pDir);
dvander@252
    90
		}
dvander@252
    91
	}
dvander@1914
    92
	virtual void OnPluginDestroyed(IPlugin *plugin)
dvander@1914
    93
	{
dvander@1914
    94
		if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0)
dvander@1914
    95
		{
dvander@1914
    96
			SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
dvander@1914
    97
			m_bIsLoggingHooked = false;
dvander@1914
    98
		}
dvander@1914
    99
	}
dvander@1914
   100
	virtual void AddLogHook(IPluginFunction *pFunc)
dvander@1914
   101
	{
dvander@1914
   102
		if (!m_bIsLoggingHooked)
dvander@1914
   103
		{
dvander@1914
   104
			SH_ADD_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
dvander@1914
   105
			m_bIsLoggingHooked = true;
dvander@1914
   106
		}
dvander@1914
   107
dvander@1914
   108
		g_pLogHook->AddFunction(pFunc);
dvander@1914
   109
	}
dvander@1914
   110
	virtual void RemoveLogHook(IPluginFunction *pFunc)
dvander@1914
   111
	{
dvander@1914
   112
		g_pLogHook->RemoveFunction(pFunc);
dvander@1914
   113
dvander@1914
   114
		if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0)
dvander@1914
   115
		{
dvander@1914
   116
			SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false);
dvander@1914
   117
			m_bIsLoggingHooked = false;
dvander@1914
   118
		}
dvander@1914
   119
	}
dvander@1914
   120
	virtual void LogPrint(const char *msg)
dvander@1914
   121
	{
dvander@1914
   122
		cell_t result;
dvander@1914
   123
dvander@1914
   124
		result = 0;
dvander@1914
   125
dvander@1914
   126
		g_in_game_log_hook = true;
dvander@1914
   127
		g_pLogHook->PushString(msg);
dvander@1914
   128
		g_pLogHook->Execute(&result);
dvander@1914
   129
		g_in_game_log_hook = false;
dvander@1914
   130
dvander@1914
   131
		if (result >= Pl_Handled)
dvander@1914
   132
		{
dvander@1914
   133
			RETURN_META(MRES_SUPERCEDE);
dvander@1914
   134
		}
dvander@1914
   135
	}
dvander@1914
   136
private:
dvander@1914
   137
	bool m_bIsLoggingHooked;
dvander@1378
   138
} s_FileNatives;
dvander@252
   139
faluco@274
   140
static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
dvander@252
   141
{
dvander@252
   142
	char *path;
dvander@252
   143
	int err;
dvander@252
   144
	if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE)
dvander@252
   145
	{
dvander@252
   146
		pContext->ThrowNativeErrorEx(err, NULL);
dvander@252
   147
		return 0;
dvander@252
   148
	}
dvander@252
   149
ds@652
   150
	char realpath[PLATFORM_MAX_PATH];
dvander@317
   151
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
dvander@255
   152
dvander@255
   153
	IDirectory *pDir = g_LibSys.OpenDirectory(realpath);
dvander@252
   154
	if (!pDir)
dvander@252
   155
	{
dvander@252
   156
		return 0;
dvander@252
   157
	}
dvander@252
   158
dvander@262
   159
	return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@252
   160
}
dvander@252
   161
faluco@274
   162
static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
dvander@252
   163
{
dvander@252
   164
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@252
   165
	IDirectory *pDir;
dvander@252
   166
	HandleError herr;
dvander@262
   167
	HandleSecurity sec;
dvander@252
   168
	int err;
dvander@262
   169
dvander@262
   170
	sec.pOwner = NULL;
dvander@262
   171
	sec.pIdentity = g_pCoreIdent;
dvander@262
   172
dvander@262
   173
	if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
dvander@252
   174
		!= HandleError_None)
dvander@252
   175
	{
dvander@252
   176
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@252
   177
	}
dvander@252
   178
dvander@252
   179
	if (!pDir->MoreFiles())
dvander@252
   180
	{
dvander@252
   181
		return false;
dvander@252
   182
	}
dvander@252
   183
dvander@252
   184
	cell_t *filetype;
dvander@252
   185
	if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
dvander@252
   186
	{
dvander@252
   187
		pContext->ThrowNativeErrorEx(err, NULL);
dvander@252
   188
		return 0;
dvander@252
   189
	}
dvander@252
   190
dvander@252
   191
	if (pDir->IsEntryDirectory())
dvander@252
   192
	{
dvander@252
   193
		*filetype = 1;
dvander@252
   194
	} else if (pDir->IsEntryFile()) {
dvander@252
   195
		*filetype = 2;
dvander@252
   196
	} else {
dvander@252
   197
		*filetype = 0;
dvander@252
   198
	}
dvander@252
   199
dvander@252
   200
	const char *path = pDir->GetEntryName();
dvander@255
   201
	if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
dvander@252
   202
		!= SP_ERROR_NONE)
dvander@252
   203
	{
dvander@252
   204
		pContext->ThrowNativeErrorEx(err, NULL);
dvander@252
   205
		return 0;
dvander@252
   206
	}
dvander@252
   207
dvander@255
   208
	pDir->NextEntry();
dvander@255
   209
dvander@252
   210
	return true;
dvander@252
   211
}
dvander@252
   212
faluco@274
   213
static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
faluco@274
   214
{
faluco@274
   215
	char *name, *mode;
faluco@274
   216
	int err;
faluco@274
   217
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   218
	{
faluco@274
   219
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   220
		return 0;
faluco@274
   221
	}
faluco@274
   222
	if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE)
faluco@274
   223
	{
faluco@274
   224
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   225
		return 0;
faluco@274
   226
	}
faluco@274
   227
ds@652
   228
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   229
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   230
faluco@274
   231
	FILE *pFile = fopen(realpath, mode);
faluco@274
   232
	if (!pFile)
faluco@274
   233
	{
faluco@274
   234
		return 0;
faluco@274
   235
	}
faluco@274
   236
faluco@274
   237
	return g_HandleSys.CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
faluco@274
   238
}
faluco@274
   239
faluco@274
   240
static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
faluco@274
   241
{
faluco@274
   242
	char *name;
faluco@274
   243
	int err;
faluco@274
   244
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   245
	{
faluco@274
   246
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   247
		return 0;
faluco@274
   248
	}
faluco@274
   249
ds@652
   250
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   251
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   252
faluco@274
   253
	return (unlink(realpath)) ? 0 : 1;
faluco@274
   254
}
faluco@274
   255
faluco@274
   256
static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
faluco@274
   257
{
faluco@274
   258
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@274
   259
	HandleError herr;
faluco@274
   260
	HandleSecurity sec;
faluco@274
   261
	FILE *pFile;
faluco@274
   262
	int err;
faluco@274
   263
faluco@274
   264
	sec.pOwner = NULL;
faluco@274
   265
	sec.pIdentity = g_pCoreIdent;
faluco@274
   266
faluco@274
   267
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
faluco@274
   268
		!= HandleError_None)
faluco@274
   269
	{
faluco@274
   270
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
faluco@274
   271
	}
faluco@274
   272
faluco@274
   273
	char *buf;
faluco@274
   274
	if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE)
faluco@274
   275
	{
faluco@274
   276
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   277
		return 0;
faluco@274
   278
	}
faluco@274
   279
dvander@638
   280
	if (fgets(buf, params[3], pFile) == NULL)
dvander@638
   281
	{
dvander@638
   282
		return 0;
dvander@638
   283
	}
faluco@274
   284
faluco@274
   285
	return 1;
faluco@274
   286
}
faluco@274
   287
faluco@274
   288
static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
faluco@274
   289
{
faluco@274
   290
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@274
   291
	HandleError herr;
faluco@274
   292
	HandleSecurity sec;
faluco@274
   293
	FILE *pFile;
faluco@274
   294
faluco@274
   295
	sec.pOwner = NULL;
faluco@274
   296
	sec.pIdentity = g_pCoreIdent;
faluco@274
   297
faluco@274
   298
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
faluco@274
   299
		!= HandleError_None)
faluco@274
   300
	{
faluco@274
   301
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
faluco@274
   302
	}
faluco@274
   303
faluco@274
   304
	return (feof(pFile)) ? 1 : 0;
faluco@274
   305
}
faluco@274
   306
faluco@274
   307
static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
faluco@274
   308
{
faluco@274
   309
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@274
   310
	HandleError herr;
faluco@274
   311
	HandleSecurity sec;
faluco@274
   312
	FILE *pFile;
faluco@274
   313
faluco@274
   314
	sec.pOwner = NULL;
faluco@274
   315
	sec.pIdentity = g_pCoreIdent;
faluco@274
   316
faluco@274
   317
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
faluco@274
   318
		!= HandleError_None)
faluco@274
   319
	{
faluco@274
   320
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
faluco@274
   321
	}
faluco@274
   322
faluco@274
   323
	fseek(pFile, params[2], params[3]);
faluco@274
   324
	
faluco@274
   325
	return 1;
faluco@274
   326
}
faluco@274
   327
faluco@274
   328
static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params)
faluco@274
   329
{
faluco@274
   330
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@274
   331
	HandleError herr;
faluco@274
   332
	HandleSecurity sec;
faluco@274
   333
	FILE *pFile;
faluco@274
   334
faluco@274
   335
	sec.pOwner = NULL;
faluco@274
   336
	sec.pIdentity = g_pCoreIdent;
faluco@274
   337
faluco@274
   338
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
faluco@274
   339
		!= HandleError_None)
faluco@274
   340
	{
faluco@274
   341
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
faluco@274
   342
	}
faluco@274
   343
faluco@274
   344
	return ftell(pFile);
faluco@274
   345
}
faluco@274
   346
faluco@274
   347
static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
faluco@274
   348
{
faluco@274
   349
	char *name;
faluco@274
   350
	int err;
faluco@274
   351
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   352
	{
faluco@274
   353
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   354
		return 0;
faluco@274
   355
	}
faluco@274
   356
dvander@1854
   357
	if (params[0] >= 2 && params[2] == 1)
dvander@1854
   358
	{
dvander@1854
   359
		return basefilesystem->FileExists(name) ? 1 : 0;
dvander@1854
   360
	}
dvander@1854
   361
ds@652
   362
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   363
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   364
#ifdef PLATFORM_WINDOWS
faluco@274
   365
	struct _stat s;
faluco@274
   366
	if (_stat(realpath, &s) != 0)
faluco@274
   367
	{
faluco@274
   368
		return 0;
faluco@274
   369
	}
faluco@274
   370
	if (s.st_mode & S_IFREG)
faluco@274
   371
	{
faluco@274
   372
		return 1;
faluco@274
   373
	}
faluco@274
   374
	return 0;
dvander@351
   375
#elif defined PLATFORM_POSIX
faluco@274
   376
	struct stat s;
faluco@274
   377
	if (stat(realpath, &s) != 0)
faluco@274
   378
	{
faluco@274
   379
		return 0;
faluco@274
   380
	}
faluco@274
   381
	if (S_ISREG(s.st_mode))
faluco@274
   382
	{
faluco@274
   383
		return 1;
faluco@274
   384
	}
faluco@274
   385
	return 0;
faluco@274
   386
#endif
faluco@274
   387
}
faluco@274
   388
faluco@274
   389
static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
faluco@274
   390
{
faluco@274
   391
	char *newpath, *oldpath;
faluco@274
   392
	int err;
faluco@274
   393
	if ((err=pContext->LocalToString(params[1], &newpath)) != SP_ERROR_NONE)
faluco@274
   394
	{
faluco@274
   395
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   396
		return 0;
faluco@274
   397
	}
faluco@274
   398
	if ((err=pContext->LocalToString(params[2], &oldpath)) != SP_ERROR_NONE)
faluco@274
   399
	{
faluco@274
   400
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   401
		return 0;
faluco@274
   402
	}
faluco@274
   403
ds@652
   404
	char new_realpath[PLATFORM_MAX_PATH];
dvander@636
   405
	g_SourceMod.BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath);
ds@652
   406
	char old_realpath[PLATFORM_MAX_PATH];
dvander@636
   407
	g_SourceMod.BuildPath(Path_Game, old_realpath, sizeof(old_realpath), "%s", oldpath);
faluco@274
   408
faluco@274
   409
#ifdef PLATFORM_WINDOWS
faluco@274
   410
	return (MoveFileA(old_realpath, new_realpath)) ? 1 : 0;
dvander@351
   411
#elif defined PLATFORM_POSIX
faluco@274
   412
	return (rename(old_realpath, new_realpath)) ? 0 : 1;
faluco@274
   413
#endif
faluco@274
   414
}
faluco@274
   415
faluco@274
   416
static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
faluco@274
   417
{
faluco@274
   418
	char *name;
faluco@274
   419
	int err;
faluco@274
   420
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   421
	{
faluco@274
   422
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   423
		return 0;
faluco@274
   424
	}
faluco@274
   425
ds@652
   426
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   427
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   428
#ifdef PLATFORM_WINDOWS
faluco@274
   429
	struct _stat s;
faluco@274
   430
	if (_stat(realpath, &s) != 0)
faluco@274
   431
	{
faluco@274
   432
		return 0;
faluco@274
   433
	}
faluco@274
   434
	if (s.st_mode & S_IFDIR)
faluco@274
   435
	{
faluco@274
   436
		return 1;
faluco@274
   437
	}
faluco@274
   438
	return 0;
dvander@351
   439
#elif defined PLATFORM_POSIX
faluco@274
   440
	struct stat s;
faluco@274
   441
	if (stat(realpath, &s) != 0)
faluco@274
   442
	{
faluco@274
   443
		return 0;
faluco@274
   444
	}
faluco@274
   445
	if (S_ISDIR(s.st_mode))
faluco@274
   446
	{
faluco@274
   447
		return 1;
faluco@274
   448
	}
faluco@274
   449
	return 0;
faluco@274
   450
#endif
faluco@274
   451
}
faluco@274
   452
faluco@274
   453
static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
faluco@274
   454
{
faluco@274
   455
	char *name;
faluco@274
   456
	int err;
faluco@274
   457
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   458
	{
faluco@274
   459
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   460
		return -1;
faluco@274
   461
	}
faluco@274
   462
ds@652
   463
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   464
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   465
#ifdef PLATFORM_WINDOWS
faluco@274
   466
	struct _stat s;
faluco@274
   467
	if (_stat(realpath, &s) != 0)
faluco@274
   468
	{
faluco@274
   469
		return -1;
faluco@274
   470
	}
faluco@274
   471
	if (s.st_mode & S_IFREG)
faluco@274
   472
	{
faluco@274
   473
		return static_cast<cell_t>(s.st_size);
faluco@274
   474
	}
faluco@274
   475
	return -1;
dvander@351
   476
#elif defined PLATFORM_POSIX
faluco@274
   477
	struct stat s;
faluco@274
   478
	if (stat(realpath, &s) != 0)
faluco@274
   479
	{
faluco@274
   480
		return -1;
faluco@274
   481
	}
faluco@274
   482
	if (S_ISREG(s.st_mode))
faluco@274
   483
	{
faluco@274
   484
		return static_cast<cell_t>(s.st_size);
faluco@274
   485
	}
faluco@274
   486
	return -1;
faluco@274
   487
#endif
faluco@274
   488
}
faluco@274
   489
dvander@2307
   490
static cell_t sm_CreateDirectory(IPluginContext *pContext, const cell_t *params)
dvander@2307
   491
{
dvander@2307
   492
	char *name;
dvander@2307
   493
	char realpath[PLATFORM_MAX_PATH];
dvander@2307
   494
dvander@2307
   495
	pContext->LocalToString(params[1], &name);
dvander@2307
   496
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
dvander@2307
   497
dvander@2307
   498
#if defined PLATFORM_WINDOWS
dvander@2307
   499
	return mkdir(realpath) == 0;
dvander@2307
   500
#else
dvander@2307
   501
	return mkdir(realpath, params[2]) == 0;
dvander@2307
   502
#endif
dvander@2307
   503
}
dvander@2307
   504
faluco@274
   505
static cell_t sm_RemoveDir(IPluginContext *pContext, const cell_t *params)
faluco@274
   506
{
faluco@274
   507
	char *name;
faluco@274
   508
	int err;
faluco@274
   509
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
faluco@274
   510
	{
faluco@274
   511
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   512
		return 0;
faluco@274
   513
	}
faluco@274
   514
ds@652
   515
	char realpath[PLATFORM_MAX_PATH];
dvander@636
   516
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
faluco@274
   517
faluco@274
   518
	return (rmdir(realpath)) ? 0 : 1;
faluco@274
   519
}
faluco@274
   520
faluco@274
   521
static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
faluco@274
   522
{
faluco@274
   523
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@274
   524
	HandleError herr;
faluco@274
   525
	HandleSecurity sec;
faluco@274
   526
	FILE *pFile;
faluco@274
   527
faluco@274
   528
	sec.pOwner = NULL;
faluco@274
   529
	sec.pIdentity = g_pCoreIdent;
faluco@274
   530
faluco@274
   531
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
faluco@274
   532
		!= HandleError_None)
faluco@274
   533
	{
faluco@274
   534
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
faluco@274
   535
	}
faluco@274
   536
faluco@274
   537
	char *fmt;
faluco@274
   538
	int err;
faluco@274
   539
	if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
faluco@274
   540
	{
faluco@274
   541
		pContext->ThrowNativeErrorEx(err, NULL);
faluco@274
   542
		return 0;
faluco@274
   543
	}
faluco@274
   544
faluco@274
   545
	char buffer[2048];
faluco@274
   546
	int arg = 3;
faluco@274
   547
	atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
faluco@274
   548
	fprintf(pFile, "%s\n", buffer);
faluco@274
   549
faluco@274
   550
	return 1;
faluco@274
   551
}
faluco@274
   552
dvander@821
   553
static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params)
dvander@821
   554
{
dvander@821
   555
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@821
   556
	HandleError herr;
dvander@821
   557
	HandleSecurity sec;
dvander@821
   558
	FILE *pFile;
dvander@821
   559
dvander@821
   560
	sec.pOwner = NULL;
dvander@821
   561
	sec.pIdentity = g_pCoreIdent;
dvander@821
   562
dvander@821
   563
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@821
   564
		!= HandleError_None)
dvander@821
   565
	{
dvander@821
   566
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@821
   567
	}
dvander@821
   568
dvander@821
   569
	return (fflush(pFile) == 0) ? 1 : 0;
dvander@821
   570
}
dvander@821
   571
dvander@345
   572
static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
dvander@345
   573
{
dvander@345
   574
	char path[PLATFORM_MAX_PATH], *fmt, *buffer;
ds@711
   575
	int arg = 5;
dvander@345
   576
	pContext->LocalToString(params[2], &buffer);
dvander@345
   577
	pContext->LocalToString(params[4], &fmt);
dvander@345
   578
dvander@345
   579
	atcprintf(path, sizeof(path), fmt, pContext, params, &arg);
dvander@345
   580
dvander@345
   581
	return g_SourceMod.BuildPath(Path_SM_Rel, buffer, params[3], "%s", path);
dvander@345
   582
}
dvander@345
   583
dvander@347
   584
static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
dvander@347
   585
{
dvander@2042
   586
	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1011
   587
dvander@347
   588
	char buffer[1024];
dvander@347
   589
	size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
dvander@347
   590
dvander@2193
   591
	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1378
   592
	{
dvander@1378
   593
		return 0;
dvander@1378
   594
	}
dvander@1378
   595
dvander@347
   596
	if (len >= sizeof(buffer)-2)
dvander@347
   597
	{
dvander@347
   598
		buffer[1022] = '\n';
dvander@347
   599
		buffer[1023] = '\0';
dvander@347
   600
	} else {
dvander@347
   601
		buffer[len++] = '\n';
dvander@347
   602
		buffer[len] = '\0';
dvander@347
   603
	}
dvander@347
   604
dvander@1914
   605
	Engine_LogPrintWrapper(buffer);
dvander@347
   606
dvander@347
   607
	return 1;
dvander@347
   608
}
dvander@347
   609
dvander@347
   610
static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
dvander@347
   611
{
dvander@2042
   612
	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1011
   613
dvander@347
   614
	char buffer[1024];
dvander@351
   615
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
dvander@347
   616
dvander@2193
   617
	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1378
   618
	{
dvander@1378
   619
		return 0;
dvander@1378
   620
	}
dvander@1378
   621
dvander@1378
   622
	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@347
   623
	g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer);
dvander@347
   624
dvander@347
   625
	return 1;
dvander@347
   626
}
dvander@347
   627
dvander@347
   628
static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
dvander@347
   629
{
dvander@2042
   630
	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1011
   631
dvander@347
   632
	char buffer[1024];
dvander@351
   633
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
dvander@347
   634
dvander@2193
   635
	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1378
   636
	{
dvander@1378
   637
		return 0;
dvander@1378
   638
	}
dvander@1378
   639
dvander@1378
   640
	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@347
   641
	g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
dvander@347
   642
dvander@347
   643
	return 1;
dvander@347
   644
}
dvander@347
   645
dvander@1370
   646
static cell_t sm_GetFileTime(IPluginContext *pContext, const cell_t *params)
dvander@1370
   647
{
dvander@1370
   648
	char *name;
dvander@1370
   649
	int err;
dvander@1370
   650
	if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
dvander@1370
   651
	{
dvander@1370
   652
		pContext->ThrowNativeErrorEx(err, NULL);
dvander@1370
   653
		return 0;
dvander@1370
   654
	}
dvander@1370
   655
dvander@1738
   656
	time_t time_val;
dvander@1370
   657
	char realpath[PLATFORM_MAX_PATH];
dvander@1370
   658
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
dvander@1370
   659
dvander@1738
   660
	if (!g_LibSys.FileTime(realpath, (FileTimeType)params[2], &time_val))
dvander@1370
   661
	{
dvander@1370
   662
		return -1;
dvander@1370
   663
	}
dvander@1370
   664
dvander@1738
   665
	return (cell_t)time_val;
dvander@1370
   666
}
dvander@1370
   667
dvander@1378
   668
static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params)
dvander@1378
   669
{
dvander@1378
   670
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1378
   671
	HandleError herr;
dvander@1378
   672
	HandleSecurity sec;
dvander@1378
   673
	FILE *pFile;
dvander@1378
   674
dvander@1378
   675
	sec.pOwner = NULL;
dvander@1378
   676
	sec.pIdentity = g_pCoreIdent;
dvander@1378
   677
dvander@1378
   678
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1378
   679
		!= HandleError_None)
dvander@1378
   680
	{
dvander@1378
   681
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1378
   682
	}
dvander@1378
   683
dvander@1378
   684
	char buffer[2048];
dvander@2042
   685
	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1378
   686
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@1378
   687
dvander@2193
   688
	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1378
   689
	{
dvander@1378
   690
		return 0;
dvander@1378
   691
	}
dvander@1378
   692
dvander@1378
   693
	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
dvander@1378
   694
	g_Logger.LogToOpenFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer);
dvander@1378
   695
dvander@1378
   696
	return 1;
dvander@1378
   697
}
dvander@1378
   698
dvander@1378
   699
static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
dvander@1378
   700
{
dvander@1378
   701
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1378
   702
	HandleError herr;
dvander@1378
   703
	HandleSecurity sec;
dvander@1378
   704
	FILE *pFile;
dvander@1378
   705
dvander@1378
   706
	sec.pOwner = NULL;
dvander@1378
   707
	sec.pIdentity = g_pCoreIdent;
dvander@1378
   708
dvander@1378
   709
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1378
   710
		!= HandleError_None)
dvander@1378
   711
	{
dvander@1378
   712
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1378
   713
	}
dvander@1378
   714
dvander@1378
   715
	char buffer[2048];
dvander@2042
   716
	g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
dvander@1378
   717
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@1378
   718
dvander@2193
   719
	if (pContext->GetLastNativeError() != SP_ERROR_NONE)
dvander@1378
   720
	{
dvander@1378
   721
		return 0;
dvander@1378
   722
	}
dvander@1378
   723
dvander@1378
   724
	g_Logger.LogToOpenFile(pFile, "%s", buffer);
dvander@1378
   725
dvander@1378
   726
	return 1;
dvander@1378
   727
}
dvander@252
   728
dvander@1796
   729
static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
dvander@1796
   730
{
dvander@1796
   731
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1796
   732
	HandleError herr;
dvander@1796
   733
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1796
   734
	FILE *pFile;
dvander@1796
   735
	size_t read = 0;
dvander@1796
   736
dvander@1796
   737
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1796
   738
		!= HandleError_None)
dvander@1796
   739
	{
dvander@1796
   740
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1796
   741
	}
dvander@1796
   742
dvander@1796
   743
	if (params[4] != 1 && params[4] != 2 && params[4] != 4)
dvander@1796
   744
	{
dvander@1796
   745
		return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
dvander@1796
   746
	}
dvander@1796
   747
dvander@1796
   748
	cell_t *data;
dvander@1796
   749
	pContext->LocalToPhysAddr(params[2], &data);
dvander@1796
   750
dvander@1796
   751
	if (params[4] == 4)
dvander@1796
   752
	{
dvander@1796
   753
		read = fread(data, sizeof(cell_t), params[3], pFile);
dvander@1796
   754
	}
dvander@1796
   755
	else if (params[4] == 2)
dvander@1796
   756
	{
dvander@2431
   757
		uint16_t val;
dvander@1796
   758
		for (cell_t i = 0; i < params[3]; i++)
dvander@1796
   759
		{
dvander@2431
   760
			if (fread(&val, sizeof(uint16_t), 1, pFile) != 1)
dvander@1796
   761
			{
dvander@1796
   762
				break;
dvander@1796
   763
			}
dvander@1796
   764
			data[read++] = val;
dvander@1796
   765
		}
dvander@1796
   766
	}
dvander@1796
   767
	else if (params[4] == 1)
dvander@1796
   768
	{
dvander@2431
   769
		uint8_t val;
dvander@1796
   770
		for (cell_t i = 0; i < params[3]; i++)
dvander@1796
   771
		{
dvander@2431
   772
			if (fread(&val, sizeof(uint8_t), 1, pFile) != 1)
dvander@1796
   773
			{
dvander@1796
   774
				break;
dvander@1796
   775
			}
dvander@1796
   776
			data[read++] = val;
dvander@1796
   777
		}
dvander@1796
   778
	}
dvander@1796
   779
dvander@1796
   780
	if (read != (size_t)params[3] && ferror(pFile) != 0)
dvander@1796
   781
	{
dvander@1796
   782
		return -1;
dvander@1796
   783
	}
dvander@1796
   784
dvander@1796
   785
	return read;
dvander@1796
   786
}
dvander@1796
   787
dvander@1796
   788
static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
dvander@1796
   789
{
dvander@1796
   790
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1796
   791
	HandleError herr;
dvander@1796
   792
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1796
   793
	FILE *pFile;
dvander@1796
   794
	cell_t num_read = 0;
dvander@1796
   795
dvander@1796
   796
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1796
   797
		!= HandleError_None)
dvander@1796
   798
	{
dvander@1796
   799
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1796
   800
	}
dvander@1796
   801
dvander@1796
   802
	char *buffer;
dvander@1796
   803
	pContext->LocalToString(params[2], &buffer);
dvander@1796
   804
dvander@2445
   805
	if (params[4] != -1)
dvander@2445
   806
	{
dvander@2445
   807
		if (size_t(params[4]) > size_t(params[3]))
dvander@2445
   808
		{
dvander@2445
   809
			return pContext->ThrowNativeError("read_count (%u) is greater than buffer size (%u)",
dvander@2445
   810
				params[4],
dvander@2445
   811
				params[3]);
dvander@2445
   812
		}
dvander@2445
   813
dvander@2445
   814
		num_read = (cell_t)fread(buffer, 1, params[4], pFile);
dvander@2445
   815
dvander@2445
   816
		if (num_read != params[4] && ferror(pFile))
dvander@2445
   817
		{
dvander@2445
   818
			return -1;
dvander@2445
   819
		}
dvander@2445
   820
dvander@2445
   821
		return num_read;
dvander@2445
   822
	}
dvander@2445
   823
dvander@1796
   824
	char val;
dvander@1796
   825
	while (1)
dvander@1796
   826
	{
dvander@2445
   827
		if (params[3] == 0 || num_read >= params[3] - 1)
dvander@1796
   828
		{
dvander@1796
   829
			break;
dvander@1796
   830
		}
dvander@1796
   831
		if (fread(&val, sizeof(val), 1, pFile) != 1)
dvander@1796
   832
		{
dvander@1796
   833
			if (ferror(pFile))
dvander@1796
   834
			{
dvander@1796
   835
				return -1;
dvander@1796
   836
			}
dvander@1796
   837
			break;
dvander@1796
   838
		}
dvander@1796
   839
		if (val == '\0')
dvander@1796
   840
		{
dvander@1796
   841
			break;
dvander@1796
   842
		}
dvander@1796
   843
		if (params[3] > 0 && num_read < params[3] - 1)
dvander@1796
   844
		{
dvander@1796
   845
			buffer[num_read++] = val;
dvander@1796
   846
		}
dvander@1796
   847
	}
dvander@1796
   848
dvander@1796
   849
	if (params[3] > 0)
dvander@1796
   850
	{
dvander@1796
   851
		buffer[num_read] = '\0';
dvander@1796
   852
	}
dvander@1796
   853
dvander@1796
   854
	return num_read;
dvander@1796
   855
}
dvander@1796
   856
dvander@1796
   857
static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
dvander@1796
   858
{
dvander@1796
   859
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1796
   860
	HandleError herr;
dvander@1796
   861
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1796
   862
	FILE *pFile;
dvander@1796
   863
dvander@1796
   864
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1796
   865
		!= HandleError_None)
dvander@1796
   866
	{
dvander@1796
   867
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1796
   868
	}
dvander@1796
   869
dvander@1796
   870
	cell_t *data;
dvander@1796
   871
	pContext->LocalToPhysAddr(params[2], &data);
dvander@1796
   872
dvander@1796
   873
	if (params[4] != 1 && params[4] != 2 && params[4] != 4)
dvander@1796
   874
	{
dvander@1796
   875
		return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
dvander@1796
   876
	}
dvander@1796
   877
dvander@1796
   878
	/* :NOTE: This really isn't compatible with big endian but we will never have to worry about that. */
dvander@1796
   879
dvander@1796
   880
	if (params[4] == 4)
dvander@1796
   881
	{
dvander@1796
   882
		if (fwrite(data, sizeof(cell_t), params[3], pFile) != (size_t)params[3])
dvander@1796
   883
		{
dvander@1796
   884
			return 0;
dvander@1796
   885
		}
dvander@1796
   886
	}
dvander@1796
   887
	else if (params[4] == 2)
dvander@1796
   888
	{
dvander@1796
   889
		for (cell_t i = 0; i < params[3]; i++)
dvander@1796
   890
		{
dvander@1796
   891
			if (fwrite(&data[i], sizeof(int16_t), 1, pFile) != 1)
dvander@1796
   892
			{
dvander@1796
   893
				return 0;
dvander@1796
   894
			}
dvander@1796
   895
		}
dvander@1796
   896
	}
dvander@1796
   897
	else if (params[4] == 1)
dvander@1796
   898
	{
dvander@1796
   899
		for (cell_t i = 0; i < params[3]; i++)
dvander@1796
   900
		{
dvander@1796
   901
			if (fwrite(&data[i], sizeof(int8_t), 1, pFile) != 1)
dvander@1796
   902
			{
dvander@1796
   903
				return 0;
dvander@1796
   904
			}
dvander@1796
   905
		}
dvander@1796
   906
	}
dvander@1796
   907
dvander@1796
   908
	return 1;
dvander@1796
   909
}
dvander@1796
   910
dvander@1796
   911
static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params)
dvander@1796
   912
{
dvander@1796
   913
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@1796
   914
	HandleError herr;
dvander@1796
   915
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1796
   916
	FILE *pFile;
dvander@1796
   917
dvander@1796
   918
	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
dvander@1796
   919
		!= HandleError_None)
dvander@1796
   920
	{
dvander@1796
   921
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
dvander@1796
   922
	}
dvander@1796
   923
dvander@1796
   924
	char *buffer;
dvander@1796
   925
	pContext->LocalToString(params[2], &buffer);
dvander@1796
   926
dvander@1796
   927
	size_t len = strlen(buffer);
dvander@1796
   928
dvander@1796
   929
	if (params[3])
dvander@1796
   930
	{
dvander@1796
   931
		len++;
dvander@1796
   932
	}
dvander@1796
   933
dvander@1796
   934
	return (fwrite(buffer, sizeof(char), len, pFile) == len) ? 1 : 0;
dvander@1796
   935
}
dvander@1796
   936
dvander@1914
   937
static cell_t sm_AddGameLogHook(IPluginContext *pContext, const cell_t *params)
dvander@1914
   938
{
dvander@1914
   939
	IPluginFunction *pFunction;
dvander@1914
   940
dvander@1914
   941
	if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
dvander@1914
   942
	{
dvander@1914
   943
		return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
dvander@1914
   944
	}
dvander@1914
   945
dvander@1914
   946
	s_FileNatives.AddLogHook(pFunction);
dvander@1914
   947
	
dvander@1914
   948
	return 1;
dvander@1914
   949
}
dvander@1914
   950
dvander@1914
   951
static cell_t sm_RemoveGameLogHook(IPluginContext *pContext, const cell_t *params)
dvander@1914
   952
{
dvander@1914
   953
	IPluginFunction *pFunction;
dvander@1914
   954
dvander@1914
   955
	if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
dvander@1914
   956
	{
dvander@1914
   957
		return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
dvander@1914
   958
	}
dvander@1914
   959
dvander@1914
   960
	s_FileNatives.RemoveLogHook(pFunction);
dvander@1914
   961
dvander@1914
   962
	return 1;
dvander@1914
   963
}
dvander@1914
   964
dvander@252
   965
REGISTER_NATIVES(filesystem)
dvander@252
   966
{
dvander@252
   967
	{"OpenDirectory",			sm_OpenDirectory},
dvander@252
   968
	{"ReadDirEntry",			sm_ReadDirEntry},
faluco@274
   969
	{"OpenFile",				sm_OpenFile},
faluco@274
   970
	{"DeleteFile",				sm_DeleteFile},
faluco@274
   971
	{"ReadFileLine",			sm_ReadFileLine},
faluco@274
   972
	{"IsEndOfFile",				sm_IsEndOfFile},
faluco@274
   973
	{"FileSeek",				sm_FileSeek},
faluco@274
   974
	{"FilePosition",			sm_FilePosition},
faluco@274
   975
	{"FileExists",				sm_FileExists},
faluco@274
   976
	{"RenameFile",				sm_RenameFile},
faluco@274
   977
	{"DirExists",				sm_DirExists},
faluco@274
   978
	{"FileSize",				sm_FileSize},
faluco@274
   979
	{"RemoveDir",				sm_RemoveDir},
faluco@274
   980
	{"WriteFileLine",			sm_WriteFileLine},
dvander@345
   981
	{"BuildPath",				sm_BuildPath},
dvander@636
   982
	{"LogToGame",				sm_LogToGame},
dvander@636
   983
	{"LogMessage",				sm_LogMessage},
dvander@347
   984
	{"LogError",				sm_LogError},
dvander@821
   985
	{"FlushFile",				sm_FlushFile},
dvander@1370
   986
	{"GetFileTime",				sm_GetFileTime},
dvander@1378
   987
	{"LogToOpenFile",			sm_LogToOpenFile},
dvander@1379
   988
	{"LogToOpenFileEx",			sm_LogToOpenFileEx},
dvander@1796
   989
	{"ReadFile",				sm_ReadFile},
dvander@1796
   990
	{"ReadFileString",			sm_ReadFileString},
dvander@1796
   991
	{"WriteFile",				sm_WriteFile},
dvander@1796
   992
	{"WriteFileString",			sm_WriteFileString},
dvander@1914
   993
	{"AddGameLogHook",			sm_AddGameLogHook},
dvander@1914
   994
	{"RemoveGameLogHook",		sm_RemoveGameLogHook},
dvander@2307
   995
	{"CreateDirectory",			sm_CreateDirectory},
dvander@252
   996
	{NULL,						NULL},
dvander@252
   997
};