diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-01-14 11:46:21 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-01-14 11:46:21 +0200 |
commit | 51c5ad1b37723b9c61d19a5a4dcff6fb28c7b836 (patch) | |
tree | 1041cc46fd852e12b49881c945172ed355dec950 | |
parent | 2229fcdcea4cbd56de54afb70ebfca1cf352f9d0 (diff) | |
download | mailutils-51c5ad1b37723b9c61d19a5a4dcff6fb28c7b836.tar.gz mailutils-51c5ad1b37723b9c61d19a5a4dcff6fb28c7b836.tar.bz2 |
docs: improve the attachment section.
* doc/texinfo/programs.texi: provide an example script illustrating
how to use mail from another programs.
-rw-r--r-- | doc/texinfo/programs.texi | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi index 7d1a6ec52..ec10d8638 100644 --- a/doc/texinfo/programs.texi +++ b/doc/texinfo/programs.texi @@ -3510,9 +3510,9 @@ $ mail -E 'set nonullbodymsg' --attach=archive.tar < /dev/null @end 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: +to be attached from the standard input stream. This option disables +the interactive mode and sets @samp{nonullbodymsg} implicitly, so that +the above example can be rewritten as: @example $ mail --attach=- < archive.tar @@ -3527,20 +3527,109 @@ above example is equivalent to: $ mail --attach-fd=0 < archive.tar @end example -Attachments created using this option have neither filename not +Attachments created with this option have neither filename nor description set, so normally the use of @option{--content-name} and/or @option{--content-filename} is advised. +The following Perl program serves as an example of using +@command{mail} from a script to construct a MIME message on the fly. +It scans all mounted file systems for executable files that have +setuid or setgid bits set and reports the names of those files in +separate attachments. Each attachment is named after the mountpoint +it describes. + +The script begins with the usual prologue stating the modules that +will be used: + +@example +#!/usr/bin/perl + +use strict; +use autodie; +@end example + +Then global variables are declared. The @samp{@@rcpt} array contains +the email addresses of the recipients: + +@example +my @@rcpt= 'root@@example.com'; +@end example + +The @samp{@@cmd} variable holds the @command{mail} command line. It +will be augmented for each file system. The initial value is set as +follows: + @example -$ 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 +my @@cmd = ('mail', + '-E set nonullbodymsg', + '--content-type=text/plain'); @end example +The @command{find} utility will be used to locate the files. The +script will start as many instances as there are mountpoints. Those +instances will be run in parallel and their standard output streams +will be connected to file descriptors passed to @command{mail} +invocation in @option{--attach-fd} options. + +The descriptors will be held in @samp{@@fds} array. This will prevent +them from being wiped out by the garbage collector. Furthermore, care +should be taken to ensure that the @code{O_CLOECEC} flag be not set +for these descriptors. This sample script takes a simplistic approach: +it instructs Perl to not close first 255 descriptors when executing +another programs: + +@example +my @@fds; +$^F = 255; +@end example + +The following code obtains the list of mount points: + +@example +open(my $in, '-|', 'mount -t nonfs,noproc,nosysfs,notmpfs'); +while (<$in>) @{ + chomp; + if (/^\S+ on (?<mpoint>.+) type (?<fstype>.+) /) @{ +@end example + +For each mountpoint, the @command{find} command line is constructed +and launched. The file descriptor is pushed to the @samp{@@fds} array +to prevent it from being collected by the garbage collector: + +@example + open(my $fd, '-|', + "find $+@{mpoint@} -xdev -type f" + . " \\( -perm -u+x -o -perm -g+x -o -perm -o+x \\)" + . " \\( -perm -u+s -o -perm -g+s \\) -print"); + push @@fds, $fd; +@end example + +Now, the @command{mail} command is instructed to create next +attachment from that file descriptor: + +@example + my $mpname = $+@{mpoint@}; + $mpname =~ tr@{/@}@{%@}; + push @@cmd, + "--content-name=Set[ug]id files on $+@{mpoint@} (type $+@{fstype@})", + "--content-filename=$mpname.list", + '--attach-fd=' . fileno($fd); + @} +@} +close $in; +@end example + +Finally, the emails of the recipients are added to the command line, +the standard input is closed to make sure @command{mail} won't enter +the interactive mode and the constructed command is executed: + +@example +push @@cmd, @@rcpt; +close STDIN; +system(@@cmd); +@end example + + @c ********************************************************************* @node Reading Mail |