1 /**
2  * @file
3  * @brief Filesystem header file.
4  */
5 
6 /*
7 All original material Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 Copyright (C) 1997-2001 Id Software, Inc.
10 
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 See the GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25 
26 */
27 
28 #pragma once
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include "../shared/ufotypes.h"
33 
34 #define	BASEDIRNAME	"base"
35 
36 /* Maximum maps constant */
37 #define	MAX_MAPS 400
38 
39 /* max length of the ufo virtual filesystem */
40 #define MAX_QPATH           64
41 
42 /* max length of a filesystem pathname
43  * windows + linux 256, macosx 32 */
44 #define	MAX_OSPATH          256
45 
46 /* max files in a directory */
47 #define	MAX_FILES           512
48 
49 /*
50 ==============================================================
51 FILESYSTEM
52 ==============================================================
53 */
54 typedef struct qFILE_s {
55 	void* z; /**< in case of the file being a zip archive */
56 	FILE *f; /**< in case the file being part of a pak or the actual file */
57 	char name[MAX_OSPATH];
58 	unsigned long filepos;
59 	unsigned long size;
60 
getFileqFILE_s61 	inline FILE* getFile () const
62 	{
63 		return f;
64 	}
65 } qFILE;
66 
67 typedef enum {
68 	FS_READ,
69 	FS_WRITE,
70 	FS_APPEND,
71 	FS_APPEND_SYNC
72 } fsMode_t;
73 
74 typedef enum {
75 	FS_SEEK_CUR,
76 	FS_SEEK_END,
77 	FS_SEEK_SET
78 } fsOrigin_t;
79 
80 /** @brief Links one file onto another - like a symlink */
81 typedef struct filelink_s {
82 	struct filelink_s* next;
83 	char* from;
84 	int fromlength;
85 	char* to;
86 } filelink_t;
87 
88 typedef struct {
89 	char name[MAX_QPATH];
90 	unsigned long filepos;
91 	unsigned long filelen;
92 } packfile_t;
93 
94 typedef struct pack_s {
95 	char filename[MAX_OSPATH];
96 	qFILE handle;
97 	int numfiles;
98 	packfile_t* files;
99 } pack_t;
100 
101 typedef struct searchpath_s {
102 	char filename[MAX_OSPATH];
103 	pack_t* pack;				/**< only one of filename / pack will be used */
104 	bool write;					/**< this is the path for writing configs and savegames - may
105 								 * only be once set to true in the whole list */
106 	struct searchpath_s* next;
107 } searchpath_t;
108 
109 /** file opening modes */
110 typedef enum {
111 	FILE_READ, FILE_WRITE, FILE_APPEND
112 } filemode_t;
113 
114 /*
115 ==============================================================
116 FILESYSTEM
117 ==============================================================
118 */
119 extern char* fs_maps[MAX_MAPS];
120 extern int fs_numInstalledMaps;
121 
122 /* directory searching */
123 #define SFF_ARCH    0x01
124 #define SFF_HIDDEN  0x02
125 #define SFF_RDONLY  0x04
126 #define SFF_SUBDIR  0x08
127 #define SFF_SYSTEM  0x10
128 
129 int FS_FileLength(qFILE * f);
130 int FS_Seek(qFILE * f, long offset, int origin);
131 int FS_WriteFile(const void* buffer, size_t len, const char* filename);
132 int FS_Write(const void* buffer, int len, qFILE * f);
133 int FS_Printf(qFILE *f, const char* msg, ...) __attribute__((format(__printf__, 2, 3)));
134 void FS_InitFilesystem(bool writeToHomeDir);
135 void FS_AddGameDirectory(const char* dir, bool write);
136 void FS_AddHomeAsGameDirectory(const char* dir, bool write);
137 void FS_RestartFilesystem(const char* gamedir);
138 const char* FS_Gamedir(void);
139 void FS_CreateOpenPipeFile(const char* filename, qFILE *f);
140 const char* FS_NextPath(const char* prevpath);
141 void FS_ExecAutoexec(void);
142 int FS_GetModList(struct linkedList_t** mods);
143 const char* FS_GetCwd(void);
144 void FS_NormPath(char* path);
145 bool FS_FileExists(const char* filename, ...) __attribute__((format(__printf__, 1, 2)));
146 
147 void FS_GetMaps(bool reset);
148 
149 int FS_OpenFile(const char* filename, qFILE * file, filemode_t mode);
150 void FS_CloseFile(qFILE * f);
151 
152 bool FS_RenameFile(const char* from, const char* to, bool relative);
153 void FS_RemoveFile(const char* osPath);
154 void FS_CopyFile(const char* fromOSPath, const char* toOSPath);
155 
156 /* note: this can't be called from another DLL, due to MS libc issues */
157 
158 int FS_LoadFile(const char* path, byte** buffer);
159 
160 /* a null buffer will just return the file length without loading */
161 /* a -1 length is not present */
162 
163 int FS_Read2(void* buffer, int len, qFILE *f, bool failOnEmptyRead);
164 int FS_Read(void* buffer, int len, qFILE * f);
165 /* properly handles partial reads */
166 
167 void FS_FreeFile(void* buffer);
168 
169 int FS_CheckFile(const char* fmt, ...) __attribute__((format(__printf__, 1, 2)));
170 
171 int FS_BuildFileList(const char* files);
172 const char* FS_NextFileFromFileList(const char* files);
173 char* FS_NextScriptHeader(const char* files, const char** name, const char** text);
174 void FS_CreatePath(const char* path);
175 
176 /* Make sure we have this available */
177 char** FS_ListFiles(const char* findname, int* numfiles, unsigned musthave, unsigned canthave);
178 
179 const char* FS_GetFileData(const char* files);
180 
181 /**
182  * @brief cleanup function
183  */
184 void FS_Shutdown(void);
185 
186 class ScopedFile {
187 private:
188 	qFILE _file;
189 public:
ScopedFile()190 	ScopedFile ()
191 	{
192 		memset(&_file, 0, sizeof(_file));
193 	}
~ScopedFile()194 	~ScopedFile ()
195 	{
196 		FS_CloseFile(&_file);
197 	}
198 	inline qFILE* operator& ()
199 	{
200 		return &_file;
201 	}
202 	inline operator bool () const
203 	{
204 		return file() || zip();
205 	}
file()206 	inline bool file () const
207 	{
208 		return _file.f;
209 	}
zip()210 	inline bool zip () const
211 	{
212 		return _file.z;
213 	}
getFile()214 	inline FILE* getFile () const
215 	{
216 		return _file.getFile();
217 	}
218 };
219