diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/oscar/aim.h | 6 | ||||
| -rw-r--r-- | protocols/oscar/chat.c | 25 | ||||
| -rw-r--r-- | protocols/oscar/im.c | 26 | ||||
| -rw-r--r-- | protocols/oscar/oscar.c | 168 | ||||
| -rw-r--r-- | protocols/oscar/tlv.c | 25 | ||||
| -rw-r--r-- | protocols/proxy.c | 22 | ||||
| -rw-r--r-- | protocols/proxy.h | 2 | 
7 files changed, 220 insertions, 54 deletions
| diff --git a/protocols/oscar/aim.h b/protocols/oscar/aim.h index f7bf1a8e..24cd7730 100644 --- a/protocols/oscar/aim.h +++ b/protocols/oscar/aim.h @@ -465,6 +465,7 @@ int aim_addtlvtochain_availmsg(aim_tlvlist_t **list, const guint16 type, const c  int aim_addtlvtochain_raw(aim_tlvlist_t **list, const guint16 t, const guint16 l, const guint8 *v);  int aim_addtlvtochain_caps(aim_tlvlist_t **list, const guint16 t, const guint32 caps);  int aim_addtlvtochain_noval(aim_tlvlist_t **list, const guint16 type); +int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance);  int aim_addtlvtochain_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *ui);  int aim_addtlvtochain_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl);  int aim_counttlvchain(aim_tlvlist_t **list); @@ -571,6 +572,11 @@ struct aim_chat_roominfo {  	unsigned short instance;  }; +struct aim_chat_invitation { +	struct gaim_connection * gc; +	char * name; +	guint8 exchange; +};  #define AIM_VISIBILITYCHANGE_PERMITADD    0x05  #define AIM_VISIBILITYCHANGE_PERMITREMOVE 0x06 diff --git a/protocols/oscar/chat.c b/protocols/oscar/chat.c index 60aabc79..033c2577 100644 --- a/protocols/oscar/chat.c +++ b/protocols/oscar/chat.c @@ -183,31 +183,6 @@ int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const  	return 0;  } -static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) -{ -	guint8 *buf; -	int buflen; -	aim_bstream_t bs; - -	buflen = 2 + 1 + strlen(roomname) + 2; -	 -	if (!(buf = g_malloc(buflen))) -		return 0; - -	aim_bstream_init(&bs, buf, buflen); - -	aimbs_put16(&bs, exchange); -	aimbs_put8(&bs, strlen(roomname)); -	aimbs_putraw(&bs, (guint8 *)roomname, strlen(roomname)); -	aimbs_put16(&bs, instance); - -	aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf); - -	g_free(buf); - -	return 0; -} -  /*   * Join a room of name roomname.  This is the first step to joining an    * already created room.  It's basically a Service Request for  diff --git a/protocols/oscar/im.c b/protocols/oscar/im.c index 085687e0..c829d409 100644 --- a/protocols/oscar/im.c +++ b/protocols/oscar/im.c @@ -1368,6 +1368,30 @@ static int incomingim_ch1(aim_session_t *sess, aim_module_t *mod, aim_frame_t *r  	return ret;  } + +static void incomingim_ch2_chat_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args) +{ + +	/* XXX aim_chat_roominfo_free() */ +	g_free(args->info.chat.roominfo.name); + +	return; +} + +static void incomingim_ch2_chat(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata) +{ + +	/* +	 * Chat room info. +	 */ +	if (servdata) +		aim_chat_readroominfo(servdata, &args->info.chat.roominfo); + +	args->destructor = (void *)incomingim_ch2_chat_free; + +	return; +} +  static void incomingim_ch2_icqserverrelay_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)  { @@ -1616,6 +1640,8 @@ static int incomingim_ch2(aim_session_t *sess, aim_module_t *mod, aim_frame_t *r  	if (args.reqclass & AIM_CAPS_ICQSERVERRELAY)  		incomingim_ch2_icqserverrelay(sess, mod, rx, snac, userinfo, &args, sdbsptr); +	else if (args.reqclass & AIM_CAPS_CHAT) +		incomingim_ch2_chat(sess, mod, rx, snac, userinfo, &args, sdbsptr);  	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 76599d8c..240bab14 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -61,7 +61,7 @@  /* Don't know if support for UTF8 is really working. For now it's UTF16 here.     static int gaim_caps = AIM_CAPS_UTF8; */ -static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY; +static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY | AIM_CAPS_CHAT;  static guint8 gaim_features[] = {0x01, 0x01, 0x01, 0x02};  struct oscar_data { @@ -155,7 +155,6 @@ static char *extract_name(const char *name) {  	return tmp;  } -#if 0  static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int id) {  	GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;  	struct chat_connection *c = NULL; @@ -170,7 +169,7 @@ static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int i  	return c;  } -#endif +  static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc,  							aim_conn_t *conn) { @@ -1075,14 +1074,15 @@ static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_  	return 1;  } +void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv); +void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv); +	  static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) { -#if 0  	struct gaim_connection *gc = sess->aux_data; -#endif  	if (args->status != AIM_RENDEZVOUS_PROPOSE)  		return 1; -#if 0 +  	if (args->reqclass & AIM_CAPS_CHAT) {  		char *name = extract_name(args->info.chat.roominfo.name);  		int *exch = g_new0(int, 1); @@ -1090,15 +1090,23 @@ static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_  		m = g_list_append(m, g_strdup(name ? name : args->info.chat.roominfo.name));  		*exch = args->info.chat.roominfo.exchange;  		m = g_list_append(m, exch); -		serv_got_chat_invite(gc, -				     name ? name : args->info.chat.roominfo.name, -				     userinfo->sn, -				     (char *)args->msg, -				     m); + +		char txt[1024]; + +		g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", name, userinfo->sn, args->msg ); + +		struct aim_chat_invitation * inv = g_new0(struct aim_chat_invitation, 1); + +		inv->gc = gc; +		inv->exchange = *exch; +		inv->name = g_strdup(name); +		 +		do_ask_dialog( gc, txt, inv, oscar_accept_chat, oscar_reject_chat); +	  		if (name)  			g_free(name);  	} -#endif +  	return 1;  } @@ -2493,6 +2501,138 @@ int oscar_send_typing(struct gaim_connection *gc, char * who, int typing)  	return( aim_im_sendmtn(od->sess, 1, who, typing ? 0x0002 : 0x0000) );  } +int oscar_chat_send(struct gaim_connection * gc, int id, char *message) +{ +	struct oscar_data * od = (struct oscar_data*)gc->proto_data; +	struct chat_connection * ccon; +	 +	if(!(ccon = find_oscar_chat(gc, id))) +		return -1; +	 +	int ret; +	guint8 len = strlen(message); +	char *s; +	  	 +	for (s = message; *s; s++) +		if (*s & 128) +			break; +	  	 +	/* Message contains high ASCII chars, time for some translation! */ +	if (*s) { +		s = g_malloc(BUF_LONG); +		/* Try if we can put it in an ISO8859-1 string first. +		   If we can't, fall back to UTF16. */ +		if ((ret = do_iconv("UTF-8", "ISO8859-1", message, s, len, BUF_LONG)) >= 0) { +			len = ret; +		} else if ((ret = do_iconv("UTF-8", "UNICODEBIG", message, s, len, BUF_LONG)) >= 0) { +			len = ret; +		} else { +			/* OOF, translation failed... Oh well.. */ +			g_free( s ); +			s = message; +		} +	} else { +		s = message; +	} +	  	 +	ret = aim_chat_send_im(od->sess, ccon->conn, AIM_CHATFLAGS_NOREFLECT, s, len); +	  	 +	if (s != message) {	 +		g_free(s); +  } +   +  return (ret >= 0); +} + +void oscar_chat_invite(struct gaim_connection * gc, int id, char *message, char *who) +{ +	struct oscar_data * od = (struct oscar_data *)gc->proto_data; +	struct chat_connection *ccon = find_oscar_chat(gc, id); +	 +	if (ccon == NULL) +		return; +	 +	aim_chat_invite(od->sess, od->conn, who, message ? message : "", +					ccon->exchange, ccon->name, 0x0); +} + +void oscar_chat_kill(struct gaim_connection *gc, struct chat_connection *cc) +{ +	struct oscar_data *od = (struct oscar_data *)gc->proto_data; + +	/* Notify the conversation window that we've left the chat */ +	serv_got_chat_left(gc, cc->id); + +	/* Destroy the chat_connection */ +	od->oscar_chats = g_slist_remove(od->oscar_chats, cc); +	if (cc->inpa > 0) +		gaim_input_remove(cc->inpa); +	aim_conn_kill(od->sess, &cc->conn); +	g_free(cc->name); +	g_free(cc->show); +	g_free(cc); +} + +void oscar_chat_leave(struct gaim_connection * gc, int id) +{ +	struct chat_connection * ccon = find_oscar_chat(gc, id); + +	if(ccon == NULL) +		return; + +	oscar_chat_kill(gc, ccon); +} + +int oscar_chat_join(struct gaim_connection * gc, char * name) +{ +    struct oscar_data * od = (struct oscar_data *)gc->proto_data; +	 +	aim_conn_t * cur; + +	if((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) { +	 +		return (aim_chatnav_createroom(od->sess, cur, name, 4) == 0); +	 +	} else { +		struct create_room * cr = g_new0(struct create_room, 1); +		cr->exchange = 4; +		cr->name = g_strdup(name); +		od->create_rooms = g_slist_append(od->create_rooms, cr); +		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_CHATNAV); +		return 1; +	} +} + +int oscar_chat_open(struct gaim_connection * gc, char *who) +{ +	struct oscar_data * od = (struct oscar_data *)gc->proto_data; + +	static int chat_id = 0; +	char * chatname = g_new0(char, strlen(gc->username)+4); +	g_snprintf(chatname, strlen(gc->username) + 4, "%s%d", gc->username, chat_id++); +   +	int ret = oscar_chat_join(gc, chatname); + +	aim_chat_invite(od->sess, od->conn, who, "", 4, chatname, 0x0); + +	g_free(chatname); +	 +	return ret; +} + +void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv) +{ +	oscar_chat_join(inv->gc, inv->name); +	g_free(inv->name); +	g_free(inv); +} + +void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv) +{ +	g_free(inv->name); +	g_free(inv); +} +  static struct prpl *my_protocol = NULL;  void oscar_init(struct prpl *ret) { @@ -2506,6 +2646,10 @@ void oscar_init(struct prpl *ret) {  	ret->get_away = oscar_get_away;  	ret->add_buddy = oscar_add_buddy;  	ret->remove_buddy = oscar_remove_buddy; +	ret->chat_send = oscar_chat_send; +	ret->chat_invite = oscar_chat_invite; +	ret->chat_leave = oscar_chat_leave; +	ret->chat_open = oscar_chat_open;  	ret->add_permit = oscar_add_permit;  	ret->add_deny = oscar_add_deny;  	ret->rem_permit = oscar_rem_permit; diff --git a/protocols/oscar/tlv.c b/protocols/oscar/tlv.c index 11b89758..9d827caf 100644 --- a/protocols/oscar/tlv.c +++ b/protocols/oscar/tlv.c @@ -339,6 +339,31 @@ int aim_addtlvtochain_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvl  	return buflen;  } +int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) +{ +	guint8 *buf; +	int buflen; +	aim_bstream_t bs; + +	buflen = 2 + 1 + strlen(roomname) + 2; +	 +	if (!(buf = g_malloc(buflen))) +		return 0; + +	aim_bstream_init(&bs, buf, buflen); + +	aimbs_put16(&bs, exchange); +	aimbs_put8(&bs, strlen(roomname)); +	aimbs_putraw(&bs, (guint8 *)roomname, strlen(roomname)); +	aimbs_put16(&bs, instance); + +	aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf); + +	g_free(buf); + +	return 0; +} +  /**   * aim_writetlvchain - Write a TLV chain into a data buffer.   * @buf: Destination buffer diff --git a/protocols/proxy.c b/protocols/proxy.c index fb87e356..0546f2d7 100644 --- a/protocols/proxy.c +++ b/protocols/proxy.c @@ -49,16 +49,6 @@  #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)  #define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL) -/*FIXME*		 -	#ifndef _WIN32 -		if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { -			closesocket(fd); -			g_free(phb); -			return -1; -		} -		fcntl(fd, F_SETFL, 0); -#endif*/ -  char proxyhost[128] = "";  int proxyport = 0;  int proxytype = PROXY_NONE; @@ -82,7 +72,7 @@ typedef struct _GaimIOClosure { -static struct sockaddr_in *gaim_gethostbyname(char *host, int port) +static struct sockaddr_in *gaim_gethostbyname(const char *host, int port)  {  	static struct sockaddr_in sin; @@ -153,7 +143,7 @@ static void gaim_io_connected(gpointer data, gint source, GaimInputCondition con  	}  } -static int proxy_connect_none(char *host, unsigned short port, struct PHB *phb) +static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb)  {  	struct sockaddr_in *sin;  	int fd = -1; @@ -280,7 +270,7 @@ static void http_canwrite(gpointer data, gint source, GaimInputCondition cond)  	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb);  } -static int proxy_connect_http(char *host, unsigned short port, struct PHB *phb) +static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb)  {  	phb->host = g_strdup(host);  	phb->port = port; @@ -364,7 +354,7 @@ static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond)  	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb);  } -static int proxy_connect_socks4(char *host, unsigned short port, struct PHB *phb) +static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb)  {  	phb->host = g_strdup(host);  	phb->port = port; @@ -546,7 +536,7 @@ static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond)  	phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb);  } -static int proxy_connect_socks5(char *host, unsigned short port, struct PHB *phb) +static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb)  {  	phb->host = g_strdup(host);  	phb->port = port; @@ -587,7 +577,7 @@ void gaim_input_remove(gint tag)  		g_source_remove(tag);  } -int proxy_connect(char *host, int port, GaimInputFunction func, gpointer data) +int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data)  {  	struct PHB *phb; diff --git a/protocols/proxy.h b/protocols/proxy.h index 7c34fc40..47c966d2 100644 --- a/protocols/proxy.h +++ b/protocols/proxy.h @@ -55,6 +55,6 @@ typedef void (*GaimInputFunction)(gpointer, gint, GaimInputCondition);  G_MODULE_EXPORT gint gaim_input_add(int, GaimInputCondition, GaimInputFunction, gpointer);  G_MODULE_EXPORT void gaim_input_remove(gint); -G_MODULE_EXPORT int proxy_connect(char *host, int port, GaimInputFunction func, gpointer data); +G_MODULE_EXPORT int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data);  #endif /* _PROXY_H_ */ | 
