7014
|
1 /*
|
|
2 * gaim - Jabber Protocol Plugin
|
|
3 *
|
|
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
|
|
5 *
|
|
6 * This program is free software; you can redistribute it and/or modify
|
|
7 * it under the terms of the GNU General Public License as published by
|
|
8 * the Free Software Foundation; either version 2 of the License, or
|
|
9 * (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 */
|
|
21 #include "internal.h"
|
|
22 #include "debug.h"
|
|
23 #include "prefs.h"
|
|
24
|
|
25 #include "iq.h"
|
|
26 #include "roster.h"
|
|
27
|
|
28
|
|
29 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
|
|
30 {
|
|
31 JabberIq *iq;
|
|
32
|
|
33 iq = g_new0(JabberIq, 1);
|
|
34
|
|
35 iq->type = type;
|
|
36
|
|
37 iq->node = xmlnode_new("iq");
|
|
38 switch(iq->type) {
|
|
39 case JABBER_IQ_SET:
|
|
40 xmlnode_set_attrib(iq->node, "type", "set");
|
|
41 break;
|
|
42 case JABBER_IQ_GET:
|
|
43 xmlnode_set_attrib(iq->node, "type", "get");
|
|
44 break;
|
|
45 case JABBER_IQ_ERROR:
|
|
46 xmlnode_set_attrib(iq->node, "type", "error");
|
|
47 break;
|
|
48 case JABBER_IQ_RESULT:
|
|
49 xmlnode_set_attrib(iq->node, "type", "result");
|
|
50 break;
|
|
51 case JABBER_IQ_NONE:
|
|
52 /* this shouldn't ever happen */
|
|
53 break;
|
|
54 }
|
|
55
|
|
56 iq->js = js;
|
|
57
|
|
58 if(type == JABBER_IQ_GET || type == JABBER_IQ_SET) {
|
|
59 iq->id = jabber_get_next_id(js);
|
|
60 xmlnode_set_attrib(iq->node, "id", iq->id);
|
|
61 }
|
|
62
|
|
63 return iq;
|
|
64 }
|
|
65
|
|
66 JabberIq *jabber_iq_new_query(JabberStream *js, JabberIqType type,
|
|
67 const char *xmlns)
|
|
68 {
|
|
69 JabberIq *iq = jabber_iq_new(js, type);
|
|
70 xmlnode *query;
|
|
71
|
|
72 query = xmlnode_new_child(iq->node, "query");
|
|
73 xmlnode_set_attrib(query, "xmlns", xmlns);
|
|
74
|
|
75 return iq;
|
|
76 }
|
|
77
|
|
78 void jabber_iq_set_callback(JabberIq *iq, JabberCallback *callback)
|
|
79 {
|
|
80 iq->callback = callback;
|
|
81 }
|
|
82
|
|
83 void jabber_iq_set_id(JabberIq *iq, const char *id)
|
|
84 {
|
|
85 if(iq->id)
|
|
86 g_free(iq->id);
|
|
87
|
|
88 if(id) {
|
|
89 xmlnode_set_attrib(iq->node, "id", id);
|
|
90 iq->id = g_strdup(id);
|
|
91 } else {
|
|
92 xmlnode_remove_attrib(iq->node, "id");
|
|
93 iq->id = NULL;
|
|
94 }
|
|
95 }
|
|
96
|
|
97 void jabber_iq_send(JabberIq *iq)
|
|
98 {
|
|
99 g_return_if_fail(iq != NULL);
|
|
100
|
|
101 jabber_send(iq->js, iq->node);
|
|
102
|
|
103 if(iq->id && iq->callback)
|
|
104 g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), iq->callback);
|
|
105
|
|
106 jabber_iq_free(iq);
|
|
107 }
|
|
108
|
|
109 void jabber_iq_free(JabberIq *iq)
|
|
110 {
|
|
111 g_return_if_fail(iq != NULL);
|
|
112
|
|
113 g_free(iq->id);
|
|
114 xmlnode_free(iq->node);
|
|
115 g_free(iq);
|
|
116 }
|
|
117
|
|
118 static void jabber_iq_handle_last(JabberStream *js, xmlnode *packet)
|
|
119 {
|
|
120 JabberIq *iq;
|
|
121 const char *from;
|
|
122 const char *id;
|
|
123 xmlnode *query;
|
|
124 char *idle_time;
|
|
125
|
|
126 from = xmlnode_get_attrib(packet, "from");
|
|
127 id = xmlnode_get_attrib(packet, "id");
|
|
128
|
|
129 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:last");
|
|
130 jabber_iq_set_id(iq, id);
|
|
131 xmlnode_set_attrib(iq->node, "to", from);
|
|
132
|
|
133 query = xmlnode_get_child(iq->node, "query");
|
|
134
|
|
135 idle_time = g_strdup_printf("%ld", js->idle ? time(NULL) - js->idle : 0);
|
|
136 xmlnode_set_attrib(query, "seconds", idle_time);
|
|
137 g_free(idle_time);
|
|
138 }
|
|
139
|
|
140 static void jabber_iq_handle_time(JabberStream *js, xmlnode *packet)
|
|
141 {
|
|
142 const char *from, *id;
|
|
143 JabberIq *iq;
|
|
144 char buf[1024];
|
|
145 xmlnode *query;
|
|
146 time_t now_t;
|
|
147 struct tm now;
|
|
148 time(&now_t);
|
|
149 localtime_r(&now_t, &now);
|
|
150
|
|
151 from = xmlnode_get_attrib(packet, "from");
|
|
152 id = xmlnode_get_attrib(packet, "id");
|
|
153
|
|
154 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time");
|
|
155 jabber_iq_set_id(iq, id);
|
|
156 xmlnode_set_attrib(iq->node, "to", from);
|
|
157
|
|
158 query = xmlnode_get_child(iq->node, "query");
|
|
159
|
|
160 strftime(buf, sizeof(buf), "%Y%m%dT%T", &now);
|
|
161 xmlnode_insert_data(xmlnode_new_child(query, "utc"), buf, -1);
|
|
162 strftime(buf, sizeof(buf), "%Z", &now);
|
|
163 xmlnode_insert_data(xmlnode_new_child(query, "tz"), buf, -1);
|
|
164 strftime(buf, sizeof(buf), "%d %b %Y %T", &now);
|
|
165 xmlnode_insert_data(xmlnode_new_child(query, "display"), buf, -1);
|
|
166
|
|
167 jabber_iq_send(iq);
|
|
168 }
|
|
169
|
|
170 static void jabber_iq_handle_version(JabberStream *js, xmlnode *packet)
|
|
171 {
|
|
172 JabberIq *iq;
|
|
173 const char *from, *id;
|
|
174 xmlnode *query;
|
|
175 char *os = NULL;
|
|
176
|
|
177 if(!gaim_prefs_get_bool("/plugins/prpl/jabber/hide_os")) {
|
|
178 struct utsname osinfo;
|
|
179
|
|
180 uname(&osinfo);
|
|
181 os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
|
|
182 osinfo.machine);
|
|
183 }
|
|
184
|
|
185 from = xmlnode_get_attrib(packet, "from");
|
|
186 id = xmlnode_get_attrib(packet, "id");
|
|
187
|
|
188 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
|
|
189 xmlnode_set_attrib(iq->node, "to", from);
|
|
190 jabber_iq_set_id(iq, id);
|
|
191
|
|
192 query = xmlnode_get_child(iq->node, "query");
|
|
193
|
|
194 xmlnode_insert_data(xmlnode_new_child(query, "name"), PACKAGE, -1);
|
|
195 xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1);
|
|
196 if(os) {
|
|
197 xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1);
|
|
198 g_free(os);
|
|
199 }
|
|
200
|
|
201 jabber_iq_send(iq);
|
|
202 }
|
|
203
|
|
204 void jabber_iq_parse(JabberStream *js, xmlnode *packet)
|
|
205 {
|
|
206 xmlnode *query;
|
|
207 const char *xmlns;
|
|
208
|
|
209 query = xmlnode_get_child(packet, "query");
|
|
210
|
|
211 if(!query)
|
|
212 return;
|
|
213
|
|
214 xmlns = xmlnode_get_attrib(query, "xmlns");
|
|
215
|
|
216 if(!xmlns)
|
|
217 return;
|
|
218
|
|
219 if(!strcmp(xmlns, "jabber:iq:roster")) {
|
|
220 jabber_roster_parse(js, packet);
|
|
221 } else if(!strcmp(xmlns, "jabber:iq:last")) {
|
|
222 jabber_iq_handle_last(js, packet);
|
|
223 } else if(!strcmp(xmlns, "jabber:iq:time")) {
|
|
224 jabber_iq_handle_time(js, packet);
|
|
225 } else if(!strcmp(xmlns, "jabber:iq:version")) {
|
|
226 jabber_iq_handle_version(js, packet);
|
|
227 } else {
|
|
228 gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns);
|
|
229 }
|
|
230 }
|
|
231
|