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.
|
|
12 *
|
|
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
|
|
135 /* Add the user record to the event structure
|
|
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
|
|
178 /* Add the user record to the event structure
|
|
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
|
|
472 * remove the conference from the list if there are no more
|
|
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);
|
|
503
|
|
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 }
|
|
508
|
|
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);
|
|
588
|
|
589 nm_event_set_conference(event, conference);
|
|
590
|
|
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 {
|
|
596
|
|
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 }
|
|
603
|
|
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 }
|