static gboolean is_icalcomp_usable (icalcomponent *icalcomp) { return icalcomp && icalcomponent_is_valid (icalcomp) && ( icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT) != NULL || icalcomponent_get_first_component (icalcomp, ICAL_VTODO_COMPONENT) != NULL); }
static gboolean deserialize (ScalixObject * object, const char *string) { ScalixAppointmentPrivate *priv; icalcomponent *icomp, *subcomp; icalcomponent_kind kind; icaltimezone *zone; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { g_warning ("No VCALENAR while deserializing! (%s)\n", string); icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { zone = icaltimezone_new (); icalcomponent_remove_component (icomp, subcomp); if (icaltimezone_set_component (zone, subcomp)) priv->timezone = zone; } kind = ICAL_VEVENT_COMPONENT; /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, kind); if (subcomp == NULL) { icalcomponent_free (icomp); return FALSE; } icalcomponent_remove_component (icomp, subcomp); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); e_cal_component_commit_sequence (E_CAL_COMPONENT (object)); priv->exceptions = NULL; while ((subcomp = icalcomponent_get_next_component (icomp, kind))) { icalcomponent_remove_component (icomp, subcomp); priv->exceptions = g_slist_prepend (priv->exceptions, subcomp); } icalcomponent_free (icomp); return TRUE; }
static gboolean set_ical_from_mime_part (CamelMimePart * part, ScalixObject * object) { CamelDataWrapper *content; CamelStream *stream; GByteArray *data; icalcomponent *icomp = NULL; icalcomponent *subcomp = NULL; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); data = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (data); camel_data_wrapper_decode_to_stream (content, stream); if (data == NULL || data->data == NULL) { g_print ("Found corrupt ical data\n"); return FALSE; } icomp = icalparser_parse_string ((const char *) data->data); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, subcomp); priv->timezone = zone; } /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); return TRUE; }
NS_IMETHODIMP calIcalComponent::GetFirstSubcomponent(const nsACString& kind, calIIcalComponent **subcomp) { NS_ENSURE_ARG_POINTER(subcomp); icalcomponent_kind compkind = icalcomponent_string_to_kind(PromiseFlatCString(kind).get()); // Maybe someday I'll support X-COMPONENTs if (compkind == ICAL_NO_COMPONENT || compkind == ICAL_X_COMPONENT) return NS_ERROR_INVALID_ARG; icalcomponent *ical = icalcomponent_get_first_component(mComponent, compkind); if (!ical) { *subcomp = nullptr; return NS_OK; } *subcomp = new calIcalComponent(ical, this); CAL_ENSURE_MEMORY(*subcomp); NS_ADDREF(*subcomp); return NS_OK; }
icalcomponent *icalcluster_get_first_component(icalcluster* impl) { icalerror_check_arg_rz((impl!=0),"cluster"); return icalcomponent_get_first_component(impl->data, ICAL_ANY_COMPONENT); }
static void icaltimezone_expand_changes (icaltimezone *zone, int end_year) { icalarray *changes; icalcomponent *comp; #if 0 printf ("\nExpanding changes for: %s to year: %i\n", zone->tzid, end_year); #endif changes = icalarray_new (sizeof (icaltimezonechange), 32); if (!changes) return; /* Scan the STANDARD and DAYLIGHT subcomponents. */ comp = icalcomponent_get_first_component (zone->component, ICAL_ANY_COMPONENT); while (comp) { icaltimezone_expand_vtimezone (comp, end_year, changes); comp = icalcomponent_get_next_component (zone->component, ICAL_ANY_COMPONENT); } /* Sort the changes. We may have duplicates but I don't think it will matter. */ icalarray_sort (changes, icaltimezone_compare_change_fn); if (zone->changes) icalarray_free (zone->changes); zone->changes = changes; zone->end_year = end_year; }
/** Loads the builtin VTIMEZONE data for the given timezone. */ static void icaltimezone_load_builtin_timezone (icaltimezone *zone) { char *filename; unsigned int filename_len; FILE *fp; icalparser *parser; icalcomponent *comp, *subcomp; /* If the location isn't set, it isn't a builtin timezone. */ if (!zone->location || !zone->location[0]) return; filename_len = strlen (get_zone_directory()) + strlen (zone->location) + 6; filename = (char*) malloc (filename_len); if (!filename) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return; } snprintf (filename, filename_len, "%s/%s.ics", get_zone_directory(), zone->location); fp = fopen (filename, "r"); free (filename); if (!fp) { icalerror_set_errno(ICAL_FILE_ERROR); return; } /* ##### B.# Sun, 11 Nov 2001 04:04:29 +1100 this is where the MALFORMEDDATA error is being set, after the call to 'icalparser_parse' fprintf(stderr, "** WARNING ** %s: %d %s\n", __FILE__, __LINE__, icalerror_strerror(icalerrno)); */ parser = icalparser_new (); icalparser_set_gen_data (parser, fp); comp = icalparser_parse (parser, icaltimezone_load_get_line_fn); icalparser_free (parser); fclose (fp); /* Find the VTIMEZONE component inside the VCALENDAR. There should be 1. */ subcomp = icalcomponent_get_first_component (comp, ICAL_VTIMEZONE_COMPONENT); if (!subcomp) { icalerror_set_errno(ICAL_PARSE_ERROR); return; } icaltimezone_get_vtimezone_properties (zone, subcomp); icalcomponent_remove_component(comp,subcomp); icalcomponent_free(comp); }
void MainWindow::saveToIcsFile(icalcomponent *comp, std::string uid) { icalset* file = icalfileset_new("/home/quentin/Public/test.ics"); icalfileset *fset = (icalfileset*) file; icalcomponent* old = fetch(file, uid.c_str()); if (old != NULL) { icalcomponent_remove_component(icalcomponent_get_first_component(fset->cluster, ICAL_ANY_COMPONENT), old); } icalcomponent_add_component(icalcomponent_get_first_component(fset->cluster, ICAL_ANY_COMPONENT), comp); icalfileset_mark(file); icalfileset_commit(file); icalfileset_free(file); }
/* * Construct a JSON array for an iCalendar component. */ static json_t *icalcomponent_as_json_array(icalcomponent *comp) { icalcomponent *c; icalproperty *p; icalcomponent_kind kind; const char* kind_string; json_t *jcomp, *jprops, *jsubs; if (!comp) return NULL; kind = icalcomponent_isa(comp); switch (kind) { case ICAL_NO_COMPONENT: return NULL; break; case ICAL_X_COMPONENT: kind_string = ""; //comp->x_name; break; default: kind_string = icalcomponent_kind_to_string(kind); } /* Create component array */ jcomp = json_array(); /* Add component name */ json_array_append_new(jcomp, json_string(lcase(icalmemory_tmp_copy(kind_string)))); /* Add properties */ jprops = json_array(); for (p = icalcomponent_get_first_property(comp, ICAL_ANY_PROPERTY); p; p = icalcomponent_get_next_property(comp, ICAL_ANY_PROPERTY)) { json_array_append_new(jprops, icalproperty_as_json_array(p)); } json_array_append_new(jcomp, jprops); /* Add sub-components */ jsubs = json_array(); for (c = icalcomponent_get_first_component(comp, ICAL_ANY_COMPONENT); c; c = icalcomponent_get_next_component(comp, ICAL_ANY_COMPONENT)) { json_array_append_new(jsubs, icalcomponent_as_json_array(c)); } json_array_append_new(jcomp, jsubs); return jcomp; }
icalcomponent *icallangbind_get_first_component(icalcomponent *c, const char *comp) { icalcomponent_kind kind = icalenum_string_to_component_kind(comp); if (kind == ICAL_NO_COMPONENT) { return 0; } return icalcomponent_get_first_component(c, kind); }
/* * Construct a XML element for an iCalendar component. */ static xmlNodePtr icalcomponent_as_xml_element(icalcomponent *comp) { icalcomponent *c; icalproperty *p; icalcomponent_kind kind; const char* kind_string; xmlNodePtr xcomp, xprops = NULL, xsubs = NULL; if (!comp) return NULL; kind = icalcomponent_isa(comp); switch (kind) { case ICAL_NO_COMPONENT: return NULL; break; case ICAL_X_COMPONENT: kind_string = ""; //comp->x_name; break; default: kind_string = icalcomponent_kind_to_string(kind); } /* Create component */ xcomp = xmlNewNode(NULL, BAD_CAST lcase(icalmemory_tmp_copy(kind_string))); /* Add properties */ for (p = icalcomponent_get_first_property(comp, ICAL_ANY_PROPERTY); p; p = icalcomponent_get_next_property(comp, ICAL_ANY_PROPERTY)) { if (!xprops) xprops = xmlNewChild(xcomp, NULL, BAD_CAST "properties", NULL); xmlAddChild(xprops, icalproperty_as_xml_element(p)); } /* Add sub-components */ for (c = icalcomponent_get_first_component(comp, ICAL_ANY_COMPONENT); c; c = icalcomponent_get_next_component(comp, ICAL_ANY_COMPONENT)) { if (!xsubs) xsubs = xmlNewChild(xcomp, NULL, BAD_CAST "components", NULL); xmlAddChild(xsubs, icalcomponent_as_xml_element(c)); } return xcomp; }
static void set_standard_offsets (icalcomponent *zone_comp, int offset) { icalcomponent *dl_comp, *s_comp; icalproperty *offset_from, *offset_to; /* Set the offset of the standard component to all the daylight components also */ for (dl_comp = icalcomponent_get_first_component (zone_comp, ICAL_XDAYLIGHT_COMPONENT); dl_comp != NULL; dl_comp = icalcomponent_get_next_component (zone_comp, ICAL_XDAYLIGHT_COMPONENT)) { offset_to = icalcomponent_get_first_property (dl_comp, ICAL_TZOFFSETTO_PROPERTY); icalproperty_set_tzoffsetto (offset_to, offset); } /* Set the tzto offset of the standard component to tzfrom */ for (s_comp = icalcomponent_get_first_component (zone_comp, ICAL_XSTANDARD_COMPONENT); s_comp != NULL; s_comp = icalcomponent_get_next_component (zone_comp, ICAL_XSTANDARD_COMPONENT)) { offset_from = icalcomponent_get_first_property (s_comp, ICAL_TZOFFSETFROM_PROPERTY); icalproperty_set_tzoffsetfrom (offset_from, offset); } }
/** * e_cal_util_component_has_alarms: * @icalcomp: An #icalcomponent. * * Checks whether an #icalcomponent has any alarm. * * Returns: TRUE if it has alarms, FALSE otherwise. */ gboolean e_cal_util_component_has_alarms (icalcomponent *icalcomp) { icalcomponent *alarm; g_return_val_if_fail (icalcomp != NULL, FALSE); alarm = icalcomponent_get_first_component ( icalcomp, ICAL_VALARM_COMPONENT); return (alarm != NULL); }
void dates_ical_drop_cb (DatesView *view, const gchar *ical, DatesData *d) { icalcomponent *icalcomp, *icalcomp2; gint events; if (!d->cal_loaded) { /* TODO: Toggle the default calendar here maybe? */ g_warning ("No calendars selected to add new event to"); return; } icalcomp = icalcomponent_new_from_string (g_strdup (ical)); if (!icalcomp) g_warning ("Error creating icalcomponent from string"); switch (icalcomponent_isa (icalcomp)) { case ICAL_VEVENT_COMPONENT : icalcomponent_set_uid (icalcomp, ""); dates_new (d, icalcomponent_new_clone (icalcomp), TRUE); return; case ICAL_VCALENDAR_COMPONENT : /* Iterate through events */ /* TODO: A confirmation dialog when calendar has * multiple events? */ events = icalcomponent_count_components (icalcomp, ICAL_VEVENT_COMPONENT); if (events == 0) { g_warning ("Dragged ical contains no supported " "kinds."); break; } icalcomp2 = icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT); do { icalcomponent_set_uid (icalcomp2, ""); dates_new (d, icalcomponent_new_clone ( icalcomp2), (events == 1) ? TRUE : FALSE); } while ((icalcomp2 = icalcomponent_get_next_component ( icalcomp2, ICAL_VEVENT_COMPONENT))); break; default : g_warning ("Dragged ical not a supported kind."); break; } icalcomponent_free (icalcomp); }
void find_sub_components(icalcomponent* comp) { icalcomponent *c; /* The second parameter to icalcomponent_get_first_component indicates the type of component to search for. This will iterate through all sub-components */ for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); c != 0; c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ do_something(c); } /* This will iterate only though VEVENT sub-components */ for(c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT); c != 0; c = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT)){ do_something(c); } }
void remove_vevent_sub_components(icalcomponent* comp){ icalcomponent *c, *next; for( c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT); c != 0; c = next) { next = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT); icalcomponent_remove_component(comp,c); do_something(c); } }
icalproperty *icalcomponent_get_first_invitee(icalcomponent *comp) { icalproperty *prop; if (icalcomponent_isa(comp) == ICAL_VPOLL_COMPONENT) { icalcomponent *vvoter = icalcomponent_get_first_component(comp, ICAL_VVOTER_COMPONENT); prop = icalcomponent_get_first_property(vvoter, ICAL_VOTER_PROPERTY); } else { prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY); } return prop; }
void MainWindow::loadFromIcsFile() { char* line; icalcomponent *c; icalparser *parser = icalparser_new(); FILE* stream = fopen("/home/quentin/Public/test.ics", "r"); icalparser_set_gen_data(parser, stream); do { line = icalparser_get_line(parser, read_stream); c = icalparser_add_line(parser, line); if (c != 0) { icalcomponent *inner = icalcomponent_get_first_component(c, ICAL_ANY_COMPONENT); while (inner != NULL) { if (icalcomponent_isa(inner) == ICAL_VTODO_COMPONENT) { const char* name = icalcomponent_get_summary(inner); const char* uid = icalcomponent_get_uid(inner); icalproperty *p = icalcomponent_get_first_property(inner, ICAL_RELATEDTO_PROPERTY); const char* parent = icalproperty_get_relatedto(p); addTask(name, uid, parent); } if (icalcomponent_isa(inner) == ICAL_VEVENT_COMPONENT) { const char* name = icalcomponent_get_summary(inner); const char* uid = icalcomponent_get_uid(inner); icalproperty *p = icalcomponent_get_first_property(inner, ICAL_RELATEDTO_PROPERTY); const char* parent = icalproperty_get_relatedto(p); p = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY); icaltimetype start = icalproperty_get_dtstart(p); p = icalcomponent_get_first_property(inner, ICAL_DTEND_PROPERTY); icaltimetype end = icalproperty_get_dtend(p); Task* task = findTask(parent); addEvent(task, uid, name, start, end); } inner = icalcomponent_get_next_component(c, ICAL_ANY_COMPONENT); } } } while (line != 0); }
static gboolean scalix_appointment_from_string (ScalixObject * object, const char *string) { icalcomponent *icomp, *subcomp; icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) == ICAL_VCALENDAR_COMPONENT) { subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); icalcomponent_remove_component (icomp, subcomp); icalcomponent_free (icomp); icomp = subcomp; } e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), icomp); return TRUE; }
/** Get VEVENT from the iTip. * * VCALENDAR * VTIMEZONE+ * VEVENT <--- will return this * * @param comp iCal component. * * @return VEVENT icalcomponent object or NULL. */ icalcomponent *icalcomponent_get_itip_payload(icalcomponent *comp) { icalcomponent *ret = NULL; g_return_val_if_fail(comp != NULL, NULL); if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT) { icalcomponent *vevent = icalcomponent_get_first_component(comp, ICAL_VEVENT_COMPONENT); if (vevent) { ret = vevent; } } else if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { ret = comp; } return ret; }
const char *get_icalcomponent_errstr(icalcomponent *ical) { icalcomponent *comp; for (comp = icalcomponent_get_first_component(ical, ICAL_ANY_COMPONENT); comp; comp = icalcomponent_get_next_component(ical, ICAL_ANY_COMPONENT)) { icalproperty *prop; for (prop = icalcomponent_get_first_property(comp, ICAL_ANY_PROPERTY); prop; prop = icalcomponent_get_next_property(comp, ICAL_ANY_PROPERTY)) { if (icalproperty_isa(prop) == ICAL_XLICERROR_PROPERTY) { const char *errstr = icalproperty_get_xlicerror(prop); char propname[256]; if (!errstr) return "Unknown iCal parsing error"; /* Check if this is an empty property error */ if (sscanf(errstr, "No value for %s property", propname) == 1) { /* Empty LOCATION is OK */ if (!strcasecmp(propname, "LOCATION")) continue; if (!strcasecmp(propname, "COMMENT")) continue; if (!strcasecmp(propname, "DESCRIPTION")) continue; } else { /* Ignore unknown property errors */ if (!strncmp(errstr, "Parse error in property name", 28)) continue; } return errstr; } } } return NULL; }
icalcomponent *icalbdbset_get_first_component(icalset *set) { icalbdbset *bset = (icalbdbset *) set; icalcomponent *c = 0; icalerror_check_arg_rz((bset != 0), "bset"); do { if (c == 0) { c = icalcomponent_get_first_component(bset->cluster, ICAL_ANY_COMPONENT); } else { c = icalcomponent_get_next_component(bset->cluster, ICAL_ANY_COMPONENT); } if (c != 0 && (bset->gauge == 0 || icalgauge_compare(bset->gauge, c) == 1)) { return c; } } while (c != 0); return 0; }
void delete_event(icalcomponent* calendar) { icalcomponent* event = find_event(calendar); if (!yes_no_prompt("Are you sure you want to delete this event? (y/n")) { return; } //Find the event in the components icalcomponent* c = icalcomponent_get_first_component(calendar, ICAL_VEVENT_COMPONENT); bool found_event = false; while((c=icalcomponent_get_current_component(c)) != 0 ) { if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT) { if (c == event) { icalcomponent_remove_component(calendar, c); found_event = true; } }else { icalcomponent_get_next_component(calendar, ICAL_VEVENT_COMPONENT); } } if (!found_event) { append_action_to_closed_log("Delete event", false); return; } append_action_to_closed_log("Delete event", true); }
/** * Add all VTODO components in a file to a list of iCal todo entries. * @param ical_todos [in] Current list of iCal todo entries. * @param filename [in] Path of the iCal file. * @return List of iCal todo entries. */ GSList* read_vtodo_from_ical_file( GSList *ical_todos, const gchar *filename ) { icalset *ical_set; icalcomponent *component; icalcomponent *c; /* Create an iCalendar set based on contents of the specified file. */ ical_set = icalfileset_new( filename ); /* Construct a list of iCalendar todo entries based on the VTODO components in the iCalendar set. */ for( component = icalfileset_get_first_component( ical_set ); component != NULL; component = icalfileset_get_next_component( ical_set ) ) { /* If the iCalendar component has a VTODO subcomponent then copy the component into our iCalendar todo list. */ for( c = icalcomponent_get_first_component( component, ICAL_VTODO_COMPONENT ); c != NULL; c = icalcomponent_get_next_component( component, ICAL_VTODO_COMPONENT ) ) { { /* Add the component to the iCalendar todo list. */ ical_todos = g_slist_append( ical_todos, c ); } } icalcomponent_free( component ); } icalfileset_free( ical_set ); return( ical_todos ); }
/** Get iTIP method. * * @param comp iCal component. * * @return Method. */ icalproperty_method icalcomponent_get_itip_method(icalcomponent *comp) { icalproperty_method method = ICAL_METHOD_NONE; if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT) { icalcomponent *vevent = icalcomponent_get_first_component(comp, ICAL_VEVENT_COMPONENT); if (vevent && icalcomponent_get_first_property(vevent, ICAL_METHOD_PROPERTY)) { method = icalcomponent_get_method(vevent); } else { method = icalcomponent_get_method(comp); } } else if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { method = icalcomponent_get_method(comp); } return method; }
void render_MIME_ICS_TPL(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset) { wc_mime_attachment *Mime = CTX(CTX_MIME_ATACH); icalproperty_method the_method = ICAL_METHOD_NONE; icalproperty *method = NULL; icalcomponent *cal = NULL; icalcomponent *c = NULL; WCTemplputParams SubTP; WCTemplputParams SuperTP; static int divcount = 0; if (StrLength(Mime->Data) == 0) { MimeLoadData(Mime); } if (StrLength(Mime->Data) > 0) { cal = icalcomponent_new_from_string(ChrPtr(Mime->Data)); } if (cal == NULL) { StrBufAppendPrintf(Mime->Data, _("There was an error parsing this calendar item.")); StrBufAppendPrintf(Mime->Data, "<br>\n"); return; } putlbstr("divname", ++divcount); putbstr("cal_partnum", NewStrBufDup(Mime->PartNum)); putlbstr("msgnum", Mime->msgnum); memset(&SubTP, 0, sizeof(WCTemplputParams)); memset(&SuperTP, 0, sizeof(WCTemplputParams)); /*//ical_dezonify(cal); */ /* If the component has subcomponents, recurse through them. */ c = icalcomponent_get_first_component(cal, ICAL_ANY_COMPONENT); c = (c != NULL) ? c : cal; method = icalcomponent_get_first_property(cal, ICAL_METHOD_PROPERTY); if (method != NULL) { the_method = icalproperty_get_method(method); } StackContext (TP, &SuperTP, &the_method, CTX_ICALMETHOD, 0, TP->Tokens); StackContext (&SuperTP, &SubTP, c, CTX_ICAL, 0, SuperTP.Tokens); FlushStrBuf(Mime->Data); /// DoTemplate(HKEY("ical_attachment_display"), Mime->Data, &SubTP); DoTemplate(HKEY("ical_edit"), Mime->Data, &SubTP); /*/ cal_process_object(Mime->Data, cal, 0, Mime->msgnum, ChrPtr(Mime->PartNum)); */ /* Free the memory we obtained from libical's constructor */ StrBufPlain(Mime->ContentType, HKEY("text/html")); StrBufAppendPrintf(WC->trailing_javascript, "eventEditAllDay(); \n" "RecurrenceShowHide(); \n" "EnableOrDisableCheckButton(); \n" ); UnStackContext(&SuperTP); UnStackContext(&SubTP); icalcomponent_free(cal); }
/** * e_cal_client_check_timezones: * @comp: a VCALENDAR containing a list of * VTIMEZONE and arbitrary other components, in * arbitrary order: these other components are * modified by this call * @comps: (element-type icalcomponent) (allow-none): a list of #icalcomponent * instances which also have to be patched; may be %NULL * @tzlookup: a callback function which is called to retrieve * a calendar's VTIMEZONE definition; the returned * definition is *not* freed by e_cal_client_check_timezones() * (to be compatible with e_cal_get_timezone()); * NULL indicates that no such timezone exists * or an error occurred * @ecalclient: an arbitrary pointer which is passed through to * the @tzlookup function * @cancellable: a #GCancellable to use in @tzlookup function * @error: an error description in case of a failure * * This function cleans up VEVENT, VJOURNAL, VTODO and VTIMEZONE * items which are to be imported into Evolution. * * Using VTIMEZONE definitions is problematic because they cannot be * updated properly when timezone definitions change. They are also * incomplete (for compatibility reason only one set of rules for * summer saving changes can be included, even if different rules * apply in different years). This function looks for matches of the * used TZIDs against system timezones and replaces such TZIDs with * the corresponding system timezone. This works for TZIDs containing * a location (found via a fuzzy string search) and for Outlook TZIDs * (via a hard-coded lookup table). * * Some programs generate broken meeting invitations with TZID, but * without including the corresponding VTIMEZONE. Importing such * invitations unchanged causes problems later on (meeting displayed * incorrectly, e_cal_get_component_as_string() fails). The situation * where this occurred in the past (found by a SyncEvolution user) is * now handled via the location based mapping. * * If this mapping fails, this function also deals with VTIMEZONE * conflicts: such conflicts occur when the calendar already contains * an old VTIMEZONE definition with the same TZID, but different * summer saving rules. Replacing the VTIMEZONE potentially breaks * displaying of old events, whereas not replacing it breaks the new * events (the behavior in Evolution <= 2.22.1). * * The way this problem is resolved is by renaming the new VTIMEZONE * definition until the TZID is unique. A running count is appended to * the TZID. All items referencing the renamed TZID are adapted * accordingly. * * Returns: %TRUE if successful, %FALSE otherwise. * * Since: 3.2 **/ gboolean e_cal_client_check_timezones (icalcomponent *comp, GList *comps, icaltimezone *(*tzlookup) (const gchar *tzid, gconstpointer ecalclient, GCancellable *cancellable, GError **error), gconstpointer ecalclient, GCancellable *cancellable, GError **error) { gboolean success = TRUE; icalcomponent *subcomp = NULL; icaltimezone *zone = icaltimezone_new (); gchar *key = NULL, *value = NULL; gchar *buffer = NULL; gchar *zonestr = NULL; gchar *tzid = NULL; GList *l; /* a hash from old to new tzid; strings dynamically allocated */ GHashTable *mapping = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* a hash of all system time zone IDs which have to be added; strings are shared with mapping hash */ GHashTable *systemtzids = g_hash_table_new (g_str_hash, g_str_equal); *error = NULL; if (!mapping || !zone) { goto nomem; } /* iterate over all VTIMEZONE definitions */ subcomp = icalcomponent_get_first_component (comp, ICAL_VTIMEZONE_COMPONENT); while (subcomp) { if (icaltimezone_set_component (zone, subcomp)) { g_free (tzid); tzid = g_strdup (icaltimezone_get_tzid (zone)); if (tzid) { const gchar *newtzid = e_cal_match_tzid (tzid); if (newtzid) { /* matched against system time zone */ g_free (key); key = g_strdup (tzid); if (!key) { goto nomem; } g_free (value); value = g_strdup (newtzid); if (!value) { goto nomem; } g_hash_table_insert (mapping, key, value); g_hash_table_insert (systemtzids, value, NULL); key = value = NULL; } else { gint counter; zonestr = icalcomponent_as_ical_string_r (subcomp); /* check for collisions with existing timezones */ for (counter = 0; counter < 100 /* sanity limit */; counter++) { icaltimezone *existing_zone; if (counter) { g_free (value); value = g_strdup_printf ("%s %d", tzid, counter); } existing_zone = tzlookup (counter ? value : tzid, ecalclient, cancellable, error); if (!existing_zone) { if (*error) { goto failed; } else { break; } } g_free (buffer); buffer = icalcomponent_as_ical_string_r (icaltimezone_get_component (existing_zone)); if (counter) { gchar *fulltzid = g_strdup_printf ("TZID:%s", value); gsize baselen = strlen ("TZID:") + strlen (tzid); gsize fulllen = strlen (fulltzid); gchar *tzidprop; /* * Map TZID with counter suffix back to basename. */ tzidprop = strstr (buffer, fulltzid); if (tzidprop) { memmove ( tzidprop + baselen, tzidprop + fulllen, strlen (tzidprop + fulllen) + 1); } g_free (fulltzid); } /* * If the strings are identical, then the * VTIMEZONE definitions are identical. If * they are not identical, then VTIMEZONE * definitions might still be semantically * correct and we waste some space by * needlesly duplicating the VTIMEZONE. This * is expected to occur rarely (if at all) in * practice. */ if (!strcmp (zonestr, buffer)) { break; } } if (!counter) { /* does not exist, nothing to do */ } else { /* timezone renamed */ icalproperty *prop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY); while (prop) { icalproperty_set_value_from_string (prop, value, "NO"); prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY); } g_free (key); key = g_strdup (tzid); g_hash_table_insert (mapping, key, value); key = value = NULL; } } } } subcomp = icalcomponent_get_next_component (comp, ICAL_VTIMEZONE_COMPONENT); } /* * now replace all TZID parameters in place */ subcomp = icalcomponent_get_first_component (comp, ICAL_ANY_COMPONENT); while (subcomp) { /* * Leave VTIMEZONE unchanged, iterate over properties of * everything else. * * Note that no attempt is made to remove unused VTIMEZONE * definitions. That would just make the code more complex for * little additional gain. However, newly used time zones are * added below. */ patch_tzids (subcomp, mapping); subcomp = icalcomponent_get_next_component (comp, ICAL_ANY_COMPONENT); } for (l = comps; l; l = l->next) { patch_tzids (l->data, mapping); } /* * add system time zones that we mapped to: adding them ensures * that the VCALENDAR remains consistent */ g_hash_table_foreach (systemtzids, addsystemtz, comp); goto done; nomem: /* set gerror for "out of memory" if possible, otherwise abort via g_error() */ *error = g_error_new (E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, "out of memory"); if (!*error) { g_error ("e_cal_check_timezones(): out of memory, cannot proceed - sorry!"); } failed: /* gerror should have been set already */ success = FALSE; done: if (mapping) { g_hash_table_destroy (mapping); } if (systemtzids) { g_hash_table_destroy (systemtzids); } if (zone) { icaltimezone_free (zone, 1); } g_free (tzid); g_free (zonestr); g_free (buffer); g_free (key); g_free (value); return success; }
icalerrorenum icalbdbset_commit(icalset *set) { DB *dbp; DBC *dbcp; DBT key, data; icalcomponent *c; char *str = NULL; int ret = 0; int reterr = ICAL_NO_ERROR; char keystore[256]; char uidbuf[256]; char datastore[1024]; char *more_mem = NULL; DB_TXN *tid = NULL; icalbdbset *bset = (icalbdbset *) set; int bad_uid_counter = 0; int retry = 0, done = 0, completed = 0, deadlocked = 0; icalerror_check_arg_re((bset != 0), "bset", ICAL_BADARG_ERROR); dbp = bset->dbp; icalerror_check_arg_re((dbp != 0), "dbp is invalid", ICAL_BADARG_ERROR); if (bset->changed == 0) { return ICAL_NO_ERROR; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.flags = DB_DBT_USERMEM; key.data = keystore; key.ulen = (u_int32_t) sizeof(keystore); data.flags = DB_DBT_USERMEM; data.data = datastore; data.ulen = (u_int32_t) sizeof(datastore); if (!ICAL_DB_ENV) { if (icalbdbset_init_dbenv(NULL, NULL) != 0) { return ICAL_INTERNAL_ERROR; } } while ((retry < MAX_RETRY) && !done) { if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit: txn_begin failed"); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit"); return ICAL_INTERNAL_ERROR; } } /* first delete everything in the database, because there could be removed components */ if ((ret = dbp->cursor(dbp, tid, &dbcp, DB_DIRTY_READ)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed"); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed"); /* leave bset->changed set to true */ return ICAL_INTERNAL_ERROR; } } /* fetch the key/data pair, then delete it */ completed = 0; while (!completed && !deadlocked) { ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT); if (ret == DB_NOTFOUND) { completed = 1; } else if (ret == ENOMEM) { if (more_mem) { free(more_mem); } more_mem = malloc(data.ulen + 1024); data.data = more_mem; data.ulen = data.ulen + 1024; } else if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else if (ret == DB_RUNRECOVERY) { tid->abort(tid); ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_get failed."); abort(); } else if (ret == 0) { if ((ret = dbcp->c_del(dbcp, 0)) != 0) { dbp->err(dbp, ret, "cursor"); if (ret == DB_KEYEMPTY) { /* never actually created, continue onward.. */ /* do nothing - break; */ } else if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else { /*char *foo = db_strerror(ret); */ abort(); } } } else { /* some other non-fatal error */ dbcp->c_close(dbcp); tid->abort(tid); if (more_mem) { free(more_mem); more_mem = NULL; } return ICAL_INTERNAL_ERROR; } } if (more_mem) { free(more_mem); more_mem = NULL; } if (deadlocked) { dbcp->c_close(dbcp); tid->abort(tid); retry++; continue; /* next retry */ } deadlocked = 0; for (c = icalcomponent_get_first_component(bset->cluster, ICAL_ANY_COMPONENT); c != 0 && !deadlocked; c = icalcomponent_get_next_component(bset->cluster, ICAL_ANY_COMPONENT)) { memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); /* Note that we're always inserting into a primary index. */ if (icalcomponent_isa(c) != ICAL_VAGENDA_COMPONENT) { char *uidstr = (char *)icalcomponent_get_uid(c); if (!uidstr) { /* this shouldn't happen */ /* no uid string, we need to add one */ snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++); key.data = uidbuf; } else { key.data = uidstr; } } else { char *relcalid = NULL; relcalid = (char *)icalcomponent_get_relcalid(c); if (relcalid == NULL) { snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++); key.data = uidbuf; } else { key.data = relcalid; } } key.size = (u_int32_t) strlen(key.data); str = icalcomponent_as_ical_string_r(c); data.data = str; data.size = (u_int32_t) strlen(str); if ((ret = dbcp->c_put(dbcp, &key, &data, DB_KEYLAST)) != 0) { if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed %s.", str); /* continue to try to put as many icalcomponent as possible */ reterr = ICAL_INTERNAL_ERROR; } } } if (str) { free(str); } if (deadlocked) { dbcp->c_close(dbcp); tid->abort(tid); retry++; continue; } if ((ret = dbcp->c_close(dbcp)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed."); reterr = ICAL_INTERNAL_ERROR; } } if ((ret = tid->commit(tid, 0)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed."); reterr = ICAL_INTERNAL_ERROR; } } done = 1; } bset->changed = 0; return reterr; }
/** Sync changes from the server to the cache. * * @param cb 3E calendar backend. * * @return TRUE on success. * * @todo Handle UID/RID. * @todo Better server error handling. * @todo Conflict resolution. */ gboolean e_cal_backend_3e_sync_server_to_cache(ECalBackend3e *cb) { GError *local_err = NULL; gboolean update_sync = TRUE; icalcomponent *ical; icalcomponent *icomp; char filter[128]; struct tm tm; time_t stamp = MAX(e_cal_backend_3e_get_sync_timestamp(cb) - 60 * 60 * 24, 0); /*XXX: always add 1 day padding to prevent timezone problems */ /* prepare query filter string */ gmtime_r(&stamp, &tm); strftime(filter, sizeof(filter), "modified_since('%F %T')", &tm); ical = get_server_objects(cb, filter); if (ical == NULL) { return FALSE; } for (icomp = icalcomponent_get_first_component(ical, ICAL_ANY_COMPONENT); icomp; icomp = icalcomponent_get_next_component(ical, ICAL_ANY_COMPONENT)) { icalcomponent_kind kind = icalcomponent_isa(icomp); icalcomponent_set_cache_state(icomp, E_CAL_COMPONENT_CACHE_STATE_NONE); if (kind == ICAL_VEVENT_COMPONENT) { ECalComponent *comp; const char *uid = icalcomponent_get_uid(icomp); gboolean server_deleted = icalcomponent_3e_status_is_deleted(icomp); ECalComponentCacheState comp_state = E_CAL_COMPONENT_CACHE_STATE_NONE; g_static_rw_lock_reader_lock(&cb->priv->cache_lock); comp = e_cal_backend_cache_get_component(cb->priv->cache, uid, NULL); g_static_rw_lock_reader_unlock(&cb->priv->cache_lock); if (comp) { comp_state = e_cal_component_get_cache_state(comp); } if (server_deleted) { /* deleted by the server */ if (comp && e_cal_component_get_cache_state(comp) != E_CAL_COMPONENT_CACHE_STATE_CREATED && e_cal_component_get_cache_state(comp) != E_CAL_COMPONENT_CACHE_STATE_MODIFIED) { char *object = e_cal_component_get_as_string(comp); ECalComponentId *id = e_cal_component_get_id(comp); g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_remove_component(cb->priv->cache, uid, NULL); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); e_cal_backend_notify_object_removed(E_CAL_BACKEND(cb), id, object, NULL); e_cal_component_free_id(id); g_free(object); } } else { char *old_object = NULL; char *object; ECalComponent *new_comp = e_cal_component_new(); e_cal_component_set_icalcomponent(new_comp, icalcomponent_new_clone(icomp)); e_cal_component_set_cache_state(new_comp, E_CAL_COMPONENT_CACHE_STATE_NONE); e_cal_backend_3e_convert_attachment_uris_to_local(cb, new_comp); if (comp) { old_object = e_cal_component_get_as_string(comp); } object = e_cal_component_get_as_string(new_comp); if (old_object == NULL) { if (e_cal_backend_3e_download_attachments(cb, new_comp, &local_err)) { /* not in cache yet */ g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_put_component(cb->priv->cache, new_comp); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); e_cal_backend_notify_object_created(E_CAL_BACKEND(cb), object); } else { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "Can't download attachment.", local_err); g_clear_error(&local_err); update_sync = FALSE; } } else if (strcmp(old_object, object)) { /* what is in cache and what is on server differs */ if (comp_state != E_CAL_COMPONENT_CACHE_STATE_NONE) { /* modified in cache, don't do anything */ } else { if (e_cal_backend_3e_download_attachments(cb, new_comp, &local_err)) { /* sync with server */ g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_put_component(cb->priv->cache, new_comp); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); e_cal_backend_notify_object_modified(E_CAL_BACKEND(cb), old_object, object); } else { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "Can't download attachment.", local_err); g_clear_error(&local_err); update_sync = FALSE; } } } g_free(old_object); g_free(object); g_object_unref(new_comp); } if (comp) { g_object_unref(comp); } } else if (kind == ICAL_VTIMEZONE_COMPONENT) { const char *tzid = icalcomponent_get_tzid(icomp); /* import non-existing timezones from the server */ if (!e_cal_backend_cache_get_timezone(cb->priv->cache, tzid)) { icaltimezone *zone = icaltimezone_new(); icalcomponent *zone_comp = icalcomponent_new_clone(icomp); if (icaltimezone_set_component(zone, zone_comp)) { g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_put_timezone(cb->priv->cache, zone); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); } else { icalcomponent_free(zone_comp); } icaltimezone_free(zone, 1); } } else { g_warning("Unsupported component kind (%d) found on the 3e server.", kind); } } if (update_sync) { e_cal_backend_3e_set_sync_timestamp(cb, time(NULL)); } icalcomponent_free(ical); return TRUE; }
/* Add all ZONEs and LINKs in the given directory to the hash table */ void do_zonedir(const char *dir, struct hash_table *tzentries, struct zoneinfo *info) { DIR *dirp; struct dirent *dirent; signals_poll(); if (verbose) printf("Rebuilding %s\n", dir); dirp = opendir(dir); if (!dirp) { fprintf(stderr, "can't open zoneinfo directory %s\n", dir); } while ((dirent = readdir(dirp))) { char path[2048], *tzid; int plen; struct stat sbuf; struct zoneinfo *zi; if (*dirent->d_name == '.') continue; plen = snprintf(path, sizeof(path), "%s/%s", dir, dirent->d_name); lstat(path, &sbuf); if (S_ISDIR(sbuf.st_mode)) { /* Path is a directory (region) */ do_zonedir(path, tzentries, info); } else if (S_ISLNK(sbuf.st_mode)) { /* Path is a symlink (alias) */ char link[1024], *alias; ssize_t llen; /* Isolate tzid in path */ if ((llen = readlink(path, link, sizeof(link))) < 0) continue; link[llen-4] = '\0'; /* Trim ".ics" */ for (tzid = link; !strncmp(tzid, "../", 3); tzid += 3); /* Isolate alias in path */ path[plen-4] = '\0'; /* Trim ".ics" */ alias = path + strlen(config_dir) + strlen("zoneinfo") + 2; if (verbose) printf("\tLINK: %s -> %s\n", alias, tzid); /* Create hash entry for alias */ if (!(zi = hash_lookup(alias, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(alias, zi, tzentries); } zi->type = ZI_LINK; appendstrlist(&zi->data, tzid); /* Create/update hash entry for tzid */ if (!(zi = hash_lookup(tzid, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(tzid, zi, tzentries); } zi->type = ZI_ZONE; appendstrlist(&zi->data, alias); } else if (S_ISREG(sbuf.st_mode)) { /* Path is a regular file (zone) */ int fd; const char *base = NULL; size_t len = 0; icalcomponent *ical, *comp; icalproperty *prop; /* Parse the iCalendar file for important properties */ if ((fd = open(path, O_RDONLY)) == -1) continue; map_refresh(fd, 1, &base, &len, MAP_UNKNOWN_LEN, path, NULL); close(fd); ical = icalparser_parse_string(base); map_free(&base, &len); if (!ical) continue; /* skip non-iCalendar files */ comp = icalcomponent_get_first_component(ical, ICAL_VTIMEZONE_COMPONENT); prop = icalcomponent_get_first_property(comp, ICAL_TZID_PROPERTY); tzid = (char *) icalproperty_get_value_as_string(prop); if (verbose) printf("\tZONE: %s\n", tzid); /* Create/update hash entry for tzid */ if (!(zi = hash_lookup(tzid, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(tzid, zi, tzentries); } zi->type = ZI_ZONE; prop = icalcomponent_get_first_property(comp, ICAL_LASTMODIFIED_PROPERTY); zi->dtstamp = icaltime_as_timet(icalproperty_get_lastmodified(prop)); icalcomponent_free(ical); /* Check overall lastmod */ if (zi->dtstamp > info->dtstamp) info->dtstamp = zi->dtstamp; } else { fprintf(stderr, "unknown path type %s\n", path); } } closedir(dirp); }