24 #include "syncml_internals.h"
25 #include "sml_parse_internals.h"
26 #include "sml_elements_internals.h"
27 #include "sml_command_internals.h"
28 #include "sml_error_internals.h"
32 smlTrace(TRACE_ENTRY,
"%s(%s, %s, %p)", __func__, VA_STRING(locURI), VA_STRING(locName), error);
36 smlErrorSet(error, SML_ERROR_GENERIC,
"No locURI was given");
44 location->refCount = 1;
45 location->locURI = g_strdup(locURI);
46 location->locName = g_strdup(locName);
48 smlTrace(TRACE_EXIT,
"%s: %p", __func__, location);
58 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, loc);
61 g_atomic_int_inc(&(loc->refCount));
63 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, loc->refCount);
69 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, loc);
72 if (g_atomic_int_dec_and_test(&(loc->refCount))) {
73 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
76 smlSafeCFree(&(loc->locURI));
79 smlSafeCFree(&(loc->locName));
81 smlSafeFree((gpointer *)&loc);
84 smlTrace(TRACE_EXIT,
"%s", __func__);
93 void smlLocationSetURI(
SmlLocation *loc,
const char *uri)
98 smlSafeCFree(&(loc->locURI));
99 loc->locURI = g_strdup(uri);
108 void smlLocationSetName(
SmlLocation *loc,
const char *name)
113 smlSafeCFree(&(loc->locName));
114 loc->locName = g_strdup(name);
119 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, source, error);
126 location->refCount = 1;
128 smlLocationCopy(source, location);
130 smlTrace(TRACE_EXIT,
"%s: %p", __func__, location);
140 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, source, target);
145 smlSafeCFree(&(target->locURI));
148 smlSafeCFree(&(target->locName));
150 target->locURI = g_strdup(source->locURI);
151 target->locName = g_strdup(source->locName);
153 smlTrace(TRACE_EXIT,
"%s", __func__);
156 #define URL_DELIMITER "/"
158 char *strreplace(
const char *input,
const char *needle,
const char *replacement)
160 char *output = g_strdup(input);
162 while (g_strrstr(output, needle)) {
163 char *buffer = g_strndup(output, g_strrstr(output, needle) - output);
164 char *buffer2 = g_strconcat(buffer, replacement ? replacement :
"", g_strrstr(output, needle) + strlen(needle), NULL);
165 smlSafeCFree(&output);
167 smlSafeCFree(&buffer);
173 char *normalizeUrl(
const char *url)
175 smlTrace(TRACE_ENTRY,
"%s(%s)", __func__, VA_STRING(url));
180 char *buffer = strreplace(url,
"./",
"");
181 char *buffer2 = strreplace(buffer,
"//",
"/");
182 smlSafeCFree(&buffer);
184 if (strlen(buffer2) > 0 && buffer2[strlen(buffer2) - 1] ==
'/')
185 buffer2[strlen(buffer2) - 1] = 0;
187 smlTrace(TRACE_EXIT,
"%s: %s", __func__, VA_STRING(buffer2));
193 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, objectroot,
object, urlroot, url);
195 smlTrace(TRACE_INTERNAL,
"%s: objectroot: %s", __func__, VA_STRING(objectroot->locURI));
197 smlTrace(TRACE_INTERNAL,
"%s: object: %s", __func__, VA_STRING(object->locURI));
199 smlTrace(TRACE_INTERNAL,
"%s: urlroot: %s", __func__, VA_STRING(urlroot->locURI));
201 smlTrace(TRACE_INTERNAL,
"%s: url: %s", __func__, VA_STRING(url->locURI));
202 char *cmpobjurl = NULL;
205 char *buffer2 = NULL;
208 if (
object && !url) {
209 smlTrace(TRACE_EXIT,
"%s: url not given but object: FALSE", __func__);
214 smlTrace(TRACE_EXIT,
"%s: No object given: TRUE", __func__);
218 if (g_path_is_absolute(url->locURI) || !urlroot)
219 cmpurl = normalizeUrl(url->locURI);
221 buffer2 = normalizeUrl(url->locURI);
222 buffer = g_strconcat(urlroot->locURI,
"/", buffer2, NULL);
223 cmpurl = normalizeUrl(buffer);
224 smlSafeCFree(&buffer);
225 smlSafeCFree(&buffer2);
228 if (g_path_is_absolute(object->locURI) || !objectroot)
229 cmpobjurl = normalizeUrl(object->locURI);
231 buffer2 = normalizeUrl(object->locURI);
232 buffer = g_strconcat(objectroot->locURI,
"/", buffer2, NULL);
233 cmpobjurl = normalizeUrl(buffer);
234 smlSafeCFree(&buffer);
235 smlSafeCFree(&buffer2);
239 smlTrace(TRACE_INTERNAL,
"%s: Comparing %s and %s", __func__, VA_STRING(cmpobjurl), VA_STRING(cmpurl));
241 if (strcmp(cmpobjurl, cmpurl))
246 smlSafeCFree(&cmpobjurl);
247 smlSafeCFree(&cmpurl);
249 smlTrace(TRACE_EXIT,
"%s: %i", __func__, ret);
253 SmlBool smlLocationIsRelative(
SmlLocation *location)
257 return g_path_is_absolute(location->locURI) ? FALSE : TRUE;
262 smlTrace(TRACE_ENTRY,
"%s(%s, %s, %p)", __func__, VA_STRING(last), VA_STRING(next), error);
269 anchor->last = g_strdup(last);
270 anchor->next = g_strdup(next);
272 smlTrace(TRACE_EXIT,
"%s: %p", __func__, anchor);
282 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, anchor);
285 smlSafeCFree(&(anchor->last));
288 smlSafeCFree(&(anchor->next));
290 smlSafeFree((gpointer *)&anchor);
292 smlTrace(TRACE_EXIT,
"%s", __func__);
297 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, header);
299 if (header->sessionID)
300 smlSafeCFree(&(header->sessionID));
303 smlSafeCFree(&(header->emi));
306 smlLocationUnref(header->source);
309 smlLocationUnref(header->target);
311 if (header->responseURI)
312 smlSafeCFree(&(header->responseURI));
314 smlSafeFree((gpointer *)&header);
316 smlTrace(TRACE_EXIT,
"%s", __func__);
321 smlTrace(TRACE_ENTRY,
"%s(%i, %p)", __func__, size, error);
331 smlTrace(TRACE_EXIT,
"%s: %p", __func__, item);
340 SmlItem *smlItemNewForData(
const char *data,
unsigned int size,
SmlError **error)
342 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, data, size, error);
345 SmlItem *item = smlItemNew(size, error);
350 if (!smlItemAddData(item, data, size, error))
351 goto error_free_item;
354 smlTrace(TRACE_EXIT,
"%s: %p", __func__, item);
366 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, item);
369 g_atomic_int_inc(&(item->refCount));
371 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, item->refCount);
375 void smlItemUnref(
SmlItem *item)
377 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, item);
380 if (g_atomic_int_dec_and_test(&(item->refCount))) {
381 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
384 smlLocationUnref(item->source);
387 smlLocationUnref(item->target);
389 if (item->sourceParent)
390 smlLocationUnref(item->sourceParent);
392 if (item->targetParent)
393 smlLocationUnref(item->targetParent);
396 smlAnchorFree(item->anchor);
399 xmlBufferFree(item->buffer);
401 if (item->contenttype)
402 smlSafeCFree(&(item->contenttype));
404 smlSafeFree((gpointer *)&item);
407 smlTrace(TRACE_EXIT,
"%s: %i", __func__, item ? item->refCount : 0);
410 SmlBool smlItemAddData(
SmlItem *item,
const char *data,
unsigned int size,
SmlError **error)
412 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %i, %p)", __func__, item, data, size, error);
415 if (item->size && xmlBufferLength(item->buffer) + size > item->size) {
416 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add data. size limit reached");
423 item->buffer = xmlBufferCreateSize(item->size);
425 item->buffer = xmlBufferCreateSize(size);
428 if (xmlBufferAdd(item->buffer, (xmlChar *)data, size) != 0) {
429 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add data.");
434 smlTrace(TRACE_EXIT,
"%s", __func__);
446 smlAssert(xmlBufferLength(item->buffer) >= 0);
451 if ((
unsigned int)xmlBufferLength(item->buffer) != item->size)
453 smlTrace(TRACE_INTERNAL,
"%s: failed because size (%d != %d) does not match (%s).",
454 __func__, item->size,
455 xmlBufferLength(item->buffer), VA_STRING((
char *)xmlBufferContent(item->buffer)));
462 SmlBool smlItemHasData(
SmlItem *item)
465 return item->buffer ? TRUE : FALSE;
472 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, item, data, size, error);
477 smlErrorSet(error, SML_ERROR_GENERIC,
"Item check failed");
481 *size = xmlBufferLength(item->buffer);
482 *data = g_strndup((
const char *) xmlBufferContent(item->buffer), *size);
483 xmlBufferFree(item->buffer);
486 smlTrace(TRACE_EXIT,
"%s", __func__);
497 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, item, data, size, error);
501 smlErrorSet(error, SML_ERROR_GENERIC,
"Item check failed");
505 *data = (
char *)xmlBufferContent(item->buffer);
506 *size = xmlBufferLength(item->buffer);
508 smlTrace(TRACE_EXIT,
"%s", __func__);
521 item->source = source;
522 smlLocationRef(source);
537 item->target = target;
538 smlLocationRef(target);
551 smlAssert(sourceParent);
553 item->sourceParent = sourceParent;
554 smlLocationRef(sourceParent);
561 return item->sourceParent;
567 smlAssert(targetParent);
569 item->targetParent = targetParent;
570 smlLocationRef(targetParent);
577 return item->targetParent;
580 void smlItemSetRaw(
SmlItem *item, SmlBool raw)
587 SmlCred *smlCredNewFromString(
const char *type,
592 smlTrace(TRACE_ENTRY,
"%s(%s, %s, %s, %p)", __func__, VA_STRING(data), VA_STRING(type), VA_STRING(format), error);
595 SmlAuthType smlType = SML_AUTH_TYPE_UNKNOWN;
596 SmlFormatType smlFormat = SML_FORMAT_TYPE_UNKNOWN;
598 if (!type || !strcmp(type, SML_AUTH_BASIC)) {
599 smlType = SML_AUTH_TYPE_BASIC;
600 }
else if (!strcmp(type, SML_AUTH_MD5)) {
601 smlType = SML_AUTH_TYPE_MD5;
603 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown type - %s.", type);
607 if (!format || !strcmp(format, SML_BASE64)) {
608 smlFormat = SML_FORMAT_TYPE_BASE64;
610 smlErrorSet(error, SML_ERROR_GENERIC,
"SyncML credential: Unknown format - %s.", format);
615 smlErrorSet(error, SML_ERROR_GENERIC,
"Data is missing in %s.", __func__);
619 smlTrace(TRACE_EXIT,
"%s", __func__);
620 return smlCredNew(smlType, smlFormat, data, NULL, error);
626 SmlCred *smlCredNewAuth(SmlAuthType type,
627 const char *username,
628 const char *password,
631 smlTrace(TRACE_ENTRY,
"%s(%d, %s, %p)", __func__, type, VA_STRING(username), error);
636 if (username == NULL || !strlen(username)) {
637 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
638 "If authentication should be used then the username must be set.");
641 if (password == NULL || !strlen(password)) {
642 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
643 "If authentication should be used then the password must be set.");
652 cred->format = SML_FORMAT_TYPE_BASE64;
654 cred->username = g_strdup(username);
655 cred->password = g_strdup(password);
657 smlTrace(TRACE_EXIT,
"%s", __func__);
661 smlSafeFree((gpointer *)&cred);
666 SmlCred *smlCredNew(SmlAuthType type,
667 SmlFormatType format,
669 const char *username,
672 smlTrace(TRACE_ENTRY,
"%s(%s, %d, %d, %p)", __func__, VA_STRING(data), type, format, error);
680 cred->format = format;
681 cred->data = g_strdup(data);
683 cred->username = g_strdup(username);
685 cred->username = NULL;
688 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cred);
692 smlSafeCFree(&(cred->data));
694 smlSafeCFree(&(cred->username));
696 smlSafeFree((gpointer *)&cred);
703 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, cred);
706 g_atomic_int_inc(&(cred->refCount));
708 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, cred->refCount);
711 void smlCredUnref(
SmlCred *cred)
713 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, cred);
716 if (g_atomic_int_dec_and_test(&(cred->refCount))) {
717 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
720 smlSafeCFree(&(cred->data));
722 smlSafeCFree(&(cred->username));
724 smlSafeCFree(&(cred->password));
726 smlSafeFree((gpointer *)&cred);
729 smlTrace(TRACE_EXIT,
"%s", __func__);
733 void smlCredFree(
SmlCred *cred)
740 smlTrace(TRACE_ENTRY,
"%s(%u, %p)", __func__, type, error);
745 smlAssert(type != SML_AUTH_TYPE_UNKNOWN);
751 chal->format = SML_FORMAT_TYPE_BASE64;
753 if (type == SML_AUTH_TYPE_MD5)
761 chal->nonce_length = 26;
762 chal->nonce_b64 = g_base64_encode(
763 (
const unsigned char *) chal->nonce_plain,
765 if (!chal->nonce_b64) {
767 "The nonce of the challenge cannot be base64 encoded.");
772 smlTrace(TRACE_EXIT,
"%s", __func__);
775 if (chal->nonce_plain)
776 smlSafeCFree(&(chal->nonce_plain));
778 smlSafeCFree(&(chal->nonce_b64));
780 smlSafeFree((gpointer *)&chal);
791 smlTrace(TRACE_ENTRY,
"%s", __func__);
796 smlAssert(type == SML_AUTH_TYPE_MD5);
805 chal->type = SML_AUTH_TYPE_MD5;
806 chal->format = SML_FORMAT_TYPE_BASE64;
807 chal->nonce_plain = g_strndup(nonce, length);
808 chal->nonce_length = length;
811 chal->nonce_b64 = g_base64_encode((
const unsigned char *) nonce, length);
812 if (!chal->nonce_b64) {
814 "The base64 encoding of the nonce failed.");
818 smlTrace(TRACE_EXIT,
"%s", __func__);
830 smlTrace(TRACE_ENTRY,
"%s", __func__);
835 smlAssert(type == SML_AUTH_TYPE_MD5);
844 chal->type = SML_AUTH_TYPE_MD5;
845 chal->format = SML_FORMAT_TYPE_BASE64;
846 chal->nonce_b64 = g_strdup(nonce);
850 chal->nonce_plain = (
char *) g_base64_decode(nonce, &length);
851 if (!chal->nonce_plain || length < 1) {
853 "The base64 encoded nonce cannot be decoded.");
856 chal->nonce_length = length;
858 smlTrace(TRACE_EXIT,
"%s", __func__);
867 smlTrace(TRACE_ENTRY,
"%s", __func__);
870 g_atomic_int_inc(&(chal->refCount));
872 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, chal->refCount);
875 void smlChalUnref(
SmlChal *chal)
877 smlTrace(TRACE_ENTRY,
"%s", __func__);
880 if (g_atomic_int_dec_and_test(&(chal->refCount))) {
881 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
883 if (chal->nonce_plain)
884 smlSafeCFree(&(chal->nonce_plain));
887 smlSafeCFree(&(chal->nonce_b64));
889 smlSafeFree((gpointer *)&chal);
892 smlTrace(TRACE_EXIT,
"%s", __func__);
896 void smlChalFree(
SmlChal *chal)
903 smlTrace(TRACE_ENTRY,
"%s(%s, %s, %p)", __func__, VA_STRING(uid), VA_STRING(newuid), error);
913 item->source = smlLocationNew(newuid, NULL, error);
915 goto error_free_item;
917 item->target = smlLocationNew(uid, NULL, error);
919 goto error_free_source;
921 smlTrace(TRACE_EXIT,
"%s: %p", __func__, item);
925 smlLocationUnref(item->source);
927 smlSafeFree((gpointer *)&item);
935 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, item);
938 g_atomic_int_inc(&(item->refCount));
940 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, item->refCount);
946 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, item);
949 if (g_atomic_int_dec_and_test(&(item->refCount))) {
950 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
954 smlLocationUnref(item->source);
960 smlLocationUnref(item->target);
964 smlSafeFree((gpointer *)&item);
967 smlTrace(TRACE_EXIT,
"%s", __func__);
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
SmlBool smlItemStealData(SmlItem *item, char **data, unsigned int *size, SmlError **error)
char * smlRandStr(int maxlength, SmlBool exact)
Creates a random string.
SmlBool smlItemGetData(SmlItem *item, char **data, unsigned int *size, SmlError **error)
SmlBool smlItemCheck(SmlItem *item)
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.