Mercurial > pidgin
annotate src/protocols/novell/nmevent.c @ 9251:45d2ad4ac1c1
[gaim-migrate @ 10050]
Stu Tomlinson has provided a nice patch to move the separation of IM
and Chat windows back into the core from the extplacement plugin.
It's awesome to have crazy patch writers, and even better to have
crazy patch writers who write what I want to write before I do it,
thus saving me the effort.
committer: Tailor Script <tailor@pidgin.im>
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Wed, 09 Jun 2004 20:47:07 +0000 |
parents | 6663ad2386d9 |
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 } |