Пример #1
0
/* 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);
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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);
			}
		}
	}
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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);
}
Пример #14
0
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);
}