static void on_find_objects(GP11Session *session, GAsyncResult *result, SeahorsePkcs11Refresher *self) { GList *objects, *l; GError *err = NULL; gulong handle; g_assert (SEAHORSE_IS_PKCS11_REFRESHER (self)); objects = gp11_session_find_objects_finish (session, result, &err); if (err != NULL) { seahorse_pkcs11_mark_complete (SEAHORSE_OPERATION (self), err); return; } /* Remove all objects that were found, from the check table */ for (l = objects; l; l = g_list_next (l)) { seahorse_pkcs11_source_receive_object (self->source, l->data); handle = gp11_object_get_handle (l->data); g_hash_table_remove (self->checks, &handle); } /* Remove everything not found from the context */ g_hash_table_foreach_remove (self->checks, remove_each_object, NULL); seahorse_pkcs11_mark_complete (SEAHORSE_OPERATION (self), NULL); }
static void send_callback (SoupSession *session, SoupMessage *msg, SeahorseHKPOperation *hop) { gchar *errmsg; if (hop->cancelling) return; if (SOUP_MESSAGE_IS_ERROR (msg)) { fail_hkp_operation (hop, msg, NULL); return; } errmsg = get_send_result (msg->response_body->data); if (errmsg) { fail_hkp_operation (hop, NULL, errmsg); g_free (errmsg); return; } /* A successful status from the server is all we want in this case */ if (--hop->requests <= 0) seahorse_operation_mark_done (SEAHORSE_OPERATION (hop), FALSE, NULL); else seahorse_operation_mark_progress_full (SEAHORSE_OPERATION (hop), _("Uploading keys..."), hop->requests, hop->total); }
/* dispose of all our internal references */ static void seahorse_server_source_dispose (GObject *gobject) { SeahorseServerSource *ssrc; SeahorseSource *sksrc; /* * Note that after this executes the rest of the object should * still work without a segfault. This basically nullifies the * object, but doesn't free it. * * This function should also be able to run multiple times. */ ssrc = SEAHORSE_SERVER_SOURCE (gobject); sksrc = SEAHORSE_SOURCE (gobject); g_assert (ssrc->priv); /* Clear out all the operations */ if (ssrc->priv->mop) { if(seahorse_operation_is_running (SEAHORSE_OPERATION (ssrc->priv->mop))) seahorse_operation_cancel (SEAHORSE_OPERATION (ssrc->priv->mop)); g_object_unref (ssrc->priv->mop); ssrc->priv->mop = NULL; } G_OBJECT_CLASS (parent_class)->dispose (gobject); }
static void refresh_callback (SoupSession *session, SoupMessage *msg, SeahorseHKPOperation *hop) { GList *keys, *k; if (hop->cancelling) return; if (SOUP_MESSAGE_IS_ERROR (msg)) { fail_hkp_operation (hop, msg, NULL); return; } keys = parse_hkp_index (msg->response_body->data); for (k = keys; k; k = g_list_next (k)) add_key (hop->hsrc, SEAHORSE_PGP_KEY (k->data)); seahorse_object_list_free (keys); if (--hop->requests <= 0) seahorse_operation_mark_done (SEAHORSE_OPERATION (hop), FALSE, NULL); else seahorse_operation_mark_progress_full (SEAHORSE_OPERATION (hop), _("Searching for keys..."), hop->requests, hop->total); }
static void get_callback (SoupSession *session, SoupMessage *msg, SeahorseHKPOperation *hop) { GError *err = NULL; const gchar *start; const gchar *end; GOutputStream *output; const gchar *text; gboolean ret; guint len; gsize written; if (hop->cancelling) return; if (SOUP_MESSAGE_IS_ERROR (msg)) { fail_hkp_operation (hop, msg, NULL); return; } end = text = msg->response_body->data; len = msg->response_body->length; for (;;) { len -= end - text; text = end; if(!detect_key (text, len, &start, &end)) break; /* Any key blocks get written to our result data */ output = seahorse_operation_get_result (SEAHORSE_OPERATION (hop)); g_return_if_fail (G_IS_OUTPUT_STREAM (output)); ret = g_output_stream_write_all (output, start, end - start, &written, NULL, &err) && g_output_stream_write_all (output, "\n", 1, &written, NULL, &err) && g_output_stream_flush (output, NULL, &err); if (!ret) { seahorse_operation_mark_done (SEAHORSE_OPERATION (hop), FALSE, err); return; } } if (--hop->requests <= 0) { output = seahorse_operation_get_result (SEAHORSE_OPERATION (hop)); g_return_if_fail (G_IS_OUTPUT_STREAM (output)); g_output_stream_close (output, NULL, &err); seahorse_operation_mark_done (SEAHORSE_OPERATION (hop), FALSE, err); } else { seahorse_operation_mark_progress_full (SEAHORSE_OPERATION (hop), _("Retrieving keys..."), hop->requests, hop->total); } }
static SeahorseOperation* seahorse_hkp_source_search (SeahorseSource *src, const gchar *match) { SeahorseHKPOperation *hop; SoupMessage *message; GHashTable *form; gchar *t; SoupURI *uri; gchar hexfpr[11]; g_assert (SEAHORSE_IS_SOURCE (src)); g_assert (SEAHORSE_IS_HKP_SOURCE (src)); hop = setup_hkp_operation (SEAHORSE_HKP_SOURCE (src)); uri = get_http_server_uri (src, "/pks/lookup"); g_return_val_if_fail (uri, FALSE); form = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (form, "op", "index"); if (is_hex_keyid (match)) { strncpy (hexfpr, "0x", 3); strncpy (hexfpr + 2, match, 9); g_hash_table_insert (form, "search", hexfpr); } else g_hash_table_insert (form, "search", (char *)match); soup_uri_set_query_from_form (uri, form); g_hash_table_destroy (form); message = soup_message_new_from_uri ("GET", uri); soup_session_queue_message (hop->session, message, (SoupSessionCallback)refresh_callback, hop); hop->total = hop->requests = 1; t = g_strdup_printf (_("Searching for keys on: %s"), uri->host); seahorse_operation_mark_progress (SEAHORSE_OPERATION (hop), t, -1); g_free (t); soup_uri_free (uri); seahorse_server_source_take_operation (SEAHORSE_SERVER_SOURCE (src), SEAHORSE_OPERATION (hop)); g_object_ref (hop); return SEAHORSE_OPERATION (hop); }
static GObject* seahorse_pkcs11_refresher_constructor (GType type, guint n_props, GObjectConstructParam *props) { SeahorsePkcs11Refresher *self = SEAHORSE_PKCS11_REFRESHER (G_OBJECT_CLASS (seahorse_pkcs11_refresher_parent_class)->constructor(type, n_props, props)); GP11Slot *slot; GList *objects, *l; gulong handle; g_return_val_if_fail (self, NULL); g_return_val_if_fail (self->source, NULL); objects = seahorse_context_get_objects (NULL, SEAHORSE_SOURCE (self->source)); for (l = objects; l; l = g_list_next (l)) { if (g_object_class_find_property (G_OBJECT_GET_CLASS (l->data), "pkcs11-handle")) { g_object_get (l->data, "pkcs11-handle", &handle, NULL); g_hash_table_insert (self->checks, g_memdup (&handle, sizeof (handle)), g_object_ref (l->data)); } } g_list_free (objects); /* Step 1. Load the session */ slot = seahorse_pkcs11_source_get_slot (self->source); gp11_slot_open_session_async (slot, CKF_RW_SESSION, NULL, NULL, self->cancellable, (GAsyncReadyCallback)on_open_session, self); seahorse_operation_mark_start (SEAHORSE_OPERATION (self)); return G_OBJECT (self); }
/** * pop: a seahorse operation * gstarterr: the gpgme error that could have occured earlier * cryptdata: gpgme cryptdata * result: the result of the gpgme operation (out) * resultlength: length of the created buffer (out) (can be NULL) * error: will be set on error * * Finishes the gpgme processing and returns the result * * returns: TRUE on successful operation, FALSE else */ static gboolean process_crypto_result (SeahorseGpgmeOperation *pop, gpgme_error_t gstarterr, gpgme_data_t cryptdata, gchar **result, gsize *resultlength, GError **error) { size_t len; char *data; /* Starting the operation failed? */ if (!GPG_IS_OK (gstarterr)) { gpgme_data_release (cryptdata); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_CRYPTO, "%s", gpgme_strerror (gstarterr)); return FALSE; } /* Wait for it to finish (can run main loop stuff) */ seahorse_operation_wait (SEAHORSE_OPERATION (pop)); if (seahorse_operation_is_cancelled (SEAHORSE_OPERATION (pop))) { g_set_error (error, SEAHORSE_DBUS_CANCELLED, 0, "%s", ""); return FALSE; } else if (seahorse_operation_is_successful (SEAHORSE_OPERATION (pop))) { data = gpgme_data_release_and_get_mem (cryptdata, &len); *result = g_strndup (data, len); if (resultlength != NULL) *resultlength = (gsize)len; g_free (data); return TRUE; } else { /* A failed operation always has an error */ g_assert (seahorse_operation_get_error (SEAHORSE_OPERATION (pop))); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_CRYPTO, "%s", seahorse_operation_get_error (SEAHORSE_OPERATION (pop))->message); gpgme_data_release (cryptdata); return FALSE; } }
static void proxy_call_notification (DBusGProxy *proxy, DBusGProxyCall *call_id, void *data) { SeahorseOperation *op; op = SEAHORSE_OPERATION (data); seahorse_operation_mark_progress (op, _("Import is complete"), 1); seahorse_operation_mark_done (op, FALSE, NULL); g_free (buffer); }
static void on_deleted (GP11Object *object, GAsyncResult *result, SeahorsePkcs11Deleter *self) { GError *err = NULL; g_return_if_fail (SEAHORSE_IS_PKCS11_DELETER (self)); if (!gp11_object_destroy_finish (object, result, &err)) { /* Ignore objects that have gone away */ if (err->code != CKR_OBJECT_HANDLE_INVALID) { seahorse_pkcs11_mark_complete (SEAHORSE_OPERATION (self), err); return; } g_error_free (err); } seahorse_context_remove_object (NULL, SEAHORSE_OBJECT (self->object)); seahorse_pkcs11_mark_complete (SEAHORSE_OPERATION (self), NULL); }
static void seahorse_pkcs11_mark_complete (SeahorseOperation *self, GError *error) { SeahorseOperation *operation = SEAHORSE_OPERATION (self); if (error == NULL) seahorse_operation_mark_done (operation, FALSE, NULL); else if (error->code == CKR_FUNCTION_CANCELED) seahorse_operation_mark_done (operation, TRUE, NULL); else seahorse_operation_mark_done (operation, FALSE, error); g_clear_error (&error); }
/** * seahorse_context_search_remote: * @sctx: A #SeahorseContext (can be NULL) * @search: a keyword (name, email address...) to search for * * Searches for the key matching @search o the remote servers * * Returns: The created search operation */ SeahorseOperation* seahorse_context_search_remote (SeahorseContext *sctx, const gchar *search) { SeahorseSource *ks; SeahorseMultiOperation *mop = NULL; SeahorseOperation *op = NULL; GSList *l, *names; GHashTable *servers = NULL; gchar *uri; if (!sctx) sctx = seahorse_context_for_app (); g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL); /* Get a list of all selected key servers */ names = seahorse_gconf_get_string_list (LASTSERVERS_KEY); if (names) { servers = g_hash_table_new (g_str_hash, g_str_equal); for (l = names; l; l = g_slist_next (l)) g_hash_table_insert (servers, l->data, GINT_TO_POINTER (TRUE)); } for (l = sctx->pv->sources; l; l = g_slist_next (l)) { ks = SEAHORSE_SOURCE (l->data); if (seahorse_source_get_location (ks) != SEAHORSE_LOCATION_REMOTE) continue; if (servers) { g_object_get (ks, "uri", &uri, NULL); if (!g_hash_table_lookup (servers, uri)) { g_free (uri); continue; } g_free (uri); } if (mop == NULL && op != NULL) { mop = seahorse_multi_operation_new (); seahorse_multi_operation_take (mop, op); } op = seahorse_source_search (ks, search); if (mop != NULL) seahorse_multi_operation_take (mop, op); } seahorse_util_string_slist_free (names); return mop ? SEAHORSE_OPERATION (mop) : op; }
/* Cancels operation and marks the HKP operation as failed */ static void fail_hkp_operation (SeahorseHKPOperation *hop, SoupMessage *msg, const gchar *text) { gchar *t, *server; GError *error = NULL; if (!seahorse_operation_is_running (SEAHORSE_OPERATION (hop))) return; g_object_get (hop->hsrc, "key-server", &server, NULL); if (text) { error = g_error_new (HKP_ERROR_DOMAIN, msg ? msg->status_code : 0, "%s", text); } else if (msg) { /* Make the body lower case, and no tags */ t = g_strndup (msg->response_body->data, msg->response_body->length); if (t != NULL) { dehtmlize (t); seahorse_util_string_lower (t); } if (t && strstr (t, "no keys")) error = NULL; /* not found is not an error */ else if (t && strstr (t, "too many")) error = g_error_new (HKP_ERROR_DOMAIN, 0, _("Search was not specific enough. Server '%s' found too many keys."), server); else error = g_error_new (HKP_ERROR_DOMAIN, msg->status_code, _("Couldn't communicate with server '%s': %s"), server, msg->reason_phrase); g_free (t); } else { /* We should always have msg or text */ g_assert (FALSE); } seahorse_operation_mark_done (SEAHORSE_OPERATION (hop), FALSE, error); g_free (server); }
static void seahorse_operation_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SeahorseOperation *op = SEAHORSE_OPERATION (object); switch (prop_id) { case PROP_MESSAGE: g_free (op->message); op->message = g_value_dup_string (value); break; } }
static SeahorseHKPOperation* setup_hkp_operation (SeahorseHKPSource *hsrc) { SeahorseHKPOperation *hop; g_return_val_if_fail (SEAHORSE_IS_HKP_SOURCE (hsrc), NULL); hop = g_object_new (SEAHORSE_TYPE_HKP_OPERATION, NULL); hop->hsrc = hsrc; g_object_ref (hsrc); seahorse_operation_mark_start (SEAHORSE_OPERATION (hop)); return hop; }
static GObject* seahorse_pkcs11_deleter_constructor (GType type, guint n_props, GObjectConstructParam *props) { SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (G_OBJECT_CLASS (seahorse_pkcs11_deleter_parent_class)->constructor(type, n_props, props)); g_return_val_if_fail (self, NULL); g_return_val_if_fail (self->object, NULL); /* Start the delete */ gp11_object_destroy_async (seahorse_pkcs11_object_get_pkcs11_object (self->object), self->cancellable, (GAsyncReadyCallback)on_deleted, self); seahorse_operation_mark_start (SEAHORSE_OPERATION (self)); return G_OBJECT (self); }
/** * seahorse_progress_status_set_operation: * @swidget: The SeahorseWidget to add the operation to * @operation: The operation to add * * Adds the operation to the widget. * */ void seahorse_progress_status_set_operation (SeahorseWidget *swidget, SeahorseOperation *operation) { SeahorseOperation *prev; /* * Note that this is not one off, the operation is monitored until it is * replaced, so if the operation starts up again the progress will be * displayed */ g_return_if_fail (SEAHORSE_IS_WIDGET (swidget)); g_return_if_fail (SEAHORSE_IS_OPERATION (operation)); prev = SEAHORSE_OPERATION (g_object_get_data (G_OBJECT (swidget), "operation")); if (prev) { /* If it's the same operation, just ignore */ if (prev == operation) return; /* If the previous one was a multi operation, just piggy back this one in */ if (SEAHORSE_IS_MULTI_OPERATION (prev)) { g_object_ref (operation); seahorse_multi_operation_take (SEAHORSE_MULTI_OPERATION (prev), operation); return; } /* Otherwise disconnect old progress, replace with new */ disconnect_progress (swidget, prev); } g_object_ref (operation); g_object_set_data_full (G_OBJECT (swidget), "operation", operation, (GDestroyNotify)g_object_unref); g_signal_connect (swidget, "destroy", G_CALLBACK (disconnect_progress), operation); if (!seahorse_operation_is_running (operation)) operation_done (operation, swidget); operation_progress (operation, seahorse_operation_get_message (operation), seahorse_operation_get_progress (operation), swidget); g_signal_connect (operation, "done", G_CALLBACK (operation_done), swidget); g_signal_connect (operation, "progress", G_CALLBACK (operation_progress), swidget); }
/* free private vars */ static void seahorse_operation_finalize (GObject *gobject) { SeahorseOperation *op = SEAHORSE_OPERATION (gobject); g_assert (!op->is_running); if (op->error) { g_error_free (op->error); op->error = NULL; } g_free (op->message); op->message = NULL; G_OBJECT_CLASS (seahorse_operation_parent_class)->finalize (gobject); }
/** * seahorse_context_retrieve_objects: * @sctx: A #SeahorsecContext * @ktype: The type of the keys to transfer * @ids: The key ids to transfer * @to: A #SeahorseSource. If NULL, it will use @ktype to find a source * * Copies remote objects to a local source * * Returns: A #SeahorseOperation */ SeahorseOperation* seahorse_context_retrieve_objects (SeahorseContext *sctx, GQuark ktype, GSList *ids, SeahorseSource *to) { SeahorseMultiOperation *mop = NULL; SeahorseOperation *op = NULL; SeahorseSource *sksrc; GSList *sources, *l; if (!sctx) sctx = seahorse_context_for_app (); g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL); if (!to) { to = seahorse_context_find_source (sctx, ktype, SEAHORSE_LOCATION_LOCAL); if (!to) { /* TODO: How can we warn caller about this. Do we need to? */ g_warning ("couldn't find a local source for: %s", g_quark_to_string (ktype)); return seahorse_operation_new_complete (NULL); } } sources = seahorse_context_find_sources (sctx, ktype, SEAHORSE_LOCATION_REMOTE); if (!sources) { g_warning ("no sources found for type: %s", g_quark_to_string (ktype)); return seahorse_operation_new_complete (NULL); } for (l = sources; l; l = g_slist_next (l)) { sksrc = SEAHORSE_SOURCE (l->data); g_return_val_if_fail (SEAHORSE_IS_SOURCE (sksrc), NULL); if (op != NULL) { if (mop == NULL) mop = seahorse_multi_operation_new (); seahorse_multi_operation_take (mop, op); } /* Start a new transfer operation between the two key sources */ op = seahorse_transfer_operation_new (NULL, sksrc, to, ids); g_return_val_if_fail (op != NULL, FALSE); } return mop ? SEAHORSE_OPERATION (mop) : op; }
/* dispose of all our internal references */ static void seahorse_operation_dispose (GObject *gobject) { SeahorseOperation *op = SEAHORSE_OPERATION (gobject); if (op->is_running) seahorse_operation_cancel (op); g_assert (!op->is_running); /* We do this in dispose in case it's a circular reference */ if (op->result && op->result_destroy) (op->result_destroy) (op->result); op->result = NULL; op->result_destroy = NULL; G_OBJECT_CLASS (seahorse_operation_parent_class)->dispose (gobject); }
static void seahorse_operation_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { SeahorseOperation *op = SEAHORSE_OPERATION (object); switch (prop_id) { case PROP_PROGRESS: g_value_set_double (value, op->progress); break; case PROP_MESSAGE: g_value_set_string (value, op->message); break; case PROP_RESULT: g_value_set_pointer (value, op->result); break; } }
static void on_open_session(GP11Slot *slot, GAsyncResult *result, SeahorsePkcs11Refresher *self) { GError *err = NULL; GP11Attributes *attrs; g_return_if_fail (SEAHORSE_IS_PKCS11_REFRESHER (self)); self->session = gp11_slot_open_session_finish (slot, result, &err); if (!self->session) { seahorse_pkcs11_mark_complete (SEAHORSE_OPERATION (self), err); return; } /* Step 2. Load all the objects that we want */ attrs = gp11_attributes_new (); gp11_attributes_add_boolean (attrs, CKA_TOKEN, TRUE); gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE); gp11_session_find_objects_async (self->session, attrs, self->cancellable, (GAsyncReadyCallback)on_find_objects, self); gp11_attributes_unref (attrs); }
static gboolean import_start (SeahorseToolMode *mode, const gchar *uri, gpgme_data_t uridata, SeahorsePGPOperation *pop, GError **err) { size_t size; SeahorseOperation *op; gpgme_error_t gerr; /* Start actual import */ op = SEAHORSE_OPERATION (pop); init_crypt(); buffer = g_malloc0(IMPORT_BUFFER_SIZE); /* Allocate memory for key data */ size = gpgme_data_read (uridata, (void*) buffer, IMPORT_BUFFER_SIZE); if (size > 0) { import_proxy_call = dbus_g_proxy_begin_call (dbus_key_proxy, "ImportKeys", proxy_call_notification, pop, NULL, G_TYPE_STRING, "openpgp", G_TYPE_STRING, buffer, G_TYPE_INVALID); seahorse_operation_mark_start (op); seahorse_operation_mark_progress (op, _("Importing keys ..."), 0.5); } else { g_free (buffer); gerr = gpgme_err_code_from_errno (errno); seahorse_util_gpgme_to_error (gerr, err); return FALSE; } return TRUE; }
static SeahorseOperation* seahorse_hkp_source_import (SeahorseSource *sksrc, GInputStream *input) { SeahorseHKPOperation *hop; SeahorseHKPSource *hsrc; SoupMessage *message; GSList *keydata = NULL; GString *buf = NULL; GHashTable *form; gchar *key, *t; SoupURI *uri; GSList *l; guint len; g_return_val_if_fail (SEAHORSE_IS_HKP_SOURCE (sksrc), NULL); hsrc = SEAHORSE_HKP_SOURCE (sksrc); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_object_ref (input); for (;;) { buf = g_string_sized_new (2048); len = seahorse_util_read_data_block (buf, input, "-----BEGIN PGP PUBLIC KEY BLOCK-----", "-----END PGP PUBLIC KEY BLOCK-----"); if (len > 0) { keydata = g_slist_prepend (keydata, g_string_free (buf, FALSE)); } else { g_string_free (buf, TRUE); break; } } if (g_slist_length (keydata) == 0) { g_object_unref (input); return seahorse_operation_new_complete (NULL); } /* Figure out the URI we're sending to */ uri = get_http_server_uri (sksrc, "/pks/add"); g_return_val_if_fail (uri, FALSE); /* New operation and away we go */ keydata = g_slist_reverse (keydata); hop = setup_hkp_operation (hsrc); form = g_hash_table_new (g_str_hash, g_str_equal); for (l = keydata; l; l = g_slist_next (l)) { g_assert (l->data != NULL); g_hash_table_insert (form, "keytext", l->data); key = soup_form_encode_urlencoded (form); message = soup_message_new_from_uri ("POST", uri); soup_message_set_request (message, "application/x-www-form-urlencoded", SOUP_MEMORY_TAKE, key, strlen (key)); soup_session_queue_message (hop->session, message, (SoupSessionCallback)send_callback, hop); hop->requests++; } g_hash_table_destroy (form); hop->total = hop->requests; t = g_strdup_printf (_("Connecting to: %s"), uri->host); seahorse_operation_mark_progress (SEAHORSE_OPERATION (hop), t, -1); g_free (t); soup_uri_free (uri); seahorse_util_string_slist_free (keydata); g_object_unref (input); return SEAHORSE_OPERATION (hop); }
static SeahorseOperation* seahorse_hkp_source_export_raw (SeahorseSource *sksrc, GSList *keyids, GOutputStream *output) { SeahorseHKPOperation *hop; SeahorseHKPSource *hsrc; SoupMessage *message; gchar *t; SoupURI *uri; const gchar *fpr; gchar hexfpr[11]; GHashTable *form; guint len; GSList *l; g_return_val_if_fail (SEAHORSE_IS_HKP_SOURCE (sksrc), NULL); g_return_val_if_fail (output == NULL || G_IS_OUTPUT_STREAM (output), NULL); hsrc = SEAHORSE_HKP_SOURCE (sksrc); if (g_slist_length (keyids) == 0) return seahorse_operation_new_complete (NULL); uri = get_http_server_uri (sksrc, "/pks/lookup"); g_return_val_if_fail (uri, FALSE); /* New operation started */ hop = setup_hkp_operation (hsrc); g_object_ref (output); seahorse_operation_mark_result (SEAHORSE_OPERATION (hop), output, g_object_unref); /* prepend the hex prefix (0x) to make keyservers happy */ strncpy(hexfpr, "0x", 3); form = g_hash_table_new (g_str_hash, g_str_equal); for (l = keyids; l; l = g_slist_next (l)) { /* Get the key id and limit it to 8 characters */ fpr = seahorse_pgp_key_calc_rawid (GPOINTER_TO_UINT (l->data)); len = strlen (fpr); if (len > 8) fpr += (len - 8); strncpy(hexfpr + 2, fpr, 9); /* The get key URI */ g_hash_table_insert (form, "op", "get"); g_hash_table_insert (form, "search", (char *)hexfpr); soup_uri_set_query_from_form (uri, form); message = soup_message_new_from_uri ("GET", uri); soup_session_queue_message (hop->session, message, (SoupSessionCallback)get_callback, hop); hop->requests++; } g_hash_table_destroy (form); hop->total = hop->requests; t = g_strdup_printf (_("Connecting to: %s"), uri->host); seahorse_operation_mark_progress (SEAHORSE_OPERATION (hop), t, -1); g_free (t); soup_uri_free (uri); return SEAHORSE_OPERATION (hop); }
/** * seahorse_context_transfer_objects: * @sctx: The #SeahorseContext (can be NULL) * @objects: the objects to import * @to: a source to import to (can be NULL) * * * * Returns: A transfer operation */ SeahorseOperation* seahorse_context_transfer_objects (SeahorseContext *sctx, GList *objects, SeahorseSource *to) { SeahorseSource *from; SeahorseOperation *op = NULL; SeahorseMultiOperation *mop = NULL; SeahorseObject *sobj; GSList *ids = NULL; GList *next, *l; GQuark ktype; if (!sctx) sctx = seahorse_context_for_app (); g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL); objects = g_list_copy (objects); /* Sort by key source */ objects = seahorse_util_objects_sort (objects); while (objects) { /* break off one set (same keysource) */ next = seahorse_util_objects_splice (objects); g_assert (SEAHORSE_IS_OBJECT (objects->data)); sobj = SEAHORSE_OBJECT (objects->data); /* Export from this key source */ from = seahorse_object_get_source (sobj); g_return_val_if_fail (from != NULL, FALSE); ktype = seahorse_source_get_tag (from); /* Find a local keysource to import to */ if (!to) { to = seahorse_context_find_source (sctx, ktype, SEAHORSE_LOCATION_LOCAL); if (!to) { /* TODO: How can we warn caller about this. Do we need to? */ g_warning ("couldn't find a local source for: %s", g_quark_to_string (ktype)); } } /* Make sure it's the same type */ if (ktype != seahorse_source_get_tag (to)) { /* TODO: How can we warn caller about this. Do we need to? */ g_warning ("destination is not of type: %s", g_quark_to_string (ktype)); } if (to != NULL && from != to) { if (op != NULL) { if (mop == NULL) mop = seahorse_multi_operation_new (); seahorse_multi_operation_take (mop, op); } /* Build id list */ for (l = objects; l; l = g_list_next (l)) ids = g_slist_prepend (ids, GUINT_TO_POINTER (seahorse_object_get_id (l->data))); ids = g_slist_reverse (ids); /* Start a new transfer operation between the two sources */ op = seahorse_transfer_operation_new (NULL, from, to, ids); g_return_val_if_fail (op != NULL, FALSE); g_slist_free (ids); ids = NULL; } g_list_free (objects); objects = next; } /* No objects done, just return success */ if (!mop && !op) { g_warning ("no valid objects to transfer found"); return seahorse_operation_new_complete (NULL); } return mop ? SEAHORSE_OPERATION (mop) : op; }
/** * seahorse_progress_status_get_operation: * @swidget: The SeahorseWidget to extract the operation from * * * * Returns: The operation stored in the widget */ SeahorseOperation* seahorse_progress_status_get_operation (SeahorseWidget *swidget) { return SEAHORSE_OPERATION (g_object_get_data (G_OBJECT (swidget), "operation")); }
static gboolean step_operation (FilesCtx *ctx, SeahorseToolMode *mode, GError **err) { SeahorsePGPOperation *pop = NULL; gpgme_data_t data = NULL; gboolean ret = FALSE; SeahorseOperation *op; FileInfo *finfo; GList *l; gchar *filename; /* Reset our done counter */ ctx->done = 0; for (l = ctx->finfos; l; l = g_list_next (l)) { finfo = (FileInfo*)l->data; if (!finfo || !finfo->file) continue; ctx->cur = finfo; /* A new operation for each context */ pop = seahorse_pgp_operation_new (NULL); op = SEAHORSE_OPERATION (pop); data = seahorse_vfs_data_create_full (finfo->file, SEAHORSE_VFS_READ, (SeahorseVfsProgressCb)progress_cb, ctx, err); if (!data) goto finally; /* Inhibit popping up of progress dialog */ seahorse_tool_progress_block (TRUE); /* Embed filename during encryption */ if (mode_encrypt) { filename = g_file_get_basename (finfo->file); gpgme_data_set_file_name (data, filename); g_free (filename); } /* The start callback */ if (mode->startcb) { if (!(mode->startcb) (mode, finfo->uri, data, pop, err)) goto finally; } /* Let progress dialog pop up */ seahorse_tool_progress_block (FALSE); /* Run until the operation completes */ seahorse_util_wait_until ((!seahorse_operation_is_running (op) || !seahorse_tool_progress_check ())); /* If cancel then reflect that */ if (seahorse_operation_is_running (op)) { seahorse_operation_cancel (op); goto finally; } if (!seahorse_operation_is_successful (op)) { seahorse_operation_copy_error (op, err); goto finally; } /* The done callback */ if (mode->donecb) { if (!(mode->donecb) (mode, finfo->uri, data, pop, err)) goto finally; } ctx->done += g_file_info_get_size (finfo->info); ctx->cur = NULL; g_object_unref (pop); pop = NULL; gpgme_data_release (data); data = NULL; } seahorse_tool_progress_update (1.0, ""); ret = TRUE; finally: if (pop) g_object_unref (pop); if (data) gpgme_data_release (data); return ret; }