comparison src/protocols/msn/cmdproc.c @ 8810:a7affa2e2986

[gaim-migrate @ 9572] Forgot these. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sun, 25 Apr 2004 23:40:13 +0000
parents
children f8038b1f7449
comparison
equal deleted inserted replaced
8809:fde4101fa183 8810:a7affa2e2986
1 /**
2 * @file cmdproc.c MSN command processor functions
3 *
4 * gaim
5 *
6 * Copyright (C) 2003, Christian Hammond <chipx86@gnupdate.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 #include "msn.h"
23 #include "cmdproc.h"
24
25 typedef struct
26 {
27 char *command;
28 MsnMessage *msg;
29
30 } MsnQueueEntry;
31
32 MsnCmdProc *
33 msn_cmdproc_new(MsnSession *session)
34 {
35 MsnCmdProc *cmdproc;
36
37 cmdproc = g_new0(MsnCmdProc, 1);
38
39 cmdproc->session = session;
40 cmdproc->txqueue = g_queue_new();
41 cmdproc->history = msn_history_new();
42
43 return cmdproc;
44 }
45
46 void
47 msn_cmdproc_destroy(MsnCmdProc *cmdproc)
48 {
49 MsnTransaction *trans;
50
51 if (cmdproc->last_trans != NULL)
52 g_free(cmdproc->last_trans);
53
54 while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL)
55 msn_transaction_destroy(trans);
56
57 g_queue_free(cmdproc->txqueue);
58
59 while (cmdproc->msg_queue != NULL)
60 {
61 MsnQueueEntry *entry = cmdproc->msg_queue->data;
62
63 msn_cmdproc_unqueue_message(cmdproc, entry->msg);
64 }
65
66 msn_history_destroy(cmdproc->history);
67 }
68
69 void
70 msn_cmdproc_process_queue(MsnCmdProc *cmdproc)
71 {
72 MsnTransaction *trans;
73
74 while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL &&
75 cmdproc->error == 0)
76 {
77 msn_cmdproc_send_trans(cmdproc, trans);
78 }
79 }
80
81 void
82 msn_cmdproc_queue_trans(MsnCmdProc *cmdproc, MsnTransaction *trans)
83 {
84 g_return_if_fail(cmdproc != NULL);
85 g_return_if_fail(trans != NULL);
86
87 gaim_debug_info("msn", "Appending command to queue.\n");
88
89 g_queue_push_tail(cmdproc->txqueue, trans);
90 }
91
92 static void
93 show_debug_cmd(MsnCmdProc *cmdproc, gboolean incoming, const char *command)
94 {
95 MsnServConn *servconn;
96 const char *names[] = { "NS", "SB" };
97 char *show;
98 char tmp;
99 size_t len;
100
101 servconn = cmdproc->servconn;
102 len = strlen(command);
103 show = g_strdup(command);
104
105 tmp = (incoming) ? 'S' : 'C';
106
107 if ((show[len - 1] == '\n') && (show[len - 2] == '\r'))
108 {
109 show[len - 2] = '\0';
110 }
111
112 gaim_debug_misc("msn", "%c: %s %03d: %s\n", tmp,
113 names[servconn->type], servconn->num, show);
114
115 g_free(show);
116 }
117
118 void
119 msn_cmdproc_send_trans(MsnCmdProc *cmdproc, MsnTransaction *trans)
120 {
121 MsnServConn *servconn;
122 char *data;
123 size_t len;
124
125 g_return_if_fail(cmdproc != NULL);
126 g_return_if_fail(trans != NULL);
127
128 servconn = cmdproc->servconn;
129 msn_history_add(cmdproc->history, trans);
130
131 data = msn_transaction_to_string(trans);
132
133 cmdproc->last_trans = g_strdup(data);
134
135 len = strlen(data);
136
137 show_debug_cmd(cmdproc, FALSE, data);
138
139 if (trans->callbacks == NULL)
140 trans->callbacks = g_hash_table_lookup(cmdproc->cbs_table->cmds,
141 trans->command);
142
143 if (trans->payload != NULL)
144 {
145 data = g_realloc(data, len + trans->payload_len);
146 memcpy(data + len, trans->payload, trans->payload_len);
147 len += trans->payload_len;
148 }
149
150 msn_servconn_write(servconn, data, len);
151
152 g_free(data);
153 }
154
155 void
156 msn_cmdproc_send_quick(MsnCmdProc *cmdproc, const char *command,
157 const char *format, ...)
158 {
159 MsnServConn *servconn;
160 char *data;
161 char *params;
162 va_list arg;
163 size_t len;
164
165 g_return_if_fail(cmdproc != NULL);
166 g_return_if_fail(command != NULL);
167
168 servconn = cmdproc->servconn;
169
170 va_start(arg, format);
171 params = g_strdup_vprintf(format, arg);
172 va_end(arg);
173
174 if (params != NULL)
175 data = g_strdup_printf("%s %s\r\n", command, params);
176 else
177 data = g_strdup_printf("%s\r\n", command);
178
179 g_free(params);
180
181 len = strlen(data);
182
183 show_debug_cmd(cmdproc, FALSE, data);
184
185 msn_servconn_write(servconn, data, len);
186
187 g_free(data);
188 }
189
190 void
191 msn_cmdproc_send(MsnCmdProc *cmdproc, const char *command,
192 const char *format, ...)
193 {
194 MsnTransaction *trans;
195 va_list arg;
196
197 g_return_if_fail(cmdproc != NULL);
198 g_return_if_fail(command != NULL);
199
200 trans = g_new0(MsnTransaction, 1);
201
202 trans->command = g_strdup(command);
203
204 va_start(arg, format);
205 trans->params = g_strdup_vprintf(format, arg);
206 va_end(arg);
207
208 msn_cmdproc_send_trans(cmdproc, trans);
209 }
210
211 void
212 msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
213 {
214 MsnServConn *servconn;
215 MsnMsgCb cb;
216
217 servconn = cmdproc->servconn;
218
219 cb = g_hash_table_lookup(cmdproc->cbs_table->msgs,
220 msn_message_get_content_type(msg));
221
222 if (cb == NULL)
223 {
224 gaim_debug_warning("msn", "Unhandled content-type '%s': %s\n",
225 msn_message_get_content_type(msg),
226 msn_message_get_body(msg));
227
228 return;
229 }
230
231 cb(cmdproc, msg);
232 }
233
234 void
235 msn_cmdproc_process_payload(MsnCmdProc *cmdproc, char *payload, int payload_len)
236 {
237 g_return_if_fail(cmdproc != NULL);
238 g_return_if_fail(cmdproc->payload_cb != NULL);
239
240 cmdproc->payload_cb(cmdproc, payload, payload_len);
241 }
242
243 void
244 msn_cmdproc_process_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
245 {
246 MsnSession *session;
247 MsnServConn *servconn;
248 MsnTransaction *trans = NULL;
249 MsnTransCb cb = NULL;
250 GSList *l, *l_next = NULL;
251
252 session = cmdproc->session;
253 servconn = cmdproc->servconn;
254
255 if (cmd->trId)
256 trans = msn_history_find(cmdproc->history, cmd->trId);
257
258 if (g_ascii_isdigit(cmd->command[0]))
259 {
260 if (trans != NULL)
261 {
262 MsnErrorCb error_cb = NULL;
263 int error;
264
265 error = atoi(cmd->command);
266 if (cmdproc->cbs_table->errors != NULL)
267 error_cb = g_hash_table_lookup(cmdproc->cbs_table->errors, trans->command);
268
269 if (error_cb != NULL)
270 error_cb(cmdproc, trans, error);
271 else
272 {
273 #if 1
274 msn_error_handle(cmdproc->session, error);
275 #else
276 gaim_debug_warning("msn", "Unhandled error '%s'\n",
277 cmd->command);
278 #endif
279 }
280
281 return;
282 }
283 }
284
285 if (cmdproc->cbs_table->async != NULL)
286 cb = g_hash_table_lookup(cmdproc->cbs_table->async, cmd->command);
287
288 if (cb == NULL && cmd->trId)
289 {
290 if (trans != NULL)
291 {
292 cmd->trans = trans;
293
294 if (trans->callbacks)
295 cb = g_hash_table_lookup(trans->callbacks, cmd->command);
296 }
297 }
298
299 if (cb != NULL)
300 cb(cmdproc, cmd);
301 else
302 {
303 gaim_debug_warning("msn", "Unhandled command '%s'\n",
304 cmd->command);
305
306 return;
307 }
308
309 if (g_list_find(session->servconns, servconn) == NULL)
310 return;
311
312 /* Process all queued messages that are waiting on this command. */
313 for (l = cmdproc->msg_queue; l != NULL; l = l_next)
314 {
315 MsnQueueEntry *entry = l->data;
316 MsnMessage *msg;
317
318 l_next = l->next;
319
320 if (entry->command == NULL ||
321 !g_ascii_strcasecmp(entry->command, cmd->command))
322 {
323 msg = entry->msg;
324
325 msn_message_ref(msg);
326
327 msn_cmdproc_process_msg(cmdproc, msg);
328
329 msn_cmdproc_unqueue_message(cmdproc, entry->msg);
330
331 msn_message_destroy(msg);
332 entry->msg = NULL;
333 }
334 }
335 }
336
337 void
338 msn_cmdproc_process_cmd_text(MsnCmdProc *cmdproc, const char *command)
339 {
340 show_debug_cmd(cmdproc, TRUE, command);
341
342 if (cmdproc->last_cmd != NULL)
343 msn_command_destroy(cmdproc->last_cmd);
344
345 cmdproc->last_cmd = msn_command_from_string(command);
346
347 msn_cmdproc_process_cmd(cmdproc, cmdproc->last_cmd);
348 }
349
350 void
351 msn_cmdproc_queue_message(MsnCmdProc *cmdproc, const char *command,
352 MsnMessage *msg)
353 {
354 MsnQueueEntry *entry;
355
356 g_return_if_fail(cmdproc != NULL);
357 g_return_if_fail(msg != NULL);
358
359 entry = g_new0(MsnQueueEntry, 1);
360 entry->msg = msg;
361 entry->command = (command == NULL ? NULL : g_strdup(command));
362
363 cmdproc->msg_queue = g_slist_append(cmdproc->msg_queue, entry);
364
365 msn_message_ref(msg);
366 }
367
368 void
369 msn_cmdproc_unqueue_message(MsnCmdProc *cmdproc, MsnMessage *msg)
370 {
371 MsnQueueEntry *entry = NULL;
372 GSList *l;
373
374 g_return_if_fail(cmdproc != NULL);
375 g_return_if_fail(msg != NULL);
376
377 for (l = cmdproc->msg_queue; l != NULL; l = l->next)
378 {
379 entry = l->data;
380
381 if (entry->msg == msg)
382 break;
383
384 entry = NULL;
385 }
386
387 g_return_if_fail(entry != NULL);
388
389 msn_message_unref(msg);
390
391 cmdproc->msg_queue = g_slist_remove(cmdproc->msg_queue, entry);
392
393 if (entry->command != NULL)
394 g_free(entry->command);
395
396 g_free(entry);
397 }