docs: improve the attachment section.
* doc/texinfo/programs.texi: provide an example script illustrating how to use mail from another programs.
Showing
1 changed file
with
100 additions
and
11 deletions
... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment