struct icalperiodtype icalspanlist_next_free_time(icalspanlist *sl, struct icaltimetype t) { pvl_elem itr; struct icalperiodtype period; struct icaltime_span *s; time_t rangett = icaltime_as_timet(t); period.start = icaltime_null_time(); period.end = icaltime_null_time(); itr = pvl_head(sl->spans); s = (struct icaltime_span *)pvl_data(itr); if (s == 0) { /* No elements in span */ return period; } /* Is the reference time before the first span? If so, assume that the reference time is free */ if (rangett < s->start) { /* End of period is start of first span if span is busy, end of the span if it is free */ period.start = t; if (s->is_busy == 1) { period.end = icaltime_from_timet(s->start, 0); } else { period.end = icaltime_from_timet(s->end, 0); } return period; } /* Otherwise, find the first free span that contains the reference time. */ for (itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { s = (struct icaltime_span *)pvl_data(itr); if (s->is_busy == 0 && s->start >= rangett && (rangett < s->end || s->end == s->start)) { if (rangett < s->start) { period.start = icaltime_from_timet(s->start, 0); } else { period.start = icaltime_from_timet(rangett, 0); } period.end = icaltime_from_timet(s->end, 0); return period; } } period.start = icaltime_null_time(); period.end = icaltime_null_time(); return period; }
struct icalperiodtype icalperiodtype_null_period(void) { struct icalperiodtype p; p.start = icaltime_null_time(); p.end = icaltime_null_time(); p.duration = icaldurationtype_null_duration(); return p; }
struct icalperiodtype icalperiodtype_from_string (const char* str) { struct icalperiodtype p, null_p; char *s = icalmemory_strdup(str); char *start, *end = s; icalerrorstate es; /* Errors are normally generated in the following code, so save the error state for resoration later */ icalerrorenum e = icalerrno; p.start = p.end = icaltime_null_time(); p.duration = icaldurationtype_from_int(0); null_p = p; if(s == 0) goto error; start = s; end = strchr(s, '/'); if(end == 0) goto error; *end = 0; end++; p.start = icaltime_from_string(start); if (icaltime_is_null_time(p.start)) goto error; es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); p.end = icaltime_from_string(end); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); if (icaltime_is_null_time(p.end)) { p.duration = icaldurationtype_from_string(end); if(icaldurationtype_as_int(p.duration) == 0) goto error; } icalerrno = e; icalmemory_free_buffer(s); return p; error: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); if (s) icalmemory_free_buffer (s); return null_p; }
int main (int argc, char **argv) { gint error = 0; JanaTime *jtime; icaltimetype itime; icaltimezone *zone = icaltimezone_get_builtin_timezone ( "Europe/London"); /* Test DST conversions */ itime = icaltime_null_time (); itime.second = 0; itime.minute = 0; itime.hour = 2; itime.day = 1; itime.month = 1; itime.year = 2007; itime = icaltime_convert_to_zone (itime, zone); g_type_init (); jtime = jana_ecal_time_new_from_icaltime (&itime); /*g_debug ("%s time: %d/%d/%d, %d:%02d %s", jana_time_get_tzname (jtime), jana_time_get_day (jtime), jana_time_get_month (jtime), jana_time_get_year (jtime), jana_time_get_hours (jtime), jana_time_get_minutes (jtime), jana_time_get_daylight (jtime) ? "DST" : ""); g_debug ("Setting time forward to BST");*/ jana_time_set_month (jtime, 7); if ((jana_time_get_hours (jtime) != 3) || (!jana_time_get_daylight (jtime))) error = 1; /*g_debug ("%s time: %d/%d/%d, %d:%02d %s", jana_time_get_tzname (jtime), jana_time_get_day (jtime), jana_time_get_month (jtime), jana_time_get_year (jtime), jana_time_get_hours (jtime), jana_time_get_minutes (jtime), jana_time_get_daylight (jtime) ? "DST" : "");*/ g_object_unref (jtime); if (error) g_warning ("Error (%d)", error); else g_message ("Success"); return error; }
struct icaltriggertype icaltriggertype_from_string(const char* str) { struct icaltriggertype tr, null_tr; int old_ieaf = icalerror_errors_are_fatal; tr.time= icaltime_null_time(); tr.duration = icaldurationtype_from_int(0); null_tr = tr; if(str == 0) goto error; icalerror_errors_are_fatal = 0; tr.time = icaltime_from_string(str); icalerror_errors_are_fatal = old_ieaf; if (icaltime_is_null_time(tr.time)){ tr.duration = icaldurationtype_from_string(str); if(icaldurationtype_as_int(tr.duration) == 0) goto error; } return tr; error: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return null_tr; }
struct icaltriggertype icaltriggertype_from_int(const int reltime) { struct icaltriggertype tr; tr.time = icaltime_null_time(); tr.duration = icaldurationtype_from_int(reltime); return tr; }
static void cell_date_edit_text_set_value (ECellText *cell, ETableModel *model, gint col, gint row, const gchar *text) { ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell); ETimeParseStatus status; struct tm tmp_tm; ECellDateEditValue *value; gboolean is_date = TRUE; /* Try to parse just a date first. If the value is only a date, we * use a DATE value. */ status = e_time_parse_date (text, &tmp_tm); if (status == E_TIME_PARSE_INVALID) { is_date = FALSE; status = e_time_parse_date_and_time (text, &tmp_tm); if (status == E_TIME_PARSE_INVALID) { show_date_warning (ecd); return; } } if (status == E_TIME_PARSE_NONE) { value = NULL; } else { ECellDateEditValue dv; dv.tt = icaltime_null_time (); dv.tt.year = tmp_tm.tm_year + 1900; dv.tt.month = tmp_tm.tm_mon + 1; dv.tt.day = tmp_tm.tm_mday; dv.tt.hour = tmp_tm.tm_hour; dv.tt.minute = tmp_tm.tm_min; dv.tt.second = tmp_tm.tm_sec; dv.tt.is_date = is_date; /* FIXME: We assume it is being set to the current timezone. * Is that OK? */ if (is_date) { dv.zone = NULL; } else { dv.zone = e_cell_date_edit_text_get_timezone (ecd); } value = &dv; } e_table_model_set_value_at (model, col, row, value); }
struct icaltriggertype icalvalue_get_trigger(const icalvalue* impl) { struct icaltriggertype tr; icalerror_check_arg( (impl!=0),"value"); icalerror_check_arg( (impl!=0),"value"); if(impl->kind == ICAL_DATETIME_VALUE){ tr.duration = icaldurationtype_from_int(0); tr.time = impl->data.v_time; } else if(impl->kind == ICAL_DURATION_VALUE){ tr.time = icaltime_null_time(); tr.duration = impl->data.v_duration; } else { tr.duration = icaldurationtype_from_int(0); tr.time = icaltime_null_time(); icalerror_set_errno(ICAL_BADARG_ERROR); } return tr; }
struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(const icalvalue* impl) { struct icaldatetimeperiodtype dtp; icalerror_check_arg( (impl!=0),"value"); icalerror_check_value_type(value, ICAL_DATETIMEPERIOD_VALUE); if(impl->kind == ICAL_DATETIME_VALUE){ dtp.period = icalperiodtype_null_period(); dtp.time = impl->data.v_time; } else if(impl->kind == ICAL_PERIOD_VALUE) { dtp.period = impl->data.v_period; dtp.time = icaltime_null_time(); } else { dtp.period = icalperiodtype_null_period(); dtp.time = icaltime_null_time(); icalerror_set_errno(ICAL_BADARG_ERROR); } return dtp; }
static struct icaltimetype get_last_modified (icalcomponent *component) { icalcomponent *inner = icalcomponent_get_inner (component); icalproperty *prop; prop = icalcomponent_get_first_property (inner, ICAL_LASTMODIFIED_PROPERTY); if (prop == 0) { return icaltime_null_time (); } return icalproperty_get_lastmodified (prop); }
/** * time_from_isodate: * @str: Date/time value in ISO 8601 format. * * Converts an ISO 8601 UTC time string into a time_t value. * * Return value: Time_t corresponding to the specified ISO string. * Note that we only allow UTC times at present. **/ time_t time_from_isodate (const char *str) { struct icaltimetype tt = icaltime_null_time (); icaltimezone *utc_zone; int len, i; g_return_val_if_fail (str != NULL, -1); /* yyyymmdd[Thhmmss[Z]] */ len = strlen (str); if (!(len == 8 || len == 15 || len == 16)) return -1; for (i = 0; i < len; i++) if (!((i != 8 && i != 15 && isdigit (str[i])) || (i == 8 && str[i] == 'T') || (i == 15 && str[i] == 'Z'))) return -1; #define digit_at(x,y) (x[y] - '0') tt.year = digit_at (str, 0) * 1000 + digit_at (str, 1) * 100 + digit_at (str, 2) * 10 + digit_at (str, 3); tt.month = digit_at (str, 4) * 10 + digit_at (str, 5); tt.day = digit_at (str, 6) * 10 + digit_at (str, 7); if (len > 8) { tt.hour = digit_at (str, 9) * 10 + digit_at (str, 10); tt.minute = digit_at (str, 11) * 10 + digit_at (str, 12); tt.second = digit_at (str, 13) * 10 + digit_at (str, 14); } utc_zone = icaltimezone_get_utc_timezone (); return icaltime_as_timet_with_zone (tt, utc_zone); }
/* Event handler for day groups in the month item. A button press makes the calendar jump to the * selected day and destroys the Go-to dialog box. */ static void ecal_event (ECalendarItem *calitem, gpointer user_data) { GoToDialog *dlg = user_data; GDate start_date, end_date; struct icaltimetype tt = icaltime_null_time (); time_t et; e_calendar_item_get_selection (calitem, &start_date, &end_date); tt.year = g_date_get_year (&start_date); tt.month = g_date_get_month (&start_date); tt.day = g_date_get_day (&start_date); et = icaltime_as_timet_with_zone (tt, gnome_calendar_get_timezone (dlg->gcal)); gnome_calendar_goto (dlg->gcal, et); gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_NONE); /* gnome_dialog_close (GNOME_DIALOG (dlg->dialog)); */ }
struct icaltriggertype icaltriggertype_from_string(const char* str) { struct icaltriggertype tr, null_tr; icalerrorstate es = ICAL_ERROR_DEFAULT; icalerrorenum e; tr.time= icaltime_null_time(); tr.duration = icaldurationtype_from_int(0); null_tr = tr; /* Suppress errors so a failure in icaltime_from_string() does not cause an abort */ es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); if(str == 0) goto error; icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); e = icalerrno; icalerror_set_errno(ICAL_NO_ERROR); tr.time = icaltime_from_string(str); if (icaltime_is_null_time(tr.time)){ tr.duration = icaldurationtype_from_string(str); if (icaldurationtype_is_bad_duration(tr.duration)) goto error; } icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); icalerror_set_errno(e); return tr; error: icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return tr; }
static void clear_comp_info (ECalComponentPreview *preview) { ECalComponentPreviewPrivate *priv; g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); priv = preview->priv; g_free (priv->cal_uid); priv->cal_uid = NULL; g_free (priv->comp_uid); priv->comp_uid = NULL; priv->comp_last_modified = icaltime_null_time (); priv->comp_sequence = -1; g_clear_object (&priv->client); g_clear_object (&priv->comp); if (priv->timezone) { icaltimezone_free (priv->timezone, 1); priv->timezone = NULL; } }
/* Stores information about actually shown component and * returns whether component in the preview changed */ static gboolean update_comp_info (ECalComponentPreview *preview, ECalClient *client, ECalComponent *comp, icaltimezone *zone, gboolean use_24_hour_format) { ECalComponentPreviewPrivate *priv; gboolean changed; g_return_val_if_fail (preview != NULL, TRUE); g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), TRUE); priv = preview->priv; if (!E_IS_CAL_COMPONENT (comp) || !E_IS_CAL_CLIENT (client)) { changed = !priv->cal_uid; clear_comp_info (preview); } else { ESource *source; const gchar *uid; gchar *cal_uid; gchar *comp_uid; struct icaltimetype comp_last_modified, *itm = NULL; gint *sequence = NULL; gint comp_sequence; source = e_client_get_source (E_CLIENT (client)); cal_uid = g_strdup (e_source_get_uid (source)); e_cal_component_get_uid (comp, &uid); comp_uid = g_strdup (uid); e_cal_component_get_last_modified (comp, &itm); if (itm) { comp_last_modified = *itm; e_cal_component_free_icaltimetype (itm); } else comp_last_modified = icaltime_null_time (); e_cal_component_get_sequence (comp, &sequence); if (sequence) { comp_sequence = *sequence; e_cal_component_free_sequence (sequence); } else comp_sequence = 0; changed = !priv->cal_uid || !priv->comp_uid || !cal_uid || !comp_uid || !g_str_equal (priv->cal_uid, cal_uid) || !g_str_equal (priv->comp_uid, comp_uid) || priv->comp_sequence != comp_sequence || icaltime_compare (priv->comp_last_modified, comp_last_modified) != 0; clear_comp_info (preview); priv->cal_uid = cal_uid; priv->comp_uid = comp_uid; priv->comp_sequence = comp_sequence; priv->comp_last_modified = comp_last_modified; priv->comp = g_object_ref (comp); priv->client = g_object_ref (client); priv->timezone = icaltimezone_copy (zone); priv->use_24_hour_format = use_24_hour_format; } return changed; }
void create_new_component_with_va_args() { icalcomponent* calendar; struct icaltimetype atime = icaltime_from_timet( time(0),0); struct icaldatetimeperiodtype rtime; rtime.period.start = icaltime_from_timet( time(0),0); rtime.period.end = icaltime_from_timet( time(0),0); rtime.period.end.hour++; rtime.time = icaltime_null_time(); calendar = icalcomponent_vanew( ICAL_VCALENDAR_COMPONENT, icalproperty_new_version("2.0"), icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"), icalcomponent_vanew( ICAL_VTIMEZONE_COMPONENT, icalproperty_new_tzid("America/New_York"), icalcomponent_vanew( ICAL_XDAYLIGHT_COMPONENT, icalproperty_new_dtstart(atime), icalproperty_new_rdate(rtime), icalproperty_new_tzoffsetfrom(-4.0), icalproperty_new_tzoffsetto(-5.0), icalproperty_new_tzname("EST"), NULL ), icalcomponent_vanew( ICAL_XSTANDARD_COMPONENT, icalproperty_new_dtstart(atime), icalproperty_new_rdate(rtime), icalproperty_new_tzoffsetfrom(-5.0), icalproperty_new_tzoffsetto(-4.0), icalproperty_new_tzname("EST"), NULL ), NULL ), icalcomponent_vanew( ICAL_VEVENT_COMPONENT, icalproperty_new_dtstamp(atime), icalproperty_new_uid("guid-1.host1.com"), icalproperty_vanew_organizer( "*****@*****.**", icalparameter_new_role(ICAL_ROLE_CHAIR), NULL ), icalproperty_vanew_attendee( "*****@*****.**", icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT), icalparameter_new_rsvp(ICAL_RSVP_TRUE), icalparameter_new_cutype(ICAL_CUTYPE_GROUP), NULL ), icalproperty_new_description("Project XYZ Review Meeting"), icalproperty_new_categories("MEETING"), icalproperty_new_class(ICAL_CLASS_PUBLIC), icalproperty_new_created(atime), icalproperty_new_summary("XYZ Project Review"), icalproperty_vanew_dtstart( atime, icalparameter_new_tzid("America/New_York"), NULL ), icalproperty_vanew_dtend( atime, icalparameter_new_tzid("America/New_York"), NULL ), icalproperty_new_location("1CP Conference Room 4350"), NULL ), NULL ); ok("creating a complex vcalendar", (calendar != NULL)); if (VERBOSE && calendar) printf("%s\n",icalcomponent_as_ical_string(calendar)); icalcomponent_free(calendar); }
/* * Construct an iCalendar property value from XML content. */ static icalvalue *xml_element_to_icalvalue(xmlNodePtr xtype, icalvalue_kind kind) { icalvalue *value = NULL; xmlNodePtr node; xmlChar *content = NULL; switch (kind) { case ICAL_GEO_VALUE: { struct icalgeotype geo; node = xmlFirstElementChild(xtype); if (!node) { syslog(LOG_WARNING, "Missing <latitude> XML element"); break; } else if (xmlStrcmp(node->name, BAD_CAST "latitude")) { syslog(LOG_WARNING, "Expected <latitude> XML element, received %s", node->name); break; } content = xmlNodeGetContent(node); geo.lat = atof((const char *) content); node = xmlNextElementSibling(node); if (!node) { syslog(LOG_WARNING, "Missing <longitude> XML element"); break; } else if (xmlStrcmp(node->name, BAD_CAST "longitude")) { syslog(LOG_WARNING, "Expected <longitude> XML element, received %s", node->name); break; } xmlFree(content); content = xmlNodeGetContent(node); geo.lon = atof((const char *) content); value = icalvalue_new_geo(geo); break; } case ICAL_PERIOD_VALUE: { struct icalperiodtype p; p.start = p.end = icaltime_null_time(); p.duration = icaldurationtype_from_int(0); node = xmlFirstElementChild(xtype); if (!node) { syslog(LOG_WARNING, "Missing <start> XML element"); break; } else if (xmlStrcmp(node->name, BAD_CAST "start")) { syslog(LOG_WARNING, "Expected <start> XML element, received %s", node->name); break; } content = xmlNodeGetContent(node); p.start = icaltime_from_string((const char *) content); if (icaltime_is_null_time(p.start)) break; node = xmlNextElementSibling(node); if (!node) { syslog(LOG_WARNING, "Missing <end> / <duration> XML element"); break; } else if (!xmlStrcmp(node->name, BAD_CAST "end")) { xmlFree(content); content = xmlNodeGetContent(node); p.end = icaltime_from_string((const char *) content); if (icaltime_is_null_time(p.end)) break; } else if (!xmlStrcmp(node->name, BAD_CAST "duration")) { xmlFree(content); content = xmlNodeGetContent(node); p.duration = icaldurationtype_from_string((const char *) content); if (icaldurationtype_as_int(p.duration) == 0) break; } else { syslog(LOG_WARNING, "Expected <end> / <duration> XML element, received %s", node->name); break; } value = icalvalue_new_period(p); break; } case ICAL_RECUR_VALUE: { struct buf rrule = BUF_INITIALIZER; struct hash_table byrules; struct icalrecurrencetype rt; char *sep = ""; construct_hash_table(&byrules, 10, 1); /* create an iCal RRULE string from xCal <recur> sub-elements */ for (node = xmlFirstElementChild(xtype); node; node = xmlNextElementSibling(node)) { content = xmlNodeGetContent(node); if (!xmlStrncmp(node->name, BAD_CAST "by", 2)) { /* BY* rules can have a list of values - assemble them using a hash table */ struct buf *vals = hash_lookup((const char *) node->name, &byrules); if (vals) { /* append this value to existing list */ buf_printf(vals, ",%s", (char *) content); } else { /* create new list with this valiue */ vals = xzmalloc(sizeof(struct buf)); buf_setcstr(vals, (char *) content); hash_insert((char *) node->name, vals, &byrules); } } else { /* single value rpart */ buf_printf(&rrule, "%s%s=%s", sep, ucase((char *) node->name), (char *) content); sep = ";"; } xmlFree(content); content = NULL; } /* append the BY* rules to RRULE buffer */ hash_enumerate(&byrules, (void (*)(const char*, void*, void*)) &append_byrule, &rrule); free_hash_table(&byrules, NULL); /* parse our iCal RRULE string */ rt = icalrecurrencetype_from_string(buf_cstring(&rrule)); buf_free(&rrule); if (rt.freq != ICAL_NO_RECURRENCE) value = icalvalue_new_recur(rt); break; } case ICAL_REQUESTSTATUS_VALUE: { struct icalreqstattype rst = { ICAL_UNKNOWN_STATUS, NULL, NULL }; short maj, min; node = xmlFirstElementChild(xtype); if (!node) { syslog(LOG_WARNING, "Missing <code> XML element"); break; } else if (xmlStrcmp(node->name, BAD_CAST "code")) { syslog(LOG_WARNING, "Expected <code> XML element, received %s", node->name); break; } content = xmlNodeGetContent(node); if (sscanf((const char *) content, "%hd.%hd", &maj, &min) == 2) { rst.code = icalenum_num_to_reqstat(maj, min); } if (rst.code == ICAL_UNKNOWN_STATUS) { syslog(LOG_WARNING, "Unknown request-status code"); break; } node = xmlNextElementSibling(node); if (!node) { syslog(LOG_WARNING, "Missing <description> XML element"); break; } else if (xmlStrcmp(node->name, BAD_CAST "description")) { syslog(LOG_WARNING, "Expected <description> XML element, received %s", node->name); break; } xmlFree(content); content = xmlNodeGetContent(node); rst.desc = (const char *) content; node = xmlNextElementSibling(node); if (node) { if (xmlStrcmp(node->name, BAD_CAST "data")) { syslog(LOG_WARNING, "Expected <data> XML element, received %s", node->name); break; } xmlFree(content); content = xmlNodeGetContent(node); rst.debug = (const char *) content; } value = icalvalue_new_requeststatus(rst); break; } case ICAL_UTCOFFSET_VALUE: { int n, utcoffset, hours, minutes, seconds = 0; char sign; content = xmlNodeGetContent(xtype); n = sscanf((const char *) content, "%c%02d:%02d:%02d", &sign, &hours, &minutes, &seconds); if (n < 3) { syslog(LOG_WARNING, "Unexpected utc-offset format"); break; } utcoffset = hours*3600 + minutes*60 + seconds; if (sign == '-') utcoffset = -utcoffset; value = icalvalue_new_utcoffset(utcoffset); break; } default: content = xmlNodeGetContent(xtype); value = icalvalue_new_from_string(kind, (const char *) content); break; } if (content) xmlFree(content); return value; }
void test_recur_file() { icalset *cin = 0; struct icaltimetype next; icalcomponent *itr; icalproperty *desc, *dtstart, *rrule; struct icalrecurrencetype recur; icalrecur_iterator* ritr; time_t tt; char* file; int num_recurs_found = 0; icalfileset_options options = {O_RDONLY, 0644, 0}; icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL); #ifndef WIN32 signal(SIGALRM,sig_alrm); #endif file = getenv("ICAL_RECUR_FILE"); if (!file) file = TEST_DATADIR "/recur.txt"; #ifndef WIN32 alarm(15); /* to get file lock */ #endif cin = icalset_new(ICAL_FILE_SET, file, &options); #ifndef WIN32 alarm(0); #endif ok("opening file with recurring events", (cin!=NULL)); assert(cin!=NULL); for (itr = icalfileset_get_first_component(cin); itr != 0; itr = icalfileset_get_next_component(cin)){ int badcomp = 0; int expected_events = 0; char msg[128]; struct icaltimetype start = icaltime_null_time(); struct icaltimetype startmin = icaltime_from_timet(1,0); struct icaltimetype endmax = icaltime_null_time(); const char *desc_str = "malformed component"; desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY); dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY); rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY); if (desc) { desc_str = icalproperty_get_description(desc); } ok((char*)desc_str, !(desc == 0 || dtstart == 0 || rrule == 0)); if (desc == 0 || dtstart == 0 || rrule == 0) { badcomp = 1; if (VERBOSE) { printf("\n******** Error in input component ********\n"); printf("The following component is malformed:\n %s\n", desc_str); } continue; } if (VERBOSE) { printf("\n\n#### %s\n",desc_str); printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule))); } recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); ritr = icalrecur_iterator_new(recur,start); tt = icaltime_as_timet(start); if (VERBOSE) printf("#### %s\n",ctime(&tt )); icalrecur_iterator_free(ritr); for(ritr = icalrecur_iterator_new(recur,start), next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next); next = icalrecur_iterator_next(ritr)){ tt = icaltime_as_timet(next); if (VERBOSE) printf(" %s",ctime(&tt )); } icalrecur_iterator_free(ritr); num_recurs_found = 0; expected_events = get_expected_numevents(itr); icalcomponent_foreach_recurrence(itr, startmin, endmax, recur_callback, &num_recurs_found); sprintf(msg," expecting total of %d events", expected_events); int_is(msg, num_recurs_found, expected_events); } icalset_free(cin); }
/* Create a new component */ void create_new_component() { icalcomponent* calendar; icalcomponent* timezone; icalcomponent* tzc; icalcomponent* event; struct icaltimetype atime = icaltime_from_timet( 1023398689, 0); struct icaldatetimeperiodtype rtime; icalproperty* property; char *calendar_as_string; rtime.period.start = icaltime_from_timet( 1023398689,0); rtime.period.end = icaltime_from_timet( 1023409689,0); rtime.period.end.hour++; rtime.time = icaltime_null_time(); /* Create calendar and add properties */ calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); icalcomponent_add_property( calendar, icalproperty_new_version("2.0") ); icalcomponent_add_property( calendar, icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN") ); /* Create a timezone object and add it to the calendar */ timezone = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT); icalcomponent_add_property( timezone, icalproperty_new_tzid("America/New_York") ); /* Add a sub-component of the timezone */ tzc = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); icalcomponent_add_property( tzc, icalproperty_new_dtstart(atime) ); icalcomponent_add_property( tzc, icalproperty_new_rdate(rtime) ); icalcomponent_add_property( tzc, icalproperty_new_tzoffsetfrom(-5*3600) ); icalcomponent_add_property( tzc, icalproperty_new_tzoffsetto(-4*3600) ); icalcomponent_add_property( tzc, icalproperty_new_tzname("EST") ); icalcomponent_add_component(timezone,tzc); icalcomponent_add_component(calendar,timezone); /* Add a second subcomponent */ tzc = icalcomponent_new(ICAL_XSTANDARD_COMPONENT); icalcomponent_add_property( tzc, icalproperty_new_dtstart(atime) ); icalcomponent_add_property( tzc, icalproperty_new_rdate(rtime) ); icalcomponent_add_property( tzc, icalproperty_new_tzoffsetfrom(-4*3600) ); icalcomponent_add_property( tzc, icalproperty_new_tzoffsetto(-5*3600) ); icalcomponent_add_property( tzc, icalproperty_new_tzname("EST") ); icalcomponent_add_component(timezone,tzc); /* Add an event */ event = icalcomponent_new(ICAL_VEVENT_COMPONENT); icalcomponent_add_property( event, icalproperty_new_dtstamp(atime) ); icalcomponent_add_property( event, icalproperty_new_uid("guid-1.host1.com") ); /* add a property that has parameters */ property = icalproperty_new_organizer("*****@*****.**"); icalproperty_add_parameter( property, icalparameter_new_role(ICAL_ROLE_CHAIR) ); icalcomponent_add_property(event,property); /* add another property that has parameters */ property = icalproperty_new_attendee("*****@*****.**"); icalproperty_add_parameter( property, icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT) ); icalproperty_add_parameter( property, icalparameter_new_rsvp(ICAL_RSVP_TRUE) ); icalproperty_add_parameter( property, icalparameter_new_cutype(ICAL_CUTYPE_GROUP) ); icalcomponent_add_property(event,property); /* more properties */ icalcomponent_add_property( event, icalproperty_new_description("Project XYZ Review Meeting") ); icalcomponent_add_property( event, icalproperty_new_categories("MEETING") ); icalcomponent_add_property( event, icalproperty_new_class(ICAL_CLASS_PRIVATE) ); icalcomponent_add_property( event, icalproperty_new_created(atime) ); icalcomponent_add_property( event, icalproperty_new_summary("XYZ Project Review") ); property = icalproperty_new_dtstart(atime); icalproperty_add_parameter( property, icalparameter_new_tzid("America/New_York") ); icalcomponent_add_property(event,property); property = icalproperty_new_dtend(atime); icalproperty_add_parameter( property, icalparameter_new_tzid("America/New_York") ); icalcomponent_add_property(event,property); icalcomponent_add_property( event, icalproperty_new_location("1CP Conference Room 4350") ); icalcomponent_add_component(calendar,event); calendar_as_string = icalcomponent_as_ical_string(calendar); is("build large, complex component", calendar_as_string, create_new_component_str); if (VERBOSE && calendar) printf("%s\n",icalcomponent_as_ical_string(calendar)); if (calendar) icalcomponent_free(calendar); }
static void annum_shell_view_date_navigator_selection_changed_cb (AnnumShellView * self, ECalendarItem * calitem) { AnnumShellContent *prox_shell_content; GnomeCalendarViewType switch_to; GnomeCalendarViewType view_type; GnomeCalendar *calendar; ECalModel *model; GDate start_date, end_date; GDate new_start_date, new_end_date; icaltimetype tt; icaltimezone *timezone; time_t start, end, new_time; gboolean starts_on_week_start_day; gint new_days_shown; gint week_start_day; prox_shell_content = self->priv->prox_shell_content; calendar = annum_shell_content_get_calendar (prox_shell_content); model = gnome_calendar_get_model (calendar); view_type = gnome_calendar_get_view (calendar); switch_to = view_type; timezone = e_cal_model_get_timezone (model); week_start_day = e_cal_model_get_week_start_day (model); e_cal_model_get_time_range (model, &start, &end); time_to_gdate_with_zone (&start_date, start, timezone); time_to_gdate_with_zone (&end_date, end, timezone); if (view_type == GNOME_CAL_MONTH_VIEW) { EWeekView *week_view; ECalendarView *calendar_view; gboolean multi_week_view; gboolean compress_weekend; calendar_view = gnome_calendar_get_calendar_view (calendar, GNOME_CAL_MONTH_VIEW); week_view = E_WEEK_VIEW (calendar_view); multi_week_view = e_week_view_get_multi_week_view (week_view); compress_weekend = e_week_view_get_compress_weekend (week_view); if (week_start_day == 0 && (!multi_week_view || compress_weekend)) g_date_add_days (&start_date, 1); } g_date_subtract_days (&end_date, 1); e_calendar_item_get_selection (calitem, &new_start_date, &new_end_date); /* There used to be a check here to make sure the rest of the * code only ran when the date actually changed. We do not * this to simplify always having three columns for the day * view. */ new_days_shown = g_date_get_julian (&new_end_date) - g_date_get_julian (&new_start_date) + 1; /* If a complete week is selected we show the week view. * Note that if weekends are compressed and the week start * day is set to Sunday, we don't actually show complete * weeks in the week view, so this may need tweaking. */ starts_on_week_start_day = (g_date_get_weekday (&new_start_date) % 7 == week_start_day); /* Update selection to be in the new time range. */ tt = icaltime_null_time (); tt.year = g_date_get_year (&new_start_date); tt.month = g_date_get_month (&new_start_date); tt.day = g_date_get_day (&new_start_date); new_time = icaltime_as_timet_with_zone (tt, timezone); /* Switch views as appropriate, and change the number of * days or weeks shown. */ if (new_days_shown > 9) { if (view_type != GNOME_CAL_LIST_VIEW) { ECalendarView *calendar_view; calendar_view = gnome_calendar_get_calendar_view (calendar, GNOME_CAL_MONTH_VIEW); e_week_view_set_weeks_shown (E_WEEK_VIEW (calendar_view), (new_days_shown + 6) / 7); switch_to = GNOME_CAL_MONTH_VIEW; } } else if (new_days_shown == 7 && starts_on_week_start_day) switch_to = GNOME_CAL_WEEK_VIEW; else { ECalendarView *calendar_view; calendar_view = gnome_calendar_get_calendar_view (calendar, GNOME_CAL_DAY_VIEW); /* We always show three days */ if (new_days_shown == 1) new_days_shown = 3; e_day_view_set_days_shown (E_DAY_VIEW (calendar_view), new_days_shown); if (new_days_shown != 5 || !starts_on_week_start_day) switch_to = GNOME_CAL_DAY_VIEW; else if (view_type != GNOME_CAL_WORK_WEEK_VIEW) switch_to = GNOME_CAL_DAY_VIEW; } /* Make the views display things properly. */ gnome_calendar_update_view_times (calendar, new_time); gnome_calendar_set_view (calendar, switch_to); gnome_calendar_set_range_selected (calendar, TRUE); gnome_calendar_notify_dates_shown_changed (calendar); g_signal_emit (self, signals[DATE_CHANGED], 0, switch_to); }
/** @brief Contructor. * * Create a time from an ISO format string. * * @todo If the given string specifies a DATE-TIME not in UTC, there * is no way to know if this is a floating time or really refers to a * timezone. We should probably add a new constructor: * icaltime_from_string_with_zone() */ struct icaltimetype icaltime_from_string(const char *str) { struct icaltimetype tt = icaltime_null_time(); size_t size; icalerror_check_arg_re(str != 0, "str", icaltime_null_time()); size = strlen(str); if ((size == 15) || (size == 19)) { /* floating time with/without separators */ tt.is_utc = 0; tt.is_date = 0; } else if ((size == 16) || (size == 20)) { /* UTC time, ends in 'Z' */ if ((str[15] != 'Z') && (str[19] != 'Z')) goto FAIL; tt.is_utc = 1; tt.zone = icaltimezone_get_utc_timezone(); tt.is_date = 0; } else if ((size == 8) || (size == 10)) { /* A DATE */ tt.is_utc = 0; tt.is_date = 1; } else { /* error */ goto FAIL; } if (tt.is_date == 1) { if (size == 10) { char dsep1, dsep2; if (sscanf(str, "%04d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day) < 5) { goto FAIL; } if ((dsep1 != '-') || (dsep2 != '-')) { goto FAIL; } } else if (sscanf(str, "%04d%02d%02d", &tt.year, &tt.month, &tt.day) < 3) { goto FAIL; } } else { if (size > 16) { char dsep1, dsep2, tsep, tsep1, tsep2; if (sscanf(str, "%04d%c%02d%c%02d%c%02d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day, &tsep, &tt.hour, &tsep1, &tt.minute, &tsep2, &tt.second) < 11) { goto FAIL; } if ((tsep != 'T') || (dsep1 != '-') || (dsep2 != '-') || (tsep1 != ':') || (tsep2 != ':')) { goto FAIL; } } else { char tsep; if (sscanf(str, "%04d%02d%02d%c%02d%02d%02d", &tt.year, &tt.month, &tt.day, &tsep, &tt.hour, &tt.minute, &tt.second) < 7) { goto FAIL; } if (tsep != 'T') { goto FAIL; } } } return tt; FAIL: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return icaltime_null_time(); }
/** Gets the TZNAMEs used for the last STANDARD & DAYLIGHT components in a VTIMEZONE. If both STANDARD and DAYLIGHT components use the same TZNAME, it returns that. If they use different TZNAMEs, it formats them like "EST/EDT". The returned string should be freed by the caller. */ static char* icaltimezone_get_tznames_from_vtimezone (icalcomponent *component) { icalcomponent *comp; icalcomponent_kind type; icalproperty *prop; struct icaltimetype dtstart; struct icaldatetimeperiodtype rdate; const char *current_tzname; const char *standard_tzname = NULL, *daylight_tzname = NULL; struct icaltimetype standard_max_date, daylight_max_date; struct icaltimetype current_max_date; standard_max_date = icaltime_null_time(); daylight_max_date = icaltime_null_time(); /* Step through the STANDARD & DAYLIGHT subcomponents. */ comp = icalcomponent_get_first_component (component, ICAL_ANY_COMPONENT); while (comp) { type = icalcomponent_isa (comp); if (type == ICAL_XSTANDARD_COMPONENT || type == ICAL_XDAYLIGHT_COMPONENT) { current_max_date = icaltime_null_time (); current_tzname = NULL; /* Step through the properties. We want to find the TZNAME, and the largest DTSTART or RDATE. */ prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY); while (prop) { switch (icalproperty_isa (prop)) { case ICAL_TZNAME_PROPERTY: current_tzname = icalproperty_get_tzname (prop); break; case ICAL_DTSTART_PROPERTY: dtstart = icalproperty_get_dtstart (prop); if (icaltime_compare (dtstart, current_max_date) > 0) current_max_date = dtstart; break; case ICAL_RDATE_PROPERTY: rdate = icalproperty_get_rdate (prop); if (icaltime_compare (rdate.time, current_max_date) > 0) current_max_date = rdate.time; break; default: break; } prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY); } if (current_tzname) { if (type == ICAL_XSTANDARD_COMPONENT) { if (!standard_tzname || icaltime_compare (current_max_date, standard_max_date) > 0) { standard_max_date = current_max_date; standard_tzname = current_tzname; } } else { if (!daylight_tzname || icaltime_compare (current_max_date, daylight_max_date) > 0) { daylight_max_date = current_max_date; daylight_tzname = current_tzname; } } } } comp = icalcomponent_get_next_component (component, ICAL_ANY_COMPONENT); } /* Outlook (2000) places "Standard Time" and "Daylight Time" in the TZNAME strings, which is totally useless. So we return NULL in that case. */ if (standard_tzname && !strcmp (standard_tzname, "Standard Time")) return NULL; /* If both standard and daylight TZNAMEs were found, if they are the same we return just one, else we format them like "EST/EDT". */ if (standard_tzname && daylight_tzname) { unsigned int standard_len, daylight_len; char *tznames; if (!strcmp (standard_tzname, daylight_tzname)) return strdup (standard_tzname); standard_len = strlen (standard_tzname); daylight_len = strlen (daylight_tzname); tznames = malloc (standard_len + daylight_len + 2); strcpy (tznames, standard_tzname); tznames[standard_len] = '/'; strcpy (tznames + standard_len + 1, daylight_tzname); return tznames; } else { const char *tznames; /* If either of the TZNAMEs was found just return that, else NULL. */ tznames = standard_tzname ? standard_tzname : daylight_tzname; return tznames ? strdup (tznames) : NULL; } }
int main(int argc, char *argv[]) { icalcomponent *c, *next_c = NULL; int i = 0; int dont_remove; icalfileset_options options = { O_RDONLY, 0644, 0, NULL }; icalset *f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-incoming.ics", &options); icalset *trash = icalset_new_file("trash.ics"); icalset *cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-calendar.ics", &options); icalset *out = icalset_new_file("outgoing.ics"); const char *this_user = "******"; _unused(argc); _unused(argv); assert(f != 0); assert(cal != 0); assert(trash != 0); assert(out != 0); /* Foreach incoming message */ for (c = icalset_get_first_component(f); c != 0; c = next_c) { icalproperty_xlicclass class; icalcomponent *match; icalcomponent *inner; icalcomponent *reply = 0; assert(c != 0); inner = icalcomponent_get_first_real_component(c); i++; reply = 0; dont_remove = 0; if (inner == 0) { printf("Bad component, no inner\n %s\n", icalcomponent_as_ical_string(c)); continue; } /* Find a booked component that is matched to the incoming message, based on the incoming component's UID, SEQUENCE and RECURRENCE-ID */ match = icalset_fetch_match(cal, c); class = icalclassify(c, match, this_user); /* Print out the notes associated with the incoming component and the matched component in the */ { const char *inc_note = 0; const char *match_note = 0; icalproperty *p; for (p = icalcomponent_get_first_property(c, ICAL_X_PROPERTY); p != 0; p = icalcomponent_get_next_property(c, ICAL_X_PROPERTY)) { if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) { inc_note = icalproperty_get_x(p); } } if (match != 0) { for (p = icalcomponent_get_first_property(match, ICAL_X_PROPERTY); p != 0; p = icalcomponent_get_next_property(match, ICAL_X_PROPERTY)) { if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) { match_note = icalproperty_get_x(p); } } } if (inc_note != 0) { printf("Incoming: %s\n", inc_note); } if (match_note != 0) { printf("Match : %s\n", match_note); } } /* Main processing structure */ switch (class) { case ICAL_XLICCLASS_NONE:{ char temp[1024]; /* Huh? Return an error to sender */ icalrestriction_check(c); icalcomponent_convert_errors(c); snprintf(temp, 1024, "I can't understand the component you sent.\n" "Here is the component you sent, possibly with error messages:\n" "%s", icalcomponent_as_ical_string(c)); reply = icalmessage_new_error_reply(c, this_user, temp, "", ICAL_UNKNOWN_STATUS); break; } case ICAL_XLICCLASS_PUBLISHNEW:{ /* Don't accept published events from anyone but self. If self, fall through to ICAL_XLICCLASS_REQUESTNEW */ } case ICAL_XLICCLASS_REQUESTNEW:{ /* Book the new component if it does not overlap anything. If the time is busy and the start time is an even modulo 4, delegate to [email protected]. If the time is busy and is 1 modulo 4, counterpropose for the first available free time. Otherwise, deline the meeting */ icalcomponent *overlaps = icalclassify_find_overlaps(cal, c); if (overlaps == 0) { /* No overlaps, book the meeting */ /* icalset_add_component(cal,icalcomponent_new_clone(c));*/ /* Return a reply */ reply = icalmessage_new_accept_reply( c, this_user, "I can make it to this meeting"); (void)icalset_add_component(out, reply); } else { /* There was a conflict, so delegate, counterpropose or decline it */ struct icaltimetype dtstart = icalcomponent_get_dtstart(c); if (dtstart.hour % 4 == 0) { /* Delegate the meeting */ reply = icalmessage_new_delegate_reply( c, this_user, "*****@*****.**", "Unfortunately, I have another commitment that conflicts " "with this meeting. I am delegating my attendance to Bob."); (void)icalset_add_component(out, reply); } else if (dtstart.hour % 4 == 1) { /* Counter propose to next available time */ icalcomponent *newc; struct icalperiodtype next_time; icalspanlist *spanl = icalspanlist_new(cal, dtstart, icaltime_null_time()); next_time = icalspanlist_next_free_time(spanl, icalcomponent_get_dtstart(c)); newc = icalcomponent_new_clone(c); icalcomponent_set_dtstart(newc, next_time.start); /* Hack, the duration of the counterproposed meeting may be longer than the free time available */ icalcomponent_set_duration(newc, icalcomponent_get_duration(c)); reply = icalmessage_new_counterpropose_reply( c, newc, this_user, "Unfortunately, I have another commitment that conflicts with " "this meeting. I am proposing a time that works better for me."); (void)icalset_add_component(out, reply); icalspanlist_free(spanl); icalcomponent_free(newc); } else { /* Decline the meeting */ reply = icalmessage_new_decline_reply( c, this_user, "I can't make it to this meeting"); (void)icalset_add_component(out, reply); } } icalcomponent_free(overlaps); break; } case ICAL_XLICCLASS_PUBLISHFREEBUSY:{ /* Store the busy time information in a file named after the sender */ break; } case ICAL_XLICCLASS_PUBLISHUPDATE:{ /* Only accept publish updates from self. If self, fall through to ICAL_XLICCLASS_REQUESTUPDATE */ } case ICAL_XLICCLASS_REQUESTUPDATE:{ /* always accept the changes */ break; } case ICAL_XLICCLASS_REQUESTRESCHEDULE:{ /* Use same rules as REQUEST_NEW */ (void)icalclassify_find_overlaps(cal, c); break; } case ICAL_XLICCLASS_REQUESTDELEGATE:{ break; } case ICAL_XLICCLASS_REQUESTNEWORGANIZER:{ break; } case ICAL_XLICCLASS_REQUESTFORWARD:{ break; } case ICAL_XLICCLASS_REQUESTSTATUS:{ break; } case ICAL_XLICCLASS_REQUESTFREEBUSY:{ break; } case ICAL_XLICCLASS_REPLYACCEPT:{ /* Change the PARTSTAT of the sender */ break; } case ICAL_XLICCLASS_REPLYDECLINE:{ /* Change the PARTSTAT of the sender */ break; } case ICAL_XLICCLASS_REPLYCRASHERACCEPT:{ /* Add the crasher to the ATTENDEE list with the appropriate PARTSTAT */ break; } case ICAL_XLICCLASS_REPLYCRASHERDECLINE:{ /* Add the crasher to the ATTENDEE list with the appropriate PARTSTAT */ break; } case ICAL_XLICCLASS_ADDINSTANCE:{ break; } case ICAL_XLICCLASS_CANCELEVENT:{ /* Remove the component */ break; } case ICAL_XLICCLASS_CANCELINSTANCE:{ break; } case ICAL_XLICCLASS_CANCELALL:{ /* Remove the component */ break; } case ICAL_XLICCLASS_REFRESH:{ /* Resend the latest copy of the request */ break; } case ICAL_XLICCLASS_COUNTER:{ break; } case ICAL_XLICCLASS_DECLINECOUNTER:{ break; } case ICAL_XLICCLASS_MALFORMED:{ /* Send back an error */ break; } case ICAL_XLICCLASS_OBSOLETE:{ printf(" ** Got an obsolete component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_MISSEQUENCED:{ printf(" ** Got a missequenced component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_UNKNOWN:{ printf(" ** Don't know what to do with this component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_X: case ICAL_XLICCLASS_REPLYDELEGATE: default:{ } } #if 0 if (reply != 0) { /* Don't send the reply if the RSVP parameter indicates not to */ icalcomponent *reply_inner; icalproperty *attendee; icalparameter *rsvp; reply_inner = icalcomponent_get_first_real_component(reply); attendee = icalcomponent_get_first_property(reply_inner, ICAL_ATTENDEE_PROPERTY); rsvp = icalproperty_get_first_parameter(attendee, ICAL_RSVP_PARAMETER); if (rsvp == 0 || icalparameter_get_rsvp(rsvp) == 1) { icalrestriction_check(reply); send_message(reply, this_user); } icalcomponent_free(reply); } #endif if (reply != 0) { printf("%s\n", icalcomponent_as_ical_string(reply)); } next_c = icalset_get_next_component(f); if (dont_remove == 0) { /*icalset_remove_component(f,c); icalset_add_component(trash,c); */ } } #if 0 for (c = icalset_get_first_component(out); c != 0; c = icalset_get_next_component(out)) { printf("%s", icalcomponent_as_ical_string(c)); } #endif icalset_free(f); icalset_free(trash); icalset_free(cal); icalset_free(out); return 0; }
static gboolean put_component_to_store (ECalBackendHttp *cb, ECalComponent *comp) { time_t time_start, time_end; ECalBackendHttpPrivate *priv; ECalComponent *cache_comp; const gchar *uid; gchar *rid; priv = cb->priv; e_cal_component_get_uid (comp, &uid); rid = e_cal_component_get_recurid_as_string (comp); cache_comp = e_cal_backend_store_get_component (priv->store, uid, rid); g_free (rid); if (cache_comp) { gboolean changed = TRUE; struct icaltimetype stamp1, stamp2; stamp1 = icaltime_null_time (); stamp2 = icaltime_null_time (); e_cal_component_get_dtstamp (comp, &stamp1); e_cal_component_get_dtstamp (cache_comp, &stamp2); changed = (icaltime_is_null_time (stamp1) && !icaltime_is_null_time (stamp2)) || (!icaltime_is_null_time (stamp1) && icaltime_is_null_time (stamp2)) || (icaltime_compare (stamp1, stamp2) != 0); if (!changed) { struct icaltimetype *last_modified1 = NULL, *last_modified2 = NULL; e_cal_component_get_last_modified (comp, &last_modified1); e_cal_component_get_last_modified (cache_comp, &last_modified2); changed = (last_modified1 != NULL && last_modified2 == NULL) || (last_modified1 == NULL && last_modified2 != NULL) || (last_modified1 != NULL && last_modified2 != NULL && icaltime_compare (*last_modified1, *last_modified2) != 0); if (last_modified1) e_cal_component_free_icaltimetype (last_modified1); if (last_modified2) e_cal_component_free_icaltimetype (last_modified2); if (!changed) { gint *sequence1 = NULL, *sequence2 = NULL; e_cal_component_get_sequence (comp, &sequence1); e_cal_component_get_sequence (cache_comp, &sequence2); changed = (sequence1 != NULL && sequence2 == NULL) || (sequence1 == NULL && sequence2 != NULL) || (sequence1 != NULL && sequence2 != NULL && *sequence1 != *sequence2); if (sequence1) e_cal_component_free_sequence (sequence1); if (sequence2) e_cal_component_free_sequence (sequence2); } } g_object_unref (cache_comp); if (!changed) return FALSE; } e_cal_util_get_component_occur_times ( comp, &time_start, &time_end, resolve_tzid, cb, icaltimezone_get_utc_timezone (), e_cal_backend_get_kind (E_CAL_BACKEND (cb))); e_cal_backend_store_put_component_with_time_range (priv->store, comp, time_start, time_end); return TRUE; }