| |
1 /* |
| |
2 * nmevent.c |
| |
3 * |
| |
4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved. |
| |
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; version 2 of the License. |
| |
9 * |
| |
10 * This program is distributed in the hope that it will be useful, |
| |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
13 * GNU General Public License for more details. |
| |
14 * |
| |
15 * You should have received a copy of the GNU General Public License |
| |
16 * along with this program; if not, write to the Free Software |
| |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
18 * |
| |
19 */ |
| |
20 |
| |
21 #include <glib.h> |
| |
22 #include <string.h> |
| |
23 #include <time.h> |
| |
24 #include "nmevent.h" |
| |
25 #include "nmfield.h" |
| |
26 #include "nmconn.h" |
| |
27 #include "nmuserrecord.h" |
| |
28 #include "nmrtf.h" |
| |
29 |
| |
30 #define MAX_UINT32 0xFFFFFFFF |
| |
31 |
| |
32 struct _NMEvent |
| |
33 { |
| |
34 |
| |
35 /* Event type */ |
| |
36 int type; |
| |
37 |
| |
38 /* The DN of the event source */ |
| |
39 char *source; |
| |
40 |
| |
41 /* Timestamp of the event */ |
| |
42 guint32 gmt; |
| |
43 |
| |
44 /* Conference to associate with the event */ |
| |
45 NMConference *conference; |
| |
46 |
| |
47 /* User record to associate with the event */ |
| |
48 NMUserRecord *user_record; |
| |
49 |
| |
50 /* Text associated with the event */ |
| |
51 char *text; |
| |
52 |
| |
53 /* Reference count for event structure */ |
| |
54 int ref_count; |
| |
55 |
| |
56 }; |
| |
57 |
| |
58 /* Handle getdetails response and set the new user record into the event */ |
| |
59 static void |
| |
60 _got_user_for_event(NMUser * user, NMERR_T ret_val, |
| |
61 gpointer resp_data, gpointer user_data) |
| |
62 { |
| |
63 NMUserRecord *user_record; |
| |
64 NMEvent *event; |
| |
65 nm_event_cb cb; |
| |
66 |
| |
67 if (user == NULL) |
| |
68 return; |
| |
69 |
| |
70 user_record = resp_data; |
| |
71 event = user_data; |
| |
72 |
| |
73 if (ret_val == NM_OK) { |
| |
74 if (event && user_record) { |
| |
75 |
| |
76 /* Add the user record to the event structure |
| |
77 * and make the callback. |
| |
78 */ |
| |
79 nm_event_set_user_record(event, user_record); |
| |
80 if ((cb = nm_user_get_event_callback(user))) { |
| |
81 cb(user, event); |
| |
82 } |
| |
83 } |
| |
84 |
| |
85 } else { |
| |
86 /* Cleanup resp_data */ |
| |
87 |
| |
88 } |
| |
89 |
| |
90 /* Clean up */ |
| |
91 if (event) |
| |
92 nm_release_event(event); |
| |
93 |
| |
94 } |
| |
95 |
| |
96 /* Handle getdetails response, set the new user record into the event |
| |
97 * and add the user record as a participant in the conference |
| |
98 */ |
| |
99 static void |
| |
100 _got_user_for_conference(NMUser * user, NMERR_T ret_val, |
| |
101 gpointer resp_data, gpointer user_data) |
| |
102 { |
| |
103 NMUserRecord *user_record = resp_data; |
| |
104 NMEvent *event = user_data; |
| |
105 NMConference *conference; |
| |
106 nm_event_cb cb; |
| |
107 |
| |
108 if (user == NULL) |
| |
109 return; |
| |
110 |
| |
111 if (event && user_record) { |
| |
112 |
| |
113 conference = nm_event_get_conference(event); |
| |
114 if (conference) { |
| |
115 |
| |
116 /* Add source of event as recip of the conference */ |
| |
117 nm_conference_add_participant(conference, user_record); |
| |
118 |
| |
119 /* Add the user record to the event structure |
| |
120 * and make the callback. |
| |
121 */ |
| |
122 nm_event_set_user_record(event, user_record); |
| |
123 if ((cb = nm_user_get_event_callback(user))) { |
| |
124 cb(user, event); |
| |
125 } |
| |
126 } |
| |
127 } |
| |
128 |
| |
129 if (event) |
| |
130 nm_release_event(event); |
| |
131 } |
| |
132 |
| |
133 /* Read the receive message event, set up the event object, and |
| |
134 * get details for the event source if we don't have them yet. |
| |
135 */ |
| |
136 static NMERR_T |
| |
137 handle_receive_message(NMUser * user, NMEvent * event, gboolean autoreply) |
| |
138 { |
| |
139 NMConference *conference; |
| |
140 NMUserRecord *user_record; |
| |
141 NMConn *conn; |
| |
142 NMERR_T rc = NM_OK; |
| |
143 guint32 size = 0, flags = 0; |
| |
144 char *msg = NULL; |
| |
145 char *nortf = NULL; |
| |
146 char *guid = NULL; |
| |
147 |
| |
148 conn = nm_user_get_conn(user); |
| |
149 |
| |
150 /* Read the conference guid */ |
| |
151 rc = nm_read_uint32(conn, &size); |
| |
152 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
153 |
| |
154 if (rc == NM_OK) { |
| |
155 guid = g_new0(char, size + 1); |
| |
156 rc = nm_read_all(conn, guid, size); |
| |
157 } |
| |
158 |
| |
159 /* Read the conference flags */ |
| |
160 if (rc == NM_OK) { |
| |
161 rc = nm_read_uint32(conn, &flags); |
| |
162 } |
| |
163 |
| |
164 /* Read the message text */ |
| |
165 if (rc == NM_OK) { |
| |
166 rc = nm_read_uint32(conn, &size); |
| |
167 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
168 |
| |
169 if (rc == NM_OK) { |
| |
170 msg = g_new0(char, size + 1); |
| |
171 rc = nm_read_all(conn, msg, size); |
| |
172 |
| |
173 gaim_debug(GAIM_DEBUG_INFO, "novell", "Message is %s\n", msg); |
| |
174 |
| |
175 /* Auto replies are not in RTF format! */ |
| |
176 if (!autoreply) { |
| |
177 NMRtfContext *ctx; |
| |
178 |
| |
179 ctx = nm_rtf_init(); |
| |
180 nortf = nm_rtf_strip_formatting(ctx, msg); |
| |
181 nm_rtf_deinit(ctx); |
| |
182 |
| |
183 gaim_debug(GAIM_DEBUG_INFO, "novell", |
| |
184 "Message without RTF is %s\n", nortf); |
| |
185 |
| |
186 /* Store the event data */ |
| |
187 nm_event_set_text(event, nortf); |
| |
188 |
| |
189 } else { |
| |
190 |
| |
191 /* Store the event data */ |
| |
192 nm_event_set_text(event, msg); |
| |
193 } |
| |
194 } |
| |
195 } |
| |
196 |
| |
197 /* Check to see if we already know about the conference */ |
| |
198 conference = nm_conference_list_find(user, guid); |
| |
199 if (conference) { |
| |
200 |
| |
201 nm_conference_set_flags(conference, flags); |
| |
202 nm_event_set_conference(event, conference); |
| |
203 |
| |
204 /* Add a reference to the user record in our event object */ |
| |
205 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
206 if (user_record) { |
| |
207 nm_event_set_user_record(event, user_record); |
| |
208 } |
| |
209 |
| |
210 } else { |
| |
211 |
| |
212 /* This is a new conference, so create one and add it to our list */ |
| |
213 conference = nm_create_conference(guid); |
| |
214 nm_conference_set_flags(conference, flags); |
| |
215 |
| |
216 /* Add a reference to the conference in the event */ |
| |
217 nm_event_set_conference(event, conference); |
| |
218 |
| |
219 /* Add new conference to the conference list */ |
| |
220 nm_conference_list_add(user, conference); |
| |
221 |
| |
222 /* Check to see if we have details for the event source yet */ |
| |
223 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
224 if (user_record) { |
| |
225 |
| |
226 /* We do so add the user record as a recipient of the conference */ |
| |
227 nm_conference_add_participant(conference, user_record); |
| |
228 |
| |
229 /* Add a reference to the user record in our event object */ |
| |
230 nm_event_set_user_record(event, user_record); |
| |
231 |
| |
232 } else { |
| |
233 |
| |
234 /* Need to go to the server to get details for the user */ |
| |
235 rc = nm_send_get_details(user, nm_event_get_source(event), |
| |
236 _got_user_for_conference, event); |
| |
237 if (rc == NM_OK) |
| |
238 rc = -1; /* Not done processing the event yet! */ |
| |
239 } |
| |
240 |
| |
241 nm_release_conference(conference); |
| |
242 } |
| |
243 |
| |
244 if (msg) |
| |
245 g_free(msg); |
| |
246 |
| |
247 if (nortf) |
| |
248 g_free(nortf); |
| |
249 |
| |
250 if (guid) |
| |
251 g_free(guid); |
| |
252 |
| |
253 return rc; |
| |
254 } |
| |
255 |
| |
256 /* Read the invite event, set up the event object, and |
| |
257 * get details for the event source if we don't have them yet. |
| |
258 */ |
| |
259 static NMERR_T |
| |
260 handle_conference_invite(NMUser * user, NMEvent * event) |
| |
261 { |
| |
262 NMERR_T rc = NM_OK; |
| |
263 guint32 size = 0; |
| |
264 char *guid = NULL; |
| |
265 char *msg = NULL; |
| |
266 NMConn *conn; |
| |
267 NMUserRecord *user_record; |
| |
268 |
| |
269 conn = nm_user_get_conn(user); |
| |
270 |
| |
271 /* Read the conference guid */ |
| |
272 rc = nm_read_uint32(conn, &size); |
| |
273 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
274 |
| |
275 if (rc == NM_OK) { |
| |
276 guid = g_new0(char, size + 1); |
| |
277 rc = nm_read_all(conn, guid, size); |
| |
278 } |
| |
279 |
| |
280 /* Read the the message */ |
| |
281 if (rc == NM_OK) { |
| |
282 rc = nm_read_uint32(conn, &size); |
| |
283 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
284 |
| |
285 if (rc == NM_OK) { |
| |
286 msg = g_new0(char, size + 1); |
| |
287 rc = nm_read_all(conn, msg, size); |
| |
288 } |
| |
289 } |
| |
290 |
| |
291 /* Store the event data */ |
| |
292 if (rc == NM_OK) { |
| |
293 NMConference *conference; |
| |
294 |
| |
295 nm_event_set_text(event, msg); |
| |
296 |
| |
297 conference = nm_conference_list_find(user, guid); |
| |
298 if (conference == NULL) { |
| |
299 conference = nm_create_conference(guid); |
| |
300 |
| |
301 /* Add new conference to the list and the event */ |
| |
302 nm_conference_list_add(user, conference); |
| |
303 nm_event_set_conference(event, conference); |
| |
304 |
| |
305 /* Check to see if we have details for the event source yet */ |
| |
306 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
307 if (user_record) { |
| |
308 |
| |
309 /* Add a reference to the user record in our event object */ |
| |
310 nm_event_set_user_record(event, user_record); |
| |
311 |
| |
312 } else { |
| |
313 |
| |
314 /* Need to go to the server to get details for the user */ |
| |
315 rc = nm_send_get_details(user, nm_event_get_source(event), |
| |
316 _got_user_for_event, event); |
| |
317 if (rc == NM_OK) |
| |
318 rc = -1; /* Not done processing the event yet! */ |
| |
319 } |
| |
320 |
| |
321 nm_release_conference(conference); |
| |
322 |
| |
323 } |
| |
324 } |
| |
325 |
| |
326 if (msg) |
| |
327 g_free(msg); |
| |
328 |
| |
329 if (guid) |
| |
330 g_free(guid); |
| |
331 |
| |
332 return rc; |
| |
333 } |
| |
334 |
| |
335 /* Read the invite notify event, set up the event object, and |
| |
336 * get details for the event source if we don't have them yet. |
| |
337 */ |
| |
338 static NMERR_T |
| |
339 handle_conference_invite_notify(NMUser * user, NMEvent * event) |
| |
340 { |
| |
341 NMERR_T rc = NM_OK; |
| |
342 guint32 size = 0; |
| |
343 char *guid = NULL; |
| |
344 NMConn *conn; |
| |
345 NMConference *conference; |
| |
346 NMUserRecord *user_record; |
| |
347 |
| |
348 conn = nm_user_get_conn(user); |
| |
349 |
| |
350 /* Read the conference guid */ |
| |
351 rc = nm_read_uint32(conn, &size); |
| |
352 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
353 |
| |
354 if (rc == NM_OK) { |
| |
355 guid = g_new0(char, size + 1); |
| |
356 rc = nm_read_all(conn, guid, size); |
| |
357 } |
| |
358 |
| |
359 conference = nm_conference_list_find(user, guid); |
| |
360 if (conference) { |
| |
361 nm_event_set_conference(event, conference); |
| |
362 |
| |
363 /* Check to see if we have details for the event source yet */ |
| |
364 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
365 if (user_record) { |
| |
366 |
| |
367 /* Add a reference to the user record in our event object */ |
| |
368 nm_event_set_user_record(event, user_record); |
| |
369 |
| |
370 } else { |
| |
371 |
| |
372 /* Need to go to the server to get details for the user */ |
| |
373 rc = nm_send_get_details(user, nm_event_get_source(event), |
| |
374 _got_user_for_event, event); |
| |
375 if (rc == NM_OK) |
| |
376 rc = -1; /* Not done processing the event yet! */ |
| |
377 } |
| |
378 |
| |
379 } else { |
| |
380 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
381 } |
| |
382 |
| |
383 |
| |
384 if (guid) |
| |
385 g_free(guid); |
| |
386 |
| |
387 return rc; |
| |
388 } |
| |
389 |
| |
390 /* Read the conference reject event and set up the event object */ |
| |
391 static NMERR_T |
| |
392 handle_conference_reject(NMUser * user, NMEvent * event) |
| |
393 { |
| |
394 NMERR_T rc = NM_OK; |
| |
395 guint32 size = 0; |
| |
396 char *guid = NULL; |
| |
397 NMConn *conn; |
| |
398 NMConference *conference; |
| |
399 |
| |
400 conn = nm_user_get_conn(user); |
| |
401 |
| |
402 /* Read the conference guid */ |
| |
403 rc = nm_read_uint32(conn, &size); |
| |
404 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
405 |
| |
406 if (rc == NM_OK) { |
| |
407 guid = g_new0(char, size + 1); |
| |
408 rc = nm_read_all(conn, guid, size); |
| |
409 } |
| |
410 |
| |
411 if (rc == NM_OK) { |
| |
412 conference = nm_conference_list_find(user, guid); |
| |
413 if (conference) { |
| |
414 nm_event_set_conference(event, conference); |
| |
415 } else { |
| |
416 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
417 } |
| |
418 } |
| |
419 |
| |
420 if (guid) |
| |
421 g_free(guid); |
| |
422 |
| |
423 return rc; |
| |
424 } |
| |
425 |
| |
426 /* Read the conference left event, set up the event object, and |
| |
427 * remove the conference from the list if there are no more |
| |
428 * participants |
| |
429 */ |
| |
430 static NMERR_T |
| |
431 handle_conference_left(NMUser * user, NMEvent * event) |
| |
432 { |
| |
433 NMERR_T rc = NM_OK; |
| |
434 guint32 size = 0, flags = 0; |
| |
435 char *guid = NULL; |
| |
436 NMConference *conference; |
| |
437 NMConn *conn; |
| |
438 |
| |
439 conn = nm_user_get_conn(user); |
| |
440 |
| |
441 /* Read the conference guid */ |
| |
442 rc = nm_read_uint32(conn, &size); |
| |
443 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
444 |
| |
445 if (rc == NM_OK) { |
| |
446 guid = g_new0(char, size + 1); |
| |
447 rc = nm_read_all(conn, guid, size); |
| |
448 } |
| |
449 |
| |
450 /* Read the conference flags */ |
| |
451 if (rc == NM_OK) { |
| |
452 rc = nm_read_uint32(conn, &flags); |
| |
453 } |
| |
454 |
| |
455 if (rc == NM_OK) { |
| |
456 conference = nm_conference_list_find(user, guid); |
| |
457 if (conference) { |
| |
458 nm_event_set_conference(event, conference); |
| |
459 nm_conference_set_flags(conference, flags); |
| |
460 |
| |
461 nm_conference_remove_participant(conference, nm_event_get_source(event)); |
| |
462 if (nm_conference_get_participant_count(conference) == 0) { |
| |
463 nm_conference_list_remove(user, conference); |
| |
464 } |
| |
465 |
| |
466 } else { |
| |
467 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
468 } |
| |
469 } |
| |
470 |
| |
471 if (guid) |
| |
472 g_free(guid); |
| |
473 |
| |
474 return rc; |
| |
475 } |
| |
476 |
| |
477 /* Read the conference closed, set up the event object, and |
| |
478 * remove the conference from the list |
| |
479 */ |
| |
480 static NMERR_T |
| |
481 handle_conference_closed(NMUser * user, NMEvent * event) |
| |
482 { |
| |
483 NMERR_T rc = NM_OK; |
| |
484 guint32 size = 0; |
| |
485 char *guid = NULL; |
| |
486 NMConference *conference; |
| |
487 NMConn *conn; |
| |
488 |
| |
489 conn = nm_user_get_conn(user); |
| |
490 |
| |
491 /* Read the conference guid */ |
| |
492 rc = nm_read_uint32(conn, &size); |
| |
493 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
494 |
| |
495 if (rc == NM_OK) { |
| |
496 guid = g_new0(char, size + 1); |
| |
497 rc = nm_read_all(conn, guid, size); |
| |
498 } |
| |
499 |
| |
500 if (rc == NM_OK) { |
| |
501 conference = nm_conference_list_find(user, guid); |
| |
502 if (conference) { |
| |
503 nm_event_set_conference(event, conference); |
| |
504 nm_conference_list_remove(user, conference); |
| |
505 } else { |
| |
506 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
507 } |
| |
508 } |
| |
509 |
| |
510 if (guid) |
| |
511 g_free(guid); |
| |
512 |
| |
513 return rc; |
| |
514 } |
| |
515 |
| |
516 /* Read the conference joined event, set up the event object, and |
| |
517 * get details for the event source if we don't have them yet. |
| |
518 */ |
| |
519 static NMERR_T |
| |
520 handle_conference_joined(NMUser * user, NMEvent * event) |
| |
521 { |
| |
522 NMERR_T rc = NM_OK; |
| |
523 guint32 size = 0, flags = 0; |
| |
524 char *guid = NULL; |
| |
525 NMConn *conn; |
| |
526 NMConference *conference; |
| |
527 NMUserRecord *user_record; |
| |
528 |
| |
529 conn = nm_user_get_conn(user); |
| |
530 |
| |
531 /* Read the conference guid */ |
| |
532 rc = nm_read_uint32(conn, &size); |
| |
533 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
534 |
| |
535 if (rc == NM_OK) { |
| |
536 guid = g_new0(char, size + 1); |
| |
537 rc = nm_read_all(conn, guid, size); |
| |
538 } |
| |
539 |
| |
540 /* Read the conference flags */ |
| |
541 if (rc == NM_OK) { |
| |
542 rc = nm_read_uint32(conn, &flags); |
| |
543 } |
| |
544 |
| |
545 if (rc == NM_OK) { |
| |
546 conference = nm_conference_list_find(user, guid); |
| |
547 if (conference) { |
| |
548 nm_conference_set_flags(conference, flags); |
| |
549 |
| |
550 nm_event_set_conference(event, conference); |
| |
551 |
| |
552 /* Add the new user to the participants list */ |
| |
553 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
554 if (user_record) { |
| |
555 nm_conference_remove_participant(conference, |
| |
556 nm_user_record_get_dn(user_record)); |
| |
557 nm_conference_add_participant(conference, user_record); |
| |
558 } else { |
| |
559 |
| |
560 /* Need to go to the server to get details for the user */ |
| |
561 rc = nm_send_get_details(user, nm_event_get_source(event), |
| |
562 _got_user_for_conference, event); |
| |
563 if (rc == NM_OK) |
| |
564 rc = -1; /* Not done processing the event yet! */ |
| |
565 } |
| |
566 |
| |
567 } else { |
| |
568 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
569 } |
| |
570 } |
| |
571 |
| |
572 if (guid) |
| |
573 g_free(guid); |
| |
574 |
| |
575 return rc; |
| |
576 } |
| |
577 |
| |
578 /* Read the typing event and set up the event object */ |
| |
579 static NMERR_T |
| |
580 handle_typing(NMUser * user, NMEvent * event) |
| |
581 { |
| |
582 NMERR_T rc = NM_OK; |
| |
583 guint32 size = 0; |
| |
584 char *guid = NULL; |
| |
585 NMConference *conference; |
| |
586 NMConn *conn; |
| |
587 |
| |
588 conn = nm_user_get_conn(user); |
| |
589 |
| |
590 /* Read the conference guid */ |
| |
591 rc = nm_read_uint32(conn, &size); |
| |
592 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
593 |
| |
594 if (rc == NM_OK) { |
| |
595 guid = g_new0(char, size + 1); |
| |
596 rc = nm_read_all(conn, guid, size); |
| |
597 } |
| |
598 |
| |
599 if (rc == NM_OK) { |
| |
600 conference = nm_conference_list_find(user, guid); |
| |
601 if (conference) { |
| |
602 nm_event_set_conference(event, conference); |
| |
603 } else { |
| |
604 rc = NMERR_CONFERENCE_NOT_FOUND; |
| |
605 } |
| |
606 } |
| |
607 |
| |
608 if (guid) |
| |
609 g_free(guid); |
| |
610 |
| |
611 return rc; |
| |
612 } |
| |
613 |
| |
614 /* Read the event, set up the event object, and update |
| |
615 * the status in the user record (for the event source) |
| |
616 */ |
| |
617 static NMERR_T |
| |
618 handle_status_change(NMUser * user, NMEvent * event) |
| |
619 { |
| |
620 NMERR_T rc = NM_OK; |
| |
621 guint16 status; |
| |
622 guint32 size; |
| |
623 char *text = NULL; |
| |
624 NMUserRecord *user_record; |
| |
625 NMConn *conn; |
| |
626 |
| |
627 conn = nm_user_get_conn(user); |
| |
628 |
| |
629 /* Read new status */ |
| |
630 rc = nm_read_uint16(conn, &status); |
| |
631 if (rc == NM_OK) { |
| |
632 |
| |
633 /* Read the status text */ |
| |
634 rc = nm_read_uint32(conn, &size); |
| |
635 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
636 |
| |
637 if (rc == NM_OK) { |
| |
638 text = g_new0(char, size + 1); |
| |
639 rc = nm_read_all(conn, text, size); |
| |
640 } |
| |
641 } |
| |
642 |
| |
643 if (rc == NM_OK) { |
| |
644 nm_event_set_text(event, text); |
| |
645 |
| |
646 /* Get a reference to the user record and store the new status */ |
| |
647 user_record = nm_find_user_record(user, nm_event_get_source(event)); |
| |
648 if (user_record) { |
| |
649 nm_event_set_user_record(event, user_record); |
| |
650 nm_user_record_set_status(user_record, status, text); |
| |
651 } |
| |
652 } |
| |
653 |
| |
654 if (text) |
| |
655 g_free(text); |
| |
656 |
| |
657 return rc; |
| |
658 } |
| |
659 |
| |
660 /* Read the undeliverable event */ |
| |
661 static NMERR_T |
| |
662 handle_undeliverable_status(NMUser * user, NMEvent * event) |
| |
663 { |
| |
664 NMERR_T rc = NM_OK; |
| |
665 guint32 size = 0; |
| |
666 char *guid = NULL; |
| |
667 NMConn *conn; |
| |
668 |
| |
669 conn = nm_user_get_conn(user); |
| |
670 |
| |
671 /* Read the conference guid */ |
| |
672 rc = nm_read_uint32(conn, &size); |
| |
673 if (size == MAX_UINT32) return NMERR_PROTOCOL; |
| |
674 |
| |
675 if (rc == NM_OK) { |
| |
676 guid = g_new0(char, size + 1); |
| |
677 rc = nm_read_all(conn, guid, size); |
| |
678 } |
| |
679 |
| |
680 if (guid) |
| |
681 g_free(guid); |
| |
682 |
| |
683 return rc; |
| |
684 } |
| |
685 |
| |
686 /******************************************************************************* |
| |
687 * Event API -- see header file for comments |
| |
688 ******************************************************************************/ |
| |
689 |
| |
690 NMEvent * |
| |
691 nm_create_event(int type, const char *source, guint32 gmt) |
| |
692 { |
| |
693 NMEvent *event = g_new0(NMEvent, 1); |
| |
694 |
| |
695 event->type = type; |
| |
696 event->gmt = gmt; |
| |
697 |
| |
698 if (source) |
| |
699 event->source = g_strdup(source); |
| |
700 |
| |
701 event->ref_count = 1; |
| |
702 |
| |
703 return event; |
| |
704 } |
| |
705 |
| |
706 void |
| |
707 nm_release_event(NMEvent * event) |
| |
708 { |
| |
709 if (event == NULL) { |
| |
710 return; |
| |
711 } |
| |
712 |
| |
713 if (--(event->ref_count) == 0) { |
| |
714 |
| |
715 if (event->source) |
| |
716 g_free(event->source); |
| |
717 |
| |
718 if (event->conference) |
| |
719 nm_release_conference(event->conference); |
| |
720 |
| |
721 if (event->user_record) |
| |
722 nm_release_user_record(event->user_record); |
| |
723 |
| |
724 if (event->text) |
| |
725 g_free(event->text); |
| |
726 |
| |
727 g_free(event); |
| |
728 } |
| |
729 } |
| |
730 |
| |
731 |
| |
732 NMConference * |
| |
733 nm_event_get_conference(NMEvent * event) |
| |
734 { |
| |
735 if (event) |
| |
736 return event->conference; |
| |
737 else |
| |
738 return NULL; |
| |
739 } |
| |
740 |
| |
741 void |
| |
742 nm_event_set_conference(NMEvent * event, NMConference * conference) |
| |
743 { |
| |
744 if (event && conference) { |
| |
745 nm_conference_add_ref(conference); |
| |
746 event->conference = conference; |
| |
747 } |
| |
748 } |
| |
749 |
| |
750 NMUserRecord * |
| |
751 nm_event_get_user_record(NMEvent * event) |
| |
752 { |
| |
753 if (event) |
| |
754 return event->user_record; |
| |
755 else |
| |
756 return NULL; |
| |
757 } |
| |
758 |
| |
759 void |
| |
760 nm_event_set_user_record(NMEvent * event, NMUserRecord * user_record) |
| |
761 { |
| |
762 if (event && user_record) { |
| |
763 nm_user_record_add_ref(user_record); |
| |
764 event->user_record = user_record; |
| |
765 } |
| |
766 } |
| |
767 |
| |
768 const char * |
| |
769 nm_event_get_text(NMEvent * event) |
| |
770 { |
| |
771 if (event) |
| |
772 return event->text; |
| |
773 else |
| |
774 return NULL; |
| |
775 } |
| |
776 |
| |
777 void |
| |
778 nm_event_set_text(NMEvent * event, const char *text) |
| |
779 { |
| |
780 if (event) { |
| |
781 if (text) |
| |
782 event->text = g_strdup(text); |
| |
783 else |
| |
784 event->text = NULL; |
| |
785 } |
| |
786 } |
| |
787 |
| |
788 const char * |
| |
789 nm_event_get_source(NMEvent * event) |
| |
790 { |
| |
791 if (event) |
| |
792 return event->source; |
| |
793 else |
| |
794 return NULL; |
| |
795 } |
| |
796 |
| |
797 int |
| |
798 nm_event_get_type(NMEvent * event) |
| |
799 { |
| |
800 if (event) |
| |
801 return event->type; |
| |
802 else |
| |
803 return -1; |
| |
804 } |
| |
805 |
| |
806 time_t |
| |
807 nm_event_get_gmt(NMEvent * event) |
| |
808 { |
| |
809 if (event) |
| |
810 return event->gmt; |
| |
811 else |
| |
812 return (time_t)-1; |
| |
813 } |
| |
814 |
| |
815 NMERR_T |
| |
816 nm_process_event(NMUser * user, int type) |
| |
817 { |
| |
818 NMERR_T rc = NM_OK; |
| |
819 guint32 size = 0; |
| |
820 NMEvent *event = NULL; |
| |
821 char *source = NULL; |
| |
822 nm_event_cb cb; |
| |
823 NMConn *conn; |
| |
824 |
| |
825 if (user == NULL) |
| |
826 return NMERR_BAD_PARM; |
| |
827 |
| |
828 if (type < NMEVT_START || type > NMEVT_STOP) |
| |
829 return NMERR_PROTOCOL; |
| |
830 |
| |
831 conn = nm_user_get_conn(user); |
| |
832 |
| |
833 /* Read the event source */ |
| |
834 rc = nm_read_uint32(conn, &size); |
| |
835 if (rc == NM_OK) { |
| |
836 if (size > 0) { |
| |
837 source = g_new0(char, size); |
| |
838 |
| |
839 rc = nm_read_all(conn, source, size); |
| |
840 } |
| |
841 } |
| |
842 |
| |
843 /* Read the event data */ |
| |
844 if (rc == NM_OK) { |
| |
845 event = nm_create_event(type, source, time(0)); |
| |
846 |
| |
847 if (event) { |
| |
848 |
| |
849 switch (type) { |
| |
850 case NMEVT_STATUS_CHANGE: |
| |
851 rc = handle_status_change(user, event); |
| |
852 break; |
| |
853 |
| |
854 case NMEVT_RECEIVE_MESSAGE: |
| |
855 rc = handle_receive_message(user, event, FALSE); |
| |
856 break; |
| |
857 |
| |
858 case NMEVT_RECEIVE_AUTOREPLY: |
| |
859 rc = handle_receive_message(user, event, TRUE); |
| |
860 break; |
| |
861 |
| |
862 case NMEVT_USER_TYPING: |
| |
863 case NMEVT_USER_NOT_TYPING: |
| |
864 rc = handle_typing(user, event); |
| |
865 break; |
| |
866 |
| |
867 case NMEVT_CONFERENCE_LEFT: |
| |
868 rc = handle_conference_left(user, event); |
| |
869 break; |
| |
870 |
| |
871 case NMEVT_CONFERENCE_CLOSED: |
| |
872 rc = handle_conference_closed(user, event); |
| |
873 break; |
| |
874 |
| |
875 case NMEVT_CONFERENCE_JOINED: |
| |
876 rc = handle_conference_joined(user, event); |
| |
877 break; |
| |
878 |
| |
879 case NMEVT_CONFERENCE_INVITE: |
| |
880 rc = handle_conference_invite(user, event); |
| |
881 break; |
| |
882 |
| |
883 case NMEVT_CONFERENCE_REJECT: |
| |
884 rc = handle_conference_reject(user, event); |
| |
885 break; |
| |
886 |
| |
887 case NMEVT_CONFERENCE_INVITE_NOTIFY: |
| |
888 rc = handle_conference_invite_notify(user, event); |
| |
889 break; |
| |
890 |
| |
891 case NMEVT_UNDELIVERABLE_STATUS: |
| |
892 rc = handle_undeliverable_status(user, event); |
| |
893 break; |
| |
894 |
| |
895 case NMEVT_INVALID_RECIPIENT: |
| |
896 /* Nothing else to read, just callback */ |
| |
897 break; |
| |
898 |
| |
899 case NMEVT_USER_DISCONNECT: |
| |
900 /* Nothing else to read, just callback */ |
| |
901 break; |
| |
902 |
| |
903 case NMEVT_SERVER_DISCONNECT: |
| |
904 /* Nothing else to read, just callback */ |
| |
905 break; |
| |
906 |
| |
907 case NMEVT_RECEIVE_FILE: |
| |
908 case NMEVT_CONTACT_ADD: |
| |
909 /* Safely ignored for now */ |
| |
910 break; |
| |
911 |
| |
912 default: |
| |
913 gaim_debug(GAIM_DEBUG_INFO, "novell", |
| |
914 "Unknown event %d received.\n", type); |
| |
915 rc = NMERR_PROTOCOL; |
| |
916 break; |
| |
917 } |
| |
918 } |
| |
919 } |
| |
920 |
| |
921 if (rc == (NMERR_T)-1) { |
| |
922 /* -1 means that we are not ready to callback yet. */ |
| |
923 rc = NM_OK; |
| |
924 } else if (rc == NM_OK && (cb = nm_user_get_event_callback(user))) { |
| |
925 |
| |
926 cb(user, event); |
| |
927 |
| |
928 if (event) |
| |
929 nm_release_event(event); |
| |
930 } else { |
| |
931 if (event) |
| |
932 nm_release_event(event); |
| |
933 } |
| |
934 |
| |
935 /* Cleanup */ |
| |
936 if (source) |
| |
937 g_free(source); |
| |
938 |
| |
939 return rc; |
| |
940 } |