]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/common/vfs.c
Merge remote-tracking branch 'ttimo/master'
[xonotic/netradiant.git] / tools / quake3 / common / vfs.c
index 04af830e1ee7d8c4917223a6ea416d0bdd4d2617..ada7ee713c14d8548e51b273e7e119a95401157d 100644 (file)
 // 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;
 
 // =============================================================================
@@ -169,14 +158,34 @@ void vfsInitDirectory( const char *path ){
        char filename[PATH_MAX];
        char *dirlist;
        GDir *dir;
+       int j;
 
-       if ( g_numDirs == ( VFS_MAXDIRS - 1 ) ) {
+       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 ) {
                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++;
@@ -192,10 +201,34 @@ void vfsInitDirectory( const char *path ){
                                        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;
                                        }
@@ -281,10 +314,14 @@ 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
@@ -318,10 +355,14 @@ 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