Mercurial > pidgin.yaz
annotate libgaim/protocols/novell/nmuser.c @ 14594:78f121689460
[gaim-migrate @ 17319]
Rest of SF Patch #1559532 from Mike Stoddard
Fixes SF Bug 1520965
Fixes SF Bug 1544012
"This is patch to fix connection problems in the Novell
protocol plugin. It should fix bugs 1520965 and 1544012."
"The two bugs are both connection problems. Unfortunately the
plugin is designed to be a little too synchronous so
non-blocking i/o causes problems for it. The fix is to retry
a little longer in nm_read_all and to not disconnect if
errno is EAGAIN after processing an incoming response or
event. When I get more time I will work on making the plugin
more asynchronous so that we don't have to block in
nm_read_all. For now however this patch will get people
working again. Any suggestions/comments are welcome."
I consulted with Daniel on this one, and I'm committing it as a temporary fix, since Mike says he's going to fix it for real later.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 19 Sep 2006 01:01:20 +0000 |
parents | 60b1bc8dbf37 |
children | 897d2d09787e |
rev | line source |
---|---|
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 guint32 val; | |
1001 | |
1002 if (user == NULL) | |
1003 return NMERR_BAD_PARM; | |
1004 | |
1005 conn = user->conn; | |
1006 | |
1007 /* Check to see if this is an event or a response */ | |
14594
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1008 rc = nm_read_all(conn, (char *) &val, sizeof(val)); |
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1009 if (rc == NM_OK) { |
14192 | 1010 if (strncmp((char *) &val, "HTTP", strlen("HTTP")) == 0) |
1011 rc = nm_process_response(user); | |
1012 else | |
1013 rc = nm_process_event(user, GUINT32_FROM_LE(val)); | |
1014 | |
1015 } else { | |
14594
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1016 if (errno == EAGAIN) |
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1017 rc = NM_OK; |
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1018 else |
78f121689460
[gaim-migrate @ 17319]
Richard Laager <rlaager@wiktel.com>
parents:
14192
diff
changeset
|
1019 rc = NMERR_PROTOCOL; |
14192 | 1020 } |
1021 | |
1022 return rc; | |
1023 } | |
1024 | |
1025 NMConference * | |
1026 nm_find_conversation(NMUser * user, const char *who) | |
1027 { | |
1028 NMConference *conference = NULL; | |
1029 NMConference *tmp; | |
1030 GSList *cnode; | |
1031 | |
1032 if (user && user->conferences) { | |
1033 for (cnode = user->conferences; cnode; cnode = cnode->next) { | |
1034 tmp = cnode->data; | |
1035 if (nm_conference_get_participant_count(tmp) == 1) { | |
1036 NMUserRecord *ur = nm_conference_get_participant(tmp, 0); | |
1037 | |
1038 if (ur) { | |
1039 if (nm_utf8_str_equal(nm_user_record_get_dn(ur), who)) { | |
1040 conference = tmp; | |
1041 break; | |
1042 } | |
1043 } | |
1044 } | |
1045 } | |
1046 } | |
1047 | |
1048 return conference; | |
1049 } | |
1050 | |
1051 void | |
1052 nm_conference_list_add(NMUser * user, NMConference * conf) | |
1053 { | |
1054 if (user == NULL || conf == NULL) | |
1055 return; | |
1056 | |
1057 nm_conference_add_ref(conf); | |
1058 user->conferences = g_slist_append(user->conferences, conf); | |
1059 } | |
1060 | |
1061 void | |
1062 nm_conference_list_remove(NMUser * user, NMConference * conf) | |
1063 { | |
1064 if (user == NULL || conf == NULL) | |
1065 return; | |
1066 | |
1067 if (g_slist_find(user->conferences, conf)) { | |
1068 user->conferences = g_slist_remove(user->conferences, conf); | |
1069 nm_release_conference(conf); | |
1070 } | |
1071 } | |
1072 | |
1073 void | |
1074 nm_conference_list_free(NMUser * user) | |
1075 { | |
1076 GSList *cnode; | |
1077 NMConference *conference; | |
1078 | |
1079 if (user == NULL) | |
1080 return; | |
1081 | |
1082 if (user->conferences) { | |
1083 for (cnode = user->conferences; cnode; cnode = cnode->next) { | |
1084 conference = cnode->data; | |
1085 cnode->data = NULL; | |
1086 nm_release_conference(conference); | |
1087 } | |
1088 | |
1089 g_slist_free(user->conferences); | |
1090 user->conferences = NULL; | |
1091 } | |
1092 } | |
1093 | |
1094 NMConference * | |
1095 nm_conference_list_find(NMUser * user, const char *guid) | |
1096 { | |
1097 GSList *cnode; | |
1098 NMConference *conference = NULL, *tmp; | |
1099 | |
1100 if (user == NULL || guid == NULL) | |
1101 return NULL; | |
1102 | |
1103 if (user->conferences) { | |
1104 for (cnode = user->conferences; cnode; cnode = cnode->next) { | |
1105 tmp = cnode->data; | |
1106 if (nm_are_guids_equal(nm_conference_get_guid(tmp), guid)) { | |
1107 conference = tmp; | |
1108 break; | |
1109 } | |
1110 } | |
1111 } | |
1112 | |
1113 return conference; | |
1114 } | |
1115 | |
1116 gboolean | |
1117 nm_are_guids_equal(const char *guid1, const char *guid2) | |
1118 { | |
1119 if (guid1 == NULL || guid2 == NULL) | |
1120 return FALSE; | |
1121 | |
1122 return (strncmp(guid1, guid2, CONF_GUID_END) == 0); | |
1123 } | |
1124 | |
1125 void | |
1126 nm_user_add_contact(NMUser * user, NMContact * contact) | |
1127 { | |
1128 if (user == NULL || contact == NULL) | |
1129 return; | |
1130 | |
1131 nm_contact_add_ref(contact); | |
1132 | |
1133 g_hash_table_insert(user->contacts, | |
1134 g_utf8_strdown(nm_contact_get_dn(contact), -1), contact); | |
1135 } | |
1136 | |
1137 void | |
1138 nm_user_add_user_record(NMUser * user, NMUserRecord * user_record) | |
1139 { | |
1140 nm_user_record_add_ref(user_record); | |
1141 | |
1142 g_hash_table_insert(user->user_records, | |
1143 g_utf8_strdown(nm_user_record_get_dn(user_record), -1), | |
1144 user_record); | |
1145 | |
1146 g_hash_table_insert(user->display_id_to_dn, | |
1147 g_utf8_strdown(nm_user_record_get_display_id(user_record), | |
1148 -1), | |
1149 g_utf8_strdown(nm_user_record_get_dn(user_record), -1)); | |
1150 | |
1151 } | |
1152 | |
1153 nm_event_cb | |
1154 nm_user_get_event_callback(NMUser * user) | |
1155 { | |
1156 if (user == NULL) | |
1157 return NULL; | |
1158 | |
1159 return user->evt_callback; | |
1160 } | |
1161 | |
1162 NMConn * | |
1163 nm_user_get_conn(NMUser * user) | |
1164 { | |
1165 if (user == NULL) | |
1166 return NULL; | |
1167 | |
1168 return user->conn; | |
1169 } | |
1170 | |
1171 NMERR_T | |
1172 nm_create_contact_list(NMUser * user) | |
1173 { | |
1174 NMERR_T rc = NM_OK; | |
1175 NMField *locate = NULL; | |
1176 | |
1177 if (user == NULL || user->fields == NULL) { | |
1178 return NMERR_BAD_PARM; | |
1179 } | |
1180 | |
1181 /* Create the root folder */ | |
1182 user->root_folder = nm_create_folder(""); | |
1183 | |
1184 /* Find the contact list in the login fields */ | |
1185 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, user->fields); | |
1186 if (locate != NULL) { | |
1187 | |
1188 /* Add the folders and then the contacts */ | |
1189 nm_folder_add_contacts_and_folders(user, user->root_folder, | |
1190 (NMField *) (locate->ptr_value)); | |
1191 | |
1192 } | |
1193 | |
1194 return rc; | |
1195 } | |
1196 | |
1197 gboolean nm_user_is_privacy_locked(NMUser *user) | |
1198 { | |
1199 if (user) { | |
1200 return user->privacy_locked; | |
1201 } | |
1202 | |
1203 return FALSE; | |
1204 } | |
1205 | |
1206 static gboolean | |
1207 _create_privacy_list(NMUser * user, NMRequest *request) | |
1208 { | |
1209 NMField *locate = NULL; | |
1210 GSList *need_details = NULL; | |
1211 | |
1212 /* Are the privacy settings locked */ | |
1213 locate = nm_locate_field(NM_A_LOCKED_ATTR_LIST, user->fields); | |
1214 if (locate && locate->ptr_value) { | |
1215 if (locate->type == NMFIELD_TYPE_UTF8 && | |
1216 (nm_utf8_strcasecmp(locate->ptr_value, NM_A_BLOCKING) == 0)) { | |
1217 user->privacy_locked = TRUE; | |
1218 } else if (locate->type == NMFIELD_TYPE_MV || | |
1219 locate->type == NMFIELD_TYPE_ARRAY) { | |
1220 NMField *tmp = (NMField *)locate->ptr_value; | |
1221 while (tmp && tmp->tag) { | |
1222 if (nm_utf8_strcasecmp(tmp->ptr_value, NM_A_BLOCKING) == 0) { | |
1223 user->privacy_locked = TRUE; | |
1224 break; | |
1225 } | |
1226 tmp++; | |
1227 } | |
1228 } | |
1229 } | |
1230 | |
1231 /* Set default deny flag */ | |
1232 locate = nm_locate_field(NM_A_BLOCKING, user->fields); | |
1233 if (locate && locate->ptr_value) { | |
1234 user->default_deny = atoi((char *)locate->ptr_value); | |
1235 } | |
1236 | |
1237 /* Read internal blocking allow list */ | |
1238 locate = nm_locate_field(NM_A_BLOCKING_ALLOW_LIST, user->fields); | |
1239 if (locate && locate->ptr_value) { | |
1240 | |
1241 if (locate->type == NMFIELD_TYPE_MV) { | |
1242 locate = (NMField *)locate->ptr_value; | |
1243 for (; locate->tag != NULL; locate++) { | |
1244 if (locate->ptr_value) { | |
1245 | |
1246 user->allow_list = g_slist_append(user->allow_list, (char *)locate->ptr_value); | |
1247 | |
1248 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL) | |
1249 need_details = g_slist_append(need_details, (char *)locate->ptr_value); | |
1250 | |
1251 } | |
1252 } | |
1253 } else { | |
1254 | |
1255 user->allow_list = g_slist_append(user->allow_list, (char *)locate->ptr_value); | |
1256 | |
1257 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL) | |
1258 need_details = g_slist_append(need_details, (char *)locate->ptr_value); | |
1259 | |
1260 } | |
1261 } | |
1262 | |
1263 /* Read internal blocking deny list */ | |
1264 locate = nm_locate_field(NM_A_BLOCKING_DENY_LIST, user->fields); | |
1265 if (locate && locate->ptr_value) { | |
1266 | |
1267 if (locate->type == NMFIELD_TYPE_MV) { | |
1268 locate = (NMField *)locate->ptr_value; | |
1269 for (; locate->tag != NULL; locate++) { | |
1270 if (locate->ptr_value) { | |
1271 | |
1272 user->deny_list = g_slist_append(user->deny_list, (char *)locate->ptr_value); | |
1273 | |
1274 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL) | |
1275 need_details = g_slist_append(need_details, (char *)locate->ptr_value); | |
1276 | |
1277 } | |
1278 } | |
1279 } else { | |
1280 | |
1281 user->deny_list = g_slist_append(user->deny_list, (char *)locate->ptr_value); | |
1282 | |
1283 if (nm_find_user_record(user, (char *)locate->ptr_value) == NULL) | |
1284 need_details = g_slist_append(need_details, (char *)locate->ptr_value); | |
1285 | |
1286 } | |
1287 } | |
1288 | |
1289 if (need_details) { | |
1290 | |
1291 nm_request_add_ref(request); | |
1292 nm_send_multiple_get_details(user, need_details, | |
1293 _handle_multiple_get_details_login_cb, request); | |
1294 | |
1295 return FALSE; | |
1296 } | |
1297 | |
1298 return TRUE; | |
1299 } | |
1300 | |
1301 void | |
1302 nm_destroy_contact_list(NMUser * user) | |
1303 { | |
1304 if (user == NULL) | |
1305 return; | |
1306 | |
1307 if (user->root_folder) { | |
1308 nm_release_folder(user->root_folder); | |
1309 user->root_folder = NULL; | |
1310 } | |
1311 } | |
1312 | |
1313 NMFolder * | |
1314 nm_get_root_folder(NMUser * user) | |
1315 { | |
1316 if (user == NULL) | |
1317 return NULL; | |
1318 | |
1319 if (user->root_folder == NULL) | |
1320 nm_create_contact_list(user); | |
1321 | |
1322 return user->root_folder; | |
1323 } | |
1324 | |
1325 NMContact * | |
1326 nm_find_contact(NMUser * user, const char *name) | |
1327 { | |
1328 char *str; | |
1329 const char *dn = NULL; | |
1330 NMContact *contact = NULL; | |
1331 | |
1332 if (user == NULL || name == NULL) | |
1333 return NULL; | |
1334 | |
1335 str = g_utf8_strdown(name, -1); | |
1336 if (strstr(str, "=")) { | |
1337 dn = str; | |
1338 } else { | |
1339 /* Assume that we have a display id instead of a dn */ | |
1340 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str); | |
1341 } | |
1342 | |
1343 /* Find contact object in reference table */ | |
1344 if (dn) { | |
1345 contact = (NMContact *) g_hash_table_lookup(user->contacts, dn); | |
1346 } | |
1347 | |
1348 g_free(str); | |
1349 return contact; | |
1350 } | |
1351 | |
1352 GList * | |
1353 nm_find_contacts(NMUser * user, const char *dn) | |
1354 { | |
1355 guint32 i, cnt; | |
1356 NMFolder *folder; | |
1357 NMContact *contact; | |
1358 GList *contacts = NULL; | |
1359 | |
1360 if (user == NULL || dn == NULL) | |
1361 return NULL; | |
1362 | |
1363 /* Check for contact at the root */ | |
1364 contact = nm_folder_find_contact(user->root_folder, dn); | |
1365 if (contact) { | |
1366 contacts = g_list_append(contacts, contact); | |
1367 contact = NULL; | |
1368 } | |
1369 | |
1370 /* Check for contact in each subfolder */ | |
1371 cnt = nm_folder_get_subfolder_count(user->root_folder); | |
1372 for (i = 0; i < cnt; i++) { | |
1373 folder = nm_folder_get_subfolder(user->root_folder, i); | |
1374 contact = nm_folder_find_contact(folder, dn); | |
1375 if (contact) { | |
1376 contacts = g_list_append(contacts, contact); | |
1377 contact = NULL; | |
1378 } | |
1379 } | |
1380 | |
1381 return contacts; | |
1382 } | |
1383 | |
1384 NMUserRecord * | |
1385 nm_find_user_record(NMUser * user, const char *name) | |
1386 { | |
1387 char *str = NULL; | |
1388 const char *dn = NULL; | |
1389 NMUserRecord *user_record = NULL; | |
1390 | |
1391 if (user == NULL || name == NULL) | |
1392 return NULL; | |
1393 | |
1394 str = g_utf8_strdown(name, -1); | |
1395 if (strstr(str, "=")) { | |
1396 dn = str; | |
1397 } else { | |
1398 /* Assume that we have a display id instead of a dn */ | |
1399 dn = (const char *) g_hash_table_lookup(user->display_id_to_dn, str); | |
1400 } | |
1401 | |
1402 /* Find user record in reference table */ | |
1403 if (dn) { | |
1404 user_record = | |
1405 (NMUserRecord *) g_hash_table_lookup(user->user_records, dn); | |
1406 } | |
1407 | |
1408 g_free(str); | |
1409 return user_record; | |
1410 } | |
1411 | |
1412 const char * | |
1413 nm_lookup_dn(NMUser * user, const char *display_id) | |
1414 { | |
1415 const char *dn; | |
1416 char *lower; | |
1417 | |
1418 if (user == NULL || display_id == NULL) | |
1419 return NULL; | |
1420 | |
1421 lower = g_utf8_strdown(display_id, -1); | |
1422 dn = g_hash_table_lookup(user->display_id_to_dn, lower); | |
1423 g_free(lower); | |
1424 | |
1425 return dn; | |
1426 } | |
1427 | |
1428 NMFolder * | |
1429 nm_find_folder(NMUser * user, const char *name) | |
1430 { | |
1431 NMFolder *folder = NULL, *temp; | |
1432 int i, num_folders; | |
1433 const char *tname = NULL; | |
1434 | |
1435 if (user == NULL || name == NULL) | |
1436 return NULL; | |
1437 | |
1438 if (*name == '\0') | |
1439 return user->root_folder; | |
1440 | |
1441 num_folders = nm_folder_get_subfolder_count(user->root_folder); | |
1442 for (i = 0; i < num_folders; i++) { | |
1443 temp = nm_folder_get_subfolder(user->root_folder, i); | |
1444 tname = nm_folder_get_name(temp); | |
1445 if (tname && (strcmp(tname, name) == 0)) { | |
1446 folder = temp; | |
1447 break; | |
1448 } | |
1449 } | |
1450 | |
1451 return folder; | |
1452 } | |
1453 | |
1454 NMFolder * | |
1455 nm_find_folder_by_id(NMUser * user, int object_id) | |
1456 { | |
1457 NMFolder *folder = NULL, *temp; | |
1458 int i, num_folders; | |
1459 | |
1460 if (user == NULL) | |
1461 return NULL; | |
1462 | |
1463 if (object_id == 0) | |
1464 return user->root_folder; | |
1465 | |
1466 num_folders = nm_folder_get_subfolder_count(user->root_folder); | |
1467 for (i = 0; i < num_folders; i++) { | |
1468 temp = nm_folder_get_subfolder(user->root_folder, i); | |
1469 if (nm_folder_get_id(temp) == object_id) { | |
1470 folder = temp; | |
1471 break; | |
1472 } | |
1473 } | |
1474 | |
1475 return folder; | |
1476 } | |
1477 | |
1478 static void | |
1479 _handle_multiple_get_details_login_cb(NMUser * user, NMERR_T ret_code, | |
1480 gpointer resp_data, gpointer user_data) | |
1481 { | |
1482 nm_response_cb cb; | |
1483 NMRequest *request = user_data; | |
1484 | |
1485 if (user == NULL || request == NULL) | |
1486 return; | |
1487 | |
1488 if ((cb = nm_request_get_callback(request))) { | |
1489 cb(user, ret_code, nm_request_get_data(request), | |
1490 nm_request_get_user_define(request)); | |
1491 nm_release_request(request); | |
1492 } | |
1493 } | |
1494 | |
1495 static void | |
1496 _handle_multiple_get_details_joinconf_cb(NMUser * user, NMERR_T ret_code, | |
1497 gpointer resp_data, gpointer user_data) | |
1498 { | |
1499 NMRequest *request = user_data; | |
1500 NMUserRecord *user_record = resp_data; | |
1501 NMConference *conference; | |
1502 GSList *list, *node; | |
1503 | |
1504 if (user == NULL || resp_data == NULL || user_data == NULL) | |
1505 return; | |
1506 | |
1507 conference = nm_request_get_data(request); | |
1508 list = nm_request_get_user_define(request); | |
1509 | |
1510 if (ret_code == 0 && conference && list) { | |
1511 | |
1512 /* Add the user to the conference */ | |
1513 nm_conference_add_participant(conference, user_record); | |
1514 | |
1515 /* Find the user in the list and remove it */ | |
1516 for (node = list; node; node = node->next) { | |
1517 if (nm_utf8_str_equal(nm_user_record_get_dn(user_record), | |
1518 (const char *) node->data)) { | |
1519 list = g_slist_remove(list, node->data); | |
1520 nm_request_set_user_define(request, list); | |
1521 g_free(node->data); | |
1522 break; | |
1523 } | |
1524 } | |
1525 | |
1526 /* Time to callback? */ | |
1527 if (g_slist_length(list) == 0) { | |
1528 nm_response_cb cb = nm_request_get_callback(request); | |
1529 | |
1530 if (cb) { | |
1531 cb(user, 0, conference, conference); | |
1532 } | |
1533 g_slist_free(list); | |
1534 nm_release_request(request); | |
1535 } | |
1536 } | |
1537 } | |
1538 | |
1539 static NMERR_T | |
1540 nm_call_handler(NMUser * user, NMRequest * request, NMField * fields) | |
1541 { | |
1542 NMERR_T rc = NM_OK, ret_code = NM_OK; | |
1543 NMConference *conf = NULL; | |
1544 NMUserRecord *user_record = NULL; | |
1545 NMField *locate = NULL; | |
1546 NMField *field = NULL; | |
1547 const char *cmd; | |
1548 nm_response_cb cb; | |
1549 gboolean done = TRUE; | |
1550 | |
1551 if (user == NULL || request == NULL || fields == NULL) | |
1552 return NMERR_BAD_PARM; | |
1553 | |
1554 /* Get the return code */ | |
1555 field = nm_locate_field(NM_A_SZ_RESULT_CODE, fields); | |
1556 if (field) { | |
1557 ret_code = atoi((char *) field->ptr_value); | |
1558 } else { | |
1559 ret_code = NMERR_PROTOCOL; | |
1560 } | |
1561 | |
1562 cmd = nm_request_get_cmd(request); | |
1563 if (ret_code == NM_OK && cmd != NULL) { | |
1564 | |
1565 if (strcmp("login", cmd) == 0) { | |
1566 | |
1567 user->user_record = nm_create_user_record_from_fields(fields); | |
1568 | |
1569 /* Save the users fields */ | |
1570 user->fields = nm_copy_field_array(fields); | |
1571 | |
1572 nm_create_contact_list(user); | |
1573 done = _create_privacy_list(user, request); | |
1574 | |
1575 } else if (strcmp("setstatus", cmd) == 0) { | |
1576 | |
1577 /* Nothing to do */ | |
1578 | |
1579 } else if (strcmp("createconf", cmd) == 0) { | |
1580 | |
1581 conf = (NMConference *) nm_request_get_data(request); | |
1582 | |
1583 /* get the convo guid */ | |
1584 locate = nm_locate_field(NM_A_FA_CONVERSATION, fields); | |
1585 if (locate) { | |
1586 field = | |
1587 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value); | |
1588 if (field) { | |
1589 nm_conference_set_guid(conf, (char *) field->ptr_value); | |
1590 } | |
1591 } | |
1592 | |
1593 nm_conference_list_add(user, conf); | |
1594 nm_release_conference(conf); | |
1595 | |
1596 } else if (strcmp("leaveconf", cmd) == 0) { | |
1597 | |
1598 conf = (NMConference *) nm_request_get_data(request); | |
1599 nm_conference_list_remove(user, conf); | |
1600 | |
1601 } else if (strcmp("joinconf", cmd) == 0) { | |
1602 GSList *list = NULL, *node; | |
1603 | |
1604 conf = nm_request_get_data(request); | |
1605 | |
1606 locate = nm_locate_field(NM_A_FA_CONTACT_LIST, fields); | |
1607 if (locate && locate->ptr_value != 0) { | |
1608 | |
1609 field = (NMField *) locate->ptr_value; | |
1610 while ((field = nm_locate_field(NM_A_SZ_DN, field))) { | |
1611 if (field && field->ptr_value != 0) { | |
1612 | |
1613 if (nm_utf8_str_equal | |
1614 (nm_user_record_get_dn(user->user_record), | |
1615 (const char *) field->ptr_value)) { | |
1616 field++; | |
1617 continue; | |
1618 } | |
1619 | |
1620 user_record = | |
1621 nm_find_user_record(user, | |
1622 (const char *) field->ptr_value); | |
1623 if (user_record == NULL) { | |
1624 list = | |
1625 g_slist_append(list, | |
1626 g_strdup((char *) field->ptr_value)); | |
1627 } else { | |
1628 nm_conference_add_participant(conf, user_record); | |
1629 } | |
1630 } | |
1631 field++; | |
1632 } | |
1633 | |
1634 if (list != NULL) { | |
1635 | |
1636 done = FALSE; | |
1637 nm_request_set_user_define(request, list); | |
1638 nm_request_add_ref(request); | |
1639 for (node = list; node; node = node->next) { | |
1640 | |
1641 nm_send_get_details(user, (const char *) node->data, | |
1642 _handle_multiple_get_details_joinconf_cb, | |
1643 request); | |
1644 } | |
1645 } | |
1646 } | |
1647 | |
1648 } else if (strcmp("getdetails", cmd) == 0) { | |
1649 | |
1650 locate = nm_locate_field(NM_A_FA_RESULTS, fields); | |
1651 while (locate && locate->ptr_value != 0) { | |
1652 | |
1653 user_record = nm_create_user_record_from_fields(locate); | |
1654 if (user_record) { | |
1655 NMUserRecord *tmp; | |
1656 | |
1657 tmp = | |
1658 nm_find_user_record(user, | |
1659 nm_user_record_get_dn(user_record)); | |
1660 if (tmp) { | |
1661 | |
1662 /* Update the existing user record */ | |
1663 nm_user_record_copy(tmp, user_record); | |
1664 nm_release_user_record(user_record); | |
1665 user_record = tmp; | |
1666 | |
1667 } else { | |
1668 nm_user_add_user_record(user, user_record); | |
1669 nm_release_user_record(user_record); | |
1670 } | |
1671 | |
1672 /* Response data is new user record */ | |
1673 nm_request_set_data(request, (gpointer) user_record); | |
1674 } | |
1675 | |
1676 locate = nm_locate_field(NM_A_FA_RESULTS, locate+1); | |
1677 } | |
1678 | |
1679 } else if (strcmp("createfolder", cmd) == 0) { | |
1680 | |
1681 _update_contact_list(user, fields); | |
1682 | |
1683 } else if (strcmp("createcontact", cmd) == 0) { | |
1684 | |
1685 _update_contact_list(user, fields); | |
1686 | |
1687 locate = | |
1688 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value); | |
1689 if (locate) { | |
1690 | |
1691 NMContact *new_contact = | |
1692 nm_folder_find_item_by_object_id(user->root_folder, | |
1693 atoi((char *)locate->ptr_value)); | |
1694 | |
1695 if (new_contact) { | |
1696 | |
1697 /* Add the contact to our cache */ | |
1698 nm_user_add_contact(user, new_contact); | |
1699 | |
1700 /* Set the contact as the response data */ | |
1701 nm_request_set_data(request, (gpointer) new_contact); | |
1702 | |
1703 } | |
1704 | |
1705 } | |
1706 | |
1707 } else if (strcmp("deletecontact", cmd) == 0) { | |
1708 | |
1709 _update_contact_list(user, fields); | |
1710 | |
1711 } else if (strcmp("movecontact", cmd) == 0) { | |
1712 | |
1713 _update_contact_list(user, fields); | |
1714 | |
1715 } else if (strcmp("getstatus", cmd) == 0) { | |
1716 | |
1717 locate = nm_locate_field(NM_A_SZ_STATUS, fields); | |
1718 if (locate) { | |
1719 nm_user_record_set_status((NMUserRecord *) | |
1720 nm_request_get_data(request), | |
1721 atoi((char *) locate->ptr_value), NULL); | |
1722 } | |
1723 | |
1724 } else if (strcmp("updateitem", cmd) == 0) { | |
1725 | |
1726 /* Nothing extra to do here */ | |
1727 | |
1728 } else if (strcmp("createblock", cmd) == 0) { | |
1729 if ((locate = nm_locate_field(NM_A_BLOCKING_DENY_LIST, fields))) { | |
1730 if (locate->ptr_value) { | |
1731 user->deny_list = g_slist_append(user->deny_list, g_strdup((char *)locate->ptr_value)); | |
1732 } | |
1733 } else if ((locate = nm_locate_field(NM_A_BLOCKING_ALLOW_LIST, fields))) { | |
1734 if (locate->ptr_value) { | |
1735 user->allow_list = g_slist_append(user->allow_list, g_strdup((char *)locate->ptr_value)); | |
1736 } | |
1737 } | |
1738 } else if (strcmp("updateblocks", cmd) == 0) { | |
1739 /* nothing to do here */ | |
1740 } else { | |
1741 | |
1742 /* Nothing to do, just print debug message */ | |
1743 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
1744 "nm_call_handler(): Unknown request command, %s\n", cmd); | |
1745 | |
1746 } | |
1747 } | |
1748 | |
1749 if (done && (cb = nm_request_get_callback(request))) { | |
1750 | |
1751 cb(user, ret_code, nm_request_get_data(request), | |
1752 nm_request_get_user_define(request)); | |
1753 } | |
1754 | |
1755 return rc; | |
1756 } | |
1757 | |
1758 static NMERR_T | |
1759 nm_process_response(NMUser * user) | |
1760 { | |
1761 NMERR_T rc = NM_OK; | |
1762 NMField *fields = NULL; | |
1763 NMField *field = NULL; | |
1764 NMConn *conn = user->conn; | |
1765 NMRequest *req = NULL; | |
1766 | |
1767 rc = nm_read_header(conn); | |
1768 if (rc == NM_OK) { | |
1769 rc = nm_read_fields(conn, -1, &fields); | |
1770 } | |
1771 | |
1772 if (rc == NM_OK) { | |
1773 field = nm_locate_field(NM_A_SZ_TRANSACTION_ID, fields); | |
1774 if (field != NULL && field->ptr_value != 0) { | |
1775 req = nm_conn_find_request(conn, atoi((char *) field->ptr_value)); | |
1776 if (req != NULL) { | |
1777 rc = nm_call_handler(user, req, fields); | |
1778 nm_conn_remove_request_item(conn, req); | |
1779 } | |
1780 | |
1781 } | |
1782 } | |
1783 | |
1784 if (fields) | |
1785 nm_free_fields(&fields); | |
1786 | |
1787 return rc; | |
1788 } | |
1789 | |
1790 /* | |
1791 * Some utility functions...haven't figured out where | |
1792 * they belong yet. | |
1793 */ | |
1794 gint | |
1795 nm_utf8_strcasecmp(gconstpointer str1, gconstpointer str2) | |
1796 { | |
1797 gint rv; | |
1798 char *str1_down = g_utf8_strdown(str1, -1); | |
1799 char *str2_down = g_utf8_strdown(str2, -1); | |
1800 | |
1801 rv = g_utf8_collate(str1_down, str2_down); | |
1802 | |
1803 g_free(str1_down); | |
1804 g_free(str2_down); | |
1805 | |
1806 return rv; | |
1807 } | |
1808 | |
1809 gboolean | |
1810 nm_utf8_str_equal(gconstpointer str1, gconstpointer str2) | |
1811 { | |
1812 return (nm_utf8_strcasecmp(str1, str2) == 0); | |
1813 } | |
1814 | |
1815 char * | |
1816 nm_typed_to_dotted(const char *typed) | |
1817 { | |
1818 unsigned i = 0, j = 0; | |
1819 char *dotted; | |
1820 | |
1821 if (typed == NULL) | |
1822 return NULL; | |
1823 | |
1824 dotted = g_new0(char, strlen(typed)); | |
1825 | |
1826 do { | |
1827 | |
1828 /* replace comma with a dot */ | |
1829 if (j != 0) { | |
1830 dotted[j] = '.'; | |
1831 j++; | |
1832 } | |
1833 | |
1834 /* skip the type */ | |
1835 while (typed[i] != '\0' && typed[i] != '=') | |
1836 i++; | |
1837 | |
1838 /* verify that we aren't running off the end */ | |
1839 if (typed[i] == '\0') { | |
1840 dotted[j] = '\0'; | |
1841 break; | |
1842 } | |
1843 | |
1844 i++; | |
1845 | |
1846 /* copy the object name to context */ | |
1847 while (typed[i] != '\0' && typed[i] != ',') { | |
1848 dotted[j] = typed[i]; | |
1849 j++; | |
1850 i++; | |
1851 } | |
1852 | |
1853 } while (typed[i] != '\0'); | |
1854 | |
1855 return dotted; | |
1856 } | |
1857 | |
1858 const char * | |
1859 nm_error_to_string(NMERR_T err) | |
1860 { | |
1861 static char *unknown_msg = NULL; | |
1862 | |
1863 g_free(unknown_msg); | |
1864 unknown_msg = NULL; | |
1865 | |
1866 switch (err) { | |
1867 | |
1868 case NMERR_BAD_PARM: | |
1869 return _("Required parameters not passed in"); | |
1870 | |
1871 case NMERR_TCP_WRITE: | |
1872 return _("Unable to write to network"); | |
1873 | |
1874 case NMERR_TCP_READ: | |
1875 return _("Unable to read from network"); | |
1876 | |
1877 case NMERR_PROTOCOL: | |
1878 return _("Error communicating with server"); | |
1879 | |
1880 case NMERR_CONFERENCE_NOT_FOUND: | |
1881 case NMERR_CONFERENCE_NOT_FOUND_2: | |
1882 return _("Conference not found"); | |
1883 | |
1884 case NMERR_CONFERENCE_NOT_INSTANTIATED: | |
1885 return _("Conference does not exist"); | |
1886 | |
1887 case NMERR_DUPLICATE_FOLDER: | |
1888 case NMERR_FOLDER_EXISTS: | |
1889 return _("A folder with that name already exists"); | |
1890 | |
1891 case NMERR_NOT_SUPPORTED: | |
1892 return _("Not supported"); | |
1893 | |
1894 case NMERR_PASSWORD_EXPIRED: | |
1895 case NMERR_PASSWORD_EXPIRED_2: | |
1896 return _("Password has expired"); | |
1897 | |
1898 case NMERR_PASSWORD_INVALID: | |
1899 return _("Invalid password"); | |
1900 | |
1901 case NMERR_USER_NOT_FOUND: | |
1902 return _("User not found"); | |
1903 | |
1904 case NMERR_USER_DISABLED: | |
1905 return _("Account has been disabled"); | |
1906 | |
1907 case NMERR_DIRECTORY_FAILURE: | |
1908 return _("The server could not access the directory"); | |
1909 | |
1910 case NMERR_ADMIN_LOCKED: | |
1911 return _("Your system administrator has disabled this operation"); | |
1912 | |
1913 case NMERR_SERVER_BUSY: | |
1914 return _("The server is unavailable; try again later"); | |
1915 | |
1916 case NMERR_DUPLICATE_CONTACT: | |
1917 return _("Cannot add a contact to the same folder twice"); | |
1918 | |
1919 case NMERR_USER_NOT_ALLOWED: | |
1920 return _("Cannot add yourself"); | |
1921 | |
1922 case NMERR_MASTER_ARCHIVE_MISSING: | |
1923 return _("Master archive is misconfigured"); | |
1924 | |
1925 case NMERR_AUTHENTICATION_FAILED: | |
1926 case NMERR_CREDENTIALS_MISSING: | |
1927 return _("Invalid username or password"); | |
1928 | |
1929 case NMERR_HOST_NOT_FOUND: | |
1930 return _("Could not recognize the host of the username you entered"); | |
1931 | |
1932 case NMERR_ACCESS_DENIED: | |
1933 return _("Your account has been disabled because too many invalid passwords were entered"); | |
1934 | |
1935 case NMERR_DUPLICATE_PARTICIPANT: | |
1936 return _("You cannot add the same person twice to a conversation"); | |
1937 | |
1938 case NMERR_TOO_MANY_CONTACTS: | |
1939 case NMERR_TOO_MANY_FOLDERS: | |
1940 return _("You have reached your limit for the number of contacts allowed"); | |
1941 | |
1942 case NMERR_OBJECT_NOT_FOUND: | |
1943 return _("You have entered an invalid username"); | |
1944 | |
1945 case NMERR_DIRECTORY_UPDATE: | |
1946 return _("An error occurred while updating the directory"); | |
1947 | |
1948 case NMERR_SERVER_PROTOCOL: | |
1949 return _("Incompatible protocol version"); | |
1950 | |
1951 case NMERR_USER_BLOCKED: | |
1952 return _("The user has blocked you"); | |
1953 | |
1954 case NMERR_EVAL_CONNECTION_LIMIT: | |
1955 return _("This evaluation version does not allow more than ten users to log in at one time"); | |
1956 | |
1957 case NMERR_CONVERSATION_INVITE: | |
1958 return _("The user is either offline or you are blocked"); | |
1959 | |
1960 default: | |
1961 unknown_msg = g_strdup_printf (_("Unknown error: 0x%X"), err); | |
1962 | |
1963 return unknown_msg; | |
1964 } | |
1965 } | |
1966 | |
1967 static void | |
1968 _update_contact_list(NMUser * user, NMField * fields) | |
1969 { | |
1970 NMField *list, *cursor, *locate; | |
1971 gint objid1; | |
1972 NMContact *contact; | |
1973 NMFolder *folder; | |
1974 gpointer item; | |
1975 | |
1976 if (user == NULL || fields == NULL) | |
1977 return; | |
1978 | |
1979 /* Is it wrapped in a RESULTS array? */ | |
1980 if (strcmp(fields->tag, NM_A_FA_RESULTS) == 0) { | |
1981 list = (NMField *) fields->ptr_value; | |
1982 } else { | |
1983 list = fields; | |
1984 } | |
1985 | |
1986 /* Update the cached contact list */ | |
1987 cursor = (NMField *) list->ptr_value; | |
1988 while (cursor->tag != NULL) { | |
1989 if ((g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) || | |
1990 (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) == 0)) { | |
1991 | |
1992 locate = | |
1993 nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) cursor->ptr_value); | |
1994 if (locate != NULL && locate->ptr_value != 0) { | |
1995 objid1 = atoi((char *) locate->ptr_value); | |
1996 item = | |
1997 nm_folder_find_item_by_object_id(user->root_folder, objid1); | |
1998 if (item != NULL) { | |
1999 if (cursor->method == NMFIELD_METHOD_ADD) { | |
2000 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) { | |
2001 contact = (NMContact *) item; | |
2002 nm_contact_update_list_properties(contact, cursor); | |
2003 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) | |
2004 == 0) { | |
2005 folder = (NMFolder *) item; | |
2006 nm_folder_update_list_properties(folder, cursor); | |
2007 } | |
2008 } else if (cursor->method == NMFIELD_METHOD_DELETE) { | |
2009 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) { | |
2010 contact = (NMContact *) item; | |
2011 folder = | |
2012 nm_find_folder_by_id(user, | |
2013 nm_contact_get_parent_id | |
2014 (contact)); | |
2015 if (folder) { | |
2016 nm_folder_remove_contact(folder, contact); | |
2017 } | |
2018 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) | |
2019 == 0) { | |
2020 /* TODO: write nm_folder_remove_folder */ | |
2021 /* ignoring for now, should not be a big deal */ | |
2022 /* folder = (NMFolder *) item;*/ | |
2023 /* nm_folder_remove_folder(user->root_folder, folder);*/ | |
2024 } | |
2025 } | |
2026 } else { | |
2027 | |
2028 if (cursor->method == NMFIELD_METHOD_ADD) { | |
2029 | |
2030 /* Not found, so we need to add it */ | |
2031 if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_CONTACT) == 0) { | |
2032 | |
2033 const char *dn = NULL; | |
2034 | |
2035 locate = | |
2036 nm_locate_field(NM_A_SZ_DN, | |
2037 (NMField *) cursor->ptr_value); | |
2038 if (locate != NULL && locate->ptr_value != 0) { | |
2039 dn = (const char *) locate->ptr_value; | |
2040 if (dn != NULL) { | |
2041 contact = | |
2042 nm_create_contact_from_fields(cursor); | |
2043 if (contact) { | |
2044 nm_folder_add_contact_to_list(user-> | |
2045 root_folder, | |
2046 contact); | |
2047 nm_release_contact(contact); | |
2048 } | |
2049 } | |
2050 } | |
2051 } else if (g_ascii_strcasecmp(cursor->tag, NM_A_FA_FOLDER) | |
2052 == 0) { | |
2053 folder = nm_create_folder_from_fields(cursor); | |
2054 nm_folder_add_folder_to_list(user->root_folder, | |
2055 folder); | |
2056 nm_release_folder(folder); | |
2057 } | |
2058 } | |
2059 } | |
2060 } | |
2061 } | |
2062 cursor++; | |
2063 } | |
2064 } | |
2065 | |
2066 static char * | |
2067 nm_rtfize_text(char *text) | |
2068 { | |
2069 GString *gstr = NULL; | |
2070 unsigned char *pch; | |
2071 char *uni_str = NULL, *rtf = NULL; | |
2072 int bytes; | |
2073 gunichar uc; | |
2074 | |
2075 gstr = g_string_sized_new(strlen(text)*2); | |
2076 pch = (unsigned char *)text; | |
2077 while (*pch) { | |
2078 if ((*pch) <= 0x7F) { | |
2079 switch (*pch) { | |
2080 case '{': | |
2081 case '}': | |
2082 case '\\': | |
2083 gstr = g_string_append_c(gstr, '\\'); | |
2084 gstr = g_string_append_c(gstr, *pch); | |
2085 break; | |
2086 case '\n': | |
2087 gstr = g_string_append(gstr, "\\par "); | |
2088 break; | |
2089 default: | |
2090 gstr = g_string_append_c(gstr, *pch); | |
2091 break; | |
2092 } | |
2093 pch++; | |
2094 } else { | |
2095 /* convert the utf-8 character to ucs-4 for rtf encoding */ | |
2096 if(*pch <= 0xDF) { | |
2097 uc = ((((gunichar)pch[0]) & 0x001F) << 6) | | |
2098 (((gunichar)pch[1]) & 0x003F); | |
2099 bytes = 2; | |
2100 } else if(*pch <= 0xEF) { | |
2101 uc = ((((gunichar)pch[0]) & 0x000F) << 12) | | |
2102 ((((gunichar)pch[1]) & 0x003F) << 6) | | |
2103 (((gunichar)pch[2]) & 0x003F); | |
2104 bytes = 3; | |
2105 } else if (*pch <= 0xF7) { | |
2106 uc = ((((gunichar)pch[0]) & 0x0007) << 18) | | |
2107 ((((gunichar)pch[1]) & 0x003F) << 12) | | |
2108 ((((gunichar)pch[2]) & 0x003F) << 6) | | |
2109 (((gunichar)pch[3]) & 0x003F); | |
2110 bytes = 4; | |
2111 } else if (*pch <= 0xFB) { | |
2112 uc = ((((gunichar)pch[0]) & 0x0003) << 24) | | |
2113 ((((gunichar)pch[1]) & 0x003F) << 18) | | |
2114 ((((gunichar)pch[2]) & 0x003F) << 12) | | |
2115 ((((gunichar)pch[3]) & 0x003F) << 6) | | |
2116 (((gunichar)pch[4]) & 0x003F); | |
2117 bytes = 5; | |
2118 } else if (*pch <= 0xFD) { | |
2119 uc = ((((gunichar)pch[0]) & 0x0001) << 30) | | |
2120 ((((gunichar)pch[1]) & 0x003F) << 24) | | |
2121 ((((gunichar)pch[2]) & 0x003F) << 18) | | |
2122 ((((gunichar)pch[3]) & 0x003F) << 12) | | |
2123 ((((gunichar)pch[4]) & 0x003F) << 6) | | |
2124 (((gunichar)pch[5]) & 0x003F); | |
2125 bytes = 6; | |
2126 } else { | |
2127 /* should never happen ... bogus utf-8! */ | |
2128 gaim_debug_info("novell", "bogus utf-8 lead byte: 0x%X\n", pch[0]); | |
2129 uc = 0x003F; | |
2130 bytes = 1; | |
2131 } | |
2132 uni_str = g_strdup_printf("\\u%d?", uc); | |
2133 gaim_debug_info("novell", "unicode escaped char %s\n", uni_str); | |
2134 gstr = g_string_append(gstr, uni_str); | |
2135 pch += bytes; | |
2136 g_free(uni_str); | |
2137 } | |
2138 } | |
2139 | |
2140 rtf = g_strdup_printf(RTF_TEMPLATE, gstr->str); | |
2141 g_string_free(gstr, TRUE); | |
2142 return rtf; | |
2143 } |