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