1 /*
2  * Copyright (C) 2007,2008,2009 Colin DIDIER
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 
18 #include "module.h"
19 #include "signals.h"
20 
21 #include "xmpp-servers.h"
22 #include "rosters-tools.h"
23 #include "tools.h"
24 
25 static void
sig_set_presence(XMPP_SERVER_REC * server,const int show,const char * status,const int priority)26 sig_set_presence(XMPP_SERVER_REC *server, const int show, const char *status,
27     const int priority)
28 {
29 	LmMessage *lmsg;
30 	char *str;
31 
32 	g_return_if_fail(IS_XMPP_SERVER(server));
33 	if (!xmpp_presence_changed(show, server->show, status,
34 	    server->away_reason, priority, server->priority)) {
35 		signal_stop();
36 		return;
37 	}
38 	server->show = show;
39 	g_free(server->away_reason);
40 	server->away_reason = g_strdup(status);
41 	if (!xmpp_priority_out_of_bound(priority))
42 		server->priority = priority;
43 	lmsg = lm_message_new(NULL, LM_MESSAGE_TYPE_PRESENCE);
44 	if (show != XMPP_PRESENCE_AVAILABLE)
45 		lm_message_node_add_child(lmsg->node, "show",
46 		    xmpp_presence_show[server->show]);
47 	if (status != NULL) {
48 		str = xmpp_recode_out(server->away_reason);
49 		lm_message_node_add_child(lmsg->node, "status", str);
50 		g_free(str);
51 	}
52 	str = g_strdup_printf("%d", server->priority);
53 	lm_message_node_add_child(lmsg->node, "priority", str);
54 	g_free(str);
55 	signal_emit("xmpp send presence", 2, server, lmsg);
56 	lm_message_unref(lmsg);
57 	if (show != XMPP_PRESENCE_AVAILABLE) /* away */
58 		signal_emit("event 306", 2, server, server->jid);
59 	else if (server->usermode_away) /* unaway */
60 		signal_emit("event 305", 2, server, server->jid);
61 }
62 
63 static void
sig_recv_message(XMPP_SERVER_REC * server,LmMessage * lmsg,const int type,const char * id,const char * from,const char * to)64 sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type,
65     const char *id, const char *from, const char *to)
66 {
67 	LmMessageNode *node;
68 	char *str, *subject;
69 
70 	if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET
71 	    && type != LM_MESSAGE_SUB_TYPE_HEADLINE
72 	    && type != LM_MESSAGE_SUB_TYPE_NORMAL
73 	    && type != LM_MESSAGE_SUB_TYPE_CHAT)
74 	    || server->ischannel(SERVER(server), from))
75 		return;
76 	node = lm_message_node_get_child(lmsg->node, "subject");
77 	if (node != NULL && node->value != NULL && *node->value != '\0') {
78 		str = xmpp_recode_in(node->value);
79 		subject = g_strconcat("Subject: ", str, (void *)NULL);
80 		g_free(str);
81 		signal_emit("message private", 4, server, subject, from, from);
82 		g_free(subject);
83 	}
84 	node = lm_message_node_get_child(lmsg->node, "body");
85 	if (node != NULL && node->value != NULL && *node->value != '\0') {
86 		str = xmpp_recode_in(node->value);
87 		if (g_ascii_strncasecmp(str, "/me ", 4) == 0)
88 			signal_emit("message xmpp action", 5,
89 			    server, str+4, from, from,
90 			    GINT_TO_POINTER(SEND_TARGET_NICK));
91 		else
92 			signal_emit("message private", 4, server,
93 			    str, from, from);
94 		g_free(str);
95 	}
96 }
97 
98 void
protocol_init(void)99 protocol_init(void)
100 {
101 	signal_add_first("xmpp set presence", sig_set_presence);
102 	signal_add("xmpp recv message", sig_recv_message);
103 }
104 
105 void
protocol_deinit(void)106 protocol_deinit(void)
107 {
108 	signal_remove("xmpp set presence", sig_set_presence);
109 	signal_remove("xmpp recv message", sig_recv_message);
110 }
111