]> icculus.org git repositories - divverent/darkplaces.git/blob - quakeio.c
forgot to put in extern qboolean hlbsp;
[divverent/darkplaces.git] / quakeio.c
1 /*
2         quakeio.c
3
4         (description)
5
6         Copyright (C) 1996-1997  Id Software, Inc.
7         Copyright (C) 1999,2000  contributors of the QuakeForge project
8         Please see the file "AUTHORS" for a list of contributors
9
10         This program is free software; you can redistribute it and/or
11         modify it under the terms of the GNU General Public License
12         as published by the Free Software Foundation; either version 2
13         of the License, or (at your option) any later version.
14
15         This program is distributed in the hope that it will be useful,
16         but WITHOUT ANY WARRANTY; without even the implied warranty of
17         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19         See the GNU General Public License for more details.
20
21         You should have received a copy of the GNU General Public License
22         along with this program; if not, write to:
23
24                 Free Software Foundation, Inc.
25                 59 Temple Place - Suite 330
26                 Boston, MA  02111-1307, USA
27
28         $Id$
29 */
30
31 #include <stdlib.h>
32 #include <string.h>
33 #ifdef WIN32
34 # include <io.h>
35 # include <fcntl.h>
36 #else
37 # include <pwd.h>
38 # include <unistd.h>
39 #endif
40
41 #define HAVE_ZLIB
42
43 #ifdef _MSC_VER
44 # define _POSIX_
45 #endif
46
47 #include <stdarg.h>
48 #include <stdlib.h>
49 #include <limits.h>
50
51 #include "QF/quakefs.h"
52 #include "QF/quakeio.h"
53
54 #ifdef WIN32
55 # ifndef __BORLANDC__
56 #  define setmode _setmode
57 #  define O_BINARY _O_BINARY
58 # endif
59 #endif
60
61 void
62 Qexpand_squiggle (const char *path, char *dest)
63 {
64         char       *home;
65
66 #ifndef _WIN32
67         struct passwd *pwd_ent;
68 #endif
69
70         if (strncmp (path, "~/", 2) != 0) {
71                 strcpy (dest, path);
72                 return;
73         }
74
75 #ifdef _WIN32
76         // LordHavoc: first check HOME to duplicate previous version behavior
77         // (also handy if someone wants it somewhere other than their
78         //  windows directory)
79         home = getenv ("HOME");
80         if (!home || !home[0])
81                 home = getenv ("WINDIR");
82 #else
83         if ((pwd_ent = getpwuid (getuid ()))) {
84                 home = pwd_ent->pw_dir;
85         } else
86                 home = getenv ("HOME");
87 #endif
88
89         if (home) {
90                 strcpy (dest, home);
91                 strncat (dest, path + 1, MAX_OSPATH - strlen (dest));   // skip
92                                                                                                                                 // leading ~
93         } else
94                 strcpy (dest, path);
95 }
96
97 int
98 Qrename (const char *old, const char *new)
99 {
100         char        e_old[PATH_MAX];
101         char        e_new[PATH_MAX];
102
103         Qexpand_squiggle (old, e_old);
104         Qexpand_squiggle (new, e_new);
105         return rename (e_old, e_new);
106 }
107
108 QFile *
109 Qopen (const char *path, const char *mode)
110 {
111         QFile      *file;
112         char        m[80], *p;
113         int         zip = 0;
114         char        e_path[PATH_MAX];
115
116         Qexpand_squiggle (path, e_path);
117         path = e_path;
118
119         for (p = m; *mode && p - m < (sizeof (m) - 1); mode++) {
120                 if (*mode == 'z') {
121                         zip = 1;
122                         continue;
123                 }
124 #ifndef HAVE_ZLIB
125                 if (strchr ("0123456789fh", *mode)) {
126                         continue;
127                 }
128 #endif
129                 *p++ = *mode;
130         }
131         *p = 0;
132
133         file = calloc (sizeof (*file), 1);
134         if (!file)
135                 return 0;
136 #ifdef HAVE_ZLIB
137         if (zip) {
138                 file->gzfile = gzopen (path, m);
139                 if (!file->gzfile) {
140                         free (file);
141                         return 0;
142                 }
143         } else
144 #endif
145         {
146                 file->file = fopen (path, m);
147                 if (!file->file) {
148                         free (file);
149                         return 0;
150                 }
151         }
152         return file;
153 }
154
155 QFile *
156 Qdopen (int fd, const char *mode)
157 {
158         QFile      *file;
159         char        m[80], *p;
160         int         zip = 0;
161
162         for (p = m; *mode && p - m < (sizeof (m) - 1); mode++) {
163                 if (*mode == 'z') {
164                         zip = 1;
165                         continue;
166                 }
167                 *p++ = *mode;
168         }
169
170         *p = 0;
171
172         file = calloc (sizeof (*file), 1);
173         if (!file)
174                 return 0;
175 #ifdef HAVE_ZLIB
176         if (zip) {
177                 file->gzfile = gzdopen (fd, m);
178                 if (!file->gzfile) {
179                         free (file);
180                         return 0;
181                 }
182         } else
183 #endif
184         {
185                 file->file = fdopen (fd, m);
186                 if (!file->file) {
187                         free (file);
188                         return 0;
189                 }
190         }
191 #ifdef WIN32
192         if (file->file)
193                 setmode (_fileno (file->file), O_BINARY);
194 #endif
195         return file;
196 }
197
198 void
199 Qclose (QFile *file)
200 {
201         if (file->file)
202                 fclose (file->file);
203 #ifdef HAVE_ZLIB
204         else
205                 gzclose (file->gzfile);
206 #endif
207         free (file);
208 }
209
210 int
211 Qread (QFile *file, void *buf, int count)
212 {
213         if (file->file)
214                 return fread (buf, 1, count, file->file);
215 #ifdef HAVE_ZLIB
216         else
217                 return gzread (file->gzfile, buf, count);
218 #else
219         return -1;
220 #endif
221 }
222
223 int
224 Qwrite (QFile *file, void *buf, int count)
225 {
226         if (file->file)
227                 return fwrite (buf, 1, count, file->file);
228 #ifdef HAVE_ZLIB
229         else
230                 return gzwrite (file->gzfile, buf, count);
231 #else
232         return -1;
233 #endif
234 }
235
236 int
237 Qprintf (QFile *file, const char *fmt, ...)
238 {
239         va_list     args;
240         int         ret = -1;
241
242         va_start (args, fmt);
243         if (file->file)
244                 ret = vfprintf (file->file, fmt, args);
245 #ifdef HAVE_ZLIB
246         else {
247                 char        buf[4096];
248
249                 va_start (args, fmt);
250 #ifdef HAVE_VSNPRINTF
251                 (void) vsnprintf (buf, sizeof (buf), fmt, args);
252 #else
253                 (void) vsprintf (buf, fmt, args);
254 #endif
255                 va_end (args);
256                 ret = strlen (buf);                             /* some *snprintf don't return the nb 
257                                                                                    of bytes written */
258                 if (ret > 0)
259                         ret = gzwrite (file->gzfile, buf, (unsigned) ret);
260         }
261 #endif
262         va_end (args);
263         return ret;
264 }
265
266 char *
267 Qgets (QFile *file, char *buf, int count)
268 {
269         if (file->file)
270                 return fgets (buf, count, file->file);
271 #ifdef HAVE_ZLIB
272         else
273                 return gzgets (file->gzfile, buf, count);
274 #else
275         return 0;
276 #endif
277 }
278
279 int
280 Qgetc (QFile *file)
281 {
282         if (file->file)
283                 return fgetc (file->file);
284 #ifdef HAVE_ZLIB
285         else
286                 return gzgetc (file->gzfile);
287 #else
288         return -1;
289 #endif
290 }
291
292 int
293 Qputc (QFile *file, int c)
294 {
295         if (file->file)
296                 return fputc (c, file->file);
297 #ifdef HAVE_ZLIB
298         else
299                 return gzputc (file->gzfile, c);
300 #else
301         return -1;
302 #endif
303 }
304
305 int
306 Qseek (QFile *file, long offset, int whence)
307 {
308         if (file->file)
309                 return fseek (file->file, offset, whence);
310 #ifdef HAVE_ZLIB
311         else
312                 return gzseek (file->gzfile, offset, whence);
313 #else
314         return -1;
315 #endif
316 }
317
318 long
319 Qtell (QFile *file)
320 {
321         if (file->file)
322                 return ftell (file->file);
323 #ifdef HAVE_ZLIB
324         else
325                 return gztell (file->gzfile);
326 #else
327         return -1;
328 #endif
329 }
330
331 int
332 Qflush (QFile *file)
333 {
334         if (file->file)
335                 return fflush (file->file);
336 #ifdef HAVE_ZLIB
337         else
338                 return gzflush (file->gzfile, Z_SYNC_FLUSH);
339 #else
340         return -1;
341 #endif
342 }
343
344 int
345 Qeof (QFile *file)
346 {
347         if (file->file)
348                 return feof (file->file);
349 #ifdef HAVE_ZLIB
350         else
351                 return gzeof (file->gzfile);
352 #else
353         return -1;
354 #endif
355 }
356
357 /*
358
359         Qgetline
360
361         Dynamic length version of Qgets. DO NOT free the buffer.
362
363 */
364 char *
365 Qgetline (QFile *file)
366 {
367         static int  size = 256;
368         static char *buf = 0;
369         int         len;
370
371         if (!buf)
372                 buf = malloc (size);
373
374         if (!Qgets (file, buf, size))
375                 return 0;
376
377         len = strlen (buf);
378         while (buf[len - 1] != '\n') {
379                 char       *t = realloc (buf, size + 256);
380
381                 if (!t)
382                         return 0;
383                 buf = t;
384                 size += 256;
385                 if (!Qgets (file, buf + len, size - len))
386                         break;
387                 len = strlen (buf);
388         }
389         return buf;
390 }
391
392 int
393 Qgetpos (QFile *file, fpos_t * pos)
394 {
395 #ifdef HAVE_FPOS_T_STRUCT
396         pos->__pos = Qtell (file);
397         return pos->__pos == -1 ? -1 : 0;
398 #else
399         *pos = Qtell (file);
400         return *pos == -1 ? -1 : 0;
401 #endif
402 }
403
404 int
405 Qsetpos (QFile *file, fpos_t * pos)
406 {
407 #ifdef HAVE_FPOS_T_STRUCT
408         return Qseek (file, pos->__pos, 0);
409 #else
410         return Qseek (file, *pos, 0);
411 #endif
412 }