~micahg/ubuntu/natty/pidgin/2.7.9-2

« back to all changes in this revision

Viewing changes to libpurple/protocols/msn/cmdproc.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-12-02 16:45:52 UTC
  • mfrom: (2.3.14 sid)
  • Revision ID: james.westby@ubuntu.com-20101202164552-z64wykojzacbb546
Tags: 1:2.7.7-1ubuntu1
New upstream version, drop msn workaround

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * along with this program; if not, write to the Free Software
22
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
23
23
 */
24
 
#include "msn.h"
 
24
 
 
25
#include "internal.h"
 
26
#include "debug.h"
 
27
 
25
28
#include "cmdproc.h"
 
29
#include "error.h"
26
30
 
27
31
MsnCmdProc *
28
32
msn_cmdproc_new(MsnSession *session)
122
126
                return;
123
127
        }
124
128
 
125
 
        msn_history_add(cmdproc->history, trans);
 
129
        if (trans->saveable)
 
130
                msn_history_add(cmdproc->history, trans);
126
131
 
127
132
        data = msn_transaction_to_string(trans);
128
133
 
155
160
}
156
161
 
157
162
void
158
 
msn_cmdproc_send_quick(MsnCmdProc *cmdproc, const char *command,
159
 
                                           const char *format, ...)
160
 
{
161
 
        MsnServConn *servconn;
162
 
        char *data;
163
 
        char *params = NULL;
164
 
        va_list arg;
165
 
        size_t len;
166
 
 
167
 
        g_return_if_fail(cmdproc != NULL);
168
 
        g_return_if_fail(command != NULL);
169
 
 
170
 
        servconn = cmdproc->servconn;
171
 
 
172
 
        if (!servconn->connected)
173
 
                return;
174
 
 
175
 
        if (format != NULL)
176
 
        {
177
 
                va_start(arg, format);
178
 
                params = g_strdup_vprintf(format, arg);
179
 
                va_end(arg);
180
 
        }
181
 
 
182
 
        if (params != NULL)
183
 
                data = g_strdup_printf("%s %s\r\n", command, params);
184
 
        else
185
 
                data = g_strdup_printf("%s\r\n", command);
186
 
 
187
 
        g_free(params);
188
 
 
189
 
        len = strlen(data);
190
 
 
191
 
        show_debug_cmd(cmdproc, FALSE, data);
192
 
 
193
 
        msn_servconn_write(servconn, data, len);
194
 
 
195
 
        g_free(data);
196
 
}
197
 
 
198
 
void
199
 
msn_cmdproc_send(MsnCmdProc *cmdproc, const char *command,
200
 
                                 const char *format, ...)
201
 
{
202
 
        MsnTransaction *trans;
203
 
        va_list arg;
204
 
 
205
 
        g_return_if_fail(cmdproc != NULL);
206
 
        g_return_if_fail(command != NULL);
207
 
 
208
 
        if (!cmdproc->servconn->connected)
209
 
                return;
210
 
 
211
 
        trans = g_new0(MsnTransaction, 1);
212
 
 
213
 
        trans->cmdproc = cmdproc;
214
 
        trans->command = g_strdup(command);
215
 
 
216
 
        if (format != NULL)
217
 
        {
218
 
                va_start(arg, format);
219
 
                trans->params = g_strdup_vprintf(format, arg);
220
 
                va_end(arg);
221
 
        }
222
 
 
223
 
        msn_cmdproc_send_trans(cmdproc, trans);
224
 
}
225
 
 
226
 
void
227
163
msn_cmdproc_process_payload(MsnCmdProc *cmdproc, char *payload,
228
164
                                                        int payload_len)
229
165
{
243
179
msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
244
180
{
245
181
        MsnMsgTypeCb cb;
246
 
        const char *messageId = NULL;
 
182
        const char *message_id = NULL;
247
183
 
248
184
        /* Multi-part messages */
249
 
        if ((messageId = msn_message_get_attr(msg, "Message-ID")) != NULL) {
250
 
                const char *chunk_text = msn_message_get_attr(msg, "Chunks");
 
185
        message_id = msn_message_get_header_value(msg, "Message-ID");
 
186
        if (message_id != NULL) {
 
187
                /* This is the first in a series of chunks */
 
188
 
 
189
                const char *chunk_text = msn_message_get_header_value(msg, "Chunks");
251
190
                guint chunk;
252
191
                if (chunk_text != NULL) {
253
192
                        chunk = strtol(chunk_text, NULL, 10);
254
 
                        /* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent 
 
193
                        /* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent
255
194
                           some random client causing pidgin to hog a ton of memory.
256
195
                           Probably should figure out the maximum that the official client
257
196
                           actually supports, though. */
258
197
                        if (chunk > 0 && chunk < 1024) {
259
198
                                msg->total_chunks = chunk;
260
199
                                msg->received_chunks = 1;
261
 
                                g_hash_table_insert(cmdproc->multiparts, (gpointer)messageId, msn_message_ref(msg));
262
 
                                purple_debug_info("msn", "Received chunked message, messageId: '%s', total chunks: %d\n",
263
 
                                                  messageId, chunk);
 
200
                                g_hash_table_insert(cmdproc->multiparts, (gpointer)message_id, msn_message_ref(msg));
 
201
                                purple_debug_info("msn", "Received chunked message, message_id: '%s', total chunks: %d\n",
 
202
                                                  message_id, chunk);
264
203
                        } else {
265
 
                                purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", messageId, chunk);
 
204
                                purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", message_id, chunk);
266
205
                        }
267
206
                        return;
268
207
                } else {
269
 
                        chunk_text = msn_message_get_attr(msg, "Chunk");
 
208
                        chunk_text = msn_message_get_header_value(msg, "Chunk");
270
209
                        if (chunk_text != NULL) {
271
 
                                MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, messageId);
 
210
                                /* This is one chunk in a series of chunks */
 
211
 
 
212
                                MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, message_id);
272
213
                                chunk = strtol(chunk_text, NULL, 10);
273
 
                                if (first == NULL) {
274
 
                                        purple_debug_error("msn",
275
 
                                                           "Unable to find first chunk of messageId '%s' to correspond with chunk %d.\n",
276
 
                                                           messageId, chunk+1);
277
 
                                } else if (first->received_chunks == chunk) {
 
214
                                if (first != NULL) {
 
215
                                        if (first->received_chunks != chunk) {
 
216
                                                /*
 
217
                                                 * We received an out of order chunk number (i.e. not the
 
218
                                                 * next one in the sequence).  Not sure if this can happen
 
219
                                                 * legitimately, but we definitely don't handle it right
 
220
                                                 * now.
 
221
                                                 */
 
222
                                                g_hash_table_remove(cmdproc->multiparts, message_id);
 
223
                                                return;
 
224
                                        }
 
225
 
278
226
                                        /* Chunk is from 1 to total-1 (doesn't count first one) */
279
 
                                        purple_debug_info("msn", "Received chunk %d of %d, messageId: '%s'\n",
280
 
                                                          chunk+1, first->total_chunks, messageId);
 
227
                                        purple_debug_info("msn", "Received chunk %d of %d, message_id: '%s'\n",
 
228
                                                        chunk + 1, first->total_chunks, message_id);
281
229
                                        first->body = g_realloc(first->body, first->body_len + msg->body_len);
282
230
                                        memcpy(first->body + first->body_len, msg->body, msg->body_len);
283
231
                                        first->body_len += msg->body_len;
284
232
                                        first->received_chunks++;
285
233
                                        if (first->received_chunks != first->total_chunks)
 
234
                                                /* We're waiting for more chunks */
286
235
                                                return;
287
 
                                        else
288
 
                                                /* We're done! Send it along... The caller takes care of
289
 
                                                   freeing the old one. */
290
 
                                                msg = first;
 
236
 
 
237
                                        /*
 
238
                                         * We have all the chunks for this message, great!  Send
 
239
                                         * it along... The caller takes care of freeing the old one.
 
240
                                         */
 
241
                                        msg = first;
291
242
                                } else {
292
 
                                        /* TODO: Can you legitimately receive chunks out of order? */
293
 
                                        g_hash_table_remove(cmdproc->multiparts, messageId);
294
 
                                        return;
 
243
                                        purple_debug_error("msn",
 
244
                                                           "Unable to find first chunk of message_id '%s' to correspond with chunk %d.\n",
 
245
                                                           message_id, chunk + 1);
295
246
                                }
296
247
                        } else {
297
 
                                purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", messageId);
 
248
                                purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", message_id);
298
249
                        }
299
250
                }
300
251
        }
314
265
                purple_debug_warning("msn", "Unhandled content-type '%s'\n",
315
266
                                                   msn_message_get_content_type(msg));
316
267
 
317
 
        if (messageId != NULL)
318
 
                g_hash_table_remove(cmdproc->multiparts, messageId);
 
268
        if (message_id != NULL)
 
269
                g_hash_table_remove(cmdproc->multiparts, message_id);
319
270
}
320
271
 
321
272
void