ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/utils.C
Revision: 1.108
Committed: Sat Nov 17 23:40:00 2018 UTC (5 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.107: +1 -0 lines
Log Message:
copyright update 2018

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.68 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 root 1.101 *
4 root 1.108 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
5 root 1.104 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
6 root 1.101 *
7 root 1.89 * Deliantra is free software: you can redistribute it and/or modify it under
8     * the terms of the Affero GNU General Public License as published by the
9     * Free Software Foundation, either version 3 of the License, or (at your
10     * option) any later version.
11 root 1.101 *
12 root 1.60 * 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 root 1.101 *
17 root 1.89 * You should have received a copy of the Affero GNU General Public License
18     * and the GNU General Public License along with this program. If not, see
19     * <http://www.gnu.org/licenses/>.
20 root 1.101 *
21 root 1.68 * The authors can be reached via e-mail to <support@deliantra.net>
22 pippijn 1.39 */
23 elmex 1.1
24     /*
25 root 1.92 * General convenience functions for deliantra.
26 elmex 1.1 */
27    
28 root 1.37 #include <cstdlib>
29     #include <sys/types.h>
30     #include <unistd.h>
31     #include <sys/time.h>
32     #include <time.h>
33     #include <signal.h>
34    
35 elmex 1.1 #include <global.h>
36     #include <material.h>
37 sf-marcmagus 1.87 #include <object.h>
38 elmex 1.1
39 root 1.79 #include <sys/time.h>
40     #include <sys/resource.h>
41    
42 root 1.4 #include <glib.h>
43    
44 root 1.63 refcnt_base::refcnt_t refcnt_dummy;
45 root 1.74 ssize_t slice_alloc;
46 root 1.40
47 sf-marcmagus 1.87 /******************************************************************************/
48    
49     /* Checks a player-provided string which will become the msg property of
50     * an object for dangerous input.
51     */
52 root 1.105 bool
53 sf-marcmagus 1.87 msg_is_safe (const char *msg)
54     {
55     bool safe = true;
56    
57     /* Trying to cheat by getting data into the object */
58 root 1.88 if (!strncmp (msg, "endmsg", sizeof ("endmsg") - 1)
59     || strstr (msg, "\nendmsg"))
60 sf-marcmagus 1.87 safe = false;
61    
62     /* Trying to make the object talk, and potentially access arbitrary code */
63     if (object::msg_has_dialogue (msg))
64     safe = false;
65    
66     return safe;
67     }
68    
69 root 1.14 /////////////////////////////////////////////////////////////////////////////
70    
71 root 1.37 void
72     fork_abort (const char *msg)
73     {
74     if (!fork ())
75     {
76 root 1.80 signal (SIGINT , SIG_IGN);
77     signal (SIGTERM, SIG_IGN);
78     signal (SIGABRT, SIG_IGN);
79 root 1.79
80 root 1.81 signal (SIGSEGV, SIG_DFL);
81 root 1.103 signal (SIGFPE , SIG_DFL);
82     #ifdef SIGBUS
83 root 1.81 signal (SIGBUS , SIG_DFL);
84 root 1.103 #endif
85 root 1.81 signal (SIGILL , SIG_DFL);
86     signal (SIGTRAP, SIG_DFL);
87    
88 root 1.52 // try to put corefiles into a subdirectory, if existing, to allow
89     // an administrator to reduce the I/O load.
90     chdir ("cores");
91 root 1.79
92     // try to detach us from as many external dependencies as possible
93     // as coredumping can take time by closing all fd's.
94     {
95     struct rlimit lim;
96    
97     if (getrlimit (RLIMIT_NOFILE, &lim))
98     lim.rlim_cur = 1024;
99    
100     for (int i = 0; i < lim.rlim_cur; ++i)
101     close (i);
102     }
103    
104 root 1.81 {
105     sigset_t empty;
106     sigemptyset (&empty);
107     sigprocmask (SIG_SETMASK, &empty, 0);
108     }
109    
110     // try to coredump with SIGTRAP
111     kill (getpid (), SIGTRAP);
112 root 1.37 abort ();
113     }
114    
115 root 1.38 LOG (llevError, "fork abort: %s\n", msg);
116 root 1.37 }
117 root 1.38
118 root 1.99 void *
119 root 1.106 salloc_ (int n)
120 root 1.10 {
121 root 1.25 void *ptr = g_slice_alloc (n);
122 root 1.13
123 root 1.23 if (!ptr)
124 root 1.13 throw std::bad_alloc ();
125 root 1.4
126 root 1.74 slice_alloc += n;
127 root 1.23 return ptr;
128     }
129    
130 root 1.99 void *
131 root 1.106 salloc_ (int n, void *src)
132 root 1.23 {
133 root 1.25 void *ptr = salloc_ (n);
134 root 1.23
135 root 1.24 if (src)
136 root 1.25 memcpy (ptr, src, n);
137 root 1.24 else
138 root 1.25 memset (ptr, 0, n);
139 root 1.23
140     return ptr;
141 root 1.3 }
142 root 1.11
143 root 1.69 /******************************************************************************/
144    
145 root 1.72 #if DEBUG_SALLOC
146 root 1.69
147 root 1.70 #define MAGIC 0xa1b2c35543deadLL
148 root 1.69
149 root 1.99 void *
150     g_slice_alloc (unsigned long size)
151 root 1.69 {
152     unsigned long *p = (unsigned long *) (g_slice_alloc)(size + sizeof (unsigned long));
153     *p++ = size ^ MAGIC;
154     //fprintf (stderr, "g_slice_alloc %ld %p\n", size, p);//D
155     return (void *)p;
156     }
157    
158 root 1.99 void *
159     g_slice_alloc0 (unsigned long size)
160 root 1.69 {
161     return memset (g_slice_alloc (size), 0, size);
162     }
163    
164 root 1.99 void
165     g_slice_free1 (unsigned long size, void *ptr)
166 root 1.69 {
167 root 1.74 //fprintf (stderr, "g_slice_free %ld %p\n", size, ptr);//D
168 root 1.69 if (expect_true (ptr))
169     {
170     unsigned long *p = (unsigned long *)ptr;
171     unsigned long s = *--p ^ MAGIC;
172    
173 root 1.71 if (size != (unsigned long)(*p ^ MAGIC))
174 root 1.74 {
175     LOG (logBacktrace | llevError, "slice free size (%lx) doesn't match alloc size (%lx)\n", size, s);
176     abort ();
177     }
178 root 1.69
179     *p = MAGIC;
180    
181     (g_slice_free1)(s + sizeof (unsigned long), p);
182     }
183     }
184    
185     #endif
186    
187     /******************************************************************************/
188    
189 root 1.99 refcnt_buf::refcnt_buf (size_t size)
190     {
191 root 1.102 static uint32_t empty_buf [2] = { 0, 1 }; // 2 == never deallocated
192     data = (char *)empty_buf + overhead;
193     assert (overhead == sizeof (empty_buf));
194     inc ();
195 root 1.99 }
196    
197     refcnt_buf::refcnt_buf (void *data, size_t size)
198     {
199     _alloc (size);
200     memcpy (this->data, data, size);
201     }
202    
203     refcnt_buf::~refcnt_buf ()
204     {
205     dec ();
206     }
207    
208 root 1.102 void
209     refcnt_buf::_dealloc ()
210     {
211     sfree<char> (data - overhead, size () + overhead);
212     }
213    
214 root 1.99 refcnt_buf &
215     refcnt_buf::operator =(const refcnt_buf &src)
216     {
217     dec ();
218     data = src.data;
219 root 1.102 inc ();
220 root 1.99 return *this;
221     }
222    
223     /******************************************************************************/
224    
225 root 1.86 int
226     assign (char *dst, const char *src, int maxsize)
227 root 1.11 {
228     if (!src)
229     src = "";
230    
231     int len = strlen (src);
232    
233 root 1.86 if (len >= maxsize)
234 root 1.11 {
235 root 1.86 if (maxsize <= 4)
236 root 1.11 {
237 root 1.86 memset (dst, '.', maxsize - 2);
238     dst [maxsize - 1] = 0;
239 root 1.11 }
240     else
241     {
242 root 1.86 memcpy (dst, src, maxsize - 4);
243     memcpy (dst + maxsize - 4, "...", 4);
244 root 1.11 }
245 root 1.86
246     len = maxsize;
247 root 1.11 }
248     else
249 root 1.86 memcpy (dst, src, ++len);
250    
251     return len;
252 root 1.11 }
253    
254 root 1.90 char *
255     vformat (const char *format, va_list ap)
256     {
257 root 1.96 static dynbuf_text bufs[8];
258     static int bufidx;
259    
260     dynbuf_text &buf = bufs [++bufidx & 7];
261    
262     buf.clear ();
263 root 1.90 buf.vprintf (format, ap);
264     return buf;
265     }
266    
267     char *
268 root 1.51 format (const char *format, ...)
269     {
270 root 1.65 va_list ap;
271     va_start (ap, format);
272 root 1.90 char *buf = vformat (format, ap);
273 root 1.65 va_end (ap);
274    
275     return buf;
276 root 1.51 }
277    
278 root 1.99 tstamp
279     now ()
280 root 1.23 {
281     struct timeval tv;
282    
283     gettimeofday (&tv, 0);
284     return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
285     }
286 root 1.17
287 root 1.32 int
288     similar_direction (int a, int b)
289     {
290     if (!a || !b)
291     return 0;
292    
293     int diff = (b - a) & 7;
294     return diff <= 1 || diff >= 7;
295     }
296    
297 root 1.48 /* crc32 0xdebb20e3 table and supplementary functions. */
298     extern const uint32_t crc_32_tab[256] =
299     {
300     0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
301     0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
302     0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
303     0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
304     0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
305     0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
306     0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
307     0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
308     0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
309     0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
310     0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
311     0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
312     0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
313     0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
314     0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
315     0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
316     0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
317     0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
318     0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
319     0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
320     0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
321     0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
322     0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
323     0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
324     0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
325     0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
326     0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
327     0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
328     0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
329     0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
330     0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
331     0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
332     0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
333     0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
334     0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
335     0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
336     0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
337     0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
338     0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
339     0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
340     0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
341     0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
342     0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
343     0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
344     0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
345     0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
346     0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
347     0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
348     0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
349     0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
350     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
351     0x2d02ef8dL
352     };
353    
354 root 1.99 void
355     thread::start (void *(*start_routine)(void *), void *arg)
356 root 1.73 {
357 root 1.75 pthread_attr_t attr;
358    
359     pthread_attr_init (&attr);
360     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
361     pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096
362     ? sizeof (long) * 4096 : PTHREAD_STACK_MIN);
363     #ifdef PTHREAD_SCOPE_PROCESS
364     pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
365     #endif
366    
367 root 1.73 sigset_t fullsigset, oldsigset;
368     sigfillset (&fullsigset);
369    
370     pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
371    
372 root 1.75 if (pthread_create (&id, &attr, start_routine, arg))
373 root 1.73 cleanup ("unable to create a new thread");
374    
375     pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
376     }
377 root 1.75