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

Annotation of /pvpgn-1.7.4/src/bnetd/connection.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) 1998 Mark Baysinger (mbaysing@ucsd.edu)
3     * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
4     * Copyright (C) 2000,2001 Marco Ziech (mmz@gmx.net)
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20     #define CONNECTION_INTERNAL_ACCESS
21     #include "common/setup_before.h"
22     #include <stdio.h>
23     // amadeo
24     #ifdef WIN32_GUI
25     #include <win32/winmain.h>
26     #endif
27     #ifdef HAVE_STDDEF_H
28     # include <stddef.h>
29     #else
30     # ifndef NULL
31     # define NULL ((void *)0)
32     # endif
33     #endif
34     #ifdef STDC_HEADERS
35     # include <stdlib.h>
36     #else
37     # ifdef HAVE_MALLOC_H
38     # include <malloc.h>
39     # endif
40     #endif
41     #include "compat/strtoul.h"
42     #ifdef HAVE_STRING_H
43     # include <string.h>
44     #else
45     # ifdef HAVE_STRINGS_H
46     # include <strings.h>
47     # endif
48     #endif
49     #ifdef HAVE_ASSERT_H
50     # include <assert.h>
51     #endif
52     #include "compat/strchr.h"
53     #include "compat/strrchr.h"
54     #include "compat/strdup.h"
55     #include "compat/strcasecmp.h"
56     #include "compat/strncasecmp.h"
57     #include <errno.h>
58     #include "compat/strerror.h"
59     #ifdef HAVE_UNISTD_H
60     # include <unistd.h>
61     #endif
62     #ifdef TIME_WITH_SYS_TIME
63     # include <sys/time.h>
64     # include <time.h>
65     #else
66     # ifdef HAVE_SYS_TIME_H
67     # include <sys/time.h>
68     # else
69     # include <time.h>
70     # endif
71     #endif
72     #include "compat/difftime.h"
73     #ifdef HAVE_SYS_TYPES_H
74     # include <sys/types.h>
75     #endif
76     #ifdef HAVE_SYS_SOCKET_H
77     # include <sys/socket.h>
78     #endif
79     #include "compat/socket.h"
80     #include "compat/psock.h"
81     #include "common/eventlog.h"
82     #include "common/addr.h"
83     #include "account.h"
84     #include "account_wrap.h"
85     #include "realm.h"
86     #include "channel.h"
87     #include "game.h"
88     #include "common/queue.h"
89     #include "tick.h"
90     #include "common/packet.h"
91     #include "common/tag.h"
92     #include "common/bn_type.h"
93     #include "message.h"
94     #include "common/version.h"
95     #include "prefs.h"
96     #include "common/util.h"
97     #include "common/list.h"
98     #include "watch.h"
99     #include "timer.h"
100     #include "irc.h"
101     #include "ipban.h"
102     #include "game_conv.h"
103     #include "udptest_send.h"
104     #include "character.h"
105     #include "versioncheck.h"
106     #include "common/bnet_protocol.h"
107     #include "common/field_sizes.h"
108     #include "anongame.h"
109     #include "clan.h"
110     #include "connection.h"
111     #include "topic.h"
112     #include "server.h"
113     #include "handle_d2cs.h"
114     #include "command_groups.h"
115     #include "common/rcm.h"
116     #include "common/fdwatch.h"
117     #include "common/elist.h"
118     #include "common/xalloc.h"
119     #include "common/setup_after.h"
120    
121     /* types and data structures used for the connlist array */
122     typedef struct {
123     t_connection *c;
124     t_elist freelist;
125     } t_conn_entry;
126    
127     t_conn_entry *connarray = NULL;
128     t_elist arrayflist;
129    
130     static int totalcount=0;
131     static t_list * conn_head=NULL;
132     static t_list * conn_dead=NULL;
133    
134     static void conn_send_welcome(t_connection * c);
135     static void conn_send_issue(t_connection * c);
136    
137     static int connarray_create(void);
138     static void connarray_destroy(void);
139     static t_connection *connarray_get_conn(unsigned index);
140     static unsigned connarray_add_conn(t_connection *c);
141     static void connarray_del_conn(unsigned index);
142    
143     static void conn_send_welcome(t_connection * c)
144     {
145     char const * filename;
146     FILE * fp;
147    
148     if (!c)
149     {
150     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
151     return;
152     }
153    
154     if (c->protocol.cflags & conn_flags_welcomed)
155     return;
156     if (conn_get_class(c)==conn_class_irc)
157     {
158     c->protocol.cflags|= conn_flags_welcomed;
159     return;
160     }
161     if ((filename = prefs_get_motdfile()))
162     {
163     if ((fp = fopen(filename,"r")))
164     {
165     message_send_file(c,fp);
166     if (fclose(fp)<0)
167     { eventlog(eventlog_level_error,__FUNCTION__,"could not close MOTD file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno)); }
168     }
169     else
170     { eventlog(eventlog_level_error,__FUNCTION__,"could not open MOTD file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); }
171     }
172     c->protocol.cflags|= conn_flags_welcomed;
173     }
174    
175    
176     static void conn_send_issue(t_connection * c)
177     {
178     char const * filename;
179     FILE * fp;
180    
181     if (!c)
182     {
183     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
184     return;
185     }
186    
187     if ((filename = prefs_get_issuefile()))
188     if ((fp = fopen(filename,"r")))
189     {
190     message_send_file(c,fp);
191     if (fclose(fp)<0)
192     eventlog(eventlog_level_error,__FUNCTION__,"could not close issue file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno));
193     }
194     else
195     eventlog(eventlog_level_error,__FUNCTION__,"could not open issue file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
196     else
197     eventlog(eventlog_level_debug,__FUNCTION__,"no issue file");
198     }
199    
200     // [zap-zero] 20020629
201     extern void conn_shutdown(t_connection * c, time_t now, t_timer_data foo)
202     {
203     if (!c)
204     {
205     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
206     return;
207     }
208    
209     if (now==(time_t)0) /* zero means user logged out before expiration */
210     {
211     eventlog(eventlog_level_trace,__FUNCTION__,"[%d] connection allready closed",conn_get_socket(c));
212     return;
213     }
214    
215     eventlog(eventlog_level_trace,__FUNCTION__,"[%d] closing connection",conn_get_socket(c));
216    
217     conn_set_state(c, conn_state_destroy);
218     }
219    
220     extern void conn_test_latency(t_connection * c, time_t now, t_timer_data delta)
221     {
222     t_packet * packet;
223    
224     if (!c)
225     {
226     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
227     return;
228     }
229    
230    
231     if (now==(time_t)0) /* zero means user logged out before expiration */
232     return;
233    
234     if (conn_get_state(c)==conn_state_destroy) // [zap-zero] 20020910
235     return; // state_destroy: do nothing
236    
237    
238     if (conn_get_class(c)==conn_class_irc) {
239     /* We should start pinging the client after we received the first line ... */
240     /* NOTE: RFC2812 only suggests that PINGs are being sent
241     * if no other activity is detected. However it explecitly
242     * allows PINGs to be sent if there is activity on this
243     * connection. In other words we just don't care :)
244     */
245     if (conn_get_ircping(c)!=0) {
246     eventlog(eventlog_level_warn,__FUNCTION__,"[%d] ping timeout (closing connection)",conn_get_socket(c));
247     conn_set_latency(c,0);
248     conn_set_state(c,conn_state_destroy);
249     }
250     irc_send_ping(c);
251     } else if(conn_get_class(c)==conn_class_w3route) {
252     if(!(packet = packet_create(packet_class_w3route))) {
253     eventlog(eventlog_level_error,__FUNCTION__,"[%d] packet_create failed",conn_get_socket(c));
254     } else {
255     packet_set_size(packet,sizeof(t_server_w3route_echoreq));
256     packet_set_type(packet,SERVER_W3ROUTE_ECHOREQ);
257     bn_int_set(&packet->u.server_w3route_echoreq.ticks,get_ticks());
258     conn_push_outqueue(c, packet);
259     packet_del_ref(packet);
260     }
261     } else {
262    
263     /* FIXME: I think real Battle.net sends these even before login */
264     if (!conn_get_game(c))
265     {
266     if ((packet = packet_create(packet_class_bnet)))
267     {
268     packet_set_size(packet,sizeof(t_server_echoreq));
269     packet_set_type(packet,SERVER_ECHOREQ);
270     bn_int_set(&packet->u.server_echoreq.ticks,get_ticks());
271     conn_push_outqueue(c,packet);
272     packet_del_ref(packet);
273     }
274     else
275     { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); }
276     }
277     }
278    
279     if (timerlist_add_timer(c,now+(time_t)delta.n,conn_test_latency,delta)<0)
280     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
281     }
282    
283    
284     static void conn_send_nullmsg(t_connection * c, time_t now, t_timer_data delta)
285     {
286     if (!c)
287     {
288     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
289     return;
290     }
291    
292     if (now==(time_t)0) /* zero means user logged out before expiration */
293     return;
294    
295     message_send_text(c,message_type_null,c,NULL);
296    
297     if (timerlist_add_timer(c,now+(time_t)delta.n,conn_send_nullmsg,delta)<0)
298     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
299     }
300    
301    
302     extern char const * conn_class_get_str(t_conn_class class)
303     {
304     switch (class)
305     {
306     case conn_class_init:
307     return "init";
308     case conn_class_bnet:
309     return "bnet";
310     case conn_class_file:
311     return "file";
312     case conn_class_bot:
313     return "bot";
314     case conn_class_d2cs_bnetd:
315     return "d2cs_bnetd";
316     case conn_class_telnet:
317     return "telnet";
318     case conn_class_irc:
319     return "irc";
320     case conn_class_none:
321     return "none";
322     case conn_class_w3route:
323     return "w3route";
324     default:
325     return "UNKNOWN";
326     }
327     }
328    
329    
330     extern char const * conn_state_get_str(t_conn_state state)
331     {
332     switch (state)
333     {
334     case conn_state_empty:
335     return "empty";
336     case conn_state_initial:
337     return "initial";
338     case conn_state_connected:
339     return "connected";
340     case conn_state_bot_username:
341     return "bot_username";
342     case conn_state_bot_password:
343     return "bot_password";
344     case conn_state_loggedin:
345     return "loggedin";
346     case conn_state_destroy:
347     return "destroy";
348     case conn_state_untrusted:
349     return "untrusted";
350     case conn_state_pending_raw:
351     return "pending_raw";
352     default:
353     return "UNKNOWN";
354     }
355     }
356    
357     extern int conn_set_realm_cb(void *data, void *newref);
358    
359     extern t_connection * conn_create(int tsock, int usock, unsigned int real_local_addr, unsigned short real_local_port, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port)
360     {
361     t_connection * temp;
362    
363    
364     if (tsock<0)
365     {
366     eventlog(eventlog_level_error,__FUNCTION__,"got bad TCP socket %d",tsock);
367     return NULL;
368     }
369     if (usock<-1) /* -1 is allowed for some connection classes like bot, irc, and telnet */
370     {
371     eventlog(eventlog_level_error,__FUNCTION__,"got bad UDP socket %d",usock);
372     return NULL;
373     }
374    
375     temp = xmalloc(sizeof(t_connection));
376     temp->socket.tcp_sock = tsock;
377     temp->socket.tcp_addr = addr;
378     temp->socket.tcp_port = port;
379     temp->socket.udp_sock = usock;
380     temp->socket.udp_addr = addr; /* same for now but client can request it to be different */
381     temp->socket.local_addr = local_addr;
382     temp->socket.local_port = local_port;
383     temp->socket.real_local_addr = real_local_addr;
384     temp->socket.real_local_port = real_local_port;
385     temp->socket.udp_port = port;
386     temp->socket.fdw_idx = -1;
387     temp->protocol.class = conn_class_init;
388     temp->protocol.state = conn_state_initial;
389     temp->protocol.sessionkey = ((unsigned int)rand())^((unsigned int)now+(unsigned int)real_local_port);
390     temp->protocol.sessionnum = connarray_add_conn(temp);
391     temp->protocol.secret = ((unsigned int)rand())^(totalcount+((unsigned int)now));
392     temp->protocol.flags = MF_PLUG;
393     temp->protocol.latency = 0;
394     temp->protocol.chat.dnd = NULL;
395     temp->protocol.chat.away = NULL;
396     temp->protocol.chat.ignore_list = NULL;
397     temp->protocol.chat.ignore_count = 0;
398     temp->protocol.chat.quota.totcount = 0;
399     temp->protocol.chat.quota.list = list_create();
400     temp->protocol.client.versionid = 0;
401     temp->protocol.client.gameversion = 0;
402     temp->protocol.client.checksum = 0;
403     temp->protocol.client.archtag = 0;
404     temp->protocol.client.clienttag = 0;
405     temp->protocol.client.clientver = NULL;
406     temp->protocol.client.gamelang = 0;
407     temp->protocol.client.country = NULL;
408     temp->protocol.client.tzbias = 0;
409     temp->protocol.client.host = NULL;
410     temp->protocol.client.user = NULL;
411     temp->protocol.client.clientexe = NULL;
412     temp->protocol.client.owner = NULL;
413     temp->protocol.client.cdkey = NULL;
414     temp->protocol.client.versioncheck = NULL;
415     temp->protocol.account = NULL;
416     temp->protocol.chat.channel = NULL;
417     temp->protocol.chat.last_message = now;
418     temp->protocol.chat.lastsender = NULL;
419     temp->protocol.chat.irc.ircline = NULL;
420     temp->protocol.chat.irc.ircping = 0;
421     temp->protocol.chat.irc.ircpass = NULL;
422     temp->protocol.chat.tmpOP_channel = NULL;
423     temp->protocol.chat.tmpVOICE_channel = NULL;
424     temp->protocol.game = NULL;
425     temp->protocol.queues.outqueue = NULL;
426     temp->protocol.queues.outsize = 0;
427     temp->protocol.queues.outsizep = 0;
428     temp->protocol.queues.inqueue = NULL;
429     temp->protocol.queues.insize = 0;
430     temp->protocol.loggeduser = NULL;
431     temp->protocol.d2.realm = NULL;
432     rcm_regref_init(&temp->protocol.d2.realm_regref,&conn_set_realm_cb,temp);
433     temp->protocol.d2.character = NULL;
434     temp->protocol.d2.realminfo = NULL;
435     temp->protocol.d2.charname = NULL;
436     temp->protocol.w3.w3_playerinfo = NULL;
437     temp->protocol.w3.routeconn = NULL;
438     temp->protocol.w3.anongame = NULL;
439     temp->protocol.w3.anongame_search_starttime = 0;
440     temp->protocol.bound = NULL;
441     elist_init(&temp->protocol.timers);
442     temp->protocol.cr_time = now;
443     temp->protocol.passfail_count = 0;
444    
445    
446     temp->protocol.cflags = 0;
447    
448     list_prepend_data(conn_head,temp);
449    
450     eventlog(eventlog_level_info,__FUNCTION__,"[%d][%d] sessionkey=0x%08x sessionnum=0x%08x",temp->socket.tcp_sock,temp->socket.udp_sock,temp->protocol.sessionkey,temp->protocol.sessionnum);
451    
452     return temp;
453     }
454    
455    
456     extern t_anongame * conn_create_anongame(t_connection *c)
457     {
458     t_anongame * temp;
459     int i;
460    
461     if(c->protocol.w3.anongame) {
462     eventlog(eventlog_level_error,__FUNCTION__,"anongame already allocated");
463     return c->protocol.w3.anongame;
464     }
465    
466     temp = xmalloc(sizeof(t_anongame));
467     temp->count = 0;
468     temp->id = 0;
469     temp->tid = 0;
470    
471     for (i=0; i < ANONGAME_MAX_GAMECOUNT/2; i++)
472     temp->tc[i] = NULL;
473    
474     temp->race = 0;
475     temp->playernum = 0;
476     temp->handle = 0;
477     temp->addr = 0;
478     temp->loaded = 0;
479     temp->joined = 0;
480     temp->map_prefs = 0xffffffff;
481     temp->type = 0;
482     temp->gametype = 0;
483     temp->queue = 0;
484     temp->info = NULL;
485    
486     c->protocol.w3.anongame = temp;
487    
488     return temp;
489     }
490    
491     extern t_anongame * conn_get_anongame(t_connection *c)
492     {
493     if(!c) {
494     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
495     return NULL;
496     }
497     return c->protocol.w3.anongame;
498     }
499    
500     extern void conn_destroy_anongame(t_connection *c)
501     {
502     t_anongame * a;
503    
504     if (!c)
505     {
506     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
507     return;
508     }
509    
510     if (!(a = c->protocol.w3.anongame))
511     {
512     eventlog(eventlog_level_error,__FUNCTION__,"NULL anongame");
513     return;
514     }
515    
516     // delete reference to this connection
517     if(a->info) {
518     a->info->player[a->playernum-1] = NULL;
519     if(--(a->info->currentplayers) == 0)
520     anongameinfo_destroy(a->info);
521     }
522    
523     // [quetzal] 20020824
524     // unqueue from anongame search list,
525     // if we got AT game, unqueue entire team.
526     if (anongame_arranged(a->queue)) {
527     anongame_unqueue(a->tc[0], a->queue);
528     } else {
529     anongame_unqueue(c, a->queue);
530     }
531     xfree(c->protocol.w3.anongame);
532     c->protocol.w3.anongame = NULL;
533     }
534    
535     extern void conn_destroy(t_connection * c, t_elem ** elem, int conn_or_dead_list)
536     {
537     char const * classstr;
538     t_elem * curr;
539    
540    
541     if (c == NULL) {
542     eventlog(eventlog_level_error, "conn_destroy", "got NULL connection");
543     return;
544     }
545    
546     classstr = conn_class_get_str(c->protocol.class);
547    
548     if (list_remove_data(conn_head,c,(conn_or_dead_list)?&curr:elem)<0)
549     {
550     eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
551     return;
552     }
553    
554     if (c->protocol.class==conn_class_d2cs_bnetd)
555     {
556     t_realm * realm;
557    
558     realm=conn_get_realm(c);
559     if (realm)
560     realm_deactive(realm);
561     else
562     {
563     eventlog(eventlog_level_error,__FUNCTION__,"could not find realm for d2cs connection");
564     }
565     }
566     else if (c->protocol.class == conn_class_w3route && c->protocol.w3.routeconn && c->protocol.w3.routeconn->protocol.w3.anongame)
567     {
568     anongame_stats(c);
569     conn_destroy_anongame(c->protocol.w3.routeconn); // [zap-zero] destroy anongame too when game connection is invalid
570     }
571    
572     if (c->protocol.d2.realm) {
573     realm_add_player_number(c->protocol.d2.realm,-1);
574     realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
575     }
576    
577    
578     /* free the memory with user quota */
579     {
580     t_qline * qline;
581    
582     LIST_TRAVERSE(c->protocol.chat.quota.list,curr)
583     {
584     qline = elem_get_data(curr);
585     xfree(qline);
586     list_remove_elem(c->protocol.chat.quota.list,&curr);
587     }
588     list_destroy(c->protocol.chat.quota.list);
589     }
590    
591     /* if this user in a channel, notify everyone that the user has left */
592     if (c->protocol.chat.channel)
593     channel_del_connection(c->protocol.chat.channel,c);
594    
595     if ((c->protocol.game) && (c->protocol.account))
596     {
597     if (game_get_status(c->protocol.game)==game_status_started)
598     {
599     game_set_self_report(c->protocol.game,c->protocol.account,game_result_disconnect);
600     game_set_report(c->protocol.game,c->protocol.account,"disconnect","disconnect");
601     }
602     }
603    
604     conn_set_game(c,NULL,NULL,NULL,game_type_none,0);
605     c->protocol.state = conn_state_empty;
606    
607     watchlist_del_all_events(c);
608     timerlist_del_all_timers(c);
609    
610     clanmember_set_offline(c);
611    
612     if(c->protocol.account)
613     watchlist_notify_event(c->protocol.account,NULL,c->protocol.client.clienttag,watch_event_logout);
614    
615     if (c->protocol.client.versioncheck)
616     versioncheck_destroy((void *)c->protocol.client.versioncheck); /* avoid warning */
617    
618     if (c->protocol.chat.lastsender)
619     xfree((void *)c->protocol.chat.lastsender); /* avoid warning */
620    
621     if (c->protocol.chat.away)
622     xfree((void *)c->protocol.chat.away); /* avoid warning */
623     if (c->protocol.chat.dnd)
624     xfree((void *)c->protocol.chat.dnd); /* avoid warning */
625     if (c->protocol.chat.tmpOP_channel)
626     xfree((void *)c->protocol.chat.tmpOP_channel); /* avoid warning */
627     if (c->protocol.chat.tmpVOICE_channel)
628     xfree((void *)c->protocol.chat.tmpVOICE_channel); /* avoid warning */
629    
630     if (c->protocol.client.clientver)
631     xfree((void *)c->protocol.client.clientver); /* avoid warning */
632     if (c->protocol.client.country)
633     xfree((void *)c->protocol.client.country); /* avoid warning */
634     if (c->protocol.client.host)
635     xfree((void *)c->protocol.client.host); /* avoid warning */
636     if (c->protocol.client.user)
637     xfree((void *)c->protocol.client.user); /* avoid warning */
638     if (c->protocol.client.clientexe)
639     xfree((void *)c->protocol.client.clientexe); /* avoid warning */
640     if (c->protocol.client.owner)
641     xfree((void *)c->protocol.client.owner); /* avoid warning */
642     if (c->protocol.client.cdkey)
643     xfree((void *)c->protocol.client.cdkey); /* avoid warning */
644     if (c->protocol.d2.realminfo)
645     xfree((void *)c->protocol.d2.realminfo); /* avoid warning */
646     if (c->protocol.d2.charname)
647     xfree((void *)c->protocol.d2.charname); /* avoid warning */
648     if (c->protocol.chat.irc.ircline)
649     xfree((void *)c->protocol.chat.irc.ircline); /* avoid warning */
650     if (c->protocol.chat.irc.ircpass)
651     xfree((void *)c->protocol.chat.irc.ircpass); /* avoid warning */
652    
653     /* ADDED BY UNDYING SOULZZ 4/8/02 */
654     if (c->protocol.w3.w3_playerinfo)
655     xfree((void *)c->protocol.w3.w3_playerinfo); /* avoid warning */
656    
657     if (c->protocol.bound)
658     c->protocol.bound->protocol.bound = NULL;
659    
660     if (c->protocol.chat.ignore_count>0)
661     {
662     if (!c->protocol.chat.ignore_list)
663     { eventlog(eventlog_level_error,__FUNCTION__,"found NULL ignore_list with ignore_count=%u",c->protocol.chat.ignore_count); }
664     else
665     { xfree(c->protocol.chat.ignore_list); }
666     }
667    
668     if (c->protocol.account)
669     {
670     eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" logged out",c->socket.tcp_sock,conn_get_loggeduser(c));
671     //amadeo
672     #ifdef WIN32_GUI
673     guiOnUpdateUserList();
674     #endif
675     if (prefs_get_sync_on_logoff()) {
676     if (account_save(conn_get_account(c),FS_FORCE) < 0)
677     eventlog(eventlog_level_error,__FUNCTION__,"cannot sync account (sync_on_logoff)");
678     }
679    
680     if (account_get_conn(c->protocol.account)==c) /* make sure you don't set this when allready on new conn (relogin with same account) */
681     account_set_conn(c->protocol.account,NULL);
682     c->protocol.account = NULL; /* the account code will free the memory later */
683     }
684    
685     /* logged user is no longer only for logged in users */
686     if (c->protocol.loggeduser) xfree((void*)c->protocol.loggeduser);
687    
688     /* make sure the connection is closed */
689     if (c->socket.tcp_sock!=-1) { /* -1 means that the socket was already closed by conn_close() */
690     fdwatch_del_fd(c->socket.fdw_idx);
691     psock_shutdown(c->socket.tcp_sock,PSOCK_SHUT_RDWR);
692     psock_close(c->socket.tcp_sock);
693     }
694     /* clear out the packet queues */
695     if (c->protocol.queues.inqueue) packet_del_ref(c->protocol.queues.inqueue);
696     queue_clear(&c->protocol.queues.outqueue);
697    
698     // [zap-zero] 20020601
699     if (c->protocol.w3.routeconn) {
700     c->protocol.w3.routeconn->protocol.w3.routeconn = NULL;
701     if(c->protocol.w3.routeconn->protocol.class == conn_class_w3route)
702     conn_set_state(c->protocol.w3.routeconn, conn_state_destroy);
703     }
704    
705     if(c->protocol.w3.anongame)
706     conn_destroy_anongame(c);
707    
708     /* delete the conn from the dead list if its there, we dont check for error
709     * because connections may be destroyed without first setting state to destroy */
710     if (conn_dead) list_remove_data(conn_dead, c, (conn_or_dead_list)?elem:&curr);
711     connarray_del_conn(c->protocol.sessionnum);
712    
713     eventlog(eventlog_level_info,__FUNCTION__,"[%d] closed %s connection",c->socket.tcp_sock,classstr);
714    
715     xfree(c);
716     }
717    
718    
719     extern int conn_match(t_connection const * c, char const * username)
720     {
721     if (!c)
722     {
723     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
724     return -1;
725     }
726     if (!username)
727     {
728     eventlog(eventlog_level_error,__FUNCTION__,"got NULL username");
729     return -1;
730     }
731    
732     if (!c->protocol.account)
733     return 0;
734    
735     return account_match(c->protocol.account,username);
736     }
737    
738    
739     extern t_conn_class conn_get_class(t_connection const * c)
740     {
741     if (!c)
742     {
743     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
744     return conn_class_none;
745     }
746    
747     return c->protocol.class;
748     }
749    
750    
751     extern void conn_set_class(t_connection * c, t_conn_class class)
752     {
753     t_timer_data data;
754     unsigned long delta;
755     t_conn_class oldclass;
756    
757     if (!c)
758     {
759     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
760     return;
761     }
762    
763     if (c->protocol.class==class)
764     return;
765    
766     oldclass = c->protocol.class;
767     c->protocol.class = class;
768    
769     switch(class) {
770     case conn_class_bnet:
771     if (prefs_get_udptest_port()!=0)
772     conn_set_game_port(c,(unsigned short)prefs_get_udptest_port());
773     udptest_send(c);
774    
775     /* remove any init timers */
776     if (oldclass == conn_class_init) timerlist_del_all_timers(c);
777     delta = prefs_get_latency();
778     data.n = delta;
779     if (timerlist_add_timer(c,now+(time_t)delta,conn_test_latency,data)<0)
780     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
781    
782     eventlog(eventlog_level_debug,__FUNCTION__,"added latency check timer");
783     break;
784    
785     case conn_class_w3route:
786     delta = prefs_get_latency();
787     data.n = delta;
788     if (timerlist_add_timer(c,now+(time_t)delta,conn_test_latency,data)<0)
789     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
790     break;
791    
792     case conn_class_bot:
793     case conn_class_telnet:
794     {
795     t_packet * rpacket;
796     if (class==conn_class_bot) {
797     if ((delta = prefs_get_nullmsg())>0) {
798     data.n = delta;
799     if (timerlist_add_timer(c,now+(time_t)delta,conn_send_nullmsg,data)<0)
800     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
801     }
802     }
803    
804     /* remove any init timers */
805     if (oldclass == conn_class_init) timerlist_del_all_timers(c);
806     conn_send_issue(c);
807    
808     if (!(rpacket = packet_create(packet_class_raw)))
809     eventlog(eventlog_level_error,__FUNCTION__,"could not create rpacket");
810     else {
811     packet_append_ntstring(rpacket,"Username: ");
812     conn_push_outqueue(c,rpacket);
813     packet_del_ref(rpacket);
814     }
815    
816     break;
817     }
818    
819     default:
820     /* remove any init timers */
821     if (oldclass == conn_class_init)
822     timerlist_del_all_timers(c);
823     break;
824     }
825    
826     }
827    
828    
829     extern t_conn_state conn_get_state(t_connection const * c)
830     {
831     if (!c)
832     {
833     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
834     return conn_state_empty;
835     }
836    
837     return c->protocol.state;
838     }
839    
840    
841     extern void conn_set_state(t_connection * c, t_conn_state state)
842     {
843     t_elem * elem;
844    
845     if (!c)
846     {
847     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
848     return;
849     }
850    
851     /* special case for destroying connections, add them to conn_dead list */
852     if (state == conn_state_destroy && c->protocol.state != conn_state_destroy) {
853     if (!conn_dead)
854     conn_dead = list_create();
855     list_append_data(conn_dead, c);
856     }
857     else if (state != conn_state_destroy && c->protocol.state == conn_state_destroy)
858     if (list_remove_data(conn_dead, c, &elem)) {
859     eventlog(eventlog_level_error, __FUNCTION__, "could not remove dead connection");
860     return;
861     }
862    
863     c->protocol.state = state;
864     }
865    
866     extern unsigned int conn_get_sessionkey(t_connection const * c)
867     {
868     if (!c)
869     {
870     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
871     return 0;
872     }
873    
874     return c->protocol.sessionkey;
875     }
876    
877    
878     extern unsigned int conn_get_sessionnum(t_connection const * c)
879     {
880     if (!c)
881     {
882     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
883     return 0;
884     }
885    
886     return c->protocol.sessionnum;
887     }
888    
889    
890     extern unsigned int conn_get_secret(t_connection const * c)
891     {
892     if (!c)
893     {
894     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
895     return 0;
896     }
897    
898     return c->protocol.secret;
899     }
900    
901    
902     extern unsigned int conn_get_addr(t_connection const * c)
903     {
904     if (!c)
905     {
906     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
907     return 0;
908     }
909    
910     return c->socket.tcp_addr;
911     }
912    
913    
914     extern unsigned short conn_get_port(t_connection const * c)
915     {
916     if (!c)
917     {
918     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
919     return 0;
920     }
921    
922     return c->socket.tcp_port;
923     }
924    
925    
926     extern unsigned int conn_get_local_addr(t_connection const * c)
927     {
928     if (!c)
929     {
930     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
931     return 0;
932     }
933    
934     return c->socket.local_addr;
935     }
936    
937    
938     extern unsigned short conn_get_local_port(t_connection const * c)
939     {
940     if (!c)
941     {
942     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
943     return 0;
944     }
945    
946     return c->socket.local_port;
947     }
948    
949    
950     extern unsigned int conn_get_real_local_addr(t_connection const * c)
951     {
952     if (!c)
953     {
954     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
955     return 0;
956     }
957    
958     return c->socket.real_local_addr;
959     }
960    
961    
962     extern unsigned short conn_get_real_local_port(t_connection const * c)
963     {
964     if (!c)
965     {
966     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
967     return 0;
968     }
969    
970     return c->socket.real_local_port;
971     }
972    
973    
974     extern unsigned int conn_get_game_addr(t_connection const * c)
975     {
976     if (!c)
977     {
978     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
979     return 0;
980     }
981    
982     return c->socket.udp_addr;
983     }
984    
985    
986     extern int conn_set_game_addr(t_connection * c, unsigned int game_addr)
987     {
988     if (!c)
989     {
990     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
991     return -1;
992     }
993    
994     c->socket.udp_addr = game_addr;
995     return 0;
996     }
997    
998    
999     extern unsigned short conn_get_game_port(t_connection const * c)
1000     {
1001     if (!c)
1002     {
1003     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1004     return 0;
1005     }
1006    
1007     return c->socket.udp_port;
1008     }
1009    
1010    
1011     extern int conn_set_game_port(t_connection * c, unsigned short game_port)
1012     {
1013     if (!c)
1014     {
1015     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1016     return -1;
1017     }
1018    
1019     c->socket.udp_port = game_port;
1020     return 0;
1021     }
1022    
1023    
1024     extern void conn_set_host(t_connection * c, char const * host)
1025     {
1026     if (!c)
1027     {
1028     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1029     return;
1030     }
1031     if (!host)
1032     {
1033     eventlog(eventlog_level_error,__FUNCTION__,"got NULL host");
1034     return;
1035     }
1036    
1037     if (c->protocol.client.host)
1038     xfree((void *)c->protocol.client.host); /* avoid warning */
1039     c->protocol.client.host = xstrdup(host);
1040     }
1041    
1042    
1043     extern void conn_set_user(t_connection * c, char const * user)
1044     {
1045     if (!c)
1046     {
1047     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1048     return;
1049     }
1050     if (!user)
1051     {
1052     eventlog(eventlog_level_error,__FUNCTION__,"got NULL user");
1053     return;
1054     }
1055    
1056     if (c->protocol.client.user)
1057     xfree((void *)c->protocol.client.user); /* avoid warning */
1058     c->protocol.client.user = xstrdup(user);
1059     }
1060    
1061    
1062     extern void conn_set_owner(t_connection * c, char const * owner)
1063     {
1064     if (!c)
1065     {
1066     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1067     return;
1068     }
1069     if (!owner)
1070     {
1071     eventlog(eventlog_level_error,__FUNCTION__,"got NULL owner");
1072     return;
1073     }
1074    
1075     if (c->protocol.client.owner)
1076     xfree((void *)c->protocol.client.owner); /* avoid warning */
1077     c->protocol.client.owner = xstrdup(owner);
1078     }
1079    
1080     extern const char * conn_get_user(t_connection const * c)
1081     {
1082     if (!c) {
1083     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1084     return NULL;
1085     }
1086     return c->protocol.client.user;
1087     }
1088    
1089     extern const char * conn_get_owner(t_connection const * c)
1090     {
1091     if (!c) {
1092     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1093     return NULL;
1094     }
1095     return c->protocol.client.owner;
1096     }
1097    
1098     extern void conn_set_cdkey(t_connection * c, char const * cdkey)
1099     {
1100     if (!c)
1101     {
1102     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1103     return;
1104     }
1105     if (!cdkey)
1106     {
1107     eventlog(eventlog_level_error,__FUNCTION__,"got NULL cdkey");
1108     return;
1109     }
1110    
1111     if (c->protocol.client.cdkey)
1112     xfree((void *)c->protocol.client.cdkey); /* avoid warning */
1113     c->protocol.client.cdkey = xstrdup(cdkey);
1114     }
1115    
1116    
1117     extern char const * conn_get_clientexe(t_connection const * c)
1118     {
1119     if (!c)
1120     {
1121     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1122     return NULL;
1123     }
1124    
1125     if (!c->protocol.client.clientexe)
1126     return "";
1127     return c->protocol.client.clientexe;
1128     }
1129    
1130    
1131     extern void conn_set_clientexe(t_connection * c, char const * clientexe)
1132     {
1133     char const * temp;
1134    
1135     if (!c)
1136     {
1137     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1138     return;
1139     }
1140     if (!clientexe)
1141     {
1142     eventlog(eventlog_level_error,__FUNCTION__,"got NULL clientexe");
1143     return;
1144     }
1145    
1146     temp = xstrdup(clientexe);
1147     if (c->protocol.client.clientexe)
1148     xfree((void *)c->protocol.client.clientexe); /* avoid warning */
1149     c->protocol.client.clientexe = temp;
1150     }
1151    
1152    
1153     extern char const * conn_get_clientver(t_connection const * c)
1154     {
1155     if (!c)
1156     {
1157     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1158     return NULL;
1159     }
1160    
1161     if (!c->protocol.client.clientver)
1162     return "";
1163     return c->protocol.client.clientver;
1164     }
1165    
1166    
1167     extern void conn_set_clientver(t_connection * c, char const * clientver)
1168     {
1169     char const * temp;
1170    
1171     if (!c)
1172     {
1173     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1174     return;
1175     }
1176     if (!clientver)
1177     {
1178     eventlog(eventlog_level_error,__FUNCTION__,"got NULL clientver");
1179     return;
1180     }
1181    
1182     temp = xstrdup(clientver);
1183     if (c->protocol.client.clientver)
1184     xfree((void *)c->protocol.client.clientver); /* avoid warning */
1185     c->protocol.client.clientver = temp;
1186     }
1187    
1188    
1189     extern t_tag conn_get_archtag(t_connection const * c)
1190     {
1191     if (!c) {
1192     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1193     return 0; /* unknown */
1194     }
1195    
1196     return c->protocol.client.archtag;
1197     }
1198    
1199    
1200     extern void conn_set_archtag(t_connection * c, t_tag archtag)
1201     {
1202     char archtag_str[5];
1203    
1204     if (!c) {
1205     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1206     return;
1207     }
1208     if (!tag_check_arch(archtag)) {
1209     eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN archtag");
1210     return;
1211     }
1212     if (c->protocol.client.archtag!=archtag)
1213     eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client arch to \"%s\"",conn_get_socket(c),tag_uint_to_str(archtag_str,archtag));
1214    
1215     c->protocol.client.archtag = archtag;
1216     }
1217    
1218    
1219     extern t_tag conn_get_gamelang(t_connection const * c)
1220     {
1221     if (!c)
1222     {
1223     eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1224     return 0;
1225     }
1226    
1227     return c->protocol.client.gamelang;
1228     }
1229    
1230    
1231     extern void conn_set_gamelang(t_connection * c, t_tag gamelang)
1232     {
1233     char gamelang_str[5];
1234    
1235     if (!c) {
1236     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1237     return;
1238     }
1239     if (!gamelang)
1240     return; /* only war3 & w3xp have gamelang */
1241    
1242     if (!tag_check_gamelang(gamelang)) {
1243     eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN gamelang");
1244     return;
1245     }
1246     if (c->protocol.client.gamelang!=gamelang)
1247     eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client gamelang to \"%s\"",conn_get_socket(c),tag_uint_to_str(gamelang_str,gamelang));
1248    
1249     c->protocol.client.gamelang = gamelang;
1250     }
1251    
1252    
1253     extern t_clienttag conn_get_clienttag(t_connection const * c)
1254     {
1255     if (!c)
1256     {
1257     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1258     return CLIENTTAG_UNKNOWN_UINT;
1259     }
1260    
1261     if (!c->protocol.client.clienttag)
1262     return CLIENTTAG_UNKNOWN_UINT;
1263     return c->protocol.client.clienttag;
1264     }
1265    
1266    
1267     extern t_clienttag conn_get_fake_clienttag(t_connection const * c)
1268     {
1269     char const * clienttag;
1270     t_account * account;
1271    
1272     if (!c)
1273     {
1274     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1275     return 0; /* unknown */
1276     }
1277    
1278     account = conn_get_account(c);
1279     if (account) /* BITS remote connections don't need to have an account */
1280     if ((clienttag = account_get_strattr(account,"BNET\\fakeclienttag")))
1281     return tag_str_to_uint(clienttag);
1282     return c->protocol.client.clienttag;
1283     }
1284    
1285    
1286     extern void conn_set_clienttag(t_connection * c, t_clienttag clienttag)
1287     {
1288     char clienttag_str[5];
1289    
1290     if (!c) {
1291     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1292     return;
1293     }
1294     if (!tag_check_client(clienttag)) {
1295     eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN clienttag \"%s\"",tag_uint_to_str(clienttag_str,clienttag));
1296     return;
1297     }
1298     if (c->protocol.client.clienttag!=clienttag) {
1299     eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client type to \"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag));
1300     c->protocol.client.clienttag = clienttag;
1301     if (c->protocol.chat.channel)
1302     channel_update_userflags(c);
1303     }
1304    
1305     }
1306    
1307    
1308     extern unsigned long conn_get_gameversion(t_connection const * c)
1309     {
1310     if (!c)
1311     {
1312     eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1313     return 0;
1314     }
1315    
1316     return c->protocol.client.gameversion;
1317     }
1318    
1319    
1320     extern int conn_set_gameversion(t_connection * c, unsigned long gameversion)
1321     {
1322     if (!c)
1323     {
1324     eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1325     return -1;
1326     }
1327    
1328     c->protocol.client.gameversion = gameversion;
1329     return 0;
1330     }
1331    
1332    
1333     extern unsigned long conn_get_checksum(t_connection const * c)
1334     {
1335     if (!c)
1336     {
1337     eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1338     return 0;
1339     }
1340    
1341     return c->protocol.client.checksum;
1342     }
1343    
1344    
1345     extern int conn_set_checksum(t_connection * c, unsigned long checksum)
1346     {
1347     if (!c)
1348     {
1349     eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1350     return -1;
1351     }
1352    
1353     c->protocol.client.checksum = checksum;
1354     return 0;
1355     }
1356    
1357    
1358     extern unsigned long conn_get_versionid(t_connection const * c)
1359     {
1360     if (!c)
1361     {
1362     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1363     return 0;
1364     }
1365    
1366     return c->protocol.client.versionid;
1367     }
1368    
1369    
1370     extern int conn_set_versionid(t_connection * c, unsigned long versionid)
1371     {
1372     if (!c)
1373     {
1374     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1375     return -1;
1376     }
1377    
1378     c->protocol.client.versionid = versionid;
1379     return 0;
1380     }
1381    
1382    
1383     extern int conn_get_tzbias(t_connection const * c)
1384     {
1385     if (!c)
1386     {
1387     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1388     return 0;
1389     }
1390    
1391     return c->protocol.client.tzbias;
1392     }
1393    
1394    
1395     extern void conn_set_tzbias(t_connection * c, int tzbias)
1396     {
1397     if (!c)
1398     {
1399     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1400     return;
1401     }
1402    
1403     c->protocol.client.tzbias = tzbias;
1404     }
1405    
1406    
1407     static void conn_set_account(t_connection * c, t_account * account)
1408     {
1409     t_connection * other;
1410     char const * tname;
1411    
1412     if (!c)
1413     {
1414     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1415     return;
1416     }
1417     if (!account)
1418     {
1419     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1420     return;
1421     }
1422    
1423     if ((other = connlist_find_connection_by_accountname((tname = account_get_name(account)))))
1424     {
1425     eventlog(eventlog_level_info,__FUNCTION__,"[%d] forcing logout of previous login for \"%s\"",conn_get_socket(c),tname);
1426     conn_set_state(other, conn_state_destroy);
1427     }
1428    
1429     c->protocol.account = account;
1430     c->protocol.state = conn_state_loggedin;
1431     account_set_conn(account,c);
1432     {
1433     char const * flagstr;
1434    
1435     if ((flagstr = account_get_strattr(account,"BNET\\flags\\initial")))
1436     conn_add_flags(c,strtoul(flagstr,NULL,0));
1437     }
1438    
1439     account_set_ll_time(c->protocol.account,(unsigned int)now);
1440     account_set_ll_owner(c->protocol.account,c->protocol.client.owner);
1441     account_set_ll_clienttag(c->protocol.account,c->protocol.client.clienttag);
1442     account_set_ll_ip(c->protocol.account,addr_num_to_ip_str(c->socket.tcp_addr));
1443    
1444     if (c->protocol.client.host)
1445     {
1446     xfree((void *)c->protocol.client.host); /* avoid warning */
1447     c->protocol.client.host = NULL;
1448     }
1449     if (c->protocol.client.user)
1450     {
1451     xfree((void *)c->protocol.client.user); /* avoid warning */
1452     c->protocol.client.user = NULL;
1453     }
1454     if (c->protocol.client.clientexe)
1455     {
1456     xfree((void *)c->protocol.client.clientexe); /* avoid warning */
1457     c->protocol.client.clientexe = NULL;
1458     }
1459     if (c->protocol.client.owner)
1460     {
1461     xfree((void *)c->protocol.client.owner); /* avoid warning */
1462     c->protocol.client.owner = NULL;
1463     }
1464     if (c->protocol.client.cdkey)
1465     {
1466     xfree((void *)c->protocol.client.cdkey); /* avoid warning */
1467     c->protocol.client.cdkey = NULL;
1468     }
1469    
1470     clanmember_set_online(c);
1471    
1472     totalcount++;
1473    
1474     watchlist_notify_event(c->protocol.account,NULL,c->protocol.client.clienttag,watch_event_login);
1475    
1476     return;
1477     }
1478    
1479    
1480     extern void conn_login(t_connection *c, t_account *a, const char *loggeduser)
1481     {
1482     assert(c != NULL);
1483     assert(a != NULL);
1484     assert(loggeduser != NULL);
1485    
1486     conn_set_account(c,a);
1487     if (strcmp(conn_get_loggeduser(c),loggeduser))
1488     conn_set_loggeduser(c,loggeduser);
1489     }
1490    
1491    
1492     extern t_account * conn_get_account(t_connection const * c)
1493     {
1494     if (!c)
1495     {
1496     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1497     return NULL;
1498     }
1499    
1500     return c->protocol.account;
1501     }
1502    
1503    
1504     extern int conn_set_loggeduser(t_connection * c, char const * username)
1505     {
1506     const char * temp;
1507    
1508     assert(c != NULL);
1509     assert(username != NULL);
1510    
1511     temp = xstrdup(username);
1512     if (c->protocol.loggeduser) xfree((void*)c->protocol.loggeduser);
1513    
1514     c->protocol.loggeduser = temp;
1515    
1516     return 0;
1517     }
1518    
1519    
1520     extern char const * conn_get_loggeduser(t_connection const * c)
1521     {
1522     assert(c != NULL);
1523    
1524     if (!c->protocol.loggeduser && c->protocol.account)
1525     return account_get_name(c->protocol.account);
1526     return c->protocol.loggeduser;
1527     }
1528    
1529    
1530     extern unsigned int conn_get_flags(t_connection const * c)
1531     {
1532     if (!c)
1533     {
1534     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1535     return 0;
1536     }
1537    
1538     return c->protocol.flags;
1539     }
1540    
1541    
1542     extern int conn_set_flags(t_connection * c, unsigned int flags)
1543     {
1544     if (!c) {
1545     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1546     return -1;
1547     }
1548    
1549     if (flags!=c->protocol.flags) {
1550     c->protocol.flags = flags;
1551     if (c->protocol.chat.channel) channel_update_userflags(c);
1552     }
1553    
1554     return 0;
1555     }
1556    
1557    
1558     extern void conn_add_flags(t_connection * c, unsigned int flags)
1559     {
1560     unsigned int oldflags;
1561    
1562     if (!c)
1563     {
1564     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1565     return;
1566     }
1567     oldflags = c->protocol.flags;
1568     c->protocol.flags |= flags;
1569    
1570     if (oldflags!=c->protocol.flags && c->protocol.chat.channel)
1571     channel_update_userflags(c);
1572     }
1573    
1574    
1575     extern void conn_del_flags(t_connection * c, unsigned int flags)
1576     {
1577     unsigned int oldflags;
1578    
1579     if (!c)
1580     {
1581     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1582     return;
1583     }
1584     oldflags = c->protocol.flags;
1585     c->protocol.flags &= ~flags;
1586    
1587     if (oldflags!=c->protocol.flags && c->protocol.chat.channel)
1588     channel_update_userflags(c);
1589     }
1590    
1591    
1592     extern unsigned int conn_get_latency(t_connection const * c)
1593     {
1594     if (!c)
1595     {
1596     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1597     return 0;
1598     }
1599    
1600     return c->protocol.latency;
1601     }
1602    
1603    
1604     extern void conn_set_latency(t_connection * c, unsigned int ms)
1605     {
1606     if (!c)
1607     {
1608     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1609     return;
1610     }
1611    
1612    
1613     if (c->protocol.latency != ms)
1614     {
1615     c->protocol.latency = ms;
1616    
1617     if (c->protocol.chat.channel)
1618     channel_update_latency(c);
1619     }
1620     }
1621    
1622    
1623     extern char const * conn_get_awaystr(t_connection const * c)
1624     {
1625     if (!c)
1626     {
1627     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1628     return NULL;
1629     }
1630    
1631     return c->protocol.chat.away;
1632     }
1633    
1634    
1635     extern int conn_set_awaystr(t_connection * c, char const * away)
1636     {
1637     if (!c)
1638     {
1639     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1640     return -1;
1641     }
1642    
1643     if (c->protocol.chat.away)
1644     xfree((void *)c->protocol.chat.away); /* avoid warning */
1645     if (!away)
1646     c->protocol.chat.away = NULL;
1647     else
1648     c->protocol.chat.away = xstrdup(away);
1649    
1650     return 0;
1651     }
1652    
1653    
1654     extern char const * conn_get_dndstr(t_connection const * c)
1655     {
1656     if (!c)
1657     {
1658     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1659     return NULL;
1660     }
1661    
1662     return c->protocol.chat.dnd;
1663     }
1664    
1665    
1666     extern int conn_set_dndstr(t_connection * c, char const * dnd)
1667     {
1668     if (!c)
1669     {
1670     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1671     return -1;
1672     }
1673    
1674     if (c->protocol.chat.dnd)
1675     xfree((void *)c->protocol.chat.dnd); /* avoid warning */
1676     if (!dnd)
1677     c->protocol.chat.dnd = NULL;
1678     else
1679     c->protocol.chat.dnd = xstrdup(dnd);
1680    
1681     return 0;
1682     }
1683    
1684    
1685     extern int conn_add_ignore(t_connection * c, t_account * account)
1686     {
1687     t_account * * newlist;
1688     t_connection *dest_c;
1689    
1690     if (!c) {
1691     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1692     return -1;
1693     }
1694    
1695     if (!account) {
1696     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1697     return -1;
1698     }
1699    
1700     newlist = xrealloc(c->protocol.chat.ignore_list,sizeof(t_account const *)*(c->protocol.chat.ignore_count+1));
1701     newlist[c->protocol.chat.ignore_count++] = account;
1702     c->protocol.chat.ignore_list = newlist;
1703    
1704     dest_c = account_get_conn(account);
1705     if (dest_c) {
1706     t_message *message;
1707    
1708     message = message_create(message_type_userflags,dest_c,NULL,NULL);
1709     if (!message) return 0;
1710     message_send(message,c);
1711     message_destroy(message);
1712     }
1713    
1714     return 0;
1715     }
1716    
1717    
1718     extern int conn_del_ignore(t_connection * c, t_account const * account)
1719     {
1720     t_account * * newlist;
1721     t_account * temp;
1722     unsigned int i;
1723    
1724     if (!c)
1725     {
1726     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1727     return -1;
1728     }
1729     if (!account)
1730     {
1731     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1732     return -1;
1733     }
1734    
1735     for (i=0; i<c->protocol.chat.ignore_count; i++)
1736     if (c->protocol.chat.ignore_list[i]==account)
1737     break;
1738     if (i==c->protocol.chat.ignore_count)
1739     return -1; /* not in list */
1740    
1741     /* swap entry to be deleted with last entry */
1742     temp = c->protocol.chat.ignore_list[c->protocol.chat.ignore_count-1];
1743     c->protocol.chat.ignore_list[c->protocol.chat.ignore_count-1] = c->protocol.chat.ignore_list[i];
1744     c->protocol.chat.ignore_list[i] = temp;
1745    
1746     if (c->protocol.chat.ignore_count==1) /* some realloc()s are buggy */
1747     {
1748     xfree(c->protocol.chat.ignore_list);
1749     newlist = NULL;
1750     }
1751     else
1752     newlist = xrealloc(c->protocol.chat.ignore_list,sizeof(t_account const *)*(c->protocol.chat.ignore_count-1));
1753    
1754     c->protocol.chat.ignore_count--;
1755     c->protocol.chat.ignore_list = newlist;
1756    
1757     return 0;
1758     }
1759    
1760    
1761     extern int conn_add_watch(t_connection * c, t_account * account, t_clienttag clienttag)
1762     {
1763     if (!c)
1764     {
1765     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1766     return -1;
1767     }
1768    
1769     if (watchlist_add_events(c,account,clienttag,watch_event_login|watch_event_logout|watch_event_joingame|watch_event_leavegame)<0)
1770     return -1;
1771     return 0;
1772     }
1773    
1774    
1775     extern int conn_del_watch(t_connection * c, t_account * account, t_clienttag clienttag)
1776     {
1777     if (!c)
1778     {
1779     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1780     return -1;
1781     }
1782    
1783     if (watchlist_del_events(c,account,clienttag,watch_event_login|watch_event_logout|watch_event_joingame|watch_event_leavegame)<0)
1784     return -1;
1785     return 0;
1786     }
1787    
1788    
1789     extern int conn_check_ignoring(t_connection const * c, char const * me)
1790     {
1791     unsigned int i;
1792     t_account * temp;
1793    
1794     if (!c)
1795     {
1796     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1797     return -1;
1798     }
1799    
1800     if (!me || !(temp = accountlist_find_account(me)))
1801     return -1;
1802    
1803     if (c->protocol.chat.ignore_list)
1804     for (i=0; i<c->protocol.chat.ignore_count; i++)
1805     if (c->protocol.chat.ignore_list[i]==temp)
1806     return 1;
1807    
1808     return 0;
1809     }
1810    
1811    
1812     extern t_channel * conn_get_channel(t_connection const * c)
1813     {
1814     if (!c)
1815     {
1816     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1817     return NULL;
1818     }
1819    
1820     return c->protocol.chat.channel;
1821     }
1822    
1823    
1824     extern int conn_set_channel_var(t_connection * c, t_channel * channel)
1825     {
1826     if (!c)
1827     {
1828     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1829     return -1;
1830     }
1831     c->protocol.chat.channel = channel;
1832     return 0;
1833     }
1834    
1835    
1836     extern int conn_set_channel(t_connection * c, char const * channelname)
1837     {
1838     t_channel * channel;
1839     t_channel * oldchannel;
1840     t_account * acc;
1841     t_elem * curr;
1842     int clantag=0;
1843     t_clan * clan = NULL;
1844    
1845     if (!c)
1846     {
1847     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1848     return -1;
1849     }
1850    
1851     acc = c->protocol.account;
1852    
1853     if (!acc)
1854     {
1855     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1856     return -1;
1857     }
1858    
1859     if (channelname)
1860     {
1861     unsigned int created;
1862    
1863     oldchannel=c->protocol.chat.channel;
1864    
1865     channel = channellist_find_channel_by_name(channelname,conn_get_country(c),realm_get_name(conn_get_realm(c)));
1866    
1867     if(channel && (channel == oldchannel))
1868     return 0;
1869    
1870     if((strncasecmp(channelname, "clan ", 5)==0)&&(strlen(channelname)<10))
1871     clantag = str_to_clantag(&channelname[5]);
1872    
1873     if(clantag && ((!(clan = account_get_clan(acc))) || (clan_get_clantag(clan) != clantag)))
1874     {
1875     if (!channel)
1876     {
1877     char msgtemp[MAX_MESSAGE_LEN];
1878     sprintf(msgtemp, "Unable to join channel %s, there is no member of that clan in the channel!", channelname);
1879     message_send_text(c, message_type_error, c, msgtemp);
1880     return 0;
1881     }
1882     else
1883     {
1884     t_clan * ch_clan;
1885     if((ch_clan=clanlist_find_clan_by_clantag(clantag))&&(clan_get_channel_type(ch_clan)==1))
1886     {
1887     message_send_text(c, message_type_error, c, "This is a private clan channel, unable to join!");
1888     return 0;
1889     }
1890     }
1891     }
1892    
1893     if (c->protocol.chat.channel)
1894     {
1895     channel_del_connection(c->protocol.chat.channel, c);
1896     c->protocol.chat.channel = NULL;
1897     }
1898    
1899     if (channel)
1900     {
1901     if (channel_check_banning(channel,c))
1902     {
1903     message_send_text(c,message_type_error,c,"You are banned from that channel.");
1904     return -1;
1905     }
1906    
1907     if ((account_get_auth_admin(acc,NULL)!=1) && (account_get_auth_admin(acc,channelname)!=1) &&
1908     (account_get_auth_operator(acc,NULL)!=1) && (account_get_auth_operator(acc,channelname)!=1) &&
1909     (channel_get_max(channel) == 0))
1910     {
1911     message_send_text(c,message_type_error,c,"That channel is for Admins/Operators only.");
1912     return -1;
1913     }
1914    
1915     if ((account_get_auth_admin(acc,NULL)!=1) && (account_get_auth_admin(acc,channelname)!=1) &&
1916     (account_get_auth_operator(acc,NULL)!=1) && (account_get_auth_operator(acc,channelname)!=1) &&
1917     (channel_get_max(channel) != -1) && (channel_get_curr(channel)>=channel_get_max(channel)))
1918     {
1919     message_send_text(c,message_type_error,c,"The channel is currently full.");
1920     return -1;
1921     }
1922     }
1923    
1924     if(conn_set_joingamewhisper_ack(c,0)<0)
1925     eventlog(eventlog_level_error,__FUNCTION__,"Unable to reset conn_set_joingamewhisper_ack flag");
1926    
1927     if(conn_set_leavegamewhisper_ack(c,0)<0)
1928     eventlog(eventlog_level_error,__FUNCTION__,"Unable to reset conn_set_leavegamewhisper_ack flag");
1929    
1930     /* if you're entering a channel, make sure they didn't exit a game without telling us */
1931     if (c->protocol.game)
1932     {
1933     game_del_player(conn_get_game(c),c);
1934     c->protocol.game = NULL;
1935     }
1936    
1937     created = 0;
1938    
1939     if (!channel)
1940     {
1941     if(clantag)
1942     channel = channel_create(channelname,channelname,NULL,0,1,1,prefs_get_chanlog(), NULL, NULL, (prefs_get_maxusers_per_channel() > 0) ? prefs_get_maxusers_per_channel() : -1, 0, 1,0);
1943     else
1944     channel = channel_create(channelname,channelname,NULL,0,1,1,prefs_get_chanlog(), NULL, NULL, (prefs_get_maxusers_per_channel() > 0) ? prefs_get_maxusers_per_channel() : -1, 0, 0,0);
1945     if (!channel)
1946     {
1947     eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create channel on join \"%s\"",conn_get_socket(c),channelname);
1948     return -1;
1949     }
1950     created = 1;
1951     }
1952    
1953     c->protocol.chat.channel=channel;
1954    
1955     if (channel_add_connection(channel,c)<0)
1956     {
1957     if (created)
1958     channel_destroy(channel,&curr);
1959     c->protocol.chat.channel = NULL;
1960     return -1;
1961     }
1962    
1963     eventlog(eventlog_level_info,__FUNCTION__,"[%d] joined channel \"%s\"",conn_get_socket(c),channel_get_name(c->protocol.chat.channel));
1964     conn_send_welcome(c);
1965    
1966     if(c->protocol.chat.channel && (channel_get_flags(c->protocol.chat.channel) & channel_flags_thevoid))
1967     message_send_text(c,message_type_info,c,"This channel does not have chat privileges.");
1968     if (clantag && clan && (clan_get_clantag(clan)==clantag))
1969     {
1970     char msgtemp[MAX_MESSAGE_LEN];
1971     sprintf(msgtemp,"%s",clan_get_motd(clan));
1972     message_send_text(c,message_type_info,c,msgtemp);
1973     }
1974    
1975     if (channel_get_topic(channel_get_name(c->protocol.chat.channel)) && (conn_get_class(c)!=conn_class_irc))
1976     {
1977     char msgtemp[MAX_MESSAGE_LEN];
1978    
1979     sprintf(msgtemp,"%s topic: %s",channel_get_name(c->protocol.chat.channel),channel_get_topic(channel_get_name(c->protocol.chat.channel)));
1980     message_send_text(c,message_type_info,c,msgtemp);
1981     }
1982    
1983     if (c->protocol.chat.channel && (channel_get_flags(c->protocol.chat.channel) & channel_flags_moderated))
1984     message_send_text(c,message_type_error,c,"This channel is moderated.");
1985    
1986     if(c->protocol.chat.channel!=oldchannel)
1987     clanmember_on_change_status_by_connection(c);
1988     }
1989     else
1990     {
1991     if (c->protocol.chat.channel)
1992     {
1993     channel_del_connection(c->protocol.chat.channel,c);
1994     c->protocol.chat.channel = NULL;
1995     }
1996     }
1997    
1998     return 0;
1999     }
2000    
2001    
2002     extern t_game * conn_get_game(t_connection const * c)
2003     {
2004     if (!c)
2005     {
2006     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2007     return NULL;
2008     }
2009    
2010     return c->protocol.game;
2011     }
2012    
2013    
2014     extern int conn_set_game(t_connection * c, char const * gamename, char const * gamepass, char const * gameinfo, t_game_type type, int version)
2015     /*
2016     * If game not exists (create) version != 0 (called in handle_bnet.c, function _client_startgameX())
2017     * If game exists (join) version == 0 always (called in handle_bnet.c, function _client_joingame())
2018     * If game exists (join) gameinfo == "" (called in handle_bnet.c, function _client_joingame())
2019     * [KWS]
2020     */
2021     {
2022     if (!c) {
2023     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2024     return -1;
2025     }
2026    
2027     if (c->protocol.game) {
2028     if (gamename) {
2029     if (strcasecmp(gamename,game_get_name(c->protocol.game)))
2030     eventlog(eventlog_level_error,__FUNCTION__,"[%d] tried to join a new game \"%s\" while already in a game \"%s\"!",conn_get_socket(c),gamename,game_get_name(c->protocol.game));
2031     else return 0;
2032     }
2033     game_del_player(conn_get_game(c),c);
2034     c->protocol.game = NULL;
2035     }
2036    
2037     if (gamename) {
2038     if (!(c->protocol.game = gamelist_find_game(gamename,type))) {
2039     c->protocol.game = game_create(gamename,gamepass,gameinfo,type,version,c->protocol.client.clienttag,conn_get_gameversion(c));
2040    
2041     if (c->protocol.game && conn_get_realm(c) && conn_get_charname(c)) {
2042     game_set_realmname(c->protocol.game,realm_get_name(conn_get_realm(c)));
2043     realm_add_game_number(conn_get_realm(c),1);
2044     send_d2cs_gameinforeq(c);
2045     }
2046     }
2047    
2048     if (c->protocol.game) {
2049     if (game_add_player(conn_get_game(c),gamepass,version,c)<0) {
2050     c->protocol.game = NULL; // bad password or version #
2051     return -1;
2052     }
2053    
2054     if (game_is_ladder(c->protocol.game)) {
2055     if (c == game_get_owner(c->protocol.game))
2056     message_send_text(c,message_type_info,c,"Created ladder game");
2057     else
2058     message_send_text(c,message_type_info,c,"Joined ladder game");
2059     }
2060     }
2061     } else c->protocol.game = NULL;
2062    
2063     return 0;
2064     }
2065    
2066     extern unsigned int conn_get_tcpaddr(t_connection * c)
2067     {
2068     if (!c)
2069     {
2070     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2071     return 0;
2072     }
2073    
2074     return c->socket.tcp_addr;
2075     }
2076    
2077    
2078     extern t_packet * conn_get_in_queue(t_connection * c)
2079     {
2080     assert(c);
2081    
2082     return c->protocol.queues.inqueue;
2083     }
2084    
2085    
2086     extern void conn_put_in_queue(t_connection * c, t_packet * packet)
2087     {
2088     assert(c);
2089    
2090     c->protocol.queues.inqueue = packet;
2091     }
2092    
2093    
2094     extern unsigned int conn_get_in_size(t_connection const * c)
2095     {
2096     if (!c)
2097     {
2098     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2099     return 0;
2100     }
2101    
2102     return c->protocol.queues.insize;
2103     }
2104    
2105    
2106     extern void conn_set_in_size(t_connection * c, unsigned int size)
2107     {
2108     if (!c)
2109     {
2110     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2111     return;
2112     }
2113    
2114     c->protocol.queues.insize = size;
2115     }
2116    
2117    
2118     extern unsigned int conn_get_out_size(t_connection const * c)
2119     {
2120     if (!c)
2121     {
2122     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2123     return -1;
2124     }
2125     return c->protocol.queues.outsize;
2126     }
2127    
2128    
2129     extern void conn_set_out_size(t_connection * c, unsigned int size)
2130     {
2131     if (!c)
2132     {
2133     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2134     return;
2135     }
2136    
2137     c->protocol.queues.outsize = size;
2138     }
2139    
2140     extern int conn_push_outqueue(t_connection * c, t_packet * packet)
2141     {
2142     if (!c)
2143     {
2144     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2145     return -1;
2146     }
2147    
2148     if (!packet)
2149     {
2150     eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
2151     return -1;
2152     }
2153    
2154     queue_push_packet((t_queue * *)&c->protocol.queues.outqueue, packet);
2155     if (!c->protocol.queues.outsizep++) fdwatch_update_fd(c->socket.fdw_idx, fdwatch_type_read | fdwatch_type_write);
2156    
2157     return 0;
2158     }
2159    
2160     extern t_packet * conn_peek_outqueue(t_connection * c)
2161     {
2162     if (!c)
2163     {
2164     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2165     return NULL;
2166     }
2167    
2168     return queue_peek_packet((t_queue const * const *)&c->protocol.queues.outqueue);
2169     }
2170    
2171     extern t_packet * conn_pull_outqueue(t_connection * c)
2172     {
2173     if (!c)
2174     {
2175     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2176     return NULL;
2177     }
2178    
2179     if (c->protocol.queues.outsizep) {
2180     if (!(--c->protocol.queues.outsizep)) fdwatch_update_fd(c->socket.fdw_idx, fdwatch_type_read);
2181     return queue_pull_packet((t_queue * *)&c->protocol.queues.outqueue);
2182     }
2183    
2184     return NULL;
2185     }
2186    
2187     extern char const * conn_get_username_real(t_connection const * c,char const * fn,unsigned int ln)
2188     {
2189     char const * result;
2190    
2191     if (!c)
2192     {
2193     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection (from %s:%u)",fn,ln);
2194     return NULL;
2195     }
2196    
2197     if(!c->protocol.account)
2198     {
2199     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account (from %s:%u)",fn,ln);
2200     return NULL;
2201     }
2202     result = account_get_name(c->protocol.account);
2203     if (result == NULL)
2204     eventlog(eventlog_level_error,__FUNCTION__,"returned previous error after being called by %s:%u",fn,ln);
2205    
2206     return result;
2207     }
2208    
2209    
2210     extern char const * conn_get_chatname(t_connection const * c)
2211     {
2212     if (!c)
2213     {
2214     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2215     return NULL;
2216     }
2217    
2218     if ((c->protocol.class==conn_class_bnet) && c->protocol.bound)
2219     {
2220     if (c->protocol.d2.character)
2221     return character_get_name(c->protocol.d2.character);
2222     if (c->protocol.bound->protocol.d2.character)
2223     return character_get_name(c->protocol.bound->protocol.d2.character);
2224     eventlog(eventlog_level_error,__FUNCTION__,"[%d] got connection class %s bound to class %d without a character",conn_get_socket(c),conn_class_get_str(c->protocol.class),c->protocol.bound->protocol.class);
2225     }
2226     if (!c->protocol.account)
2227     return NULL; /* no name yet */
2228     return conn_get_loggeduser(c);
2229     }
2230    
2231    
2232     extern int conn_unget_chatname(t_connection const * c, char const * name)
2233     {
2234     if (!c)
2235     {
2236     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2237     return -1;
2238     }
2239    
2240     if ((c->protocol.class==conn_class_bnet) && c->protocol.bound)
2241     return 0;
2242     return 0;
2243     }
2244    
2245    
2246     extern char const * conn_get_chatcharname(t_connection const * c, t_connection const * dst)
2247     {
2248     char const * accname;
2249     char * chatcharname;
2250    
2251     if (!c)
2252     {
2253     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2254     return NULL;
2255     }
2256    
2257     if (!c->protocol.account)
2258     return NULL; /* no name yet */
2259    
2260     /* for D2 Users */
2261     accname = conn_get_loggeduser(c);
2262     if (!accname)
2263     return NULL;
2264    
2265     if (dst && dst->protocol.d2.charname)
2266     {
2267     const char *mychar;
2268    
2269     if (c->protocol.d2.charname) mychar = c->protocol.d2.charname;
2270     else mychar = "";
2271     chatcharname = xmalloc(strlen(accname) + 2 + strlen(mychar));
2272     sprintf(chatcharname, "%s*%s", mychar, accname);
2273     } else chatcharname = xstrdup(accname);
2274    
2275     return chatcharname;
2276     }
2277    
2278    
2279     extern int conn_unget_chatcharname(t_connection const * c, char const * name)
2280     {
2281     if (!c)
2282     {
2283     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2284     return -1;
2285     }
2286     if (!name)
2287     {
2288     eventlog(eventlog_level_error,__FUNCTION__,"got NULL name");
2289     return -1;
2290     }
2291    
2292     xfree((void *)name); /* avoid warning */
2293     return 0;
2294     }
2295    
2296    
2297     extern t_message_class conn_get_message_class(t_connection const * c, t_connection const * dst)
2298     {
2299     if (dst && dst->protocol.d2.charname) /* message to D2 user must be char*account */
2300     return message_class_charjoin;
2301    
2302     return message_class_normal;
2303     }
2304    
2305    
2306     extern unsigned int conn_get_userid(t_connection const * c)
2307     {
2308     if (!c)
2309     {
2310     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2311     return 0;
2312     }
2313    
2314     if(!c->protocol.account)
2315     {
2316     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
2317     return 0;
2318     }
2319    
2320     return account_get_uid(c->protocol.account);
2321     }
2322    
2323    
2324     extern int conn_get_socket(t_connection const * c)
2325     {
2326     if (!c)
2327     {
2328     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2329     return -1;
2330     }
2331    
2332     return c->socket.tcp_sock;
2333     }
2334    
2335    
2336     extern int conn_get_game_socket(t_connection const * c)
2337     {
2338     if (!c)
2339     {
2340     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2341     return -1;
2342     }
2343    
2344     return c->socket.udp_sock;
2345     }
2346    
2347    
2348     extern int conn_set_game_socket(t_connection * c, int usock)
2349     {
2350     if (!c)
2351     {
2352     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2353     return -1;
2354     }
2355    
2356     c->socket.udp_sock = usock;
2357     return 0;
2358     }
2359    
2360    
2361     extern char const * conn_get_playerinfo(t_connection const * c)
2362     {
2363     t_account * account;
2364     static char playerinfo[MAX_PLAYERINFO_STR];
2365     t_clienttag clienttag;
2366     char revtag[5];
2367     char clienttag_str[5];
2368    
2369     if (!c)
2370     {
2371     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2372     return NULL;
2373     }
2374     if (!(account = conn_get_account(c)))
2375     {
2376     eventlog(eventlog_level_error,__FUNCTION__,"connection has no account");
2377     return NULL;
2378     }
2379    
2380     if (!(clienttag = conn_get_fake_clienttag(c)))
2381     {
2382     eventlog(eventlog_level_error,__FUNCTION__,"connection has NULL fakeclienttag");
2383     return NULL;
2384     }
2385     tag_uint_to_str(clienttag_str,clienttag);
2386     strncpy(revtag,clienttag_str,5); revtag[4] = '\0';
2387     strreverse(revtag);
2388    
2389     if (clienttag==CLIENTTAG_BNCHATBOT_UINT)
2390     {
2391     strcpy(playerinfo,revtag); /* FIXME: what to return here? */
2392     }
2393     else if (clienttag==CLIENTTAG_STARCRAFT_UINT)
2394     {
2395     if (conn_get_versionid(c)<=0x000000c7)
2396     {
2397     sprintf(playerinfo,"%s %u %u %u %u %u",
2398     revtag,
2399     account_get_ladder_rating(account,clienttag,ladder_id_normal),
2400     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2401     account_get_normal_wins(account,clienttag),
2402     0,0);
2403     }
2404     else
2405     {
2406     sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %s",
2407     revtag,
2408     account_get_ladder_rating(account,clienttag,ladder_id_normal),
2409     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2410     account_get_normal_wins(account,clienttag),
2411     0,0,0,0,0,
2412     revtag);
2413     }
2414     }
2415     else if (clienttag==CLIENTTAG_BROODWARS_UINT)
2416     {
2417     if (conn_get_versionid(c)<=0x000000c7)
2418     {
2419     sprintf(playerinfo,"%s %u %u %u %u %u",
2420     revtag,
2421     account_get_ladder_rating(account,clienttag,ladder_id_normal),
2422     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2423     account_get_normal_wins(account,clienttag),
2424     0,0);
2425     }
2426     else
2427     {
2428     sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %s",
2429     revtag,
2430     account_get_ladder_rating(account,clienttag,ladder_id_normal),
2431     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2432     account_get_normal_wins(account,clienttag),
2433     0,0,0,0,0,
2434     revtag);
2435     }
2436     }
2437     else if (clienttag==CLIENTTAG_SHAREWARE_UINT)
2438     {
2439     sprintf(playerinfo,"%s %u %u %u %u %u",
2440     revtag,
2441     account_get_ladder_rating(account,clienttag,ladder_id_normal),
2442     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2443     account_get_normal_wins(account,clienttag),
2444     0,0);
2445     }
2446     else if (clienttag==CLIENTTAG_DIABLORTL_UINT)
2447     {
2448     sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %u",
2449     revtag,
2450     account_get_normal_level(account,clienttag),
2451     account_get_normal_class(account,clienttag),
2452     account_get_normal_diablo_kills(account,clienttag),
2453     account_get_normal_strength(account,clienttag),
2454     account_get_normal_magic(account,clienttag),
2455     account_get_normal_dexterity(account,clienttag),
2456     account_get_normal_vitality(account,clienttag),
2457     account_get_normal_gold(account,clienttag),
2458     0);
2459     }
2460     else if (clienttag==CLIENTTAG_DIABLOSHR_UINT)
2461     {
2462     sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %u",
2463     revtag,
2464     account_get_normal_level(account,clienttag),
2465     account_get_normal_class(account,clienttag),
2466     account_get_normal_diablo_kills(account,clienttag),
2467     account_get_normal_strength(account,clienttag),
2468     account_get_normal_magic(account,clienttag),
2469     account_get_normal_dexterity(account,clienttag),
2470     account_get_normal_vitality(account,clienttag),
2471     account_get_normal_gold(account,clienttag),
2472     0);
2473     }
2474     else if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
2475     {
2476     unsigned int a,b;
2477    
2478     a = account_get_ladder_rating(account,clienttag,ladder_id_normal);
2479     b = account_get_ladder_rating(account,clienttag,ladder_id_ironman);
2480    
2481     sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u",
2482     revtag,
2483     a,
2484     account_get_ladder_rank(account,clienttag,ladder_id_normal),
2485     account_get_normal_wins(account,clienttag),
2486     0,
2487     0,
2488     (a>b) ? a : b,
2489     b,
2490     account_get_ladder_rank(account,clienttag,ladder_id_ironman));
2491     }
2492     else if (clienttag==CLIENTTAG_DIABLO2DV_UINT || clienttag==CLIENTTAG_DIABLO2XP_UINT)
2493     #if 0
2494     /* FIXME: Was this the old code? Can this stuff vanish? */
2495     /* Yes, this was the pre-d2close code, however I'm not sure the new code
2496     * takes care of all the cases. */
2497     {
2498     t_character * ch;
2499    
2500     if (c->protocol.d2.character)
2501     ch = c->protocol.d2.character;
2502     else
2503     if ((c->protocol.class==conn_class_bnet) && c->protocol.bound && c->protocol.bound->protocol.d2.character)
2504     ch = c->protocol.bound->protocol.d2.character;
2505     else
2506     ch = NULL;
2507    
2508     if (ch)
2509     sprintf(playerinfo,"%s%s,%s,%s",
2510     revtag,
2511     character_get_realmname(ch),
2512     character_get_name(ch),
2513     character_get_playerinfo(ch));
2514     else
2515     strcpy(playerinfo,revtag); /* open char */
2516     }
2517     else /* FIXME: this used to return the empty string... do some formats actually use that or not? */
2518     strcpy(playerinfo,revtag); /* best guess... */
2519     }
2520     #endif
2521     {
2522     /* This sets portrait of character */
2523     if (!conn_get_realm(c) || !conn_get_realminfo(c))
2524     {
2525     tag_uint_to_str(playerinfo,clienttag);
2526     //bn_int_tag_set((bn_int *)playerinfo,clienttag); /* FIXME: Is this attempting to reverse the tag? This isn't really correct... why not use the revtag stuff like above or below? */
2527     //playerinfo[strlen(clienttag)]='\0';
2528     }
2529     else
2530     {
2531     strcpy(playerinfo,conn_get_realminfo(c));
2532     }
2533     }
2534     else
2535     strcpy(playerinfo,revtag); /* open char */
2536    
2537     return playerinfo;
2538     }
2539    
2540    
2541     extern int conn_set_playerinfo(t_connection const * c, char const * playerinfo)
2542     {
2543     t_clienttag clienttag;
2544     char clienttag_str[5];
2545    
2546     if (!c)
2547     {
2548     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2549     return -1;
2550     }
2551     if (!playerinfo)
2552     {
2553     eventlog(eventlog_level_error,__FUNCTION__,"got NULL playerinfo");
2554     return -1;
2555     }
2556     clienttag = c->protocol.client.clienttag;
2557    
2558     if (clienttag==CLIENTTAG_DIABLORTL_UINT)
2559     {
2560     unsigned int level;
2561     unsigned int class;
2562     unsigned int diablo_kills;
2563     unsigned int strength;
2564     unsigned int magic;
2565     unsigned int dexterity;
2566     unsigned int vitality;
2567     unsigned int gold;
2568    
2569     if (sscanf(playerinfo,"LTRD %u %u %u %u %u %u %u %u %*u",
2570     &level,
2571     &class,
2572     &diablo_kills,
2573     &strength,
2574     &magic,
2575     &dexterity,
2576     &vitality,
2577     &gold)!=8)
2578     {
2579     eventlog(eventlog_level_error,__FUNCTION__,"got bad playerinfo");
2580     return -1;
2581     }
2582    
2583     account_set_normal_level(conn_get_account(c),clienttag,level);
2584     account_set_normal_class(conn_get_account(c),clienttag,class);
2585     account_set_normal_diablo_kills(conn_get_account(c),clienttag,diablo_kills);
2586     account_set_normal_strength(conn_get_account(c),clienttag,strength);
2587     account_set_normal_magic(conn_get_account(c),clienttag,magic);
2588     account_set_normal_dexterity(conn_get_account(c),clienttag,dexterity);
2589     account_set_normal_vitality(conn_get_account(c),clienttag,vitality);
2590     account_set_normal_gold(conn_get_account(c),clienttag,gold);
2591     }
2592     else if (clienttag==CLIENTTAG_DIABLOSHR_UINT)
2593     {
2594     unsigned int level;
2595     unsigned int class;
2596     unsigned int diablo_kills;
2597     unsigned int strength;
2598     unsigned int magic;
2599     unsigned int dexterity;
2600     unsigned int vitality;
2601     unsigned int gold;
2602    
2603     if (sscanf(playerinfo,"RHSD %u %u %u %u %u %u %u %u %*u",
2604     &level,
2605     &class,
2606     &diablo_kills,
2607     &strength,
2608     &magic,
2609     &dexterity,
2610     &vitality,
2611     &gold)!=8)
2612     {
2613     eventlog(eventlog_level_error,__FUNCTION__,"got bad playerinfo");
2614     return -1;
2615     }
2616    
2617     account_set_normal_level(conn_get_account(c),clienttag,level);
2618     account_set_normal_class(conn_get_account(c),clienttag,class);
2619     account_set_normal_diablo_kills(conn_get_account(c),clienttag,diablo_kills);
2620     account_set_normal_strength(conn_get_account(c),clienttag,strength);
2621     account_set_normal_magic(conn_get_account(c),clienttag,magic);
2622     account_set_normal_dexterity(conn_get_account(c),clienttag,dexterity);
2623     account_set_normal_vitality(conn_get_account(c),clienttag,vitality);
2624     account_set_normal_gold(conn_get_account(c),clienttag,gold);
2625     }
2626     else if (clienttag==CLIENTTAG_DIABLO2DV_UINT)
2627     {
2628     /* not much to do */ /* FIXME: get char name here? */
2629     eventlog(eventlog_level_trace,__FUNCTION__,"[%d] playerinfo request for client \"%s\" playerinfo=\"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2630     }
2631     else if (clienttag==CLIENTTAG_DIABLO2XP_UINT)
2632     {
2633     /* in playerinfo we get strings of the form "Realmname,charname" */
2634     eventlog(eventlog_level_trace,__FUNCTION__,"[%d] playerinfo request for client \"%s\" playerinfo=\"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2635     }
2636     else
2637     {
2638     eventlog(eventlog_level_warn,__FUNCTION__,"setting playerinfo for client \"%s\" not supported (playerinfo=\"%s\")",tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2639     return -1;
2640     }
2641    
2642     return 0;
2643     }
2644    
2645    
2646     extern char const * conn_get_realminfo(t_connection const * c)
2647     {
2648     if (!c)
2649     {
2650     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2651     return NULL;
2652     }
2653     return c->protocol.d2.realminfo;
2654     }
2655    
2656    
2657     extern int conn_set_realminfo(t_connection * c, char const * realminfo)
2658     {
2659     char const * temp;
2660    
2661     if (!c)
2662     {
2663     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2664     return -1;
2665     }
2666    
2667     if (realminfo)
2668     temp = xstrdup(realminfo);
2669     else
2670     temp = NULL;
2671    
2672     if (c->protocol.d2.realminfo) /* if it was set before, free it now */
2673     xfree((void *)c->protocol.d2.realminfo); /* avoid warning */
2674     c->protocol.d2.realminfo = temp;
2675     return 0;
2676     }
2677    
2678    
2679     extern char const * conn_get_charname(t_connection const * c)
2680     {
2681     if (!c)
2682     {
2683     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2684     return NULL;
2685     }
2686     return c->protocol.d2.charname;
2687     }
2688    
2689    
2690     extern int conn_set_charname(t_connection * c, char const * charname)
2691     {
2692     char const * temp;
2693    
2694     if (!c)
2695     {
2696     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2697     return -1;
2698     }
2699    
2700     if (charname)
2701     temp = xstrdup(charname);
2702     else
2703     temp = charname;
2704    
2705     if (c->protocol.d2.charname) /* free it, if it was previously set */
2706     xfree((void *)c->protocol.d2.charname); /* avoid warning */
2707     c->protocol.d2.charname = temp;
2708     return 0;
2709     }
2710    
2711    
2712     extern int conn_set_idletime(t_connection * c)
2713     {
2714     if (!c)
2715     {
2716     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2717     return -1;
2718     }
2719    
2720     c->protocol.chat.last_message = now;
2721     return 0;
2722     }
2723    
2724    
2725     extern unsigned int conn_get_idletime(t_connection const * c)
2726     {
2727     if (!c)
2728     {
2729     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2730     return 0;
2731     }
2732    
2733     return (unsigned int)difftime(now,c->protocol.chat.last_message);
2734     }
2735    
2736    
2737     extern t_realm * conn_get_realm(t_connection const * c)
2738     {
2739     if (!c)
2740     {
2741     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2742     return NULL;
2743     }
2744    
2745     return c->protocol.d2.realm;
2746     }
2747    
2748    
2749     extern int conn_set_realm(t_connection * c, t_realm * realm)
2750     {
2751     if (!c)
2752     {
2753     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2754     return -1;
2755     }
2756    
2757     if (c->protocol.d2.realm)
2758     realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
2759    
2760     if (!realm)
2761     c->protocol.d2.realm = NULL;
2762     else
2763     {
2764     c->protocol.d2.realm = realm_get(realm,&c->protocol.d2.realm_regref);
2765     eventlog(eventlog_level_debug,__FUNCTION__,"[%d] set to \"%s\"",conn_get_socket(c),realm_get_name(realm));
2766     }
2767    
2768     return 0;
2769     }
2770    
2771     extern int conn_set_realm_cb(void *data, void *newref)
2772     {
2773     t_connection *c = (t_connection*)data;
2774     t_realm *newrealm = (t_realm*)newref;
2775    
2776     assert(c->protocol.d2.realm); /* this should never be NULL here */
2777    
2778     /* we are removing a reference */
2779     realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
2780    
2781     if (newrealm)
2782     c->protocol.d2.realm = realm_get(newrealm,&c->protocol.d2.realm_regref);
2783     else {
2784     /* close the connection for players on unconfigured realms */
2785     conn_set_state(c,conn_state_destroy);
2786     c->protocol.d2.realm = NULL;
2787     }
2788    
2789     return 0;
2790     }
2791    
2792    
2793     extern int conn_set_character(t_connection * c, t_character * character)
2794     {
2795     if (!c)
2796     {
2797     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2798     return -1;
2799     }
2800     if (!character)
2801     {
2802     eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
2803     return -1;
2804     }
2805    
2806     c->protocol.d2.character = character;
2807    
2808     return 0;
2809     }
2810    
2811    
2812     extern void conn_set_country(t_connection * c, char const * country)
2813     {
2814     if (!c)
2815     {
2816     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2817     return;
2818     }
2819     if (!country)
2820     {
2821     eventlog(eventlog_level_error,__FUNCTION__,"got NULL country");
2822     return;
2823     }
2824    
2825     if (c->protocol.client.country)
2826     xfree((void *)c->protocol.client.country); /* avoid warning */
2827     c->protocol.client.country = xstrdup(country);
2828     }
2829    
2830    
2831     extern char const * conn_get_country(t_connection const * c)
2832     {
2833     if (!c)
2834     {
2835     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2836     return NULL;
2837     }
2838    
2839     return c->protocol.client.country;
2840     }
2841    
2842    
2843     extern int conn_bind(t_connection * c1, t_connection * c2)
2844     {
2845     if (!c1)
2846     {
2847     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2848     return -1;
2849     }
2850     if (!c2)
2851     {
2852     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2853     return -1;
2854     }
2855    
2856     c1->protocol.bound = c2;
2857     c2->protocol.bound = c1;
2858    
2859     return 0;
2860     }
2861    
2862    
2863     extern int conn_set_ircline(t_connection * c, char const * line)
2864     {
2865     if (!c) {
2866     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2867     return -1;
2868     }
2869     if (!line) {
2870     eventlog(eventlog_level_error,__FUNCTION__,"got NULL line");
2871     return -1;
2872     }
2873     if (c->protocol.chat.irc.ircline)
2874     xfree((void *)c->protocol.chat.irc.ircline); /* avoid warning */
2875     c->protocol.chat.irc.ircline = xstrdup(line);
2876     return 0;
2877     }
2878    
2879    
2880     extern char const * conn_get_ircline(t_connection const * c)
2881     {
2882     if (!c) {
2883     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2884     return NULL;
2885     }
2886     return c->protocol.chat.irc.ircline;
2887     }
2888    
2889    
2890     extern int conn_set_ircpass(t_connection * c, char const * pass)
2891     {
2892     if (!c) {
2893     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2894     return -1;
2895     }
2896     if (c->protocol.chat.irc.ircpass)
2897     xfree((void *)c->protocol.chat.irc.ircpass); /* avoid warning */
2898     if (!pass)
2899     c->protocol.chat.irc.ircpass = NULL;
2900     else
2901     c->protocol.chat.irc.ircpass = xstrdup(pass);
2902    
2903     return 0;
2904     }
2905    
2906    
2907     extern char const * conn_get_ircpass(t_connection const * c)
2908     {
2909     if (!c) {
2910     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2911     return NULL;
2912     }
2913     return c->protocol.chat.irc.ircpass;
2914     }
2915    
2916    
2917     extern int conn_set_ircping(t_connection * c, unsigned int ping)
2918     {
2919     if (!c) {
2920     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2921     return -1;
2922     }
2923     c->protocol.chat.irc.ircping = ping;
2924     return 0;
2925     }
2926    
2927    
2928     extern unsigned int conn_get_ircping(t_connection const * c)
2929     {
2930     if (!c) {
2931     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2932     return 0;
2933     }
2934     return c->protocol.chat.irc.ircping;
2935     }
2936    
2937     // NonReal
2938     extern int conn_get_welcomed(t_connection const * c)
2939     {
2940     if (!c)
2941     {
2942     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2943     return 0;
2944     }
2945    
2946     return (c->protocol.cflags & conn_flags_welcomed);
2947     }
2948    
2949     // NonReal
2950     extern void conn_set_welcomed(t_connection * c, int welcomed)
2951     {
2952    
2953     if (!c)
2954     {
2955     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2956     return;
2957     }
2958     c->protocol.cflags |= conn_flags_welcomed;
2959     }
2960    
2961     /* ADDED BY UNDYING SOULZZ 4/7/02 */
2962     extern int conn_set_w3_playerinfo( t_connection * c, const char * w3_playerinfo )
2963     {
2964     const char * temp;
2965    
2966     if (!c)
2967     {
2968     eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
2969     return -1;
2970     }
2971    
2972     temp = xstrdup( w3_playerinfo );
2973    
2974     if ( c->protocol.w3.w3_playerinfo )
2975     xfree((void *)c->protocol.w3.w3_playerinfo);
2976    
2977     c->protocol.w3.w3_playerinfo = temp;
2978    
2979     return 1;
2980     }
2981    
2982     extern const char * conn_get_w3_playerinfo( t_connection * c )
2983     {
2984     if (!c)
2985     {
2986     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2987     return NULL;
2988     }
2989     return c->protocol.w3.w3_playerinfo;
2990     }
2991    
2992    
2993     extern int conn_quota_exceeded(t_connection * con, char const * text)
2994     {
2995     t_qline * qline;
2996     t_elem * curr;
2997    
2998     if (!prefs_get_quota() ||
2999     !conn_get_account(con) ||
3000     (account_get_command_groups(conn_get_account(con)) & command_get_group("/admin-con"))) return 0;
3001    
3002     if (strlen(text)>prefs_get_quota_maxline())
3003     {
3004     message_send_text(con,message_type_error,con,"Your line length quota has been exceeded!");
3005     return 1;
3006     }
3007    
3008     LIST_TRAVERSE(con->protocol.chat.quota.list,curr)
3009     {
3010     qline = elem_get_data(curr);
3011     if (now>=qline->inf+(time_t)prefs_get_quota_time())
3012     {
3013     /* these lines are at least quota_time old */
3014     list_remove_elem(con->protocol.chat.quota.list,&curr);
3015     if (qline->count>con->protocol.chat.quota.totcount)
3016     eventlog(eventlog_level_error,__FUNCTION__,"qline->count=%u but con->protocol.chat.quota.totcount=%u",qline->count,con->protocol.chat.quota.totcount);
3017     con->protocol.chat.quota.totcount -= qline->count;
3018     xfree(qline);
3019     }
3020     else
3021     break; /* old items are first, so we know nothing else will match */
3022     }
3023    
3024     qline = xmalloc(sizeof(t_qline));
3025     qline->inf = now; /* set the moment */
3026     if (strlen(text)>prefs_get_quota_wrapline()) /* round up on the divide */
3027     qline->count = (strlen(text)+prefs_get_quota_wrapline()-1)/prefs_get_quota_wrapline();
3028     else
3029     qline->count = 1;
3030    
3031     list_append_data(con->protocol.chat.quota.list,qline);
3032    
3033     con->protocol.chat.quota.totcount += qline->count;
3034    
3035     if (con->protocol.chat.quota.totcount>=prefs_get_quota_lines())
3036     {
3037     message_send_text(con,message_type_error,con,"Your message quota has been exceeded!");
3038     if (con->protocol.chat.quota.totcount>=prefs_get_quota_dobae())
3039     {
3040     /* kick out the dobae user for violation of the quota rule */
3041     conn_set_state(con,conn_state_destroy);
3042     if (con->protocol.chat.channel)
3043     channel_message_log(con->protocol.chat.channel,con,0,"DISCONNECTED FOR DOBAE ABUSE");
3044     return 2;
3045     }
3046     return 1;
3047     }
3048    
3049     return 0;
3050     }
3051    
3052    
3053     extern int conn_set_lastsender(t_connection * c, char const * sender)
3054     {
3055     if (!c)
3056     {
3057     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conection");
3058     return -1;
3059     }
3060     if (c->protocol.chat.lastsender)
3061     xfree((void *)c->protocol.chat.lastsender); /* avoid warning */
3062     if (!sender)
3063     {
3064     c->protocol.chat.lastsender = NULL;
3065     return 0;
3066     }
3067     c->protocol.chat.lastsender = xstrdup(sender);
3068    
3069     return 0;
3070     }
3071    
3072    
3073     extern char const * conn_get_lastsender(t_connection const * c)
3074     {
3075     if (!c)
3076     {
3077     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3078     return NULL;
3079     }
3080     return c->protocol.chat.lastsender;
3081     }
3082    
3083    
3084     extern t_versioncheck * conn_get_versioncheck(t_connection * c)
3085     {
3086     if (!c)
3087     {
3088     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3089     return NULL;
3090     }
3091    
3092     return c->protocol.client.versioncheck;
3093     }
3094    
3095    
3096     extern int conn_set_versioncheck(t_connection * c, t_versioncheck * versioncheck)
3097     {
3098     if (!c)
3099     {
3100     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3101     return -1;
3102     }
3103     if (!versioncheck)
3104     {
3105     eventlog(eventlog_level_error,__FUNCTION__,"got NULL versioncheck");
3106     return -1;
3107     }
3108    
3109     c->protocol.client.versioncheck = versioncheck;
3110    
3111     return 0;
3112     }
3113    
3114     extern int conn_get_echoback(t_connection * c)
3115     {
3116     if (!c)
3117     {
3118     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3119     return 0;
3120     }
3121    
3122     return (c->protocol.cflags & conn_flags_echoback);
3123     }
3124    
3125     extern void conn_set_echoback(t_connection * c, int echoback)
3126     {
3127     if (!c)
3128     {
3129     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3130     return;
3131     }
3132     if (echoback)
3133     c->protocol.cflags |= conn_flags_echoback;
3134     else
3135     c->protocol.cflags &= ~conn_flags_echoback;
3136     }
3137    
3138     extern int conn_set_udpok(t_connection * c)
3139     {
3140     if (!c)
3141     {
3142     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3143     return -1;
3144     }
3145    
3146     if (!(c->protocol.cflags & conn_flags_udpok))
3147     {
3148     c->protocol.cflags|= conn_flags_udpok;
3149     c->protocol.flags &= ~MF_PLUG;
3150     }
3151    
3152     return 0;
3153     }
3154    
3155    
3156     extern t_connection * conn_get_routeconn(t_connection const * c)
3157     {
3158     if (!c)
3159     {
3160     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3161     return NULL;
3162     }
3163    
3164     return c->protocol.w3.routeconn;
3165     }
3166    
3167    
3168     extern int conn_set_routeconn(t_connection * c, t_connection * rc)
3169     {
3170     if (!c) {
3171     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conection");
3172     return -1;
3173     }
3174     c->protocol.w3.routeconn = rc;
3175    
3176     return 0;
3177     }
3178    
3179     extern int conn_get_crtime(t_connection *c)
3180     {
3181     if (!c)
3182     {
3183     eventlog(eventlog_level_error, "conn_get_crtime", "got NULL connection");
3184     return -1;
3185     }
3186     return c->protocol.cr_time;
3187     }
3188    
3189     extern int conn_set_joingamewhisper_ack(t_connection * c, unsigned int value)
3190     {
3191     if (!c)
3192     {
3193     eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3194     return -1;
3195     }
3196     if (value)
3197     c->protocol.cflags |= conn_flags_joingamewhisper;
3198     else
3199     c->protocol.cflags &= ~conn_flags_joingamewhisper;
3200     return 0;
3201     }
3202     extern int conn_get_joingamewhisper_ack(t_connection * c)
3203     {
3204     if (!c)
3205     {
3206     eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3207     return -1;
3208     }
3209     return (c->protocol.cflags & conn_flags_joingamewhisper);
3210     }
3211    
3212     extern int conn_set_leavegamewhisper_ack(t_connection * c, unsigned int value)
3213     {
3214     if (!c)
3215     {
3216     eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3217     return -1;
3218     }
3219     if (value)
3220     c->protocol.cflags |= conn_flags_leavegamewhisper;
3221     else
3222     c->protocol.cflags &= ~conn_flags_leavegamewhisper;
3223     return 0;
3224     }
3225     extern int conn_get_leavegamewhisper_ack(t_connection * c)
3226     {
3227     if (!c)
3228     {
3229     eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3230     return -1;
3231     }
3232     return (c->protocol.cflags & conn_flags_leavegamewhisper);
3233     }
3234    
3235     extern int conn_set_anongame_search_starttime(t_connection * c, time_t t)
3236     {
3237     if (c == NULL) {
3238     eventlog(eventlog_level_error, "conn_set_anongame_search_starttime", "got NULL connection");
3239     return -1;
3240     }
3241     c->protocol.w3.anongame_search_starttime = t;
3242     return 0;
3243     }
3244    
3245     extern time_t conn_get_anongame_search_starttime(t_connection * c)
3246     {
3247     if (c == NULL) {
3248     eventlog(eventlog_level_error, "conn_set_anongame_search_starttime", "got NULL connection");
3249     return ((time_t) 0);
3250     }
3251     return c->protocol.w3.anongame_search_starttime;
3252     }
3253    
3254    
3255     extern t_elist * conn_get_timer(t_connection *c)
3256     {
3257     if (!c) {
3258     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
3259     return NULL;
3260     }
3261    
3262     return &c->protocol.timers;
3263     }
3264    
3265    
3266     extern int conn_add_fdwatch(t_connection *c, fdwatch_handler handle)
3267     {
3268     assert(c);
3269     c->socket.fdw_idx = fdwatch_add_fd(c->socket.tcp_sock, fdwatch_type_read, handle, c);
3270     return c->socket.fdw_idx;
3271     }
3272    
3273    
3274     extern int conn_get_user_count_by_clienttag(t_clienttag ct)
3275     {
3276     t_connection * conn;
3277     t_elem const * curr;
3278     int clienttagusers = 0;
3279    
3280     /* Get Number of Users for client tag specific */
3281     LIST_TRAVERSE_CONST(connlist(),curr)
3282     {
3283     conn = elem_get_data(curr);
3284     if (ct == conn->protocol.client.clienttag)
3285     clienttagusers++;
3286     }
3287    
3288     return clienttagusers;
3289     }
3290    
3291     extern int connlist_create(void)
3292     {
3293     conn_head = list_create();
3294     connarray_create();
3295     return 0;
3296     }
3297    
3298     extern int connlist_destroy(void)
3299     {
3300     if (conn_dead) list_destroy(conn_dead);
3301     conn_dead = NULL;
3302     connarray_destroy();
3303     /* FIXME: if called with active connection, connection are not freed */
3304     if (list_destroy(conn_head)<0)
3305     return -1;
3306     conn_head = NULL;
3307     return 0;
3308     }
3309    
3310     extern void connlist_reap(void)
3311     {
3312     t_elem *curr;
3313     t_connection *c;
3314    
3315     if (!conn_dead || !conn_head) return;
3316    
3317     LIST_TRAVERSE(conn_dead, curr)
3318     {
3319     c = (t_connection *)elem_get_data(curr);
3320    
3321     if (!c)
3322     eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in conn_dead list");
3323     else conn_destroy(c,&curr,DESTROY_FROM_DEADLIST); /* also removes from conn_dead list and fdwatch */
3324     }
3325     }
3326    
3327     extern t_list * connlist(void)
3328     {
3329     return conn_head;
3330     }
3331    
3332    
3333     extern t_connection * connlist_find_connection_by_accountname(char const * accountname)
3334     {
3335     t_account * temp;
3336    
3337     if (!accountname)
3338     {
3339     eventlog(eventlog_level_error,__FUNCTION__,"got NULL accountname");
3340     return NULL;
3341     }
3342    
3343     if (!(temp = accountlist_find_account(accountname)))
3344     return NULL;
3345    
3346     return account_get_conn(temp);
3347     }
3348    
3349     extern t_connection * connlist_find_connection_by_account(t_account * account)
3350     {
3351     if (!account) {
3352     eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
3353     return NULL;
3354     }
3355     return account_get_conn(account);
3356     }
3357    
3358    
3359     extern t_connection * connlist_find_connection_by_sessionkey(unsigned int sessionkey)
3360     {
3361     t_connection * c;
3362     t_elem const * curr;
3363    
3364     LIST_TRAVERSE_CONST(conn_head,curr)
3365     {
3366     c = elem_get_data(curr);
3367     if (c->protocol.sessionkey==sessionkey)
3368     return c;
3369     }
3370    
3371     return NULL;
3372     }
3373    
3374    
3375     extern t_connection * connlist_find_connection_by_sessionnum(unsigned int sessionnum)
3376     {
3377     return connarray_get_conn(sessionnum);
3378     }
3379    
3380    
3381     extern t_connection * connlist_find_connection_by_socket(int socket)
3382     {
3383     t_connection * c;
3384     t_elem const * curr;
3385    
3386     LIST_TRAVERSE_CONST(conn_head,curr)
3387     {
3388     c = elem_get_data(curr);
3389     if (c->socket.tcp_sock==socket)
3390     return c;
3391     }
3392    
3393     return NULL;
3394     }
3395    
3396    
3397     extern t_connection * connlist_find_connection_by_name(char const * name, t_realm * realm)
3398     {
3399     char charname[CHAR_NAME_LEN];
3400     char const * temp;
3401    
3402     if (!name)
3403     {
3404     eventlog(eventlog_level_error,__FUNCTION__,"got NULL name");
3405     return NULL;
3406     }
3407     if (name[0]=='\0')
3408     {
3409     eventlog(eventlog_level_error,__FUNCTION__,"got empty name");
3410     return NULL;
3411     }
3412    
3413     /* format: *username */
3414     if (name[0]=='*')
3415     {
3416     name++;
3417     return connlist_find_connection_by_accountname(name);
3418     }
3419    
3420     /* If is charname@otherrealm or ch@rname@realm */
3421     if ((temp=strrchr(name,'@'))) /* search from the right */
3422     {
3423     unsigned int n;
3424    
3425     n = temp - name;
3426     if (n>=CHAR_NAME_LEN)
3427     {
3428     eventlog(eventlog_level_info,__FUNCTION__,"character name too long in \"%s\" (charname@otherrealm format)",name);
3429     return NULL;
3430     }
3431     strncpy(charname,name,n);
3432     charname[n] = '\0';
3433     return connlist_find_connection_by_charname(name,temp + 1);
3434     }
3435    
3436     /* format: charname*username */
3437     if ((temp=strchr(name,'*')))
3438     {
3439     unsigned int n;
3440    
3441     n = temp - name;
3442     if (n>=CHAR_NAME_LEN)
3443     {
3444     eventlog(eventlog_level_info,__FUNCTION__,"character name too long in \"%s\" (charname*username format)",name);
3445     return NULL;
3446     }
3447     name = temp + 1;
3448     return connlist_find_connection_by_accountname(name);
3449     }
3450    
3451     /* format: charname (realm must be not NULL) */
3452     if (realm)
3453     return connlist_find_connection_by_charname(name,realm_get_name(realm));
3454    
3455     /* format: Simple username, clients with no realm, like starcraft or d2 open,
3456     * the format is the same of charname but is matched if realmname is NULL */
3457     return connlist_find_connection_by_accountname(name);
3458     }
3459    
3460    
3461     extern t_connection * connlist_find_connection_by_charname(char const * charname, char const * realmname)
3462     {
3463     t_connection * c;
3464     t_elem const * curr;
3465    
3466     if (!realmname) {
3467     eventlog(eventlog_level_error,__FUNCTION__,"got NULL realmname");
3468     return NULL;
3469     }
3470     LIST_TRAVERSE_CONST(conn_head, curr)
3471     {
3472     c = elem_get_data(curr);
3473     if (!c)
3474     continue;
3475     if (!c->protocol.d2.charname)
3476     continue;
3477     if (!c->protocol.d2.realm)
3478     continue;
3479     if ((strcasecmp(c->protocol.d2.charname, charname)==0)&&(strcasecmp(realm_get_name(c->protocol.d2.realm),realmname)==0))
3480     return c;
3481     }
3482     return NULL;
3483     }
3484    
3485    
3486     extern t_connection * connlist_find_connection_by_uid(unsigned int uid)
3487     {
3488     t_account * temp;
3489    
3490     if (!(temp = accountlist_find_account_by_uid(uid)))
3491     {
3492     return NULL;
3493     }
3494     return account_get_conn(temp);
3495     }
3496    
3497     extern int connlist_get_length(void)
3498     {
3499     return list_get_length(conn_head);
3500     }
3501    
3502    
3503     extern unsigned int connlist_login_get_length(void)
3504     {
3505     t_connection const * c;
3506     unsigned int count;
3507     t_elem const * curr;
3508    
3509     count = 0;
3510     LIST_TRAVERSE_CONST(conn_head,curr)
3511     {
3512     c = elem_get_data(curr);
3513     if ((c->protocol.state==conn_state_loggedin)&&
3514     ((c->protocol.class==conn_class_bnet)||(c->protocol.class==conn_class_bot)||(c->protocol.class==conn_class_telnet)||(c->protocol.class==conn_class_irc)))
3515     count++;
3516     }
3517    
3518     return count;
3519     }
3520    
3521    
3522     extern int connlist_total_logins(void)
3523     {
3524     return totalcount;
3525     }
3526    
3527    
3528     extern unsigned int connlist_count_connections(unsigned int addr)
3529     {
3530     t_connection * c;
3531     t_elem const * curr;
3532     unsigned int count;
3533    
3534     count = 0;
3535    
3536     LIST_TRAVERSE_CONST(conn_head,curr)
3537     {
3538     c = (t_connection *)elem_get_data(curr);
3539     if (c->socket.tcp_addr == addr)
3540     count++;
3541     }
3542    
3543     return count;
3544     }
3545    
3546     extern int conn_update_w3_playerinfo(t_connection * c)
3547     {
3548     t_account * account;
3549     t_clienttag clienttag;
3550     t_clan * user_clan;
3551     int clantag=0;
3552     unsigned int acctlevel;
3553     char tempplayerinfo[40];
3554     char raceicon; /* appeared in 1.03 */
3555     unsigned int raceiconnumber;
3556     unsigned int wins;
3557     char const * usericon;
3558     char clantag_str_tmp[5];
3559     const char * clantag_str = NULL;
3560     char revtag[5];
3561     char clienttag_str[5];
3562    
3563     if (c == NULL) {
3564     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
3565     return -1;
3566     }
3567    
3568     account = conn_get_account(c);
3569    
3570     if (account == NULL) {
3571     eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
3572     return -1;
3573     }
3574    
3575     strncpy(revtag, tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(c)),5); revtag[4] = '\0';
3576     strreverse(revtag);
3577    
3578     clienttag = c->protocol.client.clienttag;
3579    
3580     acctlevel = account_get_highestladderlevel(account,clienttag);
3581     account_get_raceicon(account, &raceicon, &raceiconnumber, &wins, clienttag);
3582    
3583     if((user_clan = account_get_clan(account)) != NULL)
3584     clantag = clan_get_clantag(user_clan);
3585    
3586     if(clantag) {
3587     sprintf(clantag_str_tmp, "%c%c%c%c", clantag&0xff, (clantag>>8)&0xff, (clantag>>16)&0xff, clantag>>24);
3588     clantag_str=clantag_str_tmp;
3589     while((* clantag_str) == 0) clantag_str++;
3590     }
3591    
3592     if(acctlevel == 0) {
3593     if(clantag)
3594     sprintf(tempplayerinfo, "%s %s 0 %s", revtag, revtag, clantag_str);
3595     else
3596     strcpy(tempplayerinfo, revtag);
3597     eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s",conn_get_socket(c), revtag);
3598     } else {
3599     usericon = account_get_user_icon(account,clienttag);
3600     if (!usericon) {
3601     if(clantag)
3602     sprintf(tempplayerinfo, "%s %1u%c3W %u %s", revtag, raceiconnumber, raceicon, acctlevel, clantag_str);
3603     else
3604     sprintf(tempplayerinfo, "%s %1u%c3W %u", revtag, raceiconnumber, raceicon, acctlevel);
3605     eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s using generated icon [%1u%c3W]",conn_get_socket(c), revtag, raceiconnumber, raceicon);
3606     } else {
3607     if(clantag)
3608     sprintf(tempplayerinfo, "%s %s %u %s",revtag, usericon, acctlevel, clantag_str);
3609     else
3610     sprintf(tempplayerinfo, "%s %s %u",revtag, usericon, acctlevel);
3611     eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s using user-selected icon [%s]",conn_get_socket(c),revtag,usericon);
3612     }
3613     }
3614    
3615     conn_set_w3_playerinfo( c, tempplayerinfo );
3616    
3617     return 0;
3618     }
3619    
3620    
3621     extern int conn_get_passfail_count (t_connection * c)
3622     {
3623     if (!c)
3624     {
3625     eventlog(eventlog_level_error, "conn_get_passfail_count", "got NULL connection");
3626     return -1;
3627     }
3628     return c->protocol.passfail_count;
3629     }
3630    
3631    
3632     extern int conn_set_passfail_count (t_connection * c, unsigned int n)
3633     {
3634     if (c == NULL)
3635     {
3636     eventlog(eventlog_level_error, "conn_set_passfail_count", "got NULL connection");
3637     return -1;
3638     }
3639     c->protocol.passfail_count = n;
3640     return 0;
3641     }
3642    
3643    
3644     extern int conn_increment_passfail_count (t_connection * c)
3645     {
3646     unsigned int count;
3647    
3648     if (prefs_get_passfail_count() > 0)
3649     {
3650     count = conn_get_passfail_count(c) + 1;
3651     if (count == prefs_get_passfail_count())
3652     {
3653     ipbanlist_add(NULL, addr_num_to_ip_str(conn_get_addr(c)), now+(time_t)prefs_get_passfail_bantime());
3654     eventlog(eventlog_level_info,__FUNCTION__,"[%d] failed password tries: %d (banned ip)",conn_get_socket(c), count);
3655     conn_set_state(c, conn_state_destroy);
3656     return -1;
3657     }
3658     else conn_set_passfail_count(c, count);
3659     }
3660     return 0;
3661     }
3662    
3663     extern int conn_set_tmpOP_channel(t_connection * c, char const * tmpOP_channel)
3664     {
3665     if (!c)
3666     {
3667     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3668     return -1;
3669     }
3670    
3671     if (c->protocol.chat.tmpOP_channel)
3672     {
3673     xfree((void *)c->protocol.chat.tmpOP_channel);
3674     c->protocol.chat.tmpOP_channel = NULL;
3675     }
3676    
3677     if (tmpOP_channel)
3678     c->protocol.chat.tmpOP_channel = xstrdup(tmpOP_channel);
3679    
3680     return 0;
3681     }
3682    
3683     extern char const * conn_get_tmpOP_channel(t_connection * c)
3684     {
3685     if (!c)
3686     {
3687     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3688     return NULL;
3689     }
3690    
3691     return c->protocol.chat.tmpOP_channel;
3692     }
3693    
3694     extern int conn_set_tmpVOICE_channel(t_connection * c, char const * tmpVOICE_channel)
3695     {
3696     if (!c)
3697     {
3698     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3699     return -1;
3700     }
3701    
3702     if (c->protocol.chat.tmpVOICE_channel)
3703     {
3704     xfree((void *)c->protocol.chat.tmpVOICE_channel);
3705     c->protocol.chat.tmpVOICE_channel = NULL;
3706     }
3707    
3708     if (tmpVOICE_channel)
3709     c->protocol.chat.tmpVOICE_channel = xstrdup(tmpVOICE_channel);
3710    
3711     return 0;
3712     }
3713    
3714     extern char const * conn_get_tmpVOICE_channel(t_connection * c)
3715     {
3716     if (!c)
3717     {
3718     eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3719     return NULL;
3720     }
3721    
3722     return c->protocol.chat.tmpVOICE_channel;
3723     }
3724    
3725     static int connarray_create(void)
3726     {
3727     int i;
3728     t_conn_entry *curr;
3729    
3730     if (connarray) connarray_destroy();
3731     connarray = xmalloc(sizeof(t_conn_entry) * fdw_maxcons);
3732    
3733     elist_init(&arrayflist);
3734     /* put all elements as free */
3735     for(i = 0, curr = connarray; i < fdw_maxcons; i++, curr++) {
3736     elist_add_tail(&arrayflist,&curr->freelist);
3737     curr->c = NULL;
3738     }
3739    
3740     return 0;
3741     }
3742    
3743    
3744     static void connarray_destroy(void)
3745     {
3746     if (connarray) xfree((void*)connarray);
3747     connarray = NULL;
3748     }
3749    
3750     static t_connection *connarray_get_conn(unsigned index)
3751     {
3752     if (index >= fdw_maxcons) return NULL;
3753     return connarray[index].c;
3754     }
3755    
3756     static unsigned connarray_add_conn(t_connection *c)
3757     {
3758     t_conn_entry *curr;
3759    
3760     assert(c);
3761     assert(!elist_empty(&arrayflist));
3762    
3763     curr = elist_entry(elist_next(&arrayflist),t_conn_entry,freelist);
3764     assert(curr->c == NULL); /* it should never be free and != NULL */
3765     curr->c = c;
3766     elist_del(&curr->freelist);
3767     return (curr - connarray); /* return the array index */
3768     }
3769    
3770     static void connarray_del_conn(unsigned index)
3771     {
3772     t_conn_entry *curr;
3773    
3774     if (index >= fdw_maxcons) return;
3775     curr = connarray + index;
3776     curr->c = NULL;
3777     elist_add_tail(&arrayflist,&curr->freelist);
3778     }

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