sync with 0.8.1cvs22
authorPaul Mangan <paul@claws-mail.org>
Sat, 10 Aug 2002 09:19:15 +0000 (09:19 +0000)
committerPaul Mangan <paul@claws-mail.org>
Sat, 10 Aug 2002 09:19:15 +0000 (09:19 +0000)
14 files changed:
ChangeLog
ChangeLog.claws
ChangeLog.jp
configure.in
src/compose.c
src/gtksctree.c
src/mbox.c
src/pop.c
src/prefs_account.c
src/prefs_account.h
src/rfc2015.c
src/rfc2015.h
src/utils.c
src/utils.h

index 163f2ae..e855052 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2002-08-09
+
+       * src/compose.c: compose_write_to_file(): clearsign message body
+         if specified.
+         compose_clearsign_text(): new. Replaces the string with clearsigned
+         one.
+       * src/prefs_account.c: added an option for clearsign.
+       * src/rfc2015.c: rfc2015_clearsign(): new.
+         pgp_sign(): added a flag for clearsign.
+       * src/utils.[ch]: get_tmp_file(): return newly allocated unique file
+         name (needs to be freed by caller).
+         str_write_to_file(), file_read_to_str(): new.
+
 2002-08-08
 
        * src/procmsg.c: procmsg_read_mark_file(): check key duplication
index c62448f..77f466f 100644 (file)
@@ -1,3 +1,8 @@
+2002-08-10 [paul]      0.8.1claws42
+
+       * sync with 0.8.1cvs22
+               see ChangeLog 2002-08-09
+
 2002-08-09 [paul]      0.8.1claws41
 
        * tools/Makefile.am
index 8d4e8b3..8806068 100644 (file)
@@ -1,3 +1,16 @@
+2002-08-09
+
+       * src/compose.c: compose_write_to_file(): »ØÄꤷ¤¿¾ì¹ç¥á¥Ã¥»¡¼¥¸ËÜʸ
+         ¤ò¥¯¥ê¥¢½ð̾¤¹¤ë¤è¤¦¤Ë¤·¤¿¡£
+         compose_clearsign_text(): ¿·µ¬¡£Ê¸»úÎó¤ò¥¯¥ê¥¢½ð̾¤·¤¿¤â¤Î¤Ç
+         ÃÖ¤­´¹¤¨¤ë¡£
+       * src/prefs_account.c: ¥¯¥ê¥¢½ð̾¤Î¥ª¥×¥·¥ç¥ó¤òÄɲá£
+       * src/rfc2015.c: rfc2015_clearsign(): ¿·µ¬¡£
+         pgp_sign(): ¥¯¥ê¥¢½ð̾¤Î¥Õ¥é¥°¤òÄɲá£
+       * src/utils.[ch]: get_tmp_file(): ¿·µ¬¤Ë³ÎÊݤµ¤ì¤¿°ì°Õ¤Î¥Õ¥¡¥¤¥ë̾
+         ¤òÊÖ¤¹¤è¤¦¤Ë¤·¤¿(¸Æ¤Ó½Ð¤·Â¦¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë)¡£
+         str_write_to_file(), file_read_to_str(): ¿·µ¬¡£
+
 2002-08-08
 
        * src/procmsg.c: procmsg_read_mark_file(): ¥á¥â¥ê¥ê¡¼¥¯¤òÈò¤±¤ë
index b7acf9d..a301ec3 100644 (file)
@@ -8,7 +8,7 @@ MINOR_VERSION=8
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws41
+EXTRA_VERSION=claws42
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl set $target
index 7728c63..5dd1a62 100644 (file)
@@ -2743,8 +2743,8 @@ gint compose_send(Compose *compose)
        }
 
        /* write to temporary file */
-       g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg%d",
-                  get_rc_dir(), G_DIR_SEPARATOR, (gint)compose);
+       g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.%08x",
+                  get_tmp_dir(), G_DIR_SEPARATOR, (gint)compose);
 
        if (prefs_common.linewrap_at_send)
                compose_wrap_line_all(compose);
@@ -3075,6 +3075,36 @@ static gint compose_create_signers_list(Compose *compose, GSList **pkey_list)
        *pkey_list = key_list;
        return 0;
 }
+
+/* clearsign message body text */
+static gint compose_clearsign_text(Compose *compose, gchar **text)
+{
+       GSList *key_list;
+       gchar *tmp_file;
+
+       tmp_file = get_tmp_file();
+       if (str_write_to_file(*text, tmp_file) < 0) {
+               g_free(tmp_file);
+               return -1;
+       }
+
+       if (canonicalize_file_replace(tmp_file) < 0 ||
+           compose_create_signers_list(compose, &key_list) < 0 ||
+           rfc2015_clearsign(tmp_file, key_list) < 0) {
+               unlink(tmp_file);
+               g_free(tmp_file);
+               return -1;
+       }
+
+       g_free(*text);
+       *text = file_read_to_str(tmp_file);
+       unlink(tmp_file);
+       g_free(tmp_file);
+       if (*text == NULL)
+               return -1;
+
+       return 0;
+}
 #endif /* USE_GPGME */
 
 static gint compose_write_to_file(Compose *compose, const gchar *file,
@@ -3144,6 +3174,18 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
        }
        g_free(chars);
 
+#if USE_GPGME
+       if (!is_draft && compose->use_signing && compose->account->clearsign) {
+               if (compose_clearsign_text(compose, &buf) < 0) {
+                       g_warning("clearsign failed\n");
+                       fclose(fp);
+                       unlink(file);
+                       g_free(buf);
+                       return -1;
+               }
+       }
+#endif
+
        /* write headers */
        if (compose_write_headers
                (compose, fp, out_codeset, encoding, is_draft) < 0) {
@@ -3205,14 +3247,15 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
        if (is_draft)
                return 0;
 
-       if (compose->use_signing || compose->use_encryption) {
+       if ((compose->use_signing && !compose->account->clearsign) ||
+           compose->use_encryption) {
                if (canonicalize_file_replace(file) < 0) {
                        unlink(file);
                        return -1;
                }
        }
 
-       if (compose->use_signing) {
+       if (compose->use_signing && !compose->account->clearsign) {
                GSList *key_list;
 
                if (compose_create_signers_list(compose, &key_list) < 0 ||
index 13fb1c7..8a4660e 100644 (file)
@@ -220,8 +220,8 @@ select_row (GtkSCTree *sctree, gint row, gint col, guint state)
        g_return_if_fail (GTK_IS_SCTREE (sctree));
     
        range = ((state & GDK_SHIFT_MASK) != 0) &&
-               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
-               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
+               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
+               (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
        additive = ((state & GDK_CONTROL_MASK) != 0) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
index 4120b62..52f548e 100644 (file)
@@ -52,6 +52,7 @@
                fclose(tmp_fp); \
                fclose(mbox_fp); \
                unlink(tmp_file); \
+               g_free(tmp_file); \
                return -1; \
        } \
 }
@@ -111,6 +112,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                        FILE_OP_ERROR(tmp_file, "fopen");
                        g_warning(_("can't open temporary file\n"));
                        fclose(mbox_fp);
+                       g_free(tmp_file);
                        return -1;
                }
                if (change_file_mode_rw(tmp_fp, tmp_file) < 0)
@@ -199,6 +201,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                        g_warning(_("can't write to temporary file\n"));
                        fclose(mbox_fp);
                        unlink(tmp_file);
+                       g_free(tmp_file);
                        return -1;
                }
 
@@ -228,6 +231,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                if ((msgnum = folder_item_add_msg(dropfolder, tmp_file, TRUE)) < 0) {
                        fclose(mbox_fp);
                        unlink(tmp_file);
+                       g_free(tmp_file);
                        return -1;
                }
 
@@ -242,6 +246,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                msgs++;
        } while (from_line[0] != '\0');
 
+       g_free(tmp_file);
        fclose(mbox_fp);
        debug_print(_("%d messages found.\n"), msgs);
 
index e32b015..b648cfc 100644 (file)
--- a/src/pop.c
+++ b/src/pop.c
@@ -492,17 +492,21 @@ gint pop3_retr_send(SockInfo *sock, gpointer data)
 gint pop3_retr_recv(SockInfo *sock, gpointer data)
 {
        Pop3State *state = (Pop3State *)data;
-       const gchar *file;
+       gchar *file;
        gint ok, drop_ok;
        gint next_state;
        if ((ok = pop3_ok(sock, NULL)) == PS_SUCCESS) {
-               if (recv_write_to_file(sock, (file = get_tmp_file())) < 0) {
+               file = get_tmp_file();
+               if (recv_write_to_file(sock, file) < 0) {
+                       g_free(file);
                        if (state->inc_state == INC_SUCCESS)
                                state->inc_state = INC_NOSPACE;
                        return -1;
                }
 
-               if ((drop_ok = inc_drop_message(file, state)) < 0) {
+               drop_ok = inc_drop_message(file, state);
+               g_free(file);
+               if (drop_ok < 0) {
                        state->inc_state = INC_ERROR;
                        return -1;
                }
index e24e036..4f8c798 100644 (file)
@@ -129,6 +129,7 @@ static struct Privacy {
        GtkWidget *default_encrypt_chkbtn;
        GtkWidget *default_sign_chkbtn;
        GtkWidget *ascii_armored_chkbtn;
+       GtkWidget *clearsign_chkbtn;
        GtkWidget *defaultkey_radiobtn;
        GtkWidget *emailkey_radiobtn;
        GtkWidget *customkey_radiobtn;
@@ -379,6 +380,9 @@ static PrefParam param[] = {
        {"ascii_armored", "FALSE", &tmp_ac_prefs.ascii_armored, P_BOOL,
         &privacy.ascii_armored_chkbtn,
         prefs_set_data_from_toggle, prefs_set_toggle},
+       {"clearsign", "FALSE", &tmp_ac_prefs.clearsign, P_BOOL,
+        &privacy.clearsign_chkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
        {"sign_key", NULL, &tmp_ac_prefs.sign_key, P_ENUM,
         &privacy.defaultkey_radiobtn,
         prefs_account_enum_set_data_from_radiobtn,
@@ -1470,6 +1474,7 @@ static void prefs_account_privacy_create(void)
        GtkWidget *default_encrypt_chkbtn;
        GtkWidget *default_sign_chkbtn;
        GtkWidget *ascii_armored_chkbtn;
+       GtkWidget *clearsign_chkbtn;
        GtkWidget *defaultkey_radiobtn;
        GtkWidget *emailkey_radiobtn;
        GtkWidget *customkey_radiobtn;
@@ -1489,7 +1494,9 @@ static void prefs_account_privacy_create(void)
        PACK_CHECK_BUTTON (vbox2, default_sign_chkbtn,
                           _("Sign message by default"));
        PACK_CHECK_BUTTON (vbox2, ascii_armored_chkbtn,
-                          _("Use ASCII-armored format"));
+                          _("Use ASCII-armored format for encryption"));
+       PACK_CHECK_BUTTON (vbox2, clearsign_chkbtn,
+                          _("Use clear text signature"));
        gtk_signal_connect (GTK_OBJECT (ascii_armored_chkbtn), "toggled",
                            prefs_account_ascii_armored_warning, NULL);
 
@@ -1549,6 +1556,7 @@ static void prefs_account_privacy_create(void)
        privacy.default_encrypt_chkbtn = default_encrypt_chkbtn;
        privacy.default_sign_chkbtn    = default_sign_chkbtn;
        privacy.ascii_armored_chkbtn   = ascii_armored_chkbtn;
+       privacy.clearsign_chkbtn       = clearsign_chkbtn;
        privacy.defaultkey_radiobtn    = defaultkey_radiobtn;
        privacy.emailkey_radiobtn      = emailkey_radiobtn;
        privacy.customkey_radiobtn     = customkey_radiobtn;
index 7e06da4..4467ead 100644 (file)
@@ -143,6 +143,7 @@ struct _PrefsAccount
        gboolean default_encrypt;
        gboolean default_sign;
        gboolean ascii_armored;
+       gboolean clearsign;
        SignKeyType sign_key;
        gchar *sign_key_id;
 #endif /* USE_GPGME */
index 07b6f6d..96147a0 100644 (file)
@@ -480,7 +480,7 @@ int rfc2015_is_encrypted (MimeInfo *mimeinfo)
     return 1;
 }
 
-gboolean rfc2015_msg_is_encrypted (gchar *file)
+gboolean rfc2015_msg_is_encrypted (const gchar *file)
 {
        FILE *fp;
        MimeInfo *mimeinfo;
@@ -934,7 +934,8 @@ failure:
  * r_siginfo returns an XML object with information about the signature.
  */
 static GpgmeData
-pgp_sign (GpgmeData plain, GSList *key_list, char **r_siginfo)
+pgp_sign (GpgmeData plain, GSList *key_list, gboolean clearsign,
+         char **r_siginfo)
 {
     GSList *p;
     GpgmeCtx ctx = NULL;
@@ -970,7 +971,9 @@ pgp_sign (GpgmeData plain, GSList *key_list, char **r_siginfo)
 
     if (err)
        goto leave;
-    err = gpgme_op_sign (ctx, plain, sig, GPGME_SIG_MODE_DETACH);
+    err = gpgme_op_sign
+       (ctx, plain, sig,
+        clearsign ? GPGME_SIG_MODE_CLEAR : GPGME_SIG_MODE_DETACH);
     if (!err)
         *r_siginfo = gpgme_get_op_info (ctx, 0);
 
@@ -1138,7 +1141,7 @@ rfc2015_sign (const char *file, GSList *key_list)
         goto failure;
     }
 
-    sigdata = pgp_sign (plain, key_list, &siginfo); 
+    sigdata = pgp_sign (plain, key_list, FALSE, &siginfo); 
     if (siginfo) {
        micalg = extract_micalg (siginfo);
        free (siginfo);
@@ -1254,6 +1257,93 @@ failure:
 }
 
 
+/*
+ * Sign the file with clear text and replace its content with the signed one.
+ */
+gint
+rfc2015_clearsign (const gchar *file, GSList *key_list)
+{
+    FILE *fp;
+    gchar buf[BUFFSIZE];
+    GpgmeError err;
+    GpgmeData text = NULL;
+    GpgmeData sigdata = NULL;
+    size_t nread;
+    gchar *siginfo;
+
+    if ((fp = fopen(file, "rb")) == NULL) {
+       FILE_OP_ERROR(file, "fopen");
+       goto failure;
+    }
+
+    err = gpgme_data_new(&text);
+    if (err) {
+       debug_print("gpgme_data_new failed: %s\n", gpgme_strerror(err));
+       goto failure;
+    }
+
+    while (!err && fgets(buf, sizeof(buf), fp)) {
+       err = gpgme_data_write(text, buf, strlen(buf));
+    }
+    if (ferror(fp)) {
+       FILE_OP_ERROR(file, "fgets");
+       goto failure;
+    }
+    if (err) {
+       debug_print("gpgme_data_write failed: %s\n", gpgme_strerror(err));
+       goto failure;
+    }
+
+    sigdata = pgp_sign(text, key_list, TRUE, &siginfo);
+    if (siginfo) {
+       g_free(siginfo);
+    }
+    if (!sigdata)
+       goto failure;
+
+    if (fclose(fp) == EOF) {
+       FILE_OP_ERROR(file, "fclose");
+       fp = NULL;
+       goto failure;
+    }
+    if ((fp = fopen(file, "wb")) == NULL) {
+       FILE_OP_ERROR(file, "fopen");
+       goto failure;
+    }
+
+    err = gpgme_data_rewind(sigdata);
+    if (err) {
+       debug_print("gpgme_data_rewind on sigdata failed: %s\n",
+                   gpgme_strerror(err));
+       goto failure;
+    }
+
+    while (!(err = gpgme_data_read(sigdata, buf, sizeof(buf), &nread))) {
+       fwrite(buf, nread, 1, fp);
+    }
+    if (err != GPGME_EOF) {
+       debug_print("gpgme_data_read failed: %s\n", gpgme_strerror(err));
+       goto failure;
+    }
+
+    if (fclose(fp) == EOF) {
+       FILE_OP_ERROR(file, "fclose");
+       fp = NULL;
+       goto failure;
+    }
+    gpgme_data_release(text);
+    gpgme_data_release(sigdata);
+    return 0;
+
+failure:
+    if (fp)
+       fclose(fp);
+    gpgme_data_release(text);
+    gpgme_data_release(sigdata);
+    return -1;
+}
+
+
 /****************
  * Create a new boundary in a way that it is very unlikely that this
  * will occur in the following text.  It would be easy to ensure
index 7b08751..d9def6f 100644 (file)
 
 #include "procmime.h"
 
-void rfc2015_disable_all (void);
-void rfc2015_secure_remove (const char *fname);
-MimeInfo * rfc2015_find_signature (MimeInfo *mimeinfo);
-gboolean rfc2015_has_signature (MimeInfo *mimeinfo);
-void rfc2015_check_signature (MimeInfo *mimeinfo, FILE *fp);
-int rfc2015_is_encrypted (MimeInfo *mimeinfo);
-gboolean rfc2015_msg_is_encrypted (gchar *file);
-void rfc2015_decrypt_message (MsgInfo *msginfo, MimeInfo *mimeinfo, FILE *fp);
-GSList *rfc2015_create_signers_list (const char *keyid);
-int rfc2015_encrypt (const char *file, GSList *recp_list, gboolean ascii_armored);
-int rfc2015_sign (const char *file, GSList *key_list);
+void rfc2015_disable_all               (void);
+void rfc2015_secure_remove             (const gchar    *fname);
+MimeInfo *rfc2015_find_signature       (MimeInfo       *mimeinfo);
+gboolean rfc2015_has_signature         (MimeInfo       *mimeinfo);
+void rfc2015_check_signature           (MimeInfo       *mimeinfo,
+                                        FILE           *fp);
+gint rfc2015_is_encrypted              (MimeInfo       *mimeinfo);
+gboolean rfc2015_msg_is_encrypted      (const gchar    *file);
+void rfc2015_decrypt_message           (MsgInfo        *msginfo,
+                                        MimeInfo       *mimeinfo,
+                                        FILE           *fp);
+GSList *rfc2015_create_signers_list    (const gchar    *keyid);
+gint rfc2015_encrypt                   (const gchar    *file,
+                                        GSList         *recp_list,
+                                        gboolean        ascii_armored);
+gint rfc2015_sign                      (const gchar    *file,
+                                        GSList         *key_list);
+gint rfc2015_clearsign                 (const gchar    *file,
+                                        GSList         *key_list);
 
 #endif /* __RFC2015_H__ */
index 66b0b4b..ed8314c 100644 (file)
@@ -1470,11 +1470,11 @@ gchar *get_tmp_dir(void)
 
 gchar *get_tmp_file(void)
 {
-       static gchar *tmp_file = NULL;
+       gchar *tmp_file;
+       static guint32 id = 0;
 
-       if (!tmp_file)
-               tmp_file = g_strconcat(get_tmp_dir(), G_DIR_SEPARATOR_S,
-                                      "tmpfile", NULL);
+       tmp_file = g_strdup_printf("%s%ctmpfile.%08x",
+                                  get_tmp_dir(), G_DIR_SEPARATOR, id++);
 
        return tmp_file;
 }
@@ -2176,15 +2176,19 @@ gint canonicalize_file_replace(const gchar *file)
 
        tmp_file = get_tmp_file();
 
-       if (canonicalize_file(file, tmp_file) < 0)
+       if (canonicalize_file(file, tmp_file) < 0) {
+               g_free(tmp_file);
                return -1;
+       }
 
        if (move_file(tmp_file, file, TRUE) < 0) {
                g_warning("can't replace %s .\n", file);
                unlink(tmp_file);
+               g_free(tmp_file);
                return -1;
        }
 
+       g_free(tmp_file);
        return 0;
 }
 
@@ -2263,6 +2267,81 @@ FILE *str_open_as_stream(const gchar *str)
        return fp;
 }
 
+gint str_write_to_file(const gchar *str, const gchar *file)
+{
+       FILE *fp;
+       size_t len;
+
+       g_return_val_if_fail(str != NULL, -1);
+       g_return_val_if_fail(file != NULL, -1);
+
+       if ((fp = fopen(file, "wb")) == NULL) {
+               FILE_OP_ERROR(file, "fopen");
+               return -1;
+       }
+
+       len = strlen(str);
+       if (len == 0) {
+               fclose(fp);
+               return 0;
+       }
+
+       if (fwrite(str, len, 1, fp) != 1) {
+               FILE_OP_ERROR(file, "fwrite");
+               fclose(fp);
+               unlink(file);
+               return -1;
+       }
+
+       if (fclose(fp) == EOF) {
+               FILE_OP_ERROR(file, "fclose");
+               unlink(file);
+               return -1;
+       }
+
+       return 0;
+}
+
+gchar *file_read_to_str(const gchar *file)
+{
+       GByteArray *array;
+       FILE *fp;
+       gchar buf[BUFSIZ];
+       gint n_read;
+       gchar *str;
+
+       g_return_val_if_fail(file != NULL, NULL);
+
+       if ((fp = fopen(file, "rb")) == NULL) {
+               FILE_OP_ERROR(file, "fopen");
+               return NULL;
+       }
+
+       array = g_byte_array_new();
+
+       while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
+               if (n_read < sizeof(buf) && ferror(fp))
+                       break;
+               g_byte_array_append(array, buf, n_read);
+       }
+
+       if (ferror(fp)) {
+               FILE_OP_ERROR(file, "fread");
+               fclose(fp);
+               g_byte_array_free(array, TRUE);
+               return NULL;
+       }
+
+       fclose(fp);
+
+       buf[0] = '\0';
+       g_byte_array_append(array, buf, 1);
+       str = (gchar *)array->data;
+       g_byte_array_free(array, FALSE);
+
+       return str;
+}
+
 gint execute_async(gchar *const argv[])
 {
        pid_t pid;
index d1c0762..94b9d3d 100644 (file)
@@ -343,6 +343,9 @@ gint change_file_mode_rw    (FILE           *fp,
                                 const gchar    *file);
 FILE *my_tmpfile               (void);
 FILE *str_open_as_stream       (const gchar    *str);
+gint str_write_to_file         (const gchar    *str,
+                                const gchar    *file);
+gchar *file_read_to_str                (const gchar    *file);
 
 /* process execution */
 gint execute_async             (gchar *const    argv[]);