Пример #1
0
static void mimeview_show_mime_part(MimeView *mimeview, MimeInfo *partinfo)
{
	TextView *textview = mimeview->textview;
	GtkTextBuffer *buffer;
	GtkTextIter iter;
	GtkTextChildAnchor *anchor;
	GtkWidget *vbbox;
	GtkWidget *button;
	gchar buf[BUFFSIZE];

	if (!partinfo) return;

	textview_set_font(textview, NULL);
	textview_clear(textview);

	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview->text));
	gtk_text_buffer_get_start_iter(buffer, &iter);

	gtk_text_buffer_insert(buffer, &iter,
			       _("Select an action for the attached file:\n"),
			       -1);
	if (partinfo->filename || partinfo->name)
		g_snprintf(buf, sizeof(buf), "[%s  %s (%s)]\n\n",
			   partinfo->filename ? partinfo->filename :
			   partinfo->name,
			   partinfo->content_type,
			   to_human_readable(partinfo->content_size));
	else
		g_snprintf(buf, sizeof(buf), "[%s (%s)]\n\n",
			   partinfo->content_type,
			   to_human_readable(partinfo->content_size));
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, buf, -1,
						 "mimepart", NULL);

	vbbox = gtk_vbutton_box_new();
	gtk_box_set_spacing(GTK_BOX(vbbox), 5);

	button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
	gtk_container_add(GTK_CONTAINER(vbbox), button);
	g_signal_connect(button, "clicked", G_CALLBACK(open_button_clicked),
			 mimeview);
	button = gtk_button_new_with_mnemonic(_("Open _with..."));
	gtk_container_add(GTK_CONTAINER(vbbox), button);
	g_signal_connect(button, "clicked",
			 G_CALLBACK(open_with_button_clicked), mimeview);
	button = gtk_button_new_with_mnemonic(_("_Display as text"));
	gtk_container_add(GTK_CONTAINER(vbbox), button);
	g_signal_connect(button, "clicked",
			 G_CALLBACK(display_as_text_button_clicked), mimeview);
	button = gtk_button_new_with_mnemonic(_("_Save as..."));
	gtk_container_add(GTK_CONTAINER(vbbox), button);
	g_signal_connect(button, "clicked", G_CALLBACK(save_as_button_clicked),
			 mimeview);

	gtk_widget_show_all(vbbox);

	anchor = gtk_text_buffer_create_child_anchor(buffer, &iter);
	gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(textview->text),
					  vbbox, anchor);
}
Пример #2
0
void messageview_clear(MessageView *messageview)
{
	procmsg_msginfo_free(messageview->msginfo);
	messageview->msginfo = NULL;
	messageview_change_view_type(messageview, MVIEW_TEXT);
	headerview_clear(messageview->headerview);
	textview_clear(messageview->textview);
	mimeview_clear(messageview->mimeview);
}
Пример #3
0
void mimeview_clear(MimeView *mimeview)
{
	mimeview->has_attach_file = FALSE;

	gtk_tree_store_clear(mimeview->store);
	textview_clear(mimeview->textview);
	imageview_clear(mimeview->imageview);

	gtk_tree_path_free(mimeview->opened);
	mimeview->opened = NULL;

	g_free(mimeview->drag_file);
	mimeview->drag_file = NULL;
}
Пример #4
0
static void mimeview_show_signature_part(MimeView *mimeview,
					 MimeInfo *partinfo)
{
	TextView *textview = mimeview->textview;
	GtkTextBuffer *buffer;
	GtkTextIter iter;
	GtkTextChildAnchor *anchor;
	GtkWidget *vbbox;
	GtkWidget *button;

	if (!partinfo) return;

	textview_set_font(textview, NULL);
	textview_clear(textview);

	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview->text));
	gtk_text_buffer_get_start_iter(buffer, &iter);

	if (partinfo->sigstatus_full) {
		gtk_text_buffer_insert
			(buffer, &iter, partinfo->sigstatus_full, -1);
		return;
	}

	gtk_text_buffer_insert
		(buffer, &iter,
		 _("This signature has not been checked yet.\n\n"), -1);

	vbbox = gtk_vbutton_box_new();
	gtk_box_set_spacing(GTK_BOX(vbbox), 5);

	if (rfc2015_is_available()) {
		button = gtk_button_new_with_mnemonic(_("_Check signature"));
		gtk_container_add(GTK_CONTAINER(vbbox), button);
		g_signal_connect(button, "clicked",
				 G_CALLBACK(check_signature_button_clicked),
				 mimeview);
	}

	gtk_widget_show_all(vbbox);

	anchor = gtk_text_buffer_create_child_anchor(buffer, &iter);
	gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(textview->text),
					  vbbox, anchor);
}
Пример #5
0
static void mimeview_change_view_type(MimeView *mimeview, MimeViewType type)
{
	TextView  *textview  = mimeview->textview;
	ImageView *imageview = mimeview->imageview;
	GList *children;

	if (mimeview->type == type) return;

	children = gtk_container_get_children
		(GTK_CONTAINER(mimeview->mime_vbox));
	if (children) {
		gtkut_container_remove(GTK_CONTAINER(mimeview->mime_vbox),
				       GTK_WIDGET(children->data));
		g_list_free(children);
	}

	switch (mimeview->type) {
	case MIMEVIEW_IMAGE:
		imageview_clear(mimeview->imageview);
		break;
	case MIMEVIEW_TEXT:
		textview_clear(mimeview->textview);
		break;
	default:
		break;
	}

	switch (type) {
	case MIMEVIEW_IMAGE:
		gtk_container_add(GTK_CONTAINER(mimeview->mime_vbox),
				  GTK_WIDGET_PTR(imageview));
		break;
	case MIMEVIEW_TEXT:
		gtk_container_add(GTK_CONTAINER(mimeview->mime_vbox),
				  GTK_WIDGET_PTR(textview));
		break;
	default:
		return;
	}

	mimeview->type = type;
}
Пример #6
0
void mimeview_clear(MimeView *mimeview)
{
	GtkCList *clist = GTK_CLIST(mimeview->ctree);

	noticeview_hide(mimeview->siginfoview);

	gtk_clist_clear(clist);
	textview_clear(mimeview->textview);
	if (mimeview->mimeviewer != NULL)
		mimeview->mimeviewer->clear_viewer(mimeview->mimeviewer);

	if (mimeview->mimeinfo != NULL)
		procmime_mimeinfo_free_all(mimeview->mimeinfo);
	mimeview->mimeinfo = NULL;

	mimeview->opened = NULL;

	g_free(mimeview->file);
	mimeview->file = NULL;

	icon_list_clear(mimeview);
}
Пример #7
0
void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo,
			   const gchar *file)
{
	GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store);
	GtkTreeIter iter;
	gboolean valid;

	mimeview_clear(mimeview);
	textview_clear(mimeview->messageview->textview);

	g_return_if_fail(file != NULL);
	g_return_if_fail(mimeinfo != NULL);

#if USE_GPGME
	if (rfc2015_is_available() && prefs_common.auto_check_signatures) {
		FILE *fp;

		if ((fp = g_fopen(file, "rb")) == NULL) {
			FILE_OP_ERROR(file, "fopen");
			return;
		}
		rfc2015_check_signature(mimeinfo, fp);
		fclose(fp);
	} else
		set_unchecked_signature(mimeinfo);
#endif

	g_signal_handlers_block_by_func
		(G_OBJECT(mimeview->selection),
		 G_CALLBACK(mimeview_selection_changed), mimeview);

	mimeview_set_multipart_tree(mimeview, mimeinfo, NULL);
	gtk_tree_view_expand_all(GTK_TREE_VIEW(mimeview->treeview));

	g_signal_handlers_unblock_by_func
		(G_OBJECT(mimeview->selection),
		 G_CALLBACK(mimeview_selection_changed), mimeview);

	/* search first text part */
	for (valid = gtk_tree_model_get_iter_first(model, &iter); valid;
	     valid = gtkut_tree_model_next(model, &iter)) {
		MimeInfo *partinfo;

		gtk_tree_model_get(model, &iter, COL_MIME_INFO, &partinfo, -1);
		if (partinfo &&
		    (partinfo->mime_type == MIME_TEXT ||
		     partinfo->mime_type == MIME_TEXT_HTML))
			break;
	}
	textview_show_message(mimeview->messageview->textview, mimeinfo, file);

	if (!valid)
		valid = gtk_tree_model_get_iter_first(model, &iter);

	if (valid) {
		GtkTreePath *path;

		path = gtk_tree_model_get_path(model, &iter);
		gtk_tree_view_set_cursor(GTK_TREE_VIEW(mimeview->treeview),
					 path, NULL, FALSE);
		gtk_tree_path_free(path);
		if (mimeview_get_selected_part(mimeview))
			gtk_widget_grab_focus(mimeview->treeview);
	}
}
Пример #8
0
static void pgp_clear_viewer(MimeViewer *_viewer)
{
	PgpViewer *viewer = (PgpViewer *)_viewer;
	debug_print("pgp_clear_viewer\n");
	textview_clear(viewer->textview);
}
Пример #9
0
static void pgpview_show_mime_part(TextView *textview, MimeInfo *partinfo)
{
	GtkTextView *text;
	GtkTextBuffer *buffer;
	GtkTextIter iter;
	gpgme_data_t sigdata = NULL;
	gpgme_verify_result_t sigstatus = NULL;
	gpgme_ctx_t ctx = NULL;
	gpgme_key_t key = NULL;
	gpgme_signature_t sig = NULL;
	gpgme_error_t err = 0;
	gboolean imported = FALSE;

	if (!partinfo) return;
	
	textview_set_font(textview, NULL);
	textview_clear(textview);

	text = GTK_TEXT_VIEW(textview->text);
	buffer = gtk_text_view_get_buffer(text);
	gtk_text_buffer_get_start_iter(buffer, &iter);

	err = gpgme_new (&ctx);
	if (err) {
		debug_print("err : %s\n", gpgme_strerror(err));
		textview_show_mime_part(textview, partinfo);
		return;
	}
	
	sigdata = sgpgme_data_from_mimeinfo(partinfo);
	if (!sigdata) {
		g_warning("no sigdata");
		textview_show_mime_part(textview, partinfo);
		return;
	}

	/* Here we do not care about what data we attempt to verify with the
	 * signature, or about result of the verification - all we care about
	 * is that we find out ID of the key used to make this signature. */
	sigstatus = sgpgme_verify_signature(ctx, sigdata, NULL, sigdata);
	if (!sigstatus || sigstatus == GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR)) {
		g_warning("no sigstatus");
		textview_show_mime_part(textview, partinfo);
		return;
	}
	sig = sigstatus->signatures;
	if (!sig) {
		g_warning("no sig");
		textview_show_mime_part(textview, partinfo);
		return;
	}
	gpgme_get_key(ctx, sig->fpr, &key, 0);
	if (!key) {
		gchar *gpgbin = get_gpg_executable_name();
		gchar *cmd = g_strdup_printf("\"%s\" --batch --no-tty --recv-keys %s",
				(gpgbin ? gpgbin : "gpg"), sig->fpr);
		AlertValue val = G_ALERTDEFAULT;
		if (!prefs_common_get_prefs()->work_offline) {
			val = alertpanel(_("Key import"),
				_("This key is not in your keyring. Do you want "
				  "Claws Mail to try and import it from a "
				  "keyserver?"),
				  GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
			GTK_EVENTS_FLUSH();
		}
		if (val == G_ALERTDEFAULT) {
			TEXTVIEW_INSERT(_("\n  Key ID "));
			TEXTVIEW_INSERT(sig->fpr);
			TEXTVIEW_INSERT(":\n\n");
			TEXTVIEW_INSERT(_("   This key is not in your keyring.\n"));
			TEXTVIEW_INSERT(_("   It should be possible to import it "));
			if (prefs_common_get_prefs()->work_offline)
				TEXTVIEW_INSERT(_("when working online,\n   or "));
			TEXTVIEW_INSERT(_("with the following command: \n\n     "));
			TEXTVIEW_INSERT(cmd);
		} else {
			TEXTVIEW_INSERT(_("\n  Importing key ID "));
			TEXTVIEW_INSERT(sig->fpr);
			TEXTVIEW_INSERT(":\n\n");

			main_window_cursor_wait(mainwindow_get_mainwindow());
			textview_cursor_wait(textview);
			GTK_EVENTS_FLUSH();

#ifndef G_OS_WIN32
			int res = 0;
			pid_t pid = 0;

			pid = fork();
			if (pid == -1) {
				res = -1;
			} else if (pid == 0) {
				/* son */
				gchar **argv;
				argv = strsplit_with_quote(cmd, " ", 0);
				res = execvp(argv[0], argv);
				perror("execvp");
				exit(255);
			} else {
				int status = 0;
				time_t start_wait = time(NULL);
				res = -1;
				do {
					if (waitpid(pid, &status, WNOHANG) == 0 || !WIFEXITED(status)) {
						usleep(200000);
					} else {
						res = WEXITSTATUS(status);
						break;
					}
					if (time(NULL) - start_wait > 9) {
						debug_print("SIGTERM'ing gpg %d\n", pid);
						kill(pid, SIGTERM);
					}
					if (time(NULL) - start_wait > 10) {
						debug_print("SIGKILL'ing gpg %d\n", pid);
						kill(pid, SIGKILL);
						break;
					}
				} while(1);
			}
			debug_print("res %d\n", res);
			if (res == 0)
				imported = TRUE;
#else
			/* We need to call gpg in a separate thread, so that waiting for
			 * it to finish does not block the UI. */
			pthread_t pt;
			struct _ImportCtx *ctx = malloc(sizeof(struct _ImportCtx));

			ctx->done = FALSE;
			ctx->exitcode = STILL_ACTIVE;
			ctx->cmd = cmd;

			if (pthread_create(&pt, NULL,
						_import_threaded, (void *)ctx) != 0) {
				debug_print("Couldn't create thread, continuing unthreaded.\n");
				_import_threaded(ctx);
			} else {
				debug_print("Thread created, waiting for it to finish...\n");
				while (!ctx->done)
					claws_do_idle();
			}

			debug_print("Thread finished.\n");
			pthread_join(pt, NULL);

			if (ctx->exitcode == 0) {
				imported = TRUE;
			}
			g_free(ctx);
#endif
			main_window_cursor_normal(mainwindow_get_mainwindow());
			textview_cursor_normal(textview);
			if (imported) {
				TEXTVIEW_INSERT(_("   This key has been imported to your keyring.\n"));
			} else {
				TEXTVIEW_INSERT(_("   This key couldn't be imported to your keyring.\n"));
				TEXTVIEW_INSERT(_("   Key servers are sometimes slow.\n"));
				TEXTVIEW_INSERT(_("   You can try to import it manually with the command:\n\n     "));
				TEXTVIEW_INSERT(cmd);
			}
		}
		g_free(cmd);
		return;
	} else {
		TEXTVIEW_INSERT(_("\n  Key ID "));

#if defined GPGME_VERSION_NUMBER && GPGME_VERSION_NUMBER >= 0x010700
		TEXTVIEW_INSERT(key->fpr);
#else
		TEXTVIEW_INSERT(sig->fpr);
#endif

		TEXTVIEW_INSERT(":\n\n");
		TEXTVIEW_INSERT(_("   This key is in your keyring.\n"));
	}
	gpgme_data_release(sigdata);
	gpgme_release(ctx);
	textview_show_icon(textview, GTK_STOCK_DIALOG_AUTHENTICATION);
}