core cleanup: move out allow_events field
[siplcs.git] / src / core / sipe-core.c
blob3a7cfa09d5a7b177d5e07ce766bfc23bef362b96
1 /**
2 * @file sipe-core.c
4 * pidgin-sipe
6 * Copyright (C) 2010-11 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
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <stdlib.h>
28 #include <string.h>
30 #include <glib.h>
32 #include "sipe-common.h"
33 #include "http-conn.h" /* sipe-cal.h requires this */
34 #include "sip-csta.h"
35 #include "sip-sec.h"
36 #include "sip-transport.h"
37 #include "sipe-backend.h"
38 #include "sipe-buddy.h"
39 #include "sipe-cal.h"
40 #include "sipe-certificate.h"
41 #include "sipe-chat.h"
42 #include "sipe-conf.h"
43 #include "sipe-core.h"
44 #include "sipe-core-private.h"
45 #include "sipe-crypt.h"
46 #include "sipe-group.h"
47 #include "sipe-groupchat.h"
48 #include "sipe-media.h"
49 #include "sipe-mime.h"
50 #include "sipe-nls.h"
51 #include "sipe-ocs2007.h"
52 #include "sipe-schedule.h"
53 #include "sipe-session.h"
54 #include "sipe-status.h"
55 #include "sipe-subscriptions.h"
56 #include "sipe-svc.h"
57 #include "sipe-utils.h"
58 #include "sipe.h"
60 /* locale_dir is unused if ENABLE_NLS is not defined */
61 void sipe_core_init(SIPE_UNUSED_PARAMETER const char *locale_dir)
63 srand(time(NULL));
64 sip_sec_init();
66 #ifdef ENABLE_NLS
67 SIPE_DEBUG_INFO("bindtextdomain = %s",
68 bindtextdomain(PACKAGE_NAME, locale_dir));
69 SIPE_DEBUG_INFO("bind_textdomain_codeset = %s",
70 bind_textdomain_codeset(PACKAGE_NAME, "UTF-8"));
71 textdomain(PACKAGE_NAME);
72 #endif
73 /* Initialization for crypto backend (production mode) */
74 sipe_crypto_init(TRUE);
75 sipe_mime_init();
78 void sipe_core_destroy(void)
80 sipe_chat_destroy();
81 sipe_mime_shutdown();
82 sipe_crypto_shutdown();
83 sip_sec_destroy();
86 gchar *sipe_core_about(void)
88 return g_strdup_printf(
90 * Non-translatable parts, like markup, are hard-coded
91 * into the format string. This requires more translatable
92 * texts but it makes the translations less error prone.
94 "<b><font size=\"+1\">SIPE " PACKAGE_VERSION " </font></b><br/>"
95 "<br/>"
96 /* 1 */ "%s:<br/>"
97 "<li> - MS Office Communications Server 2007 R2</li><br/>"
98 "<li> - MS Office Communications Server 2007</li><br/>"
99 "<li> - MS Live Communications Server 2005</li><br/>"
100 "<li> - MS Live Communications Server 2003</li><br/>"
101 "<li> - Reuters Messaging</li><br/>"
102 "<br/>"
103 /* 2 */ "%s: <a href=\"" PACKAGE_URL "\">" PACKAGE_URL "</a><br/>"
104 /* 3,4 */ "%s: <a href=\"http://sourceforge.net/projects/sipe/forums/forum/688534\">%s</a><br/>"
105 /* 5,6 */ "%s: <a href=\"" PACKAGE_BUGREPORT "\">%s</a><br/>"
106 /* 7 */ "%s: <a href=\"" SIPE_TRANSLATIONS_URL "\">Transifex.net</a><br/>"
107 /* 8 */ "%s: GPLv2+<br/>"
108 "<br/>"
109 /* 9 */ "%s:<br/>"
110 " - CERN<br/>"
111 " - Reuters Messaging network<br/>"
112 " - Deutsche Bank<br/>"
113 " - Merrill Lynch<br/>"
114 " - Wachovia<br/>"
115 " - Intel<br/>"
116 " - Nokia<br/>"
117 " - HP<br/>"
118 " - Symantec<br/>"
119 " - Accenture<br/>"
120 " - Capgemini<br/>"
121 " - Siemens<br/>"
122 " - Alcatel-Lucent<br/>"
123 " - BT<br/>"
124 "<br/>"
125 /* 10,11 */ "%s<a href=\"" SIPE_TRANSLATIONS_URL "\">Transifex.net</a>%s.<br/>"
126 "<br/>"
127 /* 12 */ "<b>%s:</b><br/>"
128 " - Anibal Avelar<br/>"
129 " - Gabriel Burt<br/>"
130 " - Stefan Becker<br/>"
131 " - pier11<br/>"
132 " - Jakub Adam<br/>"
133 " - Tomáš Hrabčík<br/>"
134 "<br/>"
135 /* 13 */ "%s<br/>"
137 /* The next 13 texts make up the SIPE about note text */
138 /* About note, part 1/13: introduction */
139 _("A third-party plugin implementing extended version of SIP/SIMPLE used by various products"),
140 /* About note, part 2/13: home page URL (label) */
141 _("Home"),
142 /* About note, part 3/13: support forum URL (label) */
143 _("Support"),
144 /* About note, part 4/13: support forum name (hyperlink text) */
145 _("Help Forum"),
146 /* About note, part 5/13: bug tracker URL (label) */
147 _("Report Problems"),
148 /* About note, part 6/13: bug tracker URL (hyperlink text) */
149 _("Bug Tracker"),
150 /* About note, part 7/13: translation service URL (label) */
151 _("Translations"),
152 /* About note, part 8/13: license type (label) */
153 _("License"),
154 /* About note, part 9/13: known users */
155 _("We support users in such organizations as"),
156 /* About note, part 10/13: translation request, text before Transifex.net URL */
157 /* append a space if text is not empty */
158 _("Please help us to translate SIPE to your native language here at "),
159 /* About note, part 11/13: translation request, text after Transifex.net URL */
160 /* start with a space if text is not empty */
161 _(" using convenient web interface"),
162 /* About note, part 12/13: author list (header) */
163 _("Authors"),
164 /* About note, part 13/13: Localization credit */
165 /* PLEASE NOTE: do *NOT* simply translate the english original */
166 /* but write something similar to the following sentence: */
167 /* "Localization for <language name> (<language code>): <name>" */
168 _("Original texts in English (en): SIPE developers")
172 static guint sipe_ht_hash_nick(const char *nick)
174 char *lc = g_utf8_strdown(nick, -1);
175 guint bucket = g_str_hash(lc);
176 g_free(lc);
178 return bucket;
181 static gboolean sipe_ht_equals_nick(const char *nick1, const char *nick2)
183 char *nick1_norm = NULL;
184 char *nick2_norm = NULL;
185 gboolean equal;
187 if (nick1 == NULL && nick2 == NULL) return TRUE;
188 if (nick1 == NULL || nick2 == NULL ||
189 !g_utf8_validate(nick1, -1, NULL) ||
190 !g_utf8_validate(nick2, -1, NULL)) return FALSE;
192 nick1_norm = g_utf8_casefold(nick1, -1);
193 nick2_norm = g_utf8_casefold(nick2, -1);
194 equal = g_utf8_collate(nick1_norm, nick2_norm) == 0;
195 g_free(nick2_norm);
196 g_free(nick1_norm);
198 return equal;
201 struct sipe_core_public *sipe_core_allocate(const gchar *signin_name,
202 const gchar *login_domain,
203 const gchar *login_account,
204 const gchar *password,
205 const gchar *email,
206 const gchar *email_url,
207 const gchar **errmsg)
209 struct sipe_core_private *sipe_private;
210 struct sipe_account_data *sip;
211 gchar **user_domain;
213 SIPE_DEBUG_INFO("sipe_core_allocate: signin_name '%s'", signin_name);
215 /* ensure that sign-in name doesn't contain invalid characters */
216 if (strpbrk(signin_name, "\t\v\r\n") != NULL) {
217 *errmsg = _("SIP Exchange user name contains invalid characters");
218 return NULL;
221 /* ensure that sign-in name format is name@domain */
222 if (!strchr(signin_name, '@') ||
223 g_str_has_prefix(signin_name, "@") ||
224 g_str_has_suffix(signin_name, "@")) {
225 *errmsg = _("User name should be a valid SIP URI\nExample: user@company.com");
226 return NULL;
229 /* ensure that email format is name@domain (if provided) */
230 if (!is_empty(email) &&
231 (!strchr(email, '@') ||
232 g_str_has_prefix(email, "@") ||
233 g_str_has_suffix(email, "@")))
235 *errmsg = _("Email address should be valid if provided\nExample: user@company.com");
236 return NULL;
239 /* ensure that user name doesn't contain spaces */
240 user_domain = g_strsplit(signin_name, "@", 2);
241 SIPE_DEBUG_INFO("sipe_core_allocate: user '%s' domain '%s'", user_domain[0], user_domain[1]);
242 if (strchr(user_domain[0], ' ') != NULL) {
243 g_strfreev(user_domain);
244 *errmsg = _("SIP Exchange user name contains whitespace");
245 return NULL;
248 /* ensure that email_url is in proper format if enabled (if provided).
249 * Example (Exchange): https://server.company.com/EWS/Exchange.asmx
250 * Example (Domino) : https://[domino_server]/[mail_database_name].nsf
252 if (!is_empty(email_url)) {
253 char *tmp = g_ascii_strdown(email_url, -1);
254 if (!g_str_has_prefix(tmp, "https://"))
256 g_free(tmp);
257 g_strfreev(user_domain);
258 *errmsg = _("Email services URL should be valid if provided\n"
259 "Example: https://exchange.corp.com/EWS/Exchange.asmx\n"
260 "Example: https://domino.corp.com/maildatabase.nsf");
261 return NULL;
263 g_free(tmp);
266 sipe_private = g_new0(struct sipe_core_private, 1);
267 sipe_private->temporary = sip = g_new0(struct sipe_account_data, 1);
268 SIPE_CORE_PRIVATE_FLAG_UNSET(SUBSCRIBED_BUDDIES);
269 SIPE_CORE_PRIVATE_FLAG_UNSET(INITIAL_PUBLISH);
270 sipe_private->username = g_strdup(signin_name);
271 sipe_private->email = is_empty(email) ? g_strdup(signin_name) : g_strdup(email);
272 sip->authdomain = is_empty(login_domain) ? NULL : g_strdup(login_domain);
273 sip->authuser = is_empty(login_account) ? NULL : g_strdup(login_account);
274 sip->password = g_strdup(password);
275 sipe_private->public.sip_name = g_strdup(user_domain[0]);
276 sipe_private->public.sip_domain = g_strdup(user_domain[1]);
277 g_strfreev(user_domain);
279 sipe_private->buddies = g_hash_table_new((GHashFunc)sipe_ht_hash_nick, (GEqualFunc)sipe_ht_equals_nick);
280 sipe_private->our_publications = g_hash_table_new_full(g_str_hash, g_str_equal,
281 g_free, (GDestroyNotify)g_hash_table_destroy);
282 sipe_subscriptions_init(sipe_private);
283 sipe_status_set_activity(sipe_private, SIPE_ACTIVITY_UNSET);
285 return((struct sipe_core_public *)sipe_private);
288 void sipe_core_connection_cleanup(struct sipe_core_private *sipe_private)
290 g_free(sipe_private->epid);
291 sipe_private->epid = NULL;
293 sip_transport_disconnect(sipe_private);
295 sipe_schedule_cancel_all(sipe_private);
297 if (sipe_private->allowed_events) {
298 GSList *entry = sipe_private->allowed_events;
299 while (entry) {
300 g_free(entry->data);
301 entry = entry->next;
304 g_slist_free(sipe_private->allowed_events);
306 sipe_ocs2007_free(sipe_private);
308 sipe_blist_menu_free_containers(sipe_private);
310 if (sipe_private->contact)
311 g_free(sipe_private->contact);
312 sipe_private->contact = NULL;
313 if (sipe_private->register_callid)
314 g_free(sipe_private->register_callid);
315 sipe_private->register_callid = NULL;
317 if (sipe_private->focus_factory_uri)
318 g_free(sipe_private->focus_factory_uri);
319 sipe_private->focus_factory_uri = NULL;
321 if (sipe_private->calendar) {
322 sipe_cal_calendar_free(sipe_private->calendar);
324 sipe_private->calendar = NULL;
326 sipe_groupchat_free(sipe_private);
329 void sipe_core_deallocate(struct sipe_core_public *sipe_public)
331 struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
332 struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE;
334 #ifdef HAVE_VV
335 if (sipe_private->media_call) {
336 sipe_media_handle_going_offline(sipe_private->media_call);
338 #endif
340 /* leave all conversations */
341 if (sipe_private->sessions) {
342 GSList *entry;
343 while ((entry = sipe_private->sessions) != NULL) {
344 sipe_session_close(sipe_private, entry->data);
348 sipe_conf_cancel_unaccepted(sipe_private, NULL);
350 if (sipe_private->csta) {
351 sip_csta_close(sipe_private);
354 sipe_certificate_free(sipe_private);
355 sipe_svc_free(sipe_private);
357 if (sipe_backend_connection_is_valid(SIPE_CORE_PUBLIC)) {
358 sipe_subscriptions_unsubscribe(sipe_private);
359 sip_transport_deregister(sipe_private);
362 sipe_core_connection_cleanup(sipe_private);
363 g_free(sipe_private->public.sip_name);
364 g_free(sipe_private->public.sip_domain);
365 g_free(sipe_private->username);
366 g_free(sipe_private->email);
367 g_free(sip->password);
368 g_free(sip->authdomain);
369 g_free(sip->authuser);
370 g_free(sipe_private->status);
371 g_free(sipe_private->note);
372 g_free(sipe_private->ocs2005_user_states);
374 sipe_buddy_free_all(sipe_private);
375 g_hash_table_destroy(sipe_private->buddies);
376 g_hash_table_destroy(sipe_private->our_publications);
377 g_hash_table_destroy(sipe_private->user_state_publications);
378 sipe_subscriptions_destroy(sipe_private);
380 if (sipe_private->groups) {
381 GSList *entry = sipe_private->groups;
382 while (entry) {
383 struct sipe_group *group = entry->data;
384 g_free(group->name);
385 g_free(group);
386 entry = entry->next;
389 g_slist_free(sipe_private->groups);
391 if (sipe_private->our_publication_keys) {
392 GSList *entry = sipe_private->our_publication_keys;
393 while (entry) {
394 g_free(entry->data);
395 entry = entry->next;
398 g_slist_free(sipe_private->our_publication_keys);
400 #ifdef HAVE_VV
401 g_free(sipe_private->mras_uri);
402 g_free(sipe_private->media_relay_username);
403 g_free(sipe_private->media_relay_password);
404 sipe_media_relay_list_free(sipe_private->media_relays);
405 #endif
407 g_free(sip);
408 g_free(sipe_private);
412 Local Variables:
413 mode: c
414 c-file-style: "bsd"
415 indent-tabs-mode: t
416 tab-width: 8
417 End: