commit-mailutils
[Top][All Lists]
Advanced

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

[SCM] GNU Mailutils branch, master, updated. release-3.1.1-28-geabddf8


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-3.1.1-28-geabddf8
Date: Fri, 13 Jan 2017 22:12:45 +0000 (UTC)

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=eabddf8f5f18afddc13281a5fbaa562f75e76b5f

The branch, master has been updated
       via  eabddf8f5f18afddc13281a5fbaa562f75e76b5f (commit)
       via  0c76b2b1a4325a8e96292161ee95523ecb6cbc14 (commit)
      from  00c27bc22c1d032e0b9716bc87abbf6b68cbbb43 (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 eabddf8f5f18afddc13281a5fbaa562f75e76b5f
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Jan 13 14:45:09 2017 +0200

    mail: new options to read attachments from file descriptors
    
    * mail/mail.c (default_encoding,default_content_type)
    (content_name,content_filename): New statics.
    (cli_attach): Use the value of --content-name option as the
    content-type name parameter.
    The "-" argument instructs the program to read attachment from
    stdin (eqv --attach-fd=0)
    (cli_attach_fd): New function.
    (mail_options): New options: --content-name, --content-filename,
    --attach-fd
    * mail/mail.h (send_attach_file_default): Remove.
    (send_attach_file): New proto.
    * mail/send.c (atchinfo): New fields: id, name, source.
    (atchinfo_free): Update.
    (default_encoding,default_content_type): Remove globals.
    (send_attach_file): Rewrite.
    (send_attach_file_default): Remove.
    (escape_list_attachments): Print attachment identifier instead
    of the file name, which can be NULL.
    (saveatt): Use mu_attachment_create and mu_attachment_copy_from_stream.
    
    * NEWS: Update.
    * doc/texinfo/programs.texi: Document the new options.

commit 0c76b2b1a4325a8e96292161ee95523ecb6cbc14
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Jan 13 14:43:09 2017 +0200

    Fix default nullstream read mode
    
    * libmailutils/stream/nullstream.c (_nullstream_free_pattern): Always
    reset pattern and patsize.
    (mu_nullstream_create): Fix patsize.

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

Summary of changes:
 NEWS                             |   50 +++++++++++++-
 doc/texinfo/programs.texi        |  137 +++++++++++++++++++++++++++++++++++++-
 libmailutils/stream/nullstream.c |    8 +--
 mail/mail.c                      |   54 ++++++++++++++-
 mail/mail.h                      |    6 +-
 mail/send.c                      |  111 +++++++++++++++++++++---------
 6 files changed, 325 insertions(+), 41 deletions(-)

diff --git a/NEWS b/NEWS
index 90ac188..79d09c5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2016-12-17
+GNU mailutils NEWS -- history of user-visible changes. 2017-01-13
 Copyright (C) 2002-2017 Free Software Foundation, Inc.
 See the end of file for copying conditions.
 
@@ -7,6 +7,54 @@ Please send mailutils bug reports to <address@hidden>.
 
 Version 3.1.90 (Git)
 
+* mail
+
+** Modifying attachment name and filename
+
+Two new options are provided for modifying attachment name (a.k.a
+description), and file name:
+
+  --content-name=STRING
+     Sets the attachment name (description).  Technically speaking, it
+     is the "name" parameter in the Content-Type MIME header.
+     
+  --content-filename=NAME
+     Sets the file name (the "filename" parameter in the
+     Content-Description MIME header of the outgoing message.
+
+Both options affect only the next `--attach' or `--attach-fd' option.
+
+* Constructing attachments from command line
+
+The new option `--attach-fd=N' instructs mail to read attachment from
+file descriptor N.  By default, the attachments created using this
+option are unnamed, i.e. neither name parameter of the Content-Type
+header, nor the filename parameter of the Content-Disposition header
+are set.  Use the --content-name and --content-filename options to
+change these.
+
+The option `--attach-fd=0' causes attachment to be read from the
+standard input.  The option `--attach=-' has the same effect.  For
+obvious reasons, the interactive mode is suppressed in this case.
+
+The `--attach-fd' option is useful when calling `mail' from another
+program.
+
+Example:
+
+Suppose that the 'mail' binary is opened at file descriptor 5 and
+the mail.c file is opened at descriptor 6, the following command
+line sends them as attachments:
+
+  mail --encoding=base64 \
+       --content-type=application/octet-stream \
+       --content-name="the mail(1) binary" --content-filename="mail" \
+       --attach-fd=5 \
+       --encoding=binary\
+       --content-type=text/plain --content-name="mail.c source file"\
+       --content-filename=mail.c --attach-fd=6 \
+       address@hidden
+
 
 Version 3.1.1 - 2016-12-15
 
diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi
index 3e3f98e..7d1a6ec 100644
--- a/doc/texinfo/programs.texi
+++ b/doc/texinfo/programs.texi
@@ -2915,6 +2915,7 @@ Configuration Files}, for a detailed description of their 
format.
 * Invoking Mail::            Command Line Options.
 * Specifying Messages::      How to Specify Message Sets.
 * Composing Mail::           Composing Mail.
+* Attachments::              Attaching Files.
 * Reading Mail::             Reading Mail.
 * Scripting::                Scripting.
 * Mail Variables::           How to Alter the Behavior of @command{mail}.
@@ -2938,9 +2939,22 @@ mail sending mode, otherwise it operates in mail reading 
mode.
 @table @option
 @item -A @var{file}
 @itemx address@hidden
-Attach @var{file} to the composed message.  The encoding and content
-type are controlled by the @option{--encoding} and
address@hidden options, correspondingly.
+Attach @var{file} to the composed message.  The encoding, content
+type, and content description are controlled by the
address@hidden, @option{--content-type}, and
address@hidden options, correspondingly.
+
+The option @option{--attach=-} instructs @command{mail} to read the
+file to be attached from the standard input.  Interactive shell is
+disabled in this case.
+
address@hidden address@hidden
+Read attachment body from the file descriptor @var{fd}.  The
+descriptor must be open for reading.  This option is useful when
+calling @command{mail} from another program.
+
+See the options @option{--encoding}, @option{--content-type}, 
address@hidden, and @option{--content-filename}.
 
 @item -a @var{header}:@var{value}
 @itemx address@hidden:@var{value}
@@ -2950,6 +2964,14 @@ Append the given header to the composed message.
 This options sets the content type to be used by all subsequent
 @option{--attach} options.
 
address@hidden address@hidden
+Set the @samp{filename} parameter in the @samp{Content-Disposition}
+header for the next @option{--attach-fd} option.
+
address@hidden address@hidden
+Set the @samp{name} parameter (description) in the @samp{Content-Type}
+header for the next @option{--attach} or @option{--attach-fd} option.
+
 @item -E @var{command}
 @itemx address@hidden
 Execute @var{command} before opening the mailbox.  Any number of
@@ -3412,6 +3434,115 @@ the old contents of your message.
 
 @c *********************************************************************
 
address@hidden Attachments
address@hidden Sending Attachments
+
+The simplest way to attach a file from command line is by using the
address@hidden (@option{-A}) option.  Its argument specifies the
+file to attach.  For example, the following will attach the content
+of the file @file{archive.tar}:
+
address@hidden
+$ mail --attach=archive.tar
address@hidden example
+
+By default, the content type will be set to
address@hidden/octet-stream}, and the attachment will be encoded
+using the @samp{base64} encoding.  To change the content type, use the
address@hidden option.  For example, to send an HTML
+attachment:
+
address@hidden
+$ mail --content-type=text/html --attach=in.html
address@hidden example
+
+The @option{--content-type} option affects all @option{--attach}
+options that follow it.  To change the content type, simply add
+another @option{--content-type} option.  For example, to send both
+the HTML file and the archive:
+
address@hidden
+$ mail --content-type=text/html --attach=in.html \
+       --content-type=application/x-tar --attach=archive.tar
address@hidden example
+
+Similarly, the encoding to use is set up by the @option{--encoding}
+option.  As well as @option{--content-type}, this option affects all
+attachments supplied after it in the command line, until changed by
+the eventual next appearance of the same option.  Extending the above
+example:
+
address@hidden
+$ mail --content-type=text/html --encoding=quoted-printable \
+       --attach=in.html \
+       --content-type=application/x-tar --encoding=base64 \
+       --attach=archive.tar
address@hidden example
+
+Each attachment can also be assigned a @dfn{description} and a
address@hidden name}.  Normally, these are the same as the file name
+supplied with the @option{--attach} option.  However, you can change
+either or both of them using the @option{--content-name} and
address@hidden, correspondingly.  Both of these options
+affect only the next @option{--attach} (or @option{--attach-fd}, see
+below) option.
+
+All the examples above will enter the usual interactive shell,
+allowing you to compose the body of the message.  If that's not
+needed, the non-interactive use can be forced by redirecting
address@hidden/dev/null} to the standard input, e.g.:
+
address@hidden
+$ mail --attach=archive.tar < /dev/null
address@hidden example
+
+This will normally produce a message saying:
+
address@hidden
+mail: Null message body; hope that's ok
address@hidden example
+
+To suppress this message, unset the @samp{nullbodymsg} variable,
+as shown in the example below:
+
address@hidden
+$ mail -E 'set nonullbodymsg' --attach=archive.tar < /dev/null
address@hidden example
+
+The option @option{--attach=-} forces @command{mail} to read the file
+to be attached from the standard input stream.  This option implies
+disables the interactive mode and sets @samp{nonullbodymsg}
+implicitly, so that the above example can be rewritten as:
+
address@hidden
+$ mail --attach=- < archive.tar
address@hidden example
+
+Special option is provided to facilitate the use of @command{mail}
+in scripts.  The @address@hidden instructs the program to
+read the data to be attached from the file descriptor @var{N}.  The
+above example is equivalent to:
+
address@hidden
+$ mail --attach-fd=0 < archive.tar
address@hidden example
+
+Attachments created using this option have neither filename not
+description set, so normally the use of @option{--content-name} and/or
address@hidden is advised.
+
address@hidden
+$ mail --subject 'mail(1)' \
+       --content-name="The mail(1) binary" --content-filename="mail" \
+       --attach-fd 5 \
+       --encoding=binary --content-type=text/plain \
+       --content-name="mail.c source file" --content-filename=mail.c \
+       --attach-fd 6 gray@@example.org 5</usr/bin/mail \
+       6<mailutils/mail/mail.c
address@hidden example
+
address@hidden 
*********************************************************************
+
 @node Reading Mail
 @subsection Reading Mail
 
diff --git a/libmailutils/stream/nullstream.c b/libmailutils/stream/nullstream.c
index 12df168..4fdaafc 100644
--- a/libmailutils/stream/nullstream.c
+++ b/libmailutils/stream/nullstream.c
@@ -66,10 +66,10 @@ _nullstream_free_pattern (struct _mu_nullstream *np)
   if (!(np->mode & MU_NULLSTREAM_PATSTAT))
     {
       free (np->pattern);
-      np->pattern = NULL;
-      np->patsize = 0;
       np->mode &= ~MU_NULLSTREAM_PATSTAT;
     }
+  np->pattern = NULL;
+  np->patsize = 0;
 }
 
 static void
@@ -196,8 +196,8 @@ mu_nullstream_create (mu_stream_t *pref, int flags)
   np->base.truncate = _nullstream_truncate;
   np->base.done = _nullstream_done;
 
-  np->pattern = "";
-  np->patsize = 0;
+  np->pattern = "\0";
+  np->patsize = 1;
   np->mode = MU_NULLSTREAM_PATSTAT;
   
   *pref = (mu_stream_t) np;
diff --git a/mail/mail.c b/mail/mail.c
index 71fd812..ca3f08e 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -35,6 +35,11 @@ const char *program_version = "mail (" PACKAGE_STRING ")";
 int hint;
 char *file;
 char *user;
+
+char *default_encoding;
+char *default_content_type;
+char *content_name;
+char *content_filename;
 
 static void
 cli_f_option (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
@@ -134,9 +139,45 @@ cli_append (struct mu_parseopt *po, struct mu_option *opt, 
char const *arg)
 static void
 cli_attach (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
+  int fd = -1;
+  
   hint |= HINT_SEND_MODE;
-  if (send_attach_file_default (arg))
+  if (strcmp (arg, "-") == 0)
+    {
+      arg = NULL;
+      fd = 0;
+    }
+  if (send_attach_file (fd, arg, content_filename, content_name,
+                       default_content_type, default_encoding))
     exit (1);
+
+  free (content_name);
+  content_name = NULL;
+  free (content_filename);
+  content_filename = NULL;
+}
+
+static void
+cli_attach_fd (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  int rc, fd;
+  
+  hint |= HINT_SEND_MODE;
+  rc = mu_str_to_c (arg, mu_c_int, &fd, NULL);
+  if (rc)
+    {
+      mu_parseopt_error (po, _("%s: bad descriptor"), arg);
+      exit (po->po_exit_error);
+    }
+  
+  if (send_attach_file (fd, NULL, content_filename, content_name,
+                       default_content_type, default_encoding))
+    exit (1);
+
+  free (content_name);
+  content_name = NULL;
+  free (content_filename);
+  content_filename = NULL;
 }
 
 static struct mu_option mail_options[] = {
@@ -212,10 +253,21 @@ static struct mu_option mail_options[] = {
     N_("set content type for subsequent --attach options"),
     mu_c_string, &default_content_type },
   
+  { "content-name", 0, N_("NAME"), MU_OPTION_DEFAULT,
+    N_("set the Content-Type name parameter for the next --attach option"),
+    mu_c_string, &content_name },
+  { "content-filename", 0, N_("NAME"), MU_OPTION_DEFAULT,
+    N_("set the Content-Disposition filename parameter for the next --attach 
option"),
+    mu_c_string, &content_filename },
+  
   { "attach",  'A', N_("FILE"), MU_OPTION_DEFAULT,
     N_("attach FILE"),
     mu_c_string, NULL, cli_attach },
 
+  { "attach-fd",  0, N_("FD"), MU_OPTION_DEFAULT,
+    N_("attach from file descriptor FD"),
+    mu_c_string, NULL, cli_attach_fd },
+
   MU_OPTION_END
 }, *options[] = { mail_options, NULL };
 
diff --git a/mail/mail.h b/mail/mail.h
index 7efc0be..35a81d3 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -258,7 +258,11 @@ extern char *mail_expand_name (const char *name);
 
 extern void send_append_header (char const *text);
 extern void send_append_header2 (char const *name, char const *value, int 
mode);
-extern int send_attach_file_default (const char *name);
+extern int send_attach_file (int fd,
+                            const char *filename,
+                            const char *content_filename,
+                            const char *content_name,
+                            const char *content_type, const char *encoding);
 
 extern int escape_check_args (int argc, char **argv, int minargs, int maxargs);
 
diff --git a/mail/send.c b/mail/send.c
index 1ab1c18..8456ad8 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -134,55 +134,97 @@ mail_sendheader (int argc, char **argv)
 /* Attachments */
 struct atchinfo
 {
+  char *id;
   char *encoding;
   char *content_type;
+  char *name;
   char *filename;
+  mu_stream_t source;
 };
 
 static mu_list_t attlist;
 
-char *default_encoding;
-char *default_content_type;
-
 static void
 atchinfo_free (void *p)
 {
   struct atchinfo *ap = p;
+  free (ap->id);
   free (ap->encoding);
   free (ap->content_type);
+  free (ap->name);
   free (ap->filename);
+  mu_stream_destroy (&ap->source);
   free (ap);
 }
 
 int
-send_attach_file (const char *name,
+send_attach_file (int fd,
+                 const char *realname,
+                 const char *content_filename, const char *content_name,
                  const char *content_type, const char *encoding)
 {
   int rc;
   struct stat st;
   struct atchinfo *aptr;
   mu_list_t list;
-  
-  if (stat (name, &st))
+  mu_stream_t stream = NULL;
+  char *id = NULL;
+
+  if (fd >= 0)
     {
-      if (errno == ENOENT)
+      rc = mu_fd_stream_create (&stream, NULL, fd, MU_STREAM_READ);
+      if (rc)
        {
-         mu_error (_("%s: file does not exist"), name);
+         mu_error (_("can't open descriptor %d: %s"), fd, mu_strerror (rc));
          return 1;
        }
-      else
+      mu_asprintf (&id, "fd %d", fd);
+      if (fd == 0)
        {
-         mu_error (_("%s: cannot stat: %s"), name, mu_strerror (errno));
-         return 1;
+         mu_stream_destroy (&mu_strin);
+         mu_nullstream_create (&mu_strin, MU_STREAM_READ);
+         mu_stream_ioctl (mu_strin, MU_IOCTL_NULLSTREAM,
+                          MU_IOCTL_NULLSTREAM_SET_PATTERN, NULL);
+         util_do_command ("set nullbody nullbodymsg");
        }
     }
-
-  if (!S_ISREG (st.st_mode))
+  else if (realname)
     {
-      mu_error (_("%s: not a regular file"), name);
-      return 1;
-    }
+      if (!content_filename)
+       content_filename = realname;
+      if (stat (realname, &st))
+       {
+         if (errno == ENOENT)
+           {
+             mu_error (_("%s: file does not exist"), realname);
+             return 1;
+           }
+         else
+           {
+             mu_error (_("%s: cannot stat: %s"), realname,
+                       mu_strerror (errno));
+             return 1;
+           }
+       }
+      
+      if (!S_ISREG (st.st_mode))
+       {
+         mu_error (_("%s: not a regular file"), realname);
+         return 1;
+       }
 
+      rc = mu_mapfile_stream_create (&stream, realname, MU_STREAM_READ);
+      if (rc)
+       {
+         mu_error (_("can't open file %s: %s"),
+                   realname, mu_strerror (rc));
+         return 1;
+       }
+      mu_asprintf (&id, "\"%s\"", realname);
+    }
+  else
+    abort ();
+  
   if (!encoding)
     encoding = "base64";
   mu_filter_get_list (&list);
@@ -190,6 +232,8 @@ send_attach_file (const char *name,
   if (rc)
     {
       mu_error (_("unsupported encoding: %s"), encoding);
+      free (id);
+      mu_stream_destroy (&stream);
       return 1;
     }
   
@@ -205,11 +249,13 @@ send_attach_file (const char *name,
     }
   aptr = mu_alloc (sizeof (*aptr));
 
+  aptr->id = id;
   aptr->encoding = mu_strdup (encoding);  
   aptr->content_type = mu_strdup (content_type ?
-                                 content_type :
-                                   "application/octet-stream");
-  aptr->filename = mu_strdup (name);
+                                 content_type : "application/octet-stream");
+  aptr->name = content_name ? mu_strdup (content_name) : NULL;
+  aptr->filename = content_filename ? mu_strdup (content_filename) : NULL;
+  aptr->source = stream;
   rc = mu_list_append (attlist, aptr);
   if (rc)
     {
@@ -220,12 +266,6 @@ send_attach_file (const char *name,
 }
 
 int
-send_attach_file_default (const char *name)
-{
-  return send_attach_file (name, default_content_type, default_encoding);
-}
-
-int
 escape_list_attachments (int argc, char **argv, compose_env_t *env)
 {
   mu_iterator_t itr;
@@ -246,7 +286,7 @@ escape_list_attachments (int argc, char **argv, 
compose_env_t *env)
        continue;
          
       mu_printf ("%3d %-12s %-30s %-s\n",
-                i, aptr->filename, aptr->content_type, aptr->encoding);
+                i, aptr->id, aptr->content_type, aptr->encoding);
     }
   mu_iterator_destroy (&itr);
 
@@ -266,7 +306,8 @@ escape_attach (int argc, char **argv, compose_env_t *env)
     case 3:
       content_type = argv[2];
     case 2:
-      return send_attach_file (argv[1], content_type, encoding);
+      return send_attach_file (-1, argv[1], argv[1], argv[1],
+                              content_type, encoding);
     default:
       return escape_check_args (argc, argv, 2, 4);
     }
@@ -309,12 +350,20 @@ saveatt (void *item, void *data)
   int rc;
   size_t nparts;
   char *p;
-  
-  rc = mu_message_create_attachment (aptr->content_type, aptr->encoding,
-                                    aptr->filename, &part);
+
+  rc = mu_attachment_create (&part, aptr->content_type, aptr->encoding,
+                            aptr->name, aptr->filename);
+  if (rc)
+    {
+      mu_error (_("can't create attachment %s: %s"),
+               aptr->id, mu_strerror (rc));
+      return 1;
+    }
+
+  rc = mu_attachment_copy_from_stream (part, aptr->source, aptr->encoding);
   if (rc)
     {
-      mu_error (_("cannot attach \"%s\": %s"), aptr->filename,
+      mu_error (_("cannot attach %s: %s"), aptr->filename,
                mu_strerror (rc));
       return 1;
     }


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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