2 #include "sm_globals.h"
4 #include "LibrarySys.h"
5 #include "sm_stringutil.h"
7 HandleType_t g_FileType;
8 HandleType_t g_DirType;
12 public IHandleTypeDispatch
15 virtual void OnSourceModAllInitialized()
17 g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
18 g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
20 virtual void OnSourceModShutdown()
22 g_HandleSys.RemoveType(g_DirType, g_pCoreIdent);
23 g_HandleSys.RemoveType(g_FileType, g_pCoreIdent);
27 virtual void OnHandleDestroy(HandleType_t type, void *object)
29 if (type == g_FileType)
31 FILE *fp = (FILE *)object;
33 } else if (type == g_DirType) {
34 IDirectory *pDir = (IDirectory *)object;
35 g_LibSys.CloseDirectory(pDir);
41 static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
45 if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE)
47 pContext->ThrowNativeErrorEx(err, NULL);
51 char realpath[PLATFORM_MAX_PATH+1];
52 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
54 IDirectory *pDir = g_LibSys.OpenDirectory(realpath);
60 return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
63 static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
65 Handle_t hndl = static_cast<Handle_t>(params[1]);
72 sec.pIdentity = g_pCoreIdent;
74 if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
77 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
80 if (!pDir->MoreFiles())
86 if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
88 pContext->ThrowNativeErrorEx(err, NULL);
92 if (pDir->IsEntryDirectory())
95 } else if (pDir->IsEntryFile()) {
101 const char *path = pDir->GetEntryName();
102 if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
105 pContext->ThrowNativeErrorEx(err, NULL);
114 static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
118 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
120 pContext->ThrowNativeErrorEx(err, NULL);
123 if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE)
125 pContext->ThrowNativeErrorEx(err, NULL);
129 char realpath[PLATFORM_MAX_PATH+1];
130 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
132 FILE *pFile = fopen(realpath, mode);
138 return g_HandleSys.CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
141 static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
145 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
147 pContext->ThrowNativeErrorEx(err, NULL);
151 char realpath[PLATFORM_MAX_PATH+1];
152 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
154 return (unlink(realpath)) ? 0 : 1;
157 static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
159 Handle_t hndl = static_cast<Handle_t>(params[1]);
166 sec.pIdentity = g_pCoreIdent;
168 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
171 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
175 if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE)
177 pContext->ThrowNativeErrorEx(err, NULL);
181 fgets(buf, params[3], pFile);
186 static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
188 Handle_t hndl = static_cast<Handle_t>(params[1]);
194 sec.pIdentity = g_pCoreIdent;
196 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
199 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
202 return (feof(pFile)) ? 1 : 0;
205 static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
207 Handle_t hndl = static_cast<Handle_t>(params[1]);
213 sec.pIdentity = g_pCoreIdent;
215 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
218 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
221 fseek(pFile, params[2], params[3]);
226 static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params)
228 Handle_t hndl = static_cast<Handle_t>(params[1]);
234 sec.pIdentity = g_pCoreIdent;
236 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
239 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
245 static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
249 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
251 pContext->ThrowNativeErrorEx(err, NULL);
255 char realpath[PLATFORM_MAX_PATH+1];
256 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
257 #ifdef PLATFORM_WINDOWS
259 if (_stat(realpath, &s) != 0)
263 if (s.st_mode & S_IFREG)
268 #else if defined PLATFORM_POSIX
270 if (stat(realpath, &s) != 0)
274 if (S_ISREG(s.st_mode))
282 static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
284 char *newpath, *oldpath;
286 if ((err=pContext->LocalToString(params[1], &newpath)) != SP_ERROR_NONE)
288 pContext->ThrowNativeErrorEx(err, NULL);
291 if ((err=pContext->LocalToString(params[2], &oldpath)) != SP_ERROR_NONE)
293 pContext->ThrowNativeErrorEx(err, NULL);
297 char new_realpath[PLATFORM_MAX_PATH+1];
298 g_SourceMod.BuildPath(Path_SM, new_realpath, sizeof(new_realpath), "%s", newpath);
299 char old_realpath[PLATFORM_MAX_PATH+1];
300 g_SourceMod.BuildPath(Path_SM, old_realpath, sizeof(old_realpath), "%s", oldpath);
302 #ifdef PLATFORM_WINDOWS
303 return (MoveFileA(old_realpath, new_realpath)) ? 1 : 0;
304 #else if defined PLATFORM_POSIX
305 return (rename(old_realpath, new_realpath)) ? 0 : 1;
309 static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
313 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
315 pContext->ThrowNativeErrorEx(err, NULL);
319 char realpath[PLATFORM_MAX_PATH+1];
320 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
321 #ifdef PLATFORM_WINDOWS
323 if (_stat(realpath, &s) != 0)
327 if (s.st_mode & S_IFDIR)
332 #else if defined PLATFORM_POSIX
334 if (stat(realpath, &s) != 0)
338 if (S_ISDIR(s.st_mode))
346 static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
350 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
352 pContext->ThrowNativeErrorEx(err, NULL);
356 char realpath[PLATFORM_MAX_PATH+1];
357 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
358 #ifdef PLATFORM_WINDOWS
360 if (_stat(realpath, &s) != 0)
364 if (s.st_mode & S_IFREG)
366 return static_cast<cell_t>(s.st_size);
369 #else if defined PLATFORM_POSIX
371 if (stat(realpath, &s) != 0)
375 if (S_ISREG(s.st_mode))
377 return static_cast<cell_t>(s.st_size);
383 static cell_t sm_RemoveDir(IPluginContext *pContext, const cell_t *params)
387 if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE)
389 pContext->ThrowNativeErrorEx(err, NULL);
393 char realpath[PLATFORM_MAX_PATH+1];
394 g_SourceMod.BuildPath(Path_SM, realpath, sizeof(realpath), "%s", name);
396 return (rmdir(realpath)) ? 0 : 1;
399 static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
401 Handle_t hndl = static_cast<Handle_t>(params[1]);
407 sec.pIdentity = g_pCoreIdent;
409 if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
412 return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
417 if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
419 pContext->ThrowNativeErrorEx(err, NULL);
425 atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
426 fprintf(pFile, "%s\n", buffer);
431 static FileNatives s_FileNatives;
433 REGISTER_NATIVES(filesystem)
435 {"OpenDirectory", sm_OpenDirectory},
436 {"ReadDirEntry", sm_ReadDirEntry},
437 {"OpenFile", sm_OpenFile},
438 {"DeleteFile", sm_DeleteFile},
439 {"ReadFileLine", sm_ReadFileLine},
440 {"IsEndOfFile", sm_IsEndOfFile},
441 {"FileSeek", sm_FileSeek},
442 {"FilePosition", sm_FilePosition},
443 {"FileExists", sm_FileExists},
444 {"RenameFile", sm_RenameFile},
445 {"DirExists", sm_DirExists},
446 {"FileSize", sm_FileSize},
447 {"RemoveDir", sm_RemoveDir},
448 {"WriteFileLine", sm_WriteFileLine},