/* Get_free_busy handler for the file backend */ static void e_cal_backend_http_get_free_busy (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const GSList *users, time_t start, time_t end, GSList **freebusy, GError **error) { ESourceRegistry *registry; ECalBackendHttp *cbhttp; ECalBackendHttpPrivate *priv; gchar *address, *name; icalcomponent *vfb; gchar *calobj; cbhttp = E_CAL_BACKEND_HTTP (backend); priv = cbhttp->priv; if (!priv->store) { g_propagate_error (error, EDC_ERROR (NoSuchCal)); return; } registry = e_cal_backend_get_registry (E_CAL_BACKEND (backend)); if (users == NULL) { if (e_cal_backend_mail_account_get_default (registry, &address, &name)) { vfb = create_user_free_busy (cbhttp, address, name, start, end); calobj = icalcomponent_as_ical_string_r (vfb); *freebusy = g_slist_append (*freebusy, calobj); icalcomponent_free (vfb); g_free (address); g_free (name); } } else { const GSList *l; for (l = users; l != NULL; l = l->next ) { address = l->data; if (e_cal_backend_mail_account_is_valid (registry, address, &name)) { vfb = create_user_free_busy (cbhttp, address, name, start, end); calobj = icalcomponent_as_ical_string_r (vfb); *freebusy = g_slist_append (*freebusy, calobj); icalcomponent_free (vfb); g_free (name); } } } }
static void set_data_and_props (SunOneInvitationList *list, int row) { SunOneInvitationListPrivate *priv = list->priv; BonoboControlFrame *control_frame; Bonobo_PropertyBag prop_bag; ECalComponent *comp; icalcomponent *top_level; char *string; CORBA_Environment ev; if (row == -1) { set_data (BONOBO_WIDGET (priv->control), ""); return; } comp = sunone_invitation_list_model_get_comp (priv->model, row); if (!comp) return; /* Set the from address on the control */ control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (priv->control)); prop_bag = bonobo_control_frame_get_control_property_bag (control_frame, NULL); if (prop_bag != CORBA_OBJECT_NIL){ ECalComponentOrganizer organizer; CORBA_exception_init (&ev); e_cal_component_get_organizer (comp, &organizer); bonobo_property_bag_client_set_value_string (prop_bag, "from_address", organizer.value, &ev); CORBA_exception_init (&ev); bonobo_property_bag_client_set_value_gint (prop_bag, "view_only", 1, &ev); Bonobo_Unknown_unref (prop_bag, &ev); CORBA_exception_free (&ev); } /* Send the icalendar code over */ top_level = toplevel_with_zones (list, comp); string = icalcomponent_as_ical_string_r (top_level); set_data (BONOBO_WIDGET (priv->control), string); g_free (string); icalcomponent_free (top_level); }
icalcomponent *icalcluster_get_component(icalcluster *impl) { icalerror_check_arg_rz((impl!=0),"cluster"); if (icalcomponent_isa(impl->data) != ICAL_XROOT_COMPONENT) { char *obj; icalerror_warn("The top component is not an XROOT"); obj = icalcomponent_as_ical_string_r(impl->data); fprintf(stderr, "%s\n", obj); free(obj); abort(); } return impl->data; }
static gchar * test_get_default_object (ECal *client) { icalcomponent *icalcomp; GError *error = NULL; gchar *ical_string; if (e_cal_get_default_object (client, &icalcomp, &error)) { ical_string = icalcomponent_as_ical_string_r (icalcomp); cl_printf (client, "Obtained default object: %s\n", ical_string); g_free (ical_string); tests_passed++; return NULL; } else cl_printf (client, "Test Get default object : Could not get the default object: %s\n", error->message); return error->message; }
static const gchar * test_get_object (ECal *client) { const gchar *uid = "20040213T055519Z-15802-500-1-3@testcal"; gchar *actual; icalcomponent *icalcomp; gboolean compare; GError *error = NULL; if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) { cl_printf (client, "Test Get object : Could not get the object: %s\n", error->message); return error->message; } actual = icalcomponent_as_ical_string_r (icalcomp); compare = !strcmp (actual, EXPECTED); g_free (actual); mu_assert ("Test : get_object does not match the expected output", compare); return NULL; }
int icalmime_test(char* (*get_string)(char *s, size_t size, void *d), void *data) { char *out; struct sspm_part *parts; int i; if ( (parts = (struct sspm_part *) malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(parts,0,sizeof(parts)); sspm_parse_mime(parts, NUM_PARTS, /* Max parts */ icalmime_local_action_map, /* Actions */ get_string, data, /* data for get_string*/ 0 /* First header */); for(i = 0; i <NUM_PARTS && parts[i].header.major != SSPM_NO_MAJOR_TYPE ; i++){ if(parts[i].header.minor == SSPM_CALENDAR_MINOR_TYPE){ parts[i].data = icalcomponent_as_ical_string_r((icalcomponent*)parts[i].data); } } sspm_write_mime(parts,NUM_PARTS,&out,"To: [email protected]"); printf("%s\n",out); free(out); return 0; }
/** * e_cal_backend_sync_get_timezone: * @backend: An ECalBackendSync object. * @cal: An EDataCal object. * @cancellable: a #GCancellable for the operation * @tzid: ID of the timezone to retrieve. * @tzobject: Placeholder for the returned timezone. * @error: Out parameter for a #GError. * * Calls the get_timezone_sync method on the given backend. * This method is not mandatory on the backend, because here * is used internal_get_timezone call to fetch timezone from * it and that is transformed to a string. In other words, * any object deriving from ECalBackendSync can implement only * internal_get_timezone and can skip implementation of * get_timezone_sync completely. */ void e_cal_backend_sync_get_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzid, gchar **tzobject, GError **error) { e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_SYNC (backend), InvalidArg); if (E_CAL_BACKEND_SYNC_GET_CLASS (backend)->get_timezone_sync) { LOCK_WRAPPER (get_timezone_sync, (backend, cal, cancellable, tzid, tzobject, error)); } if (tzobject && !*tzobject) { icaltimezone *zone = NULL; if (backend->priv->mutex_lock) g_mutex_lock (backend->priv->sync_mutex); zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (backend), tzid); if (backend->priv->mutex_lock) g_mutex_unlock (backend->priv->sync_mutex); if (!zone) { g_propagate_error (error, e_data_cal_create_error (ObjectNotFound, NULL)); } else { icalcomponent *icalcomp; icalcomp = icaltimezone_get_component (zone); if (!icalcomp) { g_propagate_error (error, e_data_cal_create_error (InvalidObject, NULL)); } else { *tzobject = icalcomponent_as_ical_string_r (icalcomp); } } } }
static gboolean list_uids (ECal *client) { GList *objects = NULL; GList *l; if (!e_cal_get_object_list (client, "(contains? \"any\" \"test\")", &objects, NULL)) return FALSE; cl_printf (client, "UIDS: "); cl_printf (client, "\nGot %d objects\n", g_list_length (objects)); if (!objects) printf ("none\n"); else { for (l = objects; l; l = l->next) { const gchar *uid; uid = icalcomponent_get_uid (l->data); printf ("`%s' ", uid); } printf ("\n"); for (l = objects; l; l = l->next) { gchar *obj = icalcomponent_as_ical_string_r (l->data); printf ("------------------------------\n"); printf ("%s", obj); printf ("------------------------------\n"); free (obj); } } e_cal_free_object_list (objects); return FALSE; }
static gchar * e_cal_backend_http_get_backend_property (ECalBackend *backend, const gchar *prop_name) { g_return_val_if_fail (prop_name != NULL, NULL); if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) { return g_strjoin ( "," CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS, CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED, NULL); } else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS) || g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) { /* A HTTP backend has no particular email address associated * with it (although that would be a useful feature some day). */ return NULL; } else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_DEFAULT_OBJECT)) { icalcomponent *icalcomp; icalcomponent_kind kind; gchar *prop_value; kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend)); icalcomp = e_cal_util_new_component (kind); prop_value = icalcomponent_as_ical_string_r (icalcomp); icalcomponent_free (icalcomp); return prop_value; } /* Chain up to parent's get_backend_property() method. */ return E_CAL_BACKEND_CLASS (e_cal_backend_http_parent_class)-> get_backend_property (backend, prop_name); }
/** * 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; }
static gboolean write_calendar (const gchar *uid, GOutputStream *stream, gint dur_type, gint dur_value, GError **error) { EShell *shell; ESource *source; ESourceRegistry *registry; EClient *client = NULL; GSList *objects = NULL; icaltimezone *utc; time_t start = time (NULL), end; icalcomponent *top_level; gchar *email = NULL; GSList *users = NULL; gulong handler_id; gboolean success = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); switch (dur_type) { case FB_DURATION_DAYS: end = time_add_day_with_zone (start, dur_value, utc); break; default: case FB_DURATION_WEEKS: end = time_add_week_with_zone (start, dur_value, utc); break; case FB_DURATION_MONTHS: end = time_add_month_with_zone (start, dur_value, utc); break; } shell = e_shell_get_default (); registry = e_shell_get_registry (shell); source = e_source_registry_ref_source (registry, uid); if (source != NULL) { EClientCache *client_cache; client_cache = e_shell_get_client_cache (shell); client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error); g_object_unref (source); } else { g_set_error ( error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR, _("Invalid source UID '%s'"), uid); } if (client == NULL) return FALSE; if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) { if (email && *email) users = g_slist_append (users, email); } top_level = e_cal_util_new_top_level (); handler_id = g_signal_connect ( client, "free-busy-data", G_CALLBACK (free_busy_data_cb), &objects); success = e_cal_client_get_free_busy_sync ( E_CAL_CLIENT (client), start, end, users, NULL, error); if (handler_id > 0) g_signal_handler_disconnect (client, handler_id); if (success) { gchar *ical_string; GSList *iter; gboolean done = FALSE; /* This is to workaround broken dispatch of "free-busy-data" signal, * introduced in 3.8.0. This code can be removed once the below bug is * properly fixed: https://bugzilla.gnome.org/show_bug.cgi?id=692361 */ while (!done) { g_usleep (G_USEC_PER_SEC / 10); done = !g_main_context_iteration (NULL, FALSE); } for (iter = objects; iter; iter = iter->next) { ECalComponent *comp = iter->data; icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); icalcomponent_add_component (top_level, icalcomp); } ical_string = icalcomponent_as_ical_string_r (top_level); success = g_output_stream_write_all ( stream, ical_string, strlen (ical_string), NULL, NULL, error); e_cal_client_free_ecalcomp_slist (objects); g_free (ical_string); } if (users) g_slist_free (users); g_free (email); g_object_unref (client); icalcomponent_free (top_level); return success; }
static void do_save_calendar_ical (FormatHandler *handler, ESourceSelector *selector, EClientCache *client_cache, gchar *dest_uri) { ESource *primary_source; EClient *source_client; GError *error = NULL; GSList *objects = NULL; icalcomponent *top_level = NULL; if (!dest_uri) return; /* open source client */ primary_source = e_source_selector_ref_primary_selection (selector); source_client = e_client_cache_get_client_sync (client_cache, primary_source, e_source_selector_get_extension_name (selector), 30, NULL, &error); g_object_unref (primary_source); /* Sanity check. */ g_return_if_fail ( ((source_client != NULL) && (error == NULL)) || ((source_client == NULL) && (error != NULL))); if (error != NULL) { display_error_message ( gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message); g_error_free (error); return; } /* create destination file */ top_level = e_cal_util_new_top_level (); e_cal_client_get_object_list_sync ( E_CAL_CLIENT (source_client), "#t", &objects, NULL, &error); if (objects != NULL) { CompTzData tdata; GOutputStream *stream; GSList *iter; tdata.zones = g_hash_table_new (g_str_hash, g_str_equal); tdata.client = E_CAL_CLIENT (source_client); for (iter = objects; iter; iter = iter->next) { icalcomponent *icalcomp = icalcomponent_new_clone (iter->data); icalcomponent_foreach_tzid (icalcomp, insert_tz_comps, &tdata); icalcomponent_add_component (top_level, icalcomp); } g_hash_table_foreach (tdata.zones, (GHFunc) append_tz_to_comp, top_level); g_hash_table_destroy (tdata.zones); tdata.zones = NULL; /* save the file */ stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (selector))), dest_uri, &error); if (stream) { gchar *ical_str = icalcomponent_as_ical_string_r (top_level); g_output_stream_write_all (stream, ical_str, strlen (ical_str), NULL, NULL, &error); g_output_stream_close (stream, NULL, NULL); g_object_unref (stream); g_free (ical_str); } e_cal_client_free_icalcomp_slist (objects); } if (error != NULL) { display_error_message ( gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message); g_error_free (error); } /* terminate */ g_object_unref (source_client); icalcomponent_free (top_level); }
static gboolean write_calendar (const gchar *uid, GOutputStream *stream, gint dur_type, gint dur_value, GError **error) { EShell *shell; ESource *source; ESourceRegistry *registry; EClient *client = NULL; GSList *objects = NULL; icaltimezone *utc; time_t start = time (NULL), end; icalcomponent *top_level; gchar *email = NULL; GSList *users = NULL; gboolean success = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); switch (dur_type) { case FB_DURATION_DAYS: end = time_add_day_with_zone (start, dur_value, utc); break; default: case FB_DURATION_WEEKS: end = time_add_week_with_zone (start, dur_value, utc); break; case FB_DURATION_MONTHS: end = time_add_month_with_zone (start, dur_value, utc); break; } shell = e_shell_get_default (); registry = e_shell_get_registry (shell); source = e_source_registry_ref_source (registry, uid); if (source != NULL) { EClientCache *client_cache; client_cache = e_shell_get_client_cache (shell); client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error); g_object_unref (source); } else { g_set_error ( error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR, _("Invalid source UID “%s”"), uid); } if (client == NULL) return FALSE; if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) { if (email && *email) users = g_slist_append (users, email); } top_level = e_cal_util_new_top_level (); success = e_cal_client_get_free_busy_sync ( E_CAL_CLIENT (client), start, end, users, &objects, NULL, error); if (success) { gchar *ical_string; GSList *iter; for (iter = objects; iter; iter = iter->next) { ECalComponent *comp = iter->data; icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); icalcomponent_add_component (top_level, icalcomp); } ical_string = icalcomponent_as_ical_string_r (top_level); success = g_output_stream_write_all ( stream, ical_string, strlen (ical_string), NULL, NULL, error); e_cal_client_free_ecalcomp_slist (objects); g_free (ical_string); } if (users) g_slist_free (users); g_free (email); g_object_unref (client); icalcomponent_free (top_level); return success; }
static void cal_backend_get_timezone (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *cancellable, const gchar *tzid) { GError *error = NULL; gchar *object = NULL; e_cal_backend_sync_get_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, tzid, &object, &error); if (!object && tzid) { /* fallback if tzid contains only the location of timezone */ gint i, slashes = 0; for (i = 0; tzid[i]; i++) { if (tzid[i] == '/') slashes++; } if (slashes == 1) { icalcomponent *icalcomp = NULL, *free_comp = NULL; icaltimezone *zone = icaltimezone_get_builtin_timezone (tzid); if (!zone) { /* Try fetching the timezone from zone directory. There are some timezones like MST, US/Pacific etc. which do not appear in zone.tab, so they will not be available in the libical builtin timezone */ icalcomp = free_comp = icaltzutil_fetch_timezone (tzid); } if (zone) icalcomp = icaltimezone_get_component (zone); if (icalcomp) { icalcomponent *clone = icalcomponent_new_clone (icalcomp); icalproperty *prop; prop = icalcomponent_get_first_property (clone, ICAL_TZID_PROPERTY); if (prop) { /* change tzid to our, because the component has the buildin tzid */ icalproperty_set_tzid (prop, tzid); object = icalcomponent_as_ical_string_r (clone); g_clear_error (&error); } icalcomponent_free (clone); } if (free_comp) icalcomponent_free (free_comp); } /* also cache this timezone to backend */ if (object) e_cal_backend_sync_add_timezone (E_CAL_BACKEND_SYNC (backend), cal, cancellable, object, NULL); } e_data_cal_respond_get_timezone (cal, opid, error, object); g_free (object); }