/* * Copyright (C) 2009 Adam Schreiber * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * select_partygoers contains code from libcryptui which will hopefully be * removed in the future but is Copyright (C) 2005 Stefan Walter and is * available under the LGPL 2.1 or later. This probably violates the letter * but not the spirit of the license, but like I said, will be removed when the * freeze lifts on libcryptui and I can modify it. */ #include #include #include #include #include #include #include #include #include #define TYPE_G_STRING_VALUE_HASHTABLE \ (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) static const gchar *latex_header = "\\documentclass[10pt,letterpaper]{article}\n\\usepackage{ifpdf}\n\\usepackage[utf8]{inputenc}\n\\usepackage[USenglish]{babel}\n\\usepackage{latexsym}\n\\usepackage[cm]{fullpage}\n\\usepackage{multirow}\n\\begin{document}\n\\begin{tabular}{|c|c|c|}\n"; static const gchar *latex_footer = "\\hline\n\\end{tabular}\n\\end{document}"; static void selection_changed (CryptUIKeyChooser *chooser, GtkWidget *dialog) { gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, cryptui_key_chooser_have_recipients (chooser)); } static gchar ** select_partygoers (CryptUIKeyset *keyset) { CryptUIKeyChooser *chooser; GtkWidget *dialog; gchar **keys = NULL; GList *recipients, *l; guint mode = CRYPTUI_KEY_CHOOSER_RECIPIENTS; int i; dialog = gtk_dialog_new_with_buttons ("Select Partygoers", NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); chooser = cryptui_key_chooser_new (keyset, mode); g_object_set (G_OBJECT (chooser), "enforce-prefs", FALSE, NULL); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), GTK_WIDGET (chooser)); g_signal_connect (chooser, "changed", G_CALLBACK (selection_changed), dialog); selection_changed (chooser, dialog); gtk_widget_show_all (dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { recipients = cryptui_key_chooser_get_recipients (chooser); keys = g_new0(gchar*, g_list_length (recipients) + 1); for (l = recipients, i = 0; l; l = g_list_next (l), i++) keys[i] = g_strdup (l->data); g_list_free (recipients); } gtk_widget_destroy (dialog); return keys; } int main (int argc, char **argv) { CryptUIKeyset *dbus_keyset = NULL; gchar **partygoers, *filename, *uri, *str, **t, *goer, *displayname, *fprt, *bracket, *email; GtkDialog *dialog; GIOChannel *latexfile; GString *string; GError *err; gtk_init (&argc, &argv); dbus_keyset = cryptui_keyset_new ("openpgp", TRUE); /* Get keys of people attending key signing party */ partygoers = select_partygoers (dbus_keyset); dialog = GTK_DIALOG (gtk_file_chooser_dialog_new ("Output File", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL)); gtk_dialog_set_default_response (dialog, GTK_RESPONSE_ACCEPT); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE); if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); } else { g_strfreev (partygoers); exit (1); } str = g_strdup_printf ("%s.tex", filename); latexfile = g_io_channel_new_file (str, "w", NULL); g_free (str); g_io_channel_write_chars (latexfile, latex_header, -1, NULL, NULL); t = partygoers; while (*t != NULL) { goer = *t; displayname = cryptui_keyset_key_display_name (dbus_keyset, goer); email = g_strdup (displayname); string = g_string_new (displayname); bracket = g_strstr_len (displayname, strlen (displayname), "<"); string = g_string_truncate (string, bracket - displayname - 1); g_free (displayname); displayname = g_string_free (string, FALSE); string = g_string_new (email); bracket = g_strstr_len (email, strlen (email), "<"); string = g_string_erase (string, 0, bracket - email - 1); g_free (email); email = g_string_free (string, FALSE); string = g_string_new (email); bracket = g_strstr_len (email, strlen (email), ">"); if (bracket != NULL){ string = g_string_overwrite (string, bracket - email, "\\(>\\)"); string = g_string_truncate (string, bracket - email + 5); } bracket = g_strstr_len (email, strlen (email), "<"); if (bracket != NULL) { string = g_string_erase (string, bracket - email, 1); string = g_string_insert (string, bracket - email, "\\(<\\)"); } g_free (email); email = g_string_free (string, FALSE); fprt = cryptui_keyset_key_get_string (dbus_keyset, goer, "fingerprint"); str = g_strdup_printf ("\\hline\n%s&\\multirow{2}{*}{%s}&\\multirow{2}{*}{\\(\\Box\\) Yes \\(\\Box\\) No}\\\\\n%s& & \\\\\n", displayname, fprt, email); g_io_channel_write_chars (latexfile, str, -1, NULL, NULL); g_free (str); g_free (displayname); g_free (fprt); g_free (email); t++; } g_io_channel_write_chars (latexfile, latex_footer, -1, NULL, NULL); g_io_channel_shutdown (latexfile, TRUE, NULL); str = g_strdup_printf ("rubber -d %s.tex", filename); if (!g_spawn_command_line_sync (str, NULL, NULL, NULL, &err)) g_error ("Processing LaTeX file failed: %s\n", err->message); g_free (str); str = g_strdup_printf ("%s.pdf", uri); if (!g_app_info_launch_default_for_uri (str, NULL, &err)) g_error ("Launching viewer for PDF document failed: %s\n", err->message); g_free (filename); g_free (uri); return 0; }