4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
27 #include "nmuserrecord.h"
30 #define MAX_UINT32 0xFFFFFFFF
38 /* The DN of the event source */
41 /* Timestamp of the event */
44 /* Conference to associate with the event */
45 NMConference
*conference
;
47 /* User record to associate with the event */
48 NMUserRecord
*user_record
;
50 /* Text associated with the event */
53 /* Reference count for event structure */
58 /* Handle getdetails response and set the new user record into the event */
60 _got_user_for_event(NMUser
* user
, NMERR_T ret_val
,
61 gpointer resp_data
, gpointer user_data
)
63 NMUserRecord
*user_record
;
70 user_record
= resp_data
;
73 if (ret_val
== NM_OK
) {
74 if (event
&& user_record
) {
76 /* Add the user record to the event structure
77 * and make the callback.
79 nm_event_set_user_record(event
, user_record
);
80 if ((cb
= nm_user_get_event_callback(user
))) {
86 /* Cleanup resp_data */
92 nm_release_event(event
);
96 /* Handle getdetails response, set the new user record into the event
97 * and add the user record as a participant in the conference
100 _got_user_for_conference(NMUser
* user
, NMERR_T ret_val
,
101 gpointer resp_data
, gpointer user_data
)
103 NMUserRecord
*user_record
= resp_data
;
104 NMEvent
*event
= user_data
;
105 NMConference
*conference
;
111 if (event
&& user_record
) {
113 conference
= nm_event_get_conference(event
);
116 /* Add source of event as recip of the conference */
117 nm_conference_add_participant(conference
, user_record
);
119 /* Add the user record to the event structure
120 * and make the callback.
122 nm_event_set_user_record(event
, user_record
);
123 if ((cb
= nm_user_get_event_callback(user
))) {
130 nm_release_event(event
);
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.
137 handle_receive_message(NMUser
* user
, NMEvent
* event
, gboolean autoreply
)
139 NMConference
*conference
;
140 NMUserRecord
*user_record
;
143 guint32 size
= 0, flags
= 0;
148 conn
= nm_user_get_conn(user
);
150 /* Read the conference guid */
151 rc
= nm_read_uint32(conn
, &size
);
152 if (size
> 1000) return NMERR_PROTOCOL
;
155 guid
= g_new0(char, size
+ 1);
156 rc
= nm_read_all(conn
, guid
, size
);
159 /* Read the conference flags */
161 rc
= nm_read_uint32(conn
, &flags
);
164 /* Read the message text */
166 rc
= nm_read_uint32(conn
, &size
);
167 if (size
> 100000) return NMERR_PROTOCOL
;
170 msg
= g_new0(char, size
+ 1);
171 rc
= nm_read_all(conn
, msg
, size
);
173 purple_debug(PURPLE_DEBUG_INFO
, "novell", "Message is %s\n", msg
);
175 /* Auto replies are not in RTF format! */
180 nortf
= nm_rtf_strip_formatting(ctx
, msg
);
183 purple_debug(PURPLE_DEBUG_INFO
, "novell",
184 "Message without RTF is %s\n", nortf
);
186 /* Store the event data */
187 nm_event_set_text(event
, nortf
);
191 /* Store the event data */
192 nm_event_set_text(event
, msg
);
197 /* Check to see if we already know about the conference */
198 conference
= nm_conference_list_find(user
, guid
);
201 nm_conference_set_flags(conference
, flags
);
202 nm_event_set_conference(event
, conference
);
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
));
207 nm_event_set_user_record(event
, user_record
);
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
);
216 /* Add a reference to the conference in the event */
217 nm_event_set_conference(event
, conference
);
219 /* Add new conference to the conference list */
220 nm_conference_list_add(user
, conference
);
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
));
226 /* We do so add the user record as a recipient of the conference */
227 nm_conference_add_participant(conference
, user_record
);
229 /* Add a reference to the user record in our event object */
230 nm_event_set_user_record(event
, user_record
);
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
);
238 rc
= -1; /* Not done processing the event yet! */
241 nm_release_conference(conference
);
251 /* Read the invite event, set up the event object, and
252 * get details for the event source if we don't have them yet.
255 handle_conference_invite(NMUser
* user
, NMEvent
* event
)
262 NMUserRecord
*user_record
;
264 conn
= nm_user_get_conn(user
);
266 /* Read the conference guid */
267 rc
= nm_read_uint32(conn
, &size
);
268 if (size
> 1000) return NMERR_PROTOCOL
;
271 guid
= g_new0(char, size
+ 1);
272 rc
= nm_read_all(conn
, guid
, size
);
275 /* Read the the message */
277 rc
= nm_read_uint32(conn
, &size
);
278 if (size
> 100000) return NMERR_PROTOCOL
;
281 msg
= g_new0(char, size
+ 1);
282 rc
= nm_read_all(conn
, msg
, size
);
286 /* Store the event data */
288 NMConference
*conference
;
290 nm_event_set_text(event
, msg
);
292 conference
= nm_conference_list_find(user
, guid
);
293 if (conference
== NULL
) {
294 conference
= nm_create_conference(guid
);
296 /* Add new conference to the list and the event */
297 nm_conference_list_add(user
, conference
);
298 nm_event_set_conference(event
, conference
);
300 /* Check to see if we have details for the event source yet */
301 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
304 /* Add a reference to the user record in our event object */
305 nm_event_set_user_record(event
, user_record
);
309 /* Need to go to the server to get details for the user */
310 rc
= nm_send_get_details(user
, nm_event_get_source(event
),
311 _got_user_for_event
, event
);
313 rc
= -1; /* Not done processing the event yet! */
316 nm_release_conference(conference
);
327 /* Read the invite notify event, set up the event object, and
328 * get details for the event source if we don't have them yet.
331 handle_conference_invite_notify(NMUser
* user
, NMEvent
* event
)
337 NMConference
*conference
;
338 NMUserRecord
*user_record
;
340 conn
= nm_user_get_conn(user
);
342 /* Read the conference guid */
343 rc
= nm_read_uint32(conn
, &size
);
344 if (size
> 1000) return NMERR_PROTOCOL
;
347 guid
= g_new0(char, size
+ 1);
348 rc
= nm_read_all(conn
, guid
, size
);
351 conference
= nm_conference_list_find(user
, guid
);
353 nm_event_set_conference(event
, conference
);
355 /* Check to see if we have details for the event source yet */
356 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
359 /* Add a reference to the user record in our event object */
360 nm_event_set_user_record(event
, user_record
);
364 /* Need to go to the server to get details for the user */
365 rc
= nm_send_get_details(user
, nm_event_get_source(event
),
366 _got_user_for_event
, event
);
368 rc
= -1; /* Not done processing the event yet! */
372 rc
= NMERR_CONFERENCE_NOT_FOUND
;
381 /* Read the conference reject event and set up the event object */
383 handle_conference_reject(NMUser
* user
, NMEvent
* event
)
389 NMConference
*conference
;
391 conn
= nm_user_get_conn(user
);
393 /* Read the conference guid */
394 rc
= nm_read_uint32(conn
, &size
);
395 if (size
> 1000) return NMERR_PROTOCOL
;
398 guid
= g_new0(char, size
+ 1);
399 rc
= nm_read_all(conn
, guid
, size
);
403 conference
= nm_conference_list_find(user
, guid
);
405 nm_event_set_conference(event
, conference
);
407 rc
= NMERR_CONFERENCE_NOT_FOUND
;
416 /* Read the conference left event, set up the event object, and
417 * remove the conference from the list if there are no more
421 handle_conference_left(NMUser
* user
, NMEvent
* event
)
424 guint32 size
= 0, flags
= 0;
426 NMConference
*conference
;
429 conn
= nm_user_get_conn(user
);
431 /* Read the conference guid */
432 rc
= nm_read_uint32(conn
, &size
);
433 if (size
> 1000) return NMERR_PROTOCOL
;
436 guid
= g_new0(char, size
+ 1);
437 rc
= nm_read_all(conn
, guid
, size
);
440 /* Read the conference flags */
442 rc
= nm_read_uint32(conn
, &flags
);
446 conference
= nm_conference_list_find(user
, guid
);
448 nm_event_set_conference(event
, conference
);
449 nm_conference_set_flags(conference
, flags
);
451 nm_conference_remove_participant(conference
, nm_event_get_source(event
));
452 if (nm_conference_get_participant_count(conference
) == 0) {
453 nm_conference_list_remove(user
, conference
);
457 rc
= NMERR_CONFERENCE_NOT_FOUND
;
466 /* Read the conference closed, set up the event object, and
467 * remove the conference from the list
470 handle_conference_closed(NMUser
* user
, NMEvent
* event
)
475 NMConference
*conference
;
478 conn
= nm_user_get_conn(user
);
480 /* Read the conference guid */
481 rc
= nm_read_uint32(conn
, &size
);
482 if (size
> 1000) return NMERR_PROTOCOL
;
485 guid
= g_new0(char, size
+ 1);
486 rc
= nm_read_all(conn
, guid
, size
);
490 conference
= nm_conference_list_find(user
, guid
);
492 nm_event_set_conference(event
, conference
);
493 nm_conference_list_remove(user
, conference
);
495 rc
= NMERR_CONFERENCE_NOT_FOUND
;
504 /* Read the conference joined event, set up the event object, and
505 * get details for the event source if we don't have them yet.
508 handle_conference_joined(NMUser
* user
, NMEvent
* event
)
511 guint32 size
= 0, flags
= 0;
514 NMConference
*conference
;
515 NMUserRecord
*user_record
;
517 conn
= nm_user_get_conn(user
);
519 /* Read the conference guid */
520 rc
= nm_read_uint32(conn
, &size
);
521 if (size
> 1000) return NMERR_PROTOCOL
;
524 guid
= g_new0(char, size
+ 1);
525 rc
= nm_read_all(conn
, guid
, size
);
528 /* Read the conference flags */
530 rc
= nm_read_uint32(conn
, &flags
);
534 conference
= nm_conference_list_find(user
, guid
);
536 nm_conference_set_flags(conference
, flags
);
538 nm_event_set_conference(event
, conference
);
540 /* Add the new user to the participants list */
541 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
543 nm_conference_remove_participant(conference
,
544 nm_user_record_get_dn(user_record
));
545 nm_conference_add_participant(conference
, user_record
);
548 /* Need to go to the server to get details for the user */
549 rc
= nm_send_get_details(user
, nm_event_get_source(event
),
550 _got_user_for_conference
, event
);
552 rc
= -1; /* Not done processing the event yet! */
556 rc
= NMERR_CONFERENCE_NOT_FOUND
;
565 /* Read the typing event and set up the event object */
567 handle_typing(NMUser
* user
, NMEvent
* event
)
572 NMConference
*conference
;
575 conn
= nm_user_get_conn(user
);
577 /* Read the conference guid */
578 rc
= nm_read_uint32(conn
, &size
);
579 if (size
> 1000) return NMERR_PROTOCOL
;
582 guid
= g_new0(char, size
+ 1);
583 rc
= nm_read_all(conn
, guid
, size
);
587 conference
= nm_conference_list_find(user
, guid
);
589 nm_event_set_conference(event
, conference
);
591 rc
= NMERR_CONFERENCE_NOT_FOUND
;
600 /* Read the event, set up the event object, and update
601 * the status in the user record (for the event source)
604 handle_status_change(NMUser
* user
, NMEvent
* event
)
610 NMUserRecord
*user_record
;
613 conn
= nm_user_get_conn(user
);
615 /* Read new status */
616 rc
= nm_read_uint16(conn
, &status
);
619 /* Read the status text */
620 rc
= nm_read_uint32(conn
, &size
);
621 if (size
> 10000) return NMERR_PROTOCOL
;
624 text
= g_new0(char, size
+ 1);
625 rc
= nm_read_all(conn
, text
, size
);
630 nm_event_set_text(event
, text
);
632 /* Get a reference to the user record and store the new status */
633 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
635 nm_event_set_user_record(event
, user_record
);
636 nm_user_record_set_status(user_record
, status
, text
);
645 /* Read the undeliverable event */
647 handle_undeliverable_status(NMUser
* user
, NMEvent
* event
)
654 conn
= nm_user_get_conn(user
);
656 /* Read the conference guid */
657 rc
= nm_read_uint32(conn
, &size
);
658 if (size
> 1000) return NMERR_PROTOCOL
;
661 guid
= g_new0(char, size
+ 1);
662 rc
= nm_read_all(conn
, guid
, size
);
670 /*******************************************************************************
671 * Event API -- see header file for comments
672 ******************************************************************************/
675 nm_create_event(int type
, const char *source
, guint32 gmt
)
677 NMEvent
*event
= g_new0(NMEvent
, 1);
683 event
->source
= g_strdup(source
);
685 event
->ref_count
= 1;
691 nm_release_event(NMEvent
* event
)
697 if (--(event
->ref_count
) == 0) {
699 g_free(event
->source
);
701 if (event
->conference
)
702 nm_release_conference(event
->conference
);
704 if (event
->user_record
)
705 nm_release_user_record(event
->user_record
);
715 nm_event_get_conference(NMEvent
* event
)
718 return event
->conference
;
724 nm_event_set_conference(NMEvent
* event
, NMConference
* conference
)
726 if (event
&& conference
) {
727 nm_conference_add_ref(conference
);
728 event
->conference
= conference
;
733 nm_event_get_user_record(NMEvent
* event
)
736 return event
->user_record
;
742 nm_event_set_user_record(NMEvent
* event
, NMUserRecord
* user_record
)
744 if (event
&& user_record
) {
745 nm_user_record_add_ref(user_record
);
746 event
->user_record
= user_record
;
751 nm_event_get_text(NMEvent
* event
)
760 nm_event_set_text(NMEvent
* event
, const char *text
)
764 event
->text
= g_strdup(text
);
771 nm_event_get_source(NMEvent
* event
)
774 return event
->source
;
780 nm_event_get_type(NMEvent
* event
)
789 nm_event_get_gmt(NMEvent
* event
)
798 nm_process_event(NMUser
* user
, int type
)
802 NMEvent
*event
= NULL
;
808 return NMERR_BAD_PARM
;
810 if (type
< NMEVT_START
|| type
> NMEVT_STOP
)
811 return NMERR_PROTOCOL
;
813 conn
= nm_user_get_conn(user
);
815 /* Read the event source */
816 rc
= nm_read_uint32(conn
, &size
);
818 if (size
> 1000000) {
819 /* Size is larger than our 1MB sanity check. Ignore it. */
822 source
= g_new0(char, size
);
824 rc
= nm_read_all(conn
, source
, size
);
828 /* Read the event data */
830 event
= nm_create_event(type
, source
, time(0));
835 case NMEVT_STATUS_CHANGE
:
836 rc
= handle_status_change(user
, event
);
839 case NMEVT_RECEIVE_MESSAGE
:
840 rc
= handle_receive_message(user
, event
, FALSE
);
843 case NMEVT_RECEIVE_AUTOREPLY
:
844 rc
= handle_receive_message(user
, event
, TRUE
);
847 case NMEVT_USER_TYPING
:
848 case NMEVT_USER_NOT_TYPING
:
849 rc
= handle_typing(user
, event
);
852 case NMEVT_CONFERENCE_LEFT
:
853 rc
= handle_conference_left(user
, event
);
856 case NMEVT_CONFERENCE_CLOSED
:
857 rc
= handle_conference_closed(user
, event
);
860 case NMEVT_CONFERENCE_JOINED
:
861 rc
= handle_conference_joined(user
, event
);
864 case NMEVT_CONFERENCE_INVITE
:
865 rc
= handle_conference_invite(user
, event
);
868 case NMEVT_CONFERENCE_REJECT
:
869 rc
= handle_conference_reject(user
, event
);
872 case NMEVT_CONFERENCE_INVITE_NOTIFY
:
873 rc
= handle_conference_invite_notify(user
, event
);
876 case NMEVT_UNDELIVERABLE_STATUS
:
877 rc
= handle_undeliverable_status(user
, event
);
880 case NMEVT_INVALID_RECIPIENT
:
881 /* Nothing else to read, just callback */
884 case NMEVT_USER_DISCONNECT
:
885 /* Nothing else to read, just callback */
888 case NMEVT_SERVER_DISCONNECT
:
889 /* Nothing else to read, just callback */
892 case NMEVT_RECEIVE_FILE
:
893 case NMEVT_CONTACT_ADD
:
894 /* Safely ignored for now */
898 purple_debug(PURPLE_DEBUG_INFO
, "novell",
899 "Unknown event %d received.\n", type
);
906 if (rc
== (NMERR_T
)-1) {
907 /* -1 means that we are not ready to callback yet. */
909 } else if (rc
== NM_OK
&& (cb
= nm_user_get_event_callback(user
))) {
914 nm_release_event(event
);
917 nm_release_event(event
);