l10n: Updates to Portuguese (Brazilian) (pt_BR) translation
[siplcs.git] / src / core / sipe-utils.c
blobc3b1b3ffe3144e98659113c501e0fa0499b13c8e
1 /**
2 * @file sipe-utils.c
4 * pidgin-sipe
6 * Copyright (C) 2009-2010 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 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <time.h>
29 #include <glib.h>
31 #include "sip-sec.h"
32 #include "sipe-backend.h"
33 #include "sipe-core.h" /* to ensure same API for backends */
34 #include "sipe-utils.h"
35 #include "uuid.h"
36 #include "sipe.h"
38 /* Generate 32 random bits */
39 #define RANDOM32BITS (rand() & 0xFFFF)
41 gchar *gencallid(void)
43 return g_strdup_printf("%04Xg%04Xa%04Xi%04Xm%04Xt%04Xb%04Xx%04Xx",
44 RANDOM32BITS, RANDOM32BITS, RANDOM32BITS,
45 RANDOM32BITS, RANDOM32BITS, RANDOM32BITS,
46 RANDOM32BITS, RANDOM32BITS);
49 gchar *gentag(void)
51 return g_strdup_printf("%04d%04d", RANDOM32BITS, RANDOM32BITS);
54 gchar *genconfid(void)
56 return g_strdup_printf("%04X%04X%04X%04X%04X%04X%04X%04X",
57 RANDOM32BITS, RANDOM32BITS, RANDOM32BITS,
58 RANDOM32BITS, RANDOM32BITS, RANDOM32BITS,
59 RANDOM32BITS, RANDOM32BITS);
62 gchar *get_contact(const struct sipe_account_data *sip)
64 return g_strdup(sip->contact);
67 gchar *parse_from(const gchar *hdr)
69 gchar *from;
70 const gchar *tmp, *tmp2 = hdr;
72 if (!hdr) return NULL;
73 SIPE_DEBUG_INFO("parsing address out of %s", hdr);
74 tmp = strchr(hdr, '<');
76 /* i hate the different SIP UA behaviours... */
77 if (tmp) { /* sip address in <...> */
78 tmp2 = tmp + 1;
79 tmp = strchr(tmp2, '>');
80 if (tmp) {
81 from = g_strndup(tmp2, tmp - tmp2);
82 } else {
83 SIPE_DEBUG_INFO_NOFORMAT("found < without > in From");
84 return NULL;
86 } else {
87 tmp = strchr(tmp2, ';');
88 if (tmp) {
89 from = g_strndup(tmp2, tmp - tmp2);
90 } else {
91 from = g_strdup(tmp2);
94 SIPE_DEBUG_INFO("got %s", from);
95 return from;
98 int parse_cseq(const gchar *hdr)
100 int res = -1;
101 gchar **items;
102 items = g_strsplit(hdr, " ", 1);
103 if (items[0]) {
104 res = atoi(items[0]);
106 g_strfreev(items);
107 return res;
110 gchar *sip_uri_from_name(const gchar *name)
112 return(g_strdup_printf("sip:%s", name));
115 gchar *sip_uri(const gchar *string)
117 return(strstr(string, "sip:") ? g_strdup(string) : sip_uri_from_name(string));
120 gchar *
121 get_epid(struct sipe_account_data *sip)
123 if (!sip->epid) {
124 gchar *self_sip_uri = sip_uri_self(sip);
125 sip->epid = sipe_get_epid(self_sip_uri,
126 g_get_host_name(),
127 sipe_backend_network_ip_address());
128 g_free(self_sip_uri);
130 return g_strdup(sip->epid);
133 guint
134 sipe_get_pub_instance(struct sipe_account_data *sip,
135 int publication_key)
137 unsigned res = 0;
138 gchar *epid = get_epid(sip);
140 sscanf(epid, "%08x", &res);
141 g_free(epid);
143 if (publication_key == SIPE_PUB_DEVICE) {
144 /* as is */
145 } else if (publication_key == SIPE_PUB_STATE_MACHINE) { /* First hexadecimal digit is 0x3 */
146 res = (res >> 4) | 0x30000000;
147 } else if (publication_key == SIPE_PUB_STATE_USER) {
148 res = 0x20000000; /* fixed */
149 } else if (publication_key == SIPE_PUB_STATE_CALENDAR) { /* First hexadecimal digit is 0x4 */
150 res = (res >> 4) | 0x40000000;
151 } else if (publication_key == SIPE_PUB_STATE_CALENDAR_OOF) { /* First hexadecimal digit is 0x5 */
152 res = (res >> 4) | 0x50000000;
153 } else if (publication_key == SIPE_PUB_CALENDAR_DATA ||
154 publication_key == SIPE_PUB_NOTE_OOF)
155 { /* First hexadecimal digit is 0x4 */
156 unsigned calendar_id = 0;
157 char *mail_hash = sipe_get_epid(sip->email, "", "");
159 sscanf(mail_hash, "%08x", &calendar_id);
160 g_free(mail_hash);
161 res = (calendar_id >> 4) | 0x40000000;
164 return res;
166 /* an old version
167 guint
168 sipe_get_pub_instance_(struct sipe_account_data *sip,
169 const char *publication_key)
171 unsigned part_1;
172 unsigned part_2;
173 gchar *epid = get_epid(sip);
174 sscanf(epid, "%08x", &part_1);
175 g_free(epid);
176 sscanf(publication_key, "%uh", &part_2);
177 return part_1 + part_2;
180 gboolean
181 sipe_is_bad_alias(const char *uri,
182 const char *alias)
184 char *uri_alias;
185 gboolean result = FALSE;
187 if (!uri) return FALSE;
188 if (!alias) return TRUE;
190 if (g_str_has_prefix(alias, "sip:") || g_str_has_prefix(alias, "sips:")) return TRUE;
192 /* check if alias is just SIP URI but without 'sip:' prefix */
193 uri_alias = sip_uri_from_name(alias);
194 if (sipe_strcase_equal(uri, uri_alias)) {
195 result = TRUE;
197 g_free(uri_alias);
199 return result;
202 gboolean
203 is_empty(const char *st)
205 if (!st || strlen(st) == 0)
207 return TRUE;
209 /* suspecious leading or trailing staces */
210 else if (isspace((unsigned char) *st) ||
211 isspace((unsigned char) *(st + strlen(st) - 1)))
213 /* to not modify original string */
214 char *dup = g_strdup(st);
215 if (strlen(g_strstrip(dup)) == 0) {
216 g_free(dup);
217 return TRUE;
219 g_free(dup);
221 return FALSE;
224 /** Returns newly allocated string. Must be g_free()'d */
225 char *
226 replace(const char *st,
227 const char *search,
228 const char *replace)
230 char **tmp;
231 char *res;
233 if (!st) return NULL;
235 res = g_strjoinv(replace, tmp = g_strsplit(st, search, -1));
236 g_strfreev(tmp);
237 return res;
240 char *
241 fix_newlines(const char *st)
243 return replace(st, "\r\n", "\n");
246 gboolean
247 sipe_strequal(const gchar *left, const gchar *right)
249 #if GLIB_CHECK_VERSION(2,16,0)
250 return (g_strcmp0(left, right) == 0);
251 #else
252 return ((left == NULL && right == NULL) ||
253 (left != NULL && right != NULL && strcmp(left, right) == 0));
254 #endif
257 gboolean
258 sipe_strcase_equal(const gchar *left, const gchar *right)
260 return ((left == NULL && right == NULL) ||
261 (left != NULL && right != NULL && g_ascii_strcasecmp(left, right) == 0));
264 time_t
265 sipe_utils_str_to_time(const gchar *timestamp)
267 GTimeVal time;
268 g_time_val_from_iso8601(timestamp, &time);
269 return time.tv_sec;
272 gchar *
273 sipe_utils_time_to_str(time_t timestamp)
275 GTimeVal time = { timestamp, 0 };
276 return g_time_val_to_iso8601(&time);
279 size_t
280 hex_str_to_buff(const char *hex_str, guint8 **buff)
282 char two_digits[3];
283 size_t length;
284 size_t i;
286 if (!buff) return 0;
287 if (!hex_str) return 0;
289 length = strlen(hex_str)/2;
290 *buff = (unsigned char *)g_malloc(length);
291 for (i = 0; i < length; i++) {
292 two_digits[0] = hex_str[i * 2];
293 two_digits[1] = hex_str[i * 2 + 1];
294 two_digits[2] = '\0';
295 (*buff)[i] = (unsigned char)strtoul(two_digits, NULL, 16);
298 return length;
301 char *
302 buff_to_hex_str(const guint8 *buff, const size_t buff_len)
304 char *res;
305 size_t i, j;
307 if (!buff) return NULL;
309 res = g_malloc(buff_len * 2 + 1);
310 for (i = 0, j = 0; i < buff_len; i++, j+=2) {
311 sprintf(&res[j], "%02X", buff[i]);
313 res[j] = '\0';
314 return res;
317 gboolean
318 sipe_utils_parse_lines(GSList **list, gchar **lines)
320 int i;
321 gchar **parts;
322 gchar *dummy;
323 gchar *dummy2;
324 gchar *tmp;
326 for(i = 0; lines[i] && strlen(lines[i]) > 2; i++) {
327 parts = g_strsplit(lines[i], ":", 2);
328 if(!parts[0] || !parts[1]) {
329 g_strfreev(parts);
330 return FALSE;
332 dummy = parts[1];
333 dummy2 = 0;
334 while(*dummy==' ' || *dummy=='\t') dummy++;
335 dummy2 = g_strdup(dummy);
336 while(lines[i+1] && (lines[i+1][0]==' ' || lines[i+1][0]=='\t')) {
337 i++;
338 dummy = lines[i];
339 while(*dummy==' ' || *dummy=='\t') dummy++;
340 tmp = g_strdup_printf("%s %s",dummy2, dummy);
341 g_free(dummy2);
342 dummy2 = tmp;
344 *list = sipe_utils_nameval_add(*list, parts[0], dummy2);
345 g_free(dummy2);
346 g_strfreev(parts);
349 return TRUE;
352 GSList*
353 sipe_utils_nameval_add(GSList* list, const gchar *name, const gchar *value)
355 struct sipnameval *element = g_new0(struct sipnameval,1);
357 /* SANITY CHECK: the calling code must be fixed if this happens! */
358 if (!value) {
359 SIPE_DEBUG_ERROR("sipe_utils_nameval_add: NULL value for %s",
360 name);
361 value = "";
364 element->name = g_strdup(name);
365 element->value = g_strdup(value);
366 return g_slist_append(list, element);
369 void
370 sipe_utils_nameval_free(GSList *list) {
371 struct sipnameval *elem;
372 while(list) {
373 elem = list->data;
374 list = g_slist_remove(list,elem);
375 g_free(elem->name);
376 g_free(elem->value);
377 g_free(elem);
381 const gchar *
382 sipe_utils_nameval_find(const GSList *list, const gchar *name)
384 return sipe_utils_nameval_find_instance (list, name, 0);
387 const gchar *
388 sipe_utils_nameval_find_instance(const GSList *list, const gchar *name, int which)
390 const GSList *tmp;
391 struct sipnameval *elem;
392 int i = 0;
393 tmp = list;
394 while(tmp) {
395 elem = tmp->data;
396 // OCS2005 can send the same header in either all caps or mixed case
397 if (sipe_strcase_equal(elem->name, name)) {
398 if (i == which) {
399 return elem->value;
401 i++;
403 tmp = g_slist_next(tmp);
405 return NULL;
408 gchar *sipe_utils_str_replace(const gchar *string,
409 const gchar *delimiter,
410 const gchar *replacement)
412 gchar **split;
413 gchar *result;
415 if (!string || !delimiter || !replacement) return NULL;
417 split = g_strsplit(string, delimiter, 0);
418 result = g_strjoinv(replacement, split);
419 g_strfreev(split);
421 return result;
425 Local Variables:
426 mode: c
427 c-file-style: "bsd"
428 indent-tabs-mode: t
429 tab-width: 8
430 End: