14192
|
1 /*
|
|
2 * nmuser.c
|
|
3 *
|
|
4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
|
|
5 *
|
|
6 * This program is free software; you can redistribute it and/or modify
|
|
7 * it under the terms of the GNU General Public License as published by
|
|
8 * the Free Software Foundation; version 2 of the License.
|
|
9 *
|
|
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.
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License
|
|
16 * along with this program; if not, write to the Free Software
|
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 *
|
|
19 */
|
|
20
|
|
21 #include <glib.h>
|
|
22 #include <string.h>
|
|
23 #include "internal.h"
|
|
24 #include "nmfield.h"
|
|
25 #include "nmuser.h"
|
|
26 #include "nmconn.h"
|
|
27 #include "nmcontact.h"
|
|
28 #include "nmuserrecord.h"
|
|
29 #include "util.h"
|
|
30
|
|
31 /* This is the template that we wrap outgoing messages in, since the other
|
|
32 * GW Messenger clients expect messages to be in RTF.
|
|
33 */
|
|
34 #define RTF_TEMPLATE "{\\rtf1\\ansi\n"\
|
|
35 "{\\fonttbl{\\f0\\fnil Unknown;}}\n"\
|
|
36 "{\\colortbl ;\\red0\\green0\\blue0;}\n"\
|
|
37 "\\uc1\\cf1\\f0\\fs24 %s\\par\n}"
|
|
38 #define NM_MAX_MESSAGE_SIZE 2048
|
|
39
|
|
40 static NMERR_T nm_process_response(NMUser * user);
|
|
41 static void _update_contact_list(NMUser * user, NMField * fields);
|
|
42 static void _handle_multiple_get_details_login_cb(NMUser * user, NMERR_T ret_code,
|
|
43 gpointer resp_data, gpointer user_data);
|
|
44 static char * nm_rtfize_text(char *text);
|
|
45
|
|
46 /**
|
|
47 * See header for comments on on "public" functions
|
|
48 */
|
|
49
|
|
50 NMUser *
|
|
51 nm_initialize_user(const char *name, const char *server_addr,
|
|
52 int port, gpointer data, nm_event_cb event_callback)
|
|
53 {
|
|
54 NMUser *user;
|
|
55 if (name == NULL || server_addr == NULL || event_callback == NULL)
|
|
56 return NULL;
|
|
57
|
|
58 user = g_new0(NMUser, 1);
|
|
59
|
|
60
|
|
61
|
|
62 user->contacts =
|
|
63 g_hash_table_new_full(g_str_hash, nm_utf8_str_equal,
|
|
64 g_free, (GDestroyNotify) nm_release_contact);
|
|
65
|
|
66 user->user_records =
|
|
67 g_hash_table_new_full(g_str_hash, nm_utf8_str_equal, g_free,
|
|
68 (GDestroyNotify) nm_release_user_record);
|
|
69
|
|
70 user->display_id_to_dn = g_hash_table_new_full(g_str_hash, nm_utf8_str_equal,
|
|
71 g_free, g_free);
|
|
72
|
|
73 user->name = g_strdup(name);
|
|
74 user->conn = nm_create_conn(server_addr, port);
|
|
75 user->conn->addr = g_strdup(server_addr);
|
|
76 user->conn->port = port;
|
|
77 user->evt_callback = event_callback;
|
|
78 user->client_data = data;
|
|
79
|
|
80 return user;
|
|
81 }
|
|
82
|
|
83
|
|
84 void
|
|
85 nm_deinitialize_user(NMUser * user)
|
|
86 {
|
|
87 nm_release_conn(user->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
|
|
122 if (user == NULL || pwd == NULL || user_agent == NULL) {
|
|
123 return NMERR_BAD_PARM;
|
|
124 }
|
|
125
|
|
126 fields = nm_field_add_pointer(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
|
|
127 g_strdup(user->name), NMFIELD_TYPE_UTF8);
|
|
128
|
|
129 fields = nm_field_add_pointer(fields, NM_A_SZ_CREDENTIALS, 0, NMFIELD_METHOD_VALID, 0,
|
|
130 g_strdup(pwd), NMFIELD_TYPE_UTF8);
|
|
131
|
|
132 fields = nm_field_add_pointer(fields, NM_A_SZ_USER_AGENT, 0, NMFIELD_METHOD_VALID, 0,
|
|
133 g_strdup(user_agent), NMFIELD_TYPE_UTF8);
|
|
134
|
|
135 fields = nm_field_add_number(fields, NM_A_UD_BUILD, 0, NMFIELD_METHOD_VALID, 0,
|
|
136 NM_PROTOCOL_VERSION, NMFIELD_TYPE_UDWORD);
|
|
137 if (my_addr) {
|
|
138 fields = nm_field_add_pointer(fields, NM_A_IP_ADDRESS, 0, NMFIELD_METHOD_VALID, 0,
|
|
139 g_strdup(my_addr), NMFIELD_TYPE_UTF8);
|
|
140 }
|
|
141
|
|
142 /* Send the login */
|
|
143 rc = nm_send_request(user->conn, "login", fields, callback, data, NULL);
|
|
144
|
|
145 nm_free_fields(&fields);
|
|
146 return rc;
|
|
147 }
|
|
148
|
|
149 NMERR_T
|
|
150 nm_send_set_status(NMUser * user, int status, const char *text,
|
|
151 const char *auto_resp, nm_response_cb callback, gpointer data)
|
|
152 {
|
|
153 NMERR_T rc = NM_OK;
|
|
154 NMField *fields = NULL;
|
|
155
|
|
156 if (user == NULL)
|
|
157 return NMERR_BAD_PARM;
|
|
158
|
|
159 /* Add the status */
|
|
160 fields = nm_field_add_pointer(fields, NM_A_SZ_STATUS, 0, NMFIELD_METHOD_VALID, 0,
|
|
161 g_strdup_printf("%d", status), NMFIELD_TYPE_UTF8);
|
|
162
|
|
163 /* Add the status text and auto reply text if there is any */
|
|
164 if (text) {
|
|
165 fields = nm_field_add_pointer(fields, NM_A_SZ_STATUS_TEXT, 0,
|
|
166 NMFIELD_METHOD_VALID, 0, g_strdup(text),
|
|
167 NMFIELD_TYPE_UTF8);
|
|
168 }
|
|
169
|
|
170 if (auto_resp) {
|
|
171 fields = nm_field_add_pointer(fields, NM_A_SZ_MESSAGE_BODY, 0,
|
|
172 NMFIELD_METHOD_VALID, 0, g_strdup(auto_resp),
|
|
173 NMFIELD_TYPE_UTF8);
|
|
174 }
|
|
175
|
|
176 rc = nm_send_request(user->conn, "setstatus", fields, callback, data, NULL);
|
|
177
|
|
178 nm_free_fields(&fields);
|
|
179 return rc;
|
|
180 }
|
|
181
|
|
182 NMERR_T
|
|
183 nm_send_multiple_get_details(NMUser * user, GSList *names,
|
|
184 nm_response_cb callback, gpointer data)
|
|
185 {
|
|
186 NMERR_T rc = NM_OK;
|
|
187 NMField *fields = NULL;
|
|
188 GSList *node;
|
|
189
|
|
190 if (user == NULL || names == NULL)
|
|
191 return NMERR_BAD_PARM;
|
|
192
|
|
193 /* Add in DN or display id */
|
|
194 for (node = names; node; node = node->next) {
|
|
195 fields = nm_field_add_pointer(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
|
|
196 g_strdup(node->data), NMFIELD_TYPE_UTF8);
|
|
197 }
|
|
198
|
|
199 rc = nm_send_request(user->conn, "getdetails", fields, callback, data, NULL);
|
|
200
|
|
201 nm_free_fields(&fields);
|
|
202 return rc;
|
|
203 }
|
|
204
|
|
205 NMERR_T
|
|
206 nm_send_get_details(NMUser * user, const char *name,
|
|
207 nm_response_cb callback, gpointer data)
|
|
208 {
|
|
209 NMERR_T rc = NM_OK;
|
|
210 NMField *fields = NULL;
|
|
211
|
|
212 if (user == NULL || name == NULL)
|
|
213 return NMERR_BAD_PARM;
|
|
214
|
|
215 /* Add in DN or display id */
|
|
216 if (strstr("=", name)) {
|
|
217 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
218 g_strdup(name), NMFIELD_TYPE_DN);
|
|
219 } else {
|
|
220
|
|
221 const char *dn = nm_lookup_dn(user, name);
|
|
222 if (dn) {
|
|
223 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
224 g_strdup(name), NMFIELD_TYPE_DN);
|
|
225 } else {
|
|
226 fields =
|
|
227 nm_field_add_pointer(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
|
|
228 g_strdup(name), NMFIELD_TYPE_UTF8);
|
|
229 }
|
|
230
|
|
231 }
|
|
232
|
|
233 rc = nm_send_request(user->conn, "getdetails", fields, callback, data, NULL);
|
|
234
|
|
235 nm_free_fields(&fields);
|
|
236 return rc;
|
|
237 }
|
|
238
|
|
239 NMERR_T
|
|
240 nm_send_create_conference(NMUser * user, NMConference * conference,
|
|
241 nm_response_cb callback, gpointer data)
|
|
242 {
|
|
243 NMERR_T rc = NM_OK;
|
|
244 NMField *fields = NULL;
|
|
245 NMField *tmp = NULL;
|
|
246 NMField *field = NULL;
|
|
247 NMRequest *req = NULL;
|
|
248 int count, i;
|
|
249
|
|
250 if (user == NULL || conference == NULL)
|
|
251 return NMERR_BAD_PARM;
|
|
252
|
|
253 /* Add in a blank guid */
|
|
254 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
255 g_strdup(BLANK_GUID), NMFIELD_TYPE_UTF8);
|
|
256
|
|
257 fields = nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0,
|
|
258 NMFIELD_METHOD_VALID, 0, tmp,
|
|
259 NMFIELD_TYPE_ARRAY);
|
|
260 tmp = NULL;
|
|
261
|
|
262
|
|
263 /* Add participants in */
|
|
264 count = nm_conference_get_participant_count(conference);
|
|
265 for (i = 0; i < count; i++) {
|
|
266 NMUserRecord *user_record = nm_conference_get_participant(conference, i);
|
|
267
|
|
268 if (user_record) {
|
|
269 fields = nm_field_add_pointer(fields, NM_A_SZ_DN,
|
|
270 0, NMFIELD_METHOD_VALID, 0,
|
|
271 g_strdup(nm_user_record_get_dn(user_record)),
|
|
272 NMFIELD_TYPE_DN);
|
|
273 }
|
|
274 }
|
|
275
|
|
276 /* Add our user in */
|
|
277 field = nm_locate_field(NM_A_SZ_DN, user->fields);
|
|
278 if (field) {
|
|
279 fields = nm_field_add_pointer(fields, NM_A_SZ_DN,
|
|
280 0, NMFIELD_METHOD_VALID, 0,
|
|
281 g_strdup((char *) field->ptr_value),
|
|
282 NMFIELD_TYPE_DN);
|
|
283 }
|
|
284
|
|
285 rc = nm_send_request(user->conn, "createconf", fields, callback, data, &req);
|
|
286 if (rc == NM_OK && req) {
|
|
287 nm_conference_add_ref(conference);
|
|
288 nm_request_set_data(req, conference);
|
|
289 }
|
|
290
|
|
291 if (req)
|
|
292 nm_release_request(req);
|
|
293
|
|
294 nm_free_fields(&fields);
|
|
295 return rc;
|
|
296 }
|
|
297
|
|
298 NMERR_T
|
|
299 nm_send_leave_conference(NMUser * user, NMConference * conference,
|
|
300 nm_response_cb callback, gpointer data)
|
|
301 {
|
|
302 NMERR_T rc = NM_OK;
|
|
303 NMField *fields = NULL;
|
|
304 NMField *tmp = NULL;
|
|
305 NMRequest *req = NULL;
|
|
306
|
|
307 if (user == NULL || conference == NULL)
|
|
308 return NMERR_BAD_PARM;
|
|
309
|
|
310 /* Add in the conference guid */
|
|
311 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
312 g_strdup(nm_conference_get_guid(conference)),
|
|
313 NMFIELD_TYPE_UTF8);
|
|
314
|
|
315 fields = nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0,
|
|
316 NMFIELD_METHOD_VALID, 0, tmp,
|
|
317 NMFIELD_TYPE_ARRAY);
|
|
318 tmp = NULL;
|
|
319
|
|
320 /* Send the request to the server */
|
|
321 rc = nm_send_request(user->conn, "leaveconf", fields, callback, data, &req);
|
|
322 if (rc == NM_OK && req)
|
|
323 nm_request_set_data(req, conference);
|
|
324
|
|
325 if (req)
|
|
326 nm_release_request(req);
|
|
327
|
|
328 nm_free_fields(&fields);
|
|
329 return rc;
|
|
330 }
|
|
331
|
|
332 NMERR_T
|
|
333 nm_send_join_conference(NMUser * user, NMConference * conference,
|
|
334 nm_response_cb callback, gpointer data)
|
|
335 {
|
|
336 NMERR_T rc = NM_OK;
|
|
337 NMField *fields = NULL, *tmp = NULL;
|
|
338 NMRequest *req = NULL;
|
|
339
|
|
340 if (user == NULL || conference == NULL)
|
|
341 return NMERR_BAD_PARM;
|
|
342
|
|
343 /* Add in the conference guid */
|
|
344 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
345 g_strdup(nm_conference_get_guid(conference)),
|
|
346 NMFIELD_TYPE_UTF8);
|
|
347
|
|
348 fields = nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0,
|
|
349 NMFIELD_METHOD_VALID, 0, tmp,
|
|
350 NMFIELD_TYPE_ARRAY);
|
|
351 tmp = NULL;
|
|
352
|
|
353 /* Send the request to the server */
|
|
354 rc = nm_send_request(user->conn, "joinconf", fields, callback, data, &req);
|
|
355 if (rc == NM_OK && req)
|
|
356 nm_request_set_data(req, conference);
|
|
357
|
|
358 if (req)
|
|
359 nm_release_request(req);
|
|
360
|
|
361 nm_free_fields(&fields);
|
|
362 return rc;
|
|
363 }
|
|
364
|
|
365 NMERR_T
|
|
366 nm_send_reject_conference(NMUser * user, NMConference * conference,
|
|
367 nm_response_cb callback, gpointer data)
|
|
368 {
|
|
369 NMERR_T rc = NM_OK;
|
|
370 NMField *fields = NULL;
|
|
371 NMField *tmp = NULL;
|
|
372 NMRequest *req = NULL;
|
|
373
|
|
374 if (user == NULL || conference == NULL)
|
|
375 return NMERR_BAD_PARM;
|
|
376
|
|
377 /* Add in the conference guid */
|
|
378 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
379 g_strdup(nm_conference_get_guid(conference)),
|
|
380 NMFIELD_TYPE_UTF8);
|
|
381
|
|
382 fields = nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0,
|
|
383 NMFIELD_METHOD_VALID, 0, tmp,
|
|
384 NMFIELD_TYPE_ARRAY);
|
|
385 tmp = NULL;
|
|
386
|
|
387 /* Send the request to the server */
|
|
388 rc = nm_send_request(user->conn, "rejectconf", fields, callback, data, &req);
|
|
389 if (rc == NM_OK && req)
|
|
390 nm_request_set_data(req, conference);
|
|
391
|
|
392 if (req)
|
|
393 nm_release_request(req);
|
|
394
|
|
395 nm_free_fields(&fields);
|
|
396 return rc;
|
|
397 }
|
|
398
|
|
399 NMERR_T
|
|
400 nm_send_conference_invite(NMUser *user, NMConference *conference, NMUserRecord *user_record,
|
|
401 const char *message, nm_response_cb callback, gpointer data)
|
|
402 {
|
|
403 NMERR_T rc = NM_OK;
|
|
404 NMField *fields = NULL;
|
|
405 NMField *tmp = NULL;
|
|
406 NMRequest *req = NULL;
|
|
407
|
|
408 if (user == NULL || conference == NULL || user_record == NULL)
|
|
409 return NMERR_BAD_PARM;
|
|
410
|
|
411 /* Add in the conference guid */
|
|
412 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
413 g_strdup(nm_conference_get_guid(conference)),
|
|
414 NMFIELD_TYPE_UTF8);
|
|
415
|
|
416 fields = nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0,
|
|
417 NMFIELD_METHOD_VALID, 0, tmp,
|
|
418 NMFIELD_TYPE_ARRAY);
|
|
419 tmp = NULL;
|
|
420
|
|
421 /* Add in DN of user to invite */
|
|
422 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
423 g_strdup(nm_user_record_get_dn(user_record)),
|
|
424 NMFIELD_TYPE_DN);
|
|
425
|
|
426 /* Add the invite message if there is one */
|
|
427 if (message)
|
|
428 fields = nm_field_add_pointer(fields, NM_A_SZ_MESSAGE_BODY, 0, NMFIELD_METHOD_VALID, 0,
|
|
429 g_strdup(message), NMFIELD_TYPE_UTF8);
|
|
430
|
|
431 /* Send the request to the server */
|
|
432 rc = nm_send_request(user->conn, "sendinvite", fields, callback, data, &req);
|
|
433 if (rc == NM_OK && req)
|
|
434 nm_request_set_data(req, conference);
|
|
435
|
|
436 if (req)
|
|
437 nm_release_request(req);
|
|
438
|
|
439 nm_free_fields(&fields);
|
|
440 return rc;
|
|
441 }
|
|
442
|
|
443 NMERR_T
|
|
444 nm_send_message(NMUser * user, NMMessage * message, nm_response_cb callback)
|
|
445 {
|
|
446 NMERR_T rc = NM_OK;
|
|
447 char *text, *rtfized;
|
|
448 NMField *fields = NULL, *tmp = NULL;
|
|
449 NMConference *conf;
|
|
450 NMUserRecord *user_record;
|
|
451 int count, i;
|
|
452
|
|
453 if (user == NULL || message == NULL) {
|
|
454 return NMERR_BAD_PARM;
|
|
455 }
|
|
456
|
|
457 conf = nm_message_get_conference(message);
|
|
458 if (!nm_conference_is_instantiated(conf)) {
|
|
459 rc = NMERR_CONFERENCE_NOT_INSTANTIATED;
|
|
460 } else {
|
|
461
|
|
462 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
463 g_strdup(nm_conference_get_guid(conf)),
|
|
464 NMFIELD_TYPE_UTF8);
|
|
465
|
|
466 fields =
|
|
467 nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0, NMFIELD_METHOD_VALID, 0,
|
|
468 tmp, NMFIELD_TYPE_ARRAY);
|
|
469 tmp = NULL;
|
|
470
|
|
471 /* Add RTF and plain text versions of the message */
|
|
472 text = g_strdup(nm_message_get_text(message));
|
|
473
|
|
474 /* Truncate if necessary */
|
|
475 if (strlen(text) > NM_MAX_MESSAGE_SIZE)
|
|
476 text[NM_MAX_MESSAGE_SIZE] = 0;
|
|
477
|
|
478 rtfized = nm_rtfize_text(text);
|
|
479
|
|
480 gaim_debug_info("novell", "message text is: %s\n", text);
|
|
481 gaim_debug_info("novell", "message rtf is: %s\n", rtfized);
|
|
482
|
|
483 tmp = nm_field_add_pointer(tmp, NM_A_SZ_MESSAGE_BODY, 0, NMFIELD_METHOD_VALID, 0,
|
|
484 rtfized, NMFIELD_TYPE_UTF8);
|
|
485
|
|
486 tmp = nm_field_add_number(tmp, NM_A_UD_MESSAGE_TYPE, 0, NMFIELD_METHOD_VALID, 0,
|
|
487 0, NMFIELD_TYPE_UDWORD);
|
|
488
|
|
489 tmp = nm_field_add_pointer(tmp, NM_A_SZ_MESSAGE_TEXT, 0, NMFIELD_METHOD_VALID, 0,
|
|
490 text, NMFIELD_TYPE_UTF8);
|
|
491
|
|
492 fields = nm_field_add_pointer(fields, NM_A_FA_MESSAGE, 0, NMFIELD_METHOD_VALID, 0,
|
|
493 tmp, NMFIELD_TYPE_ARRAY);
|
|
494 tmp = NULL;
|
|
495
|
|
496 /* Add participants */
|
|
497 count = nm_conference_get_participant_count(conf);
|
|
498 for (i = 0; i < count; i++) {
|
|
499 user_record = nm_conference_get_participant(conf, i);
|
|
500 if (user_record) {
|
|
501 fields =
|
|
502 nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
503 g_strdup(nm_user_record_get_dn(user_record)),
|
|
504 NMFIELD_TYPE_DN);
|
|
505 }
|
|
506 }
|
|
507
|
|
508 /* Send the request */
|
|
509 rc = nm_send_request(user->conn, "sendmessage", fields, callback, NULL, NULL);
|
|
510 }
|
|
511
|
|
512 nm_free_fields(&fields);
|
|
513 return rc;
|
|
514 }
|
|
515
|
|
516 NMERR_T
|
|
517 nm_send_typing(NMUser * user, NMConference * conf,
|
|
518 gboolean typing, nm_response_cb callback)
|
|
519 {
|
|
520 NMERR_T rc = NM_OK;
|
|
521 char *str = NULL;
|
|
522 NMField *fields = NULL, *tmp = NULL;
|
|
523
|
|
524 if (user == NULL || conf == NULL) {
|
|
525 return NMERR_BAD_PARM;
|
|
526 }
|
|
527
|
|
528 if (!nm_conference_is_instantiated(conf)) {
|
|
529 rc = NMERR_CONFERENCE_NOT_INSTANTIATED;
|
|
530 } else {
|
|
531 /* Add the conference GUID */
|
|
532 tmp = nm_field_add_pointer(tmp, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
533 g_strdup(nm_conference_get_guid(conf)),
|
|
534 NMFIELD_TYPE_UTF8);
|
|
535
|
|
536 /* Add typing type */
|
|
537 str = g_strdup_printf("%d",
|
|
538 (typing ? NMEVT_USER_TYPING :
|
|
539 NMEVT_USER_NOT_TYPING));
|
|
540
|
|
541 tmp = nm_field_add_pointer(tmp, NM_A_SZ_TYPE, 0, NMFIELD_METHOD_VALID, 0,
|
|
542 str, NMFIELD_TYPE_UTF8);
|
|
543
|
|
544 fields =
|
|
545 nm_field_add_pointer(fields, NM_A_FA_CONVERSATION, 0, NMFIELD_METHOD_VALID, 0,
|
|
546 tmp, NMFIELD_TYPE_ARRAY);
|
|
547 tmp = NULL;
|
|
548
|
|
549 rc = nm_send_request(user->conn, "sendtyping", fields, callback, NULL, NULL);
|
|
550 }
|
|
551
|
|
552 nm_free_fields(&fields);
|
|
553 return rc;
|
|
554 }
|
|
555
|
|
556 NMERR_T
|
|
557 nm_send_create_contact(NMUser * user, NMFolder * folder,
|
|
558 NMContact * contact, nm_response_cb callback,
|
|
559 gpointer data)
|
|
560 {
|
|
561 NMERR_T rc = NM_OK;
|
|
562 NMField *fields = NULL;
|
|
563 NMRequest *req = NULL;
|
|
564 const char *name = NULL;
|
|
565 const char *display_name = NULL;
|
|
566
|
|
567 if (user == NULL || folder == NULL || contact == NULL) {
|
|
568 return NMERR_BAD_PARM;
|
|
569 }
|
|
570
|
|
571 /* Add parent ID */
|
|
572 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
573 g_strdup_printf("%d", nm_folder_get_id(folder)),
|
|
574 NMFIELD_TYPE_UTF8);
|
|
575
|
|
576 /* Check to see if userid is current user and return an error? */
|
|
577
|
|
578 /* Check to see if contact already exists and return an error? */
|
|
579
|
|
580 /* Add userid or dn */
|
|
581 name = nm_contact_get_dn(contact);
|
|
582 if (name == NULL)
|
|
583 return NMERR_BAD_PARM;
|
|
584
|
|
585 if (strstr("=", name)) {
|
|
586 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
587 g_strdup(name), NMFIELD_TYPE_DN);
|
|
588 } else {
|
|
589 fields = nm_field_add_pointer(fields, NM_A_SZ_USERID, 0, NMFIELD_METHOD_VALID, 0,
|
|
590 g_strdup(name), NMFIELD_TYPE_UTF8);
|
|
591 }
|
|
592
|
|
593 /* Add display name */
|
|
594 display_name = nm_contact_get_display_name(contact);
|
|
595 if (display_name)
|
|
596 fields = nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
|
|
597 g_strdup(display_name), NMFIELD_TYPE_UTF8);
|
|
598
|
|
599 /* Dispatch the request */
|
|
600 rc = nm_send_request(user->conn, "createcontact", fields, callback, data, &req);
|
|
601 if (rc == NM_OK && req)
|
|
602 nm_request_set_data(req, contact);
|
|
603
|
|
604 if (req)
|
|
605 nm_release_request(req);
|
|
606
|
|
607 nm_free_fields(&fields);
|
|
608 return rc;
|
|
609 }
|
|
610
|
|
611 NMERR_T
|
|
612 nm_send_remove_contact(NMUser * user, NMFolder * folder,
|
|
613 NMContact * contact, nm_response_cb callback,
|
|
614 gpointer data)
|
|
615 {
|
|
616 NMERR_T rc = NM_OK;
|
|
617 NMField *fields = NULL;
|
|
618 NMRequest *req = NULL;
|
|
619
|
|
620 if (user == NULL || folder == NULL || contact == NULL) {
|
|
621 return NMERR_BAD_PARM;
|
|
622 }
|
|
623
|
|
624 /* Add parent id */
|
|
625 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
626 g_strdup_printf("%d", nm_folder_get_id(folder)),
|
|
627 NMFIELD_TYPE_UTF8);
|
|
628
|
|
629 /* Add object id */
|
|
630 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
631 g_strdup_printf("%d", nm_contact_get_id(contact)),
|
|
632 NMFIELD_TYPE_UTF8);
|
|
633
|
|
634 /* Dispatch the request */
|
|
635 rc = nm_send_request(user->conn, "deletecontact", fields, callback, data, &req);
|
|
636 if (rc == NM_OK && req)
|
|
637 nm_request_set_data(req, contact);
|
|
638
|
|
639 if (req)
|
|
640 nm_release_request(req);
|
|
641
|
|
642 nm_free_fields(&fields);
|
|
643 return rc;
|
|
644 }
|
|
645
|
|
646 NMERR_T
|
|
647 nm_send_create_folder(NMUser * user, const char *name,
|
|
648 nm_response_cb callback, gpointer data)
|
|
649 {
|
|
650 NMERR_T rc = NM_OK;
|
|
651 NMField *fields = NULL;
|
|
652 NMRequest *req = NULL;
|
|
653
|
|
654 if (user == NULL || name == NULL) {
|
|
655 return NMERR_BAD_PARM;
|
|
656 }
|
|
657
|
|
658 /* Add parent ID */
|
|
659 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
660 g_strdup("0"), NMFIELD_TYPE_UTF8);
|
|
661
|
|
662 /* Add name of the folder to add */
|
|
663 fields =
|
|
664 nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
|
|
665 g_strdup(name), NMFIELD_TYPE_UTF8);
|
|
666
|
|
667 /* Add sequence, for now just put it at the bottom */
|
|
668 fields =
|
|
669 nm_field_add_pointer(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0,
|
|
670 g_strdup("-1"), NMFIELD_TYPE_UTF8);
|
|
671
|
|
672 /* Dispatch the request */
|
|
673 rc = nm_send_request(user->conn, "createfolder", fields, callback, data, &req);
|
|
674 if (rc == NM_OK && req)
|
|
675 nm_request_set_data(req, g_strdup(name));
|
|
676
|
|
677 if (req)
|
|
678 nm_release_request(req);
|
|
679
|
|
680 nm_free_fields(&fields);
|
|
681 return rc;
|
|
682 }
|
|
683
|
|
684 NMERR_T
|
|
685 nm_send_remove_folder(NMUser * user, NMFolder * folder,
|
|
686 nm_response_cb callback, gpointer data)
|
|
687 {
|
|
688 NMERR_T rc = NM_OK;
|
|
689 NMField *fields = NULL;
|
|
690 NMRequest *req = NULL;
|
|
691
|
|
692 if (user == NULL || folder == NULL) {
|
|
693 return NMERR_BAD_PARM;
|
|
694 }
|
|
695
|
|
696 /* Add the object id */
|
|
697 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
698 g_strdup_printf("%d", nm_folder_get_id(folder)),
|
|
699 NMFIELD_TYPE_UTF8);
|
|
700
|
|
701 /* Dispatch the request */
|
|
702 rc = nm_send_request(user->conn, "deletecontact", fields, callback, data, &req);
|
|
703 if (rc == NM_OK && req)
|
|
704 nm_request_set_data(req, folder);
|
|
705
|
|
706 if (req)
|
|
707 nm_release_request(req);
|
|
708
|
|
709 nm_free_fields(&fields);
|
|
710 return rc;
|
|
711 }
|
|
712
|
|
713 NMERR_T
|
|
714 nm_send_get_status(NMUser * user, NMUserRecord * user_record,
|
|
715 nm_response_cb callback, gpointer data)
|
|
716 {
|
|
717 NMERR_T rc = NM_OK;
|
|
718 NMField *fields = NULL;
|
|
719 NMRequest *req = NULL;
|
|
720 const char *dn;
|
|
721
|
|
722 if (user == NULL || user_record == NULL)
|
|
723 return NMERR_BAD_PARM;
|
|
724
|
|
725 /* Add DN to field list */
|
|
726 dn = nm_user_record_get_dn(user_record);
|
|
727 if (dn == NULL)
|
|
728 return (NMERR_T) -1;
|
|
729
|
|
730 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
|
|
731 g_strdup(dn), NMFIELD_TYPE_UTF8);
|
|
732
|
|
733 /* Dispatch the request */
|
|
734 rc = nm_send_request(user->conn, "getstatus", fields, callback, data, &req);
|
|
735 if (rc == NM_OK && req)
|
|
736 nm_request_set_data(req, user_record);
|
|
737
|
|
738 if (req)
|
|
739 nm_release_request(req);
|
|
740
|
|
741 nm_free_fields(&fields);
|
|
742 return rc;
|
|
743 }
|
|
744
|
|
745 NMERR_T
|
|
746 nm_send_rename_contact(NMUser * user, NMContact * contact,
|
|
747 const char *new_name, nm_response_cb callback,
|
|
748 gpointer data)
|
|
749 {
|
|
750 NMERR_T rc = NM_OK;
|
|
751 NMField *field = NULL, *fields = NULL, *list = NULL;
|
|
752 NMRequest *req = NULL;
|
|
753
|
|
754 if (user == NULL || contact == NULL || new_name == NULL)
|
|
755 return NMERR_BAD_PARM;
|
|
756
|
|
757 /* Create field list for current contact */
|
|
758 field = nm_contact_to_fields(contact);
|
|
759 if (field) {
|
|
760
|
|
761 fields =
|
|
762 nm_field_add_pointer(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_DELETE, 0,
|
|
763 field, NMFIELD_TYPE_ARRAY);
|
|
764 field = NULL;
|
|
765
|
|
766 /* Update the contacts display name locally */
|
|
767 nm_contact_set_display_name(contact, new_name);
|
|
768
|
|
769 /* Create field list for updated contact */
|
|
770 field = nm_contact_to_fields(contact);
|
|
771 if (field) {
|
|
772 fields =
|
|
773 nm_field_add_pointer(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_ADD, 0,
|
|
774 field, NMFIELD_TYPE_ARRAY);
|
|
775 field = NULL;
|
|
776
|
|
777 /* Package it up */
|
|
778 list =
|
|
779 nm_field_add_pointer(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID,
|
|
780 0, fields, NMFIELD_TYPE_ARRAY);
|
|
781 fields = NULL;
|
|
782
|
|
783 rc = nm_send_request(user->conn, "updateitem", list, callback, data, &req);
|
|
784 if (rc == NM_OK && req)
|
|
785 nm_request_set_data(req, contact);
|
|
786 }
|
|
787 }
|
|
788
|
|
789 if (req)
|
|
790 nm_release_request(req);
|
|
791
|
|
792 if (list)
|
|
793 nm_free_fields(&list);
|
|
794
|
|
795 return rc;
|
|
796 }
|
|
797
|
|
798 NMERR_T
|
|
799 nm_send_rename_folder(NMUser * user, NMFolder * folder, const char *new_name,
|
|
800 nm_response_cb callback, 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 || folder == NULL || new_name == NULL)
|
|
807 return NMERR_BAD_PARM;
|
|
808
|
|
809 /* Make sure folder does not already exist!? */
|
|
810 if (nm_find_folder(user, new_name))
|
|
811 return NMERR_FOLDER_EXISTS;
|
|
812
|
|
813 /* Create field list for current folder */
|
|
814 field = nm_folder_to_fields(folder);
|
|
815 if (field) {
|
|
816
|
|
817 fields = nm_field_add_pointer(fields, NM_A_FA_FOLDER, 0, NMFIELD_METHOD_DELETE, 0,
|
|
818 field, NMFIELD_TYPE_ARRAY);
|
|
819 field = NULL;
|
|
820
|
|
821 /* Update the folders display name locally */
|
|
822 nm_folder_set_name(folder, new_name);
|
|
823
|
|
824 /* Create field list for updated folder */
|
|
825 field = nm_folder_to_fields(folder);
|
|
826 if (field) {
|
|
827 fields = nm_field_add_pointer(fields, NM_A_FA_FOLDER, 0, NMFIELD_METHOD_ADD, 0,
|
|
828 field, NMFIELD_TYPE_ARRAY);
|
|
829 field = NULL;
|
|
830
|
|
831 /* Package it up */
|
|
832 list = nm_field_add_pointer(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID,
|
|
833 0, fields, NMFIELD_TYPE_ARRAY);
|
|
834 fields = NULL;
|
|
835
|
|
836 rc = nm_send_request(user->conn, "updateitem", list, callback, data, &req);
|
|
837 if (rc == NM_OK && req)
|
|
838 nm_request_set_data(req, folder);
|
|
839 }
|
|
840 }
|
|
841
|
|
842 if (req)
|
|
843 nm_release_request(req);
|
|
844
|
|
845 if (list)
|
|
846 nm_free_fields(&list);
|
|
847
|
|
848 return rc;
|
|
849 }
|
|
850
|
|
851 NMERR_T
|
|
852 nm_send_move_contact(NMUser * user, NMContact * contact, NMFolder * folder,
|
|
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 || contact == NULL || folder == NULL)
|
|
860 return NMERR_BAD_PARM;
|
|
861
|
|
862 /* Create field list for the contact */
|
|
863 field = nm_contact_to_fields(contact);
|
|
864 if (field) {
|
|
865
|
|
866 fields = nm_field_add_pointer(fields, NM_A_FA_CONTACT, 0, NMFIELD_METHOD_DELETE, 0,
|
|
867 field, NMFIELD_TYPE_ARRAY);
|
|
868 field = NULL;
|
|
869
|
|
870 /* Wrap the contact up and add it to the request field list */
|
|
871 list = nm_field_add_pointer(list, NM_A_FA_CONTACT_LIST, 0, NMFIELD_METHOD_VALID, 0,
|
|
872 fields, NMFIELD_TYPE_ARRAY);
|
|
873 fields = NULL;
|
|
874
|
|
875 /* Add sequence number */
|
|
876 list = nm_field_add_pointer(list, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID,
|
|
877 0, g_strdup("-1"), NMFIELD_TYPE_UTF8);
|
|
878
|
|
879 /* Add parent ID */
|
|
880 list = nm_field_add_pointer(list, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
|
|
881 g_strdup_printf("%d", nm_folder_get_id(folder)),
|
|
882 NMFIELD_TYPE_UTF8);
|
|
883
|
|
884 /* Dispatch the request */
|
|
885 rc = nm_send_request(user->conn, "movecontact", list, callback, data, &req);
|
|
886 if (rc == NM_OK && req)
|
|
887 nm_request_set_data(req, contact);
|
|
888
|
|
889 }
|
|
890
|
|
891 if (req)
|
|
892 nm_release_request(req);
|
|
893
|
|
894 if (list)
|
|
895 nm_free_fields(&list);
|
|
896
|
|
897 return rc;
|
|
898 }
|
|
899
|
|
900
|
|
901 NMERR_T
|
|
902 nm_send_create_privacy_item(NMUser *user, const char *who, gboolean allow_list,
|
|
903 nm_response_cb callback, gpointer data)
|
|
904 {
|
|
905 NMERR_T rc = NM_OK;
|
|
906 NMField *fields = NULL;
|
|
907 const char *tag;
|
|
908
|
|
909 if (user == NULL || who == NULL)
|
|
910 return NMERR_BAD_PARM;
|
|
911
|
|
912 if (allow_list)
|
|
913 tag = NM_A_SZ_BLOCKING_ALLOW_ITEM;
|
|
914 else
|
|
915 tag = NM_A_SZ_BLOCKING_DENY_ITEM;
|
|
916
|
|
917 fields = nm_field_add_pointer(fields, tag, 0, NMFIELD_METHOD_ADD, 0,
|
|
918 g_strdup(who), NMFIELD_TYPE_UTF8);
|
|
919
|
|
920 rc = nm_send_request(user->conn, "createblock", fields, callback, data, NULL);
|
|
921
|
|
922 nm_free_fields(&fields);
|
|
923 return rc;
|
|
924 }
|
|
925
|
|
926 NMERR_T
|
|
927 nm_send_remove_privacy_item(NMUser *user, const char *dn, gboolean allow_list,
|
|
928 nm_response_cb callback, gpointer data)
|
|
929 {
|
|
930 NMERR_T rc = NM_OK;
|
|
931 NMField *fields = NULL;
|
|
932 const char *tag;
|
|
933 GSList **list_ptr, *node;
|
|
934
|
|
935 if (user == NULL || dn == NULL)
|
|
936 return NMERR_BAD_PARM;
|
|
937
|
|
938 if (allow_list) {
|
|
939 tag = NM_A_BLOCKING_ALLOW_LIST;
|
|
940 list_ptr = &user->allow_list;
|
|
941 } else {
|
|
942 tag = NM_A_BLOCKING_DENY_LIST;
|
|
943 list_ptr = &user->deny_list;
|
|
944 }
|
|
945
|
|
946 /* Remove item from the cached list */
|
|
947 if ((node = g_slist_find_custom(*list_ptr, dn, (GCompareFunc)nm_utf8_strcasecmp))) {
|
|
948 *list_ptr = g_slist_remove_link(*list_ptr, node);
|
|
949 g_slist_free_1(node);
|
|
950 }
|
|
951
|
|
952 fields = nm_field_add_pointer(fields, tag, 0, NMFIELD_METHOD_DELETE, 0,
|
|
953 g_strdup(dn), NMFIELD_TYPE_DN);
|
|
954
|
|
955 rc = nm_send_request(user->conn, "updateblocks", fields, callback, data, NULL);
|
|
956
|
|
957 nm_free_fields(&fields);
|
|
958 return rc;
|
|
959
|
|
960 }
|
|
961
|
|
962 NMERR_T
|
|
963 nm_send_set_privacy_default(NMUser *user, gboolean default_deny,
|
|
964 nm_response_cb callback, gpointer data)
|
|
965 {
|
|
966 NMERR_T rc = NM_OK;
|
|
967 NMField *fields = NULL;
|
|
968
|
|
969 if (user == NULL)
|
|
970 return NMERR_BAD_PARM;
|
|
971
|
|
972 fields = nm_field_add_pointer(fields, NM_A_BLOCKING, 0, NMFIELD_METHOD_UPDATE, 0,
|
|
973 (default_deny ? g_strdup("1") : g_strdup("0")),
|
|
974 NMFIELD_TYPE_UTF8);
|
|
975
|
|
976 rc = nm_send_request(user->conn, "updateblocks", fields, callback, data, NULL);
|
|
977
|
|
978 nm_free_fields(&fields);
|
|
979 return rc;
|
|
980 }
|
|
981
|
|
982 NMERR_T
|
|
983 nm_send_keepalive(NMUser *user, nm_response_cb callback, gpointer data)
|
|
984 {
|
|
985 NMERR_T rc = NM_OK;
|
|
986
|
|
987 if (user == NULL)
|
|
988 return NMERR_BAD_PARM;
|
|
989
|
|
990 rc = nm_send_request(user->conn, "ping", NULL, callback, data, NULL);
|
|
991
|
|
992 return rc;
|
|
993 }
|
|
994
|
|
995 NMERR_T
|
|
996 nm_process_new_data(NMUser * user)
|
|
997 {
|
|
998 NMConn *conn;
|
|
999 NMERR_T rc = NM_OK;
|
|
1000 int ret;
|
|
1001 guint32 val;
|
|
1002
|
|
1003 if (user == NULL)
|
|
1004 return NMERR_BAD_PARM;
|
|
1005
|
|
1006 conn = user->conn;
|
|
1007
|
|
1008 /* Check to see if this is an event or a response */
|
|
1009 ret = nm_tcp_read(conn, (char *) &val, sizeof(val));
|
|
1010 if (ret == sizeof(val)) {
|
|
1011
|
|
1012 if (strncmp((char *) &val, "HTTP", strlen("HTTP")) == 0)
|
|
1013 rc = nm_process_response(user);
|
|
1014 else
|
|
1015 rc = nm_process_event(user, GUINT32_FROM_LE(val));
|
|
1016
|
|
1017 } else {
|
|
1018 rc = NMERR_PROTOCOL;
|
|
1019 }
|
|
1020
|
|
1021 return rc;
|
|
1022 }
|
|
1023
|
|
1024 NMConference *
|
|
1025 nm_find_conversation(NMUser * user, const char *who)
|
|
1026 {
|
|
1027 NMConference *conference = NULL;
|
|
1028 NMConference *tmp;
|
|
1029 GSList *cnode;
|
|
1030
|
|
1031 if (user && user->conferences) {
|
|
1032 for (cnode = user->conferences; cnode; cnode = cnode->next) {
|
|
1033 tmp = cnode->data;
|
|
1034 if (nm_conference_get_participant_count(tmp) == 1) {
|
|
1035 NMUserRecord *ur = nm_conference_get_participant(tmp, 0);
|
|
1036
|
|
1037 if (ur) {
|
|
1038 if (nm_utf8_str_equal(nm_user_record_get_dn(ur), who)) {
|
|
1039 conference = tmp;
|
|
1040 break;
|
|
1041 }
|
|
1042 }
|
|
1043 }
|
|
1044 }
|
|
1045 }
|
|
1046
|
|
1047 return conference;
|
|
1048 }
|
|
1049
|
|
1050 void
|
|
1051 nm_conference_list_add(NMUser * user, NMConference * conf)
|
|
1052 {
|
|
1053 if (user == NULL || conf == NULL)
|
|
1054 return;
|
|
1055
|
|
1056 nm_conference_add_ref(conf);
|
|
1057 user->conferences = g_slist_append(user->conferences, conf);
|
|
1058 }
|
|
1059
|
|
1060 void
|
|
1061 nm_conference_list_remove(NMUser * user, NMConference * conf)
|
|
1062 {
|
|
1063 if (user == NULL || conf == NULL)
|
|
1064 return;
|
|
1065
|
|
1066 if (g_slist_find(user->conferences, conf)) {
|
|
1067 user->conferences = g_slist_remove(user->conferences, conf);
|
|
1068 nm_release_conference(conf);
|
|
1069 }
|
|
1070 }
|
|
1071
|
|
1072 void
|
|
1073 nm_conference_list_free(NMUser * user)
|
|
1074 {
|
|
1075 GSList *cnode;
|
|
1076 NMConference *conference;
|
|
1077
|
|
1078 if (user == NULL)
|
|
1079 return;
|
|
1080
|
|
1081 if (user->conferences) {
|
|
1082 for (cnode = user->conferences; cnode; cnode = cnode->next) {
|
|
1083 conference = cnode->data;
|
|
1084 cnode->data = NULL;
|
|
1085 nm_release_conference(conference);
|
|
1086 }
|
|
1087
|
|
1088 g_slist_free(user->conferences);
|
|
1089 user->conferences = NULL;
|
|
1090 }
|
|
1091 }
|
|
1092
|
|
1093 NMConference *
|
|
1094 nm_conference_list_find(NMUser * user, const char *guid)
|
|
1095 {
|
|
1096 GSList *cnode;
|
|
1097 NMConference *conference = NULL, *tmp;
|
|
1098
|
|
1099 if (user == NULL || guid == NULL)
|
|
1100 return NULL;
|
|
1101
|
|
1102 if (user->conferences) {
|
|
1103 for (cnode = user->conferences; cnode; cnode = cnode->next) {
|
|
1104 tmp = cnode->data;
|
|
1105 if (nm_are_guids_equal(nm_conference_get_guid(tmp), guid)) {
|
|
1106 conference = tmp;
|
|
1107 break;
|
|
1108 }
|
|
1109 }
|
|
1110 }
|
|
1111
|
|
1112 return conference;
|
|
1113 }
|
|
1114
|
|
1115 gboolean
|
|
1116 nm_are_guids_equal(const char *guid1, const char *guid2)
|
|
1117 {
|
|
1118 if (guid1 == NULL || guid2 == NULL)
|
|
1119 return FALSE;
|
|
1120
|
|
1121 return (strncmp(guid1, guid2, CONF_GUID_END) == 0);
|
|
1122 }
|
|
1123
|
|
1124 void
|
|
1125 nm_user_add_contact(NMUser * user, NMContact * contact)
|
|
1126 {
|
|
1127 if (user == NULL || contact == NULL)
|
|
1128 return;
|
|
1129
|
|
1130 nm_contact_add_ref(contact);
|
|
1131
|
|
1132 g_hash_table_insert(user->contacts,
|
|
1133 g_utf8_strdown(nm_contact_get_dn(contact), -1), contact);
|
|
1134 }
|
|
1135
|
|
1136 void
|
|
1137 nm_user_add_user_record(NMUser * user, NMUserRecord * user_record)
|
|
1138 {
|
|
1139 nm_user_record_add_ref(user_record);
|
|
1140
|
|
1141 g_hash_table_insert(user->user_records,
|
|
1142 g_utf8_strdown(nm_user_record_get_dn(user_record), -1),
|
|
1143 user_record);
|
|
1144
|
|
1145 g_hash_table_insert(user->display_id_to_dn,
|
|
1146 g_utf8_strdown(nm_user_record_get_display_id(user_record),
|
|
1147 -1),
|
|
1148 g_utf8_strdown(nm_user_record_get_dn(user_record), -1));
|
|
1149
|
|
1150 }
|
|
1151
|
|
1152 nm_event_cb
|
|
1153 nm_user_get_event_callback(NMUser * user)
|
|
1154 {
|
|
1155 if (user == NULL)
|
|
1156 return NULL;
|
|
1157
|
|
1158 return user->evt_callback;
|
|
1159 }
|
|
1160
|
|
1161 NMConn *
|
|
1162 nm_user_get_conn(NMUser * user)
|
|
1163 {
|
|
1164 if (user == NULL)
|
|
1165 return NULL;
|
|
1166
|
|
1167 return user->conn;
|
|
1168 }
|
|
1169
|
|
1170 NMERR_T
|
|
1171 nm_create_contact_list(NMUser * user)
|
|
1172 {
|
|
1173 NMERR_T rc = NM_OK;
|
|
1174 NMField *locate = NULL;
|
|
1175
|
|
1176 if (user == NULL || user->fields == NULL) {
|
|
1177 return NMERR_BAD_PARM;
|
|
1178 }
|
|
1179
|
|
1180 /* Create the root folder */
|
|
1181 user->root_folder = nm_create_folder("");
|
|
1182
|
|
1183 /* Find the contact list in the login fields */
|
|
1184 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, user->fields);
|
|
1185 if (locate != NULL) {
|
|
1186
|
|
1187 /* Add the folders and then the contacts */
|
|
1188 nm_folder_add_contacts_and_folders(user, user->root_folder,
|
|
1189 (NMField *) (locate->ptr_value));
|
|
1190
|
|
1191 }
|
|
1192
|
|
1193 return rc;
|
|
1194 }
|
|
1195
|
|
1196 gboolean nm_user_is_privacy_locked(NMUser *user)
|
|
1197 {
|
|
1198 if (user) {
|
|
1199 return user->privacy_locked;
|
|
1200 }
|
|
1201
|
|
1202 return FALSE;
|
|
1203 }
|
|
1204
|
|
1205 static gboolean
|
|
1206 _create_privacy_list(NMUser * user, NMRequest *request)
|
|
1207 {
|
|
1208 NMField *locate = NULL;
|
|
1209 GSList *need_details = NULL;
|
|
1210
|
|
1211 /* Are the privacy settings locked */
|
|
1212 locate = nm_locate_field(NM_A_LOCKED_ATTR_LIST, user->fields);
|
|
1213 if (locate && locate->ptr_value) {
|
|
1214 if (locate->type == NMFIELD_TYPE_UTF8 &&
|
|
1215 (nm_utf8_strcasecmp(locate->ptr_value, NM_A_BLOCKING) == 0)) {
|
|
1216 user->privacy_locked = TRUE;
|
|
1217 } else if (locate->type == NMFIELD_TYPE_MV ||
|
|
1218 locate->type == NMFIELD_TYPE_ARRAY) {
|
|
1219 NMField *tmp = (NMField *)locate->ptr_value;
|
|
1220 while (tmp && tmp->tag) {
|
|
1221 if (nm_utf8_strcasecmp(tmp->ptr_value, NM_A_BLOCKING) == 0) {
|
|
1222 user->privacy_locked = TRUE;
|
|
1223 break;
|
|
1224 }
|
|
1225 tmp++;
|
|
1226 }
|
|
1227 }
|
|
1228 }
|
|
1229
|
|
1230 /* Set default deny flag */
|
|
1231 locate = nm_locate_field(NM_A_BLOCKING, user->fields);
|
|
1232 if (locate && locate->ptr_value) {
|
|
1233 user->default_deny = atoi((char *)locate->ptr_value);
|
|
1234 }
|
|
1235
|
|
1236 /* Read internal blocking allow list */
|
|
1237 locate = nm_locate_field(NM_A_BLOCKING_ALLOW_LIST, user->fields);
|
|
1238 if (locate && locate->ptr_value) {
|
|
1239
|
|
1240 if (locate->type == NMFIELD_TYPE_MV) {
|
|
1241 locate = (NMField *)locate->ptr_value;
|
|
1242 for (; locate->tag != NULL; locate++) {
|
|
1243 if (locate->ptr_value) {
|
|
1244
|
|
1245 user->allow_list = g_slist_append(user->allow_list, (char *)locate->ptr_value);
|
|
1246
|
|
1247 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL)
|
|
1248 need_details = g_slist_append(need_details, (char *)locate->ptr_value);
|
|
1249
|
|
1250 }
|
|
1251 }
|
|
1252 } else {
|
|
1253
|
|
1254 user->allow_list = g_slist_append(user->allow_list, (char *)locate->ptr_value);
|
|
1255
|
|
1256 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL)
|
|
1257 need_details = g_slist_append(need_details, (char *)locate->ptr_value);
|
|
1258
|
|
1259 }
|
|
1260 }
|
|
1261
|
|
1262 /* Read internal blocking deny list */
|
|
1263 locate = nm_locate_field(NM_A_BLOCKING_DENY_LIST, user->fields);
|
|
1264 if (locate && locate->ptr_value) {
|
|
1265
|
|
1266 if (locate->type == NMFIELD_TYPE_MV) {
|
|
1267 locate = (NMField *)locate->ptr_value;
|
|
1268 for (; locate->tag != NULL; locate++) {
|
|
1269 if (locate->ptr_value) {
|
|
1270
|
|
1271 user->deny_list = g_slist_append(user->deny_list, (char *)locate->ptr_value);
|
|
1272
|
|
1273 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL)
|
|
1274 need_details = g_slist_append(need_details, (char *)locate->ptr_value);
|
|
1275
|
|
1276 }
|
|
1277 }
|
|
1278 } else {
|
|
1279
|
|
1280 user->deny_list = g_slist_append(user->deny_list, (char *)locate->ptr_value);
|
|
1281
|
|
1282 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL)
|
|
1283 need_details = g_slist_append(need_details, (char *)locate->ptr_value);
|
|
1284
|
|
1285 }
|
|
1286 }
|
|
1287
|
|
1288 if (need_details) {
|
|
1289
|
|
1290 nm_request_add_ref(request);
|
|
1291 nm_send_multiple_get_details(user, need_details,
|
|
1292 _handle_multiple_get_details_login_cb, request);
|
|
1293
|
|
1294 return FALSE;
|
|
1295 }
|
|
1296
|
|
1297 return TRUE;
|
|
1298 }
|
|
1299
|
|
1300 void
|
|
1301 nm_destroy_contact_list(NMUser * user)
|
|
1302 {
|
|
1303 if (user == NULL)
|
|
1304 return;
|
|
1305
|
|
1306 if (user->root_folder) {
|
|
1307 nm_release_folder(user->root_folder);
|
|
1308 user->root_folder = NULL;
|
|
1309 }
|
|
1310 }
|
|
1311
|
|
1312 NMFolder *
|
|
1313 nm_get_root_folder(NMUser * user)
|
|
1314 {
|
|
1315 if (user == NULL)
|
|
1316 return NULL;
|
|
1317
|
|
1318 if (user->root_folder == NULL)
|
|
1319 nm_create_contact_list(user);
|
|
1320
|
|
1321 return user->root_folder;
|
|
1322 }
|
|
1323
|
|
1324 NMContact *
|
|
1325 nm_find_contact(NMUser * user, const char *name)
|
|
1326 {
|
|
1327 char *str;
|
|
1328 const char *dn = NULL;
|
|
1329 NMContact *contact = NULL;
|
|
1330
|
|
1331 if (user == NULL || name == NULL)
|
|
1332 return NULL;
|
|
1333
|
|
1334 str = g_utf8_strdown(name, -1);
|
|
1335 if (strstr(str, "=")) {
|
|
1336 dn = str;
|
|
1337 } else {
|
|
1338 /* Assume that we have a display id instead of a dn */
|
|
1339 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str);
|
|
1340 }
|
|
1341
|
|
1342 /* Find contact object in reference table */
|
|
1343 if (dn) {
|
|
1344 contact = (NMContact *) g_hash_table_lookup(user->contacts, dn);
|
|
1345 }
|
|
1346
|
|
1347 g_free(str);
|
|
1348 return contact;
|
|
1349 }
|
|
1350
|
|
1351 GList *
|
|
1352 nm_find_contacts(NMUser * user, const char *dn)
|
|
1353 {
|
|
1354 guint32 i, cnt;
|
|
1355 NMFolder *folder;
|
|
1356 NMContact *contact;
|
|
1357 GList *contacts = NULL;
|
|
1358
|
|
1359 if (user == NULL || dn == NULL)
|
|
1360 return NULL;
|
|
1361
|
|
1362 /* Check for contact at the root */
|
|
1363 contact = nm_folder_find_contact(user->root_folder, dn);
|
|
1364 if (contact) {
|
|
1365 contacts = g_list_append(contacts, contact);
|
|
1366 contact = NULL;
|
|
1367 }
|
|
1368
|
|
1369 /* Check for contact in each subfolder */
|
|
1370 cnt = nm_folder_get_subfolder_count(user->root_folder);
|
|
1371 for (i = 0; i < cnt; i++) {
|
|
1372 folder = nm_folder_get_subfolder(user->root_folder, i);
|
|
1373 contact = nm_folder_find_contact(folder, dn);
|
|
1374 if (contact) {
|
|
1375 contacts = g_list_append(contacts, contact);
|
|
1376 contact = NULL;
|
|
1377 }
|
|
1378 }
|
|
1379
|
|
1380 return contacts;
|
|
1381 }
|
|
1382
|
|
1383 NMUserRecord *
|
|
1384 nm_find_user_record(NMUser * user, const char *name)
|
|
1385 {
|
|
1386 char *str = NULL;
|
|
1387 const char *dn = NULL;
|
|
1388 NMUserRecord *user_record = NULL;
|
|
1389
|
|
1390 if (user == NULL || name == NULL)
|
|
1391 return NULL;
|
|
1392
|
|
1393 str = g_utf8_strdown(name, -1);
|
|
1394 if (strstr(str, "=")) {
|
|
1395 dn = str;
|
|
1396 } else {
|
|
1397 /* Assume that we have a display id instead of a dn */
|
|
1398 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str);
|
|
1399 }
|
|
1400
|
|
1401 /* Find user record in reference table */
|
|
1402 if (dn) {
|
|
1403 user_record =
|
|
1404 (NMUserRecord *) g_hash_table_lookup(user->user_records, dn);
|
|
1405 }
|
|
1406
|
|
1407 g_free(str);
|
|
1408 return user_record;
|
|
1409 }
|
|
1410
|
|
1411 const char *
|
|
1412 nm_lookup_dn(NMUser * user, const char *display_id)
|
|
1413 {
|
|
1414 const char *dn;
|
|
1415 char *lower;
|
|
1416
|
|
1417 if (user == NULL || display_id == NULL)
|
|
1418 return NULL;
|
|
1419
|
|
1420 lower = g_utf8_strdown(display_id, -1);
|
|
1421 dn = g_hash_table_lookup(user->display_id_to_dn, lower);
|
|
1422 g_free(lower);
|
|
1423
|
|
1424 return dn;
|
|
1425 }
|
|
1426
|
|
1427 NMFolder *
|
|
1428 nm_find_folder(NMUser * user, const char *name)
|
|
1429 {
|
|
1430 NMFolder *folder = NULL, *temp;
|
|
1431 int i, num_folders;
|
|
1432 const char *tname = NULL;
|
|
1433
|
|
1434 if (user == NULL || name == NULL)
|
|
1435 return NULL;
|
|
1436
|
|
1437 if (*name == '\0')
|
|
1438 return user->root_folder;
|
|
1439
|
|
1440 num_folders = nm_folder_get_subfolder_count(user->root_folder);
|
|
1441 for (i = 0; i < num_folders; i++) {
|
|
1442 temp = nm_folder_get_subfolder(user->root_folder, i);
|
|
1443 tname = nm_folder_get_name(temp);
|
|
1444 if (tname && (strcmp(tname, name) == 0)) {
|
|
1445 folder = temp;
|
|
1446 break;
|
|
1447 }
|
|
1448 }
|
|
1449
|
|
1450 return folder;
|
|
1451 }
|
|
1452
|
|
1453 NMFolder *
|
|
1454 nm_find_folder_by_id(NMUser * user, int object_id)
|
|
1455 {
|
|
1456 NMFolder *folder = NULL, *temp;
|
|
1457 int i, num_folders;
|
|
1458
|
|
1459 if (user == NULL)
|
|
1460 return NULL;
|
|
1461
|
|
1462 if (object_id == 0)
|
|
1463 return user->root_folder;
|
|
1464
|
|
1465 num_folders = nm_folder_get_subfolder_count(user->root_folder);
|
|
1466 for (i = 0; i < num_folders; i++) {
|
|
1467 temp = nm_folder_get_subfolder(user->root_folder, i);
|
|
1468 if (nm_folder_get_id(temp) == object_id) {
|
|
1469 folder = temp;
|
|
1470 break;
|
|
1471 }
|
|
1472 }
|
|
1473
|
|
1474 return folder;
|
|
1475 }
|
|
1476
|
|
1477 static void
|
|
1478 _handle_multiple_get_details_login_cb(NMUser * user, NMERR_T ret_code,
|
|
1479 gpointer resp_data, gpointer user_data)
|
|
1480 {
|
|
1481 nm_response_cb cb;
|
|
1482 NMRequest *request = user_data;
|
|
1483
|
|
1484 if (user == NULL || request == NULL)
|
|
1485 return;
|
|
1486
|
|
1487 if ((cb = nm_request_get_callback(request))) {
|
|
1488 cb(user, ret_code, nm_request_get_data(request),
|
|
1489 nm_request_get_user_define(request));
|
|
1490 nm_release_request(request);
|
|
1491 }
|
|
1492 }
|
|
1493
|
|
1494 static void
|
|
1495 _handle_multiple_get_details_joinconf_cb(NMUser * user, NMERR_T ret_code,
|
|
1496 gpointer resp_data, gpointer user_data)
|
|
1497 {
|
|
1498 NMRequest *request = user_data;
|
|
1499 NMUserRecord *user_record = resp_data;
|
|
1500 NMConference *conference;
|
|
1501 GSList *list, *node;
|
|
1502
|
|
1503 if (user == NULL || resp_data == NULL || user_data == NULL)
|
|
1504 return;
|
|
1505
|
|
1506 conference = nm_request_get_data(request);
|
|
1507 list = nm_request_get_user_define(request);
|
|
1508
|
|
1509 if (ret_code == 0 && conference && list) {
|
|
1510
|
|
1511 /* Add the user to the conference */
|
|
1512 nm_conference_add_participant(conference, user_record);
|
|
1513
|
|
1514 /* Find the user in the list and remove it */
|
|
1515 for (node = list; node; node = node->next) {
|
|
1516 if (nm_utf8_str_equal(nm_user_record_get_dn(user_record),
|
|
1517 (const char *) node->data)) {
|
|
1518 list = g_slist_remove(list, node->data);
|
|
1519 nm_request_set_user_define(request, list);
|
|
1520 g_free(node->data);
|
|
1521 break;
|
|
1522 }
|
|
1523 }
|
|
1524
|
|
1525 /* Time to callback? */
|
|
1526 if (g_slist_length(list) == 0) {
|
|
1527 nm_response_cb cb = nm_request_get_callback(request);
|
|
1528
|
|
1529 if (cb) {
|
|
1530 cb(user, 0, conference, conference);
|
|
1531 }
|
|
1532 g_slist_free(list);
|
|
1533 nm_release_request(request);
|
|
1534 }
|
|
1535 }
|
|
1536 }
|
|
1537
|
|
1538 static NMERR_T
|
|
1539 nm_call_handler(NMUser * user, NMRequest * request, NMField * fields)
|
|
1540 {
|
|
1541 NMERR_T rc = NM_OK, ret_code = NM_OK;
|
|
1542 NMConference *conf = NULL;
|
|
1543 NMUserRecord *user_record = NULL;
|
|
1544 NMField *locate = NULL;
|
|
1545 NMField *field = NULL;
|
|
1546 const char *cmd;
|
|
1547 nm_response_cb cb;
|
|
1548 gboolean done = TRUE;
|
|
1549
|
|
1550 if (user == NULL || request == NULL || fields == NULL)
|
|
1551 return NMERR_BAD_PARM;
|
|
1552
|
|
1553 /* Get the return code */
|
|
1554 field = nm_locate_field(NM_A_SZ_RESULT_CODE, fields);
|
|
1555 if (field) {
|
|
1556 ret_code = atoi((char *) field->ptr_value);
|
|
1557 } else {
|
|
1558 ret_code = NMERR_PROTOCOL;
|
|
1559 }
|
|
1560
|
|
1561 cmd = nm_request_get_cmd(request);
|
|
1562 if (ret_code == NM_OK && cmd != NULL) {
|
|
1563
|
|
1564 if (strcmp("login", cmd) == 0) {
|
|
1565
|
|
1566 user->user_record = nm_create_user_record_from_fields(fields);
|
|
1567
|
|
1568 /* Save the users fields */
|
|
1569 user->fields = nm_copy_field_array(fields);
|
|
1570
|
|
1571 nm_create_contact_list(user);
|
|
1572 done = _create_privacy_list(user, request);
|
|
1573
|
|
1574 } else if (strcmp("setstatus", cmd) == 0) {
|
|
1575
|
|
1576 /* Nothing to do */
|
|
1577
|
|
1578 } else if (strcmp("createconf", cmd) == 0) {
|
|
1579
|
|
1580 conf = (NMConference *) nm_request_get_data(request);
|
|
1581
|
|
1582 /* get the convo guid */
|
|
1583 locate = nm_locate_field(NM_A_FA_CONVERSATION, fields);
|
|
1584 if (locate) {
|
|
1585 field =
|
|
1586 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value);
|
|
1587 if (field) {
|
|
1588 nm_conference_set_guid(conf, (char *) field->ptr_value);
|
|
1589 }
|
|
1590 }
|
|
1591
|
|
1592 nm_conference_list_add(user, conf);
|
|
1593 nm_release_conference(conf);
|
|
1594
|
|
1595 } else if (strcmp("leaveconf", cmd) == 0) {
|
|
1596
|
|
1597 conf = (NMConference *) nm_request_get_data(request);
|
|
1598 nm_conference_list_remove(user, conf);
|
|
1599
|
|
1600 } else if (strcmp("joinconf", cmd) == 0) {
|
|
1601 GSList *list = NULL, *node;
|
|
1602
|
|
1603 conf = nm_request_get_data(request);
|
|
1604
|
|
1605 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, fields);
|
|
1606 if (locate && locate->ptr_value != 0) {
|
|
1607
|
|
1608 field = (NMField *) locate->ptr_value;
|
|
1609 while ((field = nm_locate_field(NM_A_SZ_DN, field))) {
|
|
1610 if (field && field->ptr_value != 0) {
|
|
1611
|
|
1612 if (nm_utf8_str_equal
|
|
1613 (nm_user_record_get_dn(user->user_record),
|
|
1614 (const char *) field->ptr_value)) {
|
|
1615 field++;
|
|
1616 continue;
|
|
1617 }
|
|
1618
|
|
1619 user_record =
|
|
1620 nm_find_user_record(user,
|
|
1621 (const char *) field->ptr_value);
|
|
1622 if (user_record == NULL) {
|
|
1623 list =
|
|
1624 g_slist_append(list,
|
|
1625 g_strdup((char *) field->ptr_value));
|
|
1626 } else {
|
|
1627 nm_conference_add_participant(conf, user_record);
|
|
1628 }
|
|
1629 }
|
|
1630 field++;
|
|
1631 }
|
|
1632
|
|
1633 if (list != NULL) {
|
|
1634
|
|
1635 done = FALSE;
|
|
1636 nm_request_set_user_define(request, list);
|
|
1637 nm_request_add_ref(request);
|
|
1638 for (node = list; node; node = node->next) {
|
|
1639
|
|
1640 nm_send_get_details(user, (const char *) node->data,
|
|
1641 _handle_multiple_get_details_joinconf_cb,
|
|
1642 request);
|
|
1643 }
|
|
1644 }
|
|
1645 }
|
|
1646
|
|
1647 } else if (strcmp("getdetails", cmd) == 0) {
|
|
1648
|
|
1649 locate = nm_locate_field(NM_A_FA_RESULTS, fields);
|
|
1650 while (locate && locate->ptr_value != 0) {
|
|
1651
|
|
1652 user_record = nm_create_user_record_from_fields(locate);
|
|
1653 if (user_record) {
|
|
1654 NMUserRecord *tmp;
|
|
1655
|
|
1656 tmp =
|
|
1657 nm_find_user_record(user,
|
|
1658 nm_user_record_get_dn(user_record));
|
|
1659 if (tmp) {
|
|
1660
|
|
1661 /* Update the existing user record */
|
|
1662 nm_user_record_copy(tmp, user_record);
|
|
1663 nm_release_user_record(user_record);
|
|
1664 user_record = tmp;
|
|
1665
|
|
1666 } else {
|
|
1667 nm_user_add_user_record(user, user_record);
|
|
1668 nm_release_user_record(user_record);
|
|
1669 }
|
|
1670
|
|
1671 /* Response data is new user record */
|
|
1672 nm_request_set_data(request, (gpointer) user_record);
|
|
1673 }
|
|
1674
|
|
1675 locate = nm_locate_field(NM_A_FA_RESULTS, locate+1);
|
|
1676 }
|
|
1677
|
|
1678 } else if (strcmp("createfolder", cmd) == 0) {
|
|
1679
|
|
1680 _update_contact_list(user, fields);
|
|
1681
|
|
1682 } else if (strcmp("createcontact", cmd) == 0) {
|
|
1683
|
|
1684 _update_contact_list(user, fields);
|
|
1685
|
|
1686 locate =
|
|
1687 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value);
|
|
1688 if (locate) {
|
|
1689
|
|
1690 NMContact *new_contact =
|
|
1691 nm_folder_find_item_by_object_id(user->root_folder,
|
|
1692 atoi((char *)locate->ptr_value));
|
|
1693
|
|
1694 if (new_contact) {
|
|
1695
|
|
1696 /* Add the contact to our cache */
|
|
1697 nm_user_add_contact(user, new_contact);
|
|
1698
|
|
1699 /* Set the contact as the response data */
|
|
1700 nm_request_set_data(request, (gpointer) new_contact);
|
|
1701
|
|
1702 }
|
|
1703
|
|
1704 }
|
|
1705
|
|
1706 } else if (strcmp("deletecontact", cmd) == 0) {
|
|
1707
|
|
1708 _update_contact_list(user, fields);
|
|
1709
|
|
1710 } else if (strcmp("movecontact", cmd) == 0) {
|
|
1711
|
|
1712 _update_contact_list(user, fields);
|
|
1713
|
|
1714 } else if (strcmp("getstatus", cmd) == 0) {
|
|
1715
|
|
1716 locate = nm_locate_field(NM_A_SZ_STATUS, fields);
|
|
1717 if (locate) {
|
|
1718 nm_user_record_set_status((NMUserRecord *)
|
|
1719 nm_request_get_data(request),
|
|
1720 atoi((char *) locate->ptr_value), NULL);
|
|
1721 }
|
|
1722
|
|
1723 } else if (strcmp("updateitem", cmd) == 0) {
|
|
1724
|
|
1725 /* Nothing extra to do here */
|
|
1726
|
|
1727 } else if (strcmp("createblock", cmd) == 0) {
|
|
1728 if ((locate = nm_locate_field(NM_A_BLOCKING_DENY_LIST, fields))) {
|
|
1729 if (locate->ptr_value) {
|
|
1730 user->deny_list = g_slist_append(user->deny_list, g_strdup((char *)locate->ptr_value));
|
|
1731 }
|
|
1732 } else if ((locate = nm_locate_field(NM_A_BLOCKING_ALLOW_LIST, fields))) {
|
|
1733 if (locate->ptr_value) {
|
|
1734 user->allow_list = g_slist_append(user->allow_list, g_strdup((char *)locate->ptr_value));
|
|
1735 }
|
|
1736 }
|
|
1737 } else if (strcmp("updateblocks", cmd) == 0) {
|
|
1738 /* nothing to do here */
|
|
1739 } else {
|
|
1740
|
|
1741 /* Nothing to do, just print debug message */
|
|
1742 gaim_debug(GAIM_DEBUG_INFO, "novell",
|
|
1743 "nm_call_handler(): Unknown request command, %s\n", cmd);
|
|
1744
|
|
1745 }
|
|
1746 }
|
|
1747
|
|
1748 if (done && (cb = nm_request_get_callback(request))) {
|
|
1749
|
|
1750 cb(user, ret_code, nm_request_get_data(request),
|
|
1751 nm_request_get_user_define(request));
|
|
1752 }
|
|
1753
|
|
1754 return rc;
|
|
1755 }
|
|
1756
|
|
1757 static NMERR_T
|
|
1758 nm_process_response(NMUser * user)
|
|
1759 {
|
|
1760 NMERR_T rc = NM_OK;
|
|
1761 NMField *fields = NULL;
|
|
1762 NMField *field = NULL;
|
|
1763 NMConn *conn = user->conn;
|
|
1764 NMRequest *req = NULL;
|
|
1765
|
|
1766 rc = nm_read_header(conn);
|
|
1767 if (rc == NM_OK) {
|
|
1768 rc = nm_read_fields(conn, -1, &fields);
|
|
1769 }
|
|
1770
|
|
1771 if (rc == NM_OK) {
|
|
1772 field = nm_locate_field(NM_A_SZ_TRANSACTION_ID, fields);
|
|
1773 if (field != NULL && field->ptr_value != 0) {
|
|
1774 req = nm_conn_find_request(conn, atoi((char *) field->ptr_value));
|
|
1775 if (req != NULL) {
|
|
1776 rc = nm_call_handler(user, req, fields);
|
|
1777 nm_conn_remove_request_item(conn, req);
|
|
1778 }
|
|
1779
|
|
1780 }
|
|
1781 }
|
|
1782
|
|
1783 if (fields)
|
|
1784 nm_free_fields(&fields);
|
|
1785
|
|
1786 return rc;
|
|
1787 }
|
|
1788
|
|
1789 /*
|
|
1790 * Some utility functions...haven't figured out where
|
|
1791 * they belong yet.
|
|
1792 */
|
|
1793 gint
|
|
1794 nm_utf8_strcasecmp(gconstpointer str1, gconstpointer str2)
|
|
1795 {
|
|
1796 gint rv;
|
|
1797 char *str1_down = g_utf8_strdown(str1, -1);
|
|
1798 char *str2_down = g_utf8_strdown(str2, -1);
|
|
1799
|
|
1800 rv = g_utf8_collate(str1_down, str2_down);
|
|
1801
|
|
1802 g_free(str1_down);
|
|
1803 g_free(str2_down);
|
|
1804
|
|
1805 return rv;
|
|
1806 }
|
|
1807
|
|
1808 gboolean
|
|
1809 nm_utf8_str_equal(gconstpointer str1, gconstpointer str2)
|
|
1810 {
|
|
1811 return (nm_utf8_strcasecmp(str1, str2) == 0);
|
|
1812 }
|
|
1813
|
|
1814 char *
|
|
1815 nm_typed_to_dotted(const char *typed)
|
|
1816 {
|
|
1817 unsigned i = 0, j = 0;
|
|
1818 char *dotted;
|
|
1819
|
|
1820 if (typed == NULL)
|
|
1821 return NULL;
|
|
1822
|
|
1823 dotted = g_new0(char, strlen(typed));
|
|
1824
|
|
1825 do {
|
|
1826
|
|
1827 /* replace comma with a dot */
|
|
1828 if (j != 0) {
|
|
1829 dotted[j] = '.';
|
|
1830 j++;
|
|
1831 }
|
|
1832
|
|
1833 /* skip the type */
|
|
1834 while (typed[i] != '\0' && typed[i] != '=')
|
|
1835 i++;
|
|
1836
|
|
1837 /* verify that we aren't running off the end */
|
|
1838 if (typed[i] == '\0') {
|
|
1839 dotted[j] = '\0';
|
|
1840 break;
|
|
1841 }
|
|
1842
|
|
1843 i++;
|
|
1844
|
|
1845 /* copy the object name to context */
|
|
1846 while (typed[i] != '\0' && typed[i] != ',') {
|
|
1847 dotted[j] = typed[i];
|
|
1848 j++;
|
|
1849 i++;
|
|
1850 }
|
|
1851
|
|
1852 } while (typed[i] != '\0');
|
|
1853
|
|
1854 return dotted;
|
|
1855 }
|
|
1856
|
|
1857 const char *
|
|
1858 nm_error_to_string(NMERR_T err)
|
|
1859 {
|
|
1860 static char *unknown_msg = NULL;
|
|
1861
|
|
1862 g_free(unknown_msg);
|
|
1863 unknown_msg = NULL;
|
|
1864
|
|
1865 switch (err) {
|
|
1866
|
|
1867 case NMERR_BAD_PARM:
|
|
1868 return _("Required parameters not passed in");
|
|
1869
|
|
1870 case NMERR_TCP_WRITE:
|
|
1871 return _("Unable to write to network");
|
|
1872
|
|
1873 case NMERR_TCP_READ:
|
|
1874 return _("Unable to read from network");
|
|
1875
|
|
1876 case NMERR_PROTOCOL:
|
|
1877 return _("Error communicating with server");
|
|
1878
|
|
1879 case NMERR_CONFERENCE_NOT_FOUND:
|
|
1880 case NMERR_CONFERENCE_NOT_FOUND_2:
|
|
1881 return _("Conference not found");
|
|
1882
|
|
1883 case NMERR_CONFERENCE_NOT_INSTANTIATED:
|
|
1884 return _("Conference does not exist");
|
|
1885
|
|
1886 case NMERR_DUPLICATE_FOLDER:
|
|
1887 case NMERR_FOLDER_EXISTS:
|
|
1888 return _("A folder with that name already exists");
|
|
1889
|
|
1890 case NMERR_NOT_SUPPORTED:
|
|
1891 return _("Not supported");
|
|
1892
|
|
1893 case NMERR_PASSWORD_EXPIRED:
|
|
1894 case NMERR_PASSWORD_EXPIRED_2:
|
|
1895 return _("Password has expired");
|
|
1896
|
|
1897 case NMERR_PASSWORD_INVALID:
|
|
1898 return _("Invalid password");
|
|
1899
|
|
1900 case NMERR_USER_NOT_FOUND:
|
|
1901 return _("User not found");
|
|
1902
|
|
1903 case NMERR_USER_DISABLED:
|
|
1904 return _("Account has been disabled");
|
|
1905
|
|
1906 case NMERR_DIRECTORY_FAILURE:
|
|
1907 return _("The server could not access the directory");
|
|
1908
|
|
1909 case NMERR_ADMIN_LOCKED:
|
|
1910 return _("Your system administrator has disabled this operation");
|
|
1911
|
|
1912 case NMERR_SERVER_BUSY:
|
|
1913 return _("The server is unavailable; try again later");
|
|
1914
|
|
1915 case NMERR_DUPLICATE_CONTACT:
|
|
1916 return _("Cannot add a contact to the same folder twice");
|
|
1917
|
|
1918 case NMERR_USER_NOT_ALLOWED:
|
|
1919 return _("Cannot add yourself");
|
|
1920
|
|
1921 case NMERR_MASTER_ARCHIVE_MISSING:
|
|
1922 return _("Master archive is misconfigured");
|
|
1923
|
|
1924 case NMERR_AUTHENTICATION_FAILED:
|
|
1925 case NMERR_CREDENTIALS_MISSING:
|
|
1926 return _("Invalid username or password");
|
|
1927
|
|
1928 case NMERR_HOST_NOT_FOUND:
|
|
1929 return _("Could not recognize the host of the username you entered");
|
|
1930
|
|
1931 case NMERR_ACCESS_DENIED:
|
|
1932 return _("Your account has been disabled because too many invalid passwords were entered");
|
|
1933
|
|
1934 case NMERR_DUPLICATE_PARTICIPANT:
|
|
1935 return _("You cannot add the same person twice to a conversation");
|
|
1936
|
|
1937 case NMERR_TOO_MANY_CONTACTS:
|
|
1938 case NMERR_TOO_MANY_FOLDERS:
|
|
1939 return _("You have reached your limit for the number of contacts allowed");
|
|
1940
|
|
1941 case NMERR_OBJECT_NOT_FOUND:
|
|
1942 return _("You have entered an invalid username");
|
|
1943
|
|
1944 case NMERR_DIRECTORY_UPDATE:
|
|
1945 return _("An error occurred while updating the directory");
|
|
1946
|
|
1947 case NMERR_SERVER_PROTOCOL:
|
|
1948 return _("Incompatible protocol version");
|
|
1949
|
|
1950 case NMERR_USER_BLOCKED:
|
|
1951 return _("The user has blocked you");
|
|
1952
|
|
1953 case NMERR_EVAL_CONNECTION_LIMIT:
|
|
1954 return _("This evaluation version does not allow more than ten users to log in at one time");
|
|
1955
|
|
1956 case NMERR_CONVERSATION_INVITE:
|
|
1957 return _("The user is either offline or you are blocked");
|
|
1958
|
|
1959 default:
|
|
1960 unknown_msg = g_strdup_printf (_("Unknown error: 0x%X"), err);
|
|
1961
|
|
1962 return unknown_msg;
|
|
1963 }
|
|
1964 }
|
|
1965
|
|
1966 static void
|
|
1967 _update_contact_list(NMUser * user, NMField * fields)
|
|
1968 {
|
|
1969 NMField *list, *cursor, *locate;
|
|
1970 gint objid1;
|
|
1971 NMContact *contact;
|
|
1972 NMFolder *folder;
|
|
1973 gpointer item;
|
|
1974
|
|
1975 if (user == NULL || fields == NULL)
|
|
1976 return;
|
|
1977
|
|
1978 /* Is it wrapped in a RESULTS array? */
|
|
1979 if (strcmp(fields->tag, NM_A_FA_RESULTS) == 0) {
|
|
1980 list = (NMField *) fields->ptr_value;
|
|
1981 } else {
|
|
1982 list = fields;
|
|
1983 }
|
|
1984
|
|
1985 /* Update the cached contact list */
|
|
1986 cursor = (NMField *) list->ptr_value;
|
|
1987 while (cursor->tag != NULL) {
|
|
1988 if ((g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) ||
|
|
1989 (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) == 0)) {
|
|
1990
|
|
1991 locate =
|
|
1992 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) cursor->ptr_value);
|
|
1993 if (locate != NULL && locate->ptr_value != 0) {
|
|
1994 objid1 = atoi((char *) locate->ptr_value);
|
|
1995 item =
|
|
1996 nm_folder_find_item_by_object_id(user->root_folder, objid1);
|
|
1997 if (item != NULL) {
|
|
1998 if (cursor->method == NMFIELD_METHOD_ADD) {
|
|
1999 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
|
|
2000 contact = (NMContact *) item;
|
|
2001 nm_contact_update_list_properties(contact, cursor);
|
|
2002 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
|
|
2003 == 0) {
|
|
2004 folder = (NMFolder *) item;
|
|
2005 nm_folder_update_list_properties(folder, cursor);
|
|
2006 }
|
|
2007 } else if (cursor->method == NMFIELD_METHOD_DELETE) {
|
|
2008 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
|
|
2009 contact = (NMContact *) item;
|
|
2010 folder =
|
|
2011 nm_find_folder_by_id(user,
|
|
2012 nm_contact_get_parent_id
|
|
2013 (contact));
|
|
2014 if (folder) {
|
|
2015 nm_folder_remove_contact(folder, contact);
|
|
2016 }
|
|
2017 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
|
|
2018 == 0) {
|
|
2019 /* TODO: write nm_folder_remove_folder */
|
|
2020 /* ignoring for now, should not be a big deal */
|
|
2021 /* folder = (NMFolder *) item;*/
|
|
2022 /* nm_folder_remove_folder(user->root_folder, folder);*/
|
|
2023 }
|
|
2024 }
|
|
2025 } else {
|
|
2026
|
|
2027 if (cursor->method == NMFIELD_METHOD_ADD) {
|
|
2028
|
|
2029 /* Not found, so we need to add it */
|
|
2030 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) {
|
|
2031
|
|
2032 const char *dn = NULL;
|
|
2033
|
|
2034 locate =
|
|
2035 nm_locate_field(NM_A_SZ_DN,
|
|
2036 (NMField *) cursor->ptr_value);
|
|
2037 if (locate != NULL && locate->ptr_value != 0) {
|
|
2038 dn = (const char *) locate->ptr_value;
|
|
2039 if (dn != NULL) {
|
|
2040 contact =
|
|
2041 nm_create_contact_from_fields(cursor);
|
|
2042 if (contact) {
|
|
2043 nm_folder_add_contact_to_list(user->
|
|
2044 root_folder,
|
|
2045 contact);
|
|
2046 nm_release_contact(contact);
|
|
2047 }
|
|
2048 }
|
|
2049 }
|
|
2050 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER)
|
|
2051 == 0) {
|
|
2052 folder = nm_create_folder_from_fields(cursor);
|
|
2053 nm_folder_add_folder_to_list(user->root_folder,
|
|
2054 folder);
|
|
2055 nm_release_folder(folder);
|
|
2056 }
|
|
2057 }
|
|
2058 }
|
|
2059 }
|
|
2060 }
|
|
2061 cursor++;
|
|
2062 }
|
|
2063 }
|
|
2064
|
|
2065 static char *
|
|
2066 nm_rtfize_text(char *text)
|
|
2067 {
|
|
2068 GString *gstr = NULL;
|
|
2069 unsigned char *pch;
|
|
2070 char *uni_str = NULL, *rtf = NULL;
|
|
2071 int bytes;
|
|
2072 gunichar uc;
|
|
2073
|
|
2074 gstr = g_string_sized_new(strlen(text)*2);
|
|
2075 pch = (unsigned char *)text;
|
|
2076 while (*pch) {
|
|
2077 if ((*pch) <= 0x7F) {
|
|
2078 switch (*pch) {
|
|
2079 case '{':
|
|
2080 case '}':
|
|
2081 case '\\':
|
|
2082 gstr = g_string_append_c(gstr, '\\');
|
|
2083 gstr = g_string_append_c(gstr, *pch);
|
|
2084 break;
|
|
2085 case '\n':
|
|
2086 gstr = g_string_append(gstr, "\\par ");
|
|
2087 break;
|
|
2088 default:
|
|
2089 gstr = g_string_append_c(gstr, *pch);
|
|
2090 break;
|
|
2091 }
|
|
2092 pch++;
|
|
2093 } else {
|
|
2094 /* convert the utf-8 character to ucs-4 for rtf encoding */
|
|
2095 if(*pch <= 0xDF) {
|
|
2096 uc = ((((gunichar)pch[0]) & 0x001F) << 6) |
|
|
2097 (((gunichar)pch[1]) & 0x003F);
|
|
2098 bytes = 2;
|
|
2099 } else if(*pch <= 0xEF) {
|
|
2100 uc = ((((gunichar)pch[0]) & 0x000F) << 12) |
|
|
2101 ((((gunichar)pch[1]) & 0x003F) << 6) |
|
|
2102 (((gunichar)pch[2]) & 0x003F);
|
|
2103 bytes = 3;
|
|
2104 } else if (*pch <= 0xF7) {
|
|
2105 uc = ((((gunichar)pch[0]) & 0x0007) << 18) |
|
|
2106 ((((gunichar)pch[1]) & 0x003F) << 12) |
|
|
2107 ((((gunichar)pch[2]) & 0x003F) << 6) |
|
|
2108 (((gunichar)pch[3]) & 0x003F);
|
|
2109 bytes = 4;
|
|
2110 } else if (*pch <= 0xFB) {
|
|
2111 uc = ((((gunichar)pch[0]) & 0x0003) << 24) |
|
|
2112 ((((gunichar)pch[1]) & 0x003F) << 18) |
|
|
2113 ((((gunichar)pch[2]) & 0x003F) << 12) |
|
|
2114 ((((gunichar)pch[3]) & 0x003F) << 6) |
|
|
2115 (((gunichar)pch[4]) & 0x003F);
|
|
2116 bytes = 5;
|
|
2117 } else if (*pch <= 0xFD) {
|
|
2118 uc = ((((gunichar)pch[0]) & 0x0001) << 30) |
|
|
2119 ((((gunichar)pch[1]) & 0x003F) << 24) |
|
|
2120 ((((gunichar)pch[2]) & 0x003F) << 18) |
|
|
2121 ((((gunichar)pch[3]) & 0x003F) << 12) |
|
|
2122 ((((gunichar)pch[4]) & 0x003F) << 6) |
|
|
2123 (((gunichar)pch[5]) & 0x003F);
|
|
2124 bytes = 6;
|
|
2125 } else {
|
|
2126 /* should never happen ... bogus utf-8! */
|
|
2127 gaim_debug_info("novell", "bogus utf-8 lead byte: 0x%X\n", pch[0]);
|
|
2128 uc = 0x003F;
|
|
2129 bytes = 1;
|
|
2130 }
|
|
2131 uni_str = g_strdup_printf("\\u%d?", uc);
|
|
2132 gaim_debug_info("novell", "unicode escaped char %s\n", uni_str);
|
|
2133 gstr = g_string_append(gstr, uni_str);
|
|
2134 pch += bytes;
|
|
2135 g_free(uni_str);
|
|
2136 }
|
|
2137 }
|
|
2138
|
|
2139 rtf = g_strdup_printf(RTF_TEMPLATE, gstr->str);
|
|
2140 g_string_free(gstr, TRUE);
|
|
2141 return rtf;
|
|
2142 }
|