"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "swaks" between
swaks-20201010.0.tar.gz and swaks-20201014.0.tar.gz

About: Swaks is a featureful, flexible, scriptable, transaction-oriented SMTP test tool.

swaks  (swaks-20201010.0):swaks  (swaks-20201014.0)
skipping to change at line 16 skipping to change at line 16
# Online Docs: http://jetmore.org/john/code/swaks/latest/doc/ref.txt # Online Docs: http://jetmore.org/john/code/swaks/latest/doc/ref.txt
# http://jetmore.org/john/code/swaks/faq.html # http://jetmore.org/john/code/swaks/faq.html
# Announce List: send mail to updates-swaks@jetmore.net # Announce List: send mail to updates-swaks@jetmore.net
# Project RSS: http://jetmore.org/john/blog/c/swaks/feed/ # Project RSS: http://jetmore.org/john/blog/c/swaks/feed/
# Twitter: http://www.twitter.com/SwaksSMTP # Twitter: http://www.twitter.com/SwaksSMTP
use strict; use strict;
$| = 1; $| = 1;
my($p_name) = $0 =~ m|/?([^/]+)$|; my($p_name) = $0 =~ m|/?([^/]+)$|;
my $p_version = build_version("20201010.0", '$Id$'); my $p_version = build_version("20201014.0", '$Id$');
my $p_usage = "Usage: $p_name [--help|--version] (see --help for details)"; my $p_usage = "Usage: $p_name [--help|--version] (see --help for details)";
my $p_cp = <<'EOM'; my $p_cp = <<'EOM';
Copyright (c) 2003-2008,2010-2020 John Jetmore <jj33@pobox.com> Copyright (c) 2003-2008,2010-2020 John Jetmore <jj33@pobox.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
skipping to change at line 1411 skipping to change at line 1411
(!$G::interact_method && load("Term::Rea dKey"))) (!$G::interact_method && load("Term::Rea dKey")))
{ {
$G::interact_method ||= "win32-readkey"; $G::interact_method ||= "win32-readkey";
# the trick to replace input w/ '*' doesn 't work on Win32 # the trick to replace input w/ '*' doesn 't work on Win32
# Term::ReadKey, so just use it as an stt y replacement # Term::ReadKey, so just use it as an stt y replacement
ReadMode('noecho'); ReadMode('noecho');
# need to think about this on windows som e more # need to think about this on windows som e more
#local $SIG{INT} = sub { ReadMode('restor e'); }; #local $SIG{INT} = sub { ReadMode('restor e'); };
chomp($response = <STDIN>); chomp($response = <STDIN>);
ReadMode('restore'); ReadMode('restore');
print "\n";
} else { } else {
$G::interact_method ||= "default"; $G::interact_method ||= "default";
chomp($response = <STDIN>); chomp($response = <STDIN>);
} }
} else { } else {
if ($G::interact_method eq "unix-readkey" || (!$G ::interact_method && load("Term::ReadKey"))) { if ($G::interact_method eq "unix-readkey" || (!$G ::interact_method && load("Term::ReadKey"))) {
$G::interact_method ||= "unix-readkey"; $G::interact_method ||= "unix-readkey";
my @resp = (); my @resp = ();
ReadMode('raw'); ReadMode('raw');
#local $SIG{INT} = #local $SIG{INT} =
skipping to change at line 1434 skipping to change at line 1435
if($kp_num == 127 || $kp_num == 8 ) { if($kp_num == 127 || $kp_num == 8 ) {
next if (!scalar(@resp)); next if (!scalar(@resp));
pop(@resp); pop(@resp);
print "\b \b"; print "\b \b";
} elsif($kp_num >= 32) { } elsif($kp_num >= 32) {
push(@resp, $kp); push(@resp, $kp);
print "*"; print "*";
} }
} }
ReadMode('restore'); ReadMode('restore');
print "\n";
$response = join('', @resp); $response = join('', @resp);
} elsif ($G::interact_method eq "unix-stty" || (! $G::interact_method && open(STTY, "stty -a |"))) { } elsif ($G::interact_method eq "unix-stty" || (! $G::interact_method && open(STTY, "stty -a |"))) {
$G::interact_method ||= "unix-stty"; $G::interact_method ||= "unix-stty";
{ my $foo = join('', <STTY>); } { my $foo = join('', <STTY>); }
system('stty', '-echo'); system('stty', '-echo');
chomp($response = <STDIN>); chomp($response = <STDIN>);
system('stty', 'echo'); system('stty', 'echo');
print "\n";
} else { } else {
$G::interact_method ||= "default"; $G::interact_method ||= "default";
chomp($response = <STDIN>); chomp($response = <STDIN>);
} }
} }
} }
} while ($regexp ne 'SKIP' && $response !~ /$regexp/); } while ($regexp ne 'SKIP' && $response !~ /$regexp/);
return($response); return($response);
} }
skipping to change at line 1670 skipping to change at line 1673
} }
sub get_option_struct { sub get_option_struct {
use constant { use constant {
OP_ARG_OPT => 0x01, # option takes an optional argument OP_ARG_OPT => 0x01, # option takes an optional argument
OP_ARG_REQ => 0x02, # option takes a required argument OP_ARG_REQ => 0x02, # option takes a required argument
OP_ARG_NONE => 0x04, # option does not take any argument (will return boolean) OP_ARG_NONE => 0x04, # option does not take any argument (will return boolean)
OP_FROM_PROMPT => 0x08, # option prompts for an argument if none provided OP_FROM_PROMPT => 0x08, # option prompts for an argument if none provided
OP_FROM_FILE => 0x10, # option treats arg of '-' to mean 'read from stdin' (no prompt) OP_FROM_FILE => 0x10, # option treats arg of '-' to mean 'read from stdin' (no prompt)
OP_DEPRECATED => 0x20, # This option is deprecated OP_DEPRECATED => 0x20, # This option is deprecated
OP_SENSITIVE => 0x40, # indicates that if prompted for, the arg ument should be masked (see --protect-prompt)
}; };
@G::raw_option_data = ( @G::raw_option_data = (
# location of config file. Note that the "config" option is proc essed differently # location of config file. Note that the "config" option is proc essed differently
# than any other option because it needs to be processed before s tandard option processing # than any other option because it needs to be processed before s tandard option processing
# can happen. We still define it here to make Getopt::Long and f etch_args() happy. # can happen. We still define it here to make Getopt::Long and f etch_args() happy.
{ opts => ['config'], suffix => ':s', { opts => ['config'], suffix => ':s',
cfgs => OP_ARG_OPT, cfgs => OP_ARG_OPT,
okey => 'config_file', type => 'scalar', }, okey => 'config_file', type => 'scalar', },
# envelope-(f)rom address # envelope-(f)rom address
skipping to change at line 1764 skipping to change at line 1768
# force auth, exit if not supported # force auth, exit if not supported
{ opts => ['auth', 'a'], suffix => ':s', { opts => ['auth', 'a'], suffix => ':s',
cfgs => OP_ARG_OPT, cfgs => OP_ARG_OPT,
okey => 'auth', type => 'scalar', }, okey => 'auth', type => 'scalar', },
# user for auth # user for auth
{ opts => ['auth-user', 'au'], suffix => ':s', { opts => ['auth-user', 'au'], suffix => ':s',
cfgs => OP_ARG_OPT, # we dynamically change this later cfgs => OP_ARG_OPT, # we dynamically change this later
okey => 'auth_user', type => 'scalar', }, okey => 'auth_user', type => 'scalar', },
# pass for auth # pass for auth
{ opts => ['auth-password', 'ap'], suffix => ':s', { opts => ['auth-password', 'ap'], suffix => ':s',
cfgs => OP_ARG_OPT, # we dynamically change this later cfgs => OP_ARG_OPT|OP_SENSITIVE, # we dynamically change thi s later
okey => 'auth_pass', type => 'scalar', }, okey => 'auth_pass', type => 'scalar', },
# auth type map # auth type map
{ opts => ['auth-map', 'am'], suffix => '=s', { opts => ['auth-map', 'am'], suffix => '=s',
cfgs => OP_ARG_REQ, cfgs => OP_ARG_REQ,
okey => 'auth_map', type => 'scalar', }, okey => 'auth_map', type => 'scalar', },
# extra, authenticator-specific options # extra, authenticator-specific options
{ opts => ['auth-extra', 'ae'], suffix => '=s', { opts => ['auth-extra', 'ae'], suffix => '=s',
cfgs => OP_ARG_REQ, cfgs => OP_ARG_REQ,
okey => 'auth_extra', type => 'scalar', }, okey => 'auth_extra', type => 'scalar', },
# hide passwords when possible # hide passwords when possible
skipping to change at line 2535 skipping to change at line 2539
# No arg, but we were requested to prompt the user - do s o # No arg, but we were requested to prompt the user - do s o
elsif ($optConfig->{cfgs} & OP_FROM_PROMPT) { elsif ($optConfig->{cfgs} & OP_FROM_PROMPT) {
if (!exists($optConfig->{prompt})) { if (!exists($optConfig->{prompt})) {
ptrans(12, "Internal option processing er ror: option $argExt->{opt} missing required prompt key (this is a swaks bug)"); ptrans(12, "Internal option processing er ror: option $argExt->{opt} missing required prompt key (this is a swaks bug)");
exit(1); exit(1);
} }
if (!exists($optConfig->{match})) { if (!exists($optConfig->{match})) {
ptrans(12, "Internal option processing er ror: option $argExt->{opt} missing required match key (this is a swaks bug)"); ptrans(12, "Internal option processing er ror: option $argExt->{opt} missing required match key (this is a swaks bug)");
exit(1); exit(1);
} }
$return = interact($optConfig->{prompt}, $optConf ig->{match}); $return = interact($optConfig->{prompt}, $optConf ig->{match}, $optConfig->{cfgs} & OP_SENSITIVE);
} }
# No arg, no request to prompt - this is an error since w e're requiring an arg # No arg, no request to prompt - this is an error since w e're requiring an arg
else { else {
ptrans(12, "Option processing error: option $argE xt->{opt} specified with no argument"); ptrans(12, "Option processing error: option $argE xt->{opt} specified with no argument");
exit(1); exit(1);
} }
# OP_FROM_FILE means that the above options might have re solved into '-' or @filename. If so, return the actual # OP_FROM_FILE means that the above options might have re solved into '-' or @filename. If so, return the actual
# data contained in STDIN/@filename # data contained in STDIN/@filename
if ($optConfig->{cfgs} & OP_FROM_FILE) { if ($optConfig->{cfgs} & OP_FROM_FILE) {
skipping to change at line 3447 skipping to change at line 3451
} else { } else {
$auth_user_t ||= obtain_from_netrc('login'); $auth_user_t ||= obtain_from_netrc('login');
if (!$auth_user_t) { if (!$auth_user_t) {
my $cfg = { cfgs => OP_ARG_REQ|OP_FROM_PR OMPT, prompt => 'Username: ', match => 'SKIP', okey => 'auth_user', akey => 'a uth_user' }; my $cfg = { cfgs => OP_ARG_REQ|OP_FROM_PR OMPT, prompt => 'Username: ', match => 'SKIP', okey => 'auth_user', akey => 'a uth_user' };
$auth_user_t = get_arg('auth_user', $o, $ cfg, 1); $auth_user_t = get_arg('auth_user', $o, $ cfg, 1);
} }
$n{a_user} = $auth_user_t eq '<>' ? '' : $auth_us er_t; $n{a_user} = $auth_user_t eq '<>' ? '' : $auth_us er_t;
$auth_pass_t ||= obtain_from_netrc('password', $n {a_user}); $auth_pass_t ||= obtain_from_netrc('password', $n {a_user});
if (!$auth_pass_t) { if (!$auth_pass_t) {
my $cfg = { cfgs => OP_ARG_REQ|OP_FROM_PR OMPT, prompt => 'Password: ', match => 'SKIP', okey => 'auth_pass', akey => 'a uth_pass' }; my $cfg = { cfgs => OP_ARG_REQ|OP_FROM_PR OMPT|OP_SENSITIVE, prompt => 'Password: ', match => 'SKIP', okey => 'auth_pass ', akey => 'auth_pass' };
$auth_pass_t = get_arg('auth_pass', $o, $ cfg, 1); $auth_pass_t = get_arg('auth_pass', $o, $ cfg, 1);
} }
$n{a_pass} = $auth_pass_t eq '<>' ? '' : $auth_pa ss_t; $n{a_pass} = $auth_pass_t eq '<>' ? '' : $auth_pa ss_t;
$G::auth_showpt = get_arg('auth_showpt', $o); $G::auth_showpt = get_arg('auth_showpt', $o);
$G::auth_hidepw = get_arg('auth_hidepw', $o); $G::auth_hidepw = get_arg('auth_hidepw', $o);
if (defined($G::auth_hidepw) && !$G::auth_hidepw) { if (defined($G::auth_hidepw) && !$G::auth_hidepw) {
$G::auth_hidepw = 'PROVIDED_BUT_REMOVED'; $G::auth_hidepw = 'PROVIDED_BUT_REMOVED';
} }
} }
skipping to change at line 3744 skipping to change at line 3748
} }
if ($force_getpwuid) { if ($force_getpwuid) {
return (getpwuid($<))[0]; return (getpwuid($<))[0];
} }
return $ENV{LOGNAME} || (getpwuid($<))[0]; return $ENV{LOGNAME} || (getpwuid($<))[0];
} }
sub get_date_string { sub get_date_string {
return($G::date_string) if (length($G::date_string) > 0); return($G::date_string) if (length($G::date_string) > 0);
my $et = time(); my $et = time();
my @month_names = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my @day_names = qw(Sun Mon Tue Wed Thu Fri Sat);
if (!avail("date_manip")) { if (!avail("date_manip")) {
ptrans(12, avail_str("date_manip").". Date strings will be in GM T"); ptrans(12, avail_str("date_manip").". Date strings will be in GM T");
my @l = gmtime($et); my @l = gmtime($et);
$G::date_string = sprintf("%s, %02d %s %d %02d:%02d:%02d %+05d", $G::date_string = sprintf("%s, %02d %s %d %02d:%02d:%02d %+05d",
(qw(Sun Mon Tue Wed Thu Fri Sat))[$l[6] ], $day_names[$l[6]],
$l[3], $l[3],
(qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec))[$l[4]], $month_names[$l[4]],
$l[5]+1900, $l[2], $l[1], $l[0], $l[5]+1900, $l[2], $l[1], $l[0],
0); 0);
} else { } else {
$G::date_string = POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", loc # this is convoluted because %a (week day name) and %b (month nam
altime($et)); e) are localized, but per RFC they should be in English. Since
# un-localizing didn't work on every system I tested, jump throug
h hoops here to not use those fields at all.
my @l = localtime($et);
$G::date_string = sprintf("%s, %s %s %s",
$day_names[POSIX::strftime("%w", @l
)],
POSIX::strftime("%d", @l),
$month_names[POSIX::strftime("%m",
@l) - 1],
POSIX::strftime("%Y %H:%M:%S %z", @
l));
} }
return($G::date_string); return($G::date_string);
} }
# partially Cribbed from "Programming Perl" and MIME::Base64 v2.12 # partially Cribbed from "Programming Perl" and MIME::Base64 v2.12
sub db64 { sub db64 {
my $s = shift; my $s = shift;
if (load("MIME::Base64")) { if (load("MIME::Base64")) {
return(decode_base64($s)); return(decode_base64($s));
} else { } else {
skipping to change at line 3982 skipping to change at line 3995
An option labeled with From-Prompt will prompt the user interactively for the ar gument if none is provided. An option labeled with From-Prompt will prompt the user interactively for the ar gument if none is provided.
=item From-File =item From-File
An option labeled with From-File will handle arguments as files in certain situa tions. An option labeled with From-File will handle arguments as files in certain situa tions.
If the initial argument is C<->, the final argument is the contents of C<STDIN>. Multiple options can all specify C<STDIN>, but the same content will be used f or each of them. If the initial argument is C<->, the final argument is the contents of C<STDIN>. Multiple options can all specify C<STDIN>, but the same content will be used f or each of them.
If the initial argument is prefixed with C<@>, the argument will be treated as a path to a file. The file will be opened and the contents will be used as the f inal argument. If the contents of the file can't be read, Swaks will exit. To specify a literal value starting with an C<@>, use two C<@> symbols. The first will be stripped. If the initial argument is prefixed with C<@>, the argument will be treated as a path to a file. The file will be opened and the contents will be used as the f inal argument. If the contents of the file can't be read, Swaks will exit. To specify a literal value starting with an C<@>, use two C<@> symbols. The first will be stripped.
=item Sensitive
If an option marked Sensitive attempts to prompt the user for an argument and th
e C<--protect-prompt> option is set, Swaks will attempt to mask the user input f
rom being echoed on the terminal. Swaks tries to mask the input in several ways
, but if none of them work program flow will continue with unmasked input.
=item Deprecated =item Deprecated
An option labeled Deprecated has been officially deprecated and will be removed in a future release. See the L</DEPRECATIONS> section of this documentation for details about the deprecations. An option labeled Deprecated has been officially deprecated and will be removed in a future release. See the L</DEPRECATIONS> section of this documentation for details about the deprecations.
=back =back
The exact mechanism and format for using each of the types is listed below. The exact mechanism and format for using each of the types is listed below.
=over 4 =over 4
skipping to change at line 4398 skipping to change at line 4415
=item -aos, --auth-optional-strict [<auth-type>[,<auth-type>[,...]]] =item -aos, --auth-optional-strict [<auth-type>[,<auth-type>[,...]]]
This option is a compromise between C<--auth> and C<--auth-optional>. If no com mon auth-types are found, Swaks behaves as if C<--auth-optional> were specified and proceeds with the transaction. If Swaks can't support requested auth-type, the server doesn't advertise any common auth-types, or if no credentials succeed , Swaks behaves as if C<--auth> were used and exits with an error. (Arg-Optional ) This option is a compromise between C<--auth> and C<--auth-optional>. If no com mon auth-types are found, Swaks behaves as if C<--auth-optional> were specified and proceeds with the transaction. If Swaks can't support requested auth-type, the server doesn't advertise any common auth-types, or if no credentials succeed , Swaks behaves as if C<--auth> were used and exits with an error. (Arg-Optional )
=item -au, --auth-user [<username>] =item -au, --auth-user [<username>]
Provide the username to be used for authentication. If no username is provided, indicate that Swaks should attempt to find the username via F<.netrc> (requires the L<Net::Netrc> module). If no username is provided and cannot be found via F<.netrc>, the user will be prompted to provide one. The string C<< <> >> can be supplied to mean an empty username. (Arg-Required, From-Prompt) Provide the username to be used for authentication. If no username is provided, indicate that Swaks should attempt to find the username via F<.netrc> (requires the L<Net::Netrc> module). If no username is provided and cannot be found via F<.netrc>, the user will be prompted to provide one. The string C<< <> >> can be supplied to mean an empty username. (Arg-Required, From-Prompt)
=item -ap, --auth-password [<password>] =item -ap, --auth-password [<password>]
Provide the password to be used for authentication. If no password is provided, indicate that Swaks should attempt to find the password via F<.netrc> (requires the L<Net::Netrc> module). If no password is provided and cannot be found via F <.netrc>, the user will be prompted to provide one. The string C<< <> >> can b e supplied to mean an empty password. (Arg-Required, From-Prompt) Provide the password to be used for authentication. If no password is provided, indicate that Swaks should attempt to find the password via F<.netrc> (requires the L<Net::Netrc> module). If no password is provided and cannot be found via F <.netrc>, the user will be prompted to provide one. The string C<< <> >> can b e supplied to mean an empty password. (Arg-Required, From-Prompt, Sensitive)
=item -ae, --auth-extra <key-value-pair>[,<key-value-pair>[,...]] =item -ae, --auth-extra <key-value-pair>[,<key-value-pair>[,...]]
Some of the authentication types allow extra information to be included in the a uthentication process. Rather than add a new option for every nook and cranny o f each authenticator, the C<--auth-extra> option allows this information to be s upplied. The format for <key-value-pair> is KEYWORD=VALUE. (Arg-Required) Some of the authentication types allow extra information to be included in the a uthentication process. Rather than add a new option for every nook and cranny o f each authenticator, the C<--auth-extra> option allows this information to be s upplied. The format for <key-value-pair> is KEYWORD=VALUE. (Arg-Required)
The following table lists the currently recognized keywords and the authenticato rs that use them The following table lists the currently recognized keywords and the authenticato rs that use them
=over 4 =over 4
=item realm, domain =item realm, domain
skipping to change at line 4772 skipping to change at line 4789
=item --output, --output-file <file-path> =item --output, --output-file <file-path>
=item --output-file-stdout <file-path> =item --output-file-stdout <file-path>
=item --output-file-stderr <file-path> =item --output-file-stderr <file-path>
These options allow the user to send output to files instead of C<STDOUT>/C<STDE RR>. The first option sends both to the same file. The arguments of C<&STDOUT> and C<&STDERR> are treated specially, referring to the "normal" file handles, s o C<--output-file-stderr '&STDOUT'> would redirect C<STDERR> to C<STDOUT>. Thes e options are honored for all output except C<--help> and C<--version>. (Arg-Req uired) These options allow the user to send output to files instead of C<STDOUT>/C<STDE RR>. The first option sends both to the same file. The arguments of C<&STDOUT> and C<&STDERR> are treated specially, referring to the "normal" file handles, s o C<--output-file-stderr '&STDOUT'> would redirect C<STDERR> to C<STDOUT>. Thes e options are honored for all output except C<--help> and C<--version>. (Arg-Req uired)
=item -pp, --protect-prompt =item -pp, --protect-prompt
Don't echo user input on prompts that are potentially sensitive (right now only authentication password). See also C<--auth-hide-password>. (Arg-None) Don't echo user input on prompts that are potentially sensitive (right now only authentication password). Very specifically, any option which is marked 'Sensit ive' and eventually prompts for an argument will do its best to mask that argume nt from being echoed. See also C<--auth-hide-password>. (Arg-None)
=item -hr, --hide-receive =item -hr, --hide-receive
Don't display lines sent from the remote server being received by Swaks. (Arg-No ne) Don't display lines sent from the remote server being received by Swaks. (Arg-No ne)
=item -hs, --hide-send =item -hs, --hide-send
Don't display lines being sent by Swaks to the remote server. (Arg-None) Don't display lines being sent by Swaks to the remote server. (Arg-None)
=item -hi, --hide-informational =item -hi, --hide-informational
 End of changes. 15 change blocks. 
11 lines changed or deleted 35 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)