ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/porting.C
(Generate patch)

Comparing deliantra/server/common/porting.C (file contents):
Revision 1.4 by root, Thu Sep 7 09:28:44 2006 UTC vs.
Revision 1.13 by pippijn, Mon Jan 15 21:06:18 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines