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