gint
main (gint argc,
      gchar **argv)
{
	EBookClient *book_client;
	const gchar *query_string;
	EBookQuery *query;
	gchar *sexp;
	GSList *c, *contacts;
	GError *error = NULL;

	main_initialize ();

	if (argc != 2) {
		query_string = "contains \"full_name\" \"a\"";
		printf ("usage: test-search <query>\n");
		printf ("   using default query \"%s\"\n", query_string);
	} else {
		query_string = argv[1];
	}

	query = e_book_query_from_string (query_string);
	if (!query) {
		fprintf (stderr, " * Failed to parse query string '%s'\n", query_string);
		return 1;
	}

	sexp = e_book_query_to_string (query);
	e_book_query_unref (query);

	book_client = open_system_book (FALSE);
	if (!book_client) {
		g_free (sexp);
		return 1;
	}

	if (!e_book_client_get_contacts_sync (book_client, sexp, &contacts, NULL, &error)) {
		report_error ("get contacts sync", &error);
		g_free (sexp);
		g_object_unref (book_client);
		return 1;
	}

	for (c = contacts; c; c = c->next) {
		EContact *contact = E_CONTACT (c->data);
		gchar *vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);

		printf ("%s\n\n", vcard);

		g_free (vcard);
	}

	g_slist_foreach (contacts, (GFunc) g_object_unref, NULL);
	g_slist_free (contacts);

	g_free (sexp);
	g_object_unref (book_client);

	return 0;
}
/**
 * e_book_backend_db_cache_add_contact:
 * @db: DB Handle
 * @contact: an #EContact
 *
 * Adds @contact to @cache.
 *
 * Returns: %TRUE if the contact was cached successfully, %FALSE otherwise.
 **/
gboolean
e_book_backend_db_cache_add_contact (DB *db,
                                     EContact *contact)
{
	DBT	uid_dbt, vcard_dbt;
	gint	db_error;
	gchar	*vcard_str;
	const gchar *uid;

	uid = e_contact_get_const (contact, E_CONTACT_UID);
	if (!uid) {
		printf ("no uid\n");
		printf (
			"name:%s, email:%s\n",
			(gchar *) e_contact_get (contact, E_CONTACT_GIVEN_NAME),
			(gchar *) e_contact_get (contact, E_CONTACT_EMAIL_1));
		return FALSE;
	}
	string_to_dbt (uid, &uid_dbt);

	vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
	string_to_dbt (vcard_str, &vcard_dbt);

	/* db_error = db->del (db, NULL, &uid_dbt, 0); */
	db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);

	g_free (vcard_str);

	if (db_error != 0) {
		g_warning ("db->put failed with %d", db_error);
		return FALSE;
	}
	else
		return TRUE;
}
OpenAB_Storage::StorageItem* EDSContactsStorageItemIterator::next()
{
  GError * gerror   = NULL;

  static GSList * cont = NULL;
  if (NULL == cont)
  {
    if (eFetchContactsOK != fetchContacts(1000))
    {
      return NULL;
    }
    cont = contacts;
  }

  EContact *data = static_cast<EContact *>(cont->data);
  char * vcard = e_vcard_to_string (E_VCARD (data), EVC_FORMAT_VCARD_30);
  const char * id   = (const char *)e_contact_get_const(data,E_CONTACT_UID);
  const char * rev  = (const char *)e_contact_get_const(data,E_CONTACT_REV);

  elem.id = id;
  OpenAB::PIMContactItem* newItem = new OpenAB::PIMContactItem();
  newItem->parse(vcard);
  newItem->setId(id);
  newItem->setRevision(rev);
  elem.item = newItem;

  g_free(vcard);

  cont = cont->next;

  GERROR_FREE(gerror);
  return &elem;
}
static void
scan_objects (gpointer data, gpointer user_data)
{
    ScanContext *context;
    ScalixContact *contact;
    EBookBackendSExp *sexp;
    char *ostr;
    gboolean is_search;

    context = (ScanContext *) user_data;
    contact = SCALIX_CONTACT (data);
    sexp = context->sexp;
    is_search = context->search_needed;

    if (!is_search
        || e_book_backend_sexp_match_contact (sexp, E_CONTACT (contact))) {

        if (context->return_objects == TRUE) {
            context->obj_list =
                g_list_prepend (context->obj_list, g_object_ref (contact));
        } else {
            ostr = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
            context->obj_list = g_list_prepend (context->obj_list, ostr);
        }
    }
}
static gboolean
transfer_contacts_cb (EMapiConnection *conn,
		      TALLOC_CTX *mem_ctx,
		      /* const */ EMapiObject *object,
		      guint32 obj_index,
		      guint32 obj_total,
		      gpointer user_data,
		      GCancellable *cancellable,
		      GError **perror)
{
	struct TransferContactsData *tcd = user_data;
	EContact *contact;

	g_return_val_if_fail (tcd != NULL, FALSE);
	g_return_val_if_fail (object != NULL, FALSE);
	g_return_val_if_fail (tcd->ebma != NULL, FALSE);

	contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tcd->ebma));
	if (contact) {
		if (tcd->cards)
			*tcd->cards = g_slist_prepend (*tcd->cards, e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));

		if (!e_book_backend_mapi_notify_contact_update (tcd->ebma, tcd->book_view, contact, obj_index, obj_total, FALSE, tcd->notify_contact_data)) {
			g_object_unref (contact);
			return FALSE;
		}

		g_object_unref (contact);
	} else {
		g_debug ("%s: [%d/%d] Failed to transform to contact", G_STRFUNC, obj_index, obj_total);
	}

	return TRUE;
}
int
main (int argc, char **argv)
{
	EBook *book;
	EContact *contact;
	GError *error = NULL;
	char *vcard;

	g_type_init ();

	printf ("getting the self contact\n");

	if (!e_book_get_self (&contact, &book, &error)) {
		printf ("error %d getting self: %s\n", error->code, error->message);
		g_clear_error (&error);
		return -1;
	}

	vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
	printf ("self contact = \n%s\n", vcard);
	g_free (vcard);

	g_object_unref (contact);
	g_object_unref (book);

	return 0;
}
示例#7
0
static char *evcard_to_string(EVCard *evcard, unsigned int format,
							uint64_t filter)
{
	EVCard *evcard2;
	GList *l;
	char *vcard;

	if (!filter)
		return e_vcard_to_string(evcard, EVC_FORMAT_VCARD_30);
		/* XXX There is no support for VCARD 2.1 at this time */

	/*
	 * Mandatory attributes for vCard 2.1 are VERSION ,N and TEL.
	 * Mandatory attributes for vCard 3.0 are VERSION, N, FN and TEL
	 */
	filter = format == EVC_FORMAT_VCARD_30 ? filter | 0x87: filter | 0x85;

	l = e_vcard_get_attributes(evcard);
	evcard2 = e_vcard_new();
	for (; l; l = g_list_next(l)) {
		EVCardAttribute *attrib = l->data;
		const char *name;
		int i;

		if (!attrib)
			continue;

		name = e_vcard_attribute_get_name(attrib);

		for (i = 0; attribute_mask[i] != NULL; i++) {
			if (!(filter & (1 << i)))
				continue;
			if (g_strcmp0(name, attribute_mask[i]) != 0)
				continue;

			e_vcard_add_attribute(evcard2,
					e_vcard_attribute_copy(attrib));
		}
	}

	vcard = e_vcard_to_string(evcard2, format);
	g_object_unref(evcard2);

	return vcard;
}
gint
main (gint argc,
      gchar **argv)
{
	FILE *fp;
	EVCard *vcard;
	GString *str = g_string_new ("");
	gchar *parsed_vcard;

	if (argc < 2) {
		g_warning ("Requires one parameter, a vCard file\n");
		return 1;
	}

	fp = fopen (argv[1], "r");
	if (fp == NULL) {
		g_warning ("Faile to open vCard file '%s'", argv[1]);
		return 1;
	}

	while (!feof (fp)) {
		gchar buf[1024];
		if (fgets (buf, sizeof (buf), fp))
			str = g_string_append (str, buf);
	}
	fclose (fp);

	vcard = e_vcard_new_from_string (str->str);
	g_string_free (str, TRUE);

	e_vcard_dump_structure (vcard);

	parsed_vcard = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_21);
	printf ("\nvCard 2.1: %s\n", parsed_vcard);
	g_free (parsed_vcard);

	parsed_vcard = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);
	printf ("\nvCard 3.0: %s\n", parsed_vcard);
	g_free (parsed_vcard);

	g_object_unref (vcard);

	return 0;
}
gint
main (gint argc,
      gchar **argv)
{
#if 0  /* ACCOUNT_MGMT */
	EBook *book;
	gboolean status;
	EBookQuery *query;
	GList *c, *contacts;

	g_type_init ();

	if (argc < 3) {
		printf ("usage: test-search <addressbook uri> <query>\n");
		exit (0);
	}

	query = e_book_query_from_string (argv[2]);
	if (!query) {
		printf ("failed to parse query string '%s'\n", argv[2]);
		exit (0);
	}

	book = e_book_new_system_addressbook (NULL);
	if (!book) {
		printf ("failed to create ebook\n");
		exit (0);
	}

	status = e_book_open (book, TRUE, NULL);
	if (status == FALSE) {
		printf ("failed to open addressbook\n");
		exit (0);
	}

	status = e_book_get_contacts (book, query, &contacts, NULL);
	if (status == FALSE) {
		printf ("failed to get contacts\n");
		exit (0);
	}

	for (c = contacts; c; c = c->next) {
		EContact *contact = E_CONTACT (c->data);

		printf ("%s\n", e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));

		g_object_unref (contact);
	}

	g_list_free (contacts);

	g_object_unref (book);
#endif /* ACCOUNT_MGMT */

	return 0;
}
static void
insert_contact (EBookBackendVCF *vcf, gchar *vcard)
{
	EContact *contact = e_contact_new_from_vcard (vcard);
	gchar *id;

	id = e_contact_get (contact, E_CONTACT_UID);
	if (id) {
		gchar *vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);

		vcf->priv->contact_list = g_list_prepend (vcf->priv->contact_list, vcard);

		g_hash_table_insert (vcf->priv->contacts,
				     id,
				     vcf->priv->contact_list);
	}
}
static void
e_book_backend_webdav_get_contact_list (EBookBackend *backend,
                                        EDataBook *book,
                                        guint32 opid,
                                        GCancellable *cancellable,
                                        const gchar *query)
{
	EBookBackendWebdav        *webdav = E_BOOK_BACKEND_WEBDAV (backend);
	EBookBackendWebdavPrivate *priv   = webdav->priv;
	GList                     *contact_list;
	GSList                    *vcard_list;
	GList                     *c;

	if (e_backend_get_online (E_BACKEND (backend))) {
		/* make sure the cache is up to date */
		GError *error = download_contacts (webdav, NULL, NULL, cancellable);

		if (error) {
			e_data_book_respond_get_contact_list (book, opid, error, NULL);
			return;
		}
	}

	/* answer query from cache */
	g_mutex_lock (&priv->cache_lock);
	contact_list = e_book_backend_cache_get_contacts (priv->cache, query);
	g_mutex_unlock (&priv->cache_lock);

	vcard_list   = NULL;
	for (c = contact_list; c != NULL; c = g_list_next (c)) {
		EContact *contact = c->data;
		gchar     *vcard
			= e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
		vcard_list = g_slist_append (vcard_list, vcard);
		g_object_unref (contact);
	}
	g_list_free (contact_list);

	e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (SUCCESS), vcard_list);

	g_slist_foreach (vcard_list, (GFunc) g_free, NULL);
	g_slist_free (vcard_list);
}
示例#12
0
gchar *
eab_contact_list_to_string (const GSList *contacts)
{
	GString *str = g_string_new ("");
	const GSList *l;

	for (l = contacts; l; l = l->next) {
		EContact *contact = l->data;
		gchar *vcard_str;

		e_contact_inline_local_photos (contact, NULL);
		vcard_str = e_vcard_to_string (
			E_VCARD (contact), EVC_FORMAT_VCARD_30);

		g_string_append (str, vcard_str);
		if (l->next)
			g_string_append (str, "\r\n\r\n");
	}

	return g_string_free (str, FALSE);
}
static EContact *
do_create (EBookBackendVCF  *bvcf,
	  const gchar     *vcard_req,
	  gboolean        dirty_the_file)
{
	gchar           *id;
	EContact       *contact;
	gchar           *vcard;
	const gchar     *rev;

	/* at the very least we need the unique_id generation to be
	   protected by the lock, even if the actual vcard parsing
	   isn't. */
	g_mutex_lock (bvcf->priv->mutex);
	id = e_book_backend_vcf_create_unique_id ();

	contact = e_contact_new_from_vcard (vcard_req);
	e_contact_set (contact, E_CONTACT_UID, id);
	g_free (id);

	rev = e_contact_get_const (contact,  E_CONTACT_REV);
	if (!(rev && *rev))
		set_revision (contact);

	vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);

	insert_contact (bvcf, vcard);

	if (dirty_the_file) {
		bvcf->priv->dirty = TRUE;

		if (!bvcf->priv->flush_timeout_tag)
			bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
								       vcf_flush_file, bvcf);
	}

	g_mutex_unlock (bvcf->priv->mutex);

	return contact;
}
/**
 * e_data_book_view_notify_update:
 * @book_view: an #EDataBookView
 * @contact: an #EContact
 *
 * Notify listeners that @contact has changed. This can
 * trigger an add, change or removal event depending on
 * whether the change causes the contact to start matching,
 * no longer match, or stay matching the query specified
 * by @book_view.
 **/
void
e_data_book_view_notify_update (EDataBookView *book_view,
                                EContact      *contact)
{
    EDataBookViewPrivate *priv = book_view->priv;
    gboolean currently_in_view, want_in_view;
    const gchar *id;
    gchar *vcard;

    if (!priv->running)
        return;

    g_mutex_lock (priv->pending_mutex);

    id = e_contact_get_const (contact, E_CONTACT_UID);

    currently_in_view = id_is_in_view (book_view, id);
    want_in_view =
        e_book_backend_sexp_match_contact (priv->card_sexp, contact);

    if (want_in_view) {
        vcard = e_vcard_to_string (E_VCARD (contact),
                                   EVC_FORMAT_VCARD_30);

        if (currently_in_view)
            notify_change (book_view, vcard);
        else
            notify_add (book_view, id, vcard);

        g_free (vcard);
    } else {
        if (currently_in_view)
            notify_remove (book_view, id);
        /* else nothing; we're removing a card that wasn't there */
    }

    g_mutex_unlock (priv->pending_mutex);
}
static EBookBackendSyncStatus
e_book_backend_scalix_get_contact (EBookBackendSync * backend,
                                   EDataBook * book,
                                   guint32 opid, const char *uid, char **vcard)
{
    EBookBackendScalix *bs;
    EBookBackendScalixPrivate *priv;
    ScalixObject *object;

    bs = E_BOOK_BACKEND_SCALIX (backend);
    priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs);

    object = scalix_container_get_object (priv->container, uid);

    if (object == NULL || !E_IS_VCARD (object)) {
        return GNOME_Evolution_Addressbook_ContactNotFound;
    }

    *vcard = e_vcard_to_string (E_VCARD (object), EVC_FORMAT_VCARD_30);
    g_object_unref (object);

    return GNOME_Evolution_Addressbook_Success;
}
static void
e_book_backend_webdav_get_contact (EBookBackend *backend,
                                   EDataBook *book,
                                   guint32 opid,
                                   GCancellable *cancellable,
                                   const gchar *uid)
{
	EBookBackendWebdav        *webdav = E_BOOK_BACKEND_WEBDAV (backend);
	EBookBackendWebdavPrivate *priv   = webdav->priv;
	EContact                  *contact;
	gchar                      *vcard;

	if (!e_backend_get_online (E_BACKEND (backend))) {
		g_mutex_lock (&priv->cache_lock);
		contact = e_book_backend_cache_get_contact (priv->cache, uid);
		g_mutex_unlock (&priv->cache_lock);
	} else {
		contact = download_contact (webdav, uid, cancellable);
		/* update cache as we possibly have changes */
		if (contact != NULL) {
			g_mutex_lock (&priv->cache_lock);
			e_book_backend_cache_remove_contact (priv->cache, uid);
			e_book_backend_cache_add_contact (priv->cache, contact);
			g_mutex_unlock (&priv->cache_lock);
		}
	}

	if (contact == NULL) {
		e_data_book_respond_get_contact (book, opid, EDB_ERROR (CONTACT_NOT_FOUND), NULL);
		return;
	}

	vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
	e_data_book_respond_get_contact (book, opid, EDB_ERROR (SUCCESS), vcard);
	g_free (vcard);
	g_object_unref (contact);
}
示例#17
0
gint
main (gint argc, gchar **argv)
{
	FILE *fp;
	EVCard *vcard;
	GString *str = g_string_new ("");
	gchar *parsed_vcard;

	if (argc < 2)
	  return 0;

	g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS);

	fp = fopen (argv[1], "r");

	while (!feof (fp)) {
		gchar buf[1024];
		if (fgets (buf, sizeof (buf), fp))
			str = g_string_append (str, buf);
	}
	fclose (fp);

	vcard = e_vcard_new_from_string (str->str);

	e_vcard_dump_structure (vcard);

	parsed_vcard = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);

	printf ("\nvcard: %s\n", parsed_vcard);

	g_object_unref (vcard);

	g_free (parsed_vcard);

	return 0;
}
示例#18
0
static gboolean
test_vcard (const gchar *vcard_str)
{
	EVCard *vc1, *vc2;
	gchar *str;

	/* Do not parse */
	vc1 = e_vcard_new_from_string (vcard_str);
	str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE);

	g_free (str);

	/* parse */
	e_vcard_get_attribute (vc1, "UID");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE);
	str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);

	g_free (str);

	/* parse */
	e_vcard_get_attribute (vc1, "FN");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE);
	str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);

	g_free (str);
	g_object_unref (vc1);

	/* do not parse */
	vc1 = e_vcard_new_from_string (vcard_str);
	/* Setting the UID does not cause vCard parsing */
	e_vcard_append_attribute_with_value (vc1, e_vcard_attribute_new (NULL, "UID"), "other-uid");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE);
	/* Retrieving the UID should not cause vCard parsing either */
	g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE);
	/* Getting FN attribute WILL cause parsing */
	e_vcard_get_attribute (vc1, "FN");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE);
	g_object_unref (vc1);

	/* parse */
	vc1 = e_vcard_new_from_string (vcard_str);
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == FALSE, FALSE);
	e_vcard_remove_attributes (vc1, NULL, "UID");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE);
	e_vcard_append_attribute_with_value (vc1, e_vcard_attribute_new (NULL, "UID"), "other-uid");
	g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE);
	str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30);
	vc2 = e_vcard_new_from_string (str);
	g_free (str);

	g_return_val_if_fail (compare_single_value (vc2, "UID", "other-uid"), FALSE);

	g_object_unref (vc2);

	/* parse */
	e_vcard_get_attribute (vc1, "FN");
	g_return_val_if_fail (e_vcard_is_parsed (vc1) == TRUE, FALSE);
	g_return_val_if_fail (compare_single_value (vc1, "UID", "other-uid"), FALSE);
	str = e_vcard_to_string (vc1, EVC_FORMAT_VCARD_30);
	vc2 = e_vcard_new_from_string (str);
	g_return_val_if_fail (e_vcard_is_parsed (vc2) == FALSE, FALSE);
	g_free (str);

	g_return_val_if_fail (compare_single_value (vc2, "UID", "other-uid"), FALSE);
	g_return_val_if_fail (has_only_one (vc1, "UID"), FALSE);
	g_return_val_if_fail (has_only_one (vc2, "UID"), FALSE);

	g_object_unref (vc2);
	g_object_unref (vc1);

	return TRUE;
}
示例#19
0
static gboolean
test_econtact (const gchar *vcard_str)
{
	EContact *c1, *c2;
	gchar *str;

	/* do not parse */
	c1 = e_contact_new_from_vcard (vcard_str);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == FALSE, FALSE);

	g_free (str);

	/* parse */
	e_contact_get_const (c1, E_CONTACT_UID);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == TRUE, FALSE);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);

	g_free (str);

	/* parse */
	e_contact_get_const (c1, E_CONTACT_FULL_NAME);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (g_ascii_strcasecmp (str, vcard_str) == 0, FALSE);

	g_free (str);
	g_object_unref (c1);

	/* not parsed again */
	c1 = e_contact_new_from_vcard (vcard_str);
	e_contact_set (c1, E_CONTACT_UID, "other-uid");
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == FALSE, FALSE);
	g_return_val_if_fail (compare_single_value (E_VCARD (c1), "UID", "other-uid"), FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == FALSE, FALSE);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	c2 = e_contact_new_from_vcard (str);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c2)) == FALSE, FALSE);
	g_free (str);

	g_return_val_if_fail (compare_single_value (E_VCARD (c2), "UID", "other-uid"), FALSE);

	g_object_unref (c2);

	/* parse */
	e_contact_get_const (c1, E_CONTACT_FULL_NAME);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == TRUE, FALSE);
	g_return_val_if_fail (compare_single_value (E_VCARD (c1), "UID", "other-uid"), FALSE);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	c2 = e_contact_new_from_vcard (str);
	g_free (str);

	g_return_val_if_fail (compare_single_value (E_VCARD (c2), "UID", "other-uid"), FALSE);
	g_return_val_if_fail (has_only_one (E_VCARD (c1), "UID"), FALSE);
	g_return_val_if_fail (has_only_one (E_VCARD (c2), "UID"), FALSE);

	g_object_unref (c2);
	g_object_unref (c1);

	/* do not parse */
	c1 = e_contact_new_from_vcard_with_uid (vcard_str, "other-uid");
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == FALSE, FALSE);
	g_return_val_if_fail (compare_single_value (E_VCARD (c1), "UID", "other-uid"), FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == FALSE, FALSE);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	c2 = e_contact_new_from_vcard (str);
	g_free (str);

	g_return_val_if_fail (compare_single_value (E_VCARD (c2), "UID", "other-uid"), FALSE);

	g_object_unref (c2);

	/* parse */
	e_contact_get_const (c1, E_CONTACT_FULL_NAME);
	g_return_val_if_fail (compare_single_value (E_VCARD (c1), "UID", "other-uid"), FALSE);
	g_return_val_if_fail (e_vcard_is_parsed (E_VCARD (c1)) == TRUE, FALSE);
	str = e_vcard_to_string (E_VCARD (c1), EVC_FORMAT_VCARD_30);
	c2 = e_contact_new_from_vcard (str);
	g_free (str);

	g_return_val_if_fail (compare_single_value (E_VCARD (c2), "UID", "other-uid"), FALSE);
	g_return_val_if_fail (has_only_one (E_VCARD (c1), "UID"), FALSE);
	g_return_val_if_fail (has_only_one (E_VCARD (c2), "UID"), FALSE);

	g_object_unref (c2);
	g_object_unref (c1);

	return TRUE;
}
static guint
upload_contact (EBookBackendWebdav *webdav,
                EContact *contact,
                gchar **reason,
                GCancellable *cancellable)
{
	ESource     *source;
	ESourceWebdav *webdav_extension;
	SoupMessage *message;
	gchar       *uri;
	gchar       *etag;
	const gchar  *new_etag, *redir_uri;
	gchar        *request;
	guint        status;
	gboolean     avoid_ifmatch;
	const gchar *extension_name;

	source = e_backend_get_source (E_BACKEND (webdav));

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	webdav_extension = e_source_get_extension (source, extension_name);

	source = e_backend_get_source (E_BACKEND (webdav));

	uri = e_contact_get (contact, E_CONTACT_UID);
	if (uri == NULL) {
		g_warning ("can't upload contact without UID");
		return 400;
	}

	message = soup_message_new (SOUP_METHOD_PUT, uri);
	soup_message_headers_append (message->request_headers, "User-Agent", USERAGENT);
	soup_message_headers_append (message->request_headers, "Connection", "close");

	avoid_ifmatch = e_source_webdav_get_avoid_ifmatch (webdav_extension);

	/* some servers (like apache < 2.2.8) don't handle If-Match, correctly so
	 * we can leave it out */
	if (!avoid_ifmatch) {
		/* only override if etag is still the same on the server */
		etag = e_contact_get (contact, E_CONTACT_REV);
		if (etag == NULL) {
			soup_message_headers_append (
				message->request_headers,
				"If-None-Match", "*");
		} else if (etag[0] == 'W' && etag[1] == '/') {
			g_warning ("we only have a weak ETag, don't use If-Match synchronisation");
		} else {
			soup_message_headers_append (
				message->request_headers,
				"If-Match", etag);
			g_free (etag);
		}
	}

	request = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
	soup_message_set_request (
		message, "text/vcard", SOUP_MEMORY_TEMPORARY,
		request, strlen (request));

	status   = send_and_handle_ssl (webdav, message, cancellable);
	new_etag = soup_message_headers_get_list (message->response_headers, "ETag");

	redir_uri = soup_message_headers_get_list (message->response_headers, "Location");

	/* set UID and REV fields */
	e_contact_set (contact, E_CONTACT_REV, (gconstpointer) new_etag);
	if (redir_uri && *redir_uri) {
		if (!strstr (redir_uri, "://")) {
			/* it's a relative URI */
			SoupURI *suri = soup_uri_new (uri);
			gchar *full_uri;

			soup_uri_set_path (suri, redir_uri);
			full_uri = soup_uri_to_string (suri, TRUE);

			e_contact_set (contact, E_CONTACT_UID, full_uri);

			g_free (full_uri);
			soup_uri_free (suri);
		} else {
			e_contact_set (contact, E_CONTACT_UID, redir_uri);
		}
	} else {
		e_contact_set (contact, E_CONTACT_UID, uri);
	}

	if (reason) {
		*reason = g_strdup (message->reason_phrase && *message->reason_phrase ? message->reason_phrase :
				    (soup_status_get_phrase (message->status_code) ? soup_status_get_phrase (message->status_code) : _("Unknown error")));
	}

	g_object_unref (message);
	g_free (request);
	g_free (uri);

	return status;
}
static void
ebbm_contacts_get_contact (EBookBackendMAPI *ebma, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error)
{
	EBookBackendMAPIContacts *ebmac;
	EBookBackendMAPIContactsPrivate *priv;
	EMapiConnection *conn;
	mapi_id_t mid;
	mapi_object_t obj_folder;
	struct TransferContactData tc = { 0 };
	gboolean status, has_obj_folder;
	GError *mapi_error = NULL;

	e_mapi_return_data_book_error_if_fail (ebma != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);
	e_mapi_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_MAPI_CONTACTS (ebma), E_DATA_BOOK_STATUS_INVALID_ARG);
	e_mapi_return_data_book_error_if_fail (id != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);
	e_mapi_return_data_book_error_if_fail (vcard != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);

	ebmac = E_BOOK_BACKEND_MAPI_CONTACTS (ebma);
	e_mapi_return_data_book_error_if_fail (ebmac != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);

	priv = ebmac->priv;
	e_mapi_return_data_book_error_if_fail (priv != NULL, E_DATA_BOOK_STATUS_INVALID_ARG);

	if (E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_get_contact)
		E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_get_contact (ebma, cancellable, id, vcard, &mapi_error);

	if (mapi_error) {
		g_propagate_error (error, mapi_error);
		return;
	}

	/* found in a cache */
	if (*vcard)
		return;

	e_book_backend_mapi_lock_connection (ebma);

	conn = e_book_backend_mapi_get_connection (ebma, cancellable, &mapi_error);
	if (!conn) {
		e_book_backend_mapi_unlock_connection (ebma);

		if (!mapi_error)
			g_propagate_error (error, EDB_ERROR (REPOSITORY_OFFLINE));
		else
			mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE, NULL);
		g_clear_error (&mapi_error);

		return;
	}

	status = ebbm_contacts_open_folder (ebmac, conn, &obj_folder, cancellable, &mapi_error);
	has_obj_folder = status;

	if (status) {
		status = e_mapi_util_mapi_id_from_string (id, &mid);
		if (!status) {
			g_debug ("%s: Failed to decode MID from '%s'", G_STRFUNC, id);
		}
	}

	if (status) {
		tc.ebma = ebma;
		tc.contact = NULL;

		e_mapi_connection_transfer_object (conn, &obj_folder, mid, transfer_contact_cb, &tc, cancellable, &mapi_error);
	}

	if (has_obj_folder)
		e_mapi_connection_close_folder (conn, &obj_folder, cancellable, &mapi_error);

	if (tc.contact) {
		*vcard =  e_vcard_to_string (E_VCARD (tc.contact), EVC_FORMAT_VCARD_30);
		g_object_unref (tc.contact);
	} else {
		e_book_backend_mapi_maybe_disconnect (ebma, mapi_error);

		if (!mapi_error || mapi_error->code == MAPI_E_NOT_FOUND) {
			g_propagate_error (error, EDB_ERROR (CONTACT_NOT_FOUND));
		} else {
			mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, NULL);
		}

		if (mapi_error)
			g_error_free (mapi_error);
	}

	e_book_backend_mapi_unlock_connection (ebma);
}