Commit 51c5ad1b 51c5ad1b37723b9c61d19a5a4dcff6fb28c7b836 by Sergey Poznyakoff

docs: improve the attachment section.

* doc/texinfo/programs.texi: provide an example script illustrating
how to use mail from another programs.
1 parent 2229fcdc
...@@ -3510,9 +3510,9 @@ $ mail -E 'set nonullbodymsg' --attach=archive.tar < /dev/null ...@@ -3510,9 +3510,9 @@ $ mail -E 'set nonullbodymsg' --attach=archive.tar < /dev/null
3510 @end example 3510 @end example
3511 3511
3512 The option @option{--attach=-} forces @command{mail} to read the file 3512 The option @option{--attach=-} forces @command{mail} to read the file
3513 to be attached from the standard input stream. This option implies 3513 to be attached from the standard input stream. This option disables
3514 disables the interactive mode and sets @samp{nonullbodymsg} 3514 the interactive mode and sets @samp{nonullbodymsg} implicitly, so that
3515 implicitly, so that the above example can be rewritten as: 3515 the above example can be rewritten as:
3516 3516
3517 @example 3517 @example
3518 $ mail --attach=- < archive.tar 3518 $ mail --attach=- < archive.tar
...@@ -3527,20 +3527,109 @@ above example is equivalent to: ...@@ -3527,20 +3527,109 @@ above example is equivalent to:
3527 $ mail --attach-fd=0 < archive.tar 3527 $ mail --attach-fd=0 < archive.tar
3528 @end example 3528 @end example
3529 3529
3530 Attachments created using this option have neither filename not 3530 Attachments created with this option have neither filename nor
3531 description set, so normally the use of @option{--content-name} and/or 3531 description set, so normally the use of @option{--content-name} and/or
3532 @option{--content-filename} is advised. 3532 @option{--content-filename} is advised.
3533 3533
3534 The following Perl program serves as an example of using
3535 @command{mail} from a script to construct a MIME message on the fly.
3536 It scans all mounted file systems for executable files that have
3537 setuid or setgid bits set and reports the names of those files in
3538 separate attachments. Each attachment is named after the mountpoint
3539 it describes.
3540
3541 The script begins with the usual prologue stating the modules that
3542 will be used:
3543
3544 @example
3545 #!/usr/bin/perl
3546
3547 use strict;
3548 use autodie;
3549 @end example
3550
3551 Then global variables are declared. The @samp{@@rcpt} array contains
3552 the email addresses of the recipients:
3553
3554 @example
3555 my @@rcpt= 'root@@example.com';
3556 @end example
3557
3558 The @samp{@@cmd} variable holds the @command{mail} command line. It
3559 will be augmented for each file system. The initial value is set as
3560 follows:
3561
3534 @example 3562 @example
3535 $ mail --subject 'mail(1)' \ 3563 my @@cmd = ('mail',
3536 --content-name="The mail(1) binary" --content-filename="mail" \ 3564 '-E set nonullbodymsg',
3537 --attach-fd 5 \ 3565 '--content-type=text/plain');
3538 --encoding=binary --content-type=text/plain \
3539 --content-name="mail.c source file" --content-filename=mail.c \
3540 --attach-fd 6 gray@@example.org 5</usr/bin/mail \
3541 6<mailutils/mail/mail.c
3542 @end example 3566 @end example
3543 3567
3568 The @command{find} utility will be used to locate the files. The
3569 script will start as many instances as there are mountpoints. Those
3570 instances will be run in parallel and their standard output streams
3571 will be connected to file descriptors passed to @command{mail}
3572 invocation in @option{--attach-fd} options.
3573
3574 The descriptors will be held in @samp{@@fds} array. This will prevent
3575 them from being wiped out by the garbage collector. Furthermore, care
3576 should be taken to ensure that the @code{O_CLOECEC} flag be not set
3577 for these descriptors. This sample script takes a simplistic approach:
3578 it instructs Perl to not close first 255 descriptors when executing
3579 another programs:
3580
3581 @example
3582 my @@fds;
3583 $^F = 255;
3584 @end example
3585
3586 The following code obtains the list of mount points:
3587
3588 @example
3589 open(my $in, '-|', 'mount -t nonfs,noproc,nosysfs,notmpfs');
3590 while (<$in>) @{
3591 chomp;
3592 if (/^\S+ on (?<mpoint>.+) type (?<fstype>.+) /) @{
3593 @end example
3594
3595 For each mountpoint, the @command{find} command line is constructed
3596 and launched. The file descriptor is pushed to the @samp{@@fds} array
3597 to prevent it from being collected by the garbage collector:
3598
3599 @example
3600 open(my $fd, '-|',
3601 "find $+@{mpoint@} -xdev -type f"
3602 . " \\( -perm -u+x -o -perm -g+x -o -perm -o+x \\)"
3603 . " \\( -perm -u+s -o -perm -g+s \\) -print");
3604 push @@fds, $fd;
3605 @end example
3606
3607 Now, the @command{mail} command is instructed to create next
3608 attachment from that file descriptor:
3609
3610 @example
3611 my $mpname = $+@{mpoint@};
3612 $mpname =~ tr@{/@}@{%@};
3613 push @@cmd,
3614 "--content-name=Set[ug]id files on $+@{mpoint@} (type $+@{fstype@})",
3615 "--content-filename=$mpname.list",
3616 '--attach-fd=' . fileno($fd);
3617 @}
3618 @}
3619 close $in;
3620 @end example
3621
3622 Finally, the emails of the recipients are added to the command line,
3623 the standard input is closed to make sure @command{mail} won't enter
3624 the interactive mode and the constructed command is executed:
3625
3626 @example
3627 push @@cmd, @@rcpt;
3628 close STDIN;
3629 system(@@cmd);
3630 @end example
3631
3632
3544 @c ********************************************************************* 3633 @c *********************************************************************
3545 3634
3546 @node Reading Mail 3635 @node Reading Mail
......