]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/common/vfs.c
handle forbidden dir exclusions properly now
[xonotic/netradiant.git] / tools / quake3 / common / vfs.c
index 258656612827fb9ae69dd23966b66ce1aedb1f57..9c75cb3a8549b0dc5fba3d1cc63069ce3672ffdd 100644 (file)
@@ -41,26 +41,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // Leonardo Zide (leo@lokigames.com)
 //
 
-#include <stdio.h>
-
-#if defined (__linux__) || defined (__APPLE__)
-#include <dirent.h>
-#include <unistd.h>
-#else
-#include <wtypes.h>
-#include <io.h>
-#define R_OK 04
-#define S_ISDIR(mode) (mode & _S_IFDIR)
-#define PATH_MAX 260
-#endif
-
 #include <string.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 
 #include "cmdlib.h"
+#include "filematch.h"
 #include "mathlib.h"
-#include <glib.h>
 #include "inout.h"
 #include "vfs.h"
 #include "unzip.h"
@@ -78,8 +65,10 @@ typedef struct
 
 static GSList*  g_unzFiles;
 static GSList*  g_pakFiles;
-static char     g_strDirs[VFS_MAXDIRS][PATH_MAX];
+static char     g_strDirs[VFS_MAXDIRS][PATH_MAX+1];
 static int      g_numDirs;
+char     g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX+1];
+int      g_numForbiddenDirs = 0;
 static gboolean g_bUsePak = TRUE;
 
 // =============================================================================
@@ -168,13 +157,32 @@ void vfsInitDirectory (const char *path)
   char filename[PATH_MAX];
   char *dirlist;
   GDir *dir;
+  int j;
+
+  for(j = 0; j < g_numForbiddenDirs; ++j)
+  {
+    char* dbuf = g_strdup(path);
+    if(*dbuf && dbuf[strlen(dbuf)-1] == '/')
+      dbuf[strlen(dbuf)-1] = 0;
+    const char *p = strrchr(dbuf, '/');
+    p = (p ? (p+1) : dbuf);
+    if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
+    {
+      g_free(dbuf);
+      break;
+    }
+    g_free(dbuf);
+  }
+  if(j < g_numForbiddenDirs)
+    return;
   
-  if (g_numDirs == (VFS_MAXDIRS-1))
+  if (g_numDirs == VFS_MAXDIRS)
     return;
   
   Sys_Printf ("VFS Init: %s\n", path);
   
-  strcpy (g_strDirs[g_numDirs], path);
+  strncpy (g_strDirs[g_numDirs], path, PATH_MAX);
+  g_strDirs[g_numDirs][PATH_MAX] = 0;
   vfsFixDOSName (g_strDirs[g_numDirs]);
   vfsAddSlash (g_strDirs[g_numDirs]);
   g_numDirs++;
@@ -191,10 +199,32 @@ void vfsInitDirectory (const char *path)
         if(name == NULL)
           break;
 
+        for(j = 0; j < g_numForbiddenDirs; ++j)
+        {
+          const char *p = strrchr(name, '/');
+          p = (p ? (p+1) : name);
+          if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
+            break;
+        }
+        if(j < g_numForbiddenDirs)
+          continue;
+
         dirlist = g_strdup(name);
 
         {
           char *ext = strrchr (dirlist, '.');
+
+         if(ext && !Q_stricmp(ext, ".pk3dir"))
+         {
+           if (g_numDirs == VFS_MAXDIRS)
+             continue;
+           snprintf(g_strDirs[g_numDirs], PATH_MAX, "%s/%s", path, name);
+           g_strDirs[g_numDirs][PATH_MAX] = '\0';
+           vfsFixDOSName (g_strDirs[g_numDirs]);
+           vfsAddSlash (g_strDirs[g_numDirs]);
+           ++g_numDirs;
+         }
+
           if ((ext == NULL) || (Q_stricmp (ext, ".pk3") != 0))
             continue;
         }
@@ -280,9 +310,16 @@ int vfsLoadFile (const char *filename, void **bufferptr, int index)
     
     *bufferptr = safe_malloc (len+1);
     if (*bufferptr == NULL)
-      return -1;
+       {
+               fclose(f);
+               return -1;
+       }
     
-    fread (*bufferptr, 1, len, f);
+    if(fread (*bufferptr, 1, len, f) != (size_t) len)
+       {
+               fclose(f);
+               return -1;
+       }
     fclose (f);
     
     // we need to end the buffer with a 0
@@ -317,9 +354,16 @@ int vfsLoadFile (const char *filename, void **bufferptr, int index)
         
         *bufferptr = safe_malloc (len+1);
         if (*bufferptr == NULL)
+               {
+                 fclose(f);
           return -1;
+               }
         
-        fread (*bufferptr, 1, len, f);
+        if(fread (*bufferptr, 1, len, f) != (size_t) len)
+               {
+                 fclose(f);
+          return -1;
+               }
         fclose (f);
         
         // we need to end the buffer with a 0