version 1.337, 2006/08/25 17:22:59
|
version 1.355, 2007/01/10 20:22:30
|
Line 40 use IO::File;
|
Line 40 use IO::File;
|
use POSIX; |
use POSIX; |
use Crypt::IDEA; |
use Crypt::IDEA; |
use LWP::UserAgent(); |
use LWP::UserAgent(); |
|
use Digest::MD5 qw(md5_hex); |
use GDBM_File; |
use GDBM_File; |
use Authen::Krb4; |
use Authen::Krb4; |
use Authen::Krb5; |
use Authen::Krb5; |
Line 503 sub AdjustHostContents {
|
Line 504 sub AdjustHostContents {
|
my $adjusted; |
my $adjusted; |
my $me = $perlvar{'lonHostID'}; |
my $me = $perlvar{'lonHostID'}; |
|
|
foreach my $line (split(/\n/,$contents)) { |
foreach my $line (split(/\n/,$contents)) { |
if(!(($line eq "") || ($line =~ /^ *\#/) || ($line =~ /^ *$/))) { |
if(!(($line eq "") || ($line =~ /^ *\#/) || ($line =~ /^ *$/))) { |
chomp($line); |
chomp($line); |
my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon)=split(/:/,$line); |
my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon)=split(/:/,$line); |
if ($id eq $me) { |
if ($id eq $me) { |
my $ip = gethostbyname($name); |
my $ip = gethostbyname($name); |
my $ipnew = inet_ntoa($ip); |
my $ipnew = inet_ntoa($ip); |
$ip = $ipnew; |
$ip = $ipnew; |
# Reconstruct the host line and append to adjusted: |
# Reconstruct the host line and append to adjusted: |
|
|
my $newline = "$id:$domain:$role:$name:$ip"; |
my $newline = "$id:$domain:$role:$name:$ip"; |
if($maxcon ne "") { # Not all hosts have loncnew tuning params |
if($maxcon ne "") { # Not all hosts have loncnew tuning params |
$newline .= ":$maxcon:$idleto:$mincon"; |
$newline .= ":$maxcon:$idleto:$mincon"; |
} |
} |
$adjusted .= $newline."\n"; |
$adjusted .= $newline."\n"; |
|
|
} else { # Not me, pass unmodified. |
} else { # Not me, pass unmodified. |
$adjusted .= $line."\n"; |
$adjusted .= $line."\n"; |
} |
} |
} else { # Blank or comment never re-written. |
} else { # Blank or comment never re-written. |
$adjusted .= $line."\n"; # Pass blanks and comments as is. |
$adjusted .= $line."\n"; # Pass blanks and comments as is. |
} |
} |
} |
} |
return $adjusted; |
return $adjusted; |
} |
} |
# |
# |
# InstallFile: Called to install an administrative file: |
# InstallFile: Called to install an administrative file: |
Line 835 sub AdjustOurHost {
|
Line 836 sub AdjustOurHost {
|
# Use the config line to get my hostname. |
# Use the config line to get my hostname. |
# Use gethostbyname to translate that into an IP address. |
# Use gethostbyname to translate that into an IP address. |
# |
# |
my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon) = split(/:/,$ConfigLine); |
my ($id,$domain,$role,$name,$maxcon,$idleto,$mincon) = split(/:/,$ConfigLine); |
my $BinaryIp = gethostbyname($name); |
|
my $ip = inet_ntoa($ip); |
|
# |
# |
# Reassemble the config line from the elements in the list. |
# Reassemble the config line from the elements in the list. |
# Note that if the loncnew items were not present before, they will |
# Note that if the loncnew items were not present before, they will |
# be now even if they would be empty |
# be now even if they would be empty |
# |
# |
my $newConfigLine = $id; |
my $newConfigLine = $id; |
foreach my $item ($domain, $role, $name, $ip, $maxcon, $idleto, $mincon) { |
foreach my $item ($domain, $role, $name, $maxcon, $idleto, $mincon) { |
$newConfigLine .= ":".$item; |
$newConfigLine .= ":".$item; |
} |
} |
# Replace the line: |
# Replace the line: |
Line 890 sub EditFile {
|
Line 889 sub EditFile {
|
|
|
# Split the command into it's pieces: edit:filetype:script |
# Split the command into it's pieces: edit:filetype:script |
|
|
my ($request, $filetype, $script) = split(/:/, $request,3); # : in script |
my ($cmd, $filetype, $script) = split(/:/, $request,3); # : in script |
|
|
# Check the pre-coditions for success: |
# Check the pre-coditions for success: |
|
|
if($request != "edit") { # Something is amiss afoot alack. |
if($cmd != "edit") { # Something is amiss afoot alack. |
return "error:edit request detected, but request != 'edit'\n"; |
return "error:edit request detected, but request != 'edit'\n"; |
} |
} |
if( ($filetype ne "hosts") && |
if( ($filetype ne "hosts") && |
Line 1252 sub push_file_handler {
|
Line 1251 sub push_file_handler {
|
# |
# |
sub du_handler { |
sub du_handler { |
my ($cmd, $ududir, $client) = @_; |
my ($cmd, $ududir, $client) = @_; |
my ($ududir) = split(/:/,$ududir); # Make 'telnet' testing easier. |
($ududir) = split(/:/,$ududir); # Make 'telnet' testing easier. |
my $userinput = "$cmd:$ududir"; |
my $userinput = "$cmd:$ududir"; |
|
|
if ($ududir=~/\.\./ || $ududir!~m|^/home/httpd/|) { |
if ($ududir=~/\.\./ || $ududir!~m|^/home/httpd/|) { |
Line 1576 sub change_password_handler {
|
Line 1575 sub change_password_handler {
|
# uname - Username. |
# uname - Username. |
# upass - Current password. |
# upass - Current password. |
# npass - New password. |
# npass - New password. |
|
# context - Context in which this was called |
|
# (preferences or reset_by_email). |
|
|
my ($udom,$uname,$upass,$npass)=split(/:/,$tail); |
my ($udom,$uname,$upass,$npass,$context)=split(/:/,$tail); |
|
|
$upass=&unescape($upass); |
$upass=&unescape($upass); |
$npass=&unescape($npass); |
$npass=&unescape($npass); |
&Debug("Trying to change password for $uname"); |
&Debug("Trying to change password for $uname"); |
|
|
# First require that the user can be authenticated with their |
# First require that the user can be authenticated with their |
# old password: |
# old password unless context was 'reset_by_email': |
|
|
my $validated = &validate_user($udom, $uname, $upass); |
my $validated; |
|
if ($context eq 'reset_by_email') { |
|
$validated = 1; |
|
} else { |
|
$validated = &validate_user($udom, $uname, $upass); |
|
} |
if($validated) { |
if($validated) { |
my $realpasswd = &get_auth_type($udom, $uname); # Defined since authd. |
my $realpasswd = &get_auth_type($udom, $uname); # Defined since authd. |
|
|
Line 1605 sub change_password_handler {
|
Line 1611 sub change_password_handler {
|
."to change password"); |
."to change password"); |
&Failure( $client, "non_authorized\n",$userinput); |
&Failure( $client, "non_authorized\n",$userinput); |
} |
} |
} elsif ($howpwd eq 'unix') { |
} elsif ($howpwd eq 'unix' && $context ne 'reset_by_email') { |
my $result = &change_unix_password($uname, $npass); |
my $result = &change_unix_password($uname, $npass); |
&logthis("Result of password change for $uname: ". |
&logthis("Result of password change for $uname: ". |
$result); |
$result); |
Line 2125 sub token_auth_user_file_handler {
|
Line 2131 sub token_auth_user_file_handler {
|
|
|
chomp($session); |
chomp($session); |
my $reply="non_auth\n"; |
my $reply="non_auth\n"; |
if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'. |
my $file = $perlvar{'lonIDsDir'}.'/'.$session.'.id'; |
$session.'.id')) { |
if (open(ENVIN,"$file")) { |
flock(ENVIN,LOCK_SH); |
flock(ENVIN,LOCK_SH); |
while (my $line=<ENVIN>) { |
tie(my %disk_env,'GDBM_File',"$file",&GDBM_READER(),0640); |
my ($envname)=split(/=/,$line,2); |
if (exists($disk_env{"userfile.$fname"})) { |
$envname=&unescape($envname); |
$reply="ok\n"; |
if ($envname=~ m|^userfile\.\Q$fname\E|) { $reply="ok\n"; } |
} else { |
|
foreach my $envname (keys(%disk_env)) { |
|
if ($envname=~ m|^userfile\.\Q$fname\E|) { |
|
$reply="ok\n"; |
|
last; |
|
} |
|
} |
} |
} |
|
untie(%disk_env); |
close(ENVIN); |
close(ENVIN); |
&Reply($client, $reply, "$cmd:$tail"); |
&Reply($client, $reply, "$cmd:$tail"); |
} else { |
} else { |
Line 2595 sub get_profile_entry_encrypted {
|
Line 2608 sub get_profile_entry_encrypted {
|
|
|
my $userinput = "$cmd:$tail"; |
my $userinput = "$cmd:$tail"; |
|
|
my ($cmd,$udom,$uname,$namespace,$what) = split(/:/,$userinput); |
my ($udom,$uname,$namespace,$what) = split(/:/,$tail); |
chomp($what); |
chomp($what); |
my $qresult = read_profile($udom, $uname, $namespace, $what); |
my $qresult = read_profile($udom, $uname, $namespace, $what); |
my ($first) = split(/:/, $qresult); |
my ($first) = split(/:/, $qresult); |
Line 3040 sub restore_handler {
|
Line 3053 sub restore_handler {
|
my ($cmd, $tail, $client) = @_; |
my ($cmd, $tail, $client) = @_; |
|
|
my $userinput = "$cmd:$tail"; # Only used for logging purposes. |
my $userinput = "$cmd:$tail"; # Only used for logging purposes. |
|
my ($udom,$uname,$namespace,$rid) = split(/:/,$tail); |
my ($cmd,$udom,$uname,$namespace,$rid) = split(/:/,$userinput); |
|
$namespace=~s/\//\_/g; |
$namespace=~s/\//\_/g; |
$namespace=~s/\W//g; |
$namespace = &LONCAPA::clean_username($namespace); |
|
|
chomp($rid); |
chomp($rid); |
my $qresult=''; |
my $qresult=''; |
my $hashref = &tie_user_hash($udom, $uname, $namespace, &GDBM_READER()); |
my $hashref = &tie_user_hash($udom, $uname, $namespace, &GDBM_READER()); |
Line 3216 sub reply_query_handler {
|
Line 3229 sub reply_query_handler {
|
|
|
my $userinput = "$cmd:$tail"; |
my $userinput = "$cmd:$tail"; |
|
|
my ($cmd,$id,$reply)=split(/:/,$userinput); |
my ($id,$reply)=split(/:/,$tail); |
my $store; |
my $store; |
my $execdir=$perlvar{'lonDaemons'}; |
my $execdir=$perlvar{'lonDaemons'}; |
if ($store=IO::File->new(">$execdir/tmp/$id")) { |
if ($store=IO::File->new(">$execdir/tmp/$id")) { |
Line 3352 sub dump_course_id_handler {
|
Line 3365 sub dump_course_id_handler {
|
my $userinput = "$cmd:$tail"; |
my $userinput = "$cmd:$tail"; |
|
|
my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter, |
my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter, |
$typefilter) =split(/:/,$tail); |
$typefilter,$regexp_ok) =split(/:/,$tail); |
if (defined($description)) { |
if (defined($description)) { |
$description=&unescape($description); |
$description=&unescape($description); |
} else { |
} else { |
Line 3389 sub dump_course_id_handler {
|
Line 3402 sub dump_course_id_handler {
|
} else { |
} else { |
$typefilter='.'; |
$typefilter='.'; |
} |
} |
|
if (defined($regexp_ok)) { |
|
$regexp_ok=&unescape($regexp_ok); |
|
} |
|
|
unless (defined($since)) { $since=0; } |
unless (defined($since)) { $since=0; } |
my $qresult=''; |
my $qresult=''; |
Line 3409 sub dump_course_id_handler {
|
Line 3425 sub dump_course_id_handler {
|
} |
} |
unless ($instcodefilter eq '.' || !defined($instcodefilter)) { |
unless ($instcodefilter eq '.' || !defined($instcodefilter)) { |
my $unescapeInstcode = &unescape($inst_code); |
my $unescapeInstcode = &unescape($inst_code); |
unless (eval('$unescapeInstcode=~/\Q$instcodefilter\E/i')) { |
if ($regexp_ok) { |
$match = 0; |
unless (eval('$unescapeInstcode=~/$instcodefilter/')) { |
|
$match = 0; |
|
} |
|
} else { |
|
unless (eval('$unescapeInstcode=~/\Q$instcodefilter\E/i')) { |
|
$match = 0; |
|
} |
} |
} |
} |
} |
unless ($ownerfilter eq '.' || !defined($ownerfilter)) { |
unless ($ownerfilter eq '.' || !defined($ownerfilter)) { |
Line 3456 sub dump_course_id_handler {
|
Line 3478 sub dump_course_id_handler {
|
} |
} |
unless ($typefilter eq '.' || !defined($typefilter)) { |
unless ($typefilter eq '.' || !defined($typefilter)) { |
my $unescapeType = &unescape($type); |
my $unescapeType = &unescape($type); |
if (!defined($type)) { |
if ($type eq '') { |
if ($typefilter ne 'Course') { |
if ($typefilter ne 'Course') { |
$match = 0; |
$match = 0; |
} |
} |
Line 3488 sub dump_course_id_handler {
|
Line 3510 sub dump_course_id_handler {
|
®ister_handler("courseiddump", \&dump_course_id_handler, 0, 1, 0); |
®ister_handler("courseiddump", \&dump_course_id_handler, 0, 1, 0); |
|
|
# |
# |
|
# Puts an unencrypted entry in a namespace db file at the domain level |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# Side effects: |
|
# reply is written to $client. |
|
# |
|
sub put_domain_handler { |
|
my ($cmd,$tail,$client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ($udom,$namespace,$what) =split(/:/,$tail,3); |
|
chomp($what); |
|
my @pairs=split(/\&/,$what); |
|
my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_WRCREAT(), |
|
"P", $what); |
|
if ($hashref) { |
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
$hashref->{$key}=$value; |
|
} |
|
if (&untie_domain_hash($hashref)) { |
|
&Reply($client, "ok\n", $userinput); |
|
} else { |
|
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". |
|
"while attempting putdom\n", $userinput); |
|
} |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting putdom\n", $userinput); |
|
} |
|
|
|
return 1; |
|
} |
|
®ister_handler("putdom", \&put_domain_handler, 0, 1, 0); |
|
|
|
# Unencrypted get from the namespace database file at the domain level. |
|
# This function retrieves a keyed item from a specific named database in the |
|
# domain directory. |
|
# |
|
# Parameters: |
|
# $cmd - Command request keyword (get). |
|
# $tail - Tail of the command. This is a colon separated list |
|
# consisting of the domain and the 'namespace' |
|
# which selects the gdbm file to do the lookup in, |
|
# & separated list of keys to lookup. Note that |
|
# the values are returned as an & separated list too. |
|
# $client - File descriptor open on the client. |
|
# Returns: |
|
# 1 - Continue processing. |
|
# 0 - Exit. |
|
# Side effects: |
|
# reply is written to $client. |
|
# |
|
|
|
sub get_domain_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$client:$tail"; |
|
|
|
my ($udom,$namespace,$what)=split(/:/,$tail,3); |
|
chomp($what); |
|
my @queries=split(/\&/,$what); |
|
my $qresult=''; |
|
my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_READER()); |
|
if ($hashref) { |
|
for (my $i=0;$i<=$#queries;$i++) { |
|
$qresult.="$hashref->{$queries[$i]}&"; |
|
} |
|
if (&untie_domain_hash($hashref)) { |
|
$qresult=~s/\&$//; |
|
&Reply($client, "$qresult\n", $userinput); |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". |
|
"while attempting getdom\n",$userinput); |
|
} |
|
} else { |
|
&Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting getdom\n",$userinput); |
|
} |
|
|
|
return 1; |
|
} |
|
®ister_handler("getdom", \&get_id_handler, 0, 1, 0); |
|
|
|
|
|
# |
# Puts an id to a domains id database. |
# Puts an id to a domains id database. |
# |
# |
# Parameters: |
# Parameters: |
Line 3858 sub tmp_put_handler {
|
Line 3973 sub tmp_put_handler {
|
|
|
my $userinput = "$cmd:$what"; # Reconstruct for logging. |
my $userinput = "$cmd:$what"; # Reconstruct for logging. |
|
|
|
my ($record,$context) = split(/:/,$what); |
my $store; |
if ($context ne '') { |
|
chomp($context); |
|
$context = &unescape($context); |
|
} |
|
my ($id,$store); |
$tmpsnum++; |
$tmpsnum++; |
my $id=$$.'_'.$clientip.'_'.$tmpsnum; |
if ($context eq 'resetpw') { |
|
$id = &md5_hex(&md5_hex(time.{}.rand().$$)); |
|
} else { |
|
$id = $$.'_'.$clientip.'_'.$tmpsnum; |
|
} |
$id=~s/\W/\_/g; |
$id=~s/\W/\_/g; |
$what=~s/\n//g; |
$record=~s/\n//g; |
my $execdir=$perlvar{'lonDaemons'}; |
my $execdir=$perlvar{'lonDaemons'}; |
if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) { |
if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) { |
print $store $what; |
print $store $record; |
close $store; |
close $store; |
&Reply($client, "$id\n", $userinput); |
&Reply($client, "$id\n", $userinput); |
} else { |
} else { |
Line 4181 sub validate_course_section_handler {
|
Line 4304 sub validate_course_section_handler {
|
®ister_handler("autovalidatecourse", \&validate_course_section_handler, 0, 1, 0); |
®ister_handler("autovalidatecourse", \&validate_course_section_handler, 0, 1, 0); |
|
|
# |
# |
# Create a password for a new auto-enrollment user. |
# Validate course owner's access to enrollment data for specific class section. |
# I think/guess, this password allows access to the institutions |
# |
# AIS class list server/services. Stuart can correct this comment |
# |
# when he finds out how wrong I am. |
# Formal Parameters: |
|
# $cmd - The command request that got us dispatched. |
|
# $tail - The tail of the command. In this case this is a colon separated |
|
# set of words that will be split into: |
|
# $inst_class - Institutional code for the specific class section |
|
# $courseowner - The escaped username:domain of the course owner |
|
# $cdom - The domain of the course from the institution's |
|
# point of view. |
|
# $client - The socket open on the client. |
|
# Returns: |
|
# 1 - continue processing. |
|
# |
|
|
|
sub validate_class_access_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
my $userinput = "$cmd:$tail"; |
|
my ($inst_class,$courseowner,$cdom) = split(/:/, $tail); |
|
$courseowner = &unescape($courseowner); |
|
my $outcome; |
|
eval { |
|
local($SIG{__DIE__})='DEFAULT'; |
|
$outcome=&localenroll::check_section($inst_class,$courseowner,$cdom); |
|
}; |
|
&Reply($client,"$outcome\n", $userinput); |
|
|
|
return 1; |
|
} |
|
®ister_handler("autovalidateclass_sec", \&validate_class_access_handler, 0, 1, 0); |
|
|
|
# |
|
# Create a password for a new LON-CAPA user added by auto-enrollment. |
|
# Only used for case where authentication method for new user is localauth |
# |
# |
# Formal Parameters: |
# Formal Parameters: |
# $cmd - The command request that got us dispatched. |
# $cmd - The command request that got us dispatched. |
# $tail - The tail of the command. In this case this is a colon separated |
# $tail - The tail of the command. In this case this is a colon separated |
# set of words that will be split into: |
# set of words that will be split into: |
# $authparam - An authentication parameter (username??). |
# $authparam - An authentication parameter (localauth parameter). |
# $cdom - The domain of the course from the institution's |
# $cdom - The domain of the course from the institution's |
# point of view. |
# point of view. |
# $client - The socket open on the client. |
# $client - The socket open on the client. |
Line 4317 sub get_institutional_code_format_handle
|
Line 4471 sub get_institutional_code_format_handle
|
®ister_handler("autoinstcodeformat", |
®ister_handler("autoinstcodeformat", |
\&get_institutional_code_format_handler,0,1,0); |
\&get_institutional_code_format_handler,0,1,0); |
|
|
|
sub get_institutional_defaults_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
my $userinput = "$cmd:$tail"; |
|
|
|
my $dom = $tail; |
|
my %defaults_hash; |
|
my @code_order; |
|
my $outcome; |
|
eval { |
|
local($SIG{__DIE__})='DEFAULT'; |
|
$outcome = &localenroll::instcode_defaults($dom,\%defaults_hash, |
|
\@code_order); |
|
}; |
|
if (!$@) { |
|
if ($outcome eq 'ok') { |
|
my $result=''; |
|
while (my ($key,$value) = each(%defaults_hash)) { |
|
$result.=&escape($key).'='.&escape($value).'&'; |
|
} |
|
$result .= 'code_order='.&escape(join('&',@code_order)); |
|
&Reply($client,$result."\n",$userinput); |
|
} else { |
|
&Reply($client,"error\n", $userinput); |
|
} |
|
} else { |
|
&Failure($client,"unknown_cmd\n",$userinput); |
|
} |
|
} |
|
®ister_handler("autoinstcodedefaults", |
|
\&get_institutional_defaults_handler,0,1,0); |
|
|
|
|
# Get domain specific conditions for import of student photographs to a course |
# Get domain specific conditions for import of student photographs to a course |
# |
# |
# Retrieves information from photo_permission subroutine in localenroll. |
# Retrieves information from photo_permission subroutine in localenroll. |
Line 5280 sub make_new_child {
|
Line 5466 sub make_new_child {
|
# my $tmpsnum=0; # Now global |
# my $tmpsnum=0; # Now global |
#---------------------------------------------------- kerberos 5 initialization |
#---------------------------------------------------- kerberos 5 initialization |
&Authen::Krb5::init_context(); |
&Authen::Krb5::init_context(); |
unless (($dist eq 'fedora4') || ($dist eq 'suse9.3')) { |
unless (($dist eq 'fedora5') || ($dist eq 'fedora4') |
|
|| ($dist eq 'suse9.3')) { |
&Authen::Krb5::init_ets(); |
&Authen::Krb5::init_ets(); |
} |
} |
|
|
Line 5706 sub validate_user {
|
Line 5893 sub validate_user {
|
# Authenticate via installation specific authentcation method: |
# Authenticate via installation specific authentcation method: |
$validated = &localauth::localauth($user, |
$validated = &localauth::localauth($user, |
$password, |
$password, |
$contentpwd); |
$contentpwd, |
|
$domain); |
} else { # Unrecognized auth is also bad. |
} else { # Unrecognized auth is also bad. |
$validated = 0; |
$validated = 0; |
} |
} |
Line 5732 sub addline {
|
Line 5920 sub addline {
|
my ($fname,$hostid,$ip,$newline)=@_; |
my ($fname,$hostid,$ip,$newline)=@_; |
my $contents; |
my $contents; |
my $found=0; |
my $found=0; |
my $expr='^'.$hostid.':'.$ip.':'; |
my $expr='^'.quotemeta($hostid).':'.quotemeta($ip).':'; |
$expr =~ s/\./\\\./g; |
|
my $sh; |
my $sh; |
if ($sh=IO::File->new("$fname.subscription")) { |
if ($sh=IO::File->new("$fname.subscription")) { |
while (my $subline=<$sh>) { |
while (my $subline=<$sh>) { |