X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=perl%2FAmanda%2FDevice.swg;h=479015d38da21ffffc025d1c39cf4cf2766c49b8;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=f044bfdcb84cc49db3dc6ca6b43f07c84eb0dad7;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/perl/Amanda/Device.swg b/perl/Amanda/Device.swg index f044bfd..479015d 100644 --- a/perl/Amanda/Device.swg +++ b/perl/Amanda/Device.swg @@ -30,6 +30,7 @@ #include "property.h" #include "fileheader.h" #include "glib-util.h" +#include "simpleprng.h" %} %init %{ @@ -65,30 +66,6 @@ set_sv_from_gvalue(GValue *value) case G_TYPE_UINT64: return sv_2mortal(amglue_newSVu64(g_value_get_uint64(value))); - - 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", (int)boxed_type); - - sv = sv_newmortal(); - sv_setsv(sv, &PL_sv_undef); - return sv; - } - } } /* simple types that can be constructed with sv_set*v */ @@ -255,29 +232,6 @@ typedef struct DirectTCPConnection { * Device struct, %extend-ed into a Perl class */ -typedef struct queue_fd_t { - /* Instance variables -- all readonly */ - %immutable; - int fd; - char *errmsg; - - %mutable; - - /* methods */ - %extend { - /* constructor */ - queue_fd_t(int fd) { - return queue_fd_new(fd, NULL); - } - - /* destructor */ - ~queue_fd_t() { - amfree(self->errmsg); - g_free(self); - } - } -} queue_fd_t; - %name(unaliased_name) extern char *device_unaliased_name(char *); typedef struct Device { @@ -338,11 +292,6 @@ typedef struct Device { return device_write_block(self, size, data); } - gboolean - write_from_fd(queue_fd_t *queue_fd) { - return device_write_from_fd(self, queue_fd); - } - gboolean finish_file() { return device_finish_file(self); @@ -363,10 +312,6 @@ typedef struct Device { return device_read_block(self, buffer, size); } - gboolean read_to_fd(queue_fd_t *queue_fd) { - return device_read_to_fd(self, queue_fd); - } - gboolean erase() { return device_erase(self); @@ -404,6 +349,21 @@ typedef struct Device { 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); @@ -467,10 +427,10 @@ 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 @@ -516,7 +476,11 @@ typedef struct Device { void property_get(DevicePropertyBase *pbase, GValue *out_val, PropertySurety *surety, PropertySource *source, gboolean *val_found) { - *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source); + if (pbase) { + *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source); + } else { + *val_found = FALSE; + } } /* delete typemaps */ @@ -626,6 +590,86 @@ sub new_rait_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 */ @@ -706,12 +750,6 @@ 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(PropertySurety); amglue_add_constant_short(PROPERTY_SURETY_BAD, "SURETY_BAD", PropertySurety); amglue_add_constant_short(PROPERTY_SURETY_GOOD, "SURETY_GOOD", PropertySurety);