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