summaryrefslogtreecommitdiffstats
path: root/src/.svn/text-base/caldav-utils.c.svn-base
diff options
context:
space:
mode:
Diffstat (limited to 'src/.svn/text-base/caldav-utils.c.svn-base')
-rw-r--r--src/.svn/text-base/caldav-utils.c.svn-base713
1 files changed, 0 insertions, 713 deletions
diff --git a/src/.svn/text-base/caldav-utils.c.svn-base b/src/.svn/text-base/caldav-utils.c.svn-base
deleted file mode 100644
index 50ce7ae..0000000
--- a/src/.svn/text-base/caldav-utils.c.svn-base
+++ /dev/null
@@ -1,713 +0,0 @@
-/* vim: set textwidth=80 tabstop=4: */
-
-/* Copyright (c) 2008 Michael Rasmussen (mir@datanom.net)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "caldav-utils.h"
-#include "md5.h"
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <curl/curl.h>
-#include <ctype.h>
-
-/**
- * This function is burrowed from the libcurl documentation
- * @param text
- * @param stream
- * @param ptr
- * @param size
- * @param nohex
- */
-void dump(const char* text, FILE* stream, char* ptr, size_t size, char nohex) {
- size_t i;
- size_t c;
-
- unsigned int width=0x10;
-
- if(nohex)
- /* without the hex output, we can fit more on screen */
- width = 0x40;
- fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
- for(i=0; i<size; i+= width) {
- fprintf(stream, "%04zx: ", i);
- if(!nohex) {
- /* hex not disabled, show it */
- for(c = 0; c < width; c++) {
- if(i+c < size)
- fprintf(stream, "%02x ", ptr[i+c]);
- else
- fputs(" ", stream);
- }
- }
- for(c = 0; (c < width) && (i+c < size); c++) {
- /* check for 0D0A; if found, skip past and start a new line of output */
- if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
- i+=(c+2-width);
- break;
- }
- fprintf(stream, "%c",(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
- /* check again for 0D0A, to avoid an extra \n if it's at width */
- if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
- i+=(c+3-width);
- break;
- }
- }
- fputc('\n', stream); /* newline */
- }
- fflush(stream);
-}
-
-/**
- * This function is burrowed from the libcurl documentation
- * @param handle
- * @param type
- * @param data
- * @param size
- * @param userp
- * @return
- */
-int my_trace(CURL* handle, curl_infotype type, char* data, size_t size, void* userp) {
- struct config_data* config = (struct config_data *)userp;
- const char* text;
- (void)handle; /* prevent compiler warning */
-
- switch (type) {
- case CURLINFO_TEXT:
- fprintf(stderr, "== Info: %s", data);
- default: /* in case a new one is introduced to shock us */
- return 0;
- case CURLINFO_HEADER_OUT:
- text = "=> Send header";
- break;
- case CURLINFO_DATA_OUT:
- text = "=> Send data";
- break;
- case CURLINFO_SSL_DATA_OUT:
- text = "=> Send SSL data";
- break;
- case CURLINFO_HEADER_IN:
- text = "<= Recv header";
- break;
- case CURLINFO_DATA_IN:
- text = "<= Recv data";
- break;
- case CURLINFO_SSL_DATA_IN:
- text = "<= Recv SSL data";
- break;
- }
- dump(text, stderr, data, size, config->trace_ascii);
- return 0;
-}
-
-/**
- * This function is burrowed from the libcurl documentation
- * @param ptr
- * @param size
- * @return void* to memory region
- */
-static void* myrealloc(void* ptr, size_t size) {
-/* There might be a realloc() out there that doesn't like reallocing
- * NULL pointers, so we take care of it here
- * */
- if(ptr)
- return realloc(ptr, size);
- else
- return malloc(size);
-}
-
-/**
- * This function is burrowed from the libcurl documentation
- * @param ptr
- * @param size
- * @param nmemb
- * @param data
- * @return number of written bytes
- */
-size_t WriteMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data) {
- size_t realsize = size * nmemb;
- struct MemoryStruct* mem = (struct MemoryStruct *)data;
- mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
-
- if (mem->memory) {
- memcpy(&(mem->memory[mem->size]), ptr, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
- }
- return realsize;
-}
-
-/**
- * This function is burrowed from the libcurl documentation
- * @param ptr
- * @param size
- * @param nmemb
- * @param data
- * @return number of written bytes
- */
-size_t WriteHeaderCallback(void* ptr, size_t size, size_t nmemb, void* data) {
- size_t realsize = size * nmemb;
- struct MemoryStruct* mem = (struct MemoryStruct *)data;
- mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
-
- if (mem->memory) {
- memcpy(&(mem->memory[mem->size]), ptr, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
- }
- return realsize;
-}
-
-/*
-size_t ReadMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data){
- struct MemoryStruct* mem = (struct MemoryStruct *)data;
-
- memcpy(ptr, mem->memory, mem->size);
- return mem->size;
-}
-*/
-
-/**
- * Initialize caldav settings structure.
- * @param settings @see caldav_settings
- */
-void init_caldav_settings(caldav_settings* settings) {
- settings->username = NULL;
- settings->password = NULL;
- settings->url = NULL;
- settings->file = NULL;
- settings->usehttps = FALSE;
- settings->custom_cacert = NULL;
- settings->verify_ssl_certificate = TRUE;
- settings->debug = FALSE;
- settings->trace_ascii = TRUE;
- settings->ACTION = UNKNOWN;
- settings->start = 0;
- settings->end = 0;
-}
-
-/**
- * Free memory assigned to caldav settings structure.
- * @param settings @see caldav_settings
- */
-void free_caldav_settings(caldav_settings* settings) {
- if (settings->username) {
- g_free(settings->username);
- settings->username = NULL;
- }
- if (settings->password) {
- g_free(settings->password);
- settings->password = NULL;
- }
- if (settings->url) {
- g_free(settings->url);
- settings->url = NULL;
- }
- if (settings->file) {
- g_free(settings->file);
- settings->file = NULL;
- }
- if (settings->custom_cacert) {
- g_free(settings->custom_cacert);
- settings->custom_cacert = NULL;
- }
- settings->verify_ssl_certificate = TRUE;
- settings->usehttps = FALSE;
- settings->debug = FALSE;
- settings->trace_ascii = TRUE;
- settings->ACTION = UNKNOWN;
- settings->start = 0;
- settings->end = 0;
-}
-
-static gchar* place_after_hostname(const gchar* start, const gchar* stop) {
- gchar* newpos = NULL;
- gchar* pos = (gchar *) stop;
- gboolean digit = TRUE;
-
- if (pos && stop && strcmp(start, pos) != 0) {
- while (*pos != ':' && strcmp(start, pos) != 0)
- --pos;
- if (pos > start) {
- gchar* tmp = (gchar *) pos + 1;
- /* is pos++ a port number */
- while (*tmp != '/' && digit) {
- if (isdigit(*tmp) != 0) {
- digit = TRUE;
- tmp++;
- }
- else
- digit = FALSE;
- }
- if (digit) {
- /* pos was a port number */
- while (*pos != '@' && strcmp(start, pos) != 0)
- --pos;
- if (strcmp(start, pos) != 0)
- newpos = pos;
- }
- else {
- while (*pos != '@' && pos != stop)
- pos++;
- if (pos != stop)
- newpos = pos;
- }
- }
- else {
- /* is a username present */
- gchar* tmp = NULL;
- while (*pos != '/' && pos != stop) {
- if (*pos == '@')
- tmp = pos;
- pos++;
- }
- if (tmp && pos != stop)
- newpos = tmp;
- }
- }
- return newpos;
-}
-
-/**
- * Parse URL
- * @param settings @see caldav_settings
- * @param url String containing URL to collection
- */
-void parse_url(caldav_settings* settings, const char* url) {
- char* start;
- char* pos;
- char* end;
- char* login;
-
- login = pos = end = start = NULL;
- if (!url)
- return;
- if ((pos = strstr(url, "//")) != NULL) {
- /* Does the URL use https ?*/
- if (!g_ascii_strncasecmp(url,"https",5) && settings->usehttps == FALSE) {
- settings->usehttps=TRUE;
- }
- start = g_strdup(&(*(pos + 2)));
- if ((pos = place_after_hostname(start, strrchr(start, '\0') - 1)) != NULL) {
- /* username and/or password present */
- login = g_strndup(start, pos - start);
- end = pos;
- if ((pos = strrchr(login, ':')) != NULL) {
- /* both username and password is present */
- settings->username = g_strndup(login, pos - login);
- settings->password = g_strdup(++pos);
- }
- else {
- /* only username present */
- settings->username = g_strdup(login);
- settings->password = NULL;
- }
- g_free(login);
- settings->url = g_strdup(++end);
- }
- else {
- /* no username or password present */
- settings->url = g_strdup(start);
- settings->username = NULL;
- settings->password = NULL;
- }
- g_free(start);
- }
-}
-
-/**
- * Find a specific HTTP header from last request
- * @param header HTTP header to search for
- * @param headers String of HTTP headers from last request
- * @param lowcase Should string be returned in all lower case.
- * @return The header found or NULL
- */
-#define MAX_TOKENS 2
-gchar* get_response_header(
- const char* header, gchar* headers, gboolean lowcase) {
- gchar* line;
- gchar* head = NULL;
- gchar* oldhead = NULL;
- gchar** buf;
- gchar* header_list;
- gchar* saveptr;
-
- header_list = g_strdup(headers);
- line = strtok_r(header_list, "\r\n", &saveptr);
- if (line != NULL) {
- do {
- buf = g_strsplit(line, ":", MAX_TOKENS);
- if (buf[1] != NULL) {
- if (g_ascii_strcasecmp(buf[0], header) == 0) {
- if (head) {
- oldhead = head;
- head = g_strconcat(head, ", ", buf[1], NULL);
- g_free(oldhead);
- }
- else
- head = g_strdup(buf[1]);
- if (head)
- g_strstrip(head);
- }
- }
- g_strfreev(buf);
- } while ((line = strtok_r(NULL, "\r\n", &saveptr)) != NULL);
- }
- g_free(header_list);
- if (head)
- return (lowcase) ? g_ascii_strdown(head, -1) : head;
- else
- return NULL;
-}
-
-static const char* VCAL_HEAD =
-"BEGIN:VCALENDAR\r\n"
-"PRODID:-//CalDAV Calendar//NONSGML libcaldav//EN\r\n"
-"VERSION:2.0\r\n";
-static const char* VCAL_FOOT = "END:VCALENDAR";
-
-/**
- * Parse response from CalDAV server. Internal function.
- * @param report Response from server
- * @param element XML element to find
- * @param type VCalendar element to find
- * @param wrap Is this the final parsing or just a part
- * @param recursive Stop after first match or not
- * @return the parsed result
- */
-static gchar* parse_caldav_report_wrap(
- char* report, const char* element, const char* type,
- gboolean wrap, gboolean recursive) {
- char* pos;
- char* start;
- char* object;
- char* tmp_report;
- char* tmp;
- gchar* response;
- gchar* begin_type;
- gchar* end_type;
- gboolean keep_going = TRUE;
-
- begin_type = g_strdup_printf("BEGIN:%s", type);
- end_type = g_strdup_printf("END:%s", type);
- pos = start = object = response = NULL;
- tmp_report = g_strdup(report);
- while ((pos = strstr(tmp_report, element)) != NULL && keep_going) {
- pos = strchr(pos, '>');
- if (!pos) {
- break;
- }
- pos = &(*(pos + 1));
- pos = strstr(pos, begin_type);
- if (!pos) {
- break;
- }
- object = &(*(pos + strlen(begin_type)));
- object = g_strchug(object);
- start = g_strdup(object);
- if ((pos = strstr(start, end_type)) == NULL) {
- g_free(start);
- break;
- }
- object = g_strndup(start, strlen(start) - strlen(pos));
- if (response) {
- tmp = g_strdup(response);
- g_free(response);
- response = g_strdup_printf("%s%s\r\n%s%s\r\n",
- tmp, begin_type, object, end_type);
- g_free(tmp);
- }
- else {
- if (wrap)
- response = g_strdup_printf("%s%s\r\n%s%s\r\n",
- VCAL_HEAD, begin_type, object, end_type);
- else
- response = g_strdup_printf("%s\r\n%s%s\r\n",
- begin_type, object, end_type);
- }
- if (recursive) {
- pos = strchr(pos, '>');
- g_free(tmp_report);
- tmp_report = g_strdup(&(*(pos + 1)));
- }
- else {
- keep_going = FALSE;
- }
- g_free(start);
- g_free(object);
- }
- g_free(tmp_report);
- g_free(begin_type);
- g_free(end_type);
- if (wrap)
- if (response) {
- object = g_strdup(response);
- g_free(response);
- response = g_strdup_printf("%s%s", object, VCAL_FOOT);
- g_free(object);
- }
- return response;
-}
-
-/**
- * Parse response from CalDAV server
- * @param report Response from server
- * @param element XML element to find
- * @param type VCalendar element to find
- * @return the parsed result
- */
-gchar* parse_caldav_report(char* report, const char* element, const char* type) {
- gchar* response = NULL;
- gchar* timezone = NULL;
- gchar* temp = NULL;
-
- if (!report || !element || !type)
- return NULL;
- /* test for VTIMEZONE.
- * Only the first found will be used and this will then
- * be the time zone for the entire report
- */
- timezone = parse_caldav_report_wrap(
- report, element, "VTIMEZONE", FALSE, FALSE);
- if (timezone) {
- response = g_strdup_printf("%s%s", VCAL_HEAD, timezone);
- g_free(timezone);
- temp = parse_caldav_report_wrap(report, element, type, FALSE, TRUE);
- if (temp) {
- gchar* tmp = g_strdup(response);
- g_free(response);
- response = g_strdup_printf("%s%s%s", tmp, temp, VCAL_FOOT);
- g_free(tmp);
- g_free(temp);
- }
- else {
- g_free(response);
- return NULL;
- }
- }
- else
- response = parse_caldav_report_wrap(report, element, type, TRUE, TRUE);
- return response;
-}
-
-/**
- * Convert a time_t variable to CalDAV DateTime
- * @param time a specific date and time
- * @return the CalDAV DateTime
- */
-gchar* get_caldav_datetime(time_t* time) {
- struct tm *current;
- gchar* datetime;
-
- current = localtime(time);
- datetime = g_strdup_printf("%d%.2d%.2dT%.2d%.2d%.2dZ",
- current->tm_year + 1900, current->tm_mon + 1, current->tm_mday,
- current->tm_hour, current->tm_min, current->tm_sec);
- return datetime;
-}
-
-/**
- * Create a random text string, using MD5. @see caldav_md5_hex_digest()
- * @param text some text to randomize
- * @return MD5 hash of text
- */
-gchar* random_file_name(gchar* text) {
- unsigned char* name;
- gchar md5sum[33];
-
- name = (unsigned char *) g_strdup(text);
- caldav_md5_hex_digest(md5sum, name);
- g_free(name);
- return g_strdup(md5sum);
-}
-
-/**
- * Does the event contain a UID element or not. If not add it.
- * @param object A specific event
- * @return event, eventually added UID
- */
-gchar* verify_uid(gchar* object) {
- gchar* uid;
- gchar* newobj;
- gchar* pos;
-
- newobj = g_strdup(object);
- uid = get_response_header("uid", object, TRUE);
- if (!uid) {
- object = g_strdup(newobj);
- g_free(newobj);
- pos = strstr(object, "END:VEVENT");
- newobj = g_strndup(object, strlen(object) - strlen(pos));
- newobj = g_strchomp(newobj);
- uid = random_file_name(object);
- gchar*tmp = g_strdup(newobj);
- g_free(newobj);
- newobj = g_strdup_printf("%s\r\nUID:libcaldav-%s@tempuri.org\r\n%s",
- tmp, uid, pos);
- g_free(uid);
- g_free(tmp);
- g_free(object);
- }
- else
- g_free(uid);
- /*uid = g_strdup(newobj);
- g_free(newobj);*/
- g_strchomp(newobj);
- /*g_free(uid);*/
- return newobj;
-}
-
-/**
- * Fetch a URL from a XML element
- * @param text String
- * @return URL
- */
-#define ELEM_HREF "href>"
-gchar* get_url(gchar* text) {
- gchar* pos;
- gchar* url = NULL;
-
- if ((pos = strstr(text, ELEM_HREF)) == NULL)
- return url;
- pos = &(*(pos + strlen(ELEM_HREF)));
- url = g_strndup(pos, strlen(pos) - strlen(strchr(pos, '<')));
- return url;
-}
-
-/**
- * Fetch any element from XML
- * @param text String
- * @param tag The element to look for
- * @return element
- */
-gchar* get_tag(const gchar* tag, gchar* text) {
- gchar *pos;
- gchar* res = NULL;
- gchar* the_tag = NULL;
-
- /*printf("%s\n", text);*/
- the_tag = g_strdup_printf("<%s>", tag);
- if ((pos = strstr(text, the_tag)) == NULL) {
- g_free(the_tag);
- return res;
- }
- pos = &(*(pos + strlen(the_tag)));
- res = g_strndup(pos, strlen(pos) - strlen(strchr(pos, '<')));
- g_free(the_tag);
- return res;
-}
-
-/**
- * Fetch the etag element from XML
- * @param text String
- * @return etag
- */
-#define ELEM_ETAG "getetag"
-gchar* get_etag(gchar* text) {
- gchar* etag = NULL;
-
- etag = get_tag(ELEM_ETAG, text);
- /* Maybe namespace prefixed */
- if (!etag) {
- etag = get_tag("D:getetag", text);
- }
- return etag;
-}
-
-/**
- * Fetch host from URL
- * @param url URL
- * @return host
- */
-gchar* get_host(gchar* url) {
- gchar** buf;
- gchar* result = NULL;
-
- buf = g_strsplit(url, "/", 2);
- if (buf[0]) {
- result = g_strdup(buf[0]);
- }
- g_strfreev(buf);
- return result;
-}
-
-/**
- * rebuild a raw URL with https if needed from the settings
- * @param settings caldav_settings
- * @param uri URI to use instead of base
- * @return URL
- */
-
-gchar* rebuild_url(caldav_settings* settings, gchar* uri){
- gchar* url = NULL;
- gchar* mystr = NULL;
- if (settings->usehttps) {
- mystr = "https://";
- } else {
- mystr = "http://";
- }
- if (uri)
- url = g_strdup_printf("%s%s", mystr, uri);
- else
- url = g_strdup_printf("%s%s", mystr,settings->url);
-
- return url;
-}
-
-/**
- * Prepare a curl connection
- * @param settings caldav_settings
- * @return CURL
- */
-CURL* get_curl(caldav_settings* setting) {
- CURL* curl;
- gchar* userpwd = NULL;
- gchar* url = NULL;
-
- curl = curl_easy_init();
- if (curl) {
- if (setting->username) {
- if (setting->password)
- userpwd = g_strdup_printf("%s:%s",
- setting->username, setting->password);
- else
- userpwd = g_strdup_printf("%s", setting->username);
- curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
- g_free(userpwd);
- }
- if (setting->verify_ssl_certificate)
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
- else {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
- }
- if (setting->custom_cacert)
- curl_easy_setopt(curl, CURLOPT_CAINFO, setting->custom_cacert);
- curl_easy_setopt(curl, CURLOPT_USERAGENT, __CALDAV_USERAGENT);
- url = rebuild_url(setting, NULL);
- curl_easy_setopt(curl, CURLOPT_URL, url);
- g_free(url);
- }
- return (curl) ? curl : NULL;
-}