X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=perl%2FAmanda%2FDevice.swg;h=d40031605f9bbb5955f3b74857ced43ba0212182;hb=c6f0a88c567f8536c498f554285aed1f8150da18;hp=73aac3137fd8f920a5d43d2e6664e4e909dfe4b3;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/perl/Amanda/Device.swg b/perl/Amanda/Device.swg index 73aac31..d400316 100644 --- a/perl/Amanda/Device.swg +++ b/perl/Amanda/Device.swg @@ -1,156 +1,38 @@ /* - * Copyright (c) Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. * - * This library is distributed in the hope that it will be useful, but + * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120 + * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com */ %module "Amanda::Device" %include "amglue/amglue.swg" %include "exception.i" +%import "Amanda/Header.swg"; + +%include "Amanda/Device.pod" %{ #include "device.h" #include "property.h" #include "fileheader.h" -%} - -/* import dumptype_t, among others */ -%import "Amanda/Types.swg"; - -%perlcode %{ -=head1 NAME - -Amanda::Device - interact with Amanda data-storage devices - -=head1 SYNOPSIS - - use Amanda::Device qw( :constants ); - - my $dev = Amanda::Device->new($device_name); - $dev->set_startup_properties_from_config(); - if ($dev->read_label() == $READ_LABEL_STATUS_SUCCESS) { - print "Label on $device_name is '$dev->volume_label'\n"; - } - -See http://wiki.zmanda.com/index.php/Device_API for details on how Devices are used. - -=head1 API STATUS - -Stable - -=head1 Amanda::Device Objects - -=head2 Instance Variables - -=over - -=item C<$file> - -=item C<$block> - -=item C<$in_file> - -=item C<$device_name> - -=item C<$access_mode> - -=item C<$is_eof> - -=item C<$volume_label> - -=item C<$volume_time> - -=back - -=head2 Methods - -See the wiki for descriptions of these functions - -=over - -=item C - -=item C - -=item C - -=item C - -where C<$jobinfo> is a C (see L) - -=item C - -=item C - -=item C - -=item C - -Note that Perl code is not expected to handle on-device data, so there -is currently no way to provide data to this function from Perl. This may -change in future revisions. - -=item C - -where C<$fd> is an integer file descriptor, not a filehandle - -=item C - -=item C - -=item C - -=item C - -=item C - -where C<$fd> is an integer file descriptor, not a filehandle - -Note that Perl code is not expected to handle on-device data, so there -is currently no way to access the data this function returns. This may -change in future revisions. - -=item C - -returns a list of property names. - -=item C - -returns the property as the appropriate Perl type. - -=item C - -where $value is of an appropriate type for the given property - -=item C - -=item C - -=back - -=head1 CONSTANTS - -This module defines a large number of constants. Again, consult the -wiki or C for the details on their meaning. These constants -are available from the package namespace (e.g., -C), of imported with the C<:constant> -import tag. - -=cut +#include "glib-util.h" +#include "simpleprng.h" +#include "amanda.h" +#include "sockaddr-util.h" %} %init %{ @@ -162,6 +44,11 @@ import tag. /* Utility functions for typemaps, below */ +/* return a new, mortal SV corresponding to the given GValue + * + * @param value: the value to convert + * @returns: a new, mortal SV + */ static SV * set_sv_from_gvalue(GValue *value) { @@ -171,44 +58,16 @@ set_sv_from_gvalue(GValue *value) /* complex reference types */ switch (fundamental) { case G_TYPE_LONG: - sv = sv_2mortal(amglue_newSVi64(g_value_get_long(value))); - break; + return sv_2mortal(amglue_newSVi64(g_value_get_long(value))); case G_TYPE_ULONG: - sv = sv_2mortal(amglue_newSVu64(g_value_get_ulong(value))); - break; + return sv_2mortal(amglue_newSVu64(g_value_get_ulong(value))); case G_TYPE_INT64: - sv = sv_2mortal(amglue_newSVi64(g_value_get_int64(value))); - break; + return sv_2mortal(amglue_newSVi64(g_value_get_int64(value))); case G_TYPE_UINT64: - sv = sv_2mortal(amglue_newSVu64(g_value_get_uint64(value))); - break; - - case G_TYPE_BOXED: { - GType boxed_type = G_VALUE_TYPE(value); - QualifiedSize qs; - HV *hv; - - if (boxed_type == QUALIFIED_SIZE_TYPE) { - qs = *(QualifiedSize*)(g_value_get_boxed(value)); - - /* build a hash */ - hv = (HV *)sv_2mortal((SV *)newHV()); - hv_store(hv, "accuracy", 8, newSViv(qs.accuracy), 0); - hv_store(hv, "bytes", 5, amglue_newSVi64(qs.bytes), 0); - - sv = newRV((SV *)hv); - return newRV((SV *)hv); - } else { - warn("Unsupported boxed property type #%d", boxed_type); - - sv = sv_newmortal(); - sv_setsv(sv, &PL_sv_undef); - return sv; - } - } + return sv_2mortal(amglue_newSVu64(g_value_get_uint64(value))); } /* simple types that can be constructed with sv_set*v */ @@ -260,7 +119,7 @@ set_sv_from_gvalue(GValue *value) case G_TYPE_INTERFACE: case G_TYPE_OBJECT: case G_TYPE_PARAM: - warn("Unsupported fundamental property type #%d", fundamental); + warn("Unsupported fundamental property type #%d", (int)fundamental); sv_setsv(sv, &PL_sv_undef); break; } @@ -268,106 +127,116 @@ set_sv_from_gvalue(GValue *value) return sv; } +/* Given an SV and an initialized GValue, set the GValue to the value + * represented by the SV. The GValue's type must already be set. + * + * For basic corresponding types (string -> string, integer -> integer), + * the translation is straightforward. However, if the GValue is not a + * string, but the SV has a string value, then g_value_set_from_string will + * be used to parse the string. + * + * @param sv: SV to convert + * @param value: (input/output) destination + * @returns: TRUE on success + */ static gboolean set_gvalue_from_sv(SV *sv, GValue *value) { GType fundamental = G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value)); - switch (fundamental) { - case G_TYPE_CHAR: - if (!SvIOK(sv)) return FALSE; - g_value_set_char(value, SvIV(sv)); - break; - case G_TYPE_UCHAR: - if (!SvIOK(sv)) return FALSE; - g_value_set_uchar(value, SvUV(sv)); - break; + /* if we got a string, use g_value_set_from_string to parse any funny + * values or suffixes */ + if (SvPOK(sv)) { + if (g_value_set_from_string(value, SvPV_nolen(sv))) + return TRUE; + } + /* otherwise, handle numeric types with SvIV, SvNV, or the amglue_* functions */ + switch (fundamental) { case G_TYPE_BOOLEAN: - if (!SvIOK(sv)) return FALSE; g_value_set_boolean(value, SvIV(sv)); - break; + return TRUE; + + case G_TYPE_CHAR: + g_value_set_char(value, amglue_SvI8(sv)); + return TRUE; + + case G_TYPE_UCHAR: + g_value_set_uchar(value, amglue_SvU8(sv)); + return TRUE; case G_TYPE_INT: g_value_set_int(value, amglue_SvI32(sv)); - break; + return TRUE; case G_TYPE_UINT: g_value_set_uint(value, amglue_SvU32(sv)); - break; + return TRUE; case G_TYPE_LONG: g_value_set_int64(value, amglue_SvI64(sv)); - break; + return TRUE; case G_TYPE_ULONG: g_value_set_uint64(value, amglue_SvU64(sv)); - break; + return TRUE; case G_TYPE_INT64: g_value_set_int64(value, amglue_SvI64(sv)); - break; + return TRUE; case G_TYPE_UINT64: g_value_set_uint64(value, amglue_SvU64(sv)); - break; + return TRUE; case G_TYPE_FLOAT: - if (!SvNOK(sv)) return FALSE; g_value_set_float(value, SvNV(sv)); - break; + return TRUE; case G_TYPE_DOUBLE: - if (!SvNOK(sv)) return FALSE; g_value_set_double(value, SvNV(sv)); - break; - - case G_TYPE_STRING: - if (!SvPOK(sv)) return FALSE; - g_value_set_string(value, SvPV_nolen(sv)); - break; + return TRUE; - case G_TYPE_ENUM: - if (!SvIOK(sv)) return FALSE; + case G_TYPE_ENUM: g_value_set_enum(value, SvIV(sv)); - break; + return TRUE; case G_TYPE_FLAGS: - if (!SvIOK(sv)) return FALSE; g_value_set_flags(value, SvIV(sv)); - break; + return TRUE; - /* Unsupported */ default: - case G_TYPE_POINTER: - case G_TYPE_INTERFACE: - case G_TYPE_BOXED: /* note: *getting* boxed values is supported */ - case G_TYPE_OBJECT: - case G_TYPE_PARAM: - return FALSE; + /* for anything else, let perl stringify it for us and try parsing it */ + return g_value_set_from_string(value, SvPV_nolen(sv)); } - - return TRUE; } %} +/* + * DirectTCPConnection object + */ + +typedef struct DirectTCPConnection { + %extend { + ~DirectTCPConnection() { + g_object_unref(self); + }; + + %newobject close; + char *close() { + return directtcp_connection_close(self); + } + }; +} DirectTCPConnection; + /* * Device struct, %extend-ed into a Perl class */ +%name(unaliased_name) extern char *device_unaliased_name(char *); + typedef struct Device { - /* Instance variables -- all readonly */ - %immutable; - int file; - guint64 block; - gboolean in_file; - char * device_name; - DeviceAccessMode access_mode; - gboolean is_eof; - char * volume_label; - char * volume_time; - %mutable; /* methods */ %extend { @@ -380,7 +249,27 @@ typedef struct Device { g_object_unref(self); } - ReadLabelStatusFlags + gboolean + configure(gboolean use_global_config) { + return device_configure(self, use_global_config); + } + + char * + error() { + return device_error(self); + } + + char * + status_error() { + return device_status_error(self); + } + + char * + error_or_status() { + return device_error_or_status(self); + } + + DeviceStatusFlags read_label() { return device_read_label(self); } @@ -396,33 +285,13 @@ typedef struct Device { } gboolean - start_file(const dumpfile_t *jobInfo) { + start_file(dumpfile_t *jobInfo) { return device_start_file(self, jobInfo); } - guint - write_min_size() { - return device_write_min_size(self); - } - - guint - write_max_size() { - return device_write_max_size(self); - } - - guint - read_max_size() { - return device_read_max_size(self); - } - gboolean - write_block(guint size, gpointer data, gboolean short_block) { - return device_write_block(self, size, data, short_block); - } - - gboolean - write_from_fd(int fd) { - return device_write_from_fd(self, fd); + write_block(guint size, gpointer data) { + return device_write_block(self, size, data); } gboolean @@ -445,34 +314,113 @@ typedef struct Device { return device_read_block(self, buffer, size); } - gboolean read_to_fd(int fd) { - return device_read_to_fd(self, fd); + gboolean + erase() { + return device_erase(self); + } + + gboolean + eject() { + return device_eject(self); + } + + gboolean + directtcp_supported() { + return device_directtcp_supported(self); + } + + void + listen(gboolean for_writing, DirectTCPAddr **addrs) { + /* ensure that the addresses are empty if there was an error */ + if (!device_listen(self, for_writing, addrs)) + *addrs = NULL; + } + + %newobject accept; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + accept() { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_accept(self, &conn, NULL, NULL); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + + %newobject connect; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + connect(gboolean for_writing, DirectTCPAddr *addrs) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_connect(self, for_writing, addrs, &conn, NULL, NULL); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + + gboolean + use_connection(DirectTCPConnection *conn) { + return device_use_connection(self, conn); + } + + %typemap(in,numinputs=0) guint64 *actual_size (guint64 sz) { + sz = 0; + $1 = &sz; + } + %typemap(argout) guint64 *actual_size { + SP += argvi; PUTBACK; + $result = sv_2mortal(amglue_newSVu64(*$1)); + SPAGAIN; SP -= argvi; argvi++; + } + gboolean + write_from_connection(guint64 size, guint64 *actual_size) { + return device_write_from_connection(self, size, actual_size); + } + + gboolean + read_to_connection(guint64 size, guint64 *actual_size) { + return device_read_to_connection(self, size, actual_size); } - %typemap(out) const DeviceProperty * { - int i = 0; - int len = 0; + %typemap(out) const GSList * { + GSList *iter; /* Count the DeviceProperties */ - while ($1[len].base) len++; - EXTEND(SP, len); /* make room for return values */ + EXTEND(SP, g_slist_length($1)); /* make room for return values */ /* Note that we set $result several times. the nature of * SWIG's wrapping is such that incrementing argvi points * $result to the next location in perl's argument stack. */ - for (i = 0; i < len ; i++) { - $result = sv_newmortal(); - sv_setpv($result, $1[i].base->name); + for (iter = $1; iter; iter = g_slist_next(iter)) { + DeviceProperty *prop = iter->data; + HV *hash = newHV(); + SV *rv = newRV_noinc((SV *)hash); + + hv_store(hash, "name", 4, + newSVpv(prop->base->name, 0), 0); + hv_store(hash, "description", 11, + newSVpv(prop->base->description, 0), 0); + hv_store(hash, "access", 6, + newSViv(prop->access), 0); + $result = sv_2mortal(rv); argvi++; - }; + } } - const DeviceProperty * property_list(void) { + const GSList * property_list(void) { return device_property_get_list(self); } - %typemap(out) const DeviceProperty *; /* remove typemap */ + %typemap(out) const GSList *; /* remove typemap */ /* A typemap to convert a property name to a DevicePropertyBase. */ %typemap(in) DevicePropertyBase * { @@ -481,40 +429,60 @@ typedef struct Device { if (SvPOK($input)) pname = SvPV_nolen($input); - if (pname) $1 = (DevicePropertyBase *)device_property_get_by_name(pname); - if (!pname || !$1) { - SWIG_exception_fail(SWIG_ValueError, "Invalid property name"); - } + if (pname) + $1 = (DevicePropertyBase *)device_property_get_by_name(pname); + else + $1 = NULL; } /* A typemap to convert the GValue in property_get to a return value. The * (in) typemap sets up storage for the parameters, while the (argout) converts * them to a perl SV. */ - %typemap(in,numinputs=0) (GValue *out_val, gboolean *val_found) - (GValue val, gboolean found) { + %typemap(in,numinputs=0) (GValue *out_val, PropertySurety *surety, + PropertySource *source, gboolean *val_found) + (GValue val, + PropertySurety surety, + PropertySource source, + gboolean found) { memset(&val, 0, sizeof(val)); $1 = &val; - $2 = &found; + if (GIMME_V == G_ARRAY) { + $2 = &surety; + $3 = &source; + } + $4 = &found; } - %typemap(argout) (GValue *out_val, gboolean *val_found) { + %typemap(argout) (GValue *out_val, PropertySurety *surety, + PropertySource *source, gboolean *val_found) { /* if the result is valid */ - if (*$2) { - /* move data from $1 to $result, somehow */ + if (*$4) { + /* move data from $1 to $result, somehow, being careful to + * save the perl stack while doing so */ + SP += argvi; PUTBACK; $result = set_sv_from_gvalue($1); + SPAGAIN; SP -= argvi; argvi++; /* free any memory for the GValue */ g_value_unset($1); - } else { - /* silently return 'undef', the sentinel for "undefined" */ - $result = sv_newmortal(); - sv_setsv($result, &PL_sv_undef); + + if (GIMME_V == G_ARRAY) { + $result = newSViv(*$2); + argvi++; + $result = newSViv(*$3); + argvi++; + } } - argvi++; + /* otherwise, return nothing */ } void - property_get(DevicePropertyBase *pbase, GValue *out_val, gboolean *val_found) { - *val_found = device_property_get(self, pbase->ID, out_val); + property_get(DevicePropertyBase *pbase, GValue *out_val, PropertySurety *surety, + PropertySource *source, gboolean *val_found) { + if (pbase) { + *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source); + } else { + *val_found = FALSE; + } } /* delete typemaps */ @@ -529,12 +497,35 @@ typedef struct Device { gboolean property_set(DevicePropertyBase *pbase, SV *sv) { GValue gval; + + if (!pbase) + goto fail; memset(&gval, 0, sizeof(gval)); g_value_init(&gval, pbase->type); if (!set_gvalue_from_sv(sv, &gval)) - goto fail; + goto failunset; if (!device_property_set(self, pbase->ID, &gval)) + goto failunset; + + g_value_unset(&gval); + return TRUE; + failunset: + g_value_unset(&gval); + fail: + return FALSE; + } + + gboolean + property_set_ex(DevicePropertyBase *pbase, SV *sv, + PropertySurety surety, PropertySource source) { + GValue gval; + memset(&gval, 0, sizeof(gval)); + g_value_init(&gval, pbase->type); + if (!set_gvalue_from_sv(sv, &gval)) + goto fail; + + if (!device_property_set_ex(self, pbase->ID, &gval, surety, source)) goto fail; g_value_unset(&gval); @@ -547,13 +538,145 @@ typedef struct Device { gboolean recycle_file(guint filenum) { return device_recycle_file(self, filenum); } - - void set_startup_properties_from_config(void) { - device_set_startup_properties_from_config(self); - } + + /* accessor functions */ + + int file(void) { return self->file; } + guint64 block(void) { return self->block; } + gboolean in_file(void) { return self->in_file; } + char * device_name(void) { return self->device_name; } + DeviceAccessMode access_mode(void) { return self->access_mode; } + gboolean is_eof(void) { return self->is_eof; } + gboolean is_eom(void) { return self->is_eom; } + char * volume_label(void) { return self->volume_label; } + char * volume_time(void) { return self->volume_time; } + DeviceStatusFlags status(void) { return self->status; } + gsize min_block_size(void) { return self->min_block_size; } + gsize max_block_size(void) { return self->max_block_size; } + gsize block_size(void) { return self->block_size; } + gsize header_block_size(void) { return self->header_block_size; } + dumpfile_t *volume_header(void) { return self->volume_header; } }; + } Device; +/* An alternate constructor for RAIT devices */ +%typemap(in) GSList *child_devices { + AV *av; + int i, len; + + if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV) { + SWIG_exception(SWIG_TypeError, "Expected an arrayref"); + } + av = (AV *)SvRV($input); + + $1 = NULL; + len = av_len(av); + for (i = 0; i <= len; i++) { + SV **elt = av_fetch(av, i, 0); + Device *d; + + if (elt && !SvOK(*elt)) { + $1 = g_slist_append($1, NULL); /* 'undef' => NULL */ + } else if (!elt || SWIG_ConvertPtr(*elt, (void **)&d, $descriptor(Device *), 0) == -1) { + SWIG_exception(SWIG_TypeError, "array member is not a Device"); + } else { + $1 = g_slist_append($1, d); + } + } +} +%typemap(freearg) GSList *child_devices { + g_slist_free($1); +} +%newobject rait_device_open_from_children; +Device *rait_device_open_from_children(GSList *child_devices); +%perlcode %{ +sub new_rait_from_children { + my $class = shift; # strip the $class from the arguments + return rait_device_open_from_children([@_]); +} +%} + +/* + * Utilities for installchecks (not described in POD) + */ + +%inline %{ + +/* write LENGTH bytes of random data to FILENAME, seeded with SEED */ +gboolean +write_random_to_device(guint32 seed, size_t length, Device *device) { + simpleprng_state_t prng; + char *buf; + gsize block_size = device->block_size; + g_assert(block_size < G_MAXUINT); + + buf = g_malloc(block_size); + simpleprng_seed(&prng, seed); + + while (length) { + size_t to_write = min(block_size, length); + + simpleprng_fill_buffer(&prng, buf, to_write); + if (!device_write_block(device, (guint)block_size, buf)) { + g_free(buf); + return FALSE; + } + length -= to_write; + } + + g_free(buf); + return TRUE; +} + +/* read LENGTH bytes of random data from FILENAME verifying it against + * a PRNG seeded with SEED. Sends any error messages to stderr. + */ +gboolean +verify_random_from_device(guint32 seed, size_t length, Device *device) { + simpleprng_state_t prng; + char *buf = NULL; /* first device_read_block will get the size */ + int block_size = 0; + + simpleprng_seed(&prng, seed); + + while (length) { + int bytes_read; + int size = block_size; + + bytes_read = device_read_block(device, buf, &size); + if (bytes_read == 0 && size > block_size) { + g_free(buf); + block_size = size; + buf = g_malloc(block_size); + continue; + } + if (bytes_read == -1) { + if (device->status == DEVICE_STATUS_SUCCESS) { + g_assert(device->is_eof); + g_debug("verify_random_from_device got unexpected EOF"); + } + goto error; + } + + /* strip padding */ + bytes_read = min(bytes_read, length); + + if (!simpleprng_verify_buffer(&prng, buf, bytes_read)) + goto error; + + length -= bytes_read; + } + + g_free(buf); + return TRUE; + +error: + g_free(buf); + return FALSE; +} +%} + /* * Constants */ @@ -569,15 +692,15 @@ gboolean IS_WRITABLE_ACCESS_MODE(DeviceAccessMode mode); amglue_export_tag(DeviceAccessMode, IS_WRITABLE_ACCESS_MODE); amglue_copy_to_tag(DeviceAccessMode, constants); -amglue_add_flag_tag_fns(ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_SUCCESS, "SUCCESS", ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_DEVICE_MISSING, "DEVICE_MISSING", ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_DEVICE_ERROR, "DEVICE_ERROR", ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_VOLUME_MISSING, "VOLUME_MISSING", ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_VOLUME_UNLABELED, "VOLUME_UNLABELED", ReadLabelStatusFlags); -amglue_add_constant_short(READ_LABEL_STATUS_VOLUME_ERROR, "VOLUME_ERROR", ReadLabelStatusFlags); -amglue_add_constant_noshort(READ_LABEL_STATUS_FLAGS_MAX, ReadLabelStatusFlags); -amglue_copy_to_tag(ReadLabelStatusFlags, constants); +amglue_add_flag_tag_fns(DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_SUCCESS, "SUCCESS", DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_DEVICE_ERROR, "DEVICE_ERROR", DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_DEVICE_BUSY, "DEVICE_BUSY", DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_VOLUME_MISSING, "VOLUME_MISSING", DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_VOLUME_UNLABELED, "VOLUME_UNLABELED", DeviceStatusFlags); +amglue_add_constant_short(DEVICE_STATUS_VOLUME_ERROR, "VOLUME_ERROR", DeviceStatusFlags); +amglue_add_constant_noshort(DEVICE_STATUS_FLAGS_MAX, DeviceStatusFlags); +amglue_copy_to_tag(DeviceStatusFlags, constants); amglue_add_flag_tag_fns(PropertyPhaseFlags); amglue_add_constant_short(PROPERTY_PHASE_BEFORE_START, "BEFORE_START", PropertyPhaseFlags); @@ -591,25 +714,25 @@ amglue_add_constant_noshort(PROPERTY_PHASE_SHIFT, PropertyPhaseFlags); amglue_copy_to_tag(PropertyPhaseFlags, constants); amglue_add_flag_tag_fns(PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_GET_BEFORE_START, +amglue_add_constant_short(PROPERTY_ACCESS_GET_BEFORE_START, "GET_BEFORE_START", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE, +amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE, "GET_BETWEEN_FILE_WRITE", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE, +amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE, "GET_INSIDE_FILE_WRITE", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_READ, +amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_READ, "GET_BETWEEN_FILE_READ", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_READ, +amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_READ, "GET_INSIDE_FILE_READ", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_SET_BEFORE_START, +amglue_add_constant_short(PROPERTY_ACCESS_SET_BEFORE_START, "SET_BEFORE_START", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE, +amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE, "SET_BETWEEN_FILE_WRITE", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE, +amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE, "SET_INSIDE_FILE_WRITE", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_READ, +amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_READ, "SET_BETWEEN_FILE_READ", PropertyAccessFlags); -amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_READ, +amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_READ, "SET_INSIDE_FILE_READ", PropertyAccessFlags); amglue_add_constant_noshort(PROPERTY_ACCESS_GET_MASK, PropertyAccessFlags); amglue_add_constant_noshort(PROPERTY_ACCESS_SET_MASK, PropertyAccessFlags); @@ -634,33 +757,20 @@ amglue_add_constant_short(MEDIA_ACCESS_MODE_READ_WRITE, "READ_WRITE", MediaAcces amglue_add_constant_short(MEDIA_ACCESS_MODE_WRITE_ONLY, "WRITE_ONLY", MediaAccessMode); amglue_copy_to_tag(MediaAccessMode, constants); -amglue_add_enum_tag_fns(SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_UNKNOWN, "UNKNOWN", SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_ESTIMATE, "ESTIMATE", SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_REAL, "REAL", SizeAccuracy); -amglue_copy_to_tag(SizeAccuracy, constants); - -amglue_add_flag_tag_fns(FeatureSupportFlags); -amglue_add_constant_short(FEATURE_STATUS_ENABLED, "STATUS_ENABLED", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_STATUS_DISABLED, "STATUS_DISABLED", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_SURETY_BAD, "SURETY_BAD", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_SURETY_GOOD, "SURETY_GOOD", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_SOURCE_DEFAULT, "SOURCE_DEFAULT", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_SOURCE_DETECTED, "SOURCE_DETECTED", FeatureSupportFlags); -amglue_add_constant_short(FEATURE_SOURCE_USER, "SOURCE_USER", FeatureSupportFlags); -amglue_add_constant_noshort(FEATURE_SUPPORT_FLAGS_MAX, FeatureSupportFlags); -amglue_add_constant_noshort(FEATURE_SUPPORT_FLAGS_MASK, FeatureSupportFlags); -amglue_add_constant_noshort(FEATURE_SUPPORT_FLAGS_STATUS_MASK, FeatureSupportFlags); -amglue_add_constant_noshort(FEATURE_SUPPORT_FLAGS_SURETY_MASK, FeatureSupportFlags); -amglue_add_constant_noshort(FEATURE_SUPPORT_FLAGS_SOURCE_MASK, FeatureSupportFlags); - -gboolean feature_support_flags_is_valid(FeatureSupportFlags); -amglue_export_tag(FeatureSupportFlags, feature_support_flags_is_valid); -amglue_copy_to_tag(FeatureSupportFlags, constants); +amglue_add_flag_tag_fns(PropertySurety); +amglue_add_constant_short(PROPERTY_SURETY_BAD, "SURETY_BAD", PropertySurety); +amglue_add_constant_short(PROPERTY_SURETY_GOOD, "SURETY_GOOD", PropertySurety); +amglue_copy_to_tag(PropertySurety, constants); + +amglue_add_flag_tag_fns(PropertySource); +amglue_add_constant_short(PROPERTY_SOURCE_DEFAULT, "SOURCE_DEFAULT", PropertySource); +amglue_add_constant_short(PROPERTY_SOURCE_DETECTED, "SOURCE_DETECTED", PropertySource); +amglue_add_constant_short(PROPERTY_SOURCE_USER, "SOURCE_USER", PropertySource); +amglue_copy_to_tag(PropertySource, constants); %perlcode %{ -# SWIG produces a sub-package for the Device "class", in this case named +# SWIG produces a sub-package for the Device "class", in this case named # Amanda::Device::Device. For user convenience, we allow Amanda::Device->new(..) to # do the same thing. This is a wrapper function, and not just a typeglob assignment, # because we want to get the right blessing.