Ejemplo n.º 1
0
extern void maplists_add_map_info_to_packet(t_packet * rpacket, t_clienttag clienttag, int queue)
{
    int i;

    if (clienttag==CLIENTTAG_WARCRAFT3_UINT) {
	for (i = 0; i < maplists_war3[queue][0] + 1; i++)
	    packet_append_data(rpacket, &maplists_war3[queue][i], 1);
    }
    if (clienttag==CLIENTTAG_WAR3XP_UINT) {
	for (i = 0; i < maplists_w3xp[queue][0] + 1; i++)
	    packet_append_data(rpacket, &maplists_w3xp[queue][i], 1);
    }
}
Ejemplo n.º 2
0
Archivo: irc.c Proyecto: 91D2/pvpgn
extern int irc_send_pong(t_connection * conn, char const * params)
{
    t_packet * p;
    char data[MAX_IRC_MESSAGE_LEN];
    
    if (!conn) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return -1;
    }
    if ((1+strlen(server_get_hostname())+1+4+1+strlen(server_get_hostname())+((params)?(2+strlen(params)):(0))+2+1) > MAX_IRC_MESSAGE_LEN) {
	eventlog(eventlog_level_error,__FUNCTION__,"max message length exceeded");
	return -1;
    }
    if (!(p = packet_create(packet_class_raw))) {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
	return -1;
    }
    
    if (params)
    	sprintf(data,":%s PONG %s :%s\r\n",server_get_hostname(),server_get_hostname(),params);
    else
    	sprintf(data,":%s PONG %s\r\n",server_get_hostname(),server_get_hostname());
    eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data);
    packet_set_size(p,0);
    packet_append_data(p,data,strlen(data));
    conn_push_outqueue(conn,p);
    packet_del_ref(p);
    return 0;
}
Ejemplo n.º 3
0
Archivo: irc.c Proyecto: 91D2/pvpgn
extern int irc_send_ping(t_connection * conn)
{
    t_packet * p;
    char data[MAX_IRC_MESSAGE_LEN];
    
    if (!conn) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return -1;
    }
    if (!(p = packet_create(packet_class_raw))) {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
	return -1;
    }

    if((conn_get_wol(conn) == 1))
        return 0;

    conn_set_ircping(conn,get_ticks());
    if (conn_get_state(conn)==conn_state_bot_username)
    	sprintf(data,"PING :%u\r\n",conn_get_ircping(conn)); /* Undernet doesn't reveal the servername yet ... neither do we */
    else if ((6+strlen(server_get_hostname())+2+1)<=MAX_IRC_MESSAGE_LEN)
    	sprintf(data,"PING :%s\r\n",server_get_hostname());
    else
    	eventlog(eventlog_level_error,__FUNCTION__,"maximum message length exceeded");
    eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data);
    packet_set_size(p,0);
    packet_append_data(p,data,strlen(data));
    conn_push_outqueue(conn,p);
    packet_del_ref(p);
    return 0;
}
Ejemplo n.º 4
0
Archivo: irc.c Proyecto: 91D2/pvpgn
extern int irc_send_cmd2(t_connection * conn, char const * prefix, char const * command, char const * postfix, char const * comment)
{
    t_packet * p;
    char data[MAX_IRC_MESSAGE_LEN+1];
    int len;
    
    if (!conn) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return -1;
    }
    if (!prefix)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL prefix");
	return -1;
    }
    if (!command) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL command");
	return -1;
    }
    if (!postfix)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL postfix");
	return -1;
    }
    
    if (!(p = packet_create(packet_class_raw))) {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
	return -1;
    }

    if (comment) {
        len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+2+strlen(comment)+1+2;
    	if (len > MAX_IRC_MESSAGE_LEN) {
	    eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len);
	    return -1;
	}
	else
	    sprintf(data,":%s %s %s :%s\r\n",prefix,command,postfix,comment);
    } else {
        len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+1+2;
    	if (len > MAX_IRC_MESSAGE_LEN) {
	    eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len);
	    return -1;
	}
	else
	sprintf(data,":%s %s %s\r\n",prefix,command,postfix);
    }
    packet_set_size(p,0);
    packet_append_data(p,data,len);
    // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data);
    conn_push_outqueue(conn,p);
    packet_del_ref(p);
    return 0;
}
Ejemplo n.º 5
0
extern t_packet * packet_duplicate(t_packet const * src)
{
    t_packet * p;

    if (!(p = packet_create(packet_get_class(src))))
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
	return NULL;
    }
    packet_append_data(p,src->u.data,packet_get_size(src));
    packet_set_flags(p,packet_get_flags(src));

    return p;
}
Ejemplo n.º 6
0
Archivo: irc.c Proyecto: 91D2/pvpgn
extern int irc_send_cmd(t_connection * conn, char const * command, char const * params)
{
    t_packet * p;
    char data[MAX_IRC_MESSAGE_LEN+1];
    int len;
    char const * ircname = server_get_hostname(); 
    char const * nick;
    
    if (!conn) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return -1;
    }
    if (!command) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL command");
	return -1;
    }
    if (!(p = packet_create(packet_class_raw))) {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
	return -1;
    }

    nick = conn_get_loggeduser(conn);
    if (!nick)
    	nick = "";
    	
    /* snprintf isn't portable -> check message length first */
    if (params) {
        len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+strlen(params)+2;
	if (len > MAX_IRC_MESSAGE_LEN) {
	    eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len);
	    return -1;
	}
	else
	    sprintf(data,":%s %s %s %s\r\n",ircname,command,nick,params);
    } else {
        len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+2;
    	if (len > MAX_IRC_MESSAGE_LEN) {
	    eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len);
	    return -1;
	}
	else
	sprintf(data,":%s %s %s\r\n",ircname,command,nick);
    }
    packet_set_size(p,0);
    packet_append_data(p,data,len);
    // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data);
    conn_push_outqueue(conn,p);
    packet_del_ref(p);
    return 0;
}
Ejemplo n.º 7
0
		static int _client_anongame_infos(t_connection * c, t_packet const * const packet)
		{
			t_packet * rpacket;

			if (bn_int_get(packet->u.client_findanongame_inforeq.count) > 1) {
				/* reply with 0 entries found */
				int	temp = 0;

				if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
					eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
					return -1;
				}

				packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
				packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
				bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
				bn_int_set(&rpacket->u.server_findanongame_inforeply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
				bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, 0);
				packet_append_data(rpacket, &temp, 1);

				conn_push_outqueue(c, rpacket);
				packet_del_ref(rpacket);
			}
			else {
				int i;
				int client_tag;
				int server_tag_count = 0;
				int client_tag_unk;
				int server_tag_unk;
				bn_int temp;
				char noitems;
				char * tmpdata;
				int tmplen;
				t_clienttag clienttag = conn_get_clienttag(c);
				char last_packet = 0x00;
				char other_packet = 0x01;
				char langstr[5];
				t_gamelang gamelang = conn_get_gamelang(c);
				bn_int_tag_get((bn_int const *)&gamelang, langstr, 5);

				/* Send seperate packet for each item requested
				 * sending all at once overloaded w3xp
				 * [Omega] */
				for (i = 0; i < bn_byte_get(packet->u.client_findanongame_inforeq.noitems); i++){
					noitems = 0;

					if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
						eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
						return -1;
					}

					/* Starting the packet stuff */
					packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
					packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
					bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
					bn_int_set(&rpacket->u.server_findanongame_inforeply.count, 1);

					std::memcpy(&temp, (packet_get_data_const(packet, 10 + (i * 8), 4)), sizeof(int));
					client_tag = bn_int_get(temp);
					std::memcpy(&temp, packet_get_data_const(packet, 14 + (i * 8), 4), sizeof(int));
					client_tag_unk = bn_int_get(temp);

					switch (client_tag){
					case CLIENT_FINDANONGAME_INFOTAG_URL:
						bn_int_set((bn_int*)&server_tag_unk, 0xBF1F1047);
						packet_append_data(rpacket, "LRU\0", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						// FIXME: Maybe need do do some checks to avoid prefs empty strings.
						tmpdata = anongame_infos_data_get_url(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_URL", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_MAP:
						bn_int_set((bn_int*)&server_tag_unk, 0x70E2E0D5);
						packet_append_data(rpacket, "PAM\0", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_map(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_MAP", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_TYPE:
						bn_int_set((bn_int*)&server_tag_unk, 0x7C87DEEE);
						packet_append_data(rpacket, "EPYT", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_type(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_TYPE", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_DESC:
						bn_int_set((bn_int*)&server_tag_unk, 0xA4F0A22F);
						packet_append_data(rpacket, "CSED", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_desc(langstr, clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_DESC", client_tag_unk);
						noitems++;
						server_tag_count++;
						break;
					case CLIENT_FINDANONGAME_INFOTAG_LADR:
						bn_int_set((bn_int*)&server_tag_unk, 0x3BADE25A);
						packet_append_data(rpacket, "RDAL", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_ladr(langstr, clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_LADR", client_tag_unk);
						break;
					default:
						eventlog(eventlog_level_debug, __FUNCTION__, "unrec client_tag request tagid=(0x%01x) tag=(0x%04x)", i, client_tag);

					}
					//Adding a last padding null-byte
					if (server_tag_count == bn_byte_get(packet->u.client_findanongame_inforeq.noitems))
						packet_append_data(rpacket, &last_packet, 1); /* only last packet in group gets 0x00 */
					else
						packet_append_data(rpacket, &other_packet, 1); /* the rest get 0x01 */

					//Go,go,go
					bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, noitems);
					conn_push_outqueue(c, rpacket);
					packet_del_ref(rpacket);
				}
			}
			return 0;
		}
Ejemplo n.º 8
0
		/* Open portrait in Warcraft 3 user profile */
		static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet)
		{
			t_packet * rpacket;
			//BlacKDicK 04/20/2003 Need some huge re-work on this.
			{
				struct
				{
					char	 icon_code[4];
					unsigned int portrait_code;
					char	 race;
					bn_short	 required_wins;
					char	 client_enabled;
				} tempicon;

				//FIXME: Add those to the prefs and also merge them on accoun_wrap;
				// FIXED BY DJP 07/16/2003 FOR 110 CHANGE ( TOURNEY & RACE WINS ) + Table_witdh
				short icon_req_race_wins;
				short icon_req_tourney_wins;
				int race[] = { W3_RACE_RANDOM, W3_RACE_HUMANS, W3_RACE_ORCS, W3_RACE_UNDEAD, W3_RACE_NIGHTELVES, W3_RACE_DEMONS };
				char race_char[6] = { 'R', 'H', 'O', 'U', 'N', 'D' };
				char icon_pos[5] = { '2', '3', '4', '5', '6', };
				char table_width = 6;
				char table_height = 5;
				int i, j;
				char rico;
				unsigned int rlvl, rwins;
				t_clienttag clienttag;
				t_account * acc;

				char user_icon[5];
				char const * uicon;

				clienttag = conn_get_clienttag(c);
				acc = conn_get_account(c);
				/* WAR3 uses a different table size, might change if blizzard add tournament support to RoC */
				if (clienttag == CLIENTTAG_WARCRAFT3_UINT) {
					table_width = 5;
					table_height = 4;
				}

				eventlog(eventlog_level_info, __FUNCTION__, "[%d] got FINDANONGAME Get Icons packet", conn_get_socket(c));

				if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
					eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
					return -1;
				}

				packet_set_size(rpacket, sizeof(t_server_findanongame_iconreply));
				packet_set_type(rpacket, SERVER_FINDANONGAME_ICONREPLY);
				bn_int_set(&rpacket->u.server_findanongame_iconreply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
				bn_byte_set(&rpacket->u.server_findanongame_iconreply.option, CLIENT_FINDANONGAME_GET_ICON);
				
				
				if (prefs_get_custom_icons() == 1)
				{
					// get current custom icon
					t_icon_info * icon;
					if (icon = customicons_get_icon_by_account(acc, clienttag))
						std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, icon->icon_code, 4);
				}
				else if ((uicon = account_get_user_icon(acc, clienttag)))
				{
					std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, uicon, 4);
				}
				else
				{
					account_get_raceicon(acc, &rico, &rlvl, &rwins, clienttag);
					std::sprintf(user_icon, "%1d%c3W", rlvl, rico);
					std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, user_icon, 4);
				}

				bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_width, table_width);
				bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_size, table_width*table_height);
				for (j = 0; j < table_height; j++){
					icon_req_race_wins = anongame_infos_get_ICON_REQ(j + 1, clienttag);
					for (i = 0; i < table_width; i++){
						tempicon.race = i;
						tempicon.icon_code[0] = icon_pos[j];
						tempicon.icon_code[1] = race_char[i];
						tempicon.icon_code[2] = '3';
						tempicon.icon_code[3] = 'W';
						tempicon.portrait_code = (account_icon_to_profile_icon(tempicon.icon_code, acc, clienttag));
						if (i <= 4){
							//Building the icon for the races
							bn_short_set(&tempicon.required_wins, icon_req_race_wins);
							if (account_get_racewins(acc, race[i], clienttag) >= icon_req_race_wins) {
								if (prefs_get_custom_icons() == 1)
									tempicon.client_enabled = 0;
								else
									tempicon.client_enabled = 1;
							}
							else{
								tempicon.client_enabled = 0;
							}
						}
						else{
							//Building the icon for the tourney
							icon_req_tourney_wins = anongame_infos_get_ICON_REQ_TOURNEY(j + 1);
							bn_short_set(&tempicon.required_wins, icon_req_tourney_wins);
							if (account_get_racewins(acc, race[i], clienttag) >= icon_req_tourney_wins) {
								if (prefs_get_custom_icons() == 1)
									tempicon.client_enabled = 0;
								else
									tempicon.client_enabled = 1;
							}
							else{
								tempicon.client_enabled = 0;
							}
						}
						packet_append_data(rpacket, &tempicon, sizeof(tempicon));
					}
				}
				//Go,go,go
				conn_push_outqueue(c, rpacket);
				packet_del_ref(rpacket);
			}
			return 0;
		}
Ejemplo n.º 9
0
static int init_virtconn(t_virtconn * vc, struct sockaddr_in servaddr)
{
    int  addlen;
    char connect_type;
    
    /* determine connection type by first character sent by client */
    addlen = psock_recv(virtconn_get_client_socket(vc),&connect_type,sizeof(char),0);
    
    if (addlen<0 && (psock_errno()==PSOCK_EINTR || psock_errno()==PSOCK_EAGAIN || psock_errno()==PSOCK_EWOULDBLOCK))
	return 0;
    
    /* error occurred or connection lost */
    if (addlen<1)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not get virtconn class (closing connection) (psock_recv: %s)",virtconn_get_client_socket(vc),pstrerror(psock_errno()));
	return -1;
    }
    
    switch (connect_type)
    {
    case CLIENT_INITCONN_CLASS_BNET:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated normal connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_bnet);
	
	break;
	
    case CLIENT_INITCONN_CLASS_FILE:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated file download connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_file);
	
	break;
	
    case CLIENT_INITCONN_CLASS_BOT:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated chat bot connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_bot);
	
	break;
	
    default:
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] client initiated unknown connection type 0x%02hx (length %d) (closing connection)",virtconn_get_client_socket(vc),(unsigned short)connect_type,addlen);
	return -1;
    }
    
    /* now connect to the real server */
    if (psock_connect(virtconn_get_server_socket(vc),(struct sockaddr *)&servaddr,(psock_t_socklen)sizeof(servaddr))<0)
    {
	if (psock_errno()!=PSOCK_EINPROGRESS)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not connect to server (psock_connect: %s)\n",virtconn_get_client_socket(vc),pstrerror(psock_errno()));
	    return -1;
	}
	virtconn_set_state(vc,virtconn_state_connecting);
    }
    else
	virtconn_set_state(vc,virtconn_state_connected);
    
    {
	t_packet * packet;
	
	if (!(packet = packet_create(packet_class_raw)))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create packet",virtconn_get_client_socket(vc));
	    return -1;
	}
	packet_append_data(packet,&connect_type,1);
	queue_push_packet(virtconn_get_serverout_queue(vc),packet);
	packet_del_ref(packet);
    }
    
    return 0;
}
Ejemplo n.º 10
0
Archivo: irc.c Proyecto: 91D2/pvpgn
extern int irc_message_postformat(t_packet * packet, t_connection const * dest)
{
    int len;
    /* the four elements */
    char * e1;
    char * e1_2;
    char * e2;
    char * e3;
    char * e4;
    char const * tname = NULL;
    char const * toname = "AUTH"; /* fallback name */

    if (!packet) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return -1;
    }
    if (!dest) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL dest");
	return -1;
    }

    e1 = packet_get_raw_data(packet,0);
    e2 = strchr(e1,'\n');
    if (!e2) {
	eventlog(eventlog_level_warn,__FUNCTION__,"malformed message (e2 missing)");
	return -1;
    }
    *e2++ = '\0';
    e3 = strchr(e2,'\n');
    if (!e3) {
	eventlog(eventlog_level_warn,__FUNCTION__,"malformed message (e3 missing)");
	return -1;
    }
    *e3++ = '\0';
    e4 = strchr(e3,'\n');
    if (!e4) {
	eventlog(eventlog_level_warn,__FUNCTION__,"malformed message (e4 missing)");
	return -1;
    }
    *e4++ = '\0';

    if (prefs_get_hide_addr() && !(account_get_command_groups(conn_get_account(dest)) & command_get_group("/admin-addr")))
    {
      e1_2 = strchr(e1,'@');
      if (e1_2)
      {
	  *e1_2++ = '\0';
      }
    }
    else
    e1_2 = NULL;

    if (e3[0]=='\0') { /* fill in recipient */
    	if ((tname = conn_get_chatname(dest)))
    	    toname = tname;
    } else
    	toname = e3;

    if (strcmp(toname,"\r")==0) {
	toname = ""; /* HACK: the target field is really empty */
    }
    	
    len = (strlen(e1)+1+strlen(e2)+1+strlen(toname)+1+strlen(e4)+2+1);
    if (len<=MAX_IRC_MESSAGE_LEN) {
	char msg[MAX_IRC_MESSAGE_LEN+1];

	if (e1_2)
	    sprintf(msg,"%s@hidden %s %s %s\r\n",e1,e2,toname,e4);
	else
	    sprintf(msg,"%s %s %s %s\r\n",e1,e2,toname,e4);
	eventlog(eventlog_level_debug,__FUNCTION__,"sent \"%s\"",msg);
	packet_set_size(packet,0);
	packet_append_data(packet,msg,strlen(msg));
	if (tname)
	    conn_unget_chatname(dest,tname);
	return 0;
    } else {
	/* FIXME: split up message? */
    	eventlog(eventlog_level_warn,__FUNCTION__,"maximum IRC message length exceeded");
	if (tname)
	    conn_unget_chatname(dest,tname);
	return -1;
    }
}