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.19 by root, Thu Nov 8 19:43:23 2007 UTC

1/* 1/*
2 * static char *rcsid_porting_c = 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * "$Id: porting.C,v 1.4 2006/09/07 09:28:44 root Exp $"; 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Deliantra is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <support@deliantra.net>
4 */ 22 */
5
6/*
7 CrossFire, A Multiplayer game for X-windows
8
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen
11
12 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
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 The authors can be reached via e-mail at crossfire-devel@real-time.com
27*/
28 23
29/* This file contains various functions that are not really unique for 24/* This file contains various functions that are not really unique for
30 * crossfire, but rather provides what should be standard functions 25 * crossfire, but rather provides what should be standard functions
31 * for systems that do not have them. In this way, most of the 26 * for systems that do not have them. In this way, most of the
32 * nasty system dependent stuff is contained here, with the program 27 * nasty system dependent stuff is contained here, with the program
33 * calling these functions. 28 * calling these functions.
34 */ 29 */
35 30
36 31
37#ifdef WIN32 /* ---win32 exclude/include headers */ 32/* Need to pull in the HAVE_... values somehow */
38#include "process.h" 33
39#define pid_t int /* we include it non global, because there is a redefinition in python.h */ 34#include <autoconf.h>
40#else 35
36#include <cstdio>
37#include <cstdlib>
38#include <cstdarg>
39
41#include <ctype.h> 40#include <cctype>
41
42#include <sys/stat.h> 42#include <sys/stat.h>
43#include <sys/wait.h> 43#include <sys/wait.h>
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46#include <stdio.h>
47 46
48/* Need to pull in the HAVE_... values somehow */
49/* win32 reminder: always put this in a ifndef win32 block */
50#include <autoconf.h> 47#include <unistd.h>
51#endif
52 48
53
54#ifdef HAVE_STDLIB_H
55#include <stdlib.h>
56#endif
57
58#ifdef HAVE_UNISTD_H
59#include <unistd.h>
60#endif
61
62#include <stdarg.h>
63/* Has to be after above includes so we don't redefine some values */ 49/* Has to be after above includes so we don't redefine some values */
64#include "global.h" 50#include "global.h"
65
66static 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 51
118/* This function removes everything in the directory. */ 52/* This function removes everything in the directory. */
119void 53void
120remove_directory (const char *path) 54remove_directory (const char *path)
121{ 55{
127 if ((dirp = opendir (path)) != NULL) 61 if ((dirp = opendir (path)) != NULL)
128 { 62 {
129 struct dirent *de; 63 struct dirent *de;
130 64
131 for (de = readdir (dirp); de; de = readdir (dirp)) 65 for (de = readdir (dirp); de; de = readdir (dirp))
132 { 66 {
133 /* Don't remove '.' or '..' In theory we should do a better 67 /* Don't remove '.' or '..' In theory we should do a better
134 * check for .., but the directories we are removing are fairly 68 * check for .., but the directories we are removing are fairly
135 * limited and should not have dot files in them. 69 * limited and should not have dot files in them.
136 */ 70 */
137 if (de->d_name[0] == '.') 71 if (de->d_name[0] == '.')
138 continue; 72 continue;
139 73
140 /* Linux actually has a type field in the dirent structure, 74 /* Linux actually has a type field in the dirent structure,
141 * but that is not portable - stat should be portable 75 * but that is not portable - stat should be portable
142 */ 76 */
143 status = stat (de->d_name, &statbuf); 77 status = stat (de->d_name, &statbuf);
144 if ((status != -1) && (S_ISDIR (statbuf.st_mode))) 78 if ((status != -1) && (S_ISDIR (statbuf.st_mode)))
145 { 79 {
80 sprintf (buf, "%s/%s", path, de->d_name);
81 remove_directory (buf);
82 continue;
83 }
146 sprintf (buf, "%s/%s", path, de->d_name); 84 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)) 85 if (unlink (buf))
152 { 86 {
153 LOG (llevError, "Unable to remove directory %s\n", path); 87 LOG (llevError, "Unable to remove directory %s\n", path);
154 } 88 }
155 } 89 }
156 closedir (dirp); 90 closedir (dirp);
157 } 91 }
158 if (rmdir (path)) 92 if (rmdir (path))
159 { 93 {
160 LOG (llevError, "Unable to remove directory %s\n", path); 94 LOG (llevError, "Unable to remove directory %s\n", path);
161 } 95 }
162} 96}
163 97
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
246#define DIGIT(x) (isdigit(x) ? (x) - '0' : \ 98#define DIGIT(x) (isdigit(x) ? (x) - '0' : \
247islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A') 99islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
248#define MBASE ('z' - 'a' + 1 + 10) 100#define MBASE ('z' - 'a' + 1 + 10)
249
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 101
294char * 102char *
295strcasestr_local (const char *s, const char *find) 103strcasestr_local (const char *s, const char *find)
296{ 104{
297 char c, sc; 105 char c, sc;
300 if ((c = *find++) != 0) 108 if ((c = *find++) != 0)
301 { 109 {
302 c = tolower (c); 110 c = tolower (c);
303 len = strlen (find); 111 len = strlen (find);
304 do 112 do
305 { 113 {
306 do 114 do
307 { 115 {
308 if ((sc = *s++) == 0) 116 if ((sc = *s++) == 0)
309 return NULL; 117 return NULL;
310 } 118 }
311 while (tolower (sc) != c); 119 while (tolower (sc) != c);
312 } 120 }
313 while (strncasecmp (s, find, len) != 0); 121 while (strncasecmp (s, find, len) != 0);
314 s--; 122 s--;
315 } 123 }
316 return (char *) s; 124 return (char *) s;
317} 125}
318 126
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/* 127/*
365 * returns a char-pointer to a static array, in which a representation 128 * returns a char-pointer to a static array, in which a representation
366 * of the decimal number given will be stored. 129 * of the decimal number given will be stored.
367 */ 130 */
368
369char * 131char *
370ltostr10 (signed long n) 132ltostr10 (signed long n)
371{ 133{
372 static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1 134 static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1
373 character for the trailing nul character */ 135 character for the trailing nul character */
374 snprintf (buf, sizeof (buf), "%ld", n); 136 snprintf (buf, sizeof (buf), "%ld", n);
375 return buf; 137 return buf;
376} 138}
377 139
378char * 140char *
379doubletostr10 (double v) 141doubletostr10 (double v)
380{ 142{
381 static char tbuf[200]; 143 static char tbuf[200];
144
382 sprintf (tbuf, "%f", v); 145 sprintf (tbuf, "%f", v);
383 return tbuf; 146 return tbuf;
384} 147}
385 148
386/** 149/**
388 * then it opens it and returns the file-pointer. 151 * then it opens it and returns the file-pointer.
389 */ 152 */
390FILE * 153FILE *
391open_and_uncompress (const char *name, int flag, int *compressed) 154open_and_uncompress (const char *name, int flag, int *compressed)
392{ 155{
393 size_t i;
394 FILE *fp;
395
396 *compressed = 0; 156 *compressed = 0;
397 return fopen (name, "r"); 157 return fopen (name, "r");
398} 158}
399 159
400/* 160/*
401 * See open_and_uncompress(). 161 * See open_and_uncompress().
402 */ 162 */
403 163
404void 164void
405close_and_delete (FILE *fp, int compressed) 165close_and_delete (FILE * fp, int compressed)
406{ 166{
407 fclose (fp); 167 fclose (fp);
408} 168}
409 169
410/* 170/*
417 char buf[MAX_BUF], *cp = buf; 177 char buf[MAX_BUF], *cp = buf;
418 struct stat statbuf; 178 struct stat statbuf;
419 179
420 if (!filename || !*filename) 180 if (!filename || !*filename)
421 return; 181 return;
182
422 strcpy (buf, filename); 183 assign (buf, filename);
423 184
424 while ((cp = strchr (cp + 1, (int) '/'))) 185 while ((cp = strchr (cp + 1, (int) '/')))
425 { 186 {
426 *cp = '\0'; 187 *cp = '\0';
427 if (stat (buf, &statbuf) || !S_ISDIR (statbuf.st_mode)) 188 if (stat (buf, &statbuf) || !S_ISDIR (statbuf.st_mode))
428 { 189 {
429 if (mkdir (buf, SAVE_DIR_MODE)) 190 if (mkdir (buf, SAVE_DIR_MODE))
430 { 191 {
431 LOG (llevError, "Cannot mkdir %s: %s\n", buf, strerror (errno)); 192 LOG (llevError, "Cannot mkdir %s: %s\n", buf, strerror (errno));
432 return; 193 return;
433 } 194 }
434 } 195 }
435 *cp = '/'; 196 *cp = '/';
436 } 197 }
437} 198}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines