📄 sendmail-lib.pl
字号:
# sendmail-lib.pl# Functions for managing sendmail aliases, domains and mappings.# Only sendmail versions 8.8 and above are supporteddo '../web-lib.pl';&init_config();%access = &get_module_acl();# get_sendmailcf()# Parses sendmail.cf and return a reference to an array of options.# Each line is a single character directive, followed by a list of values?sub get_sendmailcf{if (!@sendmailcf_cache) { local($lnum, $i); $lnum = 0; $i = 0; open(CF, $config{'sendmail_cf'}); while(<CF>) { s/^#.*$//g; # remove comments s/\r|\n//g; # remove newlines if (/^(\S)(\s*(.*))$/) { local(%opt); $opt{'type'} = $1; $opt{'value'} = $3; $opt{'values'} = [ split(/\s+/, $2) ]; $opt{'line'} = $lnum; $opt{'eline'} = $opt{'line'}; $opt{'pos'} = $i++; push(@sendmailcf_cache, \%opt); } $lnum++; } close(CF); }return \@sendmailcf_cache;}# check_sendmail_version(&config)# Is the sendmail config file a usable version?sub check_sendmail_version{local $ver = &find_type("V", $_[0]);return $ver && $ver->{'value'} =~ /^(\d+)/ && $1 >= 7;}# save_directives(&config, &oldvalues, &newvalues)# Given 2 arrays of directive structures, this function will replace the# old ones with the new. If the old list is empty, new directives are added# to the end of the config file. If the new list is empty, all old directives# are removed. If both exist, new ones replace old..sub save_directives{local(@old) = @{$_[1]};local(@new) = @{$_[2]};$lref = &read_file_lines($config{'sendmail_cf'});for($i=0; $i<@old || $i<@new; $i++) { if ($i >= @old) { # A new directive has been added.. put it at the end of the file $new[$i]->{'line'} = scalar(@$lref); $new[$i]->{'eline'} = $new[$i]->{'line'}+1; push(@$lref, &directive_line($new[$i])); push(@{$_[0]}, $new[$i]); } elsif ($i >= @new) { # A directive was deleted $ol = $old[$i]->{'eline'} - $old[$i]->{'line'} + 1; splice(@$lref, $old[$i]->{'line'}, $ol); &renumber($_[0], $old[$i]->{'eline'}, -$ol); splice(@{$_[0]}, &indexof($old[$i], @{$_[0]}), 1); } else { # A directive was changed $ol = $old[$i]->{'eline'} - $old[$i]->{'line'} + 1; splice(@$lref, $old[$i]->{'line'}, $ol, &directive_line($new[$i])); $new[$i]->{'line'} = $new[$i]->{'eline'} = $old[$i]->{'line'}; &renumber($_[0], $old[$i]->{'eline'}, 1-$ol); $_[0]->[&indexof($old[$i], @{$_[0]})] = $new[$i]; } }}# directive_line(&details)sub directive_line{return $_[0]->{'type'}.join(' ', @{$_[0]->{'values'}});}# renumber(config, line, offset)sub renumber{foreach $d (@{$_[0]}) { if ($d->{'line'} > $_[1]) { $d->{'line'} += $_[2]; } if ($d->{'eline'} > $_[1]) { $d->{'eline'} += $_[2]; } }}# find_type(name, &config)# Returns an array of config directives of some typesub find_type{local($c, @rv);foreach $c (@{$_[1]}) { if ($c->{'type'} eq $_[0]) { push(@rv, $c); } }return @rv ? wantarray ? @rv : $rv[0] : wantarray ? () : undef;}# find_option(name, &config)# Returns the structure and value of some option directivesub find_option{local(@opts, $o);@opts = &find_type("O", $_[1]);foreach $o (@opts) { if ($o->{'value'} =~ /^\s*([^=]+)=(.*)$/ && $1 eq $_[0]) { # found it.. return return wantarray ? ($o, $2) : $2; } }return undef;}# find_type2(type1, type2, &config)# Returns the structure and value of some directivesub find_type2{local @types = &find_type($_[0], $_[2]);local $t;foreach $t (@types) { if ($t->{'value'} =~ /^(\S)(.*)$/ && $1 eq $_[1]) { return ($t, $2); } }return undef;}# restart_sendmail()# Send a SIGHUP to sendmailsub restart_sendmail{local($pid);if (open(PID, $config{'sendmail_pid'})) { chop($pid = <PID>); close(PID); if ($pid) { kill('HUP', $pid); } }else { kill('HUP', &find_byname("sendmail")); }}# run_makemap(textfile, dbmfile, type)sub run_makemap{local($out);$out = `$config{'makemap_path'} $_[2] $_[1] <$_[0] 2>&1`;if ($?) { &error("makemap failed : <pre>$out</pre>"); }}# find_textfile(config, dbm)sub find_textfile{local($conf, $dbm) = @_;if ($conf) { return $conf; }elsif (!$dbm) { return undef; }elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash)$/i && -r $1) { # Database is like /etc/virtusertable.db, text is /etc/virtusertable return $1; }elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash)$/i && -r "$1.txt") { # Database is like /etc/virtusertable.db, text is /etc/virtusertable.txt return "$1.txt"; }elsif (-r "$dbm.txt") { # Database is like /etc/virtusertable, text is /etc/virtusertable.txt return "$dbm.txt"; }else { # Text and database have same name return $dbm; }}# mailq_dir($conf)sub mailq_dir{local ($opt, $mqueue) = &find_option("QueueDirectory", $_[0]);return $mqueue ? $mqueue : "/var/spool/mqueue";}sub sort_by_domain{local ($a1, $a2, $b1, $b2);if ($a->{'from'} =~ /^(.*)\@(.*)$/ && (($a1, $a2) = ($1, $2)) && $b->{'from'} =~ /^(.*)\@(.*)$/ && (($b1, $b2) = ($1, $2))) { return $a2 cmp $b2 ? $a2 cmp $b2 : $a1 cmp $b1; }else { return $a->{'from'} cmp $b->{'from'}; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -