comparison src/protocols/novell/nmuser.c @ 8675:9ee2542d1104

[gaim-migrate @ 9428] A GroupWise plugin from Novell. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Sat, 17 Apr 2004 13:55:28 +0000
parents
children 046dd8ef2920
comparison
equal deleted inserted replaced
8674:8c7da2e36136 8675:9ee2542d1104
1 /*
2 * nmuser.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 "nmfield.h"
26 #include "nmuser.h"
27 #include "nmconn.h"
28 #include "nmcontact.h"
29 #include "nmuserrecord.h"
30 #include "util.h"
31
32 /* This is the template that we wrap outgoing messages in, since the other
33 * GW Messenger clients expect messages to be in RTF.
34 */
35 #define RTF_TEMPLATE "{\\rtf1\\fbidis\\ansi\\ansicpg1252\\deff0\\deflang1033"\
36 "{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 "\
37 "Microsoft Sans Serif;}}\n{\\colortbl ;\\red0"\
38 "\\green0\\blue0;}\n\\viewkind4\\uc1\\pard\\ltrpar"\
39 "\\li50\\ri50\\cf1\\f0\\fs20 %s\\par\n}"
40
41 static NMERR_T nm_process_response(NMUser * user);
42
43 static void _update_contact_list(NMUser * user, NMField * fields);
44
45 /**
46 * See header for comments on on "public" functions
47 */
48
49 NMUser *
50 nm_initialize_user(const char *name, const char *server_addr,
51 int port, gpointer data, nm_event_cb event_callback)
52 {
53 if (name == NULL || server_addr == NULL || event_callback == NULL)
54 return NULL;
55
56 NMUser *user = g_new0(NMUser, 1);
57
58 user->conn = g_new0(NMConn, 1);
59
60 user->contacts =
61 g_hash_table_new_full(g_str_hash, nm_utf8_str_equal,
62 g_free, (GDestroyNotify) nm_release_contact);
63
64 user->user_records =
65 g_hash_table_new_full(g_str_hash, nm_utf8_str_equal, g_free,
66 (GDestroyNotify) nm_release_user_record);
67
68 user->display_id_to_dn = g_hash_table_new_full(g_str_hash, nm_utf8_str_equal,
69 g_free, g_free);
70
71 user->name = g_strdup(name);
72 user->conn->addr = g_strdup(server_addr);
73 user->conn->port = port;
74 user->evt_callback = event_callback;
75 user->client_data = data;
76
77 return user;
78 }
79
80
81 void
82 nm_deinitialize_user(NMUser * user)
83 {
84 NMConn *conn = user->conn;
85
86 g_free(conn->addr);
87 g_free(conn);
88
89 if (user->contacts) {
90 g_hash_table_destroy(user->contacts);
91 }
92
93 if (user->user_records) {
94 g_hash_table_destroy(user->user_records);
95 }
96
97 if (user->display_id_to_dn) {
98 g_hash_table_destroy(user->display_id_to_dn);
99 }
100
101 if (user->name) {
102 g_free(user->name);
103 }
104
105 if (user->user_record) {
106 nm_release_user_record(user->user_record);
107 }
108
109 nm_conference_list_free(user);
110 nm_destroy_contact_list(user);
111
112 g_free(user);
113 }
114
115 NMERR_T
116 nm_send_login(NMUser * user, const char *pwd, const char *my_addr,
117 const char *user_agent, nm_response_cb callback, gpointer data)
118 {
119 NMERR_T rc = NM_OK;
120 NMField *fields = NULL;
121 NMRequest *req = NULL;
122
123 if (user == NULL || pwd == NULL || user_agent == NULL) {
124 return NMERR_BAD_PARM;
125 }
126
127 fields = nm_add_field(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
128 (guint32) g_strdup(user->name), NMFIELD_TYPE_UTF8);
129
130 fields = nm_add_field(fields, NM_A_SZ_CREDENTIALS, 0, NMFIELD_METHOD_VALID, 0,
131 (guint32) g_strdup(pwd), NMFIELD_TYPE_UTF8);
132
133 fields = nm_add_field(fields, NM_A_SZ_USER_AGENT, 0, NMFIELD_METHOD_VALID, 0,
134 (guint32) g_strdup(user_agent), NMFIELD_TYPE_UTF8);
135
136 fields = nm_add_field(fields, NM_A_UD_BUILD, 0, NMFIELD_METHOD_VALID, 0,
137 (guint32) NM_PROTOCOL_VERSION,
138 NMFIELD_TYPE_UDWORD);
139 if (my_addr) {
140 fields = nm_add_field(fields, NM_A_IP_ADDRESS, 0, NMFIELD_METHOD_VALID, 0,
141 (guint32) g_strdup(my_addr), NMFIELD_TYPE_UTF8);
142 }
143
144 /* Send the login */
145 rc = nm_send_request(user->conn, "login", fields, &req);
146 if (rc == NM_OK && req != NULL) {
147 nm_request_set_callback(req, callback);
148 nm_request_set_user_define(req, data);
149 nm_conn_add_request_item(user->conn, req);
150 }
151
152 if (fields) {
153 nm_free_fields(&fields);
154 }
155
156 if (req) {
157 nm_release_request(req);
158 }
159
160 return rc;
161 }
162
163 NMERR_T
164 nm_send_set_status(NMUser * user, int status, const char *text,
165 const char *auto_resp, nm_response_cb callback, gpointer data)
166 {
167 NMERR_T rc = NM_OK;
168 NMField *fields = NULL;
169 NMRequest *req = NULL;
170
171 if (user == NULL)
172 return NMERR_BAD_PARM;
173
174 /* Add the status */
175 fields = nm_add_field(fields, NM_A_SZ_STATUS, 0, NMFIELD_METHOD_VALID, 0,
176 (guint32) g_strdup_printf("%d", status),
177 NMFIELD_TYPE_UTF8);
178
179 /* Add the status text and auto reply text if there is any */
180 if (text) {
181 fields = nm_add_field(fields, NM_A_SZ_STATUS_TEXT,
182 0, NMFIELD_METHOD_VALID, 0,
183 (guint32) g_strdup(text), NMFIELD_TYPE_UTF8);
184 }
185
186 if (auto_resp) {
187 fields = nm_add_field(fields, NM_A_SZ_MESSAGE_BODY, 0,
188 NMFIELD_METHOD_VALID, 0,
189 (guint32) g_strdup(auto_resp), NMFIELD_TYPE_UTF8);
190 }
191
192 rc = nm_send_request(user->conn, "setstatus", fields, &req);
193 if (rc == NM_OK && req) {
194 nm_request_set_callback(req, callback);
195 nm_request_set_user_define(req, data);
196 nm_conn_add_request_item(user->conn, req);
197 }
198
199 if (fields) {
200 nm_free_fields(&fields);
201 }
202
203 if (req) {
204 nm_release_request(req);
205 }
206
207 return rc;
208 }
209
210 NMERR_T
211 nm_send_get_details(NMUser * user, const char *name,
212 nm_response_cb callback, gpointer data)
213 {
214 NMERR_T rc = NM_OK;
215 NMField *fields = NULL;
216 NMRequest *req = NULL;
217
218 if (user == NULL || name == NULL)
219 return NMERR_BAD_PARM;
220
221 /* Add in DN or display id */
222 if (strstr("=", name)) {
223 fields = nm_add_field(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
224 (guint32) g_strdup(name), NMFIELD_TYPE_DN);
225 } else {
226
227 const char *dn = nm_lookup_dn(user, name);
228
229 if (dn) {
230 fields = nm_add_field(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
231 (guint32) g_strdup(name), NMFIELD_TYPE_DN);
232 } else {
233 fields =
234 nm_add_field(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
235 (guint32) g_strdup(name), NMFIELD_TYPE_UTF8);
236 }
237
238 }
239
240 rc = nm_send_request(user->conn, "getdetails", fields, &req);
241 if (rc == NM_OK) {
242 nm_request_set_callback(req, callback);
243 nm_request_set_user_define(req, data);
244 nm_conn_add_request_item(user->conn, req);
245 }
246
247 if (fields)
248 nm_free_fields(&fields);
249
250 if (req)
251 nm_release_request(req);
252
253 return rc;
254 }
255
256 NMERR_T
257 nm_send_create_conference(NMUser * user, NMConference * conference,
258 nm_response_cb callback, gpointer message)
259 {
260 NMERR_T rc = NM_OK;
261 NMField *fields = NULL;
262 NMField *tmp = NULL;
263 NMField *field = NULL;
264 NMRequest *req = NULL;
265 int count, i;
266
267 if (user == NULL || conference == NULL)
268 return NMERR_BAD_PARM;
269
270 /* Add in a blank guid */
271 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
272 (guint32) g_strdup(BLANK_GUID), NMFIELD_TYPE_UTF8);
273
274 fields = nm_add_field(fields, NM_A_FA_CONVERSATION, 0,
275 NMFIELD_METHOD_VALID, 0, (guint32) tmp,
276 NMFIELD_TYPE_ARRAY);
277 tmp = NULL;
278
279 /* Add participants in */
280 count = nm_conference_get_participant_count(conference);
281 for (i = 0; i < count; i++) {
282 NMUserRecord *user_record = nm_conference_get_participant(conference, i);
283
284 if (user_record) {
285 fields = nm_add_field(fields, NM_A_SZ_DN,
286 0, NMFIELD_METHOD_VALID, 0,
287 (guint32)
288 g_strdup(nm_user_record_get_dn(user_record)),
289 NMFIELD_TYPE_DN);
290 }
291 }
292
293 /* Add our user in */
294 field = nm_locate_field(NM_A_SZ_DN, user->fields);
295 if (field) {
296 fields = nm_add_field(fields, NM_A_SZ_DN,
297 0, NMFIELD_METHOD_VALID, 0,
298 (guint32) g_strdup((char *) field->value),
299 NMFIELD_TYPE_DN);
300 }
301
302 rc = nm_send_request(user->conn, "createconf", fields, &req);
303 if (rc == NM_OK && req) {
304 nm_request_set_callback(req, callback);
305 nm_request_set_data(req, conference);
306 nm_request_set_user_define(req, message);
307 nm_conn_add_request_item(user->conn, req);
308 }
309
310 if (req)
311 nm_release_request(req);
312
313 if (fields)
314 nm_free_fields(&fields);
315
316 return rc;
317 }
318
319 NMERR_T
320 nm_send_leave_conference(NMUser * user, NMConference * conference,
321 nm_response_cb callback, gpointer message)
322 {
323
324 NMERR_T rc = NM_OK;
325 NMField *fields = NULL;
326 NMField *tmp = NULL;
327 NMRequest *req = NULL;
328
329 if (user == NULL || conference == NULL)
330 return NMERR_BAD_PARM;
331
332 /* Add in the conference guid */
333 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
334 (guint32) g_strdup(nm_conference_get_guid(conference)),
335 NMFIELD_TYPE_UTF8);
336
337 fields = nm_add_field(fields, NM_A_FA_CONVERSATION, 0,
338 NMFIELD_METHOD_VALID, 0, (guint32) tmp,
339 NMFIELD_TYPE_ARRAY);
340 tmp = NULL;
341
342 /* Send the request to the server */
343 rc = nm_send_request(user->conn, "leaveconf", fields, &req);
344 if (rc == NM_OK && req) {
345 nm_request_set_callback(req, callback);
346 nm_request_set_data(req, conference);
347 nm_request_set_user_define(req, message);
348 nm_conn_add_request_item(user->conn, req);
349 }
350
351 if (req)
352 nm_release_request(req);
353
354 if (fields)
355 nm_free_fields(&fields);
356
357 return rc;
358 }
359
360 NMERR_T
361 nm_send_join_conference(NMUser * user, NMConference * conference,
362 nm_response_cb callback, gpointer data)
363 {
364 NMERR_T rc = NM_OK;
365 NMField *fields = NULL, *tmp = NULL;
366 NMRequest *req = NULL;
367
368 if (user == NULL || conference == NULL)
369 return NMERR_BAD_PARM;
370
371 /* Add in the conference guid */
372 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
373 (guint32) g_strdup(nm_conference_get_guid(conference)),
374 NMFIELD_TYPE_UTF8);
375
376 fields = nm_add_field(fields, NM_A_FA_CONVERSATION, 0,
377 NMFIELD_METHOD_VALID, 0, (guint32) tmp,
378 NMFIELD_TYPE_ARRAY);
379 tmp = NULL;
380
381 /* Send the request to the server */
382 rc = nm_send_request(user->conn, "joinconf", fields, &req);
383
384 /* Set up the request object so that we know what to do
385 * when we get a response
386 */
387 if (rc == NM_OK && req) {
388 nm_request_set_callback(req, callback);
389 nm_request_set_data(req, conference);
390 nm_request_set_user_define(req, data);
391 nm_conn_add_request_item(user->conn, req);
392 }
393
394 if (req)
395 nm_release_request(req);
396
397 if (fields)
398 nm_free_fields(&fields);
399
400 return rc;
401 }
402
403 NMERR_T
404 nm_send_reject_conference(NMUser * user, NMConference * conference,
405 nm_response_cb callback, gpointer data)
406 {
407 NMERR_T rc = NM_OK;
408 NMField *fields = NULL;
409 NMField *tmp = NULL;
410 NMRequest *req = NULL;
411
412 if (user == NULL || conference == NULL)
413 return NMERR_BAD_PARM;
414
415 /* Add in the conference guid */
416 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
417 (guint32) g_strdup(nm_conference_get_guid(conference)),
418 NMFIELD_TYPE_UTF8);
419
420 fields = nm_add_field(fields, NM_A_FA_CONVERSATION, 0,
421 NMFIELD_METHOD_VALID, 0, (guint32) tmp,
422 NMFIELD_TYPE_ARRAY);
423 tmp = NULL;
424
425 /* Send the request to the server */
426 rc = nm_send_request(user->conn, "rejectconf", fields, &req);
427
428 /* Set up the request object so that we know what to do
429 * when we get a response
430 */
431 if (rc == NM_OK && req) {
432 nm_request_set_callback(req, callback);
433 nm_request_set_data(req, conference);
434 nm_request_set_user_define(req, data);
435 nm_conn_add_request_item(user->conn, req);
436 }
437
438 if (req)
439 nm_release_request(req);
440
441 if (fields)
442 nm_free_fields(&fields);
443
444 return rc;
445 }
446
447 NMERR_T
448 nm_send_message(NMUser * user, NMMessage * message, nm_response_cb callback)
449 {
450 NMERR_T rc = NM_OK;
451 const char *text;
452 NMField *fields = NULL, *tmp = NULL;
453 NMRequest *req = NULL;
454 NMConference *conf;
455 NMUserRecord *user_record;
456 int count, i;
457
458 if (user == NULL || message == NULL) {
459 return NMERR_BAD_PARM;
460 }
461
462 conf = nm_message_get_conference(message);
463 if (!nm_conference_is_instantiated(conf)) {
464 rc = NMERR_CONFERENCE_NOT_INSTANTIATED;
465 } else {
466
467 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
468 (guint32) g_strdup(nm_conference_get_guid(conf)),
469 NMFIELD_TYPE_UTF8);
470
471 fields =
472 nm_add_field(fields, NM_A_FA_CONVERSATION, 0, NMFIELD_METHOD_VALID, 0,
473 (guint32) tmp, NMFIELD_TYPE_ARRAY);
474 tmp = NULL;
475
476 /* Add RTF and plain text versions of the message */
477 text = nm_message_get_text(message);
478
479 tmp = nm_add_field(tmp, NM_A_SZ_MESSAGE_BODY, 0, NMFIELD_METHOD_VALID, 0,
480 (guint32) g_strdup_printf(RTF_TEMPLATE, text),
481 NMFIELD_TYPE_UTF8);
482
483 tmp = nm_add_field(tmp, NM_A_UD_MESSAGE_TYPE, 0, NMFIELD_METHOD_VALID, 0,
484 (guint32) 0, NMFIELD_TYPE_UDWORD);
485
486 tmp = nm_add_field(tmp, NM_A_SZ_MESSAGE_TEXT, 0, NMFIELD_METHOD_VALID, 0,
487 (guint32) g_strdup(text), NMFIELD_TYPE_UTF8);
488
489 fields = nm_add_field(fields, NM_A_FA_MESSAGE, 0, NMFIELD_METHOD_VALID, 0,
490 (guint32) tmp, NMFIELD_TYPE_ARRAY);
491 tmp = NULL;
492
493 /* Add participants */
494 count = nm_conference_get_participant_count(conf);
495 for (i = 0; i < count; i++) {
496 user_record = nm_conference_get_participant(conf, i);
497 if (user_record) {
498 fields =
499 nm_add_field(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
500 (guint32)
501 g_strdup(nm_user_record_get_dn(user_record)),
502 NMFIELD_TYPE_DN);
503 }
504 }
505
506 /* Send the request */
507 rc = nm_send_request(user->conn, "sendmessage", fields, &req);
508 if (rc == NM_OK && req) {
509 nm_request_set_callback(req, callback);
510 nm_conn_add_request_item(user->conn, req);
511 }
512 }
513
514 if (fields) {
515 nm_free_fields(&fields);
516 }
517
518 if (req) {
519 nm_release_request(req);
520 }
521
522 return rc;
523 }
524
525 NMERR_T
526 nm_send_typing(NMUser * user, NMConference * conf,
527 gboolean typing, nm_response_cb callback)
528 {
529 NMERR_T rc = NM_OK;
530 char *str = NULL;
531 NMField *fields = NULL, *tmp = NULL;
532 NMRequest *req = NULL;
533
534 if (user == NULL || conf == NULL) {
535 return NMERR_BAD_PARM;
536 }
537
538 if (!nm_conference_is_instantiated(conf)) {
539 rc = NMERR_CONFERENCE_NOT_INSTANTIATED;
540 } else {
541 /* Add the conference GUID */
542 tmp = nm_add_field(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
543 (guint32) g_strdup(nm_conference_get_guid(conf)),
544 NMFIELD_TYPE_UTF8);
545
546 /* Add typing type */
547 str = g_strdup_printf("%d",
548 (typing ? NMEVT_USER_TYPING :
549 NMEVT_USER_NOT_TYPING));
550
551 tmp = nm_add_field(tmp, NM_A_SZ_TYPE, 0, NMFIELD_METHOD_VALID, 0,
552 (guint32) str, NMFIELD_TYPE_UTF8);
553
554 fields =
555 nm_add_field(fields, NM_A_FA_CONVERSATION, 0, NMFIELD_METHOD_VALID, 0,
556 (guint32) tmp, NMFIELD_TYPE_ARRAY);
557 tmp = NULL;
558
559 rc = nm_send_request(user->conn, "sendtyping", fields, &req);
560 if (rc == NM_OK && req) {
561 nm_request_set_callback(req, callback);
562 nm_conn_add_request_item(user->conn, req);
563 }
564 }
565
566 if (req)
567 nm_release_request(req);
568
569 if (fields)
570 nm_free_fields(&fields);
571
572 return rc;
573 }
574
575 NMERR_T
576 nm_send_create_contact(NMUser * user, NMFolder * folder,
577 NMContact * contact, nm_response_cb callback,
578 gpointer data)
579 {
580 NMERR_T rc = NM_OK;
581 NMField *fields = NULL;
582 NMRequest *req = NULL;
583 const char *name = NULL;
584 const char *display_name = NULL;
585
586 if (user == NULL || folder == NULL || contact == NULL) {
587 return NMERR_BAD_PARM;
588 }
589
590 /* Add parent ID */
591 fields = nm_add_field(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
592 (guint32) g_strdup_printf("%d",
593 nm_folder_get_id(folder)),
594 NMFIELD_TYPE_UTF8);
595
596 /* Check to see if userid is current user and return an error? */
597
598 /* Check to see if contact already exists and return an error? */
599
600 /* Add userid or dn */
601 name = nm_contact_get_dn(contact);
602 if (name == NULL)
603 return NMERR_BAD_PARM;
604
605 if (strstr("=", name)) {
606 fields = nm_add_field(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
607 (guint32) g_strdup(name), NMFIELD_TYPE_DN);
608 } else {
609 fields = nm_add_field(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
610 (guint32) g_strdup(name), NMFIELD_TYPE_UTF8);
611 }
612
613 /* Add display name */
614 display_name = nm_contact_get_display_name(contact);
615 if (display_name)
616 fields = nm_add_field(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
617 (guint32) g_strdup(display_name), NMFIELD_TYPE_UTF8);
618
619 /* Dispatch the request */
620 rc = nm_send_request(user->conn, "createcontact", fields, &req);
621 if (rc == NM_OK && req) {
622 nm_request_set_callback(req, callback);
623 nm_request_set_data(req, contact);
624 nm_request_set_user_define(req, data);
625 nm_conn_add_request_item(user->conn, req);
626 }
627
628 if (fields)
629 nm_free_fields(&fields);
630
631 if (req)
632 nm_release_request(req);
633
634 return rc;
635 }
636
637 NMERR_T
638 nm_send_remove_contact(NMUser * user, NMFolder * folder,
639 NMContact * contact, nm_response_cb callback,
640 gpointer data)
641 {
642 NMERR_T rc = NM_OK;
643 NMField *fields = NULL;
644 NMRequest *req = NULL;
645
646 if (user == NULL || folder == NULL || contact == NULL) {
647 return NMERR_BAD_PARM;
648 }
649
650 /* Add parent id */
651 fields = nm_add_field(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
652 (guint32) g_strdup_printf("%d",
653 nm_folder_get_id(folder)),
654 NMFIELD_TYPE_UTF8);
655
656 /* Add object id */
657 fields = nm_add_field(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
658 (guint32) g_strdup_printf("%d",
659 nm_contact_get_id(contact)),
660 NMFIELD_TYPE_UTF8);
661
662 /* Dispatch the request */
663 rc = nm_send_request(user->conn, "deletecontact", fields, &req);
664 if (rc == NM_OK && req) {
665 nm_request_set_callback(req, callback);
666 nm_request_set_data(req, contact);
667 nm_request_set_user_define(req, data);
668 nm_conn_add_request_item(user->conn, req);
669 }
670
671 if (fields)
672 nm_free_fields(&fields);
673
674 if (req)
675 nm_release_request(req);
676
677 return rc;
678 }
679
680 NMERR_T
681 nm_send_create_folder(NMUser * user, const char *name,
682 nm_response_cb callback, gpointer data)
683 {
684 NMERR_T rc = NM_OK;
685 NMField *fields = NULL;
686 NMRequest *req = NULL;
687
688 if (user == NULL || name == NULL) {
689 return NMERR_BAD_PARM;
690 }
691
692 /* Add parent ID */
693 fields = nm_add_field(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
694 (guint32) g_strdup("0"), NMFIELD_TYPE_UTF8);
695
696 /* Add name of the folder to add */
697 fields =
698 nm_add_field(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
699 (guint32) g_strdup(name), NMFIELD_TYPE_UTF8);
700
701 /* Add sequence, for now just put it at the bottom */
702 fields =
703 nm_add_field(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0,
704 (guint32) g_strdup("-1"), NMFIELD_TYPE_UTF8);
705
706 /* Dispatch the request */
707 rc = nm_send_request(user->conn, "createfolder", fields, &req);
708 if (rc == NM_OK && req) {
709 nm_request_set_callback(req, callback);
710 nm_request_set_data(req, g_strdup(name));
711 nm_request_set_user_define(req, data);
712 nm_conn_add_request_item(user->conn, req);
713 }
714
715 if (fields)
716 nm_free_fields(&fields);
717
718 if (req)
719 nm_release_request(req);
720
721 return rc;
722 }
723
724 NMERR_T
725 nm_send_remove_folder(NMUser * user, NMFolder * folder,
726 nm_response_cb callback, gpointer data)
727 {
728 NMERR_T rc = NM_OK;
729 NMField *fields = NULL;
730 NMRequest *req = NULL;
731
732 if (user == NULL || folder == NULL) {
733 return NMERR_BAD_PARM;
734 }
735
736 /* Add the object id */
737 fields = nm_add_field(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
738 (guint32) g_strdup_printf("%d", nm_folder_get_id(folder)),
739 NMFIELD_TYPE_UTF8);
740
741 /* Dispatch the request */
742 rc = nm_send_request(user->conn, "deletecontact", fields, &req);
743 if (rc == NM_OK && req) {
744 nm_request_set_callback(req, callback);
745 nm_request_set_data(req, folder);
746 nm_request_set_user_define(req, data);
747 nm_conn_add_request_item(user->conn, req);
748 }
749
750 if (fields)
751 nm_free_fields(&fields);
752
753 if (req)
754 nm_release_request(req);
755
756 return rc;
757 }
758
759 NMERR_T
760 nm_send_get_status(NMUser * user, NMUserRecord * user_record,
761 nm_response_cb callback, gpointer data)
762 {
763 NMERR_T rc = NM_OK;
764 NMField *fields = NULL;
765 NMRequest *req = NULL;
766 const char *dn;
767
768 if (user == NULL || user_record == NULL)
769 return NMERR_BAD_PARM;
770
771 /* Add DN to field list */
772 dn = nm_user_record_get_dn(user_record);
773 if (dn == NULL)
774 return (NMERR_T) -1;
775
776 fields = nm_add_field(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
777 (guint32) g_strdup(dn), NMFIELD_TYPE_UTF8);
778
779 /* Dispatch the request */
780 rc = nm_send_request(user->conn, "getstatus", fields, &req);
781 if (rc == NM_OK && req) {
782 nm_request_set_callback(req, callback);
783 nm_request_set_data(req, user_record);
784 nm_request_set_user_define(req, data);
785 nm_conn_add_request_item(user->conn, req);
786 }
787
788 if (fields)
789 nm_free_fields(&fields);
790
791 if (req)
792 nm_release_request(req);
793
794 return rc;
795 }
796
797 NMERR_T
798 nm_send_rename_contact(NMUser * user, NMContact * contact,
799 const char *new_name, nm_response_cb callback,
800 gpointer data)
801 {
802 NMERR_T rc = NM_OK;
803 NMField *field = NULL, *fields = NULL, *list = NULL;
804 NMRequest *req = NULL;
805
806 if (user == NULL || contact == NULL || new_name == NULL)
807 return NMERR_BAD_PARM;
808
809 /* Create field list for current contact */
810 field = nm_contact_to_fields(contact);
811 if (field) {
812
813 fields =
814 nm_add_field(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_DELETE, 0,
815 (guint32) field, NMFIELD_TYPE_ARRAY);
816 field = NULL;
817
818 /* Update the contacts display name locally */
819 nm_contact_set_display_name(contact, new_name);
820
821 /* Create field list for updated contact */
822 field = nm_contact_to_fields(contact);
823 if (field) {
824 fields =
825 nm_add_field(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_ADD, 0,
826 (guint32) field, NMFIELD_TYPE_ARRAY);
827 field = NULL;
828
829 /* Package it up */
830 list =
831 nm_add_field(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID,
832 0, (guint32) fields, NMFIELD_TYPE_ARRAY);
833 fields = NULL;
834
835 rc = nm_send_request(user->conn, "updateitem", list, &req);
836 if (rc == NM_OK && req) {
837 nm_request_set_callback(req, callback);
838 nm_request_set_data(req, contact);
839 nm_request_set_user_define(req, data);
840 nm_conn_add_request_item(user->conn, req);
841 }
842 }
843 }
844
845 if (list)
846 nm_free_fields(&list);
847
848 return rc;
849 }
850
851 NMERR_T
852 nm_send_rename_folder(NMUser * user, NMFolder * folder, const char *new_name,
853 nm_response_cb callback, gpointer data)
854 {
855 NMERR_T rc = NM_OK;
856 NMField *field = NULL, *fields = NULL, *list = NULL;
857 NMRequest *req = NULL;
858
859 if (user == NULL || folder == NULL || new_name == NULL)
860 return NMERR_BAD_PARM;
861
862 /* Make sure folder does not already exist!? */
863 if (nm_find_folder(user, new_name))
864 return NMERR_FOLDER_EXISTS;
865
866 /* Create field list for current folder */
867 field = nm_folder_to_fields(folder);
868 if (field) {
869
870 fields = nm_add_field(fields, NM_A_FA_FOLDER, 0, NMFIELD_METHOD_DELETE, 0,
871 (guint32) field, NMFIELD_TYPE_ARRAY);
872 field = NULL;
873
874 /* Update the folders display name locally */
875 nm_folder_set_name(folder, new_name);
876
877 /* Create field list for updated folder */
878 field = nm_folder_to_fields(folder);
879 if (field) {
880 fields =
881 nm_add_field(fields, NM_A_FA_FOLDER, 0, NMFIELD_METHOD_ADD, 0,
882 (guint32) field, NMFIELD_TYPE_ARRAY);
883 field = NULL;
884
885 /* Package it up */
886 list =
887 nm_add_field(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID,
888 0, (guint32) fields, NMFIELD_TYPE_ARRAY);
889 fields = NULL;
890
891 rc = nm_send_request(user->conn, "updateitem", list, &req);
892 if (rc == NM_OK && req) {
893 nm_request_set_callback(req, callback);
894 nm_request_set_data(req, folder);
895 nm_request_set_user_define(req, data);
896 nm_conn_add_request_item(user->conn, req);
897 }
898 }
899 }
900
901 if (list)
902 nm_free_fields(&list);
903
904 return rc;
905 }
906
907 NMERR_T
908 nm_send_move_contact(NMUser * user, NMContact * contact, NMFolder * folder,
909 nm_response_cb callback, gpointer data)
910 {
911 NMERR_T rc = NM_OK;
912 NMField *field = NULL, *fields = NULL, *list = NULL;
913 NMRequest *req = NULL;
914
915 if (user == NULL || contact == NULL || folder == NULL)
916 return NMERR_BAD_PARM;
917
918 /* Create field list for the contact */
919 field = nm_contact_to_fields(contact);
920 if (field) {
921
922 fields =
923 nm_add_field(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_DELETE, 0,
924 (guint32) field, NMFIELD_TYPE_ARRAY);
925 field = NULL;
926
927 /* Wrap the contact up and add it to the request field list */
928 list =
929 nm_add_field(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID, 0,
930 (guint32) fields, NMFIELD_TYPE_ARRAY);
931 fields = NULL;
932
933 /* Add sequence number */
934 list =
935 nm_add_field(list, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID,
936 0, (guint32) g_strdup("-1"), NMFIELD_TYPE_UTF8);
937
938 /* Add parent ID */
939 list = nm_add_field(list, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
940 (guint32) g_strdup_printf("%d",
941 nm_folder_get_id(folder)),
942 NMFIELD_TYPE_UTF8);
943
944 /* Dispatch the request */
945 rc = nm_send_request(user->conn, "movecontact", list, &req);
946 if (rc == NM_OK && req) {
947 nm_request_set_callback(req, callback);
948 nm_request_set_data(req, contact);
949 nm_request_set_user_define(req, data);
950 nm_conn_add_request_item(user->conn, req);
951
952 }
953 }
954
955 if (list)
956 nm_free_fields(&list);
957
958 return rc;
959 }
960
961
962 NMERR_T
963 nm_process_new_data(NMUser * user)
964 {
965 NMConn *conn;
966 NMERR_T rc = NM_OK;
967 int ret;
968 guint32 val;
969
970 if (user == NULL)
971 return NMERR_BAD_PARM;
972
973 conn = user->conn;
974
975 /* Check to see if this is an event or a response */
976 ret = nm_tcp_read(conn, (char *) &val, sizeof(val));
977 if (ret == sizeof(val)) {
978
979 if (strncmp((char *) &val, "HTTP", strlen("HTTP")) == 0)
980 rc = nm_process_response(user);
981 else
982 rc = nm_process_event(user, val);
983
984 } else {
985 rc = NMERR_PROTOCOL;
986 }
987
988 return rc;
989 }
990
991 NMConference *
992 nm_find_conversation(NMUser * user, const char *who)
993 {
994 NMConference *conference = NULL;
995 NMConference *tmp;
996 GSList *cnode;
997
998 if (user && user->conferences) {
999 for (cnode = user->conferences; cnode; cnode = cnode->next) {
1000 tmp = cnode->data;
1001 if (nm_conference_get_participant_count(tmp) == 1) {
1002 NMUserRecord *ur = nm_conference_get_participant(tmp, 0);
1003
1004 if (ur) {
1005 if (nm_utf8_str_equal(nm_user_record_get_dn(ur), who)) {
1006 conference = tmp;
1007 break;
1008 }
1009 }
1010 }
1011 }
1012 }
1013
1014 return conference;
1015 }
1016
1017 void
1018 nm_conference_list_add(NMUser * user, NMConference * conf)
1019 {
1020 if (user == NULL || conf == NULL)
1021 return;
1022
1023 nm_conference_add_ref(conf);
1024 user->conferences = g_slist_append(user->conferences, conf);
1025 }
1026
1027 void
1028 nm_conference_list_remove(NMUser * user, NMConference * conf)
1029 {
1030 if (user == NULL || conf == NULL)
1031 return;
1032
1033 if (g_slist_find(user->conferences, conf)) {
1034 user->conferences = g_slist_remove(user->conferences, conf);
1035 nm_release_conference(conf);
1036 }
1037 }
1038
1039 void
1040 nm_conference_list_free(NMUser * user)
1041 {
1042 GSList *cnode;
1043 NMConference *conference;
1044
1045 if (user == NULL)
1046 return;
1047
1048 if (user->conferences) {
1049 for (cnode = user->conferences; cnode; cnode = cnode->next) {
1050 conference = cnode->data;
1051 cnode->data = NULL;
1052 nm_release_conference(conference);
1053 }
1054
1055 g_slist_free(user->conferences);
1056 user->conferences = NULL;
1057 }
1058 }
1059
1060 NMConference *
1061 nm_conference_list_find(NMUser * user, const char *guid)
1062 {
1063 GSList *cnode;
1064 NMConference *conference = NULL, *tmp;
1065
1066 if (user == NULL || guid == NULL)
1067 return NULL;
1068
1069 if (user->conferences) {
1070 for (cnode = user->conferences; cnode; cnode = cnode->next) {
1071 tmp = cnode->data;
1072 if (nm_are_guids_equal(nm_conference_get_guid(tmp), guid)) {
1073 conference = tmp;
1074 break;
1075 }
1076 }
1077 }
1078
1079 return conference;
1080 }
1081
1082 gboolean
1083 nm_are_guids_equal(const char *guid1, const char *guid2)
1084 {
1085 if (guid1 == NULL || guid2 == NULL)
1086 return FALSE;
1087
1088 return (strncmp(guid1, guid2, CONF_GUID_END) == 0);
1089 }
1090
1091 void
1092 nm_user_add_contact(NMUser * user, NMContact * contact)
1093 {
1094 if (user == NULL || contact == NULL)
1095 return;
1096
1097 nm_contact_add_ref(contact);
1098
1099 g_hash_table_insert(user->contacts,
1100 g_utf8_strdown(nm_contact_get_dn(contact), -1), contact);
1101 }
1102
1103 void
1104 nm_user_add_user_record(NMUser * user, NMUserRecord * user_record)
1105 {
1106 nm_user_record_add_ref(user_record);
1107
1108 g_hash_table_insert(user->user_records,
1109 g_utf8_strdown(nm_user_record_get_dn(user_record), -1),
1110 user_record);
1111
1112 g_hash_table_insert(user->display_id_to_dn,
1113 g_utf8_strdown(nm_user_record_get_display_id(user_record),
1114 -1),
1115 g_utf8_strdown(nm_user_record_get_dn(user_record), -1));
1116
1117 }
1118
1119 nm_event_cb
1120 nm_user_get_event_callback(NMUser * user)
1121 {
1122 if (user == NULL)
1123 return NULL;
1124
1125 return user->evt_callback;
1126 }
1127
1128 NMConn *
1129 nm_user_get_conn(NMUser * user)
1130 {
1131 if (user == NULL)
1132 return NULL;
1133
1134 return user->conn;
1135 }
1136
1137 NMERR_T
1138 nm_create_contact_list(NMUser * user)
1139 {
1140 NMERR_T rc = NM_OK;
1141 NMField *locate = NULL;
1142
1143 if (user == NULL || user->fields == NULL) {
1144 return NMERR_BAD_PARM;
1145 }
1146
1147 /* Create the root folder */
1148 user->root_folder = nm_create_folder("");
1149
1150 /* Find the contact list in the login fields */
1151 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, user->fields);
1152 if (locate != NULL) {
1153
1154 /* Add the folders and then the contacts */
1155 nm_folder_add_contacts_and_folders(user, user->root_folder,
1156 (NMField *) (locate->value));
1157
1158 }
1159
1160 return rc;
1161 }
1162
1163 void
1164 nm_destroy_contact_list(NMUser * user)
1165 {
1166 if (user == NULL)
1167 return;
1168
1169 if (user->root_folder) {
1170 nm_release_folder(user->root_folder);
1171 user->root_folder = NULL;
1172 }
1173 }
1174
1175 NMFolder *
1176 nm_get_root_folder(NMUser * user)
1177 {
1178 if (user == NULL)
1179 return NULL;
1180
1181 if (user->root_folder == NULL)
1182 nm_create_contact_list(user);
1183
1184 return user->root_folder;
1185 }
1186
1187 NMContact *
1188 nm_find_contact(NMUser * user, const char *name)
1189 {
1190 char *str;
1191 const char *dn = NULL;
1192 NMContact *contact = NULL;
1193
1194 if (user == NULL || name == NULL)
1195 return NULL;
1196
1197 str = g_utf8_strdown(name, -1);
1198 if (strstr(str, "=")) {
1199 dn = str;
1200 } else {
1201 /* Assume that we have a display id instead of a dn */
1202 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str);
1203 }
1204
1205 /* Find contact object in reference table */
1206 if (dn) {
1207 contact = (NMContact *) g_hash_table_lookup(user->contacts, dn);
1208 }
1209
1210 g_free(str);
1211 return contact;
1212 }
1213
1214 GList *
1215 nm_find_contacts(NMUser * user, const char *dn)
1216 {
1217 guint32 i, cnt;
1218 NMFolder *folder;
1219 NMContact *contact;
1220 GList *contacts = NULL;
1221
1222 if (user == NULL || dn == NULL)
1223 return NULL;
1224
1225 /* Check for contact at the root */
1226 contact = nm_folder_find_contact(user->root_folder, dn);
1227 if (contact) {
1228 contacts = g_list_append(contacts, contact);
1229 contact = NULL;
1230 }
1231
1232 /* Check for contact in each subfolder */
1233 cnt = nm_folder_get_subfolder_count(user->root_folder);
1234 for (i = 0; i < cnt; i++) {
1235 folder = nm_folder_get_subfolder(user->root_folder, i);
1236 contact = nm_folder_find_contact(folder, dn);
1237 if (contact) {
1238 contacts = g_list_append(contacts, contact);
1239 contact = NULL;
1240 }
1241 }
1242
1243 return contacts;
1244 }
1245
1246 NMUserRecord *
1247 nm_find_user_record(NMUser * user, const char *name)
1248 {
1249 char *str = NULL;
1250 const char *dn = NULL;
1251 NMUserRecord *user_record = NULL;
1252
1253 if (user == NULL || name == NULL)
1254 return NULL;
1255
1256 str = g_utf8_strdown(name, -1);
1257 if (strstr(str, "=")) {
1258 dn = str;
1259 } else {
1260 /* Assume that we have a display id instead of a dn */
1261 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str);
1262 }
1263
1264 /* Find user record in reference table */
1265 if (dn) {
1266 user_record =
1267 (NMUserRecord *) g_hash_table_lookup(user->user_records, dn);
1268 }
1269
1270 g_free(str);
1271 return user_record;
1272 }
1273
1274 const char *
1275 nm_lookup_dn(NMUser * user, const char *display_id)
1276 {
1277 if (user == NULL || display_id == NULL)
1278 return NULL;
1279
1280 return (const char *) g_hash_table_lookup(user->display_id_to_dn,
1281 g_utf8_strdown(display_id, -1));
1282 }
1283
1284 NMFolder *
1285 nm_find_folder(NMUser * user, const char *name)
1286 {
1287 NMFolder *folder = NULL, *temp;
1288 int i, num_folders;
1289 const char *tname = NULL;
1290
1291 if (user == NULL || name == NULL)
1292 return NULL;
1293
1294 if (*name == '\0')
1295 return user->root_folder;
1296
1297 num_folders = nm_folder_get_subfolder_count(user->root_folder);
1298 for (i = 0; i < num_folders; i++) {
1299 temp = nm_folder_get_subfolder(user->root_folder, i);
1300 tname = nm_folder_get_name(temp);
1301
1302 if (tname && (strcmp(tname, name) == 0)) {
1303 folder = temp;
1304 break;
1305 }
1306 }
1307
1308 return folder;
1309 }
1310
1311 NMFolder *
1312 nm_find_folder_by_id(NMUser * user, int object_id)
1313 {
1314 NMFolder *folder = NULL, *temp;
1315 int i, num_folders;
1316
1317 if (user == NULL)
1318 return NULL;
1319
1320 if (object_id == 0)
1321 return user->root_folder;
1322
1323 num_folders = nm_folder_get_subfolder_count(user->root_folder);
1324 for (i = 0; i < num_folders; i++) {
1325 temp = nm_folder_get_subfolder(user->root_folder, i);
1326 if (nm_folder_get_id(temp) == object_id) {
1327 folder = temp;
1328 break;
1329 }
1330 }
1331
1332 return folder;
1333 }
1334
1335 static void
1336 _handle_multiple_get_details_joinconf_cb(NMUser * user, NMERR_T ret_code,
1337 gpointer resp_data, gpointer user_data)
1338 {
1339 NMRequest *request = user_data;
1340 NMUserRecord *user_record = resp_data;
1341 NMConference *conference;
1342 GSList *list, *node;
1343
1344 if (user == NULL || resp_data == NULL || user_data == NULL)
1345 return;
1346
1347 conference = nm_request_get_data(request);
1348 list = nm_request_get_user_define(request);
1349
1350 if (ret_code == 0 && conference && list) {
1351
1352 /* Add the user to the conference */
1353 nm_conference_add_participant(conference, user_record);
1354
1355 /* Find the user in the list and remove it */
1356 for (node = list; node; node = node->next) {
1357 if (nm_utf8_str_equal(nm_user_record_get_dn(user_record),
1358 (const char *) node->data)) {
1359 list = g_slist_remove(list, node->data);
1360 nm_request_set_user_define(request, list);
1361 g_free(node->data);
1362 break;
1363 }
1364 }
1365
1366 /* Time to callback? */
1367 if (g_slist_length(list) == 0) {
1368 nm_response_cb cb = nm_request_get_callback(request);
1369
1370 if (cb) {
1371 cb(user, 0, conference, conference);
1372 }
1373 g_slist_free(list);
1374 nm_release_request(request);
1375 }
1376 }
1377 }
1378
1379 NMERR_T
1380 nm_call_handler(NMUser * user, NMRequest * request, NMField * fields)
1381 {
1382 NMERR_T rc = NM_OK, ret_code = NM_OK;
1383 NMConference *conf = NULL;
1384 NMUserRecord *user_record = NULL;
1385 NMField *locate = NULL;
1386 NMField *field = NULL;
1387 const char *cmd;
1388 nm_response_cb cb;
1389 gboolean done = TRUE;
1390
1391 if (user == NULL || request == NULL || fields == NULL)
1392 return NMERR_BAD_PARM;
1393
1394 /* Get the return code */
1395 field = nm_locate_field(NM_A_SZ_RESULT_CODE, fields);
1396 if (field) {
1397 ret_code = atoi((char *) field->value);
1398 } else {
1399 ret_code = NMERR_PROTOCOL;
1400 }
1401
1402 cmd = nm_request_get_cmd(request);
1403 if (ret_code == NM_OK && cmd != NULL) {
1404
1405 if (strcmp("login", cmd) == 0) {
1406
1407 user->user_record = nm_create_user_record_from_fields(fields);
1408
1409 /* Save the users fields */
1410 user->fields = fields;
1411
1412 } else if (strcmp("setstatus", cmd) == 0) {
1413
1414 /* Nothing to do */
1415
1416 } else if (strcmp("createconf", cmd) == 0) {
1417
1418 conf = (NMConference *) nm_request_get_data(request);
1419
1420 /* get the convo guid */
1421 locate = nm_locate_field(NM_A_FA_CONVERSATION, fields);
1422 if (locate) {
1423 field =
1424 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->value);
1425 if (field) {
1426 nm_conference_set_guid(conf, (char *) field->value);
1427 }
1428 }
1429
1430 nm_conference_list_add(user, conf);
1431
1432 } else if (strcmp("leaveconf", cmd) == 0) {
1433
1434 conf = (NMConference *) nm_request_get_data(request);
1435 nm_conference_list_remove(user, conf);
1436
1437 } else if (strcmp("joinconf", cmd) == 0) {
1438 GSList *list = NULL, *node;
1439
1440 nm_print_fields(fields);
1441
1442 conf = nm_request_get_data(request);
1443
1444 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, fields);
1445 if (locate && locate->value != 0) {
1446
1447 field = (NMField *) locate->value;
1448 while ((field = nm_locate_field(NM_A_SZ_DN, field))) {
1449 if (field && field->value != 0) {
1450
1451 if (nm_utf8_str_equal
1452 (nm_user_record_get_dn(user->user_record),
1453 (const char *) field->value)) {
1454 field++;
1455 continue;
1456 }
1457
1458 user_record =
1459 nm_find_user_record(user,
1460 (const char *) field->value);
1461 if (user_record == NULL) {
1462 list =
1463 g_slist_append(list,
1464 g_strdup((char *) field->value));
1465 } else {
1466 nm_conference_add_participant(conf, user_record);
1467 }
1468 }
1469 field++;
1470 }
1471
1472 if (list != NULL) {
1473
1474 done = FALSE;
1475 nm_request_add_ref(request);
1476 nm_request_set_user_define(request, list);
1477 for (node = list; node; node = node->next) {
1478
1479 nm_send_get_details(user, (const char *) node->data,
1480 _handle_multiple_get_details_joinconf_cb,
1481 request);
1482 }
1483 }
1484 }
1485
1486 } else if (strcmp("getdetails", cmd) == 0) {
1487
1488 locate = nm_locate_field(NM_A_FA_RESULTS, fields);
1489 if (locate && locate->value != 0) {
1490
1491 user_record = nm_create_user_record_from_fields(locate);
1492 if (user_record) {
1493 NMUserRecord *tmp;
1494
1495 tmp =
1496 nm_find_user_record(user,
1497 nm_user_record_get_dn(user_record));
1498 if (tmp) {
1499
1500 /* Update the existing user record */
1501 nm_user_record_copy(tmp, user_record);
1502 nm_release_user_record(user_record);
1503 user_record = tmp;
1504
1505 } else {
1506
1507 nm_user_add_user_record(user, user_record);
1508 nm_release_user_record(user_record);
1509
1510 }
1511
1512 /* Response data is new user record */
1513 nm_request_set_data(request, (gpointer) user_record);
1514 }
1515
1516 }
1517
1518 } else if (strcmp("createfolder", cmd) == 0) {
1519
1520 _update_contact_list(user, fields);
1521
1522 } else if (strcmp("createcontact", cmd) == 0) {
1523
1524 _update_contact_list(user, fields);
1525
1526 locate =
1527 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->value);
1528 if (locate) {
1529
1530 NMContact *new_contact =
1531 nm_folder_find_item_by_object_id(user->root_folder,
1532 atoi((char *) locate->
1533 value));
1534
1535 if (new_contact) {
1536
1537 /* Add the contact to our cache */
1538 nm_user_add_contact(user, new_contact);
1539
1540 /* Set the contact as the response data */
1541 nm_request_set_data(request, (gpointer) new_contact);
1542
1543 }
1544
1545 }
1546
1547 } else if (strcmp("deletecontact", cmd) == 0) {
1548
1549 _update_contact_list(user, fields);
1550
1551 } else if (strcmp("movecontact", cmd) == 0) {
1552
1553 _update_contact_list(user, fields);
1554
1555 } else if (strcmp("getstatus", cmd) == 0) {
1556
1557 locate = nm_locate_field(NM_A_SZ_STATUS, fields);
1558 if (locate) {
1559 nm_user_record_set_status((NMUserRecord *)
1560 nm_request_get_data(request),
1561 atoi((char *) locate->value), NULL);
1562 }
1563
1564 } else if (strcmp("updateitem", cmd) == 0) {
1565
1566 /* Nothing extra to do here */
1567
1568 } else {
1569
1570 /* Nothing to do, just print debug message */
1571 gaim_debug(GAIM_DEBUG_INFO, "novell",
1572 "nm_call_handler(): Unknown request command, %s\n", cmd);
1573
1574 }
1575 }
1576
1577 if (done && (cb = nm_request_get_callback(request))) {
1578
1579 cb(user, ret_code, nm_request_get_data(request),
1580 nm_request_get_user_define(request));
1581
1582 }
1583
1584 return rc;
1585 }
1586
1587 static NMERR_T
1588 nm_process_response(NMUser * user)
1589 {
1590 NMERR_T rc = NM_OK;
1591 NMField *fields = NULL;
1592 NMField *field = NULL;
1593 NMConn *conn = user->conn;
1594 NMRequest *req = NULL;
1595
1596 rc = nm_read_header(conn);
1597 if (rc == NM_OK) {
1598 rc = nm_read_fields(conn, -1, &fields);
1599 }
1600
1601 if (rc == NM_OK) {
1602 field = nm_locate_field(NM_A_SZ_TRANSACTION_ID, fields);
1603 if (field != NULL && field->value != 0) {
1604 req = nm_conn_find_request(conn, atoi((char *) field->value));
1605 if (req != NULL) {
1606 rc = nm_call_handler(user, req, fields);
1607 }
1608 }
1609 }
1610
1611 return rc;
1612 }
1613
1614 /*
1615 * Some utility functions...haven't figured out where
1616 * they belong yet.
1617 */
1618 gint
1619 nm_utf8_strcasecmp(gconstpointer str1, gconstpointer str2)
1620 {
1621 gint rv;
1622 char *str1_down = g_utf8_strdown(str1, -1);
1623 char *str2_down = g_utf8_strdown(str2, -1);
1624
1625 rv = g_utf8_collate(str1_down, str2_down);
1626
1627 g_free(str1_down);
1628 g_free(str2_down);
1629
1630 return rv;
1631 }
1632
1633 gboolean
1634 nm_utf8_str_equal(gconstpointer str1, gconstpointer str2)
1635 {
1636 return (nm_utf8_strcasecmp(str1, str2) == 0);
1637 }
1638
1639 char *
1640 nm_typed_to_dotted(const char *typed)
1641 {
1642 unsigned i = 0, j = 0;
1643
1644 if (typed == NULL)
1645 return NULL;
1646
1647 char *dotted = g_new0(char, strlen(typed));
1648
1649 do {
1650
1651 /* replace comma with a dot */
1652 if (j != 0) {
1653 dotted[j] = '.';
1654 j++;
1655 }
1656
1657 /* skip the type */
1658 while (typed[i] != '\0' && typed[i] != '=')
1659 i++;
1660
1661 /* verify that we aren't running off the end */
1662 if (typed[i] == '\0') {
1663 dotted[j] = '\0';
1664 break;
1665 }
1666
1667 i++;
1668
1669 /* copy the object name to context */
1670 while (typed[i] != '\0' && typed[i] != ',') {
1671 dotted[j] = typed[i];
1672 j++;
1673 i++;
1674 }
1675
1676 } while (typed[i] != '\0');
1677
1678 return dotted;
1679 }
1680
1681 static void
1682 _update_contact_list(NMUser * user, NMField * fields)
1683 {
1684 NMField *list, *cursor, *locate;
1685 gint objid1;
1686 NMContact *contact;
1687 NMFolder *folder;
1688
1689 if (user == NULL || fields == NULL)
1690 return;
1691
1692 /* Is it wrapped in a RESULTS array? */
1693 if (strcmp(fields->tag, NM_A_FA_RESULTS) == 0) {
1694 list = (NMField *) fields->value;
1695 } else {
1696 list = fields;
1697 }
1698
1699 /* Update the cached contact list */
1700 cursor = (NMField *) list->value;
1701 while (cursor->tag != NULL) {
1702 if ((g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) ||
1703 (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) == 0)) {
1704
1705 locate =
1706 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) cursor->value);
1707 if (locate != NULL && locate->value != 0) {
1708 objid1 = atoi((char *) locate->value);
1709 gpointer item =
1710 nm_folder_find_item_by_object_id(user->root_folder, objid1);
1711 if (item != NULL) {
1712 if (cursor->method == NMFIELD_METHOD_ADD) {
1713 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
1714 contact = (NMContact *) item;
1715 nm_contact_update_list_properties(contact, cursor);
1716 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
1717 == 0) {
1718 folder = (NMFolder *) item;
1719 nm_folder_update_list_properties(folder, cursor);
1720 }
1721 } else if (cursor->method == NMFIELD_METHOD_DELETE) {
1722 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
1723 contact = (NMContact *) item;
1724 folder =
1725 nm_find_folder_by_id(user,
1726 nm_contact_get_parent_id
1727 (contact));
1728 if (folder) {
1729 nm_folder_remove_contact(folder, contact);
1730 }
1731 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
1732 == 0) {
1733 /* TODO: write nm_folder_remove_folder */
1734 /* ignoring for now, should not be a big deal */
1735 /* folder = (NMFolder *) item;*/
1736 /* nm_folder_remove_folder(user->root_folder, folder);*/
1737 }
1738 }
1739 } else {
1740
1741 if (cursor->method == NMFIELD_METHOD_ADD) {
1742
1743 /* Not found, so we need to add it */
1744 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
1745
1746 const char *dn = NULL;
1747
1748 locate =
1749 nm_locate_field(NM_A_SZ_DN,
1750 (NMField *) cursor->value);
1751 if (locate != NULL && locate->value != 0) {
1752 dn = (const char *) locate->value;
1753 if (dn != NULL) {
1754 contact =
1755 nm_create_contact_from_fields(cursor);
1756 if (contact) {
1757 nm_folder_add_contact_to_list(user->
1758 root_folder,
1759 contact);
1760 nm_release_contact(contact);
1761 }
1762 }
1763 }
1764 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
1765 == 0) {
1766 folder = nm_create_folder_from_fields(cursor);
1767 nm_folder_add_folder_to_list(user->root_folder,
1768 folder);
1769 nm_release_folder(folder);
1770 }
1771 }
1772 }
1773 }
1774 }
1775 cursor++;
1776 }
1777 }