/*
- * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2007 Colin Leroy <colin@colino.net> and
- * the Claws Mail team
+ * Claws Mail -- a GTK based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2024 the Claws Mail team and Colin Leroy <colin@colino.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
* 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.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <unistd.h>
#include <curl/curl.h>
#include <curl/curlver.h>
+#include <ctype.h>
#include "account.h"
+#include "file-utils.h"
#include "utils.h"
#include "procmsg.h"
#include "procheader.h"
#include "mainwindow.h"
#include "statusbar.h"
#include "msgcache.h"
+#include "passwordstore.h"
#include "timing.h"
#include "messageview.h"
#include <gtk/gtk.h>
-#include <dirent.h>
-
-#define VCAL_FOLDERITEM(item) ((VCalFolderItem *) item)
#ifdef USE_PTHREAD
#include <pthread.h>
static void vcal_folder_set_batch (Folder *folder,
FolderItem *item,
gboolean batch);
+static void convert_to_utc(icalcomponent *calendar);
gboolean vcal_subscribe_uri(Folder *folder, const gchar *uri);
{
N_("_New meeting..."),
N_("_Export calendar..."),
- N_("_Subscribe to webCal..."),
+ N_("_Subscribe to Webcal..."),
N_("_Unsubscribe..."),
N_("_Rename..."),
N_("U_pdate subscriptions"),
static FolderViewPopup vcal_popup =
{
- "vCalendar",
+ PLUGIN_NAME,
"<vCalendar>",
vcal_popup_entries,
G_N_ELEMENTS(vcal_popup_entries),
void vcal_folder_refresh_cal(FolderItem *item)
{
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
if (item->folder != folder)
return;
if (((VCalFolderItem *)(item))->dw)
if (vcal_class.idstr == NULL) {
debug_print("register class\n");
vcal_class.type = F_UNKNOWN;
- vcal_class.idstr = "vCalendar";
- vcal_class.uistr = "vCalendar";
+ vcal_class.idstr = PLUGIN_NAME;
+ vcal_class.uistr = PLUGIN_NAME;
/* Folder functions */
vcal_class.new_folder = vcal_folder_new;
}
if (rprop && ritr) {
struct icaldurationtype ical_dur;
- struct icaltimetype dtstart, dtend;
+ struct icaltimetype dtstart = icaltime_null_time();
+ struct icaltimetype dtend = icaltime_null_time();
evt = icalcomponent_new_clone(evt);
prop = icalcomponent_get_first_property(evt, ICAL_RRULE_PROPERTY);
if (prop) {
prop = icalcomponent_get_first_property(evt, ICAL_DTSTART_PROPERTY);
if (prop)
dtstart = icalproperty_get_dtstart(prop);
+ else
+ debug_print("event has no DTSTART!\n");
prop = icalcomponent_get_first_property(evt, ICAL_DTEND_PROPERTY);
if (prop)
dtend = icalproperty_get_dtend(prop);
+ else
+ debug_print("event has no DTEND!\n");
ical_dur = icaltime_subtract(dtend, dtstart);
next = icalrecur_iterator_next(ritr);
if (!icaltime_is_null_time(next) &&
GSList *vcal_get_events_list(FolderItem *item)
{
- DIR *dp;
- struct dirent *d;
+ GDir *dp;
+ const gchar *d;
GSList *events = NULL;
+ GError *error = NULL;
if (item != item->folder->inbox) {
GSList *subs = vcal_folder_get_webcal_events_for_folder(item);
return events;
}
- dp = opendir(vcal_manager_get_event_path());
+ dp = g_dir_open(vcal_manager_get_event_path(), 0, &error);
if (!dp) {
- FILE_OP_ERROR(vcal_manager_get_event_path(), "opendir");
+ debug_print("couldn't open dir '%s': %s (%d)\n",
+ vcal_manager_get_event_path(), error->message, error->code);
+ g_error_free(error);
return 0;
}
- while ((d = readdir(dp)) != NULL) {
+ while ((d = g_dir_read_name(dp)) != NULL) {
VCalEvent *event = NULL;
- if (d->d_name[0] == '.' || strstr(d->d_name, ".bak")
- || !strcmp(d->d_name, "internal.ics")
- || !strcmp(d->d_name, "internal.ifb")
- || !strcmp(d->d_name, "multisync"))
+ if (d[0] == '.' || strstr(d, ".bak")
+ || !strcmp(d, "internal.ics")
+ || !strcmp(d, "internal.ifb")
+ || !strcmp(d, "multisync"))
continue;
- event = vcal_manager_load_event(d->d_name);
+ event = vcal_manager_load_event(d);
if (!event)
continue;
- if (event->rec_occurence) {
+ if (event->rec_occurrence) {
vcal_manager_free_event(event);
- claws_unlink(d->d_name);
+ claws_unlink(d);
continue;
}
struct icaldurationtype ical_dur;
int i = 0;
- debug_print("dumping recurring events from main event %s\n", d->d_name);
+ debug_print("dumping recurring events from main event %s\n", d);
recur = icalrecurrencetype_from_string(event->recur);
dtstart = icaltime_from_string(event->dtstart);
next = icalrecur_iterator_next(ritr);
debug_print("next time is %snull\n", icaltime_is_null_time(next)?"":"not ");
while (!icaltime_is_null_time(next) && i < 100) {
- gchar *new_start = NULL, *new_end = NULL;
+ const gchar *new_start = NULL, *new_end = NULL;
VCalEvent *nevent = NULL;
gchar *uid = g_strdup_printf("%s-%d", event->uid, i);
new_start = icaltime_as_ical_string(next);
event->sequence, event->type);
g_free(uid);
vcal_manager_copy_attendees(event, nevent);
- nevent->rec_occurence = TRUE;
+ nevent->rec_occurrence = TRUE;
vcal_manager_save_event(nevent, FALSE);
account = vcal_manager_get_account_from_event(event);
status =
vcal_manager_free_event(event);
}
}
- closedir(dp);
+ g_dir_close(dp);
return g_slist_reverse(events);
}
continue;
g_hash_table_insert(hash_uids, GINT_TO_POINTER(n_msg), g_strdup(event->uid));
- if (event->rec_occurence) {
+ if (event->rec_occurrence) {
vcal_manager_free_event(event);
continue;
}
if (_item == folder->inbox)
vcal_remove_event(folder, msginfo);
- procmsg_msginfo_free(msginfo);
+ procmsg_msginfo_free(&msginfo);
return 0;
}
static gboolean vcal_scan_required(Folder *folder, FolderItem *item)
{
- struct stat s;
+ GStatBuf s;
VCalFolderItem *vitem = (VCalFolderItem *)item;
g_return_val_if_fail(item != NULL, FALSE);
static void vcal_set_mtime(Folder *folder, FolderItem *item)
{
- struct stat s;
+ GStatBuf s;
gchar *path = folder_item_get_path(item);
if (folder->inbox != item)
}
item->mtime = s.st_mtime;
- debug_print("VCAL: forced mtime of %s to %ld\n", item->name?item->name:"(null)", item->mtime);
+ debug_print("VCAL: forced mtime of %s to %"CM_TIME_FORMAT"\n",
+ item->name?item->name:"(null)", item->mtime);
g_free(path);
}
{
FolderItem *item = folder?folder->inbox:NULL;
gboolean need_scan = folder?vcal_scan_required(folder, item):TRUE;
+ gchar *export_pass = NULL;
+ gchar *export_freebusy_pass = NULL;
if (vcal_folder_lock_count) /* blocked */
return;
vcal_folder_lock_count++;
+
+ export_pass = vcal_passwd_get("export");
+ export_freebusy_pass = vcal_passwd_get("export_freebusy");
+
if (vcal_meeting_export_calendar(vcalprefs.export_path,
vcalprefs.export_user,
- vcalprefs.export_pass,
+ export_pass,
TRUE)) {
debug_print("exporting calendar\n");
if (vcalprefs.export_enable &&
vcalprefs.export_command &&
strlen(vcalprefs.export_command))
execute_command_line(
- vcalprefs.export_command, TRUE);
+ vcalprefs.export_command, TRUE, NULL);
+ }
+ if (export_pass != NULL) {
+ memset(export_pass, 0, strlen(export_pass));
}
+ g_free(export_pass);
if (vcal_meeting_export_freebusy(vcalprefs.export_freebusy_path,
vcalprefs.export_freebusy_user,
- vcalprefs.export_freebusy_pass)) {
+ export_freebusy_pass)) {
debug_print("exporting freebusy\n");
if (vcalprefs.export_freebusy_enable &&
vcalprefs.export_freebusy_command &&
strlen(vcalprefs.export_freebusy_command))
execute_command_line(
- vcalprefs.export_freebusy_command, TRUE);
+ vcalprefs.export_freebusy_command, TRUE, NULL);
}
+ if (export_freebusy_pass != NULL) {
+ memset(export_freebusy_pass, 0, strlen(export_freebusy_pass));
+ }
+ g_free(export_freebusy_pass);
vcal_folder_lock_count--;
if (!need_scan && folder) {
vcal_set_mtime(folder, folder->inbox);
if (!file)
continue;
debug_print("removing %s\n", file);
- g_unlink(file);
+ if (g_unlink(file) < 0)
+ FILE_OP_ERROR(file, "g_unlink");
g_free(file);
}
g_slist_free(created_files);
GSList * vcal_folder_get_waiting_events(void)
{
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
return vcal_get_events_list(folder->inbox);
}
GSList * vcal_folder_get_webcal_events(void)
{
GetWebcalData *data = g_new0(GetWebcalData, 1);
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
GSList *list = NULL;
data->item = NULL;
g_node_traverse(folder->node, G_PRE_ORDER,
void vcal_folder_free_data(void)
{
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
g_node_traverse(folder->node, G_PRE_ORDER,
G_TRAVERSE_ALL, -1, vcal_free_data_func, NULL);
GSList * vcal_folder_get_webcal_events_for_folder(FolderItem *item)
{
GetWebcalData *data = g_new0(GetWebcalData, 1);
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
GSList *list = NULL;
data->item = item;
g_node_traverse(folder->node, G_PRE_ORDER,
if (days != date)
continue;
prop = icalcomponent_get_first_property((icalcomponent *)fdata->event, ICAL_SUMMARY_PROPERTY);
- if (prop) {
- if (!g_utf8_validate(icalproperty_get_summary(prop), -1, NULL))
- summary = conv_codeset_strdup(icalproperty_get_summary(prop),
+ summary = g_strdup(icalproperty_get_summary(prop));
+ if (summary) {
+ if (!g_utf8_validate(summary, -1, NULL))
+ summary = conv_codeset_strdup(summary,
conv_get_locale_charset_str(), CS_UTF_8);
- else
- summary = g_strdup(icalproperty_get_summary(prop));
} else
- summary = g_strdup("-");
+ summary = g_strdup(_("[no summary]"));
strs = g_slist_prepend(strs, summary);
}
strcpy(result+e_len+2, (gchar *)cur->data);
}
}
- slist_free_strings(strs);
- g_slist_free(strs);
+ slist_free_strings_full(strs);
return result;
}
{
struct CBuf *buffer = (struct CBuf *)stream;
gchar *tmp = NULL;
- gchar tmpbuf[size*nmemb + 1];
+ gchar *tmpbuf = g_malloc0(size*nmemb + 1);
+
+ g_return_val_if_fail(tmpbuf != NULL, 0);
memcpy(tmpbuf, buf, size*nmemb);
- tmpbuf[size*nmemb] = '\0';
if (buffer->str) {
+ /* If the buffer already has contents, append the new data. */
tmp = g_strconcat(buffer->str, tmpbuf, NULL);
+ g_free(tmpbuf);
g_free(buffer->str);
buffer->str = tmp;
} else {
- buffer->str = g_strdup(tmpbuf);
+ buffer->str = tmpbuf;
}
return size*nmemb;
curl_easy_setopt(curl_ctx, CURLOPT_WRITEDATA, &buffer);
curl_easy_setopt(curl_ctx, CURLOPT_TIMEOUT, prefs_common_get_prefs()->io_timeout_secs);
curl_easy_setopt(curl_ctx, CURLOPT_NOSIGNAL, 1);
+#ifdef G_OS_WIN32
+ curl_easy_setopt(curl_ctx, CURLOPT_CAINFO, claws_ssl_get_cert_file());
+#endif
#if LIBCURL_VERSION_NUM >= 0x070a00
if(vcalprefs.ssl_verify_peer == FALSE) {
curl_easy_setopt(curl_ctx, CURLOPT_SSL_VERIFYPEER, 0);
thread_data *td;
#ifdef USE_PTHREAD
pthread_t pt;
- pthread_attr_t pta;
#endif
void *res;
gchar *error = NULL;
STATUSBAR_PUSH(mainwindow_get_mainwindow(), label);
#ifdef USE_PTHREAD
- if (pthread_attr_init(&pta) != 0 ||
- pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE) != 0 ||
- pthread_create(&pt, &pta,
- url_read_thread, td) != 0) {
+ if (pthread_create(&pt, NULL, url_read_thread, td) != 0) {
url_read_thread(td);
}
while (!td->done) {
curl_easy_setopt(curl_ctx, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl_ctx, CURLOPT_READDATA, fp);
curl_easy_setopt(curl_ctx, CURLOPT_HTTPHEADER, headers);
+#ifdef G_OS_WIN32
+ curl_easy_setopt(curl_ctx, CURLOPT_CAINFO, claws_ssl_get_cert_file());
+#endif
#if LIBCURL_VERSION_NUM >= 0x070a00
if(vcalprefs.ssl_verify_peer == FALSE) {
curl_easy_setopt(curl_ctx, CURLOPT_SSL_VERIFYPEER, 0);
#endif
curl_easy_setopt(curl_ctx, CURLOPT_USERAGENT,
"Claws Mail vCalendar plugin "
- "(http://www.claws-mail.org/plugins.php)");
+ "(" PLUGINS_URI ")");
curl_easy_setopt(curl_ctx, CURLOPT_INFILESIZE, filesize);
res = curl_easy_perform(curl_ctx);
g_free(userpwd);
curl_easy_getinfo(curl_ctx, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code < 200 || response_code >= 300) {
- g_warning("Can't export calendar, got code %ld\n", response_code);
+ g_warning("can't export calendar, got code %ld", response_code);
res = FALSE;
}
curl_easy_cleanup(curl_ctx);
static FolderItem *get_folder_item_for_uri(const gchar *uri)
{
- Folder *root = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *root = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
gpointer d[2];
if (root == NULL)
gchar *title = NULL;
if (strstr(str, "X-WR-CALNAME:")) {
title = g_strdup(strstr(str, "X-WR-CALNAME:")+strlen("X-WR-CALNAME:"));
- if (strstr(title, "\n"))
- *(strstr(title, "\n")) = '\0';
- if (strstr(title, "\r"))
- *(strstr(title, "\r")) = '\0';
} else if (strstr(str, "X-WR-CALDESC:")) {
title = g_strdup(strstr(str, "X-WR-CALDESC:")+strlen("X-WR-CALDESC:"));
- if (strstr(title, "\n"))
- *(strstr(title, "\n")) = '\0';
- if (strstr(title, "\r"))
- *(strstr(title, "\r")) = '\0';
}
-
- return title;
+ return strcrlftrunc(title);
}
static void update_subscription_finish(const gchar *uri, gchar *feed, gboolean verbose, gchar *error)
{
- Folder *root = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *root = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
FolderItem *item = NULL;
icalcomponent *cal = NULL;
if (root == NULL) {
- g_warning("can't get root folder\n");
+ g_warning("can't get root folder");
g_free(feed);
if (error)
g_free(error);
}
if (feed == NULL) {
+ gchar *err_msg = _("Could not retrieve the Webcal URL:\n%s:\n\n%s");
+
if (verbose && manual_update) {
- gchar *tmp;
- tmp = g_strdup(uri);
+ gchar *tmp = g_strdup(uri);
if (strlen(uri) > 61) {
tmp[55]='[';
tmp[56]='.';
tmp[59]=']';
tmp[60]='\0';
}
- alertpanel_error(_("Could not retrieve the Webcal URL:\n%s:\n\n%s"),
- tmp, error ? error:_("Unknown error"));
+ alertpanel_error(err_msg, tmp, error ? error:_("Unknown error"));
g_free(tmp);
} else {
- log_error(LOG_PROTOCOL, _("Could not retrieve the Webcal URL:\n%s:\n\n%s\n"),
- uri, error ? error:_("Unknown error"));
+ gchar *msg = g_strdup_printf("%s\n", err_msg);
+ log_error(LOG_PROTOCOL, msg, uri, error ? error:_("Unknown error"));
+ g_free(msg);
}
main_window_cursor_normal(mainwindow_get_mainwindow());
g_free(feed);
g_free(error);
return;
}
- if (strncmp(feed, "BEGIN:VCALENDAR", strlen("BEGIN:VCALENDAR"))) {
+
+ gchar *tmp = feed;
+ while (*tmp && isspace((unsigned char)*tmp))
+ tmp++;
+
+ if (strncmp(tmp, "BEGIN:VCALENDAR", strlen("BEGIN:VCALENDAR"))) {
+ gchar *err_msg = _("This URL does not look like a Webcal URL:\n%s\n%s");
+
if (verbose && manual_update) {
- alertpanel_error(_("This URL does not look like a WebCal URL:\n%s\n%s"),
- uri, error ? error:_("Unknown error"));
+ alertpanel_error(err_msg, uri, error ? error:_("Unknown error"));
} else {
- log_error(LOG_PROTOCOL, _("This URL does not look like a WebCal URL:\n%s\n%s\n"),
- uri, error ? error:_("Unknown error"));
+ gchar *msg = g_strdup_printf("%s\n", err_msg);
+ log_error(LOG_PROTOCOL, msg, uri, error ? error:_("Unknown error"));
+ g_free(msg);
}
g_free(feed);
main_window_cursor_normal(mainwindow_get_mainwindow());
gchar *title = feed_get_title(feed);
if (title == NULL) {
if (strstr(uri, "://"))
- title = g_strdup(strstr(uri,"://")+3);
+ title = g_path_get_basename(strstr(uri,"://")+3);
else
title = g_strdup(uri);
subst_for_filename(title);
- if (strlen(title) > 32) {
- title[29]=title[30]=title[31]='.';
- title[32]='\0';
- }
}
item = folder_create_folder(root->node->data, title);
if (!item) {
/* if title differs, update it */
}
cal = icalparser_parse_string(feed);
+
+ convert_to_utc(cal);
if (((VCalFolderItem *)item)->cal)
icalcomponent_free(((VCalFolderItem *)item)->cal);
static void check_subs_cb(GtkAction *action, gpointer data)
{
- Folder *root = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *root = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
if (prefs_common_get_prefs()->work_offline &&
!inc_offline_should_override(TRUE,
{
gchar *uri = NULL;
gchar *tmp = NULL;
+ gchar *clip_text = NULL, *str = NULL;
+
+ clip_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
+
+ if (clip_text) {
+ str = clip_text;
+#if GLIB_CHECK_VERSION(2,66,0)
+ GError *error = NULL;
+ GUri *uri = NULL;
+
+ /* skip any leading white-space */
+ while (str && *str && g_ascii_isspace(*str))
+ str++;
+ uri = g_uri_parse(str, G_URI_FLAGS_PARSE_RELAXED, &error);
+ if (error) {
+ g_warning("could not parse clipboard text for URI: '%s'", error->message);
+ g_error_free(error);
+ }
+ if (uri) {
+ gchar* newstr = g_uri_to_string(uri);
+
+ debug_print("URI: '%s' -> '%s'\n", str, newstr ? newstr : "N/A");
+ if (newstr)
+ g_free(newstr);
+ g_uri_unref(uri);
+ } else {
+#else
+ if (!is_uri_string(str)) {
+#endif
+ /* if no URL, ignore clipboard text */
+ str = NULL;
+ }
+ }
+
+ tmp = input_dialog(_("Subscribe to Webcal"), _("Enter the Webcal URL:"), str ? str : "");
+
+ if (clip_text)
+ g_free(clip_text);
- tmp = input_dialog(_("Subscribe to WebCal"), _("Enter the WebCal URL:"), NULL);
if (tmp == NULL)
return;
static void unsubscribe_cal_cb(GtkAction *action, gpointer data)
{
FolderView *folderview = (FolderView *)data;
- GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
- FolderItem *item;
+ FolderItem *item, *opened;
gchar *message;
AlertValue avalue;
gchar *old_id;
if (!folderview->selected) return;
- item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
+ item = folderview_get_selected_item(folderview);
g_return_if_fail(item != NULL);
g_return_if_fail(item->path != NULL);
g_return_if_fail(item->folder != NULL);
+ opened = folderview_get_opened_item(folderview);
message = g_strdup_printf
(_("Do you really want to unsubscribe?"));
- avalue = alertpanel_full(_("Delete folder"), message,
- GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL,
- FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT);
+ avalue = alertpanel_full(_("Delete subscription"), message,
+ NULL, _("_Cancel"), "edit-delete", _("_Delete"),
+ NULL, NULL, ALERTFOCUS_FIRST,
+ FALSE, NULL, ALERT_WARNING);
g_free(message);
if (avalue != G_ALERTALTERNATE) return;
vcal_item_closed(item);
- if (folderview->opened == folderview->selected ||
- gtk_cmctree_is_ancestor(ctree,
- folderview->selected,
- folderview->opened)) {
+ if (item == opened ||
+ folder_is_child_of(item, opened)) {
summary_clear_all(folderview->summaryview);
- folderview->opened = NULL;
+ folderview_close_opened(folderview, TRUE);
}
if (item->folder->klass->remove_folder(item->folder, item) < 0) {
{
FolderView *folderview = (FolderView *)data;
gint action = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current));
- GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
FolderItem *item = NULL, *oitem = NULL;
if (!folderview->selected) return;
if (setting_sensitivity) return;
- oitem = gtk_cmctree_node_get_row_data(ctree, folderview->opened);
- item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
+ oitem = folderview_get_opened_item(folderview);
+ item = folderview_get_selected_item(folderview);
if (!item)
return;
icalproperty_new_prodid(
"-//Claws Mail//NONSGML Claws Mail Calendar//EN"),
icalproperty_new_calscale("GREGORIAN"),
- 0);
+ (void*)0);
vcal_manager_event_dump(event, FALSE, FALSE, calendar, FALSE);
ical = g_strdup(icalcomponent_as_ical_string(calendar));
icalcomponent_free(calendar);
return email;
}
-static void adjust_for_local_time_zone(icalproperty *eventtime, icalproperty *tzoffsetto, int dtstart)
+static void convert_to_utc(icalcomponent *calendar)
{
- int tzoffset;
- int loctzoffset;
- time_t loctime, gmttime, evttime;
- struct icaltimetype icaltime;
-
- /* calculate local UTC offset */
- loctime = time(NULL);
- loctime = mktime(localtime(&loctime));
- gmttime = mktime(gmtime(&loctime));
- loctzoffset = loctime - gmttime;
-
- if (eventtime && tzoffsetto) {
- tzoffset = icalproperty_get_tzoffsetto(tzoffsetto);
- if (dtstart) {
- evttime = icaltime_as_timet(icalproperty_get_dtstart(eventtime));
- }
- else {
- evttime = icaltime_as_timet(icalproperty_get_dtend(eventtime));
+ icalcomponent *event;
+ icaltimezone *tz, *tzutc = icaltimezone_get_utc_timezone();
+ icalproperty *prop;
+ icalparameter *tzid;
+
+ cm_return_if_fail(calendar != NULL);
+
+ for (
+ event = icalcomponent_get_first_component(calendar,
+ ICAL_VEVENT_COMPONENT);
+ event != NULL;
+ event = icalcomponent_get_next_component(calendar,
+ ICAL_VEVENT_COMPONENT)) {
+
+ /* DTSTART */
+ if ((prop = icalcomponent_get_first_property(event, ICAL_DTSTART_PROPERTY)) != NULL
+ && (tzid = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER)) != NULL) {
+ /* Event has its DTSTART with a timezone specification, let's convert
+ * to UTC and remove the TZID parameter. */
+
+ tz = icalcomponent_get_timezone(calendar, icalparameter_get_iana_value(tzid));
+ if (tz != NULL) {
+ debug_print("Converting DTSTART to UTC.\n");
+ icaltimetype t = icalproperty_get_dtstart(prop);
+ icaltimezone_convert_time(&t, tz, tzutc);
+ icalproperty_set_dtstart(prop, t);
+ icalproperty_remove_parameter_by_ref(prop, tzid);
+ }
}
- /* convert to UTC */
- evttime -= tzoffset;
- /* and adjust for local time zone */
- evttime += loctzoffset;
- icaltime = icaltime_from_timet(evttime, 0);
-
- if (dtstart) {
- icalproperty_set_dtstart(eventtime, icaltime);
+ /* DTEND */
+ if ((prop = icalcomponent_get_first_property(event, ICAL_DTEND_PROPERTY)) != NULL
+ && (tzid = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER)) != NULL) {
+ /* Event has its DTEND with a timezone specification, let's convert
+ * to UTC and remove the TZID parameter. */
+
+ tz = icalcomponent_get_timezone(calendar, icalparameter_get_iana_value(tzid));
+ if (tz != NULL) {
+ debug_print("Converting DTEND to UTC.\n");
+ icaltimetype t = icalproperty_get_dtend(prop);
+ icaltimezone_convert_time(&t, tz, tzutc);
+ icalproperty_set_dtend(prop, t);
+ icalproperty_remove_parameter_by_ref(prop, tzid);
+ }
}
- else {
- icalproperty_set_dtend(eventtime, icaltime);
- }
}
}
gchar *int_ical = g_strdup(ical);
icalcomponent *comp = icalcomponent_new_from_string(int_ical);
icalcomponent *inner = NULL;
- icalcomponent *tzcomp = NULL;
icalproperty *prop = NULL;
GSList *list = NULL, *cur = NULL;
gchar *uid = NULL;
TO_UTF8(summary);
icalproperty_free(prop);
}
- tzcomp = icalcomponent_get_first_component(comp, ICAL_VTIMEZONE_COMPONENT);
- if (tzcomp) {
- icalproperty *evtstart = NULL;
- icalproperty *evtend = NULL;
- icalproperty *tzoffsetto = NULL;
- icalcomponent *tzstd = NULL;
-
- tzstd = icalcomponent_get_first_component(tzcomp, ICAL_XSTANDARD_COMPONENT);
- tzoffsetto = icalcomponent_get_first_property(tzstd, ICAL_TZOFFSETTO_PROPERTY);
- GET_PROP(comp, evtstart, ICAL_DTSTART_PROPERTY);
- adjust_for_local_time_zone(evtstart, tzoffsetto, TRUE);
+ convert_to_utc(comp);
- GET_PROP(comp, evtend, ICAL_DTEND_PROPERTY);
- adjust_for_local_time_zone(evtend, tzoffsetto, FALSE);
-
- if (tzoffsetto)
- icalproperty_free(tzoffsetto);
- if (evtstart)
- icalproperty_free(evtstart);
- if (evtend)
- icalproperty_free(evtend);
- if (tzstd)
- icalcomponent_free(tzstd);
- }
GET_PROP(comp, prop, ICAL_DTSTART_PROPERTY);
if (prop) {
dtstart = g_strdup(icaltime_as_ical_string(icalproperty_get_dtstart(prop)));
gboolean vcal_event_exists(const gchar *id)
{
MsgInfo *info = NULL;
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
if (!folder)
return FALSE;
info = folder_item_get_msginfo_by_msgid(folder->inbox, id);
if (info != NULL) {
- procmsg_msginfo_free(info);
+ procmsg_msginfo_free(&info);
return TRUE;
}
return FALSE;
gboolean vcal_delete_event(const gchar *id)
{
MsgInfo *info = NULL;
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
if (!folder)
return FALSE;
if (info != NULL) {
debug_print("removing event %s\n", id);
vcal_remove_event(folder, info);
- procmsg_msginfo_free(info);
+ procmsg_msginfo_free(&info);
folder_item_scan(folder->inbox);
return TRUE;
}
{
VCalEvent *event = vcal_get_event_from_ical(vevent, NULL);
gchar *retVal = NULL;
- Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
- if (!folder)
+ Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
+ if (!folder) {
+ vcal_manager_free_event(event);
return NULL;
+ }
if (event) {
if (vcal_event_exists(event->uid)) {