Mercurial > pidgin
annotate src/protocols/novell/nmevent.c @ 8718:6ab61697426e
[gaim-migrate @ 9473]
simguy wants this
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Tue, 20 Apr 2004 04:04:41 +0000 |
parents | 046dd8ef2920 |
children | a2affcdf8e01 |
rev | line source |
---|---|
8675 | 1 /* |
2 * nmevent.c | |
3 * | |
4 * Copyright © 2004 Unpublished Work of Novell, Inc. All Rights Reserved. | |
5 * | |
6 * THIS WORK IS AN UNPUBLISHED WORK OF NOVELL, INC. NO PART OF THIS WORK MAY BE | |
7 * USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, | |
8 * TRANSLATED, ABRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, | |
9 * RECAST, TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, | |
10 * INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT | |
11 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
12 * |
8675 | 13 * AS BETWEEN [GAIM] AND NOVELL, NOVELL GRANTS [GAIM] THE RIGHT TO REPUBLISH |
14 * THIS WORK UNDER THE GPL (GNU GENERAL PUBLIC LICENSE) WITH ALL RIGHTS AND | |
15 * LICENSES THEREUNDER. IF YOU HAVE RECEIVED THIS WORK DIRECTLY OR INDIRECTLY | |
16 * FROM [GAIM] AS PART OF SUCH A REPUBLICATION, YOU HAVE ALL RIGHTS AND LICENSES | |
17 * GRANTED BY [GAIM] UNDER THE GPL. IN CONNECTION WITH SUCH A REPUBLICATION, IF | |
18 * ANYTHING IN THIS NOTICE CONFLICTS WITH THE TERMS OF THE GPL, SUCH TERMS | |
19 * PREVAIL. | |
20 * | |
21 */ | |
22 | |
23 #include <glib.h> | |
24 #include <string.h> | |
25 #include <time.h> | |
26 #include "nmevent.h" | |
27 #include "nmfield.h" | |
28 #include "nmconn.h" | |
29 #include "nmuserrecord.h" | |
30 | |
31 struct _NMEvent | |
32 { | |
33 | |
34 /* Event type */ | |
35 int type; | |
36 | |
37 /* The DN of the event source */ | |
38 char *source; | |
39 | |
40 /* Timestamp of the event */ | |
41 guint32 gmt; | |
42 | |
43 /* Conference to associate with the event */ | |
44 NMConference *conference; | |
45 | |
46 /* User record to associate with the event */ | |
47 NMUserRecord *user_record; | |
48 | |
49 /* Text associated with the event */ | |
50 char *text; | |
51 | |
52 /* Reference count for event structure */ | |
53 int ref_count; | |
54 | |
55 }; | |
56 | |
57 /* Return a copy of src minus the RTF */ | |
58 static char * | |
59 _strip_rtf(const char *src, int len) | |
60 { | |
61 const char *p = src; | |
62 char *q; | |
63 char *dest = g_new0(char, len + 1); | |
64 int level = 0; | |
65 | |
66 /* Make sure we are dealing with rtf */ | |
67 if (strncmp("{\\rtf1", src, strlen("{\\rtf1")) != 0) { | |
68 strncpy(dest, src, len); | |
69 return dest; | |
70 } | |
71 p += strlen("{\\rtf1"); | |
72 | |
73 q = dest; | |
74 while (*p != '\0') { | |
75 if (*p == '\\') { | |
76 if (level == 0) { | |
77 if (*(p + 1) == '\\' || *(p + 1) == '{' || *(p + 1) == '}') { | |
78 *q++ = *(p + 1); | |
79 p++; | |
80 } else if (*(p + 1) == 't' && *(p + 2) == 'a' && *(p + 3) == 'b') { | |
81 *q++ = '\t'; | |
82 p++; | |
83 } | |
84 } | |
85 p++; | |
86 } else if (*p == '{') { | |
87 level++; | |
88 p++; | |
89 } else if (*p == '}') { | |
90 level--; | |
91 p++; | |
92 } else if (level == 0) { | |
93 if ((*p == ' ' || *p == '\r') && (*(p + 1) != '\\')) { | |
94 p++; | |
95 | |
96 if (*p == '\n' && | |
97 (*(p + 1) == '{' || *(p + 1) == '}' || *(p + 1) == '\\')) { | |
98 p++; | |
99 } else { | |
100 /* We found some text */ | |
101 while (*p != '\0' && *p != '\\' && *p != '{' && *p != '}') { | |
102 *q++ = *p; | |
103 p++; | |
104 } | |
105 } | |
106 } else { | |
107 p++; | |
108 } | |
109 } else { | |
110 p++; | |
111 } | |
112 } | |
113 | |
114 return dest; | |
115 } | |
116 | |
117 /* Handle getdetails response and set the new user record into the event */ | |
118 static void | |
119 _got_user_for_event(NMUser * user, NMERR_T ret_val, | |
120 gpointer resp_data, gpointer user_data) | |
121 { | |
122 NMUserRecord *user_record; | |
123 NMEvent *event; | |
124 nm_event_cb cb; | |
125 | |
126 if (user == NULL) | |
127 return; | |
128 | |
129 user_record = resp_data; | |
130 event = user_data; | |
131 | |
132 if (ret_val == NM_OK) { | |
133 if (event && user_record) { | |
134 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
135 /* Add the user record to the event structure |
8675 | 136 * and make the callback. |
137 */ | |
138 nm_event_set_user_record(event, user_record); | |
139 if ((cb = nm_user_get_event_callback(user))) { | |
140 cb(user, event); | |
141 } | |
142 } | |
143 | |
144 } else { | |
145 /* Cleanup resp_data */ | |
146 | |
147 } | |
148 | |
149 /* Clean up */ | |
150 if (event) | |
151 nm_release_event(event); | |
152 | |
153 } | |
154 | |
155 /* Handle getdetails response, set the new user record into the event | |
156 * and add the user record as a participant in the conference | |
157 */ | |
158 static void | |
159 _got_user_for_conference(NMUser * user, NMERR_T ret_val, | |
160 gpointer resp_data, gpointer user_data) | |
161 { | |
162 NMUserRecord *user_record = resp_data; | |
163 NMEvent *event = user_data; | |
164 NMConference *conference; | |
165 nm_event_cb cb; | |
166 | |
167 if (user == NULL) | |
168 return; | |
169 | |
170 if (event && user_record) { | |
171 | |
172 conference = nm_event_get_conference(event); | |
173 if (conference) { | |
174 | |
175 /* Add source of event as recip of the conference */ | |
176 nm_conference_add_participant(conference, user_record); | |
177 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
178 /* Add the user record to the event structure |
8675 | 179 * and make the callback. |
180 */ | |
181 nm_event_set_user_record(event, user_record); | |
182 if ((cb = nm_user_get_event_callback(user))) { | |
183 cb(user, event); | |
184 } | |
185 } | |
186 } | |
187 | |
188 if (event) | |
189 nm_release_event(event); | |
190 } | |
191 | |
192 /* Read the receive message event, set up the event object, and | |
193 * get details for the event source if we don't have them yet. | |
194 */ | |
195 static NMERR_T | |
196 handle_receive_message(NMUser * user, NMEvent * event, gboolean autoreply) | |
197 { | |
198 NMConference *conference; | |
199 NMUserRecord *user_record; | |
200 NMConn *conn; | |
201 NMERR_T rc = NM_OK; | |
202 guint32 size = 0, flags = 0; | |
203 char *msg = NULL; | |
204 char *nortf = NULL; | |
205 char *guid = NULL; | |
206 | |
207 conn = nm_user_get_conn(user); | |
208 | |
209 /* Read the conference guid */ | |
210 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
211 if (rc == NM_OK) { | |
212 guid = g_new0(char, size + 1); | |
213 rc = nm_read_all(conn, guid, size); | |
214 } | |
215 | |
216 /* Read the conference flags */ | |
217 if (rc == NM_OK) { | |
218 rc = nm_read_all(conn, (char *) &flags, sizeof(flags)); | |
219 } | |
220 | |
221 /* Read the message text */ | |
222 if (rc == NM_OK) { | |
223 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
224 if (rc == NM_OK) { | |
225 | |
226 msg = g_new0(char, size + 1); | |
227 rc = nm_read_all(conn, msg, size); | |
228 | |
229 gaim_debug(GAIM_DEBUG_INFO, "novell", "Message is %s\n", msg); | |
230 | |
231 /* Auto replies are not in RTF format! */ | |
232 if (!autoreply) { | |
233 | |
234 nortf = _strip_rtf((const char *) msg, size); | |
235 | |
236 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
237 "Message without RTF is %s\n", nortf); | |
238 | |
239 /* Store the event data */ | |
240 nm_event_set_text(event, nortf); | |
241 | |
242 } else { | |
243 | |
244 /* Store the event data */ | |
245 nm_event_set_text(event, msg); | |
246 } | |
247 } | |
248 } | |
249 | |
250 /* Check to see if we already know about the conference */ | |
251 conference = nm_conference_list_find(user, guid); | |
252 if (conference) { | |
253 | |
254 nm_conference_set_flags(conference, flags); | |
255 nm_event_set_conference(event, conference); | |
256 | |
257 /* Add a reference to the user record in our event object */ | |
258 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
259 if (user_record) { | |
260 nm_event_set_user_record(event, user_record); | |
261 } | |
262 | |
263 } else { | |
264 | |
265 /* This is a new conference, so create one and add it to our list */ | |
266 conference = nm_create_conference(guid); | |
267 nm_conference_set_flags(conference, flags); | |
268 | |
269 /* Add a reference to the conference in the event */ | |
270 nm_event_set_conference(event, conference); | |
271 | |
272 /* Add new conference to the conference list */ | |
273 nm_conference_list_add(user, conference); | |
274 | |
275 /* Check to see if we have details for the event source yet */ | |
276 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
277 if (user_record) { | |
278 | |
279 /* We do so add the user record as a recipient of the conference */ | |
280 nm_conference_add_participant(conference, user_record); | |
281 | |
282 /* Add a reference to the user record in our event object */ | |
283 nm_event_set_user_record(event, user_record); | |
284 | |
285 } else { | |
286 | |
287 /* Need to go to the server to get details for the user */ | |
288 rc = nm_send_get_details(user, nm_event_get_source(event), | |
289 _got_user_for_conference, event); | |
290 if (rc == NM_OK) | |
291 rc = -1; /* Not done processing the event yet! */ | |
292 } | |
293 | |
294 nm_release_conference(conference); | |
295 } | |
296 | |
297 if (msg) | |
298 g_free(msg); | |
299 | |
300 if (nortf) | |
301 g_free(nortf); | |
302 | |
303 if (guid) | |
304 g_free(guid); | |
305 | |
306 return rc; | |
307 } | |
308 | |
309 /* Read the invite event, set up the event object, and | |
310 * get details for the event source if we don't have them yet. | |
311 */ | |
312 static NMERR_T | |
313 handle_conference_invite(NMUser * user, NMEvent * event) | |
314 { | |
315 NMERR_T rc = NM_OK; | |
316 guint32 size = 0; | |
317 char *guid = NULL; | |
318 char *msg = NULL; | |
319 NMConn *conn; | |
320 NMUserRecord *user_record; | |
321 | |
322 conn = nm_user_get_conn(user); | |
323 | |
324 /* Read the conference guid */ | |
325 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
326 if (rc == NM_OK) { | |
327 guid = g_new0(char, size + 1); | |
328 rc = nm_read_all(conn, guid, size); | |
329 } | |
330 | |
331 /* Read the the message */ | |
332 if (rc == NM_OK) { | |
333 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
334 if (rc == NM_OK) { | |
335 msg = g_new0(char, size + 1); | |
336 rc = nm_read_all(conn, msg, size); | |
337 } | |
338 } | |
339 | |
340 /* Store the event data */ | |
341 if (rc == NM_OK) { | |
342 NMConference *conference; | |
343 | |
344 nm_event_set_text(event, msg); | |
345 | |
346 conference = nm_conference_list_find(user, guid); | |
347 if (conference == NULL) { | |
348 conference = nm_create_conference(guid); | |
349 | |
350 /* Add new conference to the list and the event */ | |
351 nm_conference_list_add(user, conference); | |
352 nm_event_set_conference(event, conference); | |
353 | |
354 /* Check to see if we have details for the event source yet */ | |
355 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
356 if (user_record) { | |
357 | |
358 /* Add a reference to the user record in our event object */ | |
359 nm_event_set_user_record(event, user_record); | |
360 | |
361 } else { | |
362 | |
363 /* Need to go to the server to get details for the user */ | |
364 rc = nm_send_get_details(user, nm_event_get_source(event), | |
365 _got_user_for_event, event); | |
366 if (rc == NM_OK) | |
367 rc = -1; /* Not done processing the event yet! */ | |
368 } | |
369 | |
370 nm_release_conference(conference); | |
371 | |
372 } | |
373 } | |
374 | |
375 if (msg) | |
376 g_free(msg); | |
377 | |
378 if (guid) | |
379 g_free(guid); | |
380 | |
381 return rc; | |
382 } | |
383 | |
384 /* Read the invite notify event, set up the event object, and | |
385 * get details for the event source if we don't have them yet. | |
386 */ | |
387 static NMERR_T | |
388 handle_conference_invite_notify(NMUser * user, NMEvent * event) | |
389 { | |
390 NMERR_T rc = NM_OK; | |
391 guint32 size = 0; | |
392 char *guid = NULL; | |
393 NMConn *conn; | |
394 NMConference *conference; | |
395 NMUserRecord *user_record; | |
396 | |
397 conn = nm_user_get_conn(user); | |
398 | |
399 /* Read the conference guid */ | |
400 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
401 if (rc == NM_OK) { | |
402 guid = g_new0(char, size + 1); | |
403 rc = nm_read_all(conn, guid, size); | |
404 } | |
405 | |
406 conference = nm_conference_list_find(user, guid); | |
407 if (conference) { | |
408 nm_event_set_conference(event, conference); | |
409 | |
410 /* Check to see if we have details for the event source yet */ | |
411 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
412 if (user_record) { | |
413 | |
414 /* Add a reference to the user record in our event object */ | |
415 nm_event_set_user_record(event, user_record); | |
416 | |
417 } else { | |
418 | |
419 /* Need to go to the server to get details for the user */ | |
420 rc = nm_send_get_details(user, nm_event_get_source(event), | |
421 _got_user_for_event, event); | |
422 if (rc == NM_OK) | |
423 rc = -1; /* Not done processing the event yet! */ | |
424 } | |
425 | |
426 } else { | |
427 rc = NMERR_CONFERENCE_NOT_FOUND; | |
428 } | |
429 | |
430 | |
431 if (guid) | |
432 g_free(guid); | |
433 | |
434 return rc; | |
435 } | |
436 | |
437 /* Read the conference reject event and set up the event object */ | |
438 static NMERR_T | |
439 handle_conference_reject(NMUser * user, NMEvent * event) | |
440 { | |
441 NMERR_T rc = NM_OK; | |
442 guint32 size = 0; | |
443 char *guid = NULL; | |
444 NMConn *conn; | |
445 NMConference *conference; | |
446 | |
447 conn = nm_user_get_conn(user); | |
448 | |
449 /* Read the conference guid */ | |
450 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
451 if (rc == NM_OK) { | |
452 guid = g_new0(char, size + 1); | |
453 rc = nm_read_all(conn, guid, size); | |
454 } | |
455 | |
456 if (rc == NM_OK) { | |
457 conference = nm_conference_list_find(user, guid); | |
458 if (conference) { | |
459 nm_event_set_conference(event, conference); | |
460 } else { | |
461 rc = NMERR_CONFERENCE_NOT_FOUND; | |
462 } | |
463 } | |
464 | |
465 if (guid) | |
466 g_free(guid); | |
467 | |
468 return rc; | |
469 } | |
470 | |
471 /* 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
|
472 * remove the conference from the list if there are no more |
8675 | 473 * participants |
474 */ | |
475 static NMERR_T | |
476 handle_conference_left(NMUser * user, NMEvent * event) | |
477 { | |
478 NMERR_T rc = NM_OK; | |
479 guint32 size = 0, flags = 0; | |
480 char *guid = NULL; | |
481 NMConference *conference; | |
482 NMConn *conn; | |
483 | |
484 conn = nm_user_get_conn(user); | |
485 | |
486 /* Read the conference guid */ | |
487 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
488 if (rc == NM_OK) { | |
489 guid = g_new0(char, size + 1); | |
490 rc = nm_read_all(conn, guid, size); | |
491 } | |
492 | |
493 /* Read the conference flags */ | |
494 if (rc == NM_OK) { | |
495 rc = nm_read_all(conn, (char *) &flags, sizeof(flags)); | |
496 } | |
497 | |
498 if (rc == NM_OK) { | |
499 conference = nm_conference_list_find(user, guid); | |
500 if (conference) { | |
501 nm_event_set_conference(event, conference); | |
502 nm_conference_set_flags(conference, flags); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
503 |
8675 | 504 nm_conference_remove_participant(conference, nm_event_get_source(event)); |
505 if (nm_conference_get_participant_count(conference) == 0) { | |
506 nm_conference_list_remove(user, conference); | |
507 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
508 |
8675 | 509 } else { |
510 rc = NMERR_CONFERENCE_NOT_FOUND; | |
511 } | |
512 } | |
513 | |
514 if (guid) | |
515 g_free(guid); | |
516 | |
517 return rc; | |
518 } | |
519 | |
520 /* Read the conference closed, set up the event object, and | |
521 * remove the conference from the list | |
522 */ | |
523 static NMERR_T | |
524 handle_conference_closed(NMUser * user, NMEvent * event) | |
525 { | |
526 NMERR_T rc = NM_OK; | |
527 guint32 size = 0; | |
528 char *guid = NULL; | |
529 NMConference *conference; | |
530 NMConn *conn; | |
531 | |
532 conn = nm_user_get_conn(user); | |
533 | |
534 /* Read the conference guid */ | |
535 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
536 if (rc == NM_OK) { | |
537 guid = g_new0(char, size + 1); | |
538 rc = nm_read_all(conn, guid, size); | |
539 } | |
540 | |
541 if (rc == NM_OK) { | |
542 conference = nm_conference_list_find(user, guid); | |
543 if (conference) { | |
544 nm_event_set_conference(event, conference); | |
545 nm_conference_list_remove(user, conference); | |
546 } else { | |
547 rc = NMERR_CONFERENCE_NOT_FOUND; | |
548 } | |
549 } | |
550 | |
551 if (guid) | |
552 g_free(guid); | |
553 | |
554 return rc; | |
555 } | |
556 | |
557 /* Read the conference joined event, set up the event object, and | |
558 * get details for the event source if we don't have them yet. | |
559 */ | |
560 static NMERR_T | |
561 handle_conference_joined(NMUser * user, NMEvent * event) | |
562 { | |
563 NMERR_T rc = NM_OK; | |
564 guint32 size = 0, flags = 0; | |
565 char *guid = NULL; | |
566 NMConn *conn; | |
567 NMConference *conference; | |
568 NMUserRecord *user_record; | |
569 | |
570 conn = nm_user_get_conn(user); | |
571 | |
572 /* Read the conference guid */ | |
573 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
574 if (rc == NM_OK) { | |
575 guid = g_new0(char, size + 1); | |
576 rc = nm_read_all(conn, guid, size); | |
577 } | |
578 | |
579 /* Read the conference flags */ | |
580 if (rc == NM_OK) { | |
581 rc = nm_read_all(conn, (char *) &flags, sizeof(flags)); | |
582 } | |
583 | |
584 if (rc == NM_OK) { | |
585 conference = nm_conference_list_find(user, guid); | |
586 if (conference) { | |
587 nm_conference_set_flags(conference, flags); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
588 |
8675 | 589 nm_event_set_conference(event, conference); |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
590 |
8675 | 591 /* Add the new user to the participants list */ |
592 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
593 if (user_record) { | |
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 */ | |
628 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
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 */ | |
665 rc = nm_read_all(conn, (char *) &status, sizeof(status)); | |
666 if (rc == NM_OK) { | |
667 | |
668 /* Read the status text */ | |
669 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
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 */ | |
707 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
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 */ | |
867 rc = nm_read_all(conn, (char *) &size, sizeof(size)); | |
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 } |