/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/adbanner.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/adbanner.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Sat Jun 10 16:20:06 2006 UTC (19 years, 9 months ago) by sysadm
Branch: MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, HEAD
Changes since 1.1: +23 -3 lines
Content type: text/x-csrc
Antibot

1 /*
2 * Copyright (C) 1999 Ross Combs (rocombs@cs.nmsu.edu)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #define ADBANNER_INTERNAL_ACCESS
19 #include "common/setup_before.h"
20 #include <stdio.h>
21 #ifdef HAVE_STDDEF_H
22 # include <stddef.h>
23 #else
24 # ifndef NULL
25 # define NULL ((void *)0)
26 # endif
27 #endif
28 #ifdef STDC_HEADERS
29 # include <stdlib.h>
30 #else
31 # ifdef HAVE_MALLOC_H
32 # include <malloc.h>
33 # endif
34 #endif
35 #ifdef HAVE_STRING_H
36 # include <string.h>
37 #else
38 # ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 # endif
41 #endif
42 #ifdef HAVE_ASSERT_H
43 # include <assert.h>
44 #endif
45 #include "compat/strrchr.h"
46 #include "compat/strdup.h"
47 #include "compat/strcasecmp.h"
48 #include <errno.h>
49 #include "compat/strerror.h"
50 #include "common/tag.h"
51 #include "common/bn_type.h"
52 #include "common/eventlog.h"
53 #include "common/list.h"
54 #include "common/util.h"
55 #include "common/xalloc.h"
56 #include "connection.h"
57 #include "adbanner.h"
58 #include "common/setup_after.h"
59
60
61 static t_list * adbannerlist_init_head=NULL;
62 static t_list * adbannerlist_start_head=NULL;
63 static t_list * adbannerlist_norm_head=NULL;
64 static unsigned int adbannerlist_init_count=0;
65 static unsigned int adbannerlist_start_count=0;
66 static unsigned int adbannerlist_norm_count=0;
67
68
69 static t_adbanner * adbanner_create(unsigned int id, unsigned int next_id, unsigned int delay, bn_int tag, char const * filename, char const * link, char const * client);
70 static int adbanner_destroy(t_adbanner const * ad);
71 static int adbannerlist_insert(t_list * head, unsigned int * count, char const * filename, unsigned int delay, char const * link, unsigned int next_id, char const * client);
72 static t_adbanner * adbannerlist_find_adbanner_by_id(t_list const * head, unsigned int id, t_clienttag clienttag);
73 static t_adbanner * adbannerlist_get_random(t_list const * head, t_clienttag client);
74
75
76 static t_adbanner * adbanner_create(unsigned int id, unsigned int next_id, unsigned int delay, bn_int tag, char const * filename, char const * link, char const * client)
77 {
78 t_adbanner * ad;
79
80 if (!filename)
81 {
82 eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
83 return NULL;
84 }
85 if (!link)
86 {
87 eventlog(eventlog_level_error,__FUNCTION__,"got NULL link");
88 return NULL;
89 }
90 if (!client)
91 {
92 eventlog(eventlog_level_error,__FUNCTION__,"got NULL client");
93 return NULL;
94 }
95
96 ad = xmalloc(sizeof(t_adbanner));
97
98 ad->id = id;
99 ad->extensiontag = bn_int_get(tag);
100 ad->delay = delay;
101 ad->next = next_id;
102 ad->filename = xstrdup(filename);
103 ad->link = xstrdup(link);
104
105 if (strcasecmp(client,"NULL")==0)
106 ad->client = 0;
107 else
108 ad->client = clienttag_str_to_uint(client);
109
110 /* I'm aware that this statement looks stupid */
111 if (ad->client && (!tag_check_client(ad->client)))
112 {
113 eventlog(eventlog_level_error,__FUNCTION__,"banner with invalid clienttag \"%s\"encountered",client);
114 xfree((void *)ad->link);
115 xfree((void *)ad->filename); /* avoid warning */
116 xfree(ad);
117 return NULL;
118 }
119
120
121 eventlog(eventlog_level_debug,__FUNCTION__,"created ad id=0x%08x filename=\"%s\" extensiontag=0x%04x delay=%u link=\"%s\" next_id=0x%08x client=\"%s\"",ad->id,ad->filename,ad->extensiontag,ad->delay,ad->link,ad->next,ad->client?client:"");
122 return ad;
123 }
124
125
126 static int adbanner_destroy(t_adbanner const * ad)
127 {
128 if (!ad)
129 {
130 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
131 return -1;
132 }
133
134 xfree((void *)ad->filename); /* avoid warning */
135 xfree((void *)ad->link); /* avoid warning */
136 xfree((void *)ad); /* avoid warning */
137
138 return 0;
139 }
140
141 extern t_adbanner * adbanner_get(t_connection const * c, unsigned int id)
142 {
143 t_adbanner * banner;
144 t_clienttag ctag = conn_get_clienttag(c);
145
146 banner = adbannerlist_find_adbanner_by_id(adbannerlist_init_head,id,ctag);
147 if (!banner) banner = adbannerlist_find_adbanner_by_id(adbannerlist_start_head,id,ctag);
148 if (!banner) banner = adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,id,ctag);
149
150 return banner;
151 }
152
153 extern t_adbanner * adbanner_pick(t_connection const * c, unsigned int prev_id)
154 {
155 t_adbanner const * prev;
156 unsigned int next_id;
157 t_clienttag ctag;
158
159
160 if (!c)
161 {
162 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
163 return NULL;
164 }
165
166 ctag = conn_get_clienttag(c);
167
168 /* sowater, 2005-04-14 */
169 if(ctag=clienttag_str_to_uint("D2XP")) {
170 char checknum;
171 unsigned int id=0;
172 t_connection const * t=c;
173 t_adbanner * adbanner_checknum;
174 checknum=conn_get_checknum(t);
175 id|=checknum;
176 eventlog(eventlog_level_debug,__FUNCTION__,"got checknum: %c, banner id: %u",checknum,id);
177 if(adbanner_checknum=adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,id,ctag))
178 return adbanner_checknum;
179 eventlog(eventlog_level_debug,__FUNCTION__,"not sending checknum banner");
180 return NULL;
181 }else{
182
183 eventlog(eventlog_level_debug,__FUNCTION__,"prev_id=%u init_count=%u start_count=%u norm_count=%u",prev_id,adbannerlist_init_count,adbannerlist_start_count,adbannerlist_norm_count);
184 /* if this is the first ad, randomly choose an init sequence (if there is one) */
185 if (prev_id==0 && adbannerlist_init_count>0)
186 return adbannerlist_get_random(adbannerlist_init_head,ctag);
187 // return list_get_data_by_pos(adbannerlist_init_head,((unsigned int)rand())%adbannerlist_init_count);
188 eventlog(eventlog_level_debug,__FUNCTION__,"not sending init banner");
189
190 /* find the previous adbanner */
191 if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_init_head,prev_id,ctag)))
192 next_id = prev->next;
193 else if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_start_head,prev_id,ctag)))
194 next_id = prev->next;
195 else if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,prev_id,ctag)))
196 next_id = prev->next;
197 else
198 next_id = 0;
199
200 /* return its next ad if there is one */
201 if (next_id)
202 {
203 t_adbanner * curr;
204
205 if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_init_head,next_id,ctag)))
206 return curr;
207 if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_start_head,next_id,ctag)))
208 return curr;
209 if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,next_id,ctag)))
210 return curr;
211
212 eventlog(eventlog_level_error,__FUNCTION__,"could not locate next requested ad with id 0x%06x",next_id);
213 }
214 /* eventlog(eventlog_level_debug,__FUNCTION__,"not sending next banner"); */
215
216 /* otherwise choose another starting point randomly */
217 if (adbannerlist_start_count>0)
218 return adbannerlist_get_random(adbannerlist_start_head,ctag);
219
220 eventlog(eventlog_level_debug,__FUNCTION__,"not sending start banner... nothing to return");
221 return NULL; /* nothing else to return */
222
223 }
224 }
225
226
227 extern unsigned int adbanner_get_id(t_adbanner const * ad)
228 {
229 if (!ad)
230 {
231 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
232 return 0;
233 }
234 return ad->id;
235 }
236
237
238 extern unsigned int adbanner_get_extensiontag(t_adbanner const * ad)
239 {
240 if (!ad)
241 {
242 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
243 return 0;
244 }
245 return ad->extensiontag;
246 }
247
248
249 extern char const * adbanner_get_filename(t_adbanner const * ad)
250 {
251 if (!ad)
252 {
253 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
254 return NULL;
255 }
256 return ad->filename;
257 }
258
259
260 extern char const * adbanner_get_link(t_adbanner const * ad)
261 {
262 if (!ad)
263 {
264 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
265 return NULL;
266 }
267 return ad->link;
268 }
269
270
271 extern t_clienttag adbanner_get_client(t_adbanner const * ad)
272 {
273 if (!ad)
274 {
275 eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
276 return CLIENTTAG_UNKNOWN_UINT;
277 }
278 return ad->client;
279 }
280
281
282 static t_adbanner * adbannerlist_find_adbanner_by_id(t_list const * head, unsigned int id, t_clienttag clienttag)
283 {
284 t_elem const * curr;
285 t_adbanner * temp;
286
287 if (!head)
288 return NULL;
289
290 LIST_TRAVERSE_CONST(head,curr)
291 {
292 if (!(temp = elem_get_data(curr)))
293 {
294 eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in list");
295 continue;
296 }
297 if (temp->id==id && (temp->client == 0 || temp->client == clienttag))
298 return temp;
299 }
300
301 return NULL;
302 }
303
304 /*
305 * Dizzy: maybe we should use a temporary list, right now we parse the list for
306 * 2 times. It should not matter for servers without more than 20 ads :)
307 */
308 static t_adbanner * adbannerlist_get_random(t_list const * head, t_clienttag client)
309 {
310 t_elem const * curr;
311 t_adbanner * temp;
312 unsigned int ccount, ocount, pos;
313
314 if (!head)
315 return NULL;
316
317 ocount = 0; ccount = 0;
318 LIST_TRAVERSE_CONST(head,curr)
319 {
320 if (!(temp = elem_get_data(curr)))
321 {
322 eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in list");
323 continue;
324 }
325 if ((adbanner_get_client(temp) == client))
326 ccount++;
327 else if ((adbanner_get_client(temp) == 0))
328 ocount++;
329 }
330 if (ccount) {
331 pos = ((unsigned int)rand())%ccount;
332 ccount = 0;
333 LIST_TRAVERSE_CONST(head,curr)
334 {
335 if (!(temp = elem_get_data(curr))) continue;
336 if ((adbanner_get_client(temp) == client))
337 if (ccount++ == pos) return temp;
338 }
339 eventlog(eventlog_level_error,__FUNCTION__,"found client ads but couldnt locate random chosed!");
340 } else if (ocount) {
341 pos = ((unsigned int)rand())%ocount;
342 ocount = 0;
343 LIST_TRAVERSE_CONST(head,curr)
344 {
345 if (!(temp = elem_get_data(curr))) continue;
346 if ((adbanner_get_client(temp) == 0))
347 if (ocount++ == pos) return temp;
348 }
349 eventlog(eventlog_level_error,__FUNCTION__,"couldnt locate random chosed!");
350 }
351
352 return NULL;
353 }
354
355
356 static int adbannerlist_insert(t_list * head, unsigned int * count, char const * filename, unsigned int delay, char const * link, unsigned int next_id, char const * client)
357 {
358 t_adbanner * ad;
359 unsigned int id;
360 char * ext;
361 bn_int bntag;
362
363 assert(head != NULL);
364 assert(count != NULL);
365 assert(filename != NULL);
366 assert(link != NULL);
367
368 if (strlen(filename)<7)
369 {
370 eventlog(eventlog_level_error,__FUNCTION__,"got bad ad filename \"%s\"",filename);
371 return -1;
372 }
373
374 ext = xmalloc(strlen(filename));
375
376 if (sscanf(filename,"%*c%*c%x.%s",&id,ext)!=2)
377 {
378 eventlog(eventlog_level_error,__FUNCTION__,"got bad ad filename \"%s\"",filename);
379 xfree(ext);
380 return -1;
381 }
382
383 if (strcasecmp(ext,"pcx")==0)
384 bn_int_tag_set(&bntag,EXTENSIONTAG_PCX);
385 else if (strcasecmp(ext,"mng")==0)
386 bn_int_tag_set(&bntag,EXTENSIONTAG_MNG);
387 else if (strcasecmp(ext,"smk")==0)
388 bn_int_tag_set(&bntag,EXTENSIONTAG_SMK);
389 else
390 {
391 eventlog(eventlog_level_error,__FUNCTION__,"unknown extension on filename \"%s\"",filename);
392 xfree(ext);
393 return -1;
394 }
395 xfree(ext);
396
397 if (!(ad = adbanner_create(id,next_id,delay,bntag,filename,link,client)))
398 {
399 eventlog(eventlog_level_error,__FUNCTION__,"could not create ad");
400 return -1;
401 }
402
403 list_prepend_data(head,ad);
404
405 (*count)++;
406
407 return 0;
408 }
409
410
411 extern int adbannerlist_create(char const * filename)
412 {
413 FILE * fp;
414 unsigned int line;
415 unsigned int pos;
416 unsigned int len;
417 char * buff;
418 char * name;
419 char * when;
420 char * link;
421 char * client;
422 char * temp;
423 unsigned int delay;
424 unsigned int next_id;
425
426 if (!filename)
427 {
428 eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
429 return -1;
430 }
431
432 adbannerlist_init_head = list_create();
433 adbannerlist_start_head = list_create();
434 adbannerlist_norm_head = list_create();
435
436 if (!(fp = fopen(filename,"r")))
437 {
438 eventlog(eventlog_level_error,__FUNCTION__,"could not open adbanner file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
439 list_destroy(adbannerlist_norm_head);
440 list_destroy(adbannerlist_start_head);
441 list_destroy(adbannerlist_init_head);
442 adbannerlist_init_head=adbannerlist_start_head=adbannerlist_norm_head = NULL;
443 return -1;
444 }
445
446 for (line=1; (buff = file_get_line(fp)); line++)
447 {
448 for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
449 if (buff[pos]=='\0' || buff[pos]=='#')
450 {
451 continue;
452 }
453 if ((temp = strrchr(buff,'#')))
454 {
455 unsigned int endpos;
456
457 *temp = '\0';
458 len = strlen(buff)+1;
459 for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
460 buff[endpos+1] = '\0';
461 }
462 len = strlen(buff)+1;
463
464 name = xmalloc(len);
465 when = xmalloc(len);
466 link = xmalloc(len);
467 client = xmalloc(len);
468
469 if (sscanf(buff," \"%[^\"]\" %[a-z] %u \"%[^\"]\" %x \"%[^\"]\"",name,when,&delay,link,&next_id,client)!=6)
470 {
471 eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\"",line,filename);
472 xfree(client);
473 xfree(link);
474 xfree(name);
475 xfree(when);
476 continue;
477 }
478
479 if (strcmp(when,"init")==0)
480 adbannerlist_insert(adbannerlist_init_head,&adbannerlist_init_count,name,delay,link,next_id,client);
481 else if (strcmp(when,"start")==0)
482 adbannerlist_insert(adbannerlist_start_head,&adbannerlist_start_count,name,delay,link,next_id,client);
483 else if (strcmp(when,"norm")==0)
484 adbannerlist_insert(adbannerlist_norm_head,&adbannerlist_norm_count,name,delay,link,next_id,client);
485 else
486 eventlog(eventlog_level_error,__FUNCTION__,"when field has unknown value on line %u in file \"%s\"",line,filename);
487
488 xfree(client);
489 xfree(link);
490 xfree(name);
491 xfree(when);
492 }
493
494 file_get_line(NULL); // clear file_get_line buffer
495 if (fclose(fp)<0)
496 eventlog(eventlog_level_error,__FUNCTION__,"could not close adbanner file \"%s\" after reading (fclose: %s)",filename,pstrerror(errno));
497 return 0;
498 }
499
500
501 extern int adbannerlist_destroy(void)
502 {
503 t_elem * curr;
504 t_adbanner * ad;
505
506 if (adbannerlist_init_head)
507 {
508 LIST_TRAVERSE(adbannerlist_init_head,curr)
509 {
510 if (!(ad = elem_get_data(curr)))
511 eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in init list");
512 else
513 adbanner_destroy(ad);
514 list_remove_elem(adbannerlist_init_head,&curr);
515 }
516 list_destroy(adbannerlist_init_head);
517 adbannerlist_init_head = NULL;
518 adbannerlist_init_count = 0;
519 }
520
521 if (adbannerlist_start_head)
522 {
523 LIST_TRAVERSE(adbannerlist_start_head,curr)
524 {
525 if (!(ad = elem_get_data(curr)))
526 eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in start list");
527 else
528 adbanner_destroy(ad);
529 list_remove_elem(adbannerlist_start_head,&curr);
530 }
531 list_destroy(adbannerlist_start_head);
532 adbannerlist_start_head = NULL;
533 adbannerlist_start_count = 0;
534 }
535
536 if (adbannerlist_norm_head)
537 {
538 LIST_TRAVERSE(adbannerlist_norm_head,curr)
539 {
540 if (!(ad = elem_get_data(curr)))
541 eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in norm list");
542 else
543 adbanner_destroy(ad);
544 list_remove_elem(adbannerlist_norm_head,&curr);
545 }
546 list_destroy(adbannerlist_norm_head);
547 adbannerlist_norm_head = NULL;
548 adbannerlist_norm_count = 0;
549 }
550
551 return 0;
552 }
553
554

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1