ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/porting.C
Revision: 1.9
Committed: Mon Dec 11 19:46:46 2006 UTC (17 years, 5 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.8: +6 -12 lines
Log Message:
removed #ifn?def WIN32 from all files

File Contents

# Content
1 /*
2 CrossFire, A Multiplayer game for X-windows
3
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 */
23
24 /* This file contains various functions that are not really unique for
25 * crossfire, but rather provides what should be standard functions
26 * for systems that do not have them. In this way, most of the
27 * nasty system dependent stuff is contained here, with the program
28 * calling these functions.
29 */
30
31
32 #include <ctype.h>
33 #include <sys/stat.h>
34 #include <sys/wait.h>
35
36 #include <sys/param.h>
37 #include <stdio.h>
38
39 /* Need to pull in the HAVE_... values somehow */
40
41 #include <autoconf.h>
42
43
44 #ifdef HAVE_STDLIB_H
45 # include <stdlib.h>
46 #endif
47
48 #ifdef HAVE_UNISTD_H
49 # include <unistd.h>
50 #endif
51
52 #include <stdarg.h>
53
54 /* Has to be after above includes so we don't redefine some values */
55 #include "global.h"
56
57 static unsigned int curtmp = 0;
58
59 /*****************************************************************************
60 * File related functions
61 ****************************************************************************/
62
63 /*
64 * A replacement for the tempnam() function since it's not defined
65 * at some unix variants.
66 */
67
68 char *
69 tempnam_local (const char *dir, const char *pfx)
70 {
71 char *name;
72 pid_t pid = getpid ();
73
74 /* HURD does not have a hard limit, but we do */
75 #ifndef MAXPATHLEN
76 # define MAXPATHLEN 4096
77 #endif
78
79 if (!(name = (char *) malloc (MAXPATHLEN)))
80 return (NULL);
81
82 if (!pfx)
83 pfx = "cftmp.";
84
85 /* This is a pretty simple method - put the pid as a hex digit and
86 * just keep incrementing the last digit. Check to see if the file
87 * already exists - if so, we'll just keep looking - eventually we should
88 * find one that is free.
89 */
90 if (dir != NULL)
91 {
92 do
93 {
94 #ifdef HAVE_SNPRINTF
95 (void) snprintf (name, MAXPATHLEN, "%s/%s%hx.%d", dir, pfx, pid, curtmp);
96 #else
97 (void) sprintf (name, "%s/%s%hx%d", dir, pfx, pid, curtmp);
98 #endif
99 curtmp++;
100 }
101 while (access (name, F_OK) != -1);
102 return (name);
103 }
104 return (NULL);
105 }
106
107
108
109 /* This function removes everything in the directory. */
110 void
111 remove_directory (const char *path)
112 {
113 DIR *dirp;
114 char buf[MAX_BUF];
115 struct stat statbuf;
116 int status;
117
118 if ((dirp = opendir (path)) != NULL)
119 {
120 struct dirent *de;
121
122 for (de = readdir (dirp); de; de = readdir (dirp))
123 {
124 /* Don't remove '.' or '..' In theory we should do a better
125 * check for .., but the directories we are removing are fairly
126 * limited and should not have dot files in them.
127 */
128 if (de->d_name[0] == '.')
129 continue;
130
131 /* Linux actually has a type field in the dirent structure,
132 * but that is not portable - stat should be portable
133 */
134 status = stat (de->d_name, &statbuf);
135 if ((status != -1) && (S_ISDIR (statbuf.st_mode)))
136 {
137 sprintf (buf, "%s/%s", path, de->d_name);
138 remove_directory (buf);
139 continue;
140 }
141 sprintf (buf, "%s/%s", path, de->d_name);
142 if (unlink (buf))
143 {
144 LOG (llevError, "Unable to remove directory %s\n", path);
145 }
146 }
147 closedir (dirp);
148 }
149 if (rmdir (path))
150 {
151 LOG (llevError, "Unable to remove directory %s\n", path);
152 }
153 }
154
155 #if defined(sgi)
156
157 # include <stdio.h>
158 # include <stdlib.h>
159 # include <string.h>
160
161 # define popen fixed_popen
162
163 FILE *
164 popen_local (const char *command, const char *type)
165 {
166 int fd[2];
167 int pd;
168 FILE *ret;
169
170 if (!strcmp (type, "r"))
171 pd = STDOUT_FILENO;
172 else if (!strcmp (type, "w"))
173 pd = STDIN_FILENO;
174 else
175 return NULL;
176
177 if (pipe (fd) != -1)
178 {
179 switch (fork ())
180 {
181 case -1:
182 close (fd[0]);
183 close (fd[1]);
184 break;
185 case 0:
186 close (fd[0]);
187 if ((fd[1] == pd) || (dup2 (fd[1], pd) == pd))
188 {
189 if (fd[1] != pd)
190 {
191 close (fd[1]);
192 }
193 execl ("/bin/sh", "sh", "-c", command, NULL);
194 close (pd);
195 }
196 _exit (1);
197 break;
198 default:
199 close (fd[1]);
200 if (ret = fdopen (fd[0], type))
201 {
202 return ret;
203 }
204 close (fd[0]);
205 break;
206 }
207 }
208 return NULL;
209 }
210
211 #endif /* defined(sgi) */
212
213
214 /*****************************************************************************
215 * String related function
216 ****************************************************************************/
217
218 /*
219 * A replacement of strdup(), since it's not defined at some
220 * unix variants.
221 */
222 char *
223 strdup_local (const char *str)
224 {
225 char *c = (char *) malloc (sizeof (char) * (strlen (str) + 1));
226
227 strcpy (c, str);
228 return c;
229 }
230
231
232 #define DIGIT(x) (isdigit(x) ? (x) - '0' : \
233 islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
234 #define MBASE ('z' - 'a' + 1 + 10)
235
236 /* This seems to be lacking on some system */
237 #if !defined(HAVE_STRNCASECMP)
238 int
239 strncasecmp (const char *s1, const char *s2, int n)
240 {
241 register int c1, c2;
242
243 while (*s1 && *s2 && n)
244 {
245 c1 = tolower (*s1);
246 c2 = tolower (*s2);
247 if (c1 != c2)
248 return (c1 - c2);
249 s1++;
250 s2++;
251 n--;
252 }
253 if (!n)
254 return (0);
255 return (int) (*s1 - *s2);
256 }
257 #endif
258
259 #if !defined(HAVE_STRCASECMP)
260 int
261 strcasecmp (const char *s1, const char *s2)
262 {
263 register int c1, c2;
264
265 while (*s1 && *s2)
266 {
267 c1 = tolower (*s1);
268 c2 = tolower (*s2);
269 if (c1 != c2)
270 return (c1 - c2);
271 s1++;
272 s2++;
273 }
274 if (*s1 == '\0' && *s2 == '\0')
275 return 0;
276 return (int) (*s1 - *s2);
277 }
278 #endif
279
280 char *
281 strcasestr_local (const char *s, const char *find)
282 {
283 char c, sc;
284 size_t len;
285
286 if ((c = *find++) != 0)
287 {
288 c = tolower (c);
289 len = strlen (find);
290 do
291 {
292 do
293 {
294 if ((sc = *s++) == 0)
295 return NULL;
296 }
297 while (tolower (sc) != c);
298 }
299 while (strncasecmp (s, find, len) != 0);
300 s--;
301 }
302 return (char *) s;
303 }
304
305 #if !defined(HAVE_SNPRINTF)
306
307 int
308 snprintf (char *dest, int max, const char *format, ...)
309 {
310 va_list var;
311 int ret;
312
313 va_start (var, format);
314 ret = vsprintf (dest, format, var);
315 va_end (var);
316 if (ret > max)
317 abort ();
318
319 return ret;
320 }
321 #endif
322
323
324 /*
325 * Based on (n+1)^2 = n^2 + 2n + 1
326 * given that 1^2 = 1, then
327 * 2^2 = 1 + (2 + 1) = 1 + 3 = 4
328 * 3^2 = 4 + (4 + 1) = 4 + 5 = 1 + 3 + 5 = 9
329 * 4^2 = 9 + (6 + 1) = 9 + 7 = 1 + 3 + 5 + 7 = 16
330 * ...
331 * In other words, a square number can be express as the sum of the
332 * series n^2 = 1 + 3 + ... + (2n-1)
333 */
334 int
335 isqrt (int n)
336 {
337 int result, sum, prev;
338
339 result = 0;
340 prev = sum = 1;
341 while (sum <= n)
342 {
343 prev += 2;
344 sum += prev;
345 ++result;
346 }
347 return result;
348 }
349
350
351 /*
352 * returns a char-pointer to a static array, in which a representation
353 * of the decimal number given will be stored.
354 */
355
356 char *
357 ltostr10 (signed long n)
358 {
359 static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1
360 character for the trailing nul character */
361 snprintf (buf, sizeof (buf), "%ld", n);
362 return buf;
363 }
364
365 char *
366 doubletostr10 (double v)
367 {
368 static char tbuf[200];
369
370 sprintf (tbuf, "%f", v);
371 return tbuf;
372 }
373
374 /**
375 * open_and_uncompress() first searches for the original filename. If it exist,
376 * then it opens it and returns the file-pointer.
377 */
378 FILE *
379 open_and_uncompress (const char *name, int flag, int *compressed)
380 {
381 *compressed = 0;
382 return fopen (name, "r");
383 }
384
385 /*
386 * See open_and_uncompress().
387 */
388
389 void
390 close_and_delete (FILE * fp, int compressed)
391 {
392 fclose (fp);
393 }
394
395 /*
396 * If any directories in the given path doesn't exist, they are created.
397 */
398
399 void
400 make_path_to_file (char *filename)
401 {
402 char buf[MAX_BUF], *cp = buf;
403 struct stat statbuf;
404
405 if (!filename || !*filename)
406 return;
407 strcpy (buf, filename);
408
409 while ((cp = strchr (cp + 1, (int) '/')))
410 {
411 *cp = '\0';
412 if (stat (buf, &statbuf) || !S_ISDIR (statbuf.st_mode))
413 {
414 if (mkdir (buf, SAVE_DIR_MODE))
415 {
416 LOG (llevError, "Cannot mkdir %s: %s\n", buf, strerror (errno));
417 return;
418 }
419 }
420 *cp = '/';
421 }
422 }