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
26 #include "nmcontact.h"
27 #include "nmuserrecord.h"
30 /* This is the template that we wrap outgoing messages in, since the other
31 * GW Messenger clients expect messages to be in RTF.
33 #define RTF_TEMPLATE "{\\rtf1\\ansi\n"\
34 "{\\fonttbl{\\f0\\fnil Unknown;}}\n"\
35 "{\\colortbl ;\\red0\\green0\\blue0;}\n"\
36 "\\uc1\\cf1\\f0\\fs24 %s\\par\n}"
37 #define NM_MAX_MESSAGE_SIZE 2048
39 static NMERR_T
nm_process_response(NMUser
* user
);
40 static void _update_contact_list(NMUser
* user
, NMField
* fields
);
41 static void _handle_multiple_get_details_login_cb(NMUser
* user
, NMERR_T ret_code
,
42 gpointer resp_data
, gpointer user_data
);
43 static char * nm_rtfize_text(char *text
);
46 * See header for comments on on "public" functions
50 nm_initialize_user(const char *name
, const char *server_addr
,
51 int port
, gpointer data
, nm_event_cb event_callback
)
54 if (name
== NULL
|| server_addr
== NULL
|| event_callback
== NULL
)
57 user
= g_new0(NMUser
, 1);
62 g_hash_table_new_full(g_str_hash
, nm_utf8_str_equal
,
63 g_free
, (GDestroyNotify
) nm_release_contact
);
66 g_hash_table_new_full(g_str_hash
, nm_utf8_str_equal
, g_free
,
67 (GDestroyNotify
) nm_release_user_record
);
69 user
->display_id_to_dn
= g_hash_table_new_full(g_str_hash
, nm_utf8_str_equal
,
72 user
->name
= g_strdup(name
);
73 user
->conn
= nm_create_conn(server_addr
, port
);
74 user
->conn
->addr
= g_strdup(server_addr
);
75 user
->conn
->port
= port
;
76 user
->evt_callback
= event_callback
;
77 user
->client_data
= data
;
84 nm_deinitialize_user(NMUser
* user
)
86 nm_release_conn(user
->conn
);
89 g_hash_table_destroy(user
->contacts
);
92 if (user
->user_records
) {
93 g_hash_table_destroy(user
->user_records
);
96 if (user
->display_id_to_dn
) {
97 g_hash_table_destroy(user
->display_id_to_dn
);
102 if (user
->user_record
) {
103 nm_release_user_record(user
->user_record
);
106 nm_conference_list_free(user
);
107 nm_destroy_contact_list(user
);
113 nm_send_login(NMUser
* user
, const char *pwd
, const char *my_addr
,
114 const char *user_agent
, nm_response_cb callback
, gpointer data
)
117 NMField
*fields
= NULL
;
119 if (user
== NULL
|| pwd
== NULL
|| user_agent
== NULL
) {
120 return NMERR_BAD_PARM
;
123 fields
= nm_field_add_pointer(fields
, NM_A_SZ_USERID
, 0, NMFIELD_METHOD_VALID
, 0,
124 g_strdup(user
->name
), NMFIELD_TYPE_UTF8
);
126 fields
= nm_field_add_pointer(fields
, NM_A_SZ_CREDENTIALS
, 0, NMFIELD_METHOD_VALID
, 0,
127 g_strdup(pwd
), NMFIELD_TYPE_UTF8
);
129 fields
= nm_field_add_pointer(fields
, NM_A_SZ_USER_AGENT
, 0, NMFIELD_METHOD_VALID
, 0,
130 g_strdup(user_agent
), NMFIELD_TYPE_UTF8
);
132 fields
= nm_field_add_number(fields
, NM_A_UD_BUILD
, 0, NMFIELD_METHOD_VALID
, 0,
133 NM_PROTOCOL_VERSION
, NMFIELD_TYPE_UDWORD
);
135 fields
= nm_field_add_pointer(fields
, NM_A_IP_ADDRESS
, 0, NMFIELD_METHOD_VALID
, 0,
136 g_strdup(my_addr
), NMFIELD_TYPE_UTF8
);
140 rc
= nm_send_request(user
->conn
, "login", fields
, callback
, data
, NULL
);
142 nm_free_fields(&fields
);
147 nm_send_set_status(NMUser
* user
, int status
, const char *text
,
148 const char *auto_resp
, nm_response_cb callback
, gpointer data
)
151 NMField
*fields
= NULL
;
154 return NMERR_BAD_PARM
;
157 fields
= nm_field_add_pointer(fields
, NM_A_SZ_STATUS
, 0, NMFIELD_METHOD_VALID
, 0,
158 g_strdup_printf("%d", status
), NMFIELD_TYPE_UTF8
);
160 /* Add the status text and auto reply text if there is any */
162 fields
= nm_field_add_pointer(fields
, NM_A_SZ_STATUS_TEXT
, 0,
163 NMFIELD_METHOD_VALID
, 0, g_strdup(text
),
168 fields
= nm_field_add_pointer(fields
, NM_A_SZ_MESSAGE_BODY
, 0,
169 NMFIELD_METHOD_VALID
, 0, g_strdup(auto_resp
),
173 rc
= nm_send_request(user
->conn
, "setstatus", fields
, callback
, data
, NULL
);
175 nm_free_fields(&fields
);
180 nm_send_multiple_get_details(NMUser
* user
, GSList
*names
,
181 nm_response_cb callback
, gpointer data
)
184 NMField
*fields
= NULL
;
187 if (user
== NULL
|| names
== NULL
)
188 return NMERR_BAD_PARM
;
190 /* Add in DN or display id */
191 for (node
= names
; node
; node
= node
->next
) {
192 fields
= nm_field_add_pointer(fields
, NM_A_SZ_USERID
, 0, NMFIELD_METHOD_VALID
, 0,
193 g_strdup(node
->data
), NMFIELD_TYPE_UTF8
);
196 rc
= nm_send_request(user
->conn
, "getdetails", fields
, callback
, data
, NULL
);
198 nm_free_fields(&fields
);
203 nm_send_get_details(NMUser
* user
, const char *name
,
204 nm_response_cb callback
, gpointer data
)
207 NMField
*fields
= NULL
;
209 if (user
== NULL
|| name
== NULL
)
210 return NMERR_BAD_PARM
;
212 /* Add in DN or display id */
213 if (strstr("=", name
)) {
214 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
215 g_strdup(name
), NMFIELD_TYPE_DN
);
218 const char *dn
= nm_lookup_dn(user
, name
);
220 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
221 g_strdup(name
), NMFIELD_TYPE_DN
);
224 nm_field_add_pointer(fields
, NM_A_SZ_USERID
, 0, NMFIELD_METHOD_VALID
, 0,
225 g_strdup(name
), NMFIELD_TYPE_UTF8
);
230 rc
= nm_send_request(user
->conn
, "getdetails", fields
, callback
, data
, NULL
);
232 nm_free_fields(&fields
);
237 nm_send_create_conference(NMUser
* user
, NMConference
* conference
,
238 nm_response_cb callback
, gpointer data
)
241 NMField
*fields
= NULL
;
243 NMField
*field
= NULL
;
244 NMRequest
*req
= NULL
;
247 if (user
== NULL
|| conference
== NULL
)
248 return NMERR_BAD_PARM
;
250 /* Add in a blank guid */
251 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
252 g_strdup(BLANK_GUID
), NMFIELD_TYPE_UTF8
);
254 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0,
255 NMFIELD_METHOD_VALID
, 0, tmp
,
260 /* Add participants in */
261 count
= nm_conference_get_participant_count(conference
);
262 for (i
= 0; i
< count
; i
++) {
263 NMUserRecord
*user_record
= nm_conference_get_participant(conference
, i
);
266 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
,
267 0, NMFIELD_METHOD_VALID
, 0,
268 g_strdup(nm_user_record_get_dn(user_record
)),
273 /* Add our user in */
274 field
= nm_locate_field(NM_A_SZ_DN
, user
->fields
);
276 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
,
277 0, NMFIELD_METHOD_VALID
, 0,
278 g_strdup((char *) field
->ptr_value
),
282 rc
= nm_send_request(user
->conn
, "createconf", fields
, callback
, data
, &req
);
283 if (rc
== NM_OK
&& req
) {
284 nm_conference_add_ref(conference
);
285 nm_request_set_data(req
, conference
);
289 nm_release_request(req
);
291 nm_free_fields(&fields
);
296 nm_send_leave_conference(NMUser
* user
, NMConference
* conference
,
297 nm_response_cb callback
, gpointer data
)
300 NMField
*fields
= NULL
;
302 NMRequest
*req
= NULL
;
304 if (user
== NULL
|| conference
== NULL
)
305 return NMERR_BAD_PARM
;
307 /* Add in the conference guid */
308 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
309 g_strdup(nm_conference_get_guid(conference
)),
312 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0,
313 NMFIELD_METHOD_VALID
, 0, tmp
,
317 /* Send the request to the server */
318 rc
= nm_send_request(user
->conn
, "leaveconf", fields
, callback
, data
, &req
);
319 if (rc
== NM_OK
&& req
)
320 nm_request_set_data(req
, conference
);
323 nm_release_request(req
);
325 nm_free_fields(&fields
);
330 nm_send_join_conference(NMUser
* user
, NMConference
* conference
,
331 nm_response_cb callback
, gpointer data
)
334 NMField
*fields
= NULL
, *tmp
= NULL
;
335 NMRequest
*req
= NULL
;
337 if (user
== NULL
|| conference
== NULL
)
338 return NMERR_BAD_PARM
;
340 /* Add in the conference guid */
341 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
342 g_strdup(nm_conference_get_guid(conference
)),
345 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0,
346 NMFIELD_METHOD_VALID
, 0, tmp
,
350 /* Send the request to the server */
351 rc
= nm_send_request(user
->conn
, "joinconf", fields
, callback
, data
, &req
);
352 if (rc
== NM_OK
&& req
)
353 nm_request_set_data(req
, conference
);
356 nm_release_request(req
);
358 nm_free_fields(&fields
);
363 nm_send_reject_conference(NMUser
* user
, NMConference
* conference
,
364 nm_response_cb callback
, gpointer data
)
367 NMField
*fields
= NULL
;
369 NMRequest
*req
= NULL
;
371 if (user
== NULL
|| conference
== NULL
)
372 return NMERR_BAD_PARM
;
374 /* Add in the conference guid */
375 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
376 g_strdup(nm_conference_get_guid(conference
)),
379 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0,
380 NMFIELD_METHOD_VALID
, 0, tmp
,
384 /* Send the request to the server */
385 rc
= nm_send_request(user
->conn
, "rejectconf", fields
, callback
, data
, &req
);
386 if (rc
== NM_OK
&& req
)
387 nm_request_set_data(req
, conference
);
390 nm_release_request(req
);
392 nm_free_fields(&fields
);
397 nm_send_conference_invite(NMUser
*user
, NMConference
*conference
, NMUserRecord
*user_record
,
398 const char *message
, nm_response_cb callback
, gpointer data
)
401 NMField
*fields
= NULL
;
403 NMRequest
*req
= NULL
;
405 if (user
== NULL
|| conference
== NULL
|| user_record
== NULL
)
406 return NMERR_BAD_PARM
;
408 /* Add in the conference guid */
409 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
410 g_strdup(nm_conference_get_guid(conference
)),
413 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0,
414 NMFIELD_METHOD_VALID
, 0, tmp
,
418 /* Add in DN of user to invite */
419 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
420 g_strdup(nm_user_record_get_dn(user_record
)),
423 /* Add the invite message if there is one */
425 fields
= nm_field_add_pointer(fields
, NM_A_SZ_MESSAGE_BODY
, 0, NMFIELD_METHOD_VALID
, 0,
426 g_strdup(message
), NMFIELD_TYPE_UTF8
);
428 /* Send the request to the server */
429 rc
= nm_send_request(user
->conn
, "sendinvite", fields
, callback
, data
, &req
);
430 if (rc
== NM_OK
&& req
)
431 nm_request_set_data(req
, conference
);
434 nm_release_request(req
);
436 nm_free_fields(&fields
);
441 nm_send_message(NMUser
* user
, NMMessage
* message
, nm_response_cb callback
)
444 char *text
, *rtfized
;
445 NMField
*fields
= NULL
, *tmp
= NULL
;
447 NMUserRecord
*user_record
;
450 if (user
== NULL
|| message
== NULL
) {
451 return NMERR_BAD_PARM
;
454 conf
= nm_message_get_conference(message
);
455 if (!nm_conference_is_instantiated(conf
)) {
456 rc
= NMERR_CONFERENCE_NOT_INSTANTIATED
;
459 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
460 g_strdup(nm_conference_get_guid(conf
)),
464 nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0, NMFIELD_METHOD_VALID
, 0,
465 tmp
, NMFIELD_TYPE_ARRAY
);
468 /* Add RTF and plain text versions of the message */
469 text
= g_strdup(nm_message_get_text(message
));
471 /* Truncate if necessary */
472 if (strlen(text
) > NM_MAX_MESSAGE_SIZE
)
473 text
[NM_MAX_MESSAGE_SIZE
] = 0;
475 rtfized
= nm_rtfize_text(text
);
477 purple_debug_info("novell", "message text is: %s\n", text
);
478 purple_debug_info("novell", "message rtf is: %s\n", rtfized
);
480 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_MESSAGE_BODY
, 0, NMFIELD_METHOD_VALID
, 0,
481 rtfized
, NMFIELD_TYPE_UTF8
);
483 tmp
= nm_field_add_number(tmp
, NM_A_UD_MESSAGE_TYPE
, 0, NMFIELD_METHOD_VALID
, 0,
484 0, NMFIELD_TYPE_UDWORD
);
486 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_MESSAGE_TEXT
, 0, NMFIELD_METHOD_VALID
, 0,
487 text
, NMFIELD_TYPE_UTF8
);
489 fields
= nm_field_add_pointer(fields
, NM_A_FA_MESSAGE
, 0, NMFIELD_METHOD_VALID
, 0,
490 tmp
, NMFIELD_TYPE_ARRAY
);
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
);
499 nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
500 g_strdup(nm_user_record_get_dn(user_record
)),
505 /* Send the request */
506 rc
= nm_send_request(user
->conn
, "sendmessage", fields
, callback
, NULL
, NULL
);
509 nm_free_fields(&fields
);
514 nm_send_typing(NMUser
* user
, NMConference
* conf
,
515 gboolean typing
, nm_response_cb callback
)
519 NMField
*fields
= NULL
, *tmp
= NULL
;
521 if (user
== NULL
|| conf
== NULL
) {
522 return NMERR_BAD_PARM
;
525 if (!nm_conference_is_instantiated(conf
)) {
526 rc
= NMERR_CONFERENCE_NOT_INSTANTIATED
;
528 /* Add the conference GUID */
529 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
530 g_strdup(nm_conference_get_guid(conf
)),
533 /* Add typing type */
534 str
= g_strdup_printf("%d",
535 (typing
? NMEVT_USER_TYPING
:
536 NMEVT_USER_NOT_TYPING
));
538 tmp
= nm_field_add_pointer(tmp
, NM_A_SZ_TYPE
, 0, NMFIELD_METHOD_VALID
, 0,
539 str
, NMFIELD_TYPE_UTF8
);
542 nm_field_add_pointer(fields
, NM_A_FA_CONVERSATION
, 0, NMFIELD_METHOD_VALID
, 0,
543 tmp
, NMFIELD_TYPE_ARRAY
);
546 rc
= nm_send_request(user
->conn
, "sendtyping", fields
, callback
, NULL
, NULL
);
549 nm_free_fields(&fields
);
554 nm_send_create_contact(NMUser
* user
, NMFolder
* folder
,
555 NMContact
* contact
, nm_response_cb callback
,
559 NMField
*fields
= NULL
;
560 NMRequest
*req
= NULL
;
561 const char *name
= NULL
;
562 const char *display_name
= NULL
;
564 if (user
== NULL
|| folder
== NULL
|| contact
== NULL
) {
565 return NMERR_BAD_PARM
;
569 fields
= nm_field_add_pointer(fields
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
570 g_strdup_printf("%d", nm_folder_get_id(folder
)),
573 /* Check to see if userid is current user and return an error? */
575 /* Check to see if contact already exists and return an error? */
577 /* Add userid or dn */
578 name
= nm_contact_get_dn(contact
);
580 return NMERR_BAD_PARM
;
582 if (strstr("=", name
)) {
583 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
584 g_strdup(name
), NMFIELD_TYPE_DN
);
586 fields
= nm_field_add_pointer(fields
, NM_A_SZ_USERID
, 0, NMFIELD_METHOD_VALID
, 0,
587 g_strdup(name
), NMFIELD_TYPE_UTF8
);
590 /* Add display name */
591 display_name
= nm_contact_get_display_name(contact
);
593 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DISPLAY_NAME
, 0, NMFIELD_METHOD_VALID
, 0,
594 g_strdup(display_name
), NMFIELD_TYPE_UTF8
);
596 /* Dispatch the request */
597 rc
= nm_send_request(user
->conn
, "createcontact", fields
, callback
, data
, &req
);
598 if (rc
== NM_OK
&& req
)
599 nm_request_set_data(req
, contact
);
602 nm_release_request(req
);
604 nm_free_fields(&fields
);
609 nm_send_remove_contact(NMUser
* user
, NMFolder
* folder
,
610 NMContact
* contact
, nm_response_cb callback
,
614 NMField
*fields
= NULL
;
615 NMRequest
*req
= NULL
;
617 if (user
== NULL
|| folder
== NULL
|| contact
== NULL
) {
618 return NMERR_BAD_PARM
;
622 fields
= nm_field_add_pointer(fields
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
623 g_strdup_printf("%d", nm_folder_get_id(folder
)),
627 fields
= nm_field_add_pointer(fields
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
628 g_strdup_printf("%d", nm_contact_get_id(contact
)),
631 /* Dispatch the request */
632 rc
= nm_send_request(user
->conn
, "deletecontact", fields
, callback
, data
, &req
);
633 if (rc
== NM_OK
&& req
)
634 nm_request_set_data(req
, contact
);
637 nm_release_request(req
);
639 nm_free_fields(&fields
);
644 nm_send_create_folder(NMUser
* user
, const char *name
,
645 nm_response_cb callback
, gpointer data
)
648 NMField
*fields
= NULL
;
649 NMRequest
*req
= NULL
;
651 if (user
== NULL
|| name
== NULL
) {
652 return NMERR_BAD_PARM
;
656 fields
= nm_field_add_pointer(fields
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
657 g_strdup("0"), NMFIELD_TYPE_UTF8
);
659 /* Add name of the folder to add */
661 nm_field_add_pointer(fields
, NM_A_SZ_DISPLAY_NAME
, 0, NMFIELD_METHOD_VALID
, 0,
662 g_strdup(name
), NMFIELD_TYPE_UTF8
);
664 /* Add sequence, for now just put it at the bottom */
666 nm_field_add_pointer(fields
, NM_A_SZ_SEQUENCE_NUMBER
, 0, NMFIELD_METHOD_VALID
, 0,
667 g_strdup("-1"), NMFIELD_TYPE_UTF8
);
669 /* Dispatch the request */
670 rc
= nm_send_request(user
->conn
, "createfolder", fields
, callback
, data
, &req
);
671 if (rc
== NM_OK
&& req
)
672 nm_request_set_data(req
, g_strdup(name
));
675 nm_release_request(req
);
677 nm_free_fields(&fields
);
682 nm_send_remove_folder(NMUser
* user
, NMFolder
* folder
,
683 nm_response_cb callback
, gpointer data
)
686 NMField
*fields
= NULL
;
687 NMRequest
*req
= NULL
;
689 if (user
== NULL
|| folder
== NULL
) {
690 return NMERR_BAD_PARM
;
693 /* Add the object id */
694 fields
= nm_field_add_pointer(fields
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
695 g_strdup_printf("%d", nm_folder_get_id(folder
)),
698 /* Dispatch the request */
699 rc
= nm_send_request(user
->conn
, "deletecontact", fields
, callback
, data
, &req
);
700 if (rc
== NM_OK
&& req
)
701 nm_request_set_data(req
, folder
);
704 nm_release_request(req
);
706 nm_free_fields(&fields
);
711 nm_send_get_status(NMUser
* user
, NMUserRecord
* user_record
,
712 nm_response_cb callback
, gpointer data
)
715 NMField
*fields
= NULL
;
716 NMRequest
*req
= NULL
;
719 if (user
== NULL
|| user_record
== NULL
)
720 return NMERR_BAD_PARM
;
722 /* Add DN to field list */
723 dn
= nm_user_record_get_dn(user_record
);
727 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
728 g_strdup(dn
), NMFIELD_TYPE_UTF8
);
730 /* Dispatch the request */
731 rc
= nm_send_request(user
->conn
, "getstatus", fields
, callback
, data
, &req
);
732 if (rc
== NM_OK
&& req
)
733 nm_request_set_data(req
, user_record
);
736 nm_release_request(req
);
738 nm_free_fields(&fields
);
743 nm_send_rename_contact(NMUser
* user
, NMContact
* contact
,
744 const char *new_name
, nm_response_cb callback
,
748 NMField
*field
= NULL
, *fields
= NULL
, *list
= NULL
;
749 NMRequest
*req
= NULL
;
751 if (user
== NULL
|| contact
== NULL
|| new_name
== NULL
)
752 return NMERR_BAD_PARM
;
754 /* Create field list for current contact */
755 field
= nm_contact_to_fields(contact
);
759 nm_field_add_pointer(fields
, NM_A_FA_CONTACT
, 0, NMFIELD_METHOD_DELETE
, 0,
760 field
, NMFIELD_TYPE_ARRAY
);
763 /* Update the contacts display name locally */
764 nm_contact_set_display_name(contact
, new_name
);
766 /* Create field list for updated contact */
767 field
= nm_contact_to_fields(contact
);
770 nm_field_add_pointer(fields
, NM_A_FA_CONTACT
, 0, NMFIELD_METHOD_ADD
, 0,
771 field
, NMFIELD_TYPE_ARRAY
);
776 nm_field_add_pointer(list
, NM_A_FA_CONTACT_LIST
, 0, NMFIELD_METHOD_VALID
,
777 0, fields
, NMFIELD_TYPE_ARRAY
);
780 rc
= nm_send_request(user
->conn
, "updateitem", list
, callback
, data
, &req
);
781 if (rc
== NM_OK
&& req
)
782 nm_request_set_data(req
, contact
);
787 nm_release_request(req
);
790 nm_free_fields(&list
);
796 nm_send_rename_folder(NMUser
* user
, NMFolder
* folder
, const char *new_name
,
797 nm_response_cb callback
, gpointer data
)
800 NMField
*field
= NULL
, *fields
= NULL
, *list
= NULL
;
801 NMRequest
*req
= NULL
;
803 if (user
== NULL
|| folder
== NULL
|| new_name
== NULL
)
804 return NMERR_BAD_PARM
;
806 /* Make sure folder does not already exist!? */
807 if (nm_find_folder(user
, new_name
))
808 return NMERR_FOLDER_EXISTS
;
810 /* Create field list for current folder */
811 field
= nm_folder_to_fields(folder
);
814 fields
= nm_field_add_pointer(fields
, NM_A_FA_FOLDER
, 0, NMFIELD_METHOD_DELETE
, 0,
815 field
, NMFIELD_TYPE_ARRAY
);
818 /* Update the folders display name locally */
819 nm_folder_set_name(folder
, new_name
);
821 /* Create field list for updated folder */
822 field
= nm_folder_to_fields(folder
);
824 fields
= nm_field_add_pointer(fields
, NM_A_FA_FOLDER
, 0, NMFIELD_METHOD_ADD
, 0,
825 field
, NMFIELD_TYPE_ARRAY
);
829 list
= nm_field_add_pointer(list
, NM_A_FA_CONTACT_LIST
, 0, NMFIELD_METHOD_VALID
,
830 0, fields
, NMFIELD_TYPE_ARRAY
);
833 rc
= nm_send_request(user
->conn
, "updateitem", list
, callback
, data
, &req
);
834 if (rc
== NM_OK
&& req
)
835 nm_request_set_data(req
, folder
);
840 nm_release_request(req
);
843 nm_free_fields(&list
);
849 nm_send_move_contact(NMUser
* user
, NMContact
* contact
, NMFolder
* folder
,
850 nm_response_cb callback
, gpointer data
)
853 NMField
*field
= NULL
, *fields
= NULL
, *list
= NULL
;
854 NMRequest
*req
= NULL
;
856 if (user
== NULL
|| contact
== NULL
|| folder
== NULL
)
857 return NMERR_BAD_PARM
;
859 /* Create field list for the contact */
860 field
= nm_contact_to_fields(contact
);
863 fields
= nm_field_add_pointer(fields
, NM_A_FA_CONTACT
, 0, NMFIELD_METHOD_DELETE
, 0,
864 field
, NMFIELD_TYPE_ARRAY
);
867 /* Wrap the contact up and add it to the request field list */
868 list
= nm_field_add_pointer(list
, NM_A_FA_CONTACT_LIST
, 0, NMFIELD_METHOD_VALID
, 0,
869 fields
, NMFIELD_TYPE_ARRAY
);
872 /* Add sequence number */
873 list
= nm_field_add_pointer(list
, NM_A_SZ_SEQUENCE_NUMBER
, 0, NMFIELD_METHOD_VALID
,
874 0, g_strdup("-1"), NMFIELD_TYPE_UTF8
);
877 list
= nm_field_add_pointer(list
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
878 g_strdup_printf("%d", nm_folder_get_id(folder
)),
881 /* Dispatch the request */
882 rc
= nm_send_request(user
->conn
, "movecontact", list
, callback
, data
, &req
);
883 if (rc
== NM_OK
&& req
)
884 nm_request_set_data(req
, contact
);
889 nm_release_request(req
);
892 nm_free_fields(&list
);
899 nm_send_create_privacy_item(NMUser
*user
, const char *who
, gboolean allow_list
,
900 nm_response_cb callback
, gpointer data
)
903 NMField
*fields
= NULL
;
906 if (user
== NULL
|| who
== NULL
)
907 return NMERR_BAD_PARM
;
910 tag
= NM_A_SZ_BLOCKING_ALLOW_ITEM
;
912 tag
= NM_A_SZ_BLOCKING_DENY_ITEM
;
914 fields
= nm_field_add_pointer(fields
, tag
, 0, NMFIELD_METHOD_ADD
, 0,
915 g_strdup(who
), NMFIELD_TYPE_UTF8
);
917 rc
= nm_send_request(user
->conn
, "createblock", fields
, callback
, data
, NULL
);
919 nm_free_fields(&fields
);
924 nm_send_remove_privacy_item(NMUser
*user
, const char *dn
, gboolean allow_list
,
925 nm_response_cb callback
, gpointer data
)
928 NMField
*fields
= NULL
;
930 GSList
**list_ptr
, *node
;
932 if (user
== NULL
|| dn
== NULL
)
933 return NMERR_BAD_PARM
;
936 tag
= NM_A_BLOCKING_ALLOW_LIST
;
937 list_ptr
= &user
->allow_list
;
939 tag
= NM_A_BLOCKING_DENY_LIST
;
940 list_ptr
= &user
->deny_list
;
943 /* Remove item from the cached list */
944 if ((node
= g_slist_find_custom(*list_ptr
, dn
, (GCompareFunc
)purple_utf8_strcasecmp
))) {
945 *list_ptr
= g_slist_delete_link(*list_ptr
, node
);
948 fields
= nm_field_add_pointer(fields
, tag
, 0, NMFIELD_METHOD_DELETE
, 0,
949 g_strdup(dn
), NMFIELD_TYPE_DN
);
951 rc
= nm_send_request(user
->conn
, "updateblocks", fields
, callback
, data
, NULL
);
953 nm_free_fields(&fields
);
959 nm_send_set_privacy_default(NMUser
*user
, gboolean default_deny
,
960 nm_response_cb callback
, gpointer data
)
963 NMField
*fields
= NULL
;
966 return NMERR_BAD_PARM
;
968 fields
= nm_field_add_pointer(fields
, NM_A_BLOCKING
, 0, NMFIELD_METHOD_UPDATE
, 0,
969 (default_deny
? g_strdup("1") : g_strdup("0")),
972 rc
= nm_send_request(user
->conn
, "updateblocks", fields
, callback
, data
, NULL
);
974 nm_free_fields(&fields
);
979 nm_send_keepalive(NMUser
*user
, nm_response_cb callback
, gpointer data
)
984 return NMERR_BAD_PARM
;
986 rc
= nm_send_request(user
->conn
, "ping", NULL
, callback
, data
, NULL
);
992 nm_process_new_data(NMUser
* user
)
999 return NMERR_BAD_PARM
;
1003 /* Check to see if this is an event or a response */
1004 rc
= nm_read_all(conn
, (char *) &val
, sizeof(val
));
1006 if (strncmp((char *) &val
, "HTTP", strlen("HTTP")) == 0)
1007 rc
= nm_process_response(user
);
1009 rc
= nm_process_event(user
, GUINT32_FROM_LE(val
));
1012 if (errno
== EAGAIN
)
1015 rc
= NMERR_PROTOCOL
;
1022 nm_find_conversation(NMUser
* user
, const char *who
)
1024 NMConference
*conference
= NULL
;
1028 if (user
&& user
->conferences
) {
1029 for (cnode
= user
->conferences
; cnode
; cnode
= cnode
->next
) {
1031 if (nm_conference_get_participant_count(tmp
) == 1) {
1032 NMUserRecord
*ur
= nm_conference_get_participant(tmp
, 0);
1035 if (nm_utf8_str_equal(nm_user_record_get_dn(ur
), who
)) {
1048 nm_conference_list_add(NMUser
* user
, NMConference
* conf
)
1050 if (user
== NULL
|| conf
== NULL
)
1053 nm_conference_add_ref(conf
);
1054 user
->conferences
= g_slist_append(user
->conferences
, conf
);
1058 nm_conference_list_remove(NMUser
* user
, NMConference
* conf
)
1060 if (user
== NULL
|| conf
== NULL
)
1063 if (g_slist_find(user
->conferences
, conf
)) {
1064 user
->conferences
= g_slist_remove(user
->conferences
, conf
);
1065 nm_release_conference(conf
);
1070 nm_conference_list_free(NMUser
* user
)
1075 g_slist_free_full(user
->conferences
, (GDestroyNotify
)nm_release_conference
);
1076 user
->conferences
= NULL
;
1080 nm_conference_list_find(NMUser
* user
, const char *guid
)
1083 NMConference
*conference
= NULL
, *tmp
;
1085 if (user
== NULL
|| guid
== NULL
)
1088 if (user
->conferences
) {
1089 for (cnode
= user
->conferences
; cnode
; cnode
= cnode
->next
) {
1091 if (nm_are_guids_equal(nm_conference_get_guid(tmp
), guid
)) {
1102 nm_are_guids_equal(const char *guid1
, const char *guid2
)
1104 if (guid1
== NULL
|| guid2
== NULL
)
1107 return (strncmp(guid1
, guid2
, CONF_GUID_END
) == 0);
1111 nm_user_add_contact(NMUser
* user
, NMContact
* contact
)
1113 if (user
== NULL
|| contact
== NULL
)
1116 nm_contact_add_ref(contact
);
1118 g_hash_table_insert(user
->contacts
,
1119 g_utf8_strdown(nm_contact_get_dn(contact
), -1), contact
);
1123 nm_user_add_user_record(NMUser
* user
, NMUserRecord
* user_record
)
1125 const char *display_id
;
1128 if (!user
|| !user_record
)
1131 display_id
= nm_user_record_get_display_id(user_record
);
1132 dn
= nm_user_record_get_dn(user_record
);
1134 if (!dn
|| !display_id
)
1137 nm_user_record_add_ref(user_record
);
1139 g_hash_table_insert(user
->user_records
,
1140 g_utf8_strdown(dn
, -1),
1143 g_hash_table_insert(user
->display_id_to_dn
,
1144 g_utf8_strdown(display_id
, -1),
1145 g_utf8_strdown(dn
, -1));
1149 nm_user_get_event_callback(NMUser
* user
)
1154 return user
->evt_callback
;
1158 nm_user_get_conn(NMUser
* user
)
1167 nm_create_contact_list(NMUser
* user
)
1170 NMField
*locate
= NULL
;
1172 if (user
== NULL
|| user
->fields
== NULL
) {
1173 return NMERR_BAD_PARM
;
1176 /* Create the root folder */
1177 user
->root_folder
= nm_create_folder("");
1179 /* Find the contact list in the login fields */
1180 locate
= nm_locate_field(NM_A_FA_CONTACT_LIST
, user
->fields
);
1181 if (locate
!= NULL
) {
1183 /* Add the folders and then the contacts */
1184 nm_folder_add_contacts_and_folders(user
, user
->root_folder
,
1185 (NMField
*) (locate
->ptr_value
));
1192 gboolean
nm_user_is_privacy_locked(NMUser
*user
)
1195 return user
->privacy_locked
;
1202 _create_privacy_list(NMUser
* user
, NMRequest
*request
)
1204 NMField
*locate
= NULL
;
1205 GSList
*need_details
= NULL
;
1207 /* Are the privacy settings locked */
1208 locate
= nm_locate_field(NM_A_LOCKED_ATTR_LIST
, user
->fields
);
1209 if (locate
&& locate
->ptr_value
) {
1210 if (locate
->type
== NMFIELD_TYPE_UTF8
&&
1211 (purple_utf8_strcasecmp(locate
->ptr_value
, NM_A_BLOCKING
) == 0)) {
1212 user
->privacy_locked
= TRUE
;
1213 } else if (locate
->type
== NMFIELD_TYPE_MV
||
1214 locate
->type
== NMFIELD_TYPE_ARRAY
) {
1215 NMField
*tmp
= (NMField
*)locate
->ptr_value
;
1216 while (tmp
&& tmp
->tag
) {
1217 if (purple_utf8_strcasecmp(tmp
->ptr_value
, NM_A_BLOCKING
) == 0) {
1218 user
->privacy_locked
= TRUE
;
1226 /* Set default deny flag */
1227 locate
= nm_locate_field(NM_A_BLOCKING
, user
->fields
);
1228 if (locate
&& locate
->ptr_value
) {
1229 user
->default_deny
= atoi((char *)locate
->ptr_value
);
1232 /* Read internal blocking allow list */
1233 locate
= nm_locate_field(NM_A_BLOCKING_ALLOW_LIST
, user
->fields
);
1234 if (locate
&& locate
->ptr_value
) {
1236 if (locate
->type
== NMFIELD_TYPE_MV
) {
1237 locate
= (NMField
*)locate
->ptr_value
;
1238 for (; locate
->tag
!= NULL
; locate
++) {
1239 if (locate
->ptr_value
) {
1241 user
->allow_list
= g_slist_append(user
->allow_list
, (char *)locate
->ptr_value
);
1243 if (nm_find_user_record(user
, (char *)locate
->ptr_value
) == NULL
)
1244 need_details
= g_slist_append(need_details
, (char *)locate
->ptr_value
);
1250 user
->allow_list
= g_slist_append(user
->allow_list
, (char *)locate
->ptr_value
);
1252 if (nm_find_user_record(user
, (char *)locate
->ptr_value
) == NULL
)
1253 need_details
= g_slist_append(need_details
, (char *)locate
->ptr_value
);
1258 /* Read internal blocking deny list */
1259 locate
= nm_locate_field(NM_A_BLOCKING_DENY_LIST
, user
->fields
);
1260 if (locate
&& locate
->ptr_value
) {
1262 if (locate
->type
== NMFIELD_TYPE_MV
) {
1263 locate
= (NMField
*)locate
->ptr_value
;
1264 for (; locate
->tag
!= NULL
; locate
++) {
1265 if (locate
->ptr_value
) {
1267 user
->deny_list
= g_slist_append(user
->deny_list
, (char *)locate
->ptr_value
);
1269 if (nm_find_user_record(user
, (char *)locate
->ptr_value
) == NULL
)
1270 need_details
= g_slist_append(need_details
, (char *)locate
->ptr_value
);
1276 user
->deny_list
= g_slist_append(user
->deny_list
, (char *)locate
->ptr_value
);
1278 if (nm_find_user_record(user
, (char *)locate
->ptr_value
) == NULL
)
1279 need_details
= g_slist_append(need_details
, (char *)locate
->ptr_value
);
1286 nm_request_add_ref(request
);
1287 nm_send_multiple_get_details(user
, need_details
,
1288 _handle_multiple_get_details_login_cb
, request
);
1297 nm_destroy_contact_list(NMUser
* user
)
1302 if (user
->root_folder
) {
1303 nm_release_folder(user
->root_folder
);
1304 user
->root_folder
= NULL
;
1309 nm_get_root_folder(NMUser
* user
)
1314 if (user
->root_folder
== NULL
)
1315 nm_create_contact_list(user
);
1317 return user
->root_folder
;
1321 nm_find_contact(NMUser
* user
, const char *name
)
1324 const char *dn
= NULL
;
1325 NMContact
*contact
= NULL
;
1327 if (user
== NULL
|| name
== NULL
)
1330 str
= g_utf8_strdown(name
, -1);
1331 if (strstr(str
, "=")) {
1334 /* Assume that we have a display id instead of a dn */
1335 dn
= (const char *) g_hash_table_lookup(user
->display_id_to_dn
, str
);
1338 /* Find contact object in reference table */
1340 contact
= (NMContact
*) g_hash_table_lookup(user
->contacts
, dn
);
1348 nm_find_contacts(NMUser
* user
, const char *dn
)
1353 GList
*contacts
= NULL
;
1355 if (user
== NULL
|| dn
== NULL
)
1358 /* Check for contact at the root */
1359 contact
= nm_folder_find_contact(user
->root_folder
, dn
);
1361 contacts
= g_list_append(contacts
, contact
);
1365 /* Check for contact in each subfolder */
1366 cnt
= nm_folder_get_subfolder_count(user
->root_folder
);
1367 for (i
= 0; i
< cnt
; i
++) {
1368 folder
= nm_folder_get_subfolder(user
->root_folder
, i
);
1369 contact
= nm_folder_find_contact(folder
, dn
);
1371 contacts
= g_list_append(contacts
, contact
);
1380 nm_find_user_record(NMUser
* user
, const char *name
)
1383 const char *dn
= NULL
;
1384 NMUserRecord
*user_record
= NULL
;
1386 if (user
== NULL
|| name
== NULL
)
1389 str
= g_utf8_strdown(name
, -1);
1390 if (strstr(str
, "=")) {
1393 /* Assume that we have a display id instead of a dn */
1394 dn
= (const char *) g_hash_table_lookup(user
->display_id_to_dn
, str
);
1397 /* Find user record in reference table */
1400 (NMUserRecord
*) g_hash_table_lookup(user
->user_records
, dn
);
1408 nm_lookup_dn(NMUser
* user
, const char *display_id
)
1413 if (user
== NULL
|| display_id
== NULL
)
1416 lower
= g_utf8_strdown(display_id
, -1);
1417 dn
= g_hash_table_lookup(user
->display_id_to_dn
, lower
);
1424 nm_find_folder(NMUser
* user
, const char *name
)
1426 NMFolder
*folder
= NULL
, *temp
;
1428 const char *tname
= NULL
;
1430 if (user
== NULL
|| name
== NULL
)
1434 return user
->root_folder
;
1436 num_folders
= nm_folder_get_subfolder_count(user
->root_folder
);
1437 for (i
= 0; i
< num_folders
; i
++) {
1438 temp
= nm_folder_get_subfolder(user
->root_folder
, i
);
1439 tname
= nm_folder_get_name(temp
);
1440 if (tname
&& purple_strequal(tname
, name
)) {
1450 nm_find_folder_by_id(NMUser
* user
, int object_id
)
1452 NMFolder
*folder
= NULL
, *temp
;
1459 return user
->root_folder
;
1461 num_folders
= nm_folder_get_subfolder_count(user
->root_folder
);
1462 for (i
= 0; i
< num_folders
; i
++) {
1463 temp
= nm_folder_get_subfolder(user
->root_folder
, i
);
1464 if (nm_folder_get_id(temp
) == object_id
) {
1474 _handle_multiple_get_details_login_cb(NMUser
* user
, NMERR_T ret_code
,
1475 gpointer resp_data
, gpointer user_data
)
1478 NMRequest
*request
= user_data
;
1480 if (user
== NULL
|| request
== NULL
)
1483 if ((cb
= nm_request_get_callback(request
))) {
1484 cb(user
, ret_code
, nm_request_get_data(request
),
1485 nm_request_get_user_define(request
));
1486 nm_release_request(request
);
1491 _handle_multiple_get_details_joinconf_cb(NMUser
* user
, NMERR_T ret_code
,
1492 gpointer resp_data
, gpointer user_data
)
1494 NMRequest
*request
= user_data
;
1495 NMUserRecord
*user_record
= resp_data
;
1496 NMConference
*conference
;
1497 GSList
*list
, *node
;
1499 if (user
== NULL
|| resp_data
== NULL
|| user_data
== NULL
)
1502 conference
= nm_request_get_data(request
);
1503 list
= nm_request_get_user_define(request
);
1505 if (ret_code
== 0 && conference
&& list
) {
1507 /* Add the user to the conference */
1508 nm_conference_add_participant(conference
, user_record
);
1510 /* Find the user in the list and remove it */
1511 node
= g_slist_find_custom(list
, nm_user_record_get_dn(user_record
), (GCompareFunc
)purple_utf8_strcasecmp
);
1514 list
= g_slist_delete_link(list
, node
);
1515 nm_request_set_user_define(request
, list
);
1518 /* Time to callback? */
1520 nm_response_cb cb
= nm_request_get_callback(request
);
1523 cb(user
, 0, conference
, conference
);
1525 nm_release_request(request
);
1531 nm_call_handler(NMUser
* user
, NMRequest
* request
, NMField
* fields
)
1533 NMERR_T rc
= NM_OK
, ret_code
= NM_OK
;
1534 NMConference
*conf
= NULL
;
1535 NMUserRecord
*user_record
= NULL
;
1536 NMField
*locate
= NULL
;
1537 NMField
*field
= NULL
;
1540 gboolean done
= TRUE
;
1542 if (user
== NULL
|| request
== NULL
|| fields
== NULL
)
1543 return NMERR_BAD_PARM
;
1545 /* Get the return code */
1546 field
= nm_locate_field(NM_A_SZ_RESULT_CODE
, fields
);
1548 ret_code
= atoi((char *) field
->ptr_value
);
1550 ret_code
= NMERR_PROTOCOL
;
1553 cmd
= nm_request_get_cmd(request
);
1554 if (ret_code
== NM_OK
&& cmd
!= NULL
) {
1556 if (purple_strequal("login", cmd
)) {
1558 user
->user_record
= nm_create_user_record_from_fields(fields
);
1560 /* Save the users fields */
1561 user
->fields
= nm_copy_field_array(fields
);
1563 nm_create_contact_list(user
);
1564 done
= _create_privacy_list(user
, request
);
1566 } else if (purple_strequal("setstatus", cmd
)) {
1570 } else if (purple_strequal("createconf", cmd
)) {
1572 conf
= (NMConference
*) nm_request_get_data(request
);
1574 /* get the convo guid */
1575 locate
= nm_locate_field(NM_A_FA_CONVERSATION
, fields
);
1578 nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
);
1580 nm_conference_set_guid(conf
, (char *) field
->ptr_value
);
1584 nm_conference_list_add(user
, conf
);
1585 nm_release_conference(conf
);
1587 } else if (purple_strequal("leaveconf", cmd
)) {
1589 conf
= (NMConference
*) nm_request_get_data(request
);
1590 nm_conference_list_remove(user
, conf
);
1592 } else if (purple_strequal("joinconf", cmd
)) {
1593 GSList
*list
= NULL
, *node
;
1595 conf
= nm_request_get_data(request
);
1597 locate
= nm_locate_field(NM_A_FA_CONTACT_LIST
, fields
);
1598 if (locate
&& locate
->ptr_value
!= 0) {
1600 field
= (NMField
*) locate
->ptr_value
;
1601 while ((field
= nm_locate_field(NM_A_SZ_DN
, field
))) {
1602 if (field
->ptr_value
!= 0) {
1604 if (nm_utf8_str_equal
1605 (nm_user_record_get_dn(user
->user_record
),
1606 (const char *) field
->ptr_value
)) {
1612 nm_find_user_record(user
,
1613 (const char *) field
->ptr_value
);
1614 if (user_record
== NULL
) {
1616 g_slist_append(list
,
1617 g_strdup((char *) field
->ptr_value
));
1619 nm_conference_add_participant(conf
, user_record
);
1628 nm_request_set_user_define(request
, list
);
1629 nm_request_add_ref(request
);
1630 for (node
= list
; node
; node
= node
->next
) {
1632 nm_send_get_details(user
, (const char *) node
->data
,
1633 _handle_multiple_get_details_joinconf_cb
,
1639 } else if (purple_strequal("getdetails", cmd
)) {
1641 locate
= nm_locate_field(NM_A_FA_RESULTS
, fields
);
1642 while (locate
&& locate
->ptr_value
!= 0) {
1644 user_record
= nm_create_user_record_from_fields(locate
);
1649 nm_find_user_record(user
,
1650 nm_user_record_get_dn(user_record
));
1653 /* Update the existing user record */
1654 nm_user_record_copy(tmp
, user_record
);
1655 nm_release_user_record(user_record
);
1659 nm_user_add_user_record(user
, user_record
);
1660 nm_release_user_record(user_record
);
1663 /* Response data is new user record */
1664 nm_request_set_data(request
, (gpointer
) user_record
);
1667 locate
= nm_locate_field(NM_A_FA_RESULTS
, locate
+1);
1670 } else if (purple_strequal("createfolder", cmd
)) {
1672 _update_contact_list(user
, fields
);
1674 } else if (purple_strequal("createcontact", cmd
)) {
1676 _update_contact_list(user
, fields
);
1679 nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
);
1682 NMContact
*new_contact
=
1683 nm_folder_find_item_by_object_id(user
->root_folder
,
1684 atoi((char *)locate
->ptr_value
));
1688 /* Add the contact to our cache */
1689 nm_user_add_contact(user
, new_contact
);
1691 /* Set the contact as the response data */
1692 nm_request_set_data(request
, (gpointer
) new_contact
);
1698 } else if (purple_strequal("deletecontact", cmd
)) {
1700 _update_contact_list(user
, fields
);
1702 } else if (purple_strequal("movecontact", cmd
)) {
1704 _update_contact_list(user
, fields
);
1706 } else if (purple_strequal("getstatus", cmd
)) {
1708 locate
= nm_locate_field(NM_A_SZ_STATUS
, fields
);
1710 nm_user_record_set_status((NMUserRecord
*)
1711 nm_request_get_data(request
),
1712 atoi((char *) locate
->ptr_value
), NULL
);
1715 } else if (purple_strequal("updateitem", cmd
)) {
1717 /* Nothing extra to do here */
1719 } else if (purple_strequal("createblock", cmd
)) {
1720 if ((locate
= nm_locate_field(NM_A_BLOCKING_DENY_LIST
, fields
))) {
1721 if (locate
->ptr_value
) {
1722 user
->deny_list
= g_slist_append(user
->deny_list
, g_strdup((char *)locate
->ptr_value
));
1724 } else if ((locate
= nm_locate_field(NM_A_BLOCKING_ALLOW_LIST
, fields
))) {
1725 if (locate
->ptr_value
) {
1726 user
->allow_list
= g_slist_append(user
->allow_list
, g_strdup((char *)locate
->ptr_value
));
1729 } else if (purple_strequal("updateblocks", cmd
)) {
1730 /* nothing to do here */
1733 /* Nothing to do, just print debug message */
1734 purple_debug(PURPLE_DEBUG_INFO
, "novell",
1735 "nm_call_handler(): Unknown request command, %s\n", cmd
);
1740 if (done
&& (cb
= nm_request_get_callback(request
))) {
1742 cb(user
, ret_code
, nm_request_get_data(request
),
1743 nm_request_get_user_define(request
));
1750 nm_process_response(NMUser
* user
)
1753 NMField
*fields
= NULL
;
1754 NMField
*field
= NULL
;
1755 NMConn
*conn
= user
->conn
;
1756 NMRequest
*req
= NULL
;
1758 rc
= nm_read_header(conn
);
1760 rc
= nm_read_fields(conn
, -1, &fields
);
1764 field
= nm_locate_field(NM_A_SZ_TRANSACTION_ID
, fields
);
1765 if (field
!= NULL
&& field
->ptr_value
!= 0) {
1766 req
= nm_conn_find_request(conn
, atoi((char *) field
->ptr_value
));
1768 rc
= nm_call_handler(user
, req
, fields
);
1769 nm_conn_remove_request_item(conn
, req
);
1776 nm_free_fields(&fields
);
1782 * Some utility functions...haven't figured out where
1787 nm_utf8_str_equal(gconstpointer str1
, gconstpointer str2
)
1789 return (purple_utf8_strcasecmp(str1
, str2
) == 0);
1793 nm_typed_to_dotted(const char *typed
)
1795 unsigned i
= 0, j
= 0;
1801 dotted
= g_new0(char, strlen(typed
) + 1);
1805 /* replace comma with a dot */
1812 while (typed
[i
] != '\0' && typed
[i
] != '=')
1815 /* verify that we aren't running off the end */
1816 if (typed
[i
] == '\0') {
1823 /* copy the object name to context */
1824 while (typed
[i
] != '\0' && typed
[i
] != ',') {
1825 dotted
[j
] = typed
[i
];
1830 } while (typed
[i
] != '\0');
1836 nm_error_to_string(NMERR_T err
)
1838 static char *unknown_msg
= NULL
;
1840 g_free(unknown_msg
);
1845 case NMERR_BAD_PARM
:
1846 return _("Required parameters not passed in");
1848 case NMERR_TCP_WRITE
:
1849 return _("Unable to write to network");
1851 case NMERR_TCP_READ
:
1852 return _("Unable to read from network");
1854 case NMERR_PROTOCOL
:
1855 return _("Error communicating with server");
1857 case NMERR_CONFERENCE_NOT_FOUND
:
1858 case NMERR_CONFERENCE_NOT_FOUND_2
:
1859 return _("Conference not found");
1861 case NMERR_CONFERENCE_NOT_INSTANTIATED
:
1862 return _("Conference does not exist");
1864 case NMERR_DUPLICATE_FOLDER
:
1865 case NMERR_FOLDER_EXISTS
:
1866 return _("A folder with that name already exists");
1868 case NMERR_NOT_SUPPORTED
:
1869 return _("Not supported");
1871 case NMERR_PASSWORD_EXPIRED
:
1872 case NMERR_PASSWORD_EXPIRED_2
:
1873 return _("Password has expired");
1875 case NMERR_PASSWORD_INVALID
:
1876 return _("Incorrect password");
1878 case NMERR_USER_NOT_FOUND
:
1879 return _("User not found");
1881 case NMERR_USER_DISABLED
:
1882 return _("Account has been disabled");
1884 case NMERR_DIRECTORY_FAILURE
:
1885 return _("The server could not access the directory");
1887 case NMERR_ADMIN_LOCKED
:
1888 return _("Your system administrator has disabled this operation");
1890 case NMERR_SERVER_BUSY
:
1891 return _("The server is unavailable; try again later");
1893 case NMERR_DUPLICATE_CONTACT
:
1894 return _("Cannot add a contact to the same folder twice");
1896 case NMERR_USER_NOT_ALLOWED
:
1897 return _("Cannot add yourself");
1899 case NMERR_MASTER_ARCHIVE_MISSING
:
1900 return _("Master archive is misconfigured");
1902 case NMERR_AUTHENTICATION_FAILED
:
1903 case NMERR_CREDENTIALS_MISSING
:
1904 return _("Incorrect username or password");
1906 case NMERR_HOST_NOT_FOUND
:
1907 return _("Could not recognize the host of the username you entered");
1909 case NMERR_ACCESS_DENIED
:
1910 return _("Your account has been disabled because too many incorrect passwords were entered");
1912 case NMERR_DUPLICATE_PARTICIPANT
:
1913 return _("You cannot add the same person twice to a conversation");
1915 case NMERR_TOO_MANY_CONTACTS
:
1916 case NMERR_TOO_MANY_FOLDERS
:
1917 return _("You have reached your limit for the number of contacts allowed");
1919 case NMERR_OBJECT_NOT_FOUND
:
1920 return _("You have entered an incorrect username");
1922 case NMERR_DIRECTORY_UPDATE
:
1923 return _("An error occurred while updating the directory");
1925 case NMERR_SERVER_PROTOCOL
:
1926 return _("Incompatible protocol version");
1928 case NMERR_USER_BLOCKED
:
1929 return _("The user has blocked you");
1931 case NMERR_EVAL_CONNECTION_LIMIT
:
1932 return _("This evaluation version does not allow more than ten users to log in at one time");
1934 case NMERR_CONVERSATION_INVITE
:
1935 return _("The user is either offline or you are blocked");
1938 unknown_msg
= g_strdup_printf (_("Unknown error: 0x%X"), err
);
1945 _update_contact_list(NMUser
* user
, NMField
* fields
)
1947 NMField
*list
, *cursor
, *locate
;
1953 if (user
== NULL
|| fields
== NULL
)
1956 /* Is it wrapped in a RESULTS array? */
1957 if (purple_strequal(fields
->tag
, NM_A_FA_RESULTS
)) {
1958 list
= (NMField
*) fields
->ptr_value
;
1963 /* Update the cached contact list */
1964 cursor
= (NMField
*) list
->ptr_value
;
1965 while (cursor
->tag
!= NULL
) {
1966 if ((g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_CONTACT
) == 0) ||
1967 (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_FOLDER
) == 0)) {
1970 nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) cursor
->ptr_value
);
1971 if (locate
!= NULL
&& locate
->ptr_value
!= 0) {
1972 objid1
= atoi((char *) locate
->ptr_value
);
1974 nm_folder_find_item_by_object_id(user
->root_folder
, objid1
);
1976 if (cursor
->method
== NMFIELD_METHOD_ADD
) {
1977 if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_CONTACT
) == 0) {
1978 contact
= (NMContact
*) item
;
1979 nm_contact_update_list_properties(contact
, cursor
);
1980 } else if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_FOLDER
)
1982 folder
= (NMFolder
*) item
;
1983 nm_folder_update_list_properties(folder
, cursor
);
1985 } else if (cursor
->method
== NMFIELD_METHOD_DELETE
) {
1986 if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_CONTACT
) == 0) {
1987 contact
= (NMContact
*) item
;
1989 nm_find_folder_by_id(user
,
1990 nm_contact_get_parent_id
1993 nm_folder_remove_contact(folder
, contact
);
1995 } else if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_FOLDER
)
1997 /* TODO: write nm_folder_remove_folder */
1998 /* ignoring for now, should not be a big deal */
1999 /* folder = (NMFolder *) item;*/
2000 /* nm_folder_remove_folder(user->root_folder, folder);*/
2005 if (cursor
->method
== NMFIELD_METHOD_ADD
) {
2007 /* Not found, so we need to add it */
2008 if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_CONTACT
) == 0) {
2011 nm_locate_field(NM_A_SZ_DN
,
2012 (NMField
*) cursor
->ptr_value
);
2013 if (locate
!= NULL
&& locate
->ptr_value
!= NULL
) {
2014 contact
= nm_create_contact_from_fields(cursor
);
2016 nm_folder_add_contact_to_list(
2017 user
->root_folder
, contact
);
2018 nm_release_contact(contact
);
2021 } else if (g_ascii_strcasecmp(cursor
->tag
, NM_A_FA_FOLDER
)
2023 folder
= nm_create_folder_from_fields(cursor
);
2024 nm_folder_add_folder_to_list(user
->root_folder
,
2026 nm_release_folder(folder
);
2037 nm_rtfize_text(char *text
)
2039 GString
*gstr
= NULL
;
2041 char *uni_str
= NULL
, *rtf
= NULL
;
2045 gstr
= g_string_sized_new(strlen(text
)*2);
2046 pch
= (unsigned char *)text
;
2048 if ((*pch
) <= 0x7F) {
2053 gstr
= g_string_append_c(gstr
, '\\');
2054 gstr
= g_string_append_c(gstr
, *pch
);
2057 gstr
= g_string_append(gstr
, "\\par ");
2060 gstr
= g_string_append_c(gstr
, *pch
);
2065 /* convert the utf-8 character to ucs-4 for rtf encoding */
2067 uc
= ((((gunichar
)pch
[0]) & 0x001F) << 6) |
2068 (((gunichar
)pch
[1]) & 0x003F);
2070 } else if(*pch
<= 0xEF) {
2071 uc
= ((((gunichar
)pch
[0]) & 0x000F) << 12) |
2072 ((((gunichar
)pch
[1]) & 0x003F) << 6) |
2073 (((gunichar
)pch
[2]) & 0x003F);
2075 } else if (*pch
<= 0xF7) {
2076 uc
= ((((gunichar
)pch
[0]) & 0x0007) << 18) |
2077 ((((gunichar
)pch
[1]) & 0x003F) << 12) |
2078 ((((gunichar
)pch
[2]) & 0x003F) << 6) |
2079 (((gunichar
)pch
[3]) & 0x003F);
2081 } else if (*pch
<= 0xFB) {
2082 uc
= ((((gunichar
)pch
[0]) & 0x0003) << 24) |
2083 ((((gunichar
)pch
[1]) & 0x003F) << 18) |
2084 ((((gunichar
)pch
[2]) & 0x003F) << 12) |
2085 ((((gunichar
)pch
[3]) & 0x003F) << 6) |
2086 (((gunichar
)pch
[4]) & 0x003F);
2088 } else if (*pch
<= 0xFD) {
2089 uc
= ((((gunichar
)pch
[0]) & 0x0001) << 30) |
2090 ((((gunichar
)pch
[1]) & 0x003F) << 24) |
2091 ((((gunichar
)pch
[2]) & 0x003F) << 18) |
2092 ((((gunichar
)pch
[3]) & 0x003F) << 12) |
2093 ((((gunichar
)pch
[4]) & 0x003F) << 6) |
2094 (((gunichar
)pch
[5]) & 0x003F);
2097 /* should never happen ... bogus utf-8! */
2098 purple_debug_info("novell", "bogus utf-8 lead byte: 0x%X\n", pch
[0]);
2102 uni_str
= g_strdup_printf("\\u%d?", uc
);
2103 purple_debug_info("novell", "unicode escaped char %s\n", uni_str
);
2104 gstr
= g_string_append(gstr
, uni_str
);
2110 rtf
= g_strdup_printf(RTF_TEMPLATE
, gstr
->str
);
2111 g_string_free(gstr
, TRUE
);