commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg-295-gf8fc208
Date: Mon, 13 Jul 2009 12:07:20 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=f8fc2081dffd950ab1c6082e4a32f0096bd7415d

The branch, master has been updated
       via  f8fc2081dffd950ab1c6082e4a32f0096bd7415d (commit)
      from  0517ca033b3222afc09f5b70626c38280c749c14 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f8fc2081dffd950ab1c6082e4a32f0096bd7415d
Author: Sergey Poznyakoff <address@hidden>
Date:   Mon Jul 13 14:42:40 2009 +0300

    mail: implement struct command.
    
    * NEWS, doc/texinfo/programs.texi: Document struct command.
    * mail/struct.c: New file.
    * mail/Makefile.am (mail_SOURCES): Add struct.c
    * mail/decode.c (fprint_msgset, mime_descend): New functions.
    Rewrite the rest using mime_descend.
    * mail/mail.h (mail_struct): New function.
    (MDHINT_SELECTED_HEADERS): New define.
    (struct mime_descend_closure, mime_descend_fn): New types.
    (mime_descend): New proto.
    (util_get_content_type): Get two arguments.
    * mail/table.c (mail_command_table): Add st[ruct].
    * mail/util.c (util_get_content_type): Get two arguments.
    All callers updated.
    (util_get_hdr_value): use mu_header_aget_value_unfold and
    mu_rtrim_class.

-----------------------------------------------------------------------

Summary of changes:
 NEWS                      |   11 +++-
 doc/texinfo/programs.texi |   16 +++++
 mail/Makefile.am          |    1 +
 mail/decode.c             |  136 +++++++++++++++++++++++++++++++--------------
 mail/mail.h               |   26 ++++++++-
 mail/struct.c             |   71 +++++++++++++++++++++++
 mail/table.c              |    2 +
 mail/util.c               |   28 +++++----
 8 files changed, 235 insertions(+), 56 deletions(-)
 create mode 100644 mail/struct.c

diff --git a/NEWS b/NEWS
index b5524bf..82514b7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2009-07-12
+GNU mailutils NEWS -- history of user-visible changes. 2009-07-13
 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 
 2008, 2009 Free Software Foundation, Inc.
 See the end of file for copying conditions.
@@ -53,6 +53,15 @@ is also allowed.
 The -F option (record outgoing messages in a file named after the
 first recipient) is implemented.
 
+** struct command
+
+The st[ruct] command allows to list message MIME structures, e.g.:
+
+& struct 2
+2[1]  text/plain                 513
+2[2]  application/octal-stream  247K
+2[3]  text/x-diff                31K
+
 ** error locations
 
 Diagnostic messages issued while processing `source' command
diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi
index d5aa430..20be516 100644
--- a/doc/texinfo/programs.texi
+++ b/doc/texinfo/programs.texi
@@ -2878,6 +2878,7 @@ Displays current mailbox summary. E.g.:
 @kyindex Print, mail command
 @kyindex Type, mail command
 @kyindex decode, mail command
address@hidden struct, mail command
 @kyindex top, mail command
 @kyindex pipe, mail command
 @kyindex |, mail command
@@ -2926,6 +2927,21 @@ defaults to five.
 Pipe the contents of specified messages through @var{shell-command}. If
 @var{shell-command} is empty but the string variable @code{cmd} is set,
 the value of this variable is used as a command name.
address@hidden struct address@hidden
+Prints the @acronym{MIME} structure of each message from
address@hidden Empty @var{msglist} means current message.
+
+Example:
+
address@hidden
address@hidden
+& struct 2
+2      multipart/mixed            14k
+2[1]   text/plain                 296
+2[2]   application/octet-stream    5k
+2[3]   text/x-diff                31k
address@hidden cartouche
address@hidden smallexample
 @end table
 
 @node Marking Messages
diff --git a/mail/Makefile.am b/mail/Makefile.am
index a47694b..bcd482d 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -84,6 +84,7 @@ mail_SOURCES = \
  shell.c\
  size.c\
  source.c\
+ struct.c\
  summary.c\
  table.c\
  tag.c\
diff --git a/mail/decode.c b/mail/decode.c
index 369ed76..1b951fb 100644
--- a/mail/decode.c
+++ b/mail/decode.c
@@ -33,7 +33,8 @@ struct decode_closure
 
 static int print_stream (mu_stream_t, FILE *);
 static int display_message (mu_message_t, msgset_t *msgset, void *closure);
-static int display_message0 (mu_message_t, const msgset_t *, int);
+static int display_submessage (struct mime_descend_closure *closure,
+                              void *data);
 static int get_content_encoding (mu_header_t hdr, char **value);
 static void run_metamail (const char *mailcap, mu_message_t mesg);
 
@@ -59,12 +60,20 @@ display_message (mu_message_t mesg, msgset_t *msgset, void 
*arg)
 {
   struct decode_closure *closure = arg;
   mu_attribute_t attr = NULL;
-
+  struct mime_descend_closure mclos;
+  
   mu_message_get_attribute (mesg, &attr);
   if (mu_attribute_is_deleted (attr))
     return 1;
 
-  display_message0 (mesg, msgset, closure->select_hdr);
+  mclos.hints = closure->select_hdr ? MDHINT_SELECTED_HEADERS : 0;
+  mclos.msgset = msgset;
+  mclos.message = mesg;
+  mclos.type = NULL;
+  mclos.encoding = NULL;
+  mclos.parent = NULL;
+
+  mime_descend (&mclos, display_submessage, NULL);
 
   /* Mark enclosing message as read */
   if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &mesg) == 0)
@@ -112,9 +121,23 @@ display_headers (FILE *out, mu_message_t mesg,
     }
 }
 
+size_t
+fprint_msgset (FILE *fp, const msgset_t *msgset)
+{
+  int i;
+  size_t n = 0;
+  
+  n = fprintf (fp, "%d", msgset->msg_part[0]);
+  for (i = 1; i < msgset->npart; i++)
+    n += fprintf (fp, "[%d", msgset->msg_part[i]);
+  for (i = 1; i < msgset->npart; i++)
+    n += fprintf (fp, "]");
+  return n;
+}
+
 static void
 display_part_header (FILE *out, const msgset_t *msgset,
-                    char *type, char *encoding)
+                    const char *type, const char *encoding)
 {
   int size = util_screen_columns () - 3;
   unsigned int i;
@@ -124,11 +147,8 @@ display_part_header (FILE *out, const msgset_t *msgset,
     fputc ('-', out);
   fputc ('+', out);
   fputc ('\n', out);
-  fprintf (out, _("| Message=%d"), msgset->msg_part[0]);
-  for (i = 1; i < msgset->npart; i++)
-    fprintf (out, "[%d", msgset->msg_part[i]);
-  for (i = 1; i < msgset->npart; i++)
-    fprintf (out, "]");
+  fprintf (out, "%s", _("| Message="));
+  fprint_msgset (out, msgset);
   fprintf (out, "\n");
 
   fprintf (out, _("| Type=%s\n"), type);
@@ -140,38 +160,49 @@ display_part_header (FILE *out, const msgset_t *msgset,
   fputc ('\n', out);
 }
 
-static int
-display_message0 (mu_message_t mesg, const msgset_t *msgset,
-                 int select_hdr)
+int
+mime_descend (struct mime_descend_closure *closure,
+             mime_descend_fn fun, void *data)
 {
+  int status = 0;
   size_t nparts = 0;
   mu_header_t hdr = NULL;
   char *type;
   char *encoding;
   int ismime = 0;
-  char *tmp;
+  struct mime_descend_closure subclosure;
 
-  mu_message_get_header (mesg, &hdr);
-  util_get_content_type (hdr, &type);
+  mu_message_get_header (closure->message, &hdr);
+  util_get_content_type (hdr, &type, NULL);
   get_content_encoding (hdr, &encoding);
 
-  mu_message_is_multipart (mesg, &ismime);
+  closure->type = type;
+  closure->encoding = encoding;
+  
+  subclosure.hints = 0;
+  subclosure.parent = closure;
+  
+  mu_message_is_multipart (closure->message, &ismime);
   if (ismime)
     {
       unsigned int j;
-      
-      mu_message_get_num_parts (mesg, &nparts);
+
+      mu_message_get_num_parts (closure->message, &nparts);
 
       for (j = 1; j <= nparts; j++)
        {
          mu_message_t message = NULL;
 
-         if (mu_message_get_part (mesg, j, &message) == 0)
+         if (mu_message_get_part (closure->message, j, &message) == 0)
            {
-             msgset_t *set = msgset_expand (msgset_dup (msgset),
+             msgset_t *set = msgset_expand (msgset_dup (closure->msgset),
                                             msgset_make_1 (j));
-             display_message0 (message, set, 0);
+             subclosure.msgset = set;
+             subclosure.message = message;
+             status = mime_descend (&subclosure, fun, data);
              msgset_free (set);
+             if (status)
+               break;
            }
        }
     }
@@ -179,14 +210,36 @@ display_message0 (mu_message_t mesg, const msgset_t 
*msgset,
     {
       mu_message_t submsg = NULL;
 
-      if (mu_message_unencapsulate (mesg, &submsg, NULL) == 0)
-       display_message0 (submsg, msgset, select_hdr);
+      if (mu_message_unencapsulate (closure->message, &submsg, NULL) == 0)
+       {
+         subclosure.hints = MDHINT_SELECTED_HEADERS;
+         subclosure.msgset = closure->msgset;
+         subclosure.message = submsg;
+         status = mime_descend (&subclosure, fun, data);
+       }
     }
-  else if (mailvar_get (&tmp, "metamail", mailvar_type_string, 0) == 0)
+  else
+    status = fun (closure, data);
+
+  closure->type = NULL;
+  closure->encoding = NULL;
+  
+  free (type);
+  free (encoding);
+
+  return status;
+}
+
+static int
+display_submessage (struct mime_descend_closure *closure, void *data)
+{
+  char *tmp;
+  
+  if (mailvar_get (&tmp, "metamail", mailvar_type_string, 0) == 0)
     {
       /* If `metamail' is set to a string, treat it as command line
         of external metamail program. */
-      run_metamail (tmp, mesg);
+      run_metamail (tmp, closure->message);
     }
   else
     {
@@ -197,19 +250,20 @@ display_message0 (mu_message_t mesg, const msgset_t 
*msgset,
       mu_stream_t stream = NULL;
       mu_header_t hdr = NULL;
       
-      mu_message_get_body (mesg, &body);
-      mu_message_get_header (mesg, &hdr);
+      mu_message_get_body (closure->message, &body);
+      mu_message_get_header (closure->message, &hdr);
       mu_body_get_stream (body, &b_stream);
 
       /* Can we decode.  */
-      if (mu_filter_create(&d_stream, b_stream, encoding,
-                       MU_FILTER_DECODE, MU_STREAM_READ) == 0)
+      if (mu_filter_create(&d_stream, b_stream, closure->encoding,
+                          MU_FILTER_DECODE, MU_STREAM_READ) == 0)
        stream = d_stream;
       else
        stream = b_stream;
-
-      display_part_header (ofile, msgset, type, encoding);
-
+      
+      display_part_header (ofile, closure->msgset,
+                          closure->type, closure->encoding);
+      
       /* If `metamail' is set to true, enable internal mailcap
         support */
       if (mailvar_get (NULL, "metamail", mailvar_type_boolean, 0) == 0)
@@ -225,33 +279,31 @@ display_message0 (mu_message_t mesg, const msgset_t 
*msgset,
          builtin_display = display_stream_mailcap (NULL, stream, hdr, no_ask,
                                                    interactive, 0, debug);
        }
-
+      
       if (builtin_display)
        {
          size_t lines = 0;
          int pagelines = util_get_crt ();
          FILE *out;
          
-         mu_message_lines (mesg, &lines);
+         mu_message_lines (closure->message, &lines);
          if (pagelines && lines > pagelines)
            out = popen (getenv ("PAGER"), "w");
          else
            out = ofile;
-
-         display_headers (out, mesg, msgset, select_hdr);
-
+         
+         display_headers (out, closure->message, closure->msgset,
+                          closure->hints & MDHINT_SELECTED_HEADERS);
+         
          print_stream (stream, out);
-
+         
          if (out != ofile)
            pclose (out);
        }
       if (d_stream)
        mu_stream_destroy (&d_stream, NULL);
     }
-
-  free (type);
-  free (encoding);
-
+  
   return 0;
 }
 
diff --git a/mail/mail.h b/mail/mail.h
index b6e4c39..54e4ce1 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -242,6 +242,7 @@ extern int mail_eq (int argc, char **argv); /* command = */
 extern int mail_setenv (int argc, char **argv);
 extern int mail_envelope (int argc, char **argv);
 extern int print_envelope (msgset_t *mspec, mu_message_t msg, void *data);
+extern int mail_struct (int argc, char **argv);
 
 extern int if_cond (void);
 
@@ -307,6 +308,27 @@ extern int msgset_member (msgset_t *set, size_t n);
 extern msgset_t *msgset_negate (msgset_t *set);
 extern size_t msgset_count (msgset_t *set);
 
+
+#define MDHINT_SELECTED_HEADERS 0x1
+
+struct mime_descend_closure
+{
+  int hints;
+  const msgset_t *msgset;
+  mu_message_t message;
+  const char *type;
+  const char *encoding;
+  const struct mime_descend_closure *parent;
+};
+
+typedef int (*mime_descend_fn) (struct mime_descend_closure *closure,
+                               void *data);
+
+extern int mime_descend (struct mime_descend_closure *closure,
+                        mime_descend_fn fun, void *data);
+
+
+
 extern int util_do_command (const char *cmd, ...) MU_PRINTFLIKE(1,2);
 
 extern int util_foreach_msg (int argc, char **argv, int flags,
@@ -369,7 +391,7 @@ extern int util_tempfile (char **namep);
 extern void util_msgset_iterate (msgset_t *msgset, 
                                  int (*fun) (mu_message_t, msgset_t *, void 
*), 
                                  void *closure);
-extern int util_get_content_type (mu_header_t hdr, char **value);
+extern int util_get_content_type (mu_header_t hdr, char **value, char **args);
 extern int util_get_hdr_value (mu_header_t hdr, const char *name, char 
**value);
 extern int util_merge_addresses (char **addr_str, const char *value);
 extern int util_header_expand (mu_header_t *hdr);
@@ -383,6 +405,8 @@ void util_mark_read (mu_message_t msg);
 
 const char *util_url_to_string (mu_url_t url);
 
+size_t fprint_msgset (FILE *fp, const msgset_t *msgset);
+
 int is_address_field (const char *name);
 
 extern int ml_got_interrupt (void);
diff --git a/mail/struct.c b/mail/struct.c
new file mode 100644
index 0000000..8d22b41
--- /dev/null
+++ b/mail/struct.c
@@ -0,0 +1,71 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   GNU Mailutils 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, or (at your option)
+   any later version.
+
+   GNU Mailutils 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 GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include "mail.h"
+
+#define PART_WIDTH 8
+
+static int
+show_part (struct mime_descend_closure *closure, void *data)
+{
+  size_t width;
+  size_t size = 0;
+  
+  width = fprint_msgset (ofile, closure->msgset);
+  for (; width < 5; width++)
+    fputc (' ', ofile);
+    
+  fprintf (ofile, " %-25s", closure->type);
+
+  mu_message_size (closure->message, &size);
+  if (size < 1024)
+    fprintf (ofile, " %4lu", (unsigned long) size);
+  else if (size < 1024*1024)
+    fprintf (ofile, "%4luK", (unsigned long) size / 1024);
+  else
+    fprintf (ofile, "%4luM", (unsigned long) size / 1024 / 1024);
+
+  fprintf (ofile, "\n");
+  return 0;
+}
+
+static int
+show_struct (msgset_t *msgset, mu_message_t msg, void *data)
+{
+  struct mime_descend_closure mclos;
+  
+  mclos.hints = 0;
+  mclos.msgset = msgset;
+  mclos.message = msg;
+  mclos.type = NULL;
+  mclos.encoding = NULL;
+  mclos.parent = NULL;
+  
+  mime_descend (&mclos, show_part, NULL);
+
+    /* Mark enclosing message as read */
+  if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &msg) == 0)
+    util_mark_read (msg);
+
+  return 0;
+}
+
+int
+mail_struct (int argc, char **argv)
+{
+  return util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT,
+                          show_struct, NULL);
+}
diff --git a/mail/table.c b/mail/table.c
index 3630908..ead4bfe 100644
--- a/mail/table.c
+++ b/mail/table.c
@@ -136,6 +136,8 @@ static const struct mail_command_entry mail_command_table[] 
= {
     mail_size, msglist_compl },
   { "so",      "source",       "so[urce] file",                0,
     mail_source, NULL },
+  { "st",       "struct",       "st[ruct] [msglist]",           0,
+    mail_struct, NULL },
   { "su",      "summary",      "su[mmary]",                    0,
     mail_summary, no_compl },
   { "T",       "Type",         "T[ype] [msglist]",             0,
diff --git a/mail/util.c b/mail/util.c
index 5faea74..95ec9b6 100644
--- a/mail/util.c
+++ b/mail/util.c
@@ -793,7 +793,7 @@ util_descend_subparts (mu_message_t mesg, msgset_t *msgset, 
mu_message_t *part)
       mu_header_t hdr = NULL;
 
       mu_message_get_header (mesg, &hdr);
-      util_get_content_type (hdr, &type);
+      util_get_content_type (hdr, &type, NULL);
       if (mu_c_strncasecmp (type, "message/rfc822", strlen (type)) == 0)
        {
          if (mu_message_unencapsulate (mesg, &submsg, NULL))
@@ -839,12 +839,12 @@ util_msgset_iterate (msgset_t *msgset,
        return;
 
       if (util_descend_subparts (mesg, msgset, &mesg) == 0)
-         (*fun)(mesg, msgset, closure);
+       (*fun) (mesg, msgset, closure);
     }
 }
 
 int
-util_get_content_type (mu_header_t hdr, char **value)
+util_get_content_type (mu_header_t hdr, char **value, char **args)
 {
   char *type = NULL;
   util_get_hdr_value (hdr, MU_HEADER_CONTENT_TYPE, &type);
@@ -854,6 +854,17 @@ util_get_content_type (mu_header_t hdr, char **value)
        free (type);
       type = strdup ("text/plain"); /* Default.  */
     }
+  else
+    {
+      char *p;
+      p = strchr (type, ';');
+      if (p)
+       {
+         *p++ = 0;
+         if (args)
+           *args = p;
+       }
+    }
   *value = type;
   return 0;
 }
@@ -861,16 +872,9 @@ util_get_content_type (mu_header_t hdr, char **value)
 int
 util_get_hdr_value (mu_header_t hdr, const char *name, char **value)
 {
-  int status = mu_header_aget_value (hdr, name, value);
+  int status = mu_header_aget_value_unfold (hdr, name, value);
   if (status == 0)
-    {
-      /* Remove the newlines.  */
-      char *nl;
-      while ((nl = strchr (*value, '\n')) != NULL)
-       {
-         *nl = ' ';
-       }
-    }
+    mu_rtrim_class (*value, MU_CTYPE_SPACE);
   return status;
 }
 


hooks/post-receive
-- 
GNU Mailutils




reply via email to

[Prev in Thread] Current Thread [Next in Thread]