ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/porting.C
Revision: 1.8
Committed: Sat Dec 9 17:28:37 2006 UTC (17 years, 5 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.7: +0 -3 lines
Log Message:
removed regex comparison. this is now done with perl

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