Merge branch 'master' into squeeze
[debian/amanda] / perl / Amanda / NDMP.pm
diff --git a/perl/Amanda/NDMP.pm b/perl/Amanda/NDMP.pm
new file mode 100644 (file)
index 0000000..30bf257
--- /dev/null
@@ -0,0 +1,787 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 2.0.4
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+package Amanda::NDMP;
+use base qw(Exporter);
+use base qw(DynaLoader);
+package Amanda::NDMPc;
+bootstrap Amanda::NDMP;
+package Amanda::NDMP;
+@EXPORT = qw();
+
+# ---------- BASE METHODS -------------
+
+package Amanda::NDMP;
+
+sub TIEHASH {
+    my ($classname,$obj) = @_;
+    return bless $obj, $classname;
+}
+
+sub CLEAR { }
+
+sub FIRSTKEY { }
+
+sub NEXTKEY { }
+
+sub FETCH {
+    my ($self,$field) = @_;
+    my $member_func = "swig_${field}_get";
+    $self->$member_func();
+}
+
+sub STORE {
+    my ($self,$field,$newval) = @_;
+    my $member_func = "swig_${field}_set";
+    $self->$member_func($newval);
+}
+
+sub this {
+    my $ptr = shift;
+    return tied(%$ptr);
+}
+
+
+# ------- FUNCTION WRAPPERS --------
+
+package Amanda::NDMP;
+
+
+############# Class : Amanda::NDMP::NDMPConnection ##############
+
+package Amanda::NDMP::NDMPConnection;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( Amanda::NDMP );
+%OWNER = ();
+%ITERATORS = ();
+sub new {
+    my $pkg = shift;
+    my $self = Amanda::NDMPc::new_NDMPConnection(@_);
+    bless $self, $pkg if defined($self);
+}
+
+sub DESTROY {
+    return unless $_[0]->isa('HASH');
+    my $self = tied(%{$_[0]});
+    return unless defined $self;
+    delete $ITERATORS{$self};
+    if (exists $OWNER{$self}) {
+        Amanda::NDMPc::delete_NDMPConnection($self);
+        delete $OWNER{$self};
+    }
+}
+
+*err_code = *Amanda::NDMPc::NDMPConnection_err_code;
+*err_msg = *Amanda::NDMPc::NDMPConnection_err_msg;
+*set_verbose = *Amanda::NDMPc::NDMPConnection_set_verbose;
+*scsi_open = *Amanda::NDMPc::NDMPConnection_scsi_open;
+*scsi_close = *Amanda::NDMPc::NDMPConnection_scsi_close;
+*scsi_execute_cdb_C = *Amanda::NDMPc::NDMPConnection_scsi_execute_cdb_C;
+*tape_open = *Amanda::NDMPc::NDMPConnection_tape_open;
+*tape_close = *Amanda::NDMPc::NDMPConnection_tape_close;
+*tape_mtio = *Amanda::NDMPc::NDMPConnection_tape_mtio;
+*tape_write = *Amanda::NDMPc::NDMPConnection_tape_write;
+*tape_read = *Amanda::NDMPc::NDMPConnection_tape_read;
+*tape_get_state = *Amanda::NDMPc::NDMPConnection_tape_get_state;
+sub DISOWN {
+    my $self = shift;
+    my $ptr = tied(%$self);
+    delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+    my $self = shift;
+    my $ptr = tied(%$self);
+    $OWNER{$ptr} = 1;
+}
+
+
+# ------- VARIABLE STUBS --------
+
+package Amanda::NDMP;
+
+*NDMP9_SCSI_DATA_DIR_NONE = *Amanda::NDMPc::NDMP9_SCSI_DATA_DIR_NONE;
+*NDMP9_SCSI_DATA_DIR_IN = *Amanda::NDMPc::NDMP9_SCSI_DATA_DIR_IN;
+*NDMP9_SCSI_DATA_DIR_OUT = *Amanda::NDMPc::NDMP9_SCSI_DATA_DIR_OUT;
+*NDMP9_TAPE_READ_MODE = *Amanda::NDMPc::NDMP9_TAPE_READ_MODE;
+*NDMP9_TAPE_RDWR_MODE = *Amanda::NDMPc::NDMP9_TAPE_RDWR_MODE;
+*NDMP9_TAPE_RAW_MODE = *Amanda::NDMPc::NDMP9_TAPE_RAW_MODE;
+*NDMP9_MTIO_FSF = *Amanda::NDMPc::NDMP9_MTIO_FSF;
+*NDMP9_MTIO_BSF = *Amanda::NDMPc::NDMP9_MTIO_BSF;
+*NDMP9_MTIO_FSR = *Amanda::NDMPc::NDMP9_MTIO_FSR;
+*NDMP9_MTIO_BSR = *Amanda::NDMPc::NDMP9_MTIO_BSR;
+*NDMP9_MTIO_REW = *Amanda::NDMPc::NDMP9_MTIO_REW;
+*NDMP9_MTIO_EOF = *Amanda::NDMPc::NDMP9_MTIO_EOF;
+*NDMP9_MTIO_OFF = *Amanda::NDMPc::NDMP9_MTIO_OFF;
+*NDMP9_MOVER_MODE_READ = *Amanda::NDMPc::NDMP9_MOVER_MODE_READ;
+*NDMP9_MOVER_MODE_WRITE = *Amanda::NDMPc::NDMP9_MOVER_MODE_WRITE;
+*NDMP9_ADDR_LOCAL = *Amanda::NDMPc::NDMP9_ADDR_LOCAL;
+*NDMP9_ADDR_TCP = *Amanda::NDMPc::NDMP9_ADDR_TCP;
+*NDMP9_ADDR_AS_CONNECTED = *Amanda::NDMPc::NDMP9_ADDR_AS_CONNECTED;
+*NDMP9_MOVER_STATE_IDLE = *Amanda::NDMPc::NDMP9_MOVER_STATE_IDLE;
+*NDMP9_MOVER_STATE_LISTEN = *Amanda::NDMPc::NDMP9_MOVER_STATE_LISTEN;
+*NDMP9_MOVER_STATE_ACTIVE = *Amanda::NDMPc::NDMP9_MOVER_STATE_ACTIVE;
+*NDMP9_MOVER_STATE_PAUSED = *Amanda::NDMPc::NDMP9_MOVER_STATE_PAUSED;
+*NDMP9_MOVER_STATE_HALTED = *Amanda::NDMPc::NDMP9_MOVER_STATE_HALTED;
+*NDMP9_MOVER_STATE_STANDBY = *Amanda::NDMPc::NDMP9_MOVER_STATE_STANDBY;
+*NDMP9_DATA_HALT_NA = *Amanda::NDMPc::NDMP9_DATA_HALT_NA;
+*NDMP9_DATA_HALT_SUCCESSFUL = *Amanda::NDMPc::NDMP9_DATA_HALT_SUCCESSFUL;
+*NDMP9_DATA_HALT_ABORTED = *Amanda::NDMPc::NDMP9_DATA_HALT_ABORTED;
+*NDMP9_DATA_HALT_INTERNAL_ERROR = *Amanda::NDMPc::NDMP9_DATA_HALT_INTERNAL_ERROR;
+*NDMP9_DATA_HALT_CONNECT_ERROR = *Amanda::NDMPc::NDMP9_DATA_HALT_CONNECT_ERROR;
+*NDMP9_MOVER_HALT_NA = *Amanda::NDMPc::NDMP9_MOVER_HALT_NA;
+*NDMP9_MOVER_HALT_CONNECT_CLOSED = *Amanda::NDMPc::NDMP9_MOVER_HALT_CONNECT_CLOSED;
+*NDMP9_MOVER_HALT_ABORTED = *Amanda::NDMPc::NDMP9_MOVER_HALT_ABORTED;
+*NDMP9_MOVER_HALT_INTERNAL_ERROR = *Amanda::NDMPc::NDMP9_MOVER_HALT_INTERNAL_ERROR;
+*NDMP9_MOVER_HALT_CONNECT_ERROR = *Amanda::NDMPc::NDMP9_MOVER_HALT_CONNECT_ERROR;
+*NDMP9_MOVER_PAUSE_NA = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_NA;
+*NDMP9_MOVER_PAUSE_EOM = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_EOM;
+*NDMP9_MOVER_PAUSE_EOF = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_EOF;
+*NDMP9_MOVER_PAUSE_SEEK = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_SEEK;
+*NDMP9_MOVER_PAUSE_MEDIA_ERROR = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_MEDIA_ERROR;
+*NDMP9_MOVER_PAUSE_EOW = *Amanda::NDMPc::NDMP9_MOVER_PAUSE_EOW;
+
+@EXPORT_OK = ();
+%EXPORT_TAGS = ();
+
+
+=head1 NAME
+
+Amanda::NDMP - communicate via NDMP
+
+=head1 SYNOPSIS
+
+  use Amanda::NDMP qw( :constants );
+
+  my $conn = Amanda::NDMP::NDMPConnection->new($host, $port, $ident, $username,
+                                              $password, $auth);
+  my ($ok, $blocksize, $file_num, $blockno) = $conn->tape_get_state();
+
+=head1 DESCRIPTION
+
+This package interfaces with the C class C<NDMPConnection> class declared in
+C<ndmp-src/ndmpconnobj.h>.  It is only available in builds that did not specify
+C<--without-ndmp>.  The C class, in turn, interfaces to the XDR code provided
+by NDMJOB, which sends and receives NDMP messages on a TCP socket.
+
+=head2 Constructor
+
+  my $conn = Amanda::NDMP::NDMPConnection->new($host, $port, $ident, $username,
+                                              $password, $auth);
+  if ($conn->err_code()) {
+    # handle error..
+  }
+
+This gets a new connection object.  This will always return an object, but the
+result should be checked for errors as described in the "Error Handling"
+section, below.
+
+The C<$host> and C<$port> give the NDMP server's host and port, respectively.
+The C<$auth> parameter defines the authentication mechanism to use: "md5" or
+"text"; "none" for no authentication; or "void" to not send any authentication
+packets at all.  For md5 or text modes, C<$username> and C<$password> specify
+the username and password for the NDMP server; these parameters must always be
+included, but can be blank for none or void.
+
+The C<$ident> parameter deserves some explanation.  NDMP scopes many
+server-side variables to the NDMP connection - for example, the "current" tape
+and taper state are associated with the NDMP connection.  To facilitate this,
+the constructor returns the I<same connection> for any constructor invocation
+with the same host, port, and identifier.  In cases where multiple connections
+are required (e.g., when two tapes are in use simultaneously), callers should
+provide different identifiers for each connection.
+
+=head2 Methods
+
+Note that not all NDMPConnection methods are available.  All of these methods
+block until the appropriate reply is received.  The underlying C class provides
+appropriate locking fundamentals to prevent corrupted on-the-wire messages.
+
+All methods return a boolean "ok" status, with false indicating an error.
+
+=head3 Error Handling
+
+  my $code = $conn->err_code();
+  my $msg = $conn->err_msg();
+
+Get the error code and message from the last method that returned false, or
+after the constructor is invoked.
+
+  $conn->set_verbose(1);
+
+This method will enable verbose logging of the NDMP transactions to the Amanda
+debug logs.
+
+=head3 SCSI Interface
+
+  my $ok = $conn->scsi_open($device);      # NDMP_SCSI_OPEN
+  my $ok = $conn->scsi_close();                    # NDMP_SCSI_CLOSE
+  # NDMP_SCSI_EXECUTE_CDB
+  my $res = $conn->scsi_execute_cdb(
+    flags => $flags,
+    timeout => $timeout,
+    cdb => $cdb,
+    datain_len => $datain_len,     # only if $flags == $NDMP9_SCSI_DATA_DIR_IN
+    dataout => $dataout            # only if $flags == $NDMP9_SCSI_DATA_DIR_OUT
+  )
+
+The first two methods are clear; the third uses keyword parameters to simplify
+a complex set of parameters.  The C<flags> argument can be
+C<$NDMP9_SCSI_DATA_DIR_IN>, to take data I<into> the server from the SCSI
+device, or C<$NDMP9_SCSI_DATA_DIR_OUT> to send data I<out> to the SCSI device.
+The C<timeout> is in milliseconds.  The C<cdb> should be a SCSI control block
+(the C<pack> function is useful here).  If the data direction is in, then
+C<datain_len> indicates the maximum amount of data to expect; otherwise,
+C<dataout> is the data to send to the device.
+
+The result is C<undef> for an error, or a hashref with the following keys:
+
+  status           SCSI status byte
+  ext_sense        SCSI extended sense data
+  datain           data from the device
+  dataout_len      number of bytes actually transmitted to the device
+
+=head3 Tape Interface
+
+  my $ok = $conn->tape_open($device, $mode);
+  my $ok = $conn->tape_close();
+
+The first method opens a tape device, using the give mode -
+C<$NDMP9_TAPE_READ_MODE> or C<$NDMP9_TAPE_RDRW_MODE>.  The second method closes
+the tape device associated with this connection.
+
+  my ($ok, $resid) = $conn->tape_mtio($op, $count);
+
+This method sends C<NDMP_TAPE_MTIO> with the given operation and count.
+Operations have the prefix C<$NDMP9_MTIO_>.  The number of incomplete
+operations is returned in C<$resid>.
+
+To read and write blocks, use these methods:
+
+  my ($ok, $actual) = $conn->tape_write($data);
+  my ($ok, $data) = $conn->tape_read($bufsize);
+
+where C<$actual> and C<$bufsize> are byte counts, and C<$data> is a string of
+data.  Finally, to get the state of the tape agent, use
+
+  my ($ok, $blocksize, $file_num, $blockno) = $conn->tape_get_state();
+
+=head2 Constants
+
+The constants required for the interface exposed here are included in this
+package.  They all begin with the prefix C<$NDMP9_>, which is an implementation
+detail of the NDMJOB library.  The constants are available from the export tag
+C<constants>:
+
+  use Amanda::NDMP qw( :constants );
+
+=cut
+
+
+
+package Amanda::NDMP::NDMPConnection;
+
+sub scsi_execute_cdb {
+    my $self = shift;
+    my %params = @_;
+
+    die "no 'flags' parameter'" unless defined $params{'flags'};
+    die "no 'timeout' parameter'" unless defined $params{'timeout'};
+    die "no 'cdb' parameter'" unless defined $params{'cdb'};
+    if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_IN) {
+       die "no 'datain_len' parameter'" unless defined $params{'datain_len'};
+    } else {
+       $params{'datain_len'} = 0;
+    }
+    if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_OUT) {
+       die "no 'dataout' parameter'" unless defined $params{'dataout'};
+    } else {
+       $params{'dataout'} = undef;
+    }
+
+    my ($ok, $dataout_len, $datain, $status, $ext_sense) =
+       $self->scsi_execute_cdb_C(
+           $params{'flags'}, $params{'timeout'},
+           $params{'cdb'}, $params{'dataout'},
+           $params{'datain_len'});
+
+    return 0 unless ($ok);
+
+    my %result = (
+       status => $status,
+       ext_sense => $ext_sense);
+    if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_IN) {
+       $result{'datain'} = $datain;
+    }
+    if ($params{'flags'} & $Amanda::NDMP::NDMP9_SCSI_DATA_DIR_OUT) {
+       $result{'dataout_len'} = $dataout_len;
+    }
+    return \%result;
+}
+
+package Amanda::NDMP;
+
+push @EXPORT_OK, qw(scsi_data_dir_to_strings);
+push @{$EXPORT_TAGS{"scsi_data_dir"}}, qw(scsi_data_dir_to_strings);
+
+my %_scsi_data_dir_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub scsi_data_dir_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_scsi_data_dir_VALUES) {
+       my $v = $_scsi_data_dir_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_SCSI_DATA_DIR_NONE);
+push @{$EXPORT_TAGS{"scsi_data_dir"}}, qw($NDMP9_SCSI_DATA_DIR_NONE);
+
+$_scsi_data_dir_VALUES{"NDMP9_SCSI_DATA_DIR_NONE"} = $NDMP9_SCSI_DATA_DIR_NONE;
+
+push @EXPORT_OK, qw($NDMP9_SCSI_DATA_DIR_IN);
+push @{$EXPORT_TAGS{"scsi_data_dir"}}, qw($NDMP9_SCSI_DATA_DIR_IN);
+
+$_scsi_data_dir_VALUES{"NDMP9_SCSI_DATA_DIR_IN"} = $NDMP9_SCSI_DATA_DIR_IN;
+
+push @EXPORT_OK, qw($NDMP9_SCSI_DATA_DIR_OUT);
+push @{$EXPORT_TAGS{"scsi_data_dir"}}, qw($NDMP9_SCSI_DATA_DIR_OUT);
+
+$_scsi_data_dir_VALUES{"NDMP9_SCSI_DATA_DIR_OUT"} = $NDMP9_SCSI_DATA_DIR_OUT;
+
+#copy symbols in scsi_data_dir to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"scsi_data_dir"}};
+
+push @EXPORT_OK, qw(tape_open_mode_to_strings);
+push @{$EXPORT_TAGS{"tape_open_mode"}}, qw(tape_open_mode_to_strings);
+
+my %_tape_open_mode_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub tape_open_mode_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_tape_open_mode_VALUES) {
+       my $v = $_tape_open_mode_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_TAPE_READ_MODE);
+push @{$EXPORT_TAGS{"tape_open_mode"}}, qw($NDMP9_TAPE_READ_MODE);
+
+$_tape_open_mode_VALUES{"NDMP9_TAPE_READ_MODE"} = $NDMP9_TAPE_READ_MODE;
+
+push @EXPORT_OK, qw($NDMP9_TAPE_RDWR_MODE);
+push @{$EXPORT_TAGS{"tape_open_mode"}}, qw($NDMP9_TAPE_RDWR_MODE);
+
+$_tape_open_mode_VALUES{"NDMP9_TAPE_RDRW_MODE"} = $NDMP9_TAPE_RDWR_MODE;
+
+push @EXPORT_OK, qw($NDMP9_TAPE_RAW_MODE);
+push @{$EXPORT_TAGS{"tape_open_mode"}}, qw($NDMP9_TAPE_RAW_MODE);
+
+$_tape_open_mode_VALUES{"NDMP9_TAPE_RAW_MODE"} = $NDMP9_TAPE_RAW_MODE;
+
+#copy symbols in tape_open_mode to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"tape_open_mode"}};
+
+push @EXPORT_OK, qw(tape_mtio_op_to_strings);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw(tape_mtio_op_to_strings);
+
+my %_tape_mtio_op_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub tape_mtio_op_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_tape_mtio_op_VALUES) {
+       my $v = $_tape_mtio_op_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_MTIO_FSF);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_FSF);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_FSF"} = $NDMP9_MTIO_FSF;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_BSF);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_BSF);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_BSF"} = $NDMP9_MTIO_BSF;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_FSR);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_FSR);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_FSR"} = $NDMP9_MTIO_FSR;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_BSR);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_BSR);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_BSR"} = $NDMP9_MTIO_BSR;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_REW);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_REW);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_REW"} = $NDMP9_MTIO_REW;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_EOF);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_EOF);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_EOF"} = $NDMP9_MTIO_EOF;
+
+push @EXPORT_OK, qw($NDMP9_MTIO_OFF);
+push @{$EXPORT_TAGS{"tape_mtio_op"}}, qw($NDMP9_MTIO_OFF);
+
+$_tape_mtio_op_VALUES{"NDMP9_MTIO_OFF"} = $NDMP9_MTIO_OFF;
+
+#copy symbols in tape_mtio_op to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"tape_mtio_op"}};
+
+push @EXPORT_OK, qw(mover_mode_to_strings);
+push @{$EXPORT_TAGS{"mover_mode"}}, qw(mover_mode_to_strings);
+
+my %_mover_mode_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub mover_mode_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_mover_mode_VALUES) {
+       my $v = $_mover_mode_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_MOVER_MODE_READ);
+push @{$EXPORT_TAGS{"mover_mode"}}, qw($NDMP9_MOVER_MODE_READ);
+
+$_mover_mode_VALUES{"NDMP9_MOVER_MODE_READ"} = $NDMP9_MOVER_MODE_READ;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_MODE_WRITE);
+push @{$EXPORT_TAGS{"mover_mode"}}, qw($NDMP9_MOVER_MODE_WRITE);
+
+$_mover_mode_VALUES{"NDMP9_MOVER_MODE_WRITE"} = $NDMP9_MOVER_MODE_WRITE;
+
+#copy symbols in mover_mode to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"mover_mode"}};
+
+push @EXPORT_OK, qw(addr_type_to_strings);
+push @{$EXPORT_TAGS{"addr_type"}}, qw(addr_type_to_strings);
+
+my %_addr_type_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub addr_type_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_addr_type_VALUES) {
+       my $v = $_addr_type_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_ADDR_LOCAL);
+push @{$EXPORT_TAGS{"addr_type"}}, qw($NDMP9_ADDR_LOCAL);
+
+$_addr_type_VALUES{"NDMP9_ADDR_LOCAL"} = $NDMP9_ADDR_LOCAL;
+
+push @EXPORT_OK, qw($NDMP9_ADDR_TCP);
+push @{$EXPORT_TAGS{"addr_type"}}, qw($NDMP9_ADDR_TCP);
+
+$_addr_type_VALUES{"NDMP9_ADDR_TCP"} = $NDMP9_ADDR_TCP;
+
+push @EXPORT_OK, qw($NDMP9_ADDR_AS_CONNECTED);
+push @{$EXPORT_TAGS{"addr_type"}}, qw($NDMP9_ADDR_AS_CONNECTED);
+
+$_addr_type_VALUES{"NDMP9_ADDR_AS_CONNECTED"} = $NDMP9_ADDR_AS_CONNECTED;
+
+#copy symbols in addr_type to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"addr_type"}};
+
+push @EXPORT_OK, qw(mover_state_to_strings);
+push @{$EXPORT_TAGS{"mover_state"}}, qw(mover_state_to_strings);
+
+my %_mover_state_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub mover_state_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_mover_state_VALUES) {
+       my $v = $_mover_state_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_IDLE);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_IDLE);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_IDLE"} = $NDMP9_MOVER_STATE_IDLE;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_LISTEN);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_LISTEN);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_LISTEN"} = $NDMP9_MOVER_STATE_LISTEN;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_ACTIVE);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_ACTIVE);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_ACTIVE"} = $NDMP9_MOVER_STATE_ACTIVE;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_PAUSED);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_PAUSED);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_PAUSED"} = $NDMP9_MOVER_STATE_PAUSED;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_HALTED);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_HALTED);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_HALTED"} = $NDMP9_MOVER_STATE_HALTED;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_STATE_STANDBY);
+push @{$EXPORT_TAGS{"mover_state"}}, qw($NDMP9_MOVER_STATE_STANDBY);
+
+$_mover_state_VALUES{"NDMP9_MOVER_STATE_STANDBY"} = $NDMP9_MOVER_STATE_STANDBY;
+
+#copy symbols in mover_state to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"mover_state"}};
+
+push @EXPORT_OK, qw(data_halt_reason_to_strings);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw(data_halt_reason_to_strings);
+
+my %_data_halt_reason_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub data_halt_reason_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_data_halt_reason_VALUES) {
+       my $v = $_data_halt_reason_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_DATA_HALT_NA);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw($NDMP9_DATA_HALT_NA);
+
+$_data_halt_reason_VALUES{"NDMP9_DATA_HALT_NA"} = $NDMP9_DATA_HALT_NA;
+
+push @EXPORT_OK, qw($NDMP9_DATA_HALT_SUCCESSFUL);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw($NDMP9_DATA_HALT_SUCCESSFUL);
+
+$_data_halt_reason_VALUES{"NDMP9_DATA_HALT_SUCCESSFUL"} = $NDMP9_DATA_HALT_SUCCESSFUL;
+
+push @EXPORT_OK, qw($NDMP9_DATA_HALT_ABORTED);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw($NDMP9_DATA_HALT_ABORTED);
+
+$_data_halt_reason_VALUES{"NDMP9_DATA_HALT_ABORTED"} = $NDMP9_DATA_HALT_ABORTED;
+
+push @EXPORT_OK, qw($NDMP9_DATA_HALT_INTERNAL_ERROR);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw($NDMP9_DATA_HALT_INTERNAL_ERROR);
+
+$_data_halt_reason_VALUES{"NDMP9_DATA_HALT_INTERNAL_ERROR"} = $NDMP9_DATA_HALT_INTERNAL_ERROR;
+
+push @EXPORT_OK, qw($NDMP9_DATA_HALT_CONNECT_ERROR);
+push @{$EXPORT_TAGS{"data_halt_reason"}}, qw($NDMP9_DATA_HALT_CONNECT_ERROR);
+
+$_data_halt_reason_VALUES{"NDMP9_DATA_HALT_CONNECT_ERROR"} = $NDMP9_DATA_HALT_CONNECT_ERROR;
+
+#copy symbols in data_halt_reason to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"data_halt_reason"}};
+
+push @EXPORT_OK, qw(mover_halt_reason_to_strings);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw(mover_halt_reason_to_strings);
+
+my %_mover_halt_reason_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub mover_halt_reason_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_mover_halt_reason_VALUES) {
+       my $v = $_mover_halt_reason_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_MOVER_HALT_NA);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw($NDMP9_MOVER_HALT_NA);
+
+$_mover_halt_reason_VALUES{"NDMP9_MOVER_HALT_NA"} = $NDMP9_MOVER_HALT_NA;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_HALT_CONNECT_CLOSED);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw($NDMP9_MOVER_HALT_CONNECT_CLOSED);
+
+$_mover_halt_reason_VALUES{"NDMP9_MOVER_HALT_CONNECT_CLOSED"} = $NDMP9_MOVER_HALT_CONNECT_CLOSED;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_HALT_ABORTED);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw($NDMP9_MOVER_HALT_ABORTED);
+
+$_mover_halt_reason_VALUES{"NDMP9_MOVER_HALT_ABORTED"} = $NDMP9_MOVER_HALT_ABORTED;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_HALT_INTERNAL_ERROR);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw($NDMP9_MOVER_HALT_INTERNAL_ERROR);
+
+$_mover_halt_reason_VALUES{"NDMP9_MOVER_HALT_INTERNAL_ERROR"} = $NDMP9_MOVER_HALT_INTERNAL_ERROR;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_HALT_CONNECT_ERROR);
+push @{$EXPORT_TAGS{"mover_halt_reason"}}, qw($NDMP9_MOVER_HALT_CONNECT_ERROR);
+
+$_mover_halt_reason_VALUES{"NDMP9_MOVER_HALT_CONNECT_ERROR"} = $NDMP9_MOVER_HALT_CONNECT_ERROR;
+
+#copy symbols in mover_halt_reason to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"mover_halt_reason"}};
+
+push @EXPORT_OK, qw(mover_pause_reason_to_strings);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw(mover_pause_reason_to_strings);
+
+my %_mover_pause_reason_VALUES;
+#Convert a flag value to a list of names for flags that are set.
+sub mover_pause_reason_to_strings {
+    my ($flags) = @_;
+    my @result = ();
+
+    for my $k (keys %_mover_pause_reason_VALUES) {
+       my $v = $_mover_pause_reason_VALUES{$k};
+
+       #is this a matching flag?
+       if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
+           push @result, $k;
+       }
+    }
+
+#by default, just return the number as a 1-element list
+    if (!@result) {
+       return ($flags);
+    }
+
+    return @result;
+}
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_NA);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_NA);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_NA"} = $NDMP9_MOVER_PAUSE_NA;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_EOM);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_EOM);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_EOM"} = $NDMP9_MOVER_PAUSE_EOM;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_EOF);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_EOF);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_EOF"} = $NDMP9_MOVER_PAUSE_EOF;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_SEEK);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_SEEK);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_SEEK"} = $NDMP9_MOVER_PAUSE_SEEK;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_MEDIA_ERROR);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_MEDIA_ERROR);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_MEDIA_ERROR"} = $NDMP9_MOVER_PAUSE_MEDIA_ERROR;
+
+push @EXPORT_OK, qw($NDMP9_MOVER_PAUSE_EOW);
+push @{$EXPORT_TAGS{"mover_pause_reason"}}, qw($NDMP9_MOVER_PAUSE_EOW);
+
+$_mover_pause_reason_VALUES{"NDMP9_MOVER_PAUSE_EOW"} = $NDMP9_MOVER_PAUSE_EOW;
+
+#copy symbols in mover_pause_reason to constants
+push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"mover_pause_reason"}};
+1;