/[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.1.1.1 - (hide annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU
CVS Tags: arelease
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

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     if (!c)
160     {
161     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
162     return NULL;
163     }
164    
165     ctag = conn_get_clienttag(c);
166    
167     /* 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); */
168     /* if this is the first ad, randomly choose an init sequence (if there is one) */
169     if (prev_id==0 && adbannerlist_init_count>0)
170     return adbannerlist_get_random(adbannerlist_init_head,ctag);
171     // return list_get_data_by_pos(adbannerlist_init_head,((unsigned int)rand())%adbannerlist_init_count);
172     /* eventlog(eventlog_level_debug,__FUNCTION__,"not sending init banner"); */
173    
174     /* find the previous adbanner */
175     if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_init_head,prev_id,ctag)))
176     next_id = prev->next;
177     else if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_start_head,prev_id,ctag)))
178     next_id = prev->next;
179     else if ((prev = adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,prev_id,ctag)))
180     next_id = prev->next;
181     else
182     next_id = 0;
183    
184     /* return its next ad if there is one */
185     if (next_id)
186     {
187     t_adbanner * curr;
188    
189     if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_init_head,next_id,ctag)))
190     return curr;
191     if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_start_head,next_id,ctag)))
192     return curr;
193     if ((curr = adbannerlist_find_adbanner_by_id(adbannerlist_norm_head,next_id,ctag)))
194     return curr;
195    
196     eventlog(eventlog_level_error,__FUNCTION__,"could not locate next requested ad with id 0x%06x",next_id);
197     }
198     /* eventlog(eventlog_level_debug,__FUNCTION__,"not sending next banner"); */
199    
200     /* otherwise choose another starting point randomly */
201     if (adbannerlist_start_count>0)
202     return adbannerlist_get_random(adbannerlist_start_head,ctag);
203    
204     /* eventlog(eventlog_level_debug,__FUNCTION__,"not sending start banner... nothing to return"); */
205     return NULL; /* nothing else to return */
206     }
207    
208    
209     extern unsigned int adbanner_get_id(t_adbanner const * ad)
210     {
211     if (!ad)
212     {
213     eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
214     return 0;
215     }
216     return ad->id;
217     }
218    
219    
220     extern unsigned int adbanner_get_extensiontag(t_adbanner const * ad)
221     {
222     if (!ad)
223     {
224     eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
225     return 0;
226     }
227     return ad->extensiontag;
228     }
229    
230    
231     extern char const * adbanner_get_filename(t_adbanner const * ad)
232     {
233     if (!ad)
234     {
235     eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
236     return NULL;
237     }
238     return ad->filename;
239     }
240    
241    
242     extern char const * adbanner_get_link(t_adbanner const * ad)
243     {
244     if (!ad)
245     {
246     eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
247     return NULL;
248     }
249     return ad->link;
250     }
251    
252    
253     extern t_clienttag adbanner_get_client(t_adbanner const * ad)
254     {
255     if (!ad)
256     {
257     eventlog(eventlog_level_error,__FUNCTION__,"got NULL ad");
258     return CLIENTTAG_UNKNOWN_UINT;
259     }
260     return ad->client;
261     }
262    
263    
264     static t_adbanner * adbannerlist_find_adbanner_by_id(t_list const * head, unsigned int id, t_clienttag clienttag)
265     {
266     t_elem const * curr;
267     t_adbanner * temp;
268    
269     if (!head)
270     return NULL;
271    
272     LIST_TRAVERSE_CONST(head,curr)
273     {
274     if (!(temp = elem_get_data(curr)))
275     {
276     eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in list");
277     continue;
278     }
279     if (temp->id==id && (temp->client == 0 || temp->client == clienttag))
280     return temp;
281     }
282    
283     return NULL;
284     }
285    
286     /*
287     * Dizzy: maybe we should use a temporary list, right now we parse the list for
288     * 2 times. It should not matter for servers without more than 20 ads :)
289     */
290     static t_adbanner * adbannerlist_get_random(t_list const * head, t_clienttag client)
291     {
292     t_elem const * curr;
293     t_adbanner * temp;
294     unsigned int ccount, ocount, pos;
295    
296     if (!head)
297     return NULL;
298    
299     ocount = 0; ccount = 0;
300     LIST_TRAVERSE_CONST(head,curr)
301     {
302     if (!(temp = elem_get_data(curr)))
303     {
304     eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in list");
305     continue;
306     }
307     if ((adbanner_get_client(temp) == client))
308     ccount++;
309     else if ((adbanner_get_client(temp) == 0))
310     ocount++;
311     }
312     if (ccount) {
313     pos = ((unsigned int)rand())%ccount;
314     ccount = 0;
315     LIST_TRAVERSE_CONST(head,curr)
316     {
317     if (!(temp = elem_get_data(curr))) continue;
318     if ((adbanner_get_client(temp) == client))
319     if (ccount++ == pos) return temp;
320     }
321     eventlog(eventlog_level_error,__FUNCTION__,"found client ads but couldnt locate random chosed!");
322     } else if (ocount) {
323     pos = ((unsigned int)rand())%ocount;
324     ocount = 0;
325     LIST_TRAVERSE_CONST(head,curr)
326     {
327     if (!(temp = elem_get_data(curr))) continue;
328     if ((adbanner_get_client(temp) == 0))
329     if (ocount++ == pos) return temp;
330     }
331     eventlog(eventlog_level_error,__FUNCTION__,"couldnt locate random chosed!");
332     }
333    
334     return NULL;
335     }
336    
337    
338     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)
339     {
340     t_adbanner * ad;
341     unsigned int id;
342     char * ext;
343     bn_int bntag;
344    
345     assert(head != NULL);
346     assert(count != NULL);
347     assert(filename != NULL);
348     assert(link != NULL);
349    
350     if (strlen(filename)<7)
351     {
352     eventlog(eventlog_level_error,__FUNCTION__,"got bad ad filename \"%s\"",filename);
353     return -1;
354     }
355    
356     ext = xmalloc(strlen(filename));
357    
358     if (sscanf(filename,"%*c%*c%x.%s",&id,ext)!=2)
359     {
360     eventlog(eventlog_level_error,__FUNCTION__,"got bad ad filename \"%s\"",filename);
361     xfree(ext);
362     return -1;
363     }
364    
365     if (strcasecmp(ext,"pcx")==0)
366     bn_int_tag_set(&bntag,EXTENSIONTAG_PCX);
367     else if (strcasecmp(ext,"mng")==0)
368     bn_int_tag_set(&bntag,EXTENSIONTAG_MNG);
369     else if (strcasecmp(ext,"smk")==0)
370     bn_int_tag_set(&bntag,EXTENSIONTAG_SMK);
371     else
372     {
373     eventlog(eventlog_level_error,__FUNCTION__,"unknown extension on filename \"%s\"",filename);
374     xfree(ext);
375     return -1;
376     }
377     xfree(ext);
378    
379     if (!(ad = adbanner_create(id,next_id,delay,bntag,filename,link,client)))
380     {
381     eventlog(eventlog_level_error,__FUNCTION__,"could not create ad");
382     return -1;
383     }
384    
385     list_prepend_data(head,ad);
386    
387     (*count)++;
388    
389     return 0;
390     }
391    
392    
393     extern int adbannerlist_create(char const * filename)
394     {
395     FILE * fp;
396     unsigned int line;
397     unsigned int pos;
398     unsigned int len;
399     char * buff;
400     char * name;
401     char * when;
402     char * link;
403     char * client;
404     char * temp;
405     unsigned int delay;
406     unsigned int next_id;
407    
408     if (!filename)
409     {
410     eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
411     return -1;
412     }
413    
414     adbannerlist_init_head = list_create();
415     adbannerlist_start_head = list_create();
416     adbannerlist_norm_head = list_create();
417    
418     if (!(fp = fopen(filename,"r")))
419     {
420     eventlog(eventlog_level_error,__FUNCTION__,"could not open adbanner file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
421     list_destroy(adbannerlist_norm_head);
422     list_destroy(adbannerlist_start_head);
423     list_destroy(adbannerlist_init_head);
424     adbannerlist_init_head=adbannerlist_start_head=adbannerlist_norm_head = NULL;
425     return -1;
426     }
427    
428     for (line=1; (buff = file_get_line(fp)); line++)
429     {
430     for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
431     if (buff[pos]=='\0' || buff[pos]=='#')
432     {
433     continue;
434     }
435     if ((temp = strrchr(buff,'#')))
436     {
437     unsigned int endpos;
438    
439     *temp = '\0';
440     len = strlen(buff)+1;
441     for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
442     buff[endpos+1] = '\0';
443     }
444     len = strlen(buff)+1;
445    
446     name = xmalloc(len);
447     when = xmalloc(len);
448     link = xmalloc(len);
449     client = xmalloc(len);
450    
451     if (sscanf(buff," \"%[^\"]\" %[a-z] %u \"%[^\"]\" %x \"%[^\"]\"",name,when,&delay,link,&next_id,client)!=6)
452     {
453     eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\"",line,filename);
454     xfree(client);
455     xfree(link);
456     xfree(name);
457     xfree(when);
458     continue;
459     }
460    
461     if (strcmp(when,"init")==0)
462     adbannerlist_insert(adbannerlist_init_head,&adbannerlist_init_count,name,delay,link,next_id,client);
463     else if (strcmp(when,"start")==0)
464     adbannerlist_insert(adbannerlist_start_head,&adbannerlist_start_count,name,delay,link,next_id,client);
465     else if (strcmp(when,"norm")==0)
466     adbannerlist_insert(adbannerlist_norm_head,&adbannerlist_norm_count,name,delay,link,next_id,client);
467     else
468     eventlog(eventlog_level_error,__FUNCTION__,"when field has unknown value on line %u in file \"%s\"",line,filename);
469    
470     xfree(client);
471     xfree(link);
472     xfree(name);
473     xfree(when);
474     }
475    
476     file_get_line(NULL); // clear file_get_line buffer
477     if (fclose(fp)<0)
478     eventlog(eventlog_level_error,__FUNCTION__,"could not close adbanner file \"%s\" after reading (fclose: %s)",filename,pstrerror(errno));
479     return 0;
480     }
481    
482    
483     extern int adbannerlist_destroy(void)
484     {
485     t_elem * curr;
486     t_adbanner * ad;
487    
488     if (adbannerlist_init_head)
489     {
490     LIST_TRAVERSE(adbannerlist_init_head,curr)
491     {
492     if (!(ad = elem_get_data(curr)))
493     eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in init list");
494     else
495     adbanner_destroy(ad);
496     list_remove_elem(adbannerlist_init_head,&curr);
497     }
498     list_destroy(adbannerlist_init_head);
499     adbannerlist_init_head = NULL;
500     adbannerlist_init_count = 0;
501     }
502    
503     if (adbannerlist_start_head)
504     {
505     LIST_TRAVERSE(adbannerlist_start_head,curr)
506     {
507     if (!(ad = elem_get_data(curr)))
508     eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in start list");
509     else
510     adbanner_destroy(ad);
511     list_remove_elem(adbannerlist_start_head,&curr);
512     }
513     list_destroy(adbannerlist_start_head);
514     adbannerlist_start_head = NULL;
515     adbannerlist_start_count = 0;
516     }
517    
518     if (adbannerlist_norm_head)
519     {
520     LIST_TRAVERSE(adbannerlist_norm_head,curr)
521     {
522     if (!(ad = elem_get_data(curr)))
523     eventlog(eventlog_level_error,__FUNCTION__,"found NULL adbanner in norm list");
524     else
525     adbanner_destroy(ad);
526     list_remove_elem(adbannerlist_norm_head,&curr);
527     }
528     list_destroy(adbannerlist_norm_head);
529     adbannerlist_norm_head = NULL;
530     adbannerlist_norm_count = 0;
531     }
532    
533     return 0;
534     }

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