sendmsg.c
资源名称:micq.tgz [点击查看]
上传用户:ai20ln
上传日期:2007-01-05
资源大小:79k
文件大小:26k
源码类别:
ICQ/即时通讯
开发平台:
Unix_Linux
- /*
- Send Message Function for ICQ...
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Author : zed@mentasm.com
- */
- #include "datatype.h"
- #include "micq.h"
- #include "msg_queue.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #ifdef _WIN32
- #include <winsock2.h>
- #else
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #endif
- #include <string.h>
- #include <assert.h>
- #include <limits.h>
- /*unsigned int next_resend;*/
- static size_t SOCKWRITE_LOW( SOK_T sok, void * ptr, size_t len );
- /* Historical */
- void Initialize_Msg_Queue()
- {
- msg_queue_init();
- }
- /****************************************************************
- Checks if packets are waiting to be resent and sends them.
- *****************************************************************/
- void Do_Resend( SOK_T sok )
- {
- struct msg *queued_msg;
- SIMPLE_MESSAGE_PTR s_mesg;
- DWORD type;
- char *data;
- char *tmp;
- char *temp;
- char url_desc[1024], url_data[1024];
- net_icq_pak pak;
- if ((queued_msg = msg_queue_pop()) != NULL)
- {
- queued_msg->attempts++;
- if (queued_msg->attempts <= 6)
- {
- if ( Verbose )
- {
- M_print( "nResending message with SEQ num %04x.tCMD ", queued_msg->seq );
- Print_CMD( Chars_2_Word( &queued_msg->body[6] ) );
- M_print( "(Attempt #%d.)n", queued_msg->attempts);
- Prompt();
- }
- if ( 0x1000 < Chars_2_Word( &queued_msg->body[6] ) ) {
- Dump_Queue();
- }
- temp = malloc( queued_msg->len );
- memcpy( temp, queued_msg->body, queued_msg->len);
- SOCKWRITE_LOW(sok, temp, queued_msg->len);
- free(temp);
- queued_msg->exp_time = time(NULL) + 10;
- msg_queue_push( queued_msg );
- }
- else
- {
- memcpy(&pak.head.ver, queued_msg->body, queued_msg->len);
- if ( CMD_SENDM == Chars_2_Word( pak.head.cmd ) ) {
- s_mesg = ( SIMPLE_MESSAGE_PTR ) pak.data;
- M_print("nDiscarding message to ");
- Print_UIN_Name( Chars_2_DW( s_mesg->uin ) );
- M_print(" after %d send attempts. Message content:n",
- queued_msg->attempts - 1);
- type = Chars_2_Word(s_mesg->type);
- data = s_mesg->len + 2;
- if (type == URL_MESS || type == MRURL_MESS)
- {
- tmp = strchr( data, 'xFE' );
- if ( tmp != NULL )
- {
- *tmp = 0;
- rus_conv("wk", data);
- strcpy(url_desc, data);
- tmp++;
- data = tmp;
- rus_conv("wk", data);
- strcpy(url_data, data);
- M_print( " Description: " MESSCOL "%s"
- NOCOL "n", url_desc );
- M_print( " URL : " MESSCOL "%s" NOCOL "n",
- url_data );
- }
- }
- else if (type == NORM_MESS || type == MRNORM_MESS)
- {
- rus_conv("wk", data);
- M_print( MESSCOL "%s", data );
- M_print( NOCOL "n" );
- }
- } else {
- M_print( "nDiscarded a " );
- Print_CMD( Chars_2_Word( pak.head.cmd ) );
- M_print( " packet.n" );
- if ( ( CMD_LOGIN == Chars_2_Word( pak.head.cmd ) ) ||
- ( CMD_KEEP_ALIVE == Chars_2_Word( pak.head.cmd ) ) ) {
- M_print( "aConnection unstable exiting....n" );
- Quit = TRUE;
- }
- }
- Prompt();
- free(queued_msg->body);
- free(queued_msg);
- }
- if ( (queued_msg = msg_queue_peek() ) != NULL )
- {
- next_resend = queued_msg->exp_time;
- }
- else
- {
- next_resend = INT_MAX;
- }
- }
- else
- {
- next_resend = INT_MAX;
- }
- }
- /*********************************
- This must be called to remove messages
- from the server
- **********************************/
- void snd_got_messages( int sok )
- {
- net_icq_pak pak;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_ACK_MESSAGES );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- last_cmd[ (seq_num - 1) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), sizeof( pak.head ) - 2 );
- }
- /*************************************
- this sends over the contact list
- **************************************/
- void snd_contact_list( int sok )
- {
- net_icq_pak pak;
- int num_used;
- int i, size;
- char *tmp;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_CONT_LIST );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- tmp = pak.data;
- tmp++;
- for ( i=0, num_used=0; i < Num_Contacts ; i++ )
- {
- if ( (S_DWORD) Contacts[ i ].uin > 0 )
- {
- DW_2_Chars( tmp, Contacts[i].uin );
- tmp+=4;
- num_used++;
- }
- }
- pak.data[0] = num_used;
- /* Word_2_Chars( pak.data, num_used ); */
- size = sizeof( DWORD ) * num_used + 1;
- size += sizeof( pak.head ) - 2;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size );
- }
- /*************************************
- this sends over the Invisible list
- that allows certain users to see you
- if you're invisible.
- **************************************/
- void snd_invis_list( int sok )
- {
- net_icq_pak pak;
- int num_used;
- int i, size;
- char *tmp;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_INVIS_LIST );
- Word_2_Chars( pak.head.seq, seq_num );
- DW_2_Chars( pak.head.UIN, UIN );
- tmp = pak.data;
- tmp++;
- for ( i=0, num_used=0; i < Num_Contacts ; i++ )
- {
- if ( (S_DWORD) Contacts[ i ].uin > 0 )
- {
- if ( Contacts[i].invis_list )
- {
- DW_2_Chars( tmp, Contacts[i].uin );
- tmp+=4;
- num_used++;
- }
- }
- }
- if ( num_used != 0 )
- {
- pak.data[0] = num_used;
- size = ( ( int ) tmp - ( int ) pak.data );
- size += sizeof( pak.head ) - 2;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size );
- seq_num++;
- }
- }
- /*************************************
- this sends over the Visible list
- that allows certain users to see you
- if you're invisible.
- **************************************/
- void snd_vis_list( int sok )
- {
- net_icq_pak pak;
- int num_used;
- int i, size;
- char *tmp;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_VIS_LIST );
- Word_2_Chars( pak.head.seq, seq_num );
- DW_2_Chars( pak.head.UIN, UIN );
- tmp = pak.data;
- tmp++;
- for ( i=0, num_used=0; i < Num_Contacts ; i++ )
- {
- if ( (S_DWORD) Contacts[ i ].uin > 0 )
- {
- if ( Contacts[i].vis_list )
- {
- DW_2_Chars( tmp, Contacts[i].uin );
- tmp+=4;
- num_used++;
- }
- }
- }
- if ( num_used != 0 )
- {
- pak.data[0] = num_used;
- size = ( ( int ) tmp - ( int ) pak.data );
- size += sizeof( pak.head ) - 2;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size );
- seq_num++;
- }
- }
- /**************************************
- This sends the second login command
- this is necessary to finish logging in.
- ***************************************/
- void snd_login_1( int sok )
- {
- net_icq_pak pak;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_LOGIN_1 );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), sizeof( pak.head ) - 2 );
- }
- /*********************************
- This must be called every 2 min.
- so the server knows we're still alive.
- JAVA client sends two different commands
- so we do also :)
- **********************************/
- void Keep_Alive( int sok )
- {
- net_icq_pak pak;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_KEEP_ALIVE );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- last_cmd[(seq_num - 1) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), sizeof( pak.head ) - 2 );
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_KEEP_ALIVE2 );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- last_cmd[(seq_num - 1) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), sizeof( pak.head ) - 2 );
- if ( Verbose )
- {
- #ifdef FUNNY_MSGS
- M_print( "nIf you go to" MESSCOL " Z'Ha'Dum " NOCOL "you will die!!!!n" );
- /* or if you don't send this packet */
- #else
- M_print( "nSend Keep_Alive packet to the servern" );
- #endif
- }
- }
- /********************************************************
- The following data constitutes fair use for compatibility.
- *********************************************************/
- unsigned char icq_check_data[257] = {
- 0x0a, 0x5b, 0x31, 0x5d, 0x20, 0x59, 0x6f, 0x75,
- 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x6f, 0x64,
- 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x49,
- 0x43, 0x51, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73,
- 0x2e, 0x20, 0x4a, 0x75, 0x73, 0x74, 0x20, 0x73,
- 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x22, 0x53,
- 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x20, 0x66,
- 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x22, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65,
- 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x6d, 0x69, 0x73,
- 0x63, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x43,
- 0x51, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x72, 0x6f,
- 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x53,
- 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x20, 0x69,
- 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
- 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x70, 0x61,
- 0x6e, 0x65, 0x6c, 0x2e, 0x20, 0x43, 0x72, 0x65,
- 0x64, 0x69, 0x74, 0x3a, 0x20, 0x45, 0x72, 0x61,
- 0x6e, 0x0a, 0x5b, 0x32, 0x5d, 0x20, 0x43, 0x61,
- 0x6e, 0x27, 0x74, 0x20, 0x72, 0x65, 0x6d, 0x65,
- 0x6d, 0x62, 0x65, 0x72, 0x20, 0x77, 0x68, 0x61,
- 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x73, 0x61,
- 0x69, 0x64, 0x3f, 0x20, 0x20, 0x44, 0x6f, 0x75,
- 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6c, 0x69, 0x63,
- 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x75,
- 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x67,
- 0x65, 0x74, 0x20, 0x61, 0x20, 0x64, 0x69, 0x61,
- 0x6c, 0x6f, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x61,
- 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
- 0x67, 0x65, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74,
- 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0
- };
- /***************************************************
- Sends a message thru the server to uin. Text is the
- message to send.
- ****************************************************/
- void icq_sendmsg( SOK_T sok, DWORD uin, char *text, DWORD msg_type)
- {
- SIMPLE_MESSAGE msg;
- net_icq_pak pak;
- int size, len;
- log_event("You sent instant message",text,uin);
- rus_conv ("kw",text);
- len = strlen(text);
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_SENDM );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( msg.uin, uin );
- Word_2_Chars(msg.type, msg_type);
- Word_2_Chars( msg.len, len + 1 ); /* length + the NULL */
- memcpy(&pak.data, &msg, sizeof( msg ) );
- memcpy(&pak.data[8], text, len + 1);
- size = sizeof( msg ) + len + 1;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /**************************************************
- Sends a authorixation to the server so the Mirabilis
- client can add the user.
- ***************************************************/
- void icq_sendauthmsg( SOK_T sok, DWORD uin)
- {
- SIMPLE_MESSAGE msg;
- net_icq_pak pak;
- int size;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_SENDM );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( msg.uin, uin );
- DW_2_Chars( msg.type, AUTH_MESSAGE ); /* A type authorization msg*/
- Word_2_Chars( msg.len, 2 );
- memcpy(&pak.data, &msg, sizeof( msg ) );
- pak.data[ sizeof(msg) ]=0x03;
- pak.data[ sizeof(msg) + 1]=0x00;
- size = sizeof( msg ) + 2;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /***************************************************
- Requests a random user from the specified group.
- ****************************************************/
- void icq_rand_user_req( SOK_T sok, DWORD group )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_RAND_SEARCH );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( pak.data, group);
- size = 4;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /***************************************************
- Sets our Random chat group
- ****************************************************/
- void icq_rand_set( SOK_T sok, DWORD group )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_RAND_SET );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( pak.data, group);
- size = 4;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /***************************************************
- Changes the users status on the server
- ****************************************************/
- void icq_change_status( SOK_T sok, DWORD status )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_STATUS_CHANGE );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( pak.data, status);
- Current_Status = status;
- size = 4;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /******************************************************************
- Logs off ICQ should handle other cleanup as well
- ********************************************************************/
- void Quit_ICQ( int sok )
- {
- net_icq_pak pak;
- int size, len;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_SEND_TEXT_CODE );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- len = strlen( "B_USER_DISCONNECTED" ) + 1;
- *(short * ) pak.data = len;
- size = len + 4;
- memcpy( &pak.data[2], "B_USER_DISCONNECTED", len );
- pak.data[ 2 + len ] = 05;
- pak.data[ 3 + len ] = 00;
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- SOCKCLOSE(sok);
- SOCKCLOSE( sok );
- }
- void info_req_99( SOK_T sok, DWORD uin )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_META_USER );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- #if ICQ_VER == 0x0002
- Word_2_Chars( pak.data , seq_num );
- DW_2_Chars( pak.data + 2, uin );
- size = 6;
- #else
- Word_2_Chars( pak.data , META_INFO_REQ );
- DW_2_Chars( pak.data + 2, uin );
- size = 6;
- #endif
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /*********************************************************
- Sends a request to the server for info on a specific user
- **********************************************************/
- void send_info_req( SOK_T sok, DWORD uin )
- {
- net_icq_pak pak;
- int size ;
- #if 1
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_INFO_REQ );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- #if ICQ_VER == 0x0002
- Word_2_Chars( pak.data , seq_num );
- DW_2_Chars( pak.data + 2, uin );
- size = 6;
- #else
- DW_2_Chars( pak.data, uin );
- size = 4;
- #endif
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- #endif
- }
- /*********************************************************
- Sends a request to the server for info on a specific user
- **********************************************************/
- void send_ext_info_req( SOK_T sok, DWORD uin )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_EXT_INFO_REQ );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- #if ICQ_VER == 0x0002
- Word_2_Chars( pak.data , seq_num );
- DW_2_Chars( pak.data + 2, uin );
- size = 6;
- #else
- DW_2_Chars( pak.data , uin );
- size = 4;
- #endif
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /***************************************************************
- Initializes a server search for the information specified
- ****************************************************************/
- void start_search( SOK_T sok, char *email, char *nick, char* first, char* last )
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_SEARCH_USER );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- /*
- Word_2_Chars( pak.data , seq_num++ );
- size = 2;
- */
- size = 0;
- Word_2_Chars( pak.data + size, strlen( nick ) + 1 );
- size += 2;
- strcpy( pak.data + size , nick );
- size += strlen( nick ) + 1;
- Word_2_Chars( pak.data + size, strlen( first ) + 1 );
- size += 2;
- strcpy( pak.data + size , first );
- size += strlen( first ) + 1;
- Word_2_Chars( pak.data + size, strlen( last ) + 1);
- size += 2;
- strcpy( pak.data + size , last );
- size += strlen( last ) +1 ;
- Word_2_Chars( pak.data + size, strlen( email ) + 1 );
- size += 2;
- strcpy( pak.data + size , email );
- size += strlen( email ) + 1;
- last_cmd[seq_num - 2 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- /***************************************************
- Registers a new UIN in the ICQ network
- ****************************************************/
- void reg_new_user( SOK_T sok, char *pass)
- {
- #if ICQ_VER == 0x0002
- srv_net_icq_pak pak;
- #else
- net_icq_pak pak;
- #endif
- char len_buf[2];
- int size, len;
- len = strlen(pass);
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_REG_NEW_USER );
- Word_2_Chars( pak.head.seq, seq_num++ );
- #if ICQ_VER != 0x0002
- Word_2_Chars( pak.head.seq2, seq_num-1 );
- #endif
- Word_2_Chars( len_buf, len );
- #if ICQ_VER == 0x0002
- memcpy(&pak.data, "x02x00", 2 );
- memcpy(&pak.data[2], len_buf, 2 );
- memcpy(&pak.data[4], pass, len + 1);
- DW_2_Chars( &pak.data[4+len], 0x0072 );
- DW_2_Chars( &pak.data[8+len], 0x0000 );
- size = len + 12;
- #else
- /* memcpy(&pak.data, "x02x00", 2 );*/
- memcpy(&pak.data[0], len_buf, 2 );
- memcpy(&pak.data[2], pass, len + 1);
- DW_2_Chars( &pak.data[2+len], 0xA0 );
- DW_2_Chars( &pak.data[6+len], 0x2461 );
- DW_2_Chars( &pak.data[10+len], 0xa00000 );
- DW_2_Chars( &pak.data[14+len], 0x00 );
- size = len + 18;
- #endif
- last_cmd[seq_num - 1 ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE_LOW( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- void Update_User_Info( SOK_T sok, USER_INFO_PTR user)
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_UPDATE_INFO );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- #if ICQ_VER == 0x0002
- Word_2_Chars( pak.data , seq_num++ );
- size = 2;
- #else
- size = 0;
- #endif
- Word_2_Chars( pak.data + size, strlen( user->nick ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->nick );
- size += strlen( user->nick ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->first ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->first );
- size += strlen( user->first ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->last ) + 1);
- size += 2;
- strcpy( pak.data + size , user->last );
- size += strlen( user->last ) +1 ;
- Word_2_Chars( pak.data + size, strlen( user->email ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->email );
- size += strlen( user->email ) + 1;
- pak.data[ size ] = user->auth;
- size++;
- last_cmd[ ( seq_num - 1 ) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_AUTH_UPDATE );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- DW_2_Chars( pak.data, ! user->auth );
- last_cmd[ ( seq_num - 1 ) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), 4 + sizeof( pak.head ) - 2);
- }
- void Update_More_User_Info( SOK_T sok, MORE_INFO_PTR user)
- {
- net_icq_pak pak;
- int size ;
- Word_2_Chars( pak.head.ver, ICQ_VER );
- Word_2_Chars( pak.head.cmd, CMD_META_USER );
- Word_2_Chars( pak.head.seq, seq_num++ );
- DW_2_Chars( pak.head.UIN, UIN );
- Word_2_Chars( pak.data , META_INFO_SET );
- size = 2;
- Word_2_Chars( pak.data + size, strlen( user->nick ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->nick );
- size += strlen( user->nick ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->first ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->first );
- size += strlen( user->first ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->last ) + 1);
- size += 2;
- strcpy( pak.data + size , user->last );
- size += strlen( user->last ) +1 ;
- Word_2_Chars( pak.data + size, strlen( user->email ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->email );
- size += strlen( user->email ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->email2 ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->email2 );
- size += strlen( user->email2 ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->email3 ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->email3 );
- size += strlen( user->email3 ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->city ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->city );
- size += strlen( user->city ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->state ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->state );
- size += strlen( user->state ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->phone ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->phone );
- size += strlen( user->phone ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->fax ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->fax );
- size += strlen( user->fax ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->street ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->street );
- size += strlen( user->street ) + 1;
- Word_2_Chars( pak.data + size, strlen( user->cellular ) + 1 );
- size += 2;
- strcpy( pak.data + size , user->cellular );
- size += strlen( user->cellular ) + 1;
- DW_2_Chars( &pak.data[ size ] , user->zip );
- size += 4;
- Word_2_Chars( &pak.data[ size ] , user->country );
- size += 2;
- pak.data[ size ++ ] = user->c_status;
- pak.data[ size ] = user->hide_email;
- size++;
- last_cmd[ ( seq_num - 1 ) & 0x3ff ] = Chars_2_Word( pak.head.cmd );
- SOCKWRITE( sok, &(pak.head.ver), size + sizeof( pak.head ) - 2);
- }
- void icq_sendurl( SOK_T sok, DWORD uin, char *description, char *url )
- {
- char buf[450];
- sprintf( buf, "%sxFE%s", url, description );
- icq_sendmsg( sok, uin, buf, URL_MESS );
- }
- void Wrinkle( void * ptr, size_t len )
- {
- static BOOL before = FALSE;
- BYTE *buf;
- DWORD chksum;
- DWORD key;
- DWORD tkey, temp;
- BYTE r1,r2;
- int n, pos;
- DWORD chk1,chk2;
- buf = ptr;
- if ( ! before ) {
- srand( time( NULL ) );
- }
- buf[2] = rand() & 0xff ;
- buf[3] = rand() & 0xff ;
- buf[4] = 0;
- buf[5] = 0;
- r1 = rand() % ( len - 4 );
- r2 = rand() & 0xff;
- chk1 = (BYTE) buf[8];
- chk1 <<= 8;
- chk1 += (BYTE) buf[4];
- chk1 <<= 8;
- chk1 += (BYTE) buf[2];
- chk1 <<= 8;
- chk1 += (BYTE) buf[6];
- chk2 = r1;
- chk2 <<= 8;
- chk2 +=(BYTE) ( buf[ r1 ] );
- chk2 <<= 8;
- chk2 += r2;
- chk2 <<= 8;
- chk2 +=(BYTE) ( icq_check_data[ r2 ] );
- chk2 ^= 0x00ff00ff;
- chksum = chk2 ^ chk1;
- DW_2_Chars( &buf[ 0x10 ], chksum );
- key = len;
- key *= 0x66756B65;
- key += chksum;
- n = ( len + 3 ) / 4;
- pos = 0;
- while ( pos < n )
- {
- if ( pos != 0x10 )
- {
- tkey = key + icq_check_data[ pos & 0xff ];
- temp = Chars_2_DW( &buf[ pos ] );
- temp ^= tkey;
- DW_2_Chars( &buf[ pos ], temp );
- }
- pos += 4;
- }
- Word_2_Chars( &buf[0], ICQ_VER );
- }
- /***************************************************************
- This handles actually sending a packet after it's been assembled.
- When V5 is implemented this will wrinkle the packet and calculate
- the checkcode.
- Adds packet to the queued messages.
- ****************************************************************/
- size_t SOCKWRITE( SOK_T sok, void * ptr, size_t len )
- {
- struct msg *msg_to_queue;
- WORD cmd;
- Word_2_Chars( &((BYTE *)ptr)[4], 0 );
- ((BYTE *)ptr)[0x0A] = ((BYTE *) ptr)[8];
- ((BYTE *)ptr)[0x0B] = ((BYTE *) ptr)[9];
- cmd = Chars_2_Word( (((ICQ_PAK_PTR)((BYTE*)ptr-2))->cmd ) );
- if ( cmd != CMD_ACK ) {
- msg_to_queue = (struct msg *) malloc(sizeof(struct msg));
- msg_to_queue->seq = Chars_2_Word( &((BYTE *)ptr)[0x0A] );
- msg_to_queue->attempts = 1;
- msg_to_queue->exp_time = time(NULL) + 10;
- msg_to_queue->body = (char *) malloc( len );
- msg_to_queue->len = len;
- memcpy(msg_to_queue->body, ptr, msg_to_queue->len);
- msg_queue_push( msg_to_queue );
- if (msg_queue_peek() == msg_to_queue)
- {
- next_resend = msg_to_queue->exp_time;
- }
- }
- return SOCKWRITE_LOW( sok, ptr, len );
- }
- /***************************************************************
- This handles actually sending a packet after it's been assembled.
- When V5 is implemented this will wrinkle the packet and calculate
- the checkcode.
- Doesn't add packet to the queue.
- ****************************************************************/
- static size_t SOCKWRITE_LOW( SOK_T sok, void * ptr, size_t len )
- {
- #if 1
- if ( Verbose > 1 )
- Hex_Dump( ptr, len );
- #endif
- Wrinkle( ptr, len );
- #if 0
- if ( Verbose > 1 )
- Hex_Dump( ptr, len );
- #endif
- return sockwrite( sok, ptr, len );
- }
- size_t SOCKREAD( SOK_T sok, void * ptr, size_t len )
- {
- size_t sz;
- sz = sockread( sok, ptr, len );
- if ( ( Verbose > 2 ) && ( sz > 0 ) )
- Hex_Dump( ptr, sz );
- return sz;
- }