view release on metacpan or search on metacpan
objects. It would be nice if we could manipulate them via OO method
calls, and then pass them right back to $fs->setacl(), wouldn't it?
And how about passing the AFS::Object::Path objects returned from
$fs->whichcell directly to an $fs->listquota call, so that the final
AFS::Object::Path objects have all of the attributes returned by both
calls, but in one set of objects?
Look for this in version 1.1
=head2 stderr handling
stderr processing needs to be handled in the _exec_cmds() method, and
for that matter, _reap_cmds() needs to be folded into _exec_cmds().
The problem is that each API method calls _save_stderr(), and then
later calls _restore_stderr(), and we leave stderr redirected for
longer than necessary. The contents of the redirected output should
be *only* the output from the commands we run, and right now, some of
our own carping can creep in there.
Worse, its possible that a failure in the API can leave stderr
redirected, resulting in a lot of confusion.
Its possible we should just suck in *ALL* of the output, both
stdout/stderr, and drop that data into a couple of arrays. Then,
method calls on the command object get gets individual rows of
stdout/stderr output.
return unless $self->_exec_cmds();
#
# Process stdout
#
while ( defined($_ = $self->_stdout() ) ) {
}
#
# Process stderr (in some cases, there's interesting data in here.
# see the fs examine/diskfree and similar api calls)
#
while ( defined($_ = $self->_stderr() ) ) {
}
Maybe something like that. By the time _exec_cmds returns, we have
reaped the commands, and collected *ALL* of the output into arrays in
the object.
=head2 Test Suite: fs lsmount using multiple dirs
We should create several mount points and then query then all with one
lsmount method call, to verify we can parse output for multiple dirs.
We should pass in some bogus paths, too, to verify the error handling
is correct as well (that code feels dubious to me).
=head1 Bugs
=head2 stdout/stderr buffering will break the fs examine/diskfree commands
Actually, all of the commands that parse per-path output, really.
Currently the code assumes the stderr output will appear first, which
is a side effect of the buffering. Some attempts to turn of buffering
didn't change this, and in any case, we don't want to be sensitive to
this (we currently are).
We need to process stderr first, to determine which paths had errors,
and then parse stdout. This will require the change descibred above
for how we handle stderr.
=cut
<!-- INDEX BEGIN -->
<UL>
<LI><A HREF="#NAME">NAME</A>
<LI><A HREF="#Enhancements">Enhancements</A>
<UL>
<LI><A HREF="#Accept_AFS_Object_objects_as_ar">Accept AFS::Object objects as arguments</A>
<LI><A HREF="#stderr_handling">stderr handling</A>
<LI><A HREF="#Test_Suite_fs_lsmount_using_mul">Test Suite: fs lsmount using multiple dirs</A>
</UL>
<LI><A HREF="#Bugs">Bugs</A>
<UL>
<LI><A HREF="#stdout_stderr_buffering_will_bre">stdout/stderr buffering will break the fs examine/diskfree commands</A>
</UL>
</UL>
<!-- INDEX END -->
<HR>
<P>
<H1><A NAME="NAME">NAME
</A></H1>
<P>
Look for this in version 1.1
<P>
<P>
<HR>
<H2><A NAME="stderr_handling">stderr handling
</A></H2>
stderr processing needs to be handled in the <CODE>_exec_cmds()</CODE>
method, and for that matter, <CODE>_reap_cmds()</CODE> needs to be folded
into <CODE>_exec_cmds().</CODE>
<P>
The problem is that each API method calls <CODE>_save_stderr(),</CODE> and
then later calls <CODE>_restore_stderr(),</CODE> and we leave stderr
redirected for longer than necessary. The contents of the redirected output
should be *only* the output from the commands we run, and right now, some
of our own carping can creep in there.
<P>
Worse, its possible that a failure in the API can leave stderr redirected,
resulting in a lot of confusion.
<P>
Its possible we should just suck in *ALL* of the output, both
stdout/stderr, and drop that data into a couple of arrays. Then, method
calls on the command object get gets individual rows of stdout/stderr
output.
<P>
<PRE> return unless $self->_exec_cmds();
</PRE>
<P>
</PRE>
<P>
<PRE> }
</PRE>
<P>
<PRE> #
# Process stderr (in some cases, there's interesting data in here.
# see the fs examine/diskfree and similar api calls)
#
while ( defined($_ = $self->_stderr() ) ) {
</PRE>
<P>
<PRE> }
</PRE>
<P>
Maybe something like that. By the time _exec_cmds returns, we have reaped
<P>
<P>
<HR>
<H1><A NAME="Bugs">Bugs
</A></H1>
<P>
<HR>
<H2><A NAME="stdout_stderr_buffering_will_bre">stdout/stderr buffering will break the fs examine/diskfree commands
</A></H2>
Actually, all of the commands that parse per-path output, really. Currently
the code assumes the stderr output will appear first, which is a side
effect of the buffering. Some attempts to turn of buffering didn't change
this, and in any case, we don't want to be sensitive to this (we currently
are).
<P>
We need to process stderr first, to determine which paths had errors, and
then parse stdout. This will require the change descibred above for how we
handle stderr.
<P>
</DL>
</BODY>
</HTML>
lib/AFS/Command/BOS.pm view on Meta::CPAN
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "getdate";
my $directory = $args{dir} || '/usr/afs/bin';
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
next unless m:File $directory/(\S+) dated ([^,]+),:;
lib/AFS/Command/BOS.pm view on Meta::CPAN
if ( /\.OLD dated ([^,\.]+)/ ) {
$file->_setAttribute( old => $1 );
}
$result->_addFile($file);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getlog {
my $self = shift;
my (%args) = @_;
lib/AFS/Command/BOS.pm view on Meta::CPAN
if ( $args{redirect} ) {
$redirectname = delete $args{redirect};
$redirect = IO::File->new(">$redirectname") || do {
$self->_Carp("Unable to write to $redirectname: $ERRNO");
return;
};
}
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my $log = "";
while ( defined($_ = $self->{handle}->getline()) ) {
next if /^Fetching log file/;
if ( $redirect ) {
lib/AFS/Command/BOS.pm view on Meta::CPAN
$redirect->close()|| do {
$self->_Carp("Unable to close $redirectname: $ERRNO");
$errors++
};
$result->_setAttribute( log => $redirectname );
} else {
$result->_setAttribute( log => $log );
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getrestart {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "getrestart";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /restarts at (.*)/ || /restarts (never)/ ) {
$result->_setAttribute( restart => $1 );
} elsif ( /binaries at (.*)/ || /binaries (never)/ ) {
$result->_setAttribute( binaries => $1 );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listhosts {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listhosts";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @hosts = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/BOS.pm view on Meta::CPAN
if ( /Host \d+ is (\S+)/i ) {
push(@hosts,$1);
}
}
$result->_setAttribute( hosts => \@hosts );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listkeys {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listkeys";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /key (\d+)/ ) {
lib/AFS/Command/BOS.pm view on Meta::CPAN
}
if ( /last changed on (.*)\./ ) {
$result->_setAttribute( keyschanged => $1 );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listusers {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "listusers";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
if ( /^SUsers are: (.*)/ ) {
$result->_setAttribute( susers => [split(/\s+/,$1)] );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
#
# XXX -- we might want to provide parsing of the bos salvage output,
# but for now, this is a non-parsed command.
#
lib/AFS/Command/BOS.pm view on Meta::CPAN
# my $self = shift;
# my (%args) = @_;
# my $result = AFS::Object::BosServer->new();
# $self->{operation} = "salvage";
# return unless $self->_parse_arguments(%args);
# return unless $self->_save_stderr();
# my $errors = 0;
# $errors++ unless $self->_exec_cmds();
# while ( defined($_ = $self->{handle}->getline()) ) {
# }
# $errors++ unless $self->_reap_cmds();
# $errors++ unless $self->_restore_stderr();
# return if $errors;
# return $result;
# }
sub status {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::BosServer->new();
$self->{operation} = "status";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my $instance = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/BOS.pm view on Meta::CPAN
$instance->_setAttribute( notifier => $1 );
}
}
if ( defined $instance ) {
$result->_addInstance($instance);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
1;
lib/AFS/Command/Base.pm view on Meta::CPAN
my $pid = fork();
unless ( defined $pid ) {
$self->_Carp("Unable to fork: $ERRNO\n");
return;
}
if ( $pid == 0 ) {
STDERR->fdopen( STDOUT->fileno(), "w" ) ||
$self->_Croak("Unable to redirect stderr: $ERRNO\n");
STDOUT->fdopen( $pipe->writer()->fileno(), "w" ) ||
$self->_Croak("Unable to redirect stdout: $ERRNO\n");
if ( $type eq 'default' ) {
exec @{$self->{command}}, 'help';
} else {
exec @{$self->{command}}, 'offline', '-help';
}
die "Unable to exec @{$self->{command}} help: $ERRNO\n";
lib/AFS/Command/Base.pm view on Meta::CPAN
my $errors = 0;
unless ( defined $pid ) {
$self->_Carp("Unable to fork: $ERRNO");
return;
}
if ( $pid == 0 ) {
STDERR->fdopen( STDOUT->fileno(), "w" ) ||
die "Unable to redirect stderr: $ERRNO\n";
STDOUT->fdopen( $pipe->writer()->fileno(), "w" ) ||
die "Unable to redirect stdout: $ERRNO\n";
exec @command, $operation, '-help';
die "Unable to exec @command help $operation: $ERRNO\n";
} else {
$pipe->reader();
while ( <$pipe> ) {
lib/AFS/Command/Base.pm view on Meta::CPAN
if ( $? ) {
$self->_Carp("Error running @command $operation -help. Unable to configure @command $operation");
$errors++;
}
return if $errors;
return $self->{_arguments}->{$operation} = $arguments;
}
sub _save_stderr {
my $self = shift;
$self->{olderr} = IO::File->new(">&STDERR") || do {
$self->_Carp("Unable to dup stderr: $ERRNO");
return;
};
my $command = basename((split /\s+/,@{$self->{command}})[0]);
$self->{tmpfile} = "/tmp/.$command.$self->{operation}.$$";
my $newerr = IO::File->new(">$self->{tmpfile}") || do {
$self->_Carp("Unable to open $self->{tmpfile}: $ERRNO");
return;
};
STDERR->fdopen( $newerr->fileno(), "w" ) || do {
$self->_Carp("Unable to reopen stderr: $ERRNO");
return;
};
$newerr->close() || do {
$self->_Carp("Unable to close $self->{tmpfile}: $ERRNO");
return;
};
return 1;
}
sub _restore_stderr {
my $self = shift;
STDERR->fdopen( $self->{olderr}->fileno(), "w") || do {
$self->_Carp("Unable to restore stderr: $ERRNO");
return;
};
$self->{olderr}->close() || do {
$self->_Carp("Unable to close saved stderr: $ERRNO");
return;
};
delete $self->{olderr};
my $newerr = IO::File->new($self->{tmpfile}) || do {
$self->_Carp("Unable to reopen $self->{tmpfile}: $ERRNO");
return;
};
lib/AFS/Command/Base.pm view on Meta::CPAN
exists $args{stdout} && $args{stdout} ne 'stdout' ) {
my $stdout = IO::File->new(">$args{stdout}") ||
$self->_Croak("Unable to open $args{stdout}: $ERRNO");
STDOUT->fdopen( $stdout->fileno(), "w" ) ||
$self->_Croak("Unable to redirect stdout: $ERRNO");
} else {
STDOUT->fdopen( $pipe->writer()->fileno(), "w" ) ||
$self->_Croak("Unable to redirect stdout: $ERRNO");
}
if ( exists $args{stderr} && $args{stderr} eq 'stdout' ) {
STDERR->fdopen( STDOUT->fileno(), "w" ) ||
$self->_Croak("Unable to redirect stderr: $ERRNO");
}
if ( $index == 0 ) {
if ( exists $args{stdin} && $args{stdin} ne 'stdin' ) {
my $stdin = IO::File->new("<$args{stdin}") ||
$self->_Croak("Unable to open $args{stdin}: $ERRNO");
STDIN->fdopen( $stdin->fileno(), "r" ) ||
$self->_Croak("Unable to redirect stdin: $ERRNO");
}
} else {
lib/AFS/Command/Base.pm view on Meta::CPAN
sub AUTOLOAD {
my $self = shift;
my (%args) = @_;
$self->{operation} = $AUTOLOAD;
$self->{operation} =~ s/.*:://;
return unless $self->_parse_arguments(%args);
return unless $self->_exec_cmds( stderr => 'stdout' );
my $errors = 0;
$errors++ unless $self->_parse_output();
$errors++ unless $self->_reap_cmds();
return if $errors;
return 1;
}
lib/AFS/Command/Base.pod view on Meta::CPAN
release, restore, etc. Commands that return complex structures of
objects, such as listvldb, listvol, etc will not be affected.
=back
=head2 setCarp
This class method configures the carp and/or croak subroutines used
throughout the API. By default, the obviously sensible thing is done:
the carp an croak subroutines exported by the Carp module are used.
These normally print output to stderr, and this method provides a
mechanism for trapping these errors and redirecting them elsewhere.
For example, stderr in a system daemon may be entirely ignored, and
syslog may be a more appropriate destination. In this case, the
setCarp method may be used to configure this, globally, for the entire
API.
AFS::Command->setCarp
(
carp => sub {
my ($lines) = @_;
foreach my $line ( split(/\n+/,$lines) ) {
syslog('warning',$line);
}
},
croak => sub {
my ($lines) = @_;
foreach my $line ( split(/\n+/,$lines) ) {
syslog('error',$line);
}
die $lines; # If we're dying, whine at stderr, too.
},
);
This method takes a list of key/value pairs, with only two supported
keys (anything else will be quietly ignored): carp an croak. The
values are CODE references (anonymous subroutines, or references to
existing subroutines). The carp CODE should not be fatal, however the
croak CODE should. The API calls the croak method in very few places,
but when it does, it assumes that call will be fatal, so if you
lib/AFS/Command/Base.pod view on Meta::CPAN
carp and/or croak subroutines were properly configured. If the values
are not CODE references, then this method will itself croak.
=head1 INSTANCE METHODS
=head2 errors
This method takes no arguments, and it returns a string, containing the
unparsed errors from the last command method invoked. This string is
reset with each subsequent command method invocation. The string is
normally the output written to stderr by the process, but in the case
of unparsed boolean commands, it contains both the stdout as well as
the stderr output.
my $result = $vos->examine
(
id => $volname,
cell => $cell,
);
unless ( $result ) {
die "Unable to examine volname '$volname' in cell '$cell':" .
$vos->errors();
}
lib/AFS/Command/FS.pm view on Meta::CPAN
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "checkservers";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @servers = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/FS.pm view on Meta::CPAN
s/^\s+//g;
s/\s+$//g;
push(@servers,$_);
}
}
}
$result->_setAttribute( servers => \@servers );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub diskfree {
my $self = shift;
return $self->_paths_method('diskfree',@_);
}
lib/AFS/Command/FS.pm view on Meta::CPAN
my $result = AFS::Object::CacheManager->new();
$self->{operation} = $operation;
my $pathkey = $operation eq 'storebehind' ? 'files' : 'path';
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my @paths = ref $args{$pathkey} eq 'ARRAY' ? @{$args{$pathkey}} : ($args{$pathkey});
my %paths = map { $_ => 1 } @paths;
my $default = undef; # Used by storebehind
while ( defined($_ = $self->{handle}->getline()) ) {
next if /^Volume Name/;
lib/AFS/Command/FS.pm view on Meta::CPAN
my $self = shift;
my (%args) = @_;
my $result = AFS::Object->new();
$self->{operation} = "exportafs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
/translator is (currently )?enabled/ && do {
$result->_setAttribute( enabled => 1 );
};
lib/AFS/Command/FS.pm view on Meta::CPAN
$result->_setAttribute( submounts => 1 );
};
/Only mounts/i && do {
$result->_setAttribute( submounts => 0 );
};
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcacheparms {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcacheparms";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /using (\d+) of the cache.s available (\d+) 1K/ ) {
$result->_setAttribute
(
used => $1,
avail => $2,
);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcellstatus {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcellstatus";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Cell (\S+) status: (no )?setuid allowed/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $1,
status => $2 ? 0 : 1,
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getclientaddrs {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getclientaddrs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @addresses = ();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
s/^\s+//;
s/\s+$//;
push(@addresses,$_);
}
$result->_setAttribute( addresses => \@addresses );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getcrypt {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getcrypt";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Security level is currently (crypt|clear)/ ) {
$result->_setAttribute( crypt => ($1 eq 'crypt' ? 1 : 0) );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub getserverprefs {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "getserverprefs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
s/^\s+//g;
s/\s+$//g;
lib/AFS/Command/FS.pm view on Meta::CPAN
(
server => $name,
preference => $preference,
);
$result->_addServer($server);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listaliases {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "listaliases";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Alias (.*) for cell (.*)/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $2,
alias => $1,
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listcells {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "listcells";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /^Cell (\S+) on hosts (.*)\.$/ ) {
my $cell = AFS::Object::Cell->new
(
cell => $1,
servers => [split(/\s+/,$2)],
);
$result->_addCell($cell);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub lsmount {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "lsmount";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my @dirs = ref $args{dir} eq 'ARRAY' ? @{$args{dir}} : ($args{dir});
my %dirs = map { $_ => 1 } @dirs;
while ( defined($_ = $self->{handle}->getline()) ) {
my $current = shift @dirs;
delete $dirs{$current};
my $path = AFS::Object::Path->new( path => $current );
lib/AFS/Command/FS.pm view on Meta::CPAN
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "sysname";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my @sysname = ();
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Current sysname is \'?([^\']+)\'?/ ) {
lib/AFS/Command/FS.pm view on Meta::CPAN
while ( s/\'([^\']+)\'\s*// ) {
push(@sysname,$1);
}
$result->_setAttribute( sysnames => \@sysname );
$result->_setAttribute( sysname => $sysname[0] );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub wscell {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::CacheManager->new();
$self->{operation} = "wscell";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /belongs to cell\s+\'(.*)\'/;
$result->_setAttribute( cell => $1 );
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
1;
lib/AFS/Command/PTS.pm view on Meta::CPAN
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "creategroup";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /group (\S+) has id (-\d+)/;
my $group = AFS::Object::Group->new
(
name => $1,
id => $2,
);
$result->_addGroup($group);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub createuser {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "createuser";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /User (\S+) has id (\d+)/;
my $user = AFS::Object::User->new
(
name => $1,
id => $2,
);
$result->_addUser($user);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub examine {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "examine";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
while ( /,\s*$/ ) {
lib/AFS/Command/PTS.pm view on Meta::CPAN
if ( $data{id} > 0 ) {
$result->_addUser( AFS::Object::User->new(%data) );
} else {
$result->_addGroup( AFS::Object::Group->new(%data) );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listentries {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listentries";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next if /^Name/;
my ($name,$id,$owner,$creator) = split;
lib/AFS/Command/PTS.pm view on Meta::CPAN
id => $id,
owner => $owner,
creator => $creator,
);
$result->_addGroup($group);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listmax {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listmax";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless /Max user id is (\d+) and max group id is (-\d+)/;
$result->_setAttribute
(
maxuserid => $1,
maxgroupid => $2,
);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listowned {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "listowned";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my $user = undef;
my $group = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /Groups owned by (\S+) \(id: (-?\d+)\)/ ) {
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
lib/AFS/Command/PTS.pm view on Meta::CPAN
my (%args) = @_;
my $result = AFS::Object::PTServer->new();
$self->{operation} = "membership";
return unless $self->_parse_arguments(%args);
my $errors = 0;
$errors++ unless $self->_exec_cmds( stderr => 'stdout' );
my $user = undef;
my $group = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
if ( /(\S+) \(id: (-?\d+)\)/ ) {
$result->_addUser($user) if $user;
$result->_addGroup($group) if $group;
lib/AFS/Command/VOS.pm view on Meta::CPAN
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::Volume->new();
my $entry = AFS::Object::VLDBEntry->new( locked => 0 );
$self->{operation} = "examine";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
#
lib/AFS/Command/VOS.pm view on Meta::CPAN
if ( /^(\S+)/ ) {
$entry->_setAttribute( name => $1 );
}
}
$result->_addVLDBEntry($entry);
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listaddrs {
my $self = shift;
my (%args) = @_;
my @result = ();
$self->{operation} = "listaddrs";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
if ( $args{printuuid} ) {
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/VOS.pm view on Meta::CPAN
if ( /^\d+\.\d+\.\d+\.\d+$/ ) {
push(@result,AFS::Object::FileServer->new( addresses => [$_] ));
} else {
push(@result,AFS::Object::FileServer->new( hostname => $_ ));
}
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return @result;
}
sub listpart {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::FileServer->new();
$self->{operation} = "listpart";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
next unless m:/vice:;
lib/AFS/Command/VOS.pm view on Meta::CPAN
s/\s+$//g;
foreach my $partname ( split ) {
my $partition = AFS::Object::Partition->new( partition => $partname );
$result->_addPartition($partition);
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listvldb {
my $self = shift;
my (%args) = @_;
$self->{operation} = "listvldb";
my $locked = 0;
my $result = AFS::Object::VLDB->new();
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
next if /^\s*$/; # If it starts with a blank line, then
lib/AFS/Command/VOS.pm view on Meta::CPAN
}
$result->_addVLDBEntry( $entry );
}
$result->_setAttribute( locked => $locked );
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub listvol {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::VolServer->new();
$self->{operation} = "listvol";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
if ( delete $args{extended} ) {
$self->_Carp("vos listvol: -extended is not supported by this version of the API");
}
while ( defined($_ = $self->{handle}->getline()) ) {
lib/AFS/Command/VOS.pm view on Meta::CPAN
$partition->_addVolumeHeader($volume);
}
$result->_addPartition($partition);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub partinfo {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::FileServer->new();
$self->{operation} = "partinfo";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
while ( defined($_ = $self->{handle}->getline()) ) {
next unless m|partition (/vice\w+): (-?\d+)\D+(\d+)$|;
my $partition = AFS::Object::Partition->new
lib/AFS/Command/VOS.pm view on Meta::CPAN
available => $2,
total => $3,
);
$result->_addPartition($partition);
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub status {
my $self = shift;
my (%args) = @_;
my $result = AFS::Object::VolServer->new();
$self->{operation} = "status";
return unless $self->_parse_arguments(%args);
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds();
my $transaction = undef;
while ( defined($_ = $self->{handle}->getline()) ) {
chomp;
lib/AFS/Command/VOS.pm view on Meta::CPAN
}
if ( /lastSendTime:\s+(\d+)/ ) {
$transaction->_setAttribute( lastSendTime => $1 );
}
}
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return $result;
}
sub dump {
my $self = shift;
my (%args) = @_;
lib/AFS/Command/VOS.pm view on Meta::CPAN
}
};
if ( $gzip ) {
push( @{$self->{cmds}}, [ 'gzip', "-$gzip", '-c' ] );
} elsif ( $bzip2 ) {
push( @{$self->{cmds}}, [ 'bzip2', "-$bzip2", '-c' ] );
}
return unless $self->_save_stderr();
my $errors = 0;
$errors++ unless $self->_exec_cmds
(
stdout => ( $args{file} ? "/dev/null" : $file ),
);
$errors++ unless $self->_reap_cmds();
$errors++ unless $self->_restore_stderr();
return if $errors;
return 1;
}
sub restore {
my $self = shift;
my (%args) = @_;
lib/AFS/Command/VOS.pm view on Meta::CPAN
if ( $gunzip ) {
unshift( @{$self->{cmds}}, [ 'gunzip', '-c' ] );
} elsif ( $bunzip2 ) {
unshift( @{$self->{cmds}}, [ 'bunzip2', '-c' ] );
}
my $errors = 0;
$errors++ unless $self->_exec_cmds
(
stderr => 'stdout',
stdin => ( $args{file} ? "/dev/null" : $file ),
);
$errors++ unless $self->_parse_output();
$errors++ unless $self->_reap_cmds();
return if $errors;
return 1;
}