67# define lseek _lseeki64
75# define unlink _unlink
81# define MAX_OSWPATH MAX_OSPATH
82# define WPATHDEF(var) wchar var[MAX_OSWPATH]
84# define WPATHDEF(var) ;
90# define FILEDESC_INVALID NULL
91# define FILEDESC_ISVALID(fd) ((fd) != NULL)
92# define FILEDESC_READ(fd,buf,count) ((fs_offset_t)SDL_RWread(fd, buf, 1, count))
93# define FILEDESC_WRITE(fd,buf,count) ((fs_offset_t)SDL_RWwrite(fd, buf, 1, count))
94# define FILEDESC_CLOSE SDL_RWclose
95# define FILEDESC_SEEK SDL_RWseek
97 filedesc_t new_fd = SDL_RWFromFile(filename,
"rb");
98 if (SDL_RWseek(new_fd, SDL_RWseek(fd, 0, RW_SEEK_CUR), RW_SEEK_SET) < 0) {
104# define unlink(name) Con_DPrintf("Sorry, no unlink support when trying to unlink %s.\n", (name))
107# define FILEDESC_INVALID -1
108# define FILEDESC_ISVALID(fd) ((fd) != -1)
109# define FILEDESC_READ read
110# define FILEDESC_WRITE write
111# define FILEDESC_CLOSE close
112# define FILEDESC_SEEK lseek
137 char *
const p = (
char *)
buf;
147 }
while (cursor <
length);
161 const char *
const p = (
const char *)
buf;
169 }
while (cursor <
length);
174#define FILEDESC_READ ReadAll
176#define FILEDESC_WRITE WriteAll
207#define ZIP_DATA_HEADER 0x504B0304
208#define ZIP_CDIR_HEADER 0x504B0102
209#define ZIP_END_HEADER 0x504B0506
212#define ZIP_MAX_COMMENTS_SIZE ((unsigned short)0xFFFF)
213#define ZIP_END_CDIR_SIZE 22
214#define ZIP_CDIR_CHUNK_BASE_SIZE 46
215#define ZIP_LOCAL_CHUNK_BASE_SIZE 30
220#define qz_inflate inflate
221#define qz_inflateEnd inflateEnd
222#define qz_inflateInit2_ inflateInit2_
223#define qz_inflateReset inflateReset
224#define qz_deflateInit2_ deflateInit2_
225#define qz_deflateEnd deflateEnd
226#define qz_deflate deflate
227#define Z_MEMLEVEL_DEFAULT 8
231#define Z_SYNC_FLUSH 2
234#define Z_STREAM_END 1
235#define Z_STREAM_ERROR (-2)
236#define Z_DATA_ERROR (-3)
237#define Z_MEM_ERROR (-4)
238#define Z_BUF_ERROR (-5)
239#define ZLIB_VERSION "1.2.3"
243#define Z_MEMLEVEL_DEFAULT 8
246#define Z_DEFAULT_COMPRESSION (-1)
248#define Z_SYNC_FLUSH 2
249#define Z_FULL_FLUSH 3
294#define QFILE_FLAG_PACKED (1 << 0)
296#define QFILE_FLAG_DEFLATED (1 << 1)
298#define QFILE_FLAG_DATA (1 << 2)
300#define QFILE_FLAG_REMOVE (1 << 3)
302#define FILE_BUFF_SIZE 2048
337typedef struct pk3_endOfCentralDir_s
352typedef struct dpackfile_s
358typedef struct dpackheader_s
370#define PACKFILE_FLAG_TRUEOFFS (1 << 0)
372#define PACKFILE_FLAG_DEFLATED (1 << 1)
374#define PACKFILE_FLAG_SYMLINK (1 << 2)
376typedef struct packfile_s
399typedef struct searchpath_s
440#define MAX_FILES_IN_PACK 65536
457cvar_t fs_unload_dlcache = {
CF_CLIENT,
"fs_unload_dlcache",
"1",
"if enabled, unload dlcache's loaded pak/pk3 files when changing server and/or map WARNING: disabling unloading can cause servers to override assets of other servers, \"memory leaking\" by dlcache assets never unloading and many more issues"};
471#if defined(WIN32) && defined(ZLIB_USES_WINAPI)
472# define ZEXPORT WINAPI
486#define qz_inflateInit2(strm, windowBits) \
487 qz_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
488#define qz_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
489 qz_deflateInit2_((strm), (level), (method), (windowBits), (memLevel), (strategy), ZLIB_VERSION, sizeof(z_stream))
496 {
"inflate", (
void **) &qz_inflate},
497 {
"inflateEnd", (
void **) &qz_inflateEnd},
498 {
"inflateInit2_", (
void **) &qz_inflateInit2_},
499 {
"inflateReset", (
void **) &qz_inflateReset},
500 {
"deflateInit2_", (
void **) &qz_deflateInit2_},
501 {
"deflateEnd", (
void **) &qz_deflateEnd},
502 {
"deflate", (
void **) &qz_deflate},
511static HRESULT (WINAPI *qSHGetFolderPath) (HWND hwndOwner,
int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
514 {
"SHGetFolderPathW", (
void **) &qSHGetFolderPath},
517static const char* shfolderdllnames [] =
524const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}};
525#define qREFKNOWNFOLDERID const GUID *
526#define qKF_FLAG_CREATE 0x8000
527#define qKF_FLAG_NO_ALIAS 0x1000
528static HRESULT (WINAPI *qSHGetKnownFolderPath) (qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
531 {
"SHGetKnownFolderPath", (
void **) &qSHGetKnownFolderPath},
534static const char* shell32dllnames [] =
541static HRESULT (WINAPI *qCoInitializeEx)(LPVOID pvReserved, DWORD dwCoInit);
542static void (WINAPI *qCoUninitialize)(
void);
543static void (WINAPI *qCoTaskMemFree)(LPVOID pv);
546 {
"CoInitializeEx", (
void **) &qCoInitializeEx},
547 {
"CoUninitialize", (
void **) &qCoUninitialize},
548 {
"CoTaskMemFree", (
void **) &qCoTaskMemFree},
551static const char* ole32dllnames [] =
586 const char* dllnames [] =
589# ifdef ZLIB_USES_WINAPI
640 unsigned char *
buffer, *ptr;
714 unsigned char *central_dir, *ptr;
737 for (ind = 0; ind < eocd->
nbentries; ind++)
770 if ((ptr[8] & 0x21) == 0 && (ptr[38] & 0x18) == 0)
773 if (remaining < namesize || namesize >= (
int)
sizeof (*pack->
files))
782 char filename [
sizeof (pack->
files[0].
name)];
787 namesize =
min(namesize, (
int)
sizeof (filename) - 1);
789 filename[namesize] =
'\0';
823 if (central_dir !=
NULL)
845 Con_Printf (
"%s is not a PK3 file\n", packfile);
853 Con_Printf (
"%s is a multi-volume ZIP archive\n", packfile);
860#if MAX_FILES_IN_PACK < 65535
873 pack->
handle = packhandle;
878 if (real_nb_files < 0)
880 Con_Printf (
"%s is not a valid PK3 file\n", packfile);
886 Con_DPrintf(
"Added packfile %s (%i files)\n", packfile, real_nb_files);
958 int (*strcmp_funct) (
const char* str1,
const char* str2);
959 int left,
right, middle;
962 strcmp_funct = pack->
ignorecase ? strcasecmp : strcmp;
967 while (left <=
right)
971 middle = (left +
right) / 2;
986 pfile = &pack->
files[left];
987 memmove (pfile + 1, pfile, (pack->
numfiles - left) * sizeof (*pfile));
1009 if (_wmkdir(pathw) == -1)
1011 if (mkdir(path, 0777) == -1)
1034 if (*
ofs ==
'/' || *
ofs ==
'\\')
1084 int i, numpackfiles;
1092 if(
FILEDESC_READ (packhandle, (
void *)&header,
sizeof(header)) !=
sizeof(header))
1094 Con_Printf (
"%s is not a packfile\n", packfile);
1098 if (memcmp(header.
id,
"PACK", 4))
1100 Con_Printf (
"%s is not a packfile\n", packfile);
1109 Con_Printf (
"%s has an invalid directory size\n", packfile);
1118 Con_Printf (
"%s has %i files\n", packfile, numpackfiles);
1127 Con_Printf(
"%s is an incomplete PAK, not loading\n", packfile);
1136 pack->
handle = packhandle;
1141 for (
i = 0;
i < numpackfiles;
i++)
1154 Con_DPrintf(
"Added packfile %s (%i files)\n", packfile, numpackfiles);
1175 Con_DPrintf(
"Added packfile %s (virtual pack)\n", dirname);
1206 *already_loaded =
true;
1212 *already_loaded =
false;
1214 if(!strcasecmp(ext,
"pk3dir") || !strcasecmp(ext,
"dpkdir"))
1216 else if(!strcasecmp(ext,
"pak"))
1218 else if(!strcasecmp(ext,
"pk3") || !strcasecmp(ext,
"dpk"))
1220 else if(!strcasecmp(ext,
"obb"))
1223 Con_Printf(
"\"%s\" does not have a pack extension\n", pakfile);
1239 if(!insertion_point->
next)
1241 if(insertion_point->
next->pack)
1243 insertion_point = insertion_point->
next;
1249 if(!insertion_point)
1259 search->
next = insertion_point->
next;
1260 insertion_point->
next = search;
1278 if(!strcasecmp(pak->
shortname + l - 7,
".pk3dir") || !strcasecmp(pak->
shortname + l - 7,
".dpkdir"))
1282 if(!strcasecmp(pak->
filename + l - 7,
".pk3dir") || !strcasecmp(pak->
filename + l - 7,
".dpkdir"))
1316 *already_loaded =
false;
1320 if(!search || search->
pack)
1322 Con_Printf(
"could not find pak \"%s\"\n", pakfile);
1405 const char *separator, *backslash, *colon, *dot;
1407 dot = strrchr(in,
'.');
1411 separator = strrchr(in,
'/');
1412 backslash = strrchr(in,
'\\');
1413 if (!separator || separator < backslash)
1414 separator = backslash;
1415 colon = strrchr(in,
':');
1416 if (!separator || separator < colon)
1419 if (separator && (dot < separator))
1433 const char *separator, *backslash, *colon;
1435 separator = strrchr(in,
'/');
1436 backslash = strrchr(in,
'\\');
1437 if (!separator || separator < backslash)
1438 separator = backslash;
1439 colon = strrchr(in,
':');
1440 if (!separator || separator < colon)
1442 return separator ? separator + 1 : in;
1494 searchnext = search->
next;
1503 searchprev->next = search->
next;
1514 searchprev = search;
1515 search = searchnext;
1589 unlink (
va(vabuf,
sizeof(vabuf),
"%s/qconsole.log",
fs_gamedir));
1602 Con_Print(
"Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
1604 Con_Print(
"Playing shareware version.\n");
1607 Con_Print(
"Playing registered version.\n");
1611 Con_Print(
"Playing registered version.\n");
1613 Con_Print(
"Playing shareware version.\n");
1650 for (
i = 0;
i < numgamedirs_ok; ++
i)
1654 Sys_Error(
"BUG: nasty gamedir name \"%s\" in gamemode_info", gamedirs_ok[
i]);
1664 for (
i = 0;
i < numgamedirs && (size_t)numgamedirs_ok <
sizeof(gamedirs_ok) /
sizeof(gamedirs_ok[0]); ++
i)
1667 for (j = 0; j < numgamedirs_ok; ++j)
1668 if (!strcasecmp(gamedirs_ok[j], gamedirs[
i]))
1671 for (k = j; k < numgamedirs_ok; ++k)
1672 gamedirs_ok[k] = gamedirs_ok[k + 1];
1694 gamedirs_ok[numgamedirs_ok++] = gamedirs[
i];
1699 for (
i = 0;
i < numgamedirs_ok;
i++)
1702 if (
i == numgamedirs_ok)
1773 for (
i = 0;
i < numgamedirs;
i++)
1779 Con_Printf(
CON_ERROR "Can not change gamedir while client is connected or server is running!\n");
1801 f =
FS_SysOpen(
va(vabuf,
sizeof(vabuf),
"%smodinfo.txt", gamedir),
"r",
false);
1827 static char buf[8192];
1914 const char **new_argv;
1916 int args_left = 256;
1919 new_argv[0] =
"dummy";
1948#if defined(__IPHONEOS__)
1959 char homedir[MAX_OSWPATH];
1964 char mydocsdir[MAX_OSWPATH];
1965 wchar mydocsdirw[MAX_OSWPATH];
1966 char savedgamesdir[MAX_OSWPATH];
1967 wchar *savedgamesdirw;
1983 if (qSHGetFolderPath && qSHGetFolderPath(
NULL, CSIDL_PERSONAL,
NULL, 0, mydocsdirw) == S_OK)
1985 NARROW(mydocsdirw, mydocsdir);
1990 _wdupenv_s(&homedirw, &homedirwlen, L
"USERPROFILE");
1991 NARROW(homedirw, homedir);
1999 homedirw = _wgetenv(L
"USERPROFILE");
2000 NARROW(homedirw, homedir);
2013 if (qSHGetKnownFolderPath && qCoInitializeEx && qCoTaskMemFree && qCoUninitialize)
2015 savedgamesdir[0] = 0;
2016 qCoInitializeEx(
NULL, COINIT_APARTMENTTHREADED);
2024 if (qSHGetKnownFolderPath(&qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS,
NULL, &savedgamesdirw) == S_OK)
2026 NARROW(savedgamesdirw, savedgamesdir);
2027 qCoTaskMemFree(savedgamesdirw);
2030 if (savedgamesdir[0])
2051 homedir = getenv(
"HOME");
2059 homedir = getenv(
"HOME");
2082#if !defined(__IPHONEOS__)
2098 if(access(
va(vabuf,
sizeof(vabuf),
"%s%s/", userdir,
gamedirname1), W_OK | X_OK) >= 0)
2124 Cmd_AddCommand(
CF_SHARED,
"gamedir",
FS_GameDir_f,
"changes active gamedir list, can take multiple arguments which shouldn't include the base directory, the last gamedir is the \"primary\" and files will be saved there (example usage: gamedir ctf id1)");
2131#ifdef __EMSCRIPTEN__
2166#elif defined(__ANDROID__)
2168#elif defined(MACOSX)
2170 if (strstr(
sys.
argv[0],
".app/"))
2177 struct stat statresult;
2200 GetCurrentDirectoryW(
sizeof(fs_basedirw) /
sizeof(*fs_basedirw), fs_basedirw);
2241 if (userdirstatus[dirmode] == 1)
2243 else if (userdirstatus[dirmode] == 0)
2246 Con_DPrintf(
"userdir %i (not applicable)\n", dirmode);
2250 if (preferreduserdirmode == 0 && userdirstatus[0] < 1)
2251 preferreduserdirmode = highestuserdirmode;
2254 if (userdirstatus[dirmode] == 1)
2257 if (dirmode == 0 && preferreduserdirmode > 0)
2258 for (dirmode = preferreduserdirmode;dirmode > 0;dirmode--)
2259 if (userdirstatus[dirmode] >= 0)
2263 Con_DPrintf(
"userdir %i is the winner\n", dirmode);
2282 cmdline_gamedirs[numgamedirs++] =
sys.
argv[
i];
2388 qbool dolock =
false;
2400 opt = O_CREAT | O_TRUNC;
2404 opt = O_CREAT | O_APPEND;
2410 for (ind = 1;
mode[ind] !=
'\0'; ind++)
2438 handle = SDL_RWFromFile(filepath,
mode);
2441 WIDE(filepath, filepathw);
2442# if _MSC_VER >= 1400
2443 _wsopen_s(&handle, filepathw,
mod | opt, (dolock ? ((
mod == O_RDONLY) ? _SH_DENYRD : _SH_DENYRW) : _SH_DENYNO), _S_IREAD | _S_IWRITE);
2445 handle = _wsopen(filepathw,
mod | opt, (dolock ? ((
mod == O_RDONLY) ? _SH_DENYRD : _SH_DENYRW) : _SH_DENYNO), _S_IREAD | _S_IWRITE);
2448 handle = open(filepath,
mod | opt, 0666);
2449 if(handle >= 0 && dolock)
2452 l.l_type = ((
mod == O_RDONLY) ? F_RDLCK : F_WRLCK);
2453 l.l_whence = SEEK_SET;
2456 if(fcntl(handle, F_SETLK, &l) == -1)
2499 file->real_length =
FILEDESC_SEEK (file->handle, 0, SEEK_END);
2503 file->position = file->real_length;
2524 pfile = &pack->
files[pack_ind];
2536 "You need the Zlib DLL to use compressed files\n",
2546 Con_Printf (
"FS_OpenPackedFile: can't lseek to %s in %s (offset: %08x%08x)\n",
2554 Con_Printf (
"FS_OpenPackedFile: can't dup package's handle (pack: %s)\n", pack->
filename);
2559 memset (file, 0,
sizeof (*file));
2560 file->handle = dup_handle;
2562 file->real_length = pfile->
realsize;
2563 file->offset = pfile->
offset;
2593 Con_Printf (
"FS_OpenPackedFile: inflate init error (file: %s)\n", pfile->
name);
2626 if (strstr(path,
"\\"))
2633 if (strstr(path,
":"))
2637 if (strstr(path,
"//"))
2641 if (strstr(path,
".."))
2649 if (strstr(path,
"./"))
2653 if (isgamedir && path[
strlen(path)-1] ==
'/')
2657 if (strstr(path,
"/."))
2675 for (; *path; path++)
2701 int (*strcmp_funct) (
const char* str1,
const char* str2);
2702 int left,
right, middle;
2705 strcmp_funct = pak->
ignorecase ? strcasecmp : strcmp;
2710 while (left <=
right)
2714 middle = (left +
right) / 2;
2729 *canonicalname =
NULL;
2739 *canonicalname = pak->
files[middle].
name;
2762 *canonicalname =
name;
2774 *canonicalname =
NULL;
2813 if(symlinkLevels <= 0)
2815 Con_Printf(
"symlink: %s: too many levels of symbolic links\n", filename);
2823 const char *mergeslash;
2828 count =
FS_Read(linkfile, linkbuf,
sizeof(linkbuf) - 1);
2835 mergeslash = strrchr(filename,
'/');
2836 mergestart = linkbuf;
2838 mergeslash = filename;
2839 while(!strncmp(mergestart,
"../", 3))
2842 while(mergeslash > filename)
2845 if(*mergeslash ==
'/')
2850 if(mergeslash == filename)
2858 int spaceNeeded = mergeslash - filename + 1;
2859 int spaceRemoved = mergestart - linkbuf;
2865 memmove(linkbuf + spaceNeeded, linkbuf + spaceRemoved,
count - spaceRemoved);
2866 memcpy(linkbuf, filename, spaceNeeded);
2867 linkbuf[
count - spaceRemoved + spaceNeeded] = 0;
2868 mergestart = linkbuf;
2871 Con_DPrintf(
"symlink: %s -> %s\n", filename, mergestart);
2874 Con_DPrintf(
"symlink: nasty path %s rejected\n", mergestart);
2877 return FS_OpenReadFile(mergestart, quiet, nonblocking, symlinkLevels - 1);
2907 Con_Printf(
"FS_OpenRealFile(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath,
mode, quiet ?
"true" :
"false");
2915 if (
mode[0] ==
'w' ||
mode[0] ==
'a' || strchr (
mode,
'+'))
2930 qfile_t *result =
NULL;
2933 Con_Printf(
"FS_OpenVirtualFile(\"%s\", %s): nasty filename rejected\n", filepath, quiet ?
"true" :
"false");
2955 memset (file, 0,
sizeof (*file));
2958 file->real_length =
size;
2985 if (
remove(file->filename) == -1)
2999 qz_inflateEnd (&file->ztk->zstream);
3024 if (file->buff_ind != file->buff_len)
3026 if (
FILEDESC_SEEK (file->handle, file->buff_ind - file->buff_len, SEEK_CUR) == -1)
3047 if (result != chunk)
3051 if (file->real_length < file->position)
3052 file->real_length = file->position;
3070 if (buffersize == 0 || !
buffer)
3074 if (file->ungetc != EOF)
3076 ((
char*)
buffer)[0] = file->ungetc;
3086 size_t left = file->real_length - file->position;
3087 if(buffersize > left)
3089 memcpy(
buffer, file->data + file->position, buffersize);
3090 file->position += buffersize;
3095 if (file->buff_ind < file->buff_len)
3097 count = file->buff_len - file->buff_ind;
3100 memcpy (
buffer, &file->buff[file->buff_ind],
count);
3101 file->buff_ind +=
count;
3103 buffersize -=
count;
3104 if (buffersize == 0)
3116 count = file->real_length - file->position;
3119 if (buffersize >
sizeof (file->buff) / 2)
3123 if (
FILEDESC_SEEK (file->handle, file->offset + file->position, SEEK_SET) == -1)
3133 file->position += nb;
3143 if (
FILEDESC_SEEK (file->handle, file->offset + file->position, SEEK_SET) == -1)
3152 file->buff_len = nb;
3153 file->position += nb;
3157 memcpy (&((
unsigned char*)
buffer)[done], file->buff,
count);
3158 file->buff_ind =
count;
3168 while (buffersize > 0)
3179 if (file->position == file->real_length)
3188 Con_Printf (
"FS_Read: unexpected end of file\n");
3204 if (buffersize <
sizeof (file->buff) / 2)
3211 Con_Printf (
"FS_Read: Can't inflate file\n");
3217 file->position += file->buff_len;
3221 memcpy (&((
unsigned char*)
buffer)[done], file->buff,
count);
3222 file->buff_ind =
count;
3233 Con_Printf (
"FS_Read: Can't inflate file\n");
3240 file->position +=
count;
3247 buffersize -=
count;
3303 if (len >= 0 && len < buff_size)
3327 if (
FS_Read (file, &c, 1) != 1)
3344 if (file->ungetc != EOF)
3369 offset += file->position - file->buff_len + file->buff_ind;
3376 offset += file->real_length;
3394 file->buff_ind =
offset + file->buff_len - file->position;
3421 if (
FILEDESC_SEEK (file->handle, file->offset, SEEK_SET) == -1)
3422 Con_Printf(
"IMPOSSIBLE: couldn't seek in already opened pk3 file.\n");
3427 qz_inflateReset (&ztk->
zstream);
3431 buffersize = 2 *
sizeof (file->buff);
3435 while (
offset > (file->position - file->buff_len + file->buff_ind))
3440 count = (diff > buffersize) ? buffersize : diff;
3463 return file->position - file->buff_len + file->buff_ind;
3476 return file->real_length;
3510 filesize = file->real_length;
3513 Con_Printf(
"FS_LoadFile(\"%s\", pool, %s, filesizepointer): trying to open a non-regular file\n", path, quiet ?
"true" :
"false");
3519 buf[filesize] =
'\0';
3523 Con_Printf(
"loaded file \"%s\" (%u bytes)\n", path, (
unsigned int)filesize);
3526 if (filesizepointer)
3527 *filesizepointer = filesize;
3557 qfile_t *file =
FS_SysOpen(path,
"rb",
false);
3578 Con_Printf(
"FS_WriteFile: failed on %s\n", filename);
3585 Con_DPrintf(
"FS_WriteFile: %s (%u bytes)\n", filename, (
unsigned int)lentotal);
3619 while ((currentchar = *in) && size_out > 1)
3621 if (currentchar ==
'.')
3623 else if (currentchar ==
'/' || currentchar ==
'\\' || currentchar ==
':')
3625 *out++ = currentchar;
3649 while (*
src !=
'/' &&
src != path)
3695 const char *canonicalname;
3712# ifndef INVALID_FILE_ATTRIBUTES
3713# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
3719 result = GetFileAttributesW(pathw);
3721 if(result == INVALID_FILE_ATTRIBUTES)
3724 if(result & FILE_ATTRIBUTE_DIRECTORY)
3731 if (stat (path,&
buf) == -1)
3735#define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
3761 int i, basepathlength, numfiles, numchars, resultlistindex, dirlistindex;
3765 const char *start, *slash, *backslash, *colon, *separator;
3768 for (
i = 0;pattern[
i] ==
'.' || pattern[
i] ==
':' || pattern[
i] ==
'/' || pattern[
i] ==
'\\';
i++)
3773 Con_Printf(
"Don't use punctuation at the beginning of a search pattern!\n");
3780 slash = strrchr(pattern,
'/');
3781 backslash = strrchr(pattern,
'\\');
3782 colon = strrchr(pattern,
':');
3783 separator =
max(slash, backslash);
3784 separator =
max(separator, colon);
3785 basepathlength = separator ? (separator + 1 - pattern) : 0;
3788 memcpy(basepath, pattern, basepathlength);
3789 basepath[basepathlength] = 0;
3798 pak = searchpath->
pack;
3812 for (resultlistindex = 0;resultlistindex < resultlist.
numstrings;resultlistindex++)
3813 if (!strcmp(resultlist.
strings[resultlistindex], temp))
3815 if (resultlistindex == resultlist.
numstrings)
3824 slash = strrchr(temp,
'/');
3825 backslash = strrchr(temp,
'\\');
3826 colon = strrchr(temp,
':');
3828 if (separator < slash)
3830 if (separator < backslash)
3831 separator = backslash;
3832 if (separator < colon)
3834 *((
char *)separator) = 0;
3852 const char *asterisk, *wildcard, *nextseparator, *prevseparator;
3857 wildcard = strchr(start,
'?');
3858 asterisk = strchr(start,
'*');
3859 if (asterisk && (!wildcard || asterisk < wildcard))
3861 wildcard = asterisk;
3866 nextseparator = strchr( wildcard,
'/' );
3870 nextseparator =
NULL;
3873 if( !nextseparator ) {
3874 nextseparator = start +
strlen( start );
3879 dp_ustr2stp(subpattern,
sizeof(subpattern), pattern, nextseparator - pattern);
3881 prevseparator = strrchr( subpattern,
'/' );
3883 prevseparator = subpattern;
3888 dp_ustr2stp(subpath,
sizeof(subpath), start, (prevseparator - subpattern) - (start - pattern));
3891 for( dirlistindex = 0 ; dirlistindex < matchedSet.
numstrings ; dirlistindex++ ) {
3897 if( dirlistindex == 0 ) {
3903 for( dirlistindex = 0 ; dirlistindex < foundSet.
numstrings ; dirlistindex++ ) {
3904 const char *direntry = foundSet.
strings[ dirlistindex ];
3911 start = nextseparator;
3914 for (dirlistindex = 0;dirlistindex < matchedSet.
numstrings;dirlistindex++)
3916 const char *matchtemp = matchedSet.
strings[dirlistindex];
3919 for (resultlistindex = 0;resultlistindex < resultlist.
numstrings;resultlistindex++)
3920 if (!strcmp(resultlist.
strings[resultlistindex], matchtemp))
3922 if (resultlistindex == resultlist.
numstrings)
3926 Con_Printf(
"SearchDirFile: %s\n", matchtemp);
3939 for (resultlistindex = 0;resultlistindex < resultlist.
numstrings;resultlistindex++)
3940 numchars += (
int)
strlen(resultlist.
strings[resultlistindex]) + 1;
3947 for (resultlistindex = 0;resultlistindex < resultlist.
numstrings;resultlistindex++)
3952 memcpy(search->
filenames[numfiles], resultlist.
strings[resultlistindex], textlen);
3954 numchars += (
int)textlen;
3992 for (
i = 0;
i < numfiles;
i++)
3995 if (columnwidth < l)
4003 if (numcolumns >= 2)
4005 numlines = (numfiles + numcolumns - 1) / numcolumns;
4006 for (
i = 0;
i < numlines;
i++)
4009 for (k = 0;k < numcolumns;k++)
4011 l =
i * numcolumns + k;
4015 for (j = 0;
name[j] && linebufpos + 1 < (
int)
sizeof(linebuf);j++)
4016 linebuf[linebufpos++] =
name[j];
4018 if (k + 1 < numcolumns && l + 1 < numfiles)
4019 for (;j < columnwidth && linebufpos + 1 < (
int)
sizeof(linebuf);j++)
4020 linebuf[linebufpos++] =
' ';
4023 linebuf[linebufpos] = 0;
4031 for (
i = 0;
i < numfiles;
i++)
4034 return (
int)numfiles;
4039 const char *pattern;
4042 Con_Printf(
"usage:\n%s [path/pattern]\n", cmdname);
4065 const char *filename;
4123 int (*strcmp_funct) (
const char* str1,
const char* str2);
4124 int left,
right, middle;
4127 strcmp_funct = pak->
ignorecase ? strcasecmp : strcmp;
4132 while (left <=
right)
4136 middle = (left +
right) / 2;
4137 diff = strcmp_funct (pak->
files[middle].
name,
"gfx/pop.lmp");
4161 unsigned char *filedata;
4163 if (filesizepointer)
4164 *filesizepointer = 0;
4165 if (!filename || !*filename)
4170 if (filesizepointer)
4171 *filesizepointer = filesize;
4181 unsigned char *out =
NULL;
4190 memset(&strm, 0,
sizeof(strm));
4200 Con_Printf(
"FS_Deflate: deflate init error!\n");
4210 Con_Printf(
"FS_Deflate: not enough memory in tempmempool!\n");
4211 qz_deflateEnd(&strm);
4221 qz_deflateEnd(&strm);
4226 if(qz_deflateEnd(&strm) !=
Z_OK)
4228 Con_Printf(
"FS_Deflate: deflateEnd failed\n");
4235 Con_Printf(
"FS_Deflate: deflate is useless on this data!\n");
4243 Con_Printf(
"FS_Deflate: not enough memory in target mempool!\n");
4248 *deflated_size = (size_t)strm.
total_out;
4260 int oldsize =
buf->maxsize;
4277 unsigned char *out =
NULL;
4278 unsigned char tmp[2048];
4288 memset(&outbuf, 0,
sizeof(outbuf));
4292 memset(&strm, 0,
sizeof(strm));
4299 Con_Printf(
"FS_Inflate: inflate init error!\n");
4321 Con_Print(
"FS_Inflate: stream error!\n");
4333 Con_Print(
"FS_Inflate: unknown error!\n");
4341 qz_inflateEnd(&strm);
4349 qz_inflateEnd(&strm);
4354 Con_Printf(
"FS_Inflate: not enough memory in target mempool!\n");
4362 *inflated_size = (size_t)outbuf.
cursize;
static unsigned char olddata[NET_MAXMESSAGE]
void Cbuf_InsertText(cmd_state_t *cmd, const char *text)
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
#define CF_READONLY
cvar cannot be changed from the console or the command buffer, and is considered CF_PERSISTENT
#define CF_PERSISTENT
cvar must not be reset on gametype switch (such as scr_screenshot_name, which otherwise isn't set to ...
#define CF_SERVER
cvar/command that only the server can change/execute
static int Cmd_Argc(cmd_state_t *cmd)
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
#define CF_CLIENT
cvar/command that only the client can change/execute
unsigned short CRC_Block(const unsigned char *data, size_t size)
char com_modname[MAX_OSPATH]
const char * gamescreenshotname
const char * gamedirname2
void COM_InitGameType(void)
const char * gameuserdirname
const char * gamedirname1
int COM_ChangeGameTypeForGameDirs(unsigned numgamedirs, const char *gamedirs[], qbool failmissing, qbool init)
gamemode_t com_startupgamegroup
@ GAME_STEELSTORM
added by motorsep
short BuffLittleShort(const unsigned char *buffer)
Extract a little endian 16bit short from the given buffer.
int BuffLittleLong(const unsigned char *buffer)
Extract a little endian 32bit int from the given buffer.
int BuffBigLong(const unsigned char *buffer)
Extract a big endian 32bit int from the given buffer.
int dpvsnprintf(char *buffer, size_t buffersize, const char *format, va_list args)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
char * dp_ustr2stp(char *dst, size_t dsize, const char *src, size_t slen)
Copies a measured byte sequence (unterminated string) to a null-terminated string.
char com_token[MAX_INPUTLINE]
char * va(char *buf, size_t buflen, const char *format,...)
qbool COM_ParseToken_Console(const char **datapointer)
void SZ_Write(sizebuf_t *buf, const unsigned char *data, int length)
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
#define dp_strlcat(dst, src, dsize)
#define dp_strlcpy(dst, src, dsize)
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
float mod(float dividend, float divisor)
void Cvar_SetValueQuick(cvar_t *var, float value)
void Cvar_SetQuick(cvar_t *var, const char *value)
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
void stringlistfreecontents(stringlist_t *list)
void stringlistinit(stringlist_t *list)
void stringlistsort(stringlist_t *list, qbool uniq)
int matchpattern(const char *in, const char *pattern, int caseinsensitive)
void stringlistappend(stringlist_t *list, const char *text)
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
static void FS_ClearSearchPath(void)
const char * FS_FileExtension(const char *in)
addgamedirs_t FS_SetGameDirs(int numgamedirs, const char *gamedirs[], qbool failmissing, qbool abortonfail)
static int FS_ListDirectory(const char *pattern, int oneperline)
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
#define QFILE_FLAG_DEFLATED
file is compressed using the deflate algorithm (PK3 only)
static qbool PK3_GetEndOfCentralDir(const char *packfile, filedesc_t packhandle, pk3_endOfCentralDir_t *eocd)
static dllfunction_t zlibfuncs[]
char fs_gamedir[MAX_OSPATH]
static void COM_InsertFlags(const char *buf)
gamedir_t * fs_all_gamedirs
unsigned char * FS_Inflate(const unsigned char *data, size_t size, size_t *inflated_size, mempool_t *mempool)
qfile_t * FS_OpenVirtualFile(const char *filepath, qbool quiet)
char fs_gamedirs[MAX_GAMEDIRS][MAX_QPATH]
static int PK3_BuildFileList(pack_t *pack, const pk3_endOfCentralDir_t *eocd)
#define ZIP_MAX_COMMENTS_SIZE
qbool FS_WriteFile(const char *filename, const void *data, fs_offset_t len)
int FS_SysOpenFD(const char *filepath, const char *mode, qbool nonblocking)
static filedesc_t FILEDESC_DUP(const char *filename, filedesc_t fd)
static fs_offset_t ReadAll(const filedesc_t fd, void *const buf, const size_t length)
fs_offset_t FS_Write(qfile_t *file, const void *data, size_t datasize)
static searchpath_t * FS_FindFile(const char *name, int *index, const char **canonicalname, qbool quiet)
#define QFILE_FLAG_PACKED
inside a package (PAK or PK3)
const char * FS_CheckGameDir(const char *gamedir)
void FS_DefaultExtension(char *path, const char *extension, size_t size_path)
qbool FS_ChangeGameDirs(int numgamedirs, const char *gamedirs[], qbool failmissing)
static qbool PK3_GetTrueFileOffset(packfile_t *pfile, pack_t *pack)
void FS_Dir_f(cmd_state_t *cmd)
void FS_Ls_f(cmd_state_t *cmd)
static pack_t * FS_LoadPackPK3FromFD(const char *packfile, filedesc_t packhandle, qbool silent)
static void FS_mkdir(const char *path)
static void FS_AddGameHierarchy(const char *dir)
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
static packfile_t * FS_AddFileToPack(const char *name, pack_t *pack, fs_offset_t offset, fs_offset_t packsize, fs_offset_t realsize, int flags)
void FS_FreeSearch(fssearch_t *search)
qfile_t * FS_SysOpen(const char *filepath, const char *mode, qbool nonblocking)
static dllhandle_t zlib_dll
Handle for Zlib DLL.
#define FILEDESC_ISVALID(fd)
fssearch_t * FS_Search(const char *pattern, int caseinsensitive, int quiet, const char *packfile)
fs_offset_t FS_Tell(qfile_t *file)
int FS_VPrintf(qfile_t *file, const char *format, va_list ap)
void FS_Purge(qfile_t *file)
int FS_Seek(qfile_t *file, fs_offset_t offset, int whence)
static const char * FS_SysCheckGameDir(const char *gamedir, char *buf, size_t buflength)
static void FS_Init_Dir(void)
void FS_Init_Commands(void)
searchpath_t * fs_searchpaths
#define MAX_FILES_IN_PACK
const char * FS_FileWithoutPath(const char *in)
static void FS_AddSelfPack(void)
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
int FS_FileType(const char *filename)
Look for a file in the packages and in the filesystem.
static int int int int memLevel
void FS_UnloadPacks_dlcache(void)
qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_dirs, qbool dlcache)
static qbool PK3_OpenLibrary(void)
static void FS_Rescan_f(cmd_state_t *cmd)
static void FS_AddGameDirectory(const char *dir)
static int(ZEXPORT *qz_inflate)(z_stream *strm
static int const char * version
int FS_UnGetc(qfile_t *file, unsigned char c)
static filedesc_t FS_SysOpenFiledesc(const char *filepath, const char *mode, qbool nonblocking)
void FS_StripExtension(const char *in, char *out, size_t size_out)
static int const char int stream_size
#define ZIP_LOCAL_CHUNK_BASE_SIZE
static fs_offset_t WriteAll(const filedesc_t fd, const void *const buf, const size_t length)
#define PACKFILE_FLAG_SYMLINK
file is a symbolic link
#define ZIP_CDIR_CHUNK_BASE_SIZE
unsigned char * FS_SysLoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
#define qz_deflateInit2(strm, level, method, windowBits, memLevel, strategy)
void FS_SanitizePath(char *path)
static void FS_GameDir_f(cmd_state_t *cmd)
void FS_RemoveOnClose(qfile_t *file)
static void AssertBufsize(sizebuf_t *buf, int length)
fs_offset_t FS_FileSize(qfile_t *file)
qbool FS_SysFileExists(const char *path)
Look for a file in the filesystem only.
int FS_Close(qfile_t *file)
const char * FS_WhichPack(const char *filename)
unsigned char * FS_Deflate(const unsigned char *data, size_t size, size_t *deflated_size, int level, mempool_t *mempool)
static pack_t * fs_selfpack
static qfile_t * FS_OpenReadFile(const char *filename, qbool quiet, qbool nonblocking, int symlinkLevels)
static pack_t * FS_LoadPackPK3(const char *packfile)
const char *const fs_checkgamedir_missing
int FS_Printf(qfile_t *file, const char *format,...)
void FS_Which_f(cmd_state_t *cmd)
static qfile_t * FS_OpenPackedFile(pack_t *pack, int pack_ind)
void FS_CreatePath(char *path)
char fs_basedir[MAX_OSPATH]
static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize)
cvar_t fs_empty_files_in_pack_mark_deletions
#define PACKFILE_FLAG_DEFLATED
file compressed using the deflate algorithm
int FS_CRCFile(const char *filename, size_t *filesizepointer)
int FS_SysFileType(const char *path)
Look for a file in the filesystem only.
int FS_Getc(qfile_t *file)
int fs_all_gamedirs_count
#define ZIP_END_CDIR_SIZE
static void PK3_CloseLibrary(void)
int FS_CheckNastyPath(const char *path, qbool isgamedir)
#define Z_MEMLEVEL_DEFAULT
int FS_Print(qfile_t *file, const char *msg)
static void FS_ListDirectoryCmd(cmd_state_t *cmd, const char *cmdname, int oneperline)
static void FS_ListGameDirs(void)
qbool FS_WriteFileInBlocks(const char *filename, const void *const *data, const fs_offset_t *len, size_t count)
static unsigned char * FS_LoadAndCloseQFile(qfile_t *file, const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
const char * FS_FileExists(const char *filename)
Look for a file in the packages and in the filesystem Returns its canonical name (same case as used i...
static pack_t * FS_LoadPackVirtual(const char *dirname)
static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbool *already_loaded, qbool keep_plain_dirs, qbool dlcache)
#define qz_inflateInit2(strm, windowBits)
static int int int int int strategy
cvar_t scr_screenshot_name
static pack_t * FS_LoadPackPAK(const char *packfile)
#define QFILE_FLAG_REMOVE
real file will be removed on close
#define QFILE_FLAG_DATA
file is actually already loaded data
qfile_t * FS_FileFromData(const unsigned char *data, const size_t size, qbool quiet)
#define Z_DEFAULT_COMPRESSION
void FS_Init_SelfPack(void)
static void FS_Path_f(cmd_state_t *cmd)
qbool FS_IsRegisteredQuakePack(const char *name)
#define PACKFILE_FLAG_TRUEOFFS
the offset in packfile_t is the true contents offset
char fs_userdir[MAX_OSPATH]
#define FS_FILETYPE_DIRECTORY
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLint GLint GLint GLsizei GLsizei GLenum format
GLsizeiptr const GLvoid * data
GLuint GLuint GLintptr offset
GLenum GLuint GLenum GLsizei const GLchar * buf
cvar_t developer_loadfile
void Host_SaveConfig(const char *file)
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
#define MAX_OSPATH
max length of a filesystem pathname
#define MAX_QPATH
max length of a quake game pathname
void S_UnloadAllSounds_f(cmd_state_t *cmd)
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
char shortname[MAX_QPATH]
qbool ignorecase
PK3 ignores case.
char filename[MAX_OSPATH]
fs_offset_t realsize
real file size (uncompressed)
fs_offset_t packsize
size in the package
fs_offset_t prepended_garbage
unsigned int cdir_offset
with respect to the starting disk number
unsigned int cdir_size
size of the central directory
unsigned short nbentries
total number of entries in the central directory on this disk
unsigned short comment_size
unsigned short localentries
number of entries in the central directory on this disk
unsigned short cdir_disknum
number of the disk with the start of the central directory
unsigned char buff[FILE_BUFF_SIZE]
fs_offset_t offset
offset into the package (0 if external file)
fs_offset_t real_length
uncompressed file size (for files opened in "read" mode)
const unsigned char * data
For data files.
fs_offset_t position
current position in the file
ztoolkit_t * ztk
For zipped files.
fs_offset_t buff_len
buffer current index and length
int ungetc
single stored character from ungetc, cleared to EOF when read
const char * filename
Kept around for QFILE_FLAG_REMOVE, unused otherwise.
filedesc_t handle
file descriptor
Search paths for files (including packages)
struct searchpath_s * next
char filename[MAX_OSPATH]
qbool active
false if only a net client
unsigned int avail_in
number of bytes available at next_in
unsigned long total_out
total nb of bytes output so far
unsigned long reserved
reserved for future use
void * opaque
private data object passed to zalloc and zfree
void * zalloc
used to allocate the internal state
int data_type
best guess about the data type: ascii or binary
void * state
not visible by applications
void * zfree
used to free the internal state
unsigned char * next_out
next output byte should be put there
unsigned long total_in
total nb of input bytes read so far
unsigned int avail_out
remaining free space at next_out
unsigned char * next_in
next input byte
unsigned long adler
adler32 value of the uncompressed data
char * msg
last error message, NULL if no error
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
qbool Sys_LoadDependency(const char **dllnames, dllhandle_t *handle, const dllfunction_t *fcts)
void Sys_FreeLibrary(dllhandle_t *handle)
int Sys_CheckParm(const char *parm)
void Sys_EM_Register_Commands(void)
#define Thread_DestroyMutex(m)
qbool Thread_HasThreads(void)
#define Thread_CreateMutex()
#define Thread_LockMutex(m)
#define Thread_UnlockMutex(m)
#define NARROW(wstr, str)
#define Mem_FreePool(pool)
#define Mem_Alloc(pool, size)
#define Mem_strdup(pool, s)
#define Mem_AllocPool(name, flags, parent)