Mercurial > pidgin.yaz
comparison libpurple/protocols/msnp9/cmdproc.c @ 21312:a07cfce78345
Add MSNP9 back as an alternative alongside the existing MSN prpl. Cowardly
old fools like me who prefer the stability of our MSNP9 code over the
features of MSNP14 can enable this using the --disable-msnp14 ./configure
option.
If we want to release from i.p.p and MSN stability is the only blocker, we
can trivially flick the default to use MSNP9 in configure.ac
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sun, 11 Nov 2007 12:57:52 +0000 |
parents | |
children | ba47ec8a2477 |
comparison
equal
deleted
inserted
replaced
21311:7d031cec5ba2 | 21312:a07cfce78345 |
---|---|
1 /** | |
2 * @file cmdproc.c MSN command processor functions | |
3 * | |
4 * purple | |
5 * | |
6 * Purple is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "cmdproc.h" | |
26 | |
27 MsnCmdProc * | |
28 msn_cmdproc_new(MsnSession *session) | |
29 { | |
30 MsnCmdProc *cmdproc; | |
31 | |
32 cmdproc = g_new0(MsnCmdProc, 1); | |
33 | |
34 cmdproc->session = session; | |
35 cmdproc->txqueue = g_queue_new(); | |
36 cmdproc->history = msn_history_new(); | |
37 | |
38 return cmdproc; | |
39 } | |
40 | |
41 void | |
42 msn_cmdproc_destroy(MsnCmdProc *cmdproc) | |
43 { | |
44 MsnTransaction *trans; | |
45 | |
46 while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL) | |
47 msn_transaction_destroy(trans); | |
48 | |
49 g_queue_free(cmdproc->txqueue); | |
50 | |
51 msn_history_destroy(cmdproc->history); | |
52 | |
53 if (cmdproc->last_cmd != NULL) | |
54 msn_command_destroy(cmdproc->last_cmd); | |
55 | |
56 g_free(cmdproc); | |
57 } | |
58 | |
59 void | |
60 msn_cmdproc_process_queue(MsnCmdProc *cmdproc) | |
61 { | |
62 MsnTransaction *trans; | |
63 | |
64 while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL) | |
65 msn_cmdproc_send_trans(cmdproc, trans); | |
66 } | |
67 | |
68 void | |
69 msn_cmdproc_queue_trans(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
70 { | |
71 g_return_if_fail(cmdproc != NULL); | |
72 g_return_if_fail(trans != NULL); | |
73 | |
74 g_queue_push_tail(cmdproc->txqueue, trans); | |
75 } | |
76 | |
77 static void | |
78 show_debug_cmd(MsnCmdProc *cmdproc, gboolean incoming, const char *command) | |
79 { | |
80 MsnServConn *servconn; | |
81 const char *names[] = { "NS", "SB" }; | |
82 char *show; | |
83 char tmp; | |
84 size_t len; | |
85 | |
86 servconn = cmdproc->servconn; | |
87 len = strlen(command); | |
88 show = g_strdup(command); | |
89 | |
90 tmp = (incoming) ? 'S' : 'C'; | |
91 | |
92 if ((show[len - 1] == '\n') && (show[len - 2] == '\r')) | |
93 { | |
94 show[len - 2] = '\0'; | |
95 } | |
96 | |
97 purple_debug_misc("msn", "%c: %s %03d: %s\n", tmp, | |
98 names[servconn->type], servconn->num, show); | |
99 | |
100 g_free(show); | |
101 } | |
102 | |
103 void | |
104 msn_cmdproc_send_trans(MsnCmdProc *cmdproc, MsnTransaction *trans) | |
105 { | |
106 MsnServConn *servconn; | |
107 char *data; | |
108 size_t len; | |
109 | |
110 g_return_if_fail(cmdproc != NULL); | |
111 g_return_if_fail(trans != NULL); | |
112 | |
113 servconn = cmdproc->servconn; | |
114 | |
115 if (!servconn->connected) | |
116 return; | |
117 | |
118 msn_history_add(cmdproc->history, trans); | |
119 | |
120 data = msn_transaction_to_string(trans); | |
121 | |
122 len = strlen(data); | |
123 | |
124 show_debug_cmd(cmdproc, FALSE, data); | |
125 | |
126 if (trans->callbacks == NULL) | |
127 trans->callbacks = g_hash_table_lookup(cmdproc->cbs_table->cmds, | |
128 trans->command); | |
129 | |
130 if (trans->payload != NULL) | |
131 { | |
132 data = g_realloc(data, len + trans->payload_len); | |
133 memcpy(data + len, trans->payload, trans->payload_len); | |
134 len += trans->payload_len; | |
135 } | |
136 | |
137 msn_servconn_write(servconn, data, len); | |
138 | |
139 g_free(data); | |
140 } | |
141 | |
142 void | |
143 msn_cmdproc_send_quick(MsnCmdProc *cmdproc, const char *command, | |
144 const char *format, ...) | |
145 { | |
146 MsnServConn *servconn; | |
147 char *data; | |
148 char *params = NULL; | |
149 va_list arg; | |
150 size_t len; | |
151 | |
152 g_return_if_fail(cmdproc != NULL); | |
153 g_return_if_fail(command != NULL); | |
154 | |
155 servconn = cmdproc->servconn; | |
156 | |
157 if (!servconn->connected) | |
158 return; | |
159 | |
160 if (format != NULL) | |
161 { | |
162 va_start(arg, format); | |
163 params = g_strdup_vprintf(format, arg); | |
164 va_end(arg); | |
165 } | |
166 | |
167 if (params != NULL) | |
168 data = g_strdup_printf("%s %s\r\n", command, params); | |
169 else | |
170 data = g_strdup_printf("%s\r\n", command); | |
171 | |
172 g_free(params); | |
173 | |
174 len = strlen(data); | |
175 | |
176 show_debug_cmd(cmdproc, FALSE, data); | |
177 | |
178 msn_servconn_write(servconn, data, len); | |
179 | |
180 g_free(data); | |
181 } | |
182 | |
183 void | |
184 msn_cmdproc_send(MsnCmdProc *cmdproc, const char *command, | |
185 const char *format, ...) | |
186 { | |
187 MsnTransaction *trans; | |
188 va_list arg; | |
189 | |
190 g_return_if_fail(cmdproc != NULL); | |
191 g_return_if_fail(command != NULL); | |
192 | |
193 if (!cmdproc->servconn->connected) | |
194 return; | |
195 | |
196 trans = g_new0(MsnTransaction, 1); | |
197 | |
198 trans->command = g_strdup(command); | |
199 | |
200 if (format != NULL) | |
201 { | |
202 va_start(arg, format); | |
203 trans->params = g_strdup_vprintf(format, arg); | |
204 va_end(arg); | |
205 } | |
206 | |
207 msn_cmdproc_send_trans(cmdproc, trans); | |
208 } | |
209 | |
210 void | |
211 msn_cmdproc_process_payload(MsnCmdProc *cmdproc, char *payload, | |
212 int payload_len) | |
213 { | |
214 MsnCommand *last; | |
215 | |
216 g_return_if_fail(cmdproc != NULL); | |
217 | |
218 last = cmdproc->last_cmd; | |
219 last->payload = g_memdup(payload, payload_len); | |
220 last->payload_len = payload_len; | |
221 | |
222 if (last->payload_cb != NULL) | |
223 last->payload_cb(cmdproc, last, payload, payload_len); | |
224 } | |
225 | |
226 void | |
227 msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
228 { | |
229 MsnMsgTypeCb cb; | |
230 | |
231 if (msn_message_get_content_type(msg) == NULL) | |
232 { | |
233 purple_debug_misc("msn", "failed to find message content\n"); | |
234 return; | |
235 } | |
236 | |
237 cb = g_hash_table_lookup(cmdproc->cbs_table->msgs, | |
238 msn_message_get_content_type(msg)); | |
239 | |
240 if (cb == NULL) | |
241 { | |
242 purple_debug_warning("msn", "Unhandled content-type '%s'\n", | |
243 msn_message_get_content_type(msg)); | |
244 | |
245 return; | |
246 } | |
247 | |
248 cb(cmdproc, msg); | |
249 } | |
250 | |
251 void | |
252 msn_cmdproc_process_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) | |
253 { | |
254 MsnTransCb cb = NULL; | |
255 MsnTransaction *trans = NULL; | |
256 | |
257 if (cmd->trId) | |
258 trans = msn_history_find(cmdproc->history, cmd->trId); | |
259 | |
260 if (trans != NULL) | |
261 if (trans->timer) | |
262 purple_timeout_remove(trans->timer); | |
263 | |
264 if (g_ascii_isdigit(cmd->command[0])) | |
265 { | |
266 if (trans != NULL) | |
267 { | |
268 MsnErrorCb error_cb = NULL; | |
269 int error; | |
270 | |
271 error = atoi(cmd->command); | |
272 | |
273 if (trans->error_cb != NULL) | |
274 error_cb = trans->error_cb; | |
275 | |
276 if (error_cb == NULL && cmdproc->cbs_table->errors != NULL) | |
277 error_cb = g_hash_table_lookup(cmdproc->cbs_table->errors, trans->command); | |
278 | |
279 if (error_cb != NULL) | |
280 { | |
281 error_cb(cmdproc, trans, error); | |
282 } | |
283 else | |
284 { | |
285 #if 1 | |
286 msn_error_handle(cmdproc->session, error); | |
287 #else | |
288 purple_debug_warning("msn", "Unhandled error '%s'\n", | |
289 cmd->command); | |
290 #endif | |
291 } | |
292 | |
293 return; | |
294 } | |
295 } | |
296 | |
297 if (cmdproc->cbs_table->async != NULL) | |
298 cb = g_hash_table_lookup(cmdproc->cbs_table->async, cmd->command); | |
299 | |
300 if (cb == NULL && trans != NULL) | |
301 { | |
302 cmd->trans = trans; | |
303 | |
304 if (trans->callbacks != NULL) | |
305 cb = g_hash_table_lookup(trans->callbacks, cmd->command); | |
306 } | |
307 | |
308 if (cb == NULL && cmdproc->cbs_table->fallback != NULL) | |
309 cb = g_hash_table_lookup(cmdproc->cbs_table->fallback, cmd->command); | |
310 | |
311 if (cb != NULL) | |
312 { | |
313 cb(cmdproc, cmd); | |
314 } | |
315 else | |
316 { | |
317 purple_debug_warning("msn", "Unhandled command '%s'\n", | |
318 cmd->command); | |
319 } | |
320 | |
321 if (trans != NULL && trans->pendent_cmd != NULL) | |
322 msn_transaction_unqueue_cmd(trans, cmdproc); | |
323 } | |
324 | |
325 void | |
326 msn_cmdproc_process_cmd_text(MsnCmdProc *cmdproc, const char *command) | |
327 { | |
328 show_debug_cmd(cmdproc, TRUE, command); | |
329 | |
330 if (cmdproc->last_cmd != NULL) | |
331 msn_command_destroy(cmdproc->last_cmd); | |
332 | |
333 cmdproc->last_cmd = msn_command_from_string(command); | |
334 | |
335 msn_cmdproc_process_cmd(cmdproc, cmdproc->last_cmd); | |
336 } |