X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=fs.c;h=87367a77c28ed8a6c61803519a1a6a46033cd2da;hp=8c8059ca59c629c07c600bb23d22d07cdde965e8;hb=2075ae43356d724bae305ce8fd36ea570718b14a;hpb=1a6348e838d7ab1cbf5bd9a1a8c52b8a20eaec2f diff --git a/fs.c b/fs.c index 8c8059ca..87367a77 100644 --- a/fs.c +++ b/fs.c @@ -74,6 +74,37 @@ # define dup _dup #endif +#if USE_RWOPS +# include +typedef SDL_RWops *filedesc_t; +# define FILEDESC_INVALID NULL +# define FILEDESC_ISVALID(fd) ((fd) != NULL) +# define FILEDESC_READ(fd,buf,count) ((fs_offset_t)SDL_RWread(fd, buf, 1, count)) +# define FILEDESC_WRITE(fd,buf,count) ((fs_offset_t)SDL_RWwrite(fd, buf, 1, count)) +# define FILEDESC_CLOSE SDL_RWclose +# define FILEDESC_SEEK SDL_RWseek +static filedesc_t FILEDESC_DUP(const char *filename, filedesc_t fd) { + filedesc_t new_fd = SDL_RWFromFile(filename, "rb"); + if (SDL_RWseek(new_fd, SDL_RWseek(fd, 0, RW_SEEK_CUR), RW_SEEK_SET) < 0) { + SDL_RWclose(new_fd); + return NULL; + } + return new_fd; +} +# define unlink(name) Con_DPrintf("Sorry, no unlink support when trying to unlink %s.\n", (name)) +#else +typedef int filedesc_t; +# define FILEDESC_INVALID -1 +# define FILEDESC_ISVALID(fd) ((fd) != -1) +# define FILEDESC_READ read +# define FILEDESC_WRITE write +# define FILEDESC_CLOSE close +# define FILEDESC_SEEK lseek +static filedesc_t FILEDESC_DUP(const char *filename, filedesc_t fd) { + return dup(fd); +} +#endif + /** \page fs File System All of Quake's data access is through a hierchal file system, but the contents @@ -212,7 +243,7 @@ typedef struct struct qfile_s { int flags; - int handle; ///< file descriptor + filedesc_t handle; ///< file descriptor fs_offset_t real_length; ///< uncompressed file size (for files opened in "read" mode) fs_offset_t position; ///< current position in the file fs_offset_t offset; ///< offset into the package (0 if external file) @@ -286,7 +317,7 @@ typedef struct pack_s { char filename [MAX_OSPATH]; char shortname [MAX_QPATH]; - int handle; + filedesc_t handle; int ignorecase; ///< PK3 ignores case int numfiles; qboolean vpack; @@ -532,14 +563,14 @@ PK3_GetEndOfCentralDir Extract the end of the central directory from a PK3 package ==================== */ -static qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOfCentralDir_t *eocd) +static qboolean PK3_GetEndOfCentralDir (const char *packfile, filedesc_t packhandle, pk3_endOfCentralDir_t *eocd) { fs_offset_t filesize, maxsize; unsigned char *buffer, *ptr; int ind; // Get the package size - filesize = lseek (packhandle, 0, SEEK_END); + filesize = FILEDESC_SEEK (packhandle, 0, SEEK_END); if (filesize < ZIP_END_CDIR_SIZE) return false; @@ -549,8 +580,8 @@ static qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk else maxsize = ZIP_MAX_COMMENTS_SIZE + ZIP_END_CDIR_SIZE; buffer = (unsigned char *)Mem_Alloc (tempmempool, maxsize); - lseek (packhandle, filesize - maxsize, SEEK_SET); - if (read (packhandle, buffer, maxsize) != (fs_offset_t) maxsize) + FILEDESC_SEEK (packhandle, filesize - maxsize, SEEK_SET); + if (FILEDESC_READ (packhandle, buffer, maxsize) != (fs_offset_t) maxsize) { Mem_Free (buffer); return false; @@ -587,8 +618,8 @@ static qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk Mem_Free (buffer); if ( - eocd->cdir_size < 0 || eocd->cdir_size > filesize || - eocd->cdir_offset < 0 || eocd->cdir_offset >= filesize || + eocd->cdir_size > filesize || + eocd->cdir_offset >= filesize || eocd->cdir_offset + eocd->cdir_size > filesize ) { @@ -615,12 +646,12 @@ static int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd) // Load the central directory in memory central_dir = (unsigned char *)Mem_Alloc (tempmempool, eocd->cdir_size); - if (lseek (pack->handle, eocd->cdir_offset, SEEK_SET) == -1) + if (FILEDESC_SEEK (pack->handle, eocd->cdir_offset, SEEK_SET) == -1) { Mem_Free (central_dir); return -1; } - if(read (pack->handle, central_dir, eocd->cdir_size) != (fs_offset_t) eocd->cdir_size) + if(FILEDESC_READ (pack->handle, central_dir, eocd->cdir_size) != (fs_offset_t) eocd->cdir_size) { Mem_Free (central_dir); return -1; @@ -668,7 +699,7 @@ static int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd) if ((ptr[8] & 0x21) == 0 && (ptr[38] & 0x18) == 0) { // Still enough bytes for the name? - if (remaining < namesize || namesize >= (int)sizeof (*pack->files)) + if (namesize < 0 || remaining < namesize || namesize >= (int)sizeof (*pack->files)) { Mem_Free (central_dir); return -1; @@ -731,7 +762,7 @@ FS_LoadPackPK3 Create a package entry associated with a PK3 file ==================== */ -static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qboolean silent) +static pack_t *FS_LoadPackPK3FromFD (const char *packfile, filedesc_t packhandle, qboolean silent) { pk3_endOfCentralDir_t eocd; pack_t *pack; @@ -741,7 +772,7 @@ static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qbool { if(!silent) Con_Printf ("%s is not a PK3 file\n", packfile); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } @@ -749,7 +780,7 @@ static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qbool if (eocd.disknum != 0 || eocd.cdir_disknum != 0) { Con_Printf ("%s is a multi-volume ZIP archive\n", packfile); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } @@ -759,7 +790,7 @@ static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qbool if (eocd.nbentries > MAX_FILES_IN_PACK) { Con_Printf ("%s contains too many files (%hu)\n", packfile, eocd.nbentries); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } #endif @@ -776,7 +807,7 @@ static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qbool if (real_nb_files < 0) { Con_Printf ("%s is not a valid PK3 file\n", packfile); - close(pack->handle); + FILEDESC_CLOSE(pack->handle); Mem_Free(pack); return NULL; } @@ -784,11 +815,13 @@ static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qbool Con_DPrintf("Added packfile %s (%i files)\n", packfile, real_nb_files); return pack; } + +static filedesc_t FS_SysOpenFiledesc(const char *filepath, const char *mode, qboolean nonblocking); static pack_t *FS_LoadPackPK3 (const char *packfile) { - int packhandle; - packhandle = FS_SysOpenFD (packfile, "rb", false); - if (packhandle < 0) + filedesc_t packhandle; + packhandle = FS_SysOpenFiledesc (packfile, "rb", false); + if (!FILEDESC_ISVALID(packhandle)) return NULL; return FS_LoadPackPK3FromFD(packfile, packhandle, false); } @@ -811,12 +844,12 @@ static qboolean PK3_GetTrueFileOffset (packfile_t *pfile, pack_t *pack) return true; // Load the local file description - if (lseek (pack->handle, pfile->offset, SEEK_SET) == -1) + if (FILEDESC_SEEK (pack->handle, pfile->offset, SEEK_SET) == -1) { Con_Printf ("Can't seek in package %s\n", pack->filename); return false; } - count = read (pack->handle, buffer, ZIP_LOCAL_CHUNK_BASE_SIZE); + count = FILEDESC_READ (pack->handle, buffer, ZIP_LOCAL_CHUNK_BASE_SIZE); if (count != ZIP_LOCAL_CHUNK_BASE_SIZE || BuffBigLong (buffer) != ZIP_DATA_HEADER) { Con_Printf ("Can't retrieve file %s in package %s\n", pfile->name, pack->filename); @@ -893,6 +926,25 @@ static packfile_t* FS_AddFileToPack (const char* name, pack_t* pack, } +static void FS_mkdir (const char *path) +{ + if(COM_CheckParm("-readonly")) + return; + +#if WIN32 + if (_mkdir (path) == -1) +#else + if (mkdir (path, 0777) == -1) +#endif + { + // No logging for this. The only caller is FS_CreatePath (which + // calls it in ways that will intentionally produce EEXIST), + // and its own callers always use the directory afterwards and + // thus will detect failure that way. + } +} + + /* ============ FS_CreatePath @@ -957,23 +1009,23 @@ static pack_t *FS_LoadPackPAK (const char *packfile) { dpackheader_t header; int i, numpackfiles; - int packhandle; + filedesc_t packhandle; pack_t *pack; dpackfile_t *info; - packhandle = FS_SysOpenFD(packfile, "rb", false); - if (packhandle < 0) + packhandle = FS_SysOpenFiledesc(packfile, "rb", false); + if (!FILEDESC_ISVALID(packhandle)) return NULL; - if(read (packhandle, (void *)&header, sizeof(header)) != sizeof(header)) + if(FILEDESC_READ (packhandle, (void *)&header, sizeof(header)) != sizeof(header)) { Con_Printf ("%s is not a packfile\n", packfile); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } if (memcmp(header.id, "PACK", 4)) { Con_Printf ("%s is not a packfile\n", packfile); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } header.dirofs = LittleLong (header.dirofs); @@ -982,26 +1034,26 @@ static pack_t *FS_LoadPackPAK (const char *packfile) if (header.dirlen % sizeof(dpackfile_t)) { Con_Printf ("%s has an invalid directory size\n", packfile); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } numpackfiles = header.dirlen / sizeof(dpackfile_t); - if (numpackfiles > MAX_FILES_IN_PACK) + if (numpackfiles < 0 || numpackfiles > MAX_FILES_IN_PACK) { Con_Printf ("%s has %i files\n", packfile, numpackfiles); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } info = (dpackfile_t *)Mem_Alloc(tempmempool, sizeof(*info) * numpackfiles); - lseek (packhandle, header.dirofs, SEEK_SET); - if(header.dirlen != read (packhandle, (void *)info, header.dirlen)) + FILEDESC_SEEK (packhandle, header.dirofs, SEEK_SET); + if(header.dirlen != FILEDESC_READ (packhandle, (void *)info, header.dirlen)) { Con_Printf("%s is an incomplete PAK, not loading\n", packfile); Mem_Free(info); - close(packhandle); + FILEDESC_CLOSE(packhandle); return NULL; } @@ -1018,6 +1070,9 @@ static pack_t *FS_LoadPackPAK (const char *packfile) fs_offset_t offset = (unsigned int)LittleLong (info[i].filepos); fs_offset_t size = (unsigned int)LittleLong (info[i].filelen); + // Ensure a zero terminated file name (required by format). + info[i].name[sizeof(info[i].name) - 1] = 0; + FS_AddFileToPack (info[i].name, pack, offset, size, size, PACKFILE_FLAG_TRUEOFFS); } @@ -1041,7 +1096,7 @@ static pack_t *FS_LoadPackVirtual (const char *dirname) pack->vpack = true; pack->ignorecase = false; strlcpy (pack->filename, dirname, sizeof(pack->filename)); - pack->handle = -1; + pack->handle = FILEDESC_INVALID; pack->numfiles = -1; pack->files = NULL; Con_DPrintf("Added packfile %s (virtual pack)\n", dirname); @@ -1329,7 +1384,7 @@ static void FS_ClearSearchPath (void) if(!search->pack->vpack) { // close the file - close(search->pack->handle); + FILEDESC_CLOSE(search->pack->handle); // free any memory associated with it if (search->pack->files) Mem_Free(search->pack->files); @@ -1620,7 +1675,7 @@ FS_CheckGameDir const char *FS_CheckGameDir(const char *gamedir) { const char *ret; - char buf[8192]; + static char buf[8192]; char vabuf[1024]; if (FS_CheckNastyPath(gamedir, true)) @@ -1704,6 +1759,41 @@ static void FS_ListGameDirs(void) #endif */ +static void COM_InsertFlags(const char *buf) { + const char *p; + char *q; + const char **new_argv; + int i = 0; + int args_left = 256; + new_argv = (const char **)Mem_Alloc(fs_mempool, sizeof(*com_argv) * (com_argc + args_left + 2)); + if(com_argc == 0) + new_argv[0] = "dummy"; // Can't really happen. + else + new_argv[0] = com_argv[0]; + ++i; + p = buf; + while(COM_ParseToken_Console(&p)) + { + size_t sz = strlen(com_token) + 1; // shut up clang + if(i > args_left) + break; + q = (char *)Mem_Alloc(fs_mempool, sz); + strlcpy(q, com_token, sz); + new_argv[i] = q; + ++i; + } + // Now: i <= args_left + 1. + if (com_argc >= 1) + { + memcpy((char *)(&new_argv[i]), &com_argv[1], sizeof(*com_argv) * (com_argc - 1)); + i += com_argc - 1; + } + // Now: i <= args_left + (com_argc || 1). + new_argv[i] = NULL; + com_argv = new_argv; + com_argc = i; +} + /* ================ FS_Init_SelfPack @@ -1713,48 +1803,37 @@ void FS_Init_SelfPack (void) { PK3_OpenLibrary (); fs_mempool = Mem_AllocPool("file management", 0, NULL); - if(com_selffd >= 0) + + // Load darkplaces.opt from the FS. + if (!COM_CheckParm("-noopt")) { - fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true); - if(fs_selfpack) + char *buf = (char *) FS_SysLoadFile("darkplaces.opt", tempmempool, true, NULL); + if(buf) + COM_InsertFlags(buf); + Mem_Free(buf); + } + +#ifndef USE_RWOPS + // Provide the SelfPack. + if (!COM_CheckParm("-noselfpack")) + { + if (com_selffd >= 0) { - char *buf, *q; - const char *p; - FS_AddSelfPack(); - buf = (char *) FS_LoadFile("darkplaces.opt", tempmempool, true, NULL); - if(buf) + fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true); + if(fs_selfpack) { - const char **new_argv; - int i = 0; - int args_left = 256; - new_argv = (const char **)Mem_Alloc(fs_mempool, sizeof(*com_argv) * (com_argc + args_left + 2)); - if(com_argc == 0) - { - new_argv[0] = "dummy"; - com_argc = 1; - } - else - { - memcpy((char *)(&new_argv[0]), &com_argv[0], sizeof(*com_argv) * com_argc); - } - p = buf; - while(COM_ParseToken_Console(&p)) + FS_AddSelfPack(); + if (!COM_CheckParm("-noopt")) { - size_t sz = strlen(com_token) + 1; // shut up clang - if(i >= args_left) - break; - q = (char *)Mem_Alloc(fs_mempool, sz); - strlcpy(q, com_token, sz); - new_argv[com_argc + i] = q; - ++i; + char *buf = (char *) FS_LoadFile("darkplaces.opt", tempmempool, true, NULL); + if(buf) + COM_InsertFlags(buf); + Mem_Free(buf); } - new_argv[i+com_argc] = NULL; - com_argv = new_argv; - com_argc = com_argc + i; } - Mem_Free(buf); } } +#endif } static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize) @@ -1904,15 +1983,15 @@ static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t use // see if we can write to this path (note: won't create path) #ifdef WIN32 // no access() here, we must try to open the file for appending - fd = FS_SysOpenFD(va(vabuf, sizeof(vabuf), "%s%s/config.cfg", userdir, gamedirname1), "a", false); + fd = FS_SysOpenFiledesc(va(vabuf, sizeof(vabuf), "%s%s/config.cfg", userdir, gamedirname1), "a", false); if(fd >= 0) - close(fd); + FILEDESC_CLOSE(fd); #else // on Unix, we don't need to ACTUALLY attempt to open the file if(access(va(vabuf, sizeof(vabuf), "%s%s/", userdir, gamedirname1), W_OK | X_OK) >= 0) fd = 1; else - fd = 0; + fd = -1; #endif if(fd >= 0) { @@ -2005,15 +2084,18 @@ void FS_Init (void) *fs_userdir = 0; // user wants roaming installation, no userdir else { +#ifdef DP_FS_USERDIR + strlcpy(fs_userdir, DP_FS_USERDIR, sizeof(fs_userdir)); +#else int dirmode; int highestuserdirmode = USERDIRMODE_COUNT - 1; int preferreduserdirmode = USERDIRMODE_COUNT - 1; int userdirstatus[USERDIRMODE_COUNT]; -#ifdef WIN32 +# ifdef WIN32 // historical behavior... if (!strcmp(gamedirname1, "id1")) preferreduserdirmode = USERDIRMODE_NOHOME; -#endif +# endif // check what limitations the user wants to impose if (COM_CheckParm("-home")) preferreduserdirmode = USERDIRMODE_HOME; if (COM_CheckParm("-mygames")) preferreduserdirmode = USERDIRMODE_MYGAMES; @@ -2045,6 +2127,7 @@ void FS_Init (void) // and finally, we picked one... FS_ChooseUserDir((userdirmode_t)dirmode, fs_userdir, sizeof(fs_userdir)); Con_DPrintf("userdir %i is the winner\n", dirmode); +#endif } // if userdir equal to basedir, clear it to avoid confusion later @@ -2130,9 +2213,9 @@ void FS_Shutdown (void) Thread_DestroyMutex(fs_mutex); } -int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking) +static filedesc_t FS_SysOpenFiledesc(const char *filepath, const char *mode, qboolean nonblocking) { - int handle = -1; + filedesc_t handle = FILEDESC_INVALID; int mod, opt; unsigned int ind; qboolean dolock = false; @@ -2154,7 +2237,7 @@ int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking) break; default: Con_Printf ("FS_SysOpen(%s, %s): invalid mode\n", filepath, mode); - return -1; + return FILEDESC_INVALID; } for (ind = 1; mode[ind] != '\0'; ind++) { @@ -2179,15 +2262,20 @@ int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking) opt |= O_NONBLOCK; if(COM_CheckParm("-readonly") && mod != O_RDONLY) - return -1; + return FILEDESC_INVALID; -#ifdef WIN32 -# if _MSC_VER >= 1400 +#if USE_RWOPS + if (dolock) + return FILEDESC_INVALID; + handle = SDL_RWFromFile(filepath, mode); +#else +# ifdef WIN32 +# if _MSC_VER >= 1400 _sopen_s(&handle, filepath, mod | opt, (dolock ? ((mod == O_RDONLY) ? _SH_DENYRD : _SH_DENYRW) : _SH_DENYNO), _S_IREAD | _S_IWRITE); -# else +# else handle = _sopen (filepath, mod | opt, (dolock ? ((mod == O_RDONLY) ? _SH_DENYRD : _SH_DENYRW) : _SH_DENYNO), _S_IREAD | _S_IWRITE); -# endif -#else +# endif +# else handle = open (filepath, mod | opt, 0666); if(handle >= 0 && dolock) { @@ -2198,15 +2286,25 @@ int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking) l.l_len = 0; if(fcntl(handle, F_SETLK, &l) == -1) { - close(handle); + FILEDESC_CLOSE(handle); handle = -1; } } +# endif #endif return handle; } +int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking) +{ +#ifdef USE_RWOPS + return -1; +#else + return FS_SysOpenFiledesc(filepath, mode, nonblocking); +#endif +} + /* ==================== FS_SysOpen @@ -2220,8 +2318,8 @@ qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblockin file = (qfile_t *)Mem_Alloc (fs_mempool, sizeof (*file)); file->ungetc = EOF; - file->handle = FS_SysOpenFD(filepath, mode, nonblocking); - if (file->handle < 0) + file->handle = FS_SysOpenFiledesc(filepath, mode, nonblocking); + if (!FILEDESC_ISVALID(file->handle)) { Mem_Free (file); return NULL; @@ -2229,13 +2327,13 @@ qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblockin file->filename = Mem_strdup(fs_mempool, filepath); - file->real_length = lseek (file->handle, 0, SEEK_END); + file->real_length = FILEDESC_SEEK (file->handle, 0, SEEK_END); // For files opened in append mode, we start at the end of the file if (mode[0] == 'a') file->position = file->real_length; else - lseek (file->handle, 0, SEEK_SET); + FILEDESC_SEEK (file->handle, 0, SEEK_SET); return file; } @@ -2251,7 +2349,7 @@ Open a packed file using its package file descriptor static qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) { packfile_t *pfile; - int dup_handle; + filedesc_t dup_handle; qfile_t* file; pfile = &pack->files[pack_ind]; @@ -2272,17 +2370,17 @@ static qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) } #endif - // LordHavoc: lseek affects all duplicates of a handle so we do it before + // LordHavoc: FILEDESC_SEEK affects all duplicates of a handle so we do it before // the dup() call to avoid having to close the dup_handle on error here - if (lseek (pack->handle, pfile->offset, SEEK_SET) == -1) + if (FILEDESC_SEEK (pack->handle, pfile->offset, SEEK_SET) == -1) { Con_Printf ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %08x%08x)\n", pfile->name, pack->filename, (unsigned int)(pfile->offset >> 32), (unsigned int)(pfile->offset)); return NULL; } - dup_handle = dup (pack->handle); - if (dup_handle < 0) + dup_handle = FILEDESC_DUP (pack->filename, pack->handle); + if (!FILEDESC_ISVALID(dup_handle)) { Con_Printf ("FS_OpenPackedFile: can't dup package's handle (pack: %s)\n", pack->filename); return NULL; @@ -2324,7 +2422,7 @@ static qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) if (qz_inflateInit2 (&ztk->zstream, -MAX_WBITS) != Z_OK) { Con_Printf ("FS_OpenPackedFile: inflate init error (file: %s)\n", pfile->name); - close(dup_handle); + FILEDESC_CLOSE(dup_handle); Mem_Free(file); return NULL; } @@ -2687,13 +2785,21 @@ int FS_Close (qfile_t* file) return 0; } - if (close (file->handle)) + if (FILEDESC_CLOSE (file->handle)) return EOF; if (file->filename) { if (file->flags & QFILE_FLAG_REMOVE) - remove(file->filename); + { + if (remove(file->filename) == -1) + { + // No need to report this. If removing a just + // written file failed, this most likely means + // someone else deleted it first - which we + // like. + } + } Mem_Free((void *) file->filename); } @@ -2727,9 +2833,9 @@ fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize) // If necessary, seek to the exact file position we're supposed to be if (file->buff_ind != file->buff_len) { - if (lseek (file->handle, file->buff_ind - file->buff_len, SEEK_CUR) == -1) + if (FILEDESC_SEEK (file->handle, file->buff_ind - file->buff_len, SEEK_CUR) == -1) { - Con_Printf("WARNING: could not seek in %s.\n"); + Con_Printf("WARNING: could not seek in %s.\n", file->filename); } } @@ -2743,7 +2849,7 @@ fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize) // figure out how much to write in one chunk fs_offset_t maxchunk = 1<<30; // 1 GiB int chunk = (int)min((fs_offset_t)datasize - written, maxchunk); - int result = (int)write (file->handle, (const unsigned char *)data + written, chunk); + int result = (int)FILEDESC_WRITE (file->handle, (const unsigned char *)data + written, chunk); // if at least some was written, add it to our accumulator if (result > 0) written += result; @@ -2751,7 +2857,7 @@ fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize) if (result != chunk) break; } - file->position = lseek (file->handle, 0, SEEK_CUR); + file->position = FILEDESC_SEEK (file->handle, 0, SEEK_CUR); if (file->real_length < file->position) file->real_length = file->position; @@ -2824,13 +2930,13 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) { if (count > (fs_offset_t)buffersize) count = (fs_offset_t)buffersize; - if (lseek (file->handle, file->offset + file->position, SEEK_SET) == -1) + if (FILEDESC_SEEK (file->handle, file->offset + file->position, SEEK_SET) == -1) { // Seek failed. When reading from a pipe, and // the caller never called FS_Seek, this still // works fine. So no reporting this error. } - nb = read (file->handle, &((unsigned char*)buffer)[done], count); + nb = FILEDESC_READ (file->handle, &((unsigned char*)buffer)[done], count); if (nb > 0) { done += nb; @@ -2844,13 +2950,13 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) { if (count > (fs_offset_t)sizeof (file->buff)) count = (fs_offset_t)sizeof (file->buff); - if (lseek (file->handle, file->offset + file->position, SEEK_SET) == -1) + if (FILEDESC_SEEK (file->handle, file->offset + file->position, SEEK_SET) == -1) { // Seek failed. When reading from a pipe, and // the caller never called FS_Seek, this still // works fine. So no reporting this error. } - nb = read (file->handle, file->buff, count); + nb = FILEDESC_READ (file->handle, file->buff, count); if (nb > 0) { file->buff_len = nb; @@ -2886,8 +2992,8 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) count = (fs_offset_t)(ztk->comp_length - ztk->in_position); if (count > (fs_offset_t)sizeof (ztk->input)) count = (fs_offset_t)sizeof (ztk->input); - lseek (file->handle, file->offset + (fs_offset_t)ztk->in_position, SEEK_SET); - if (read (file->handle, ztk->input, count) != count) + FILEDESC_SEEK (file->handle, file->offset + (fs_offset_t)ztk->in_position, SEEK_SET); + if (FILEDESC_READ (file->handle, ztk->input, count) != count) { Con_Printf ("FS_Read: unexpected end of file\n"); break; @@ -3010,7 +3116,7 @@ int FS_VPrintf (qfile_t* file, const char* format, va_list ap) buff_size *= 2; } - len = write (file->handle, tempbuff, len); + len = FILEDESC_WRITE (file->handle, tempbuff, len); Mem_Free (tempbuff); return len; @@ -3105,7 +3211,7 @@ int FS_Seek (qfile_t* file, fs_offset_t offset, int whence) // Unpacked or uncompressed files can seek directly if (! (file->flags & QFILE_FLAG_DEFLATED)) { - if (lseek (file->handle, file->offset + offset, SEEK_SET) == -1) + if (FILEDESC_SEEK (file->handle, file->offset + offset, SEEK_SET) == -1) return -1; file->position = offset; return 0; @@ -3122,7 +3228,7 @@ int FS_Seek (qfile_t* file, fs_offset_t offset, int whence) ztk->in_len = 0; ztk->in_position = 0; file->position = 0; - if (lseek (file->handle, file->offset, SEEK_SET) == -1) + if (FILEDESC_SEEK (file->handle, file->offset, SEEK_SET) == -1) Con_Printf("IMPOSSIBLE: couldn't seek in already opened pk3 file.\n"); // Reset the Zlib stream @@ -3198,19 +3304,17 @@ void FS_Purge (qfile_t* file) /* ============ -FS_LoadFile +FS_LoadAndCloseQFile -Filename are relative to the quake directory. +Loads full content of a qfile_t and closes it. Always appends a 0 byte. ============ */ -unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer) +static unsigned char *FS_LoadAndCloseQFile (qfile_t *file, const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer) { - qfile_t *file; unsigned char *buf = NULL; fs_offset_t filesize = 0; - file = FS_OpenVirtualFile(path, quiet); if (file) { filesize = file->real_length; @@ -3235,6 +3339,36 @@ unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, f } +/* +============ +FS_LoadFile + +Filename are relative to the quake directory. +Always appends a 0 byte. +============ +*/ +unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer) +{ + qfile_t *file = FS_OpenVirtualFile(path, quiet); + return FS_LoadAndCloseQFile(file, path, pool, quiet, filesizepointer); +} + + +/* +============ +FS_SysLoadFile + +Filename are OS paths. +Always appends a 0 byte. +============ +*/ +unsigned char *FS_SysLoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer) +{ + qfile_t *file = FS_SysOpen(path, "rb", false); + return FS_LoadAndCloseQFile(file, path, pool, quiet, filesizepointer); +} + + /* ============ FS_WriteFile @@ -3320,7 +3454,7 @@ void FS_DefaultExtension (char *path, const char *extension, size_t size_path) // if path doesn't have a .EXT, append extension // (extension should include the .) - src = path + strlen(path) - 1; + src = path + strlen(path); while (*src != '/' && src != path) { @@ -3415,18 +3549,6 @@ qboolean FS_SysFileExists (const char *path) return FS_SysFileType (path) != FS_FILETYPE_NONE; } -void FS_mkdir (const char *path) -{ - if(COM_CheckParm("-readonly")) - return; - -#if WIN32 - _mkdir (path); -#else - mkdir (path, 0777); -#endif -} - /* =========== FS_Search @@ -3444,7 +3566,6 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) stringlist_t dirlist; const char *slash, *backslash, *colon, *separator; char *basepath; - char temp[MAX_OSPATH]; for (i = 0;pattern[i] == '.' || pattern[i] == ':' || pattern[i] == '/' || pattern[i] == '\\';i++) ; @@ -3479,6 +3600,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) pak = searchpath->pack; for (i = 0;i < pak->numfiles;i++) { + char temp[MAX_OSPATH]; strlcpy(temp, pak->files[i].name, sizeof(temp)); while (temp[0]) { @@ -3562,6 +3684,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) // for each entry in matchedSet try to open the subdirectories specified in subpath for( dirlistindex = 0 ; dirlistindex < matchedSet.numstrings ; dirlistindex++ ) { + char temp[MAX_OSPATH]; strlcpy( temp, matchedSet.strings[ dirlistindex ], sizeof(temp) ); strlcat( temp, subpath, sizeof(temp) ); listdirectory( &foundSet, searchpath->filename, temp ); @@ -3585,17 +3708,17 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) for (dirlistindex = 0;dirlistindex < matchedSet.numstrings;dirlistindex++) { - const char *temp = matchedSet.strings[dirlistindex]; - if (matchpattern(temp, (char *)pattern, true)) + const char *matchtemp = matchedSet.strings[dirlistindex]; + if (matchpattern(matchtemp, (char *)pattern, true)) { for (resultlistindex = 0;resultlistindex < resultlist.numstrings;resultlistindex++) - if (!strcmp(resultlist.strings[resultlistindex], temp)) + if (!strcmp(resultlist.strings[resultlistindex], matchtemp)) break; if (resultlistindex == resultlist.numstrings) { - stringlistappend(&resultlist, temp); + stringlistappend(&resultlist, matchtemp); if (!quiet && developer_loading.integer) - Con_Printf("SearchDirFile: %s\n", temp); + Con_Printf("SearchDirFile: %s\n", matchtemp); } } } @@ -3806,7 +3929,7 @@ qboolean FS_IsRegisteredQuakePack(const char *name) int diff; middle = (left + right) / 2; - diff = !strcmp_funct (pak->files[middle].name, "gfx/pop.lmp"); + diff = strcmp_funct (pak->files[middle].name, "gfx/pop.lmp"); // Found it if (!diff) @@ -3917,8 +4040,7 @@ unsigned char *FS_Deflate(const unsigned char *data, size_t size, size_t *deflat return NULL; } - if(deflated_size) - *deflated_size = (size_t)strm.total_out; + *deflated_size = (size_t)strm.total_out; memcpy(out, tmp, strm.total_out); Mem_Free(tmp); @@ -4032,8 +4154,7 @@ unsigned char *FS_Inflate(const unsigned char *data, size_t size, size_t *inflat memcpy(out, outbuf.data, outbuf.cursize); Mem_Free(outbuf.data); - if(inflated_size) - *inflated_size = (size_t)outbuf.cursize; + *inflated_size = (size_t)outbuf.cursize; return out; }