/[cvs]/eggdrop1.8/src/mem.c
ViewVC logotype

Contents of /eggdrop1.8/src/mem.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Tue Oct 19 12:13:33 2010 UTC (8 years, 11 months ago) by pseudo
Branch: MAIN
CVS Tags: HEAD
Branch point for: gettext
Changes since 1.1: +21 -3 lines
File MIME type: text/x-chdr
Added full SSL support including Tcl commands.
Added support for certificate authentication.
Added support for botnet and partyline encryption using ssl.
Documented the new features and commands.
Fixed add_server() problems with IPv6 addresses in the server list.

1 /*
2 * mem.c -- handles:
3 * memory allocation and deallocation
4 * keeping track of what memory is being used by whom
5 *
6 * $Id: mem.c,v 1.1.1.1 2010/07/26 21:11:06 simple Exp $
7 */
8 /*
9 * Copyright (C) 1997 Robey Pointer
10 * Copyright (C) 1999 - 2010 Eggheads Development Team
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 #define MEMTBLSIZE 25000 /* yikes! */
28 #define COMPILING_MEM
29
30 #include "main.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <errno.h>
35
36 #include "mod/modvals.h"
37
38
39 extern module_entry *module_list;
40
41 #ifdef DEBUG_MEM
42 unsigned long memused = 0;
43 static int lastused = 0;
44
45 struct {
46 void *ptr;
47 int size;
48 short line;
49 char file[20];
50 } memtbl[MEMTBLSIZE];
51 #endif
52
53 /* Prototypes */
54 int expected_memory();
55 int expmem_chanprog();
56 int expmem_misc();
57 int expmem_fileq();
58 int expmem_users();
59 int expmem_dccutil();
60 int expmem_botnet();
61 int expmem_tcl();
62 int expmem_tclhash();
63 int expmem_tclmisc();
64 int expmem_net();
65 int expmem_modules();
66 int expmem_language();
67 int expmem_tcldcc();
68 int expmem_dns();
69 #ifdef TLS
70 int expmem_tls();
71 #endif
72
73 /* Initialize the memory structure
74 */
75 void init_mem()
76 {
77 #ifdef DEBUG_MEM
78 int i;
79
80 for (i = 0; i < MEMTBLSIZE; i++)
81 memtbl[i].ptr = NULL;
82 #endif
83 }
84
85 /* Tell someone the gory memory details
86 */
87 void tell_mem_status(char *nick)
88 {
89 #ifdef DEBUG_MEM
90 float per;
91
92 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
93 dprintf(DP_HELP, "NOTICE %s :Memory table usage: %d/%d (%.1f%% full)\n",
94 nick, lastused, MEMTBLSIZE, per);
95 #endif
96 dprintf(DP_HELP, "NOTICE %s :Think I'm using about %dk.\n", nick,
97 (int) (expected_memory() / 1024));
98 }
99
100 void tell_mem_status_dcc(int idx)
101 {
102 #ifdef DEBUG_MEM
103 int exp;
104 float per;
105
106 exp = expected_memory(); /* in main.c ? */
107 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
108 dprintf(idx, "Memory table: %d/%d (%.1f%% full)\n", lastused, MEMTBLSIZE,
109 per);
110 per = ((exp * 1.0) / (memused * 1.0)) * 100.0;
111 if (per != 100.0)
112 dprintf(idx, "Memory fault: only accounting for %d/%ld (%.1f%%)\n",
113 exp, memused, per);
114 dprintf(idx, "Memory table itself occupies an additional %dk static\n",
115 (int) (sizeof(memtbl) / 1024));
116 #endif
117 }
118
119 void debug_mem_to_dcc(int idx)
120 {
121 #ifdef DEBUG_MEM
122 # ifdef TLS
123 # define MAX_MEM 14
124 # else
125 # define MAX_MEM 13
126 # endif
127 unsigned long exp[MAX_MEM], use[MAX_MEM], l;
128 int i, j;
129 char fn[20], sofar[81];
130 module_entry *me;
131 char *p;
132
133 exp[0] = expmem_language();
134 exp[1] = expmem_chanprog();
135 exp[2] = expmem_misc();
136 exp[3] = expmem_users();
137 exp[4] = expmem_net();
138 exp[5] = expmem_dccutil();
139 exp[6] = expmem_botnet();
140 exp[7] = expmem_tcl();
141 exp[8] = expmem_tclhash();
142 exp[9] = expmem_tclmisc();
143 exp[10] = expmem_modules(1);
144 exp[11] = expmem_tcldcc();
145 exp[12] = expmem_dns();
146 #ifdef TLS
147 exp[13] = expmem_tls();
148 #endif
149
150 for (me = module_list; me; me = me->next)
151 me->mem_work = 0;
152
153 for (i = 0; i < MAX_MEM; i++)
154 use[i] = 0;
155
156 for (i = 0; i < lastused; i++) {
157 strcpy(fn, memtbl[i].file);
158 p = strchr(fn, ':');
159 if (p)
160 *p = 0;
161 l = memtbl[i].size;
162 if (!strcmp(fn, "language.c"))
163 use[0] += l;
164 else if (!strcmp(fn, "chanprog.c"))
165 use[1] += l;
166 else if (!strcmp(fn, "misc.c"))
167 use[2] += l;
168 else if (!strcmp(fn, "userrec.c"))
169 use[3] += l;
170 else if (!strcmp(fn, "net.c"))
171 use[4] += l;
172 else if (!strcmp(fn, "dccutil.c"))
173 use[5] += l;
174 else if (!strcmp(fn, "botnet.c"))
175 use[6] += l;
176 else if (!strcmp(fn, "tcl.c"))
177 use[7] += l;
178 else if (!strcmp(fn, "tclhash.c"))
179 use[8] += l;
180 else if (!strcmp(fn, "tclmisc.c"))
181 use[9] += l;
182 else if (!strcmp(fn, "modules.c"))
183 use[10] += l;
184 else if (!strcmp(fn, "tcldcc.c"))
185 use[11] += l;
186 else if (!strcmp(fn, "dns.c"))
187 use[12] += l;
188 #ifdef TLS
189 else if (!strcmp(fn, "tls.c"))
190 use[13] += l;
191 #endif
192 else if (p) {
193 for (me = module_list; me; me = me->next)
194 if (!strcmp(fn, me->name))
195 me->mem_work += l;
196 } else
197 dprintf(idx, "Not logging file %s!\n", fn);
198 }
199
200 for (i = 0; i < MAX_MEM; i++) {
201 switch (i) {
202 case 0:
203 strcpy(fn, "language.c");
204 break;
205 case 1:
206 strcpy(fn, "chanprog.c");
207 break;
208 case 2:
209 strcpy(fn, "misc.c");
210 break;
211 case 3:
212 strcpy(fn, "userrec.c");
213 break;
214 case 4:
215 strcpy(fn, "net.c");
216 break;
217 case 5:
218 strcpy(fn, "dccutil.c");
219 break;
220 case 6:
221 strcpy(fn, "botnet.c");
222 break;
223 case 7:
224 strcpy(fn, "tcl.c");
225 break;
226 case 8:
227 strcpy(fn, "tclhash.c");
228 break;
229 case 9:
230 strcpy(fn, "tclmisc.c");
231 break;
232 case 10:
233 strcpy(fn, "modules.c");
234 break;
235 case 11:
236 strcpy(fn, "tcldcc.c");
237 break;
238 case 12:
239 strcpy(fn, "dns.c");
240 break;
241 #ifdef TLS
242 case 13:
243 strcpy(fn, "tls.c");
244 break;
245 #endif
246 }
247
248 if (use[i] == exp[i])
249 dprintf(idx, "File '%-10s' accounted for %lu/%lu (ok)\n", fn, exp[i],
250 use[i]);
251 else {
252 dprintf(idx, "File '%-10s' accounted for %lu/%lu (debug follows:)\n",
253 fn, exp[i], use[i]);
254 strcpy(sofar, " ");
255 for (j = 0; j < lastused; j++) {
256 if ((p = strchr(memtbl[j].file, ':')))
257 *p = 0;
258 if (!egg_strcasecmp(memtbl[j].file, fn)) {
259 if (p)
260 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04d) ",
261 p + 1, memtbl[j].line, memtbl[j].size);
262 else
263 sprintf(&sofar[strlen(sofar)], "%-4d:(%04d) ",
264 memtbl[j].line, memtbl[j].size);
265
266 if (strlen(sofar) > 60) {
267 sofar[strlen(sofar) - 1] = 0;
268 dprintf(idx, "%s\n", sofar);
269 strcpy(sofar, " ");
270 }
271 }
272 if (p)
273 *p = ':';
274 }
275 if (sofar[0]) {
276 sofar[strlen(sofar) - 1] = 0;
277 dprintf(idx, "%s\n", sofar);
278 }
279 }
280 }
281
282 for (me = module_list; me; me = me->next) {
283 Function *f = me->funcs;
284 int expt = 0;
285
286 if ((f != NULL) && (f[MODCALL_EXPMEM] != NULL))
287 expt = f[MODCALL_EXPMEM] ();
288 if (me->mem_work == expt)
289 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (ok)\n", me->name,
290 expt, me->mem_work);
291 else {
292 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (debug follows:)\n",
293 me->name, expt, me->mem_work);
294 strcpy(sofar, " ");
295 for (j = 0; j < lastused; j++) {
296 strcpy(fn, memtbl[j].file);
297 if ((p = strchr(fn, ':')) != NULL) {
298 *p = 0;
299 if (!egg_strcasecmp(fn, me->name)) {
300 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04X) ", p + 1,
301 memtbl[j].line, memtbl[j].size);
302 if (strlen(sofar) > 60) {
303 sofar[strlen(sofar) - 1] = 0;
304 dprintf(idx, "%s\n", sofar);
305 strcpy(sofar, " ");
306 }
307 *p = ':';
308 }
309 }
310 }
311 if (sofar[0]) {
312 sofar[strlen(sofar) - 1] = 0;
313 dprintf(idx, "%s\n", sofar);
314 }
315 }
316 }
317
318 dprintf(idx, "--- End of debug memory list.\n");
319 #else
320 dprintf(idx, "Compiled without extensive memory debugging (sorry).\n");
321 #endif
322 tell_netdebug(idx);
323 }
324
325 void *n_malloc(int size, const char *file, int line)
326 {
327 void *x;
328
329 #ifdef DEBUG_MEM
330 int i = 0;
331 char *p;
332 #endif
333
334 x = (void *) malloc(size);
335 if (x == NULL) {
336 putlog(LOG_MISC, "*", "*** FAILED MALLOC %s (%d) (%d): %s", file, line,
337 size, strerror(errno));
338 fatal("Memory allocation failed", 0);
339 }
340 #ifdef DEBUG_MEM
341 if (lastused == MEMTBLSIZE) {
342 putlog(LOG_MISC, "*", "*** MEMORY TABLE FULL: %s (%d)", file, line);
343 fatal("Memory table full", 0);
344 }
345 i = lastused;
346 memtbl[i].ptr = x;
347 memtbl[i].line = line;
348 memtbl[i].size = size;
349 p = strrchr(file, '/');
350 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
351 memtbl[i].file[19] = 0;
352 memused += size;
353 lastused++;
354 #endif
355 return x;
356 }
357
358 void *n_realloc(void *ptr, int size, const char *file, int line)
359 {
360 void *x;
361 int i = 0;
362
363 #ifdef DEBUG_MEM
364 char *p;
365 #endif
366
367 /* ptr == NULL is valid. Avoiding duplicate code further down */
368 if (!ptr)
369 return n_malloc(size, file, line);
370
371 x = (void *) realloc(ptr, size);
372 if (x == NULL && size > 0) {
373 i = i;
374 putlog(LOG_MISC, "*", "*** FAILED REALLOC %s (%d)", file, line);
375 return NULL;
376 }
377 #ifdef DEBUG_MEM
378 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
379 if (i == lastused) {
380 putlog(LOG_MISC, "*", "*** ATTEMPTING TO REALLOC NON-MALLOC'D PTR: %s (%d)",
381 file, line);
382 return NULL;
383 }
384 memused -= memtbl[i].size;
385 memtbl[i].ptr = x;
386 memtbl[i].line = line;
387 memtbl[i].size = size;
388 p = strrchr(file, '/');
389 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
390 memtbl[i].file[19] = 0;
391 memused += size;
392 #endif
393 return x;
394 }
395
396 void n_free(void *ptr, const char *file, int line)
397 {
398 int i = 0;
399
400 if (ptr == NULL) {
401 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NULL PTR: %s (%d)",
402 file, line);
403 i = i;
404 return;
405 }
406 #ifdef DEBUG_MEM
407 /* Give tcl builtins an escape mechanism */
408 if (line) {
409 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
410 if (i == lastused) {
411 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NON-MALLOC'D PTR: %s (%d)",
412 file, line);
413 return;
414 }
415 memused -= memtbl[i].size;
416 lastused--;
417 /* We don't want any holes, so if this wasn't the last entry, swap it. */
418 if (i != lastused) {
419 memtbl[i].ptr = memtbl[lastused].ptr;
420 memtbl[i].size = memtbl[lastused].size;
421 memtbl[i].line = memtbl[lastused].line;
422 strcpy(memtbl[i].file, memtbl[lastused].file);
423 }
424 }
425 #endif
426 free(ptr);
427 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23