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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide 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 sysadm 1.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 sysadm 1.2
160 sysadm 1.1 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 sysadm 1.2 /* 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 sysadm 1.1 /* 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 sysadm 1.2 eventlog(eventlog_level_debug,__FUNCTION__,"not sending init banner");
189 sysadm 1.1
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 sysadm 1.2 eventlog(eventlog_level_debug,__FUNCTION__,"not sending start banner... nothing to return");
221 sysadm 1.1 return NULL; /* nothing else to return */
222 sysadm 1.2
223     }
224 sysadm 1.1 }
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 sysadm 1.2
554    

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