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.12 by root, Mon Jan 15 01:25:41 2007 UTC

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/* 1/*
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
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