6 * Copyright (C) 2011-2013 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "sip-transport.h"
32 #include "sipe-backend.h"
33 #include "sipe-buddy.h"
34 #include "sipe-core.h"
35 #include "sipe-core-private.h"
36 #include "sipe-group.h"
39 #include "sipe-utils.h"
46 struct group_user_context
{
52 sipe_group_context_destroy(gpointer data
)
54 struct group_user_context
*ctx
= data
;
55 g_free(ctx
->group_name
);
56 g_free(ctx
->user_name
);
60 void sipe_group_add_buddy(struct sipe_core_private
*sipe_private
,
61 struct sipe_group
*group
,
65 struct sipe_buddy
*buddy
= sipe_buddy_find_by_uri(sipe_private
,
68 sipe_buddy_insert_group(buddy
, group
);
69 sipe_group_update_buddy(sipe_private
, buddy
);
75 process_add_group_response(struct sipe_core_private
*sipe_private
,
77 struct transaction
*trans
)
79 if (msg
->response
== 200) {
80 struct sipe_group
*group
;
81 struct group_user_context
*ctx
= trans
->payload
->data
;
86 xml
= sipe_xml_parse(msg
->body
, msg
->bodylen
);
91 node
= sipe_xml_child(xml
, "Body/addGroup/groupID");
97 group_id
= sipe_xml_data(node
);
103 group
= sipe_group_add(sipe_private
,
107 g_ascii_strtoull(group_id
, NULL
, 10));
110 sipe_group_add_buddy(sipe_private
,
121 sipe_group_find_by_id(struct sipe_core_private
*sipe_private
,
124 struct sipe_group
*group
;
130 entry
= sipe_private
->groups
->list
;
133 if (group
->id
== id
) {
142 sipe_group_find_by_name(struct sipe_core_private
*sipe_private
,
145 struct sipe_group
*group
;
148 if (!sipe_private
|| !name
)
151 entry
= sipe_private
->groups
->list
;
154 if (sipe_strequal(group
->name
, name
)) {
163 sipe_group_create(struct sipe_core_private
*sipe_private
,
167 if (sipe_ucs_is_migrated(sipe_private
)) {
168 sipe_ucs_group_create(sipe_private
,
172 struct transaction_payload
*payload
= g_new0(struct transaction_payload
, 1);
173 struct group_user_context
*ctx
= g_new0(struct group_user_context
, 1);
174 const gchar
*soap_name
= sipe_strequal(name
, _("Other Contacts")) ? "~" : name
;
176 ctx
->group_name
= g_strdup(name
);
177 ctx
->user_name
= g_strdup(who
);
178 payload
->destroy
= sipe_group_context_destroy
;
181 /* soap_name can contain restricted characters */
182 request
= g_markup_printf_escaped("<m:name>%s</m:name>"
185 sip_soap_request_cb(sipe_private
,
188 process_add_group_response
,
194 gboolean
sipe_group_rename(struct sipe_core_private
*sipe_private
,
195 struct sipe_group
*group
,
198 gboolean renamed
= sipe_backend_buddy_group_rename(SIPE_CORE_PUBLIC
,
203 group
->name
= g_strdup(name
);
208 struct sipe_group
*sipe_group_add(struct sipe_core_private
*sipe_private
,
210 const gchar
*exchange_key
,
211 const gchar
*change_key
,
214 struct sipe_group
*group
= NULL
;
216 if (!is_empty(name
)) {
217 group
= sipe_group_find_by_name(sipe_private
, name
);
220 sipe_backend_buddy_group_add(SIPE_CORE_PUBLIC
, name
)) {
222 group
= g_new0(struct sipe_group
, 1);
223 group
->name
= g_strdup(name
);
227 group
->exchange_key
= g_strdup(exchange_key
);
229 group
->change_key
= g_strdup(change_key
);
231 sipe_private
->groups
->list
= g_slist_append(sipe_private
->groups
->list
,
234 SIPE_DEBUG_INFO("sipe_group_add: created backend group '%s' with id %d",
235 group
->name
, group
->id
);
237 SIPE_DEBUG_INFO("sipe_group_add: backend group '%s' already exists",
244 static void group_free(struct sipe_core_private
*sipe_private
,
245 struct sipe_group
*group
)
247 sipe_private
->groups
->list
= g_slist_remove(sipe_private
->groups
->list
,
250 g_free(group
->exchange_key
);
251 g_free(group
->change_key
);
255 void sipe_group_remove(struct sipe_core_private
*sipe_private
,
256 struct sipe_group
*group
)
259 SIPE_DEBUG_INFO("removing group %s (id %d)", group
->name
, group
->id
);
260 sipe_backend_buddy_group_remove(SIPE_CORE_PUBLIC
, group
->name
);
261 group_free(sipe_private
, group
);
266 sipe_core_group_rename(struct sipe_core_public
*sipe_public
,
267 const gchar
*old_name
,
268 const gchar
*new_name
)
270 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
271 struct sipe_group
*s_group
= sipe_group_find_by_name(sipe_private
, old_name
);
274 SIPE_DEBUG_INFO("sipe_core_group_rename: from '%s' to '%s'", old_name
, new_name
);
276 if (sipe_ucs_is_migrated(sipe_private
)) {
277 sipe_ucs_group_rename(sipe_private
,
281 /* new_name can contain restricted characters */
282 gchar
*request
= g_markup_printf_escaped("<m:groupID>%d</m:groupID>"
283 "<m:name>%s</m:name>"
287 sip_soap_request(sipe_private
,
293 g_free(s_group
->name
);
294 s_group
->name
= g_strdup(new_name
);
296 SIPE_DEBUG_INFO("sipe_core_group_rename: cannot find group '%s'", old_name
);
301 sipe_core_group_remove(struct sipe_core_public
*sipe_public
,
304 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
305 struct sipe_group
*s_group
= sipe_group_find_by_name(sipe_private
, name
);
308 SIPE_DEBUG_INFO("sipe_core_group_remove: delete '%s'", name
);
310 if (sipe_ucs_is_migrated(sipe_private
)) {
311 sipe_ucs_group_remove(sipe_private
,
314 gchar
*request
= g_strdup_printf("<m:groupID>%d</m:groupID>",
316 sip_soap_request(sipe_private
,
322 group_free(sipe_private
, s_group
);
324 SIPE_DEBUG_INFO("sipe_core_group_remove: cannot find group '%s'", name
);
329 * Returns string like "2 4 7 8" - group ids buddy belong to.
331 static gchar
*sipe_get_buddy_groups_string(struct sipe_buddy
*buddy
)
335 //creating array from GList, converting int to gchar*
336 gchar
**ids_arr
= g_new(gchar
*, g_slist_length(buddy
->groups
) + 1);
337 GSList
*entry
= buddy
->groups
;
339 if (!ids_arr
) return NULL
;
342 struct sipe_group
* group
= entry
->data
;
343 ids_arr
[i
] = g_strdup_printf("%d", group
->id
);
348 res
= g_strjoinv(" ", ids_arr
);
354 * Sends buddy update to server
356 static void send_buddy_update(struct sipe_core_private
*sipe_private
,
357 struct sipe_buddy
*buddy
,
360 gchar
*groups
= sipe_get_buddy_groups_string(buddy
);
364 SIPE_DEBUG_INFO("Saving buddy %s with alias '%s' and groups '%s'",
365 buddy
->name
, alias
, groups
);
367 /* alias can contain restricted characters */
368 request
= g_markup_printf_escaped("<m:displayName>%s</m:displayName>"
369 "<m:groups>%s</m:groups>"
370 "<m:subscribed>true</m:subscribed>"
373 alias
, groups
, buddy
->name
);
376 sip_soap_request(sipe_private
,
383 /* indicates that buddy information on the server needs updating */
384 void sipe_group_update_buddy(struct sipe_core_private
*sipe_private
,
385 struct sipe_buddy
*buddy
)
388 sipe_backend_buddy backend_buddy
= sipe_backend_buddy_find(SIPE_CORE_PUBLIC
,
392 gchar
*alias
= sipe_backend_buddy_get_alias(SIPE_CORE_PUBLIC
,
394 send_buddy_update(sipe_private
, buddy
, alias
);
400 void sipe_core_group_set_alias(struct sipe_core_public
*sipe_public
,
404 struct sipe_core_private
*sipe_private
= SIPE_CORE_PRIVATE
;
405 struct sipe_buddy
*buddy
= sipe_buddy_find_by_uri(sipe_private
,
409 send_buddy_update(sipe_private
, buddy
, alias
);
412 struct sipe_group
*sipe_group_first(struct sipe_core_private
*sipe_private
)
414 return(sipe_private
->groups
->list
? sipe_private
->groups
->list
->data
: NULL
);
417 guint
sipe_group_count(struct sipe_core_private
*sipe_private
)
419 return(g_slist_length(sipe_private
->groups
->list
));
422 void sipe_group_init(struct sipe_core_private
*sipe_private
)
424 sipe_private
->groups
= g_new0(struct sipe_groups
, 1);
427 void sipe_group_free(struct sipe_core_private
*sipe_private
)
431 while ((entry
= sipe_private
->groups
->list
) != NULL
)
432 group_free(sipe_private
, entry
->data
);
434 g_free(sipe_private
->groups
);
435 sipe_private
->groups
= NULL
;