/** Set icalcomponent X-* property. * * @param comp iCal component. * @param key Property name (i.e. X-EEE-WHATEVER). * @param value Property value. */ static void icomp_x_prop_set(icalcomponent *comp, const char *key, const char *value) { icalproperty *iter; g_return_if_fail(comp != NULL); g_return_if_fail(key != NULL); again: for (iter = icalcomponent_get_first_property(comp, ICAL_X_PROPERTY); iter; iter = icalcomponent_get_next_property(comp, ICAL_X_PROPERTY)) { const char *str = icalproperty_get_x_name(iter); if (str && !g_strcmp0(str, key)) { icalcomponent_remove_property(comp, iter); icalproperty_free(iter); goto again; } } if (value) { iter = icalproperty_new_x(value); icalproperty_set_x_name(iter, key); icalcomponent_add_property(comp, iter); } }
void scalix_appointment_set (ScalixAppointment * comp, const char *key, const char *value) { icalcomponent *icomp; icalproperty *icalprop; e_cal_component_commit_sequence (E_CAL_COMPONENT (comp)); icomp = e_cal_component_get_icalcomponent (E_CAL_COMPONENT (comp)); icalprop = icalproperty_new_x (value); icalproperty_set_x_name (icalprop, key); icalcomponent_add_property (icomp, icalprop); }
// TODO: double check this - need an example. void ical_property_X_MS_OLK_SENDER(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *param; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptStateFlags) return; if (!(*exchange2ical->apptStateFlags & 0x1)) return; if (!exchange2ical->SenderName) return; if (exchange2ical->SenderEmailAddress) { snprintf(outstr, 200, "mailto:%s",exchange2ical->SenderEmailAddress); prop = icalproperty_new_x(outstr); } else { prop = icalproperty_new_x("invalid:nomail"); } icalproperty_set_x_name(prop, "X-MS-OLK-SENDER"); icalcomponent_add_property(exchange2ical->vevent, prop); param = icalparameter_new_cn(exchange2ical->SenderName); icalproperty_add_parameter(prop, param); }
static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char *propname, const char *value) { icalproperty *prop; icalvalue *icalText; /* Sanity checks */ if (!parent) return NULL; if (!propname) return NULL; if (!value) return NULL; icalText = icalvalue_new_text(value); prop = icalproperty_new_x(icalvalue_as_ical_string(icalText)); icalvalue_free(icalText); icalproperty_set_x_name(prop, propname); icalcomponent_add_property(parent, prop); return prop; }
static gboolean do_mail_to_event (AsyncData *data) { EClient *client; CamelFolder *folder = data->folder; GPtrArray *uids = data->uids; GError *error = NULL; client = e_client_cache_get_client_sync (data->client_cache, data->source, data->extension_name, 30, NULL, &error); /* Sanity check. */ g_return_val_if_fail ( ((client != NULL) && (error == NULL)) || ((client == NULL) && (error != NULL)), TRUE); if (error != NULL) { report_error_idle (_("Cannot open calendar. %s"), error->message); } else if (e_client_is_readonly (E_CLIENT (client))) { switch (data->source_type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: report_error_idle (_("Selected calendar is read only, thus cannot create event there. Select other calendar, please."), NULL); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: report_error_idle (_("Selected task list is read only, thus cannot create task there. Select other task list, please."), NULL); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: report_error_idle (_("Selected memo list is read only, thus cannot create memo there. Select other memo list, please."), NULL); break; default: g_warn_if_reached (); break; } } else { gint i; ECalComponentDateTime dt, dt2; struct icaltimetype tt, tt2; struct _manage_comp *oldmc = NULL; #define cache_backend_prop(prop) { \ gchar *val = NULL; \ e_client_get_backend_property_sync (E_CLIENT (client), prop, &val, NULL, NULL); \ g_free (val); \ } /* precache backend properties, thus editor have them ready when needed */ cache_backend_prop (CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS); cache_backend_prop (CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS); cache_backend_prop (CAL_BACKEND_PROPERTY_DEFAULT_OBJECT); e_client_get_capabilities (E_CLIENT (client)); #undef cache_backend_prop /* set start day of the event as today, without time - easier than looking for a calendar's time zone */ tt = icaltime_today (); dt.value = &tt; dt.tzid = NULL; tt2 = tt; icaltime_adjust (&tt2, 1, 0, 0, 0); dt2.value = &tt2; dt2.tzid = NULL; for (i = 0; i < (uids ? uids->len : 0); i++) { CamelMimeMessage *message; ECalComponent *comp; ECalComponentText text; icalproperty *icalprop; icalcomponent *icalcomp; struct _manage_comp *mc; /* retrieve the message from the CamelFolder */ /* FIXME Not passing a GCancellable or GError. */ message = camel_folder_get_message_sync ( folder, g_ptr_array_index (uids, i), NULL, NULL); if (!message) { continue; } comp = e_cal_component_new (); switch (data->source_type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL); break; default: g_warn_if_reached (); break; } e_cal_component_set_uid (comp, camel_mime_message_get_message_id (message)); e_cal_component_set_dtstart (comp, &dt); if (data->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) { /* make it an all-day event */ e_cal_component_set_dtend (comp, &dt2); } /* set the summary */ text.value = camel_mime_message_get_subject (message); text.altrep = NULL; e_cal_component_set_summary (comp, &text); /* set all fields */ if (data->selected_text) { GSList sl; text.value = data->selected_text; text.altrep = NULL; sl.next = NULL; sl.data = &text; e_cal_component_set_description_list (comp, &sl); } else set_description (comp, message); if (data->with_attendees) { gchar *organizer; /* set actual user as organizer, to be able to change event's properties */ organizer = set_organizer (comp, data->folder); set_attendees (comp, message, organizer); g_free (organizer); } /* set attachment files */ set_attachments (E_CAL_CLIENT (client), comp, message); /* priority */ set_priority (comp, CAMEL_MIME_PART (message)); /* no need to increment a sequence number, this is a new component */ e_cal_component_abort_sequence (comp); icalcomp = e_cal_component_get_icalcomponent (comp); icalprop = icalproperty_new_x ("1"); icalproperty_set_x_name (icalprop, "X-EVOLUTION-MOVE-CALENDAR"); icalcomponent_add_property (icalcomp, icalprop); mc = g_new0 (struct _manage_comp, 1); mc->client = g_object_ref (client); mc->comp = g_object_ref (comp); g_mutex_init (&mc->mutex); g_cond_init (&mc->cond); mc->mails_count = uids->len; mc->mails_done = i + 1; /* Current task */ mc->editor_title = NULL; mc->can_continue = TRUE; if (oldmc) { /* Wait for user to quit the editor created in previous iteration * before displaying next one */ gboolean can_continue; g_mutex_lock (&oldmc->mutex); g_cond_wait (&oldmc->cond, &oldmc->mutex); g_mutex_unlock (&oldmc->mutex); can_continue = oldmc->can_continue; free_manage_comp_struct (oldmc); oldmc = NULL; if (!can_continue) break; } e_cal_client_get_object_sync ( E_CAL_CLIENT (client), icalcomponent_get_uid (icalcomp), NULL, &mc->stored_comp, NULL, NULL); /* Prioritize ahead of GTK+ redraws. */ g_idle_add_full ( G_PRIORITY_HIGH_IDLE, (GSourceFunc) do_manage_comp_idle, mc, NULL); oldmc = mc; g_object_unref (comp); g_object_unref (message); } /* Wait for the last editor and then clean up */ if (oldmc) { g_mutex_lock (&oldmc->mutex); g_cond_wait (&oldmc->cond, &oldmc->mutex); g_mutex_unlock (&oldmc->mutex); free_manage_comp_struct (oldmc); } } /* free memory */ if (client != NULL) g_object_unref (client); g_ptr_array_unref (uids); g_object_unref (folder); g_object_unref (data->client_cache); g_object_unref (data->source); g_free (data->selected_text); g_free (data); data = NULL; if (error != NULL) g_error_free (error); return TRUE; }
static void process_meeting (ECalendarView *cal_view, icalparameter_partstat status) { GList *selected; icalcomponent *clone; selected = e_calendar_view_get_selected_events (cal_view); if (selected) { ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; ECalComponent *comp = e_cal_component_new (); ReceiveData *r_data = g_new0 (ReceiveData, 1); gboolean recurring = FALSE; GThread *thread = NULL; GError *error = NULL; char *address = NULL; e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); address = itip_get_comp_attendee (comp, event->comp_data->client); if (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp)) recurring = TRUE; /* Free comp */ g_object_unref (comp); comp = NULL; clone = icalcomponent_new_clone (event->comp_data->icalcomp); change_status (clone, address, status); r_data->ecal = g_object_ref (event->comp_data->client); r_data->icalcomp = clone; if (recurring) { gint response; const char *arg; if (status == ICAL_PARTSTAT_ACCEPTED || status == ICAL_PARTSTAT_TENTATIVE) arg = "accept"; else arg = "decline"; response = e_error_run (NULL, "org.gnome.evolution.mail_shared_folder:recurrence", arg, NULL); if (response == GTK_RESPONSE_YES) { icalproperty *prop; const char *uid = icalcomponent_get_uid (r_data->icalcomp); prop = icalproperty_new_x ("All"); icalproperty_set_x_name (prop, "X-GW-RECUR-INSTANCES-MOD-TYPE"); icalcomponent_add_property (r_data->icalcomp, prop); prop = icalproperty_new_x (uid); icalproperty_set_x_name (prop, "X-GW-RECURRENCE-KEY"); icalcomponent_add_property (r_data->icalcomp, prop); } else if (response == GTK_RESPONSE_CANCEL) { finalize_receive_data (r_data); return; } } thread = g_thread_create ((GThreadFunc) receive_objects, r_data , FALSE, &error); if (!thread) { g_warning (G_STRLOC ": %s", error->message); g_error_free (error); } } }
icalproperty *icalproperty_new_tzuntil(struct icaltimetype v) { icalproperty *prop = icalproperty_new_x(icaltime_as_ical_string(v)); icalproperty_set_x_name(prop, "TZUNTIL"); return prop; }
icalproperty *icalproperty_new_tzidaliasof(const char *v) { icalproperty *prop = icalproperty_new_x(v); icalproperty_set_x_name(prop, "TZID-ALIAS-OF"); return prop; }
icalcomponent *icaltzutil_fetch_timezone(const char *location) { tzinfo type_cnts; size_t i, num_trans, num_chars, num_leaps, num_isstd, num_isgmt; size_t num_types = 0; size_t size; time_t trans; int dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx; icalcomponent *std_comp = NULL; const char *zonedir; FILE *f = NULL; char *full_path = NULL; time_t *transitions = NULL; char *r_trans = NULL, *temp; int *trans_idx = NULL; ttinfo *types = NULL; char *znames = NULL; leap *leaps = NULL; char *tzid = NULL; time_t start, end; int idx, prev_idx; icalcomponent *tz_comp = NULL, *comp = NULL, *dst_comp; icalproperty *icalprop; icaltimetype dtstart, icaltime; struct icalrecurrencetype ical_recur; if (icaltimezone_get_builtin_tzdata()) { goto error; } zonedir = icaltzutil_get_zone_directory(); if (!zonedir) { icalerror_set_errno(ICAL_FILE_ERROR); goto error; } size = strlen(zonedir) + strlen(location) + 2; full_path = (char *)malloc(size); if (full_path == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } snprintf(full_path, size, "%s/%s", zonedir, location); if ((f = fopen(full_path, "rb")) == 0) { icalerror_set_errno(ICAL_FILE_ERROR); goto error; } if (fseek(f, 20, SEEK_SET) != 0) { icalerror_set_errno(ICAL_FILE_ERROR); goto error; } EFREAD(&type_cnts, 24, 1, f); num_isgmt = (size_t)decode(type_cnts.ttisgmtcnt); num_leaps = (size_t)decode(type_cnts.leapcnt); num_chars = (size_t)decode(type_cnts.charcnt); num_trans = (size_t)decode(type_cnts.timecnt); num_isstd = (size_t)decode(type_cnts.ttisstdcnt); num_types = (size_t)decode(type_cnts.typecnt); transitions = calloc(num_trans, sizeof(time_t)); if (transitions == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } r_trans = calloc(num_trans, 4); if (r_trans == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } EFREAD(r_trans, 4, num_trans, f); temp = r_trans; if (num_trans) { trans_idx = calloc(num_trans, sizeof(int)); if (trans_idx == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } for (i = 0; i < num_trans; i++) { trans_idx[i] = fgetc(f); transitions[i] = (time_t) decode(r_trans); r_trans += 4; } } r_trans = temp; types = calloc(num_types, sizeof(ttinfo)); if (types == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } for (i = 0; i < num_types; i++) { unsigned char a[4]; int c; EFREAD(a, 4, 1, f); c = fgetc(f); types[i].isdst = (unsigned char)c; if ((c = fgetc(f)) < 0) { break; } types[i].abbr = (unsigned int)c; types[i].gmtoff = decode(a); } znames = (char *)malloc(num_chars); if (znames == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } EFREAD(znames, num_chars, 1, f); /* We got all the information which we need */ leaps = calloc(num_leaps, sizeof(leap)); if (leaps == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } for (i = 0; i < num_leaps; i++) { char c[4]; EFREAD(c, 4, 1, f); leaps[i].transition = (time_t)decode(c); EFREAD(c, 4, 1, f); leaps[i].change = decode(c); } for (i = 0; i < num_isstd; ++i) { int c = getc(f); types[i].isstd = c != 0; } while (i < num_types) { types[i++].isstd = 0; } for (i = 0; i < num_isgmt; ++i) { int c = getc(f); types[i].isgmt = c != 0; } while (i < num_types) { types[i++].isgmt = 0; } /* Read all the contents now */ for (i = 0; i < num_types; i++) { /* coverity[tainted_data] */ types[i].zname = zname_from_stridx(znames, types[i].abbr); } if (!_s_use_exact_timezones) { if (num_trans != 0) { find_transidx(transitions, types, trans_idx, (long int)num_trans, &stdidx, &dstidx); } else { stdidx = 0; } } tz_comp = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT); /* Add tzid property */ size = strlen(icaltimezone_tzid_prefix()) + strlen(location) + 1; tzid = (char *)malloc(size); if (tzid == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); goto error; } snprintf(tzid, size, "%s%s", icaltimezone_tzid_prefix(), location); icalprop = icalproperty_new_tzid(tzid); icalcomponent_add_property(tz_comp, icalprop); icalprop = icalproperty_new_x(location); icalproperty_set_x_name(icalprop, "X-LIC-LOCATION"); icalcomponent_add_property(tz_comp, icalprop); if (!_s_use_exact_timezones) { if (stdidx != -1) { if (num_trans != 0) { zidx = trans_idx[stdidx]; } else { zidx = 0; } std_comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT); icalprop = icalproperty_new_tzname(types[zidx].zname); icalcomponent_add_property(std_comp, icalprop); if (dstidx != -1) { zp_idx = trans_idx[stdidx-1]; } else { zp_idx = zidx; } /* DTSTART localtime uses TZOFFSETFROM UTC offset */ if (num_trans != 0) { trans = transitions[stdidx] + types[zp_idx].gmtoff; } else { trans = (time_t)types[zp_idx].gmtoff; } icaltime = icaltime_from_timet_with_zone(trans, 0, NULL); dtstart = icaltime; dtstart.year = 1970; dtstart.minute = dtstart.second = 0; icalprop = icalproperty_new_dtstart(dtstart); icalcomponent_add_property(std_comp, icalprop); /* If DST changes are present use RRULE */ if (dstidx != -1) { icalrecurrencetype_clear(&ical_recur); ical_recur.freq = ICAL_YEARLY_RECURRENCE; ical_recur.by_month[0] = icaltime.month; pos = calculate_pos(icaltime); pos < 0 ? (sign = -1): (sign = 1); ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime)); icalprop = icalproperty_new_rrule(ical_recur); icalcomponent_add_property(std_comp, icalprop); adjust_dtstart_day_to_rrule(std_comp, ical_recur); } icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff); icalcomponent_add_property(std_comp, icalprop); icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff); icalcomponent_add_property(std_comp, icalprop); icalcomponent_add_component(tz_comp, std_comp); } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); } if (dstidx != -1) { zidx = trans_idx[dstidx]; zp_idx = trans_idx[dstidx-1]; dst_comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); icalprop = icalproperty_new_tzname(types[zidx].zname); icalcomponent_add_property(dst_comp, icalprop); /* DTSTART localtime uses TZOFFSETFROM UTC offset */ trans = transitions[dstidx] + types[zp_idx].gmtoff; icaltime = icaltime_from_timet_with_zone(trans, 0, NULL); dtstart = icaltime; dtstart.year = 1970; dtstart.minute = dtstart.second = 0; icalprop = icalproperty_new_dtstart(dtstart); icalcomponent_add_property(dst_comp, icalprop); icalrecurrencetype_clear(&ical_recur); ical_recur.freq = ICAL_YEARLY_RECURRENCE; ical_recur.by_month[0] = icaltime.month; pos = calculate_pos(icaltime); pos < 0 ? (sign = -1): (sign = 1); ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime)); icalprop = icalproperty_new_rrule(ical_recur); icalcomponent_add_property(dst_comp, icalprop); adjust_dtstart_day_to_rrule(dst_comp, ical_recur); icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff); icalcomponent_add_property(dst_comp, icalprop); icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff); icalcomponent_add_property(dst_comp, icalprop); icalcomponent_add_component(tz_comp, dst_comp); } } else { /*exact vtimezones*/ prev_idx = 0; if (num_trans == 0) { prev_idx = idx = 0; } else { idx = trans_idx[0]; } start = 0; for (i = 1; i < num_trans; i++, start = end) { prev_idx = idx; idx = trans_idx[i]; end = transitions[i] + types[prev_idx].gmtoff; /* don't bother starting until the epoch */ if (0 > end) continue; if (types[prev_idx].isdst) { comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); } else { comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT); } icalprop = icalproperty_new_tzname(types[prev_idx].zname); icalcomponent_add_property(comp, icalprop); dtstart = icaltime_from_timet_with_zone(start, 0, NULL); icalprop = icalproperty_new_dtstart(dtstart); icalcomponent_add_property(comp, icalprop); icalprop = icalproperty_new_tzoffsetfrom(types[idx].gmtoff); icalcomponent_add_property(comp, icalprop); icalprop = icalproperty_new_tzoffsetto(types[prev_idx].gmtoff); icalcomponent_add_property(comp, icalprop); icalcomponent_add_component(tz_comp, comp); } /* finally, add a last zone with no end date */ if (types[idx].isdst) { comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); } else { comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT); } icalprop = icalproperty_new_tzname(types[idx].zname); icalcomponent_add_property(comp, icalprop); dtstart = icaltime_from_timet_with_zone(start, 0, NULL); icalprop = icalproperty_new_dtstart(dtstart); icalcomponent_add_property(comp, icalprop); icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff); icalcomponent_add_property(comp, icalprop); icalprop = icalproperty_new_tzoffsetto(types[idx].gmtoff); icalcomponent_add_property(comp, icalprop); icalcomponent_add_component(tz_comp, comp); } error: if (f) fclose(f); if (full_path) free(full_path); if (transitions) free(transitions); if (r_trans) free(r_trans); if (trans_idx) free(trans_idx); if (types) { for (i = 0; i < num_types; i++) { if (types[i].zname) { free(types[i].zname); } } free(types); } if (znames) free(znames); if (leaps) free(leaps); if (tzid) free(tzid); return tz_comp; }
void e_sendoptions_utils_fill_component (ESendOptionsDialog *sod, ECalComponent *comp) { int i = 1; icalproperty *prop; icalcomponent *icalcomp; ESendOptionsGeneral *gopts; ESendOptionsStatusTracking *sopts; gopts = sod->data->gopts; sopts = sod->data->sopts; e_cal_component_set_sequence (comp, &i); icalcomp = e_cal_component_get_icalcomponent (comp); if (e_sendoptions_get_need_general_options (sod)) { prop = icalproperty_new_x ((const char *) g_strdup_printf ("%d", gopts->priority)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-PRIORITY"); icalcomponent_add_property (icalcomp, prop); if (gopts->reply_enabled) { if (gopts->reply_convenient) prop = icalproperty_new_x ("convenient"); else prop = icalproperty_new_x ((const char *) g_strdup_printf ( "%d", gopts->reply_within)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-REPLY"); icalcomponent_add_property (icalcomp, prop); } if (gopts->expiration_enabled && gopts->expire_after) { prop = icalproperty_new_x ((const char *) g_strdup_printf ( "%d", gopts->expire_after)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-EXPIRE"); icalcomponent_add_property (icalcomp, prop); } if (gopts->delay_enabled) { struct icaltimetype temp; char *str; icaltimezone *zone = calendar_config_get_icaltimezone (); temp = icaltime_from_timet_with_zone (gopts->delay_until, FALSE, zone); str = icaltime_as_ical_string (temp); prop = icalproperty_new_x (str); g_free (str); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-DELAY"); icalcomponent_add_property (icalcomp, prop); } } if (sopts->tracking_enabled) prop = icalproperty_new_x ((const char *) g_strdup_printf ( "%d", sopts->track_when)); else prop = icalproperty_new_x ("0"); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-TRACKINFO"); icalcomponent_add_property (icalcomp, prop); prop = icalproperty_new_x ((const char *) g_strdup_printf ("%d", sopts->opened)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-OPENED"); icalcomponent_add_property (icalcomp, prop); prop = icalproperty_new_x ((const char *) g_strdup_printf ("%d", sopts->accepted)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-ACCEPTED"); icalcomponent_add_property (icalcomp, prop); prop = icalproperty_new_x ((const char *) g_strdup_printf ("%d", sopts->declined)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-DECLINED"); icalcomponent_add_property (icalcomp, prop); prop = icalproperty_new_x ((const char *) g_strdup_printf ("%d", sopts->completed)); icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-COMPLETED"); icalcomponent_add_property (icalcomp, prop); }
icalcomponent* icaltzutil_fetch_timezone (const char *location) { int ret = 0; FILE *f; tzinfo type_cnts; unsigned int num_trans, num_types, num_chars, num_leaps, num_isstd, num_isgmt; time_t *transitions = NULL; time_t trans; int *trans_idx = NULL, dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx, i; ttinfo *types = NULL; char *znames = NULL, *full_path, *tzid, *r_trans, *temp; leap *leaps = NULL; icalcomponent *tz_comp = NULL, *dst_comp = NULL, *std_comp = NULL; icalproperty *icalprop; icaltimetype dtstart, icaltime; struct icalrecurrencetype ical_recur; if (!zdir) set_zone_directory (); full_path = (char *) malloc (strlen (zdir) + strlen (location) + 2); sprintf (full_path,"%s/%s",zdir, location); if ((f = fopen (full_path, "rb")) == 0) { icalerror_set_errno (ICAL_FILE_ERROR); free (full_path); return NULL; } if ((ret = fseek (f, 20, SEEK_SET)) != 0) { icalerror_set_errno (ICAL_FILE_ERROR); goto error; } EFREAD(&type_cnts, 24, 1, f); num_isgmt = decode (type_cnts.ttisgmtcnt); num_leaps = decode (type_cnts.leapcnt); num_chars = decode (type_cnts.charcnt); num_trans = decode (type_cnts.timecnt); num_isstd = decode (type_cnts.ttisstdcnt); num_types = decode (type_cnts.typecnt); transitions = calloc (num_trans, sizeof (time_t)); r_trans = calloc (num_trans, 4); EFREAD(r_trans, 4, num_trans, f); temp = r_trans; if (num_trans) { trans_idx = calloc (num_trans, sizeof (int)); for (i = 0; i < num_trans; i++) { trans_idx [i] = fgetc (f); transitions [i] = decode (r_trans); r_trans += 4; } } free (temp); types = calloc (num_types, sizeof (ttinfo)); for (i = 0; i < num_types; i++) { unsigned char a [4]; int c; EFREAD(a, 4, 1, f); c = fgetc (f); types [i].isdst = c; if((c = fgetc (f)) < 0) { c = 0; break; } types [i].abbr = c; types [i].gmtoff = decode (a); } znames = (char *) malloc (num_chars); EFREAD(znames, num_chars, 1, f); /* We got all the information which we need */ leaps = calloc (num_leaps, sizeof (leap)); for (i = 0; i < num_leaps; i++) { char c [4]; EFREAD (c, 4, 1, f); leaps [i].transition = decode (c); EFREAD (c, 4, 1, f); leaps [i].change = decode (c); } for (i = 0; i < num_isstd; ++i) { int c = getc (f); types [i].isstd = c != 0; } while (i < num_types) types [i++].isstd = 0; for (i = 0; i < num_isgmt; ++i) { int c = getc (f); types [i].isgmt = c != 0; } while (i < num_types) types [i++].isgmt = 0; /* Read all the contents now */ for (i = 0; i < num_types; i++) types [i].zname = zname_from_stridx (znames, types [i].abbr); if (num_trans != 0) find_transidx (transitions, types, trans_idx, num_trans, &stdidx, &dstidx); else stdidx = 0; tz_comp = icalcomponent_new (ICAL_VTIMEZONE_COMPONENT); /* Add tzid property */ tzid = (char *) malloc (strlen (ical_tzid_prefix) + strlen (location) + 8); sprintf (tzid, "%sTzfile/%s", ical_tzid_prefix, location); icalprop = icalproperty_new_tzid (tzid); icalcomponent_add_property (tz_comp, icalprop); free (tzid); icalprop = icalproperty_new_x (location); icalproperty_set_x_name (icalprop, "X-LIC-LOCATION"); icalcomponent_add_property (tz_comp, icalprop); if (stdidx != -1) { if (num_trans != 0) zidx = trans_idx [stdidx]; else zidx = 0; std_comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT); icalprop = icalproperty_new_tzname (types [zidx].zname); icalcomponent_add_property (std_comp, icalprop); if (dstidx != -1) zp_idx = trans_idx [stdidx-1]; else zp_idx = zidx; /* DTSTART localtime uses TZOFFSETFROM UTC offset */ trans = transitions [stdidx] + types [zp_idx].gmtoff; icaltime = icaltime_from_timet (trans, 0); dtstart = icaltime; dtstart.year = 1970; dtstart.minute = dtstart.second = 0; icalprop = icalproperty_new_dtstart (dtstart); icalcomponent_add_property (std_comp, icalprop); /* If DST changes are present use RRULE */ if (dstidx != -1) { icalrecurrencetype_clear (&ical_recur); ical_recur.freq = ICAL_YEARLY_RECURRENCE; ical_recur.by_month [0] = icaltime.month; pos = calculate_pos (icaltime); pos < 0 ? (sign = -1): (sign = 1); ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime)); icalprop = icalproperty_new_rrule (ical_recur); icalcomponent_add_property (std_comp, icalprop); adjust_dtstart_day_to_rrule (std_comp, ical_recur); } icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff); icalcomponent_add_property (std_comp, icalprop); icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff); icalcomponent_add_property (std_comp, icalprop); icalcomponent_add_component (tz_comp, std_comp); } else icalerror_set_errno (ICAL_MALFORMEDDATA_ERROR); if (dstidx != -1) { zidx = trans_idx [dstidx]; zp_idx = trans_idx [dstidx-1]; dst_comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT); icalprop = icalproperty_new_tzname (types [zidx].zname); icalcomponent_add_property (dst_comp, icalprop); /* DTSTART localtime uses TZOFFSETFROM UTC offset */ trans = transitions [dstidx] + types [zp_idx].gmtoff; icaltime = icaltime_from_timet (trans, 0); dtstart = icaltime; dtstart.year = 1970; dtstart.minute = dtstart.second = 0; icalprop = icalproperty_new_dtstart (dtstart); icalcomponent_add_property (dst_comp, icalprop); icalrecurrencetype_clear (&ical_recur); ical_recur.freq = ICAL_YEARLY_RECURRENCE; ical_recur.by_month [0] = icaltime.month; pos = calculate_pos (icaltime); pos < 0 ? (sign = -1): (sign = 1); ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime)); icalprop = icalproperty_new_rrule (ical_recur); icalcomponent_add_property (dst_comp, icalprop); adjust_dtstart_day_to_rrule (dst_comp, ical_recur); icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff); icalcomponent_add_property (dst_comp, icalprop); icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff); icalcomponent_add_property (dst_comp, icalprop); icalcomponent_add_component (tz_comp, dst_comp); } error: if (f) fclose (f); if (transitions) free (transitions); if (trans_idx) free (trans_idx); if (types) { for (i = 0; i < num_types; i++) if (types [i].zname) free (types [i].zname); free (types); } if (znames) free (znames); free (full_path); if (leaps) free (leaps); return tz_comp; }