lintian doesn't like orphan packages with uploaders...
[debian/amanda] / device-src / device.c
index 9af29f65708c6c2cdff78bf412af4eb5c73b6d2e..6eed5238e43fa14f973c55ebd9b540996a90685c 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
- * 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 program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -28,8 +29,6 @@
 #include <regex.h>
 
 #include "device.h"
-#include "queueing.h"
-#include "device-queueing.h"
 #include "property.h"
 
 #include "timestamp.h"
@@ -184,9 +183,6 @@ static void simple_property_free(SimpleProperty *o);
 static void default_device_open_device(Device * self, char * device_name,
                                    char * device_type, char * device_node);
 static gboolean default_device_configure(Device *self, gboolean use_global_config);
-static gboolean default_device_write_from_fd(Device *self,
-                                            queue_fd_t *queue_fd);
-static gboolean default_device_read_to_fd(Device *self, queue_fd_t *queue_fd);
 static gboolean default_device_property_get_ex(Device * self, DevicePropertyId id,
                                               GValue * val,
                                               PropertySurety *surety,
@@ -307,8 +303,6 @@ device_class_init (DeviceClass * device_class)
 
     device_class->open_device = default_device_open_device;
     device_class->configure = default_device_configure;
-    device_class->write_from_fd = default_device_write_from_fd;
-    device_class->read_to_fd = default_device_read_to_fd;
     device_class->property_get_ex = default_device_property_get_ex;
     device_class->property_set_ex = default_device_property_set_ex;
     g_object_class->finalize = device_finalize;
@@ -377,6 +371,11 @@ device_base_init (DeviceClass * device_class)
            PROPERTY_ACCESS_GET_MASK|PROPERTY_ACCESS_SET_MASK,
            device_simple_property_get_fn,
            device_simple_property_set_fn);
+
+    device_class_register_property(device_class, PROPERTY_LEOM,
+           PROPERTY_ACCESS_GET_MASK,
+           device_simple_property_get_fn,
+           device_simple_property_set_fn);
 }
 
 static void simple_property_free(SimpleProperty * resp) {
@@ -433,7 +432,7 @@ handle_device_regex(const char * user_name, char ** driver_name,
         *driver_name = stralloc("tape");
         *device = stralloc(user_name);
 #else /* !WANT_TAPE_DEVICE */
-       errmsg = newvstrallocf(errmsg, "\"%s\" is not a valid device name.\n", user_name);
+       *errmsg = newvstrallocf(*errmsg, "\"%s\" is not a valid device name.\n", user_name);
        regfree(&regex);
        return FALSE;
 #endif /* WANT_TAPE_DEVICE */
@@ -528,6 +527,7 @@ device_open (char * device_name)
     device = factory(device_name, device_type, device_node);
     g_assert(device != NULL); /* factories must always return a device */
 
+    device->device_mutex = g_mutex_new();
     amfree(device_type);
     amfree(device_node);
 
@@ -650,8 +650,8 @@ dumpfile_t * make_tapestart_header(Device * self, char * label,
     } else {
         self->volume_time = g_strdup(timestamp);
     }
-    strncpy(rval->datestamp, self->volume_time, sizeof(rval->datestamp));
-    strncpy(rval->name, label, sizeof(rval->name));
+    g_strlcpy(rval->datestamp, self->volume_time, sizeof(rval->datestamp));
+    g_strlcpy(rval->name, label, sizeof(rval->name));
 
     return rval;
 }
@@ -663,7 +663,7 @@ dumpfile_t * make_tapeend_header(void) {
     rval = malloc(sizeof(*rval));
     rval->type = F_TAPEEND;
     timestamp = get_timestamp_from_time(time(NULL));
-    strncpy(rval->datestamp, timestamp, sizeof(rval->datestamp));
+    g_strlcpy(rval->datestamp, timestamp, sizeof(rval->datestamp));
     amfree(timestamp);
     return rval;
 }
@@ -883,8 +883,12 @@ property_set_block_size_fn(
 
     g_assert(block_size >= 0); /* int -> gsize (unsigned) */
     if ((gsize)block_size < self->min_block_size
-       || (gsize)block_size > self->max_block_size)
+       || (gsize)block_size > self->max_block_size) {
+       device_set_error(self,
+           g_strdup_printf("Error setting BLOCK-SIZE property to '%zu', it must be between %zu and %zu", (gsize)block_size, self->min_block_size, self->max_block_size),
+           DEVICE_STATUS_DEVICE_ERROR);
        return FALSE;
+    }
 
     self->block_size = block_size;
     self->block_size_surety = surety;
@@ -1071,60 +1075,6 @@ device_property_get_list (Device * self)
     return DEVICE_GET_CLASS(self)->class_properties_list;
 }
 
-static gboolean
-default_device_read_to_fd(Device *self, queue_fd_t *queue_fd) {
-    GValue val;
-    StreamingRequirement streaming_mode;
-
-    if (device_in_error(self)) return FALSE;
-
-    /* Get the device's parameters */
-    bzero(&val, sizeof(val));
-    if (!device_property_get(self, PROPERTY_STREAMING, &val)
-       || !G_VALUE_HOLDS(&val, STREAMING_REQUIREMENT_TYPE)) {
-       streaming_mode = STREAMING_REQUIREMENT_REQUIRED;
-    } else {
-       streaming_mode = g_value_get_enum(&val);
-    }
-
-    return QUEUE_SUCCESS ==
-       do_consumer_producer_queue_full(
-           device_read_producer,
-           self,
-           fd_write_consumer,
-           queue_fd,
-           self->block_size,
-           DEFAULT_MAX_BUFFER_MEMORY,
-           streaming_mode);
-}
-
-static gboolean
-default_device_write_from_fd(Device *self, queue_fd_t *queue_fd) {
-    GValue val;
-    StreamingRequirement streaming_mode;
-
-    if (device_in_error(self)) return FALSE;
-
-    /* Get the device's parameters */
-    bzero(&val, sizeof(val));
-    if (!device_property_get(self, PROPERTY_STREAMING, &val)
-       || !G_VALUE_HOLDS(&val, STREAMING_REQUIREMENT_TYPE)) {
-       streaming_mode = STREAMING_REQUIREMENT_REQUIRED;
-    } else {
-       streaming_mode = g_value_get_enum(&val);
-    }
-
-    return QUEUE_SUCCESS ==
-       do_consumer_producer_queue_full(
-           fd_read_producer,
-           queue_fd,
-           device_write_consumer,
-           self,
-           self->block_size,
-           DEFAULT_MAX_BUFFER_MEMORY,
-           streaming_mode);
-}
-
 /* XXX WARNING XXX
  * All the functions below this comment are stub functions that do nothing
  * but implement the virtual function table. Call these functions and they
@@ -1168,6 +1118,46 @@ device_finish (Device * self) {
     return (klass->finish)(self);
 }
 
+guint64
+device_get_bytes_read (Device * self) {
+    DeviceClass *klass;
+    guint64 bytes = 0;
+
+    g_assert(IS_DEVICE (self));
+
+    g_mutex_lock(self->device_mutex);
+    if (self->in_file) {
+       klass = DEVICE_GET_CLASS(self);
+       if (klass->get_bytes_read) {
+           bytes = (klass->get_bytes_read)(self);
+       } else {
+           bytes = self->bytes_read;
+       }
+    }
+    g_mutex_unlock(self->device_mutex);
+    return bytes;
+}
+
+guint64
+device_get_bytes_written (Device * self) {
+    DeviceClass *klass;
+    guint64 bytes = 0;
+
+    g_assert(IS_DEVICE (self));
+
+    g_mutex_lock(self->device_mutex);
+    if (self->in_file) {
+       klass = DEVICE_GET_CLASS(self);
+       if (klass->get_bytes_written) {
+           bytes = (klass->get_bytes_written)(self);
+       } else {
+           bytes = self->bytes_written;
+       }
+    }
+    g_mutex_unlock(self->device_mutex);
+    return bytes;
+}
+
 gboolean
 device_configure (Device * self, gboolean use_global_config)
 {
@@ -1241,20 +1231,6 @@ device_write_block (Device * self, guint size, gpointer block)
     return (*klass->write_block)(self,size, block);
 }
 
-gboolean
-device_write_from_fd (Device * self, queue_fd_t * queue_fd)
-{
-    DeviceClass *klass;
-
-    g_assert(IS_DEVICE (self));
-    g_assert(queue_fd->fd >= 0);
-    g_assert(IS_WRITABLE_ACCESS_MODE(self->access_mode));
-
-    klass = DEVICE_GET_CLASS(self);
-    g_assert(klass->write_from_fd);
-    return (klass->write_from_fd)(self,queue_fd);
-}
-
 gboolean
 device_start_file (Device * self, dumpfile_t * jobInfo) {
     DeviceClass * klass;
@@ -1329,21 +1305,6 @@ device_read_block (Device * self, gpointer buffer, int * size)
     return (klass->read_block)(self,buffer,size);
 }
 
-gboolean
-device_read_to_fd (Device * self, queue_fd_t *queue_fd)
-{
-    DeviceClass *klass;
-
-    g_assert(IS_DEVICE (self));
-    g_assert(queue_fd->fd >= 0);
-    g_assert(self->access_mode == ACCESS_READ);
-
-    klass = DEVICE_GET_CLASS(self);
-    g_assert(klass->read_to_fd);
-    return (klass->read_to_fd)(self,queue_fd);
-}
-
-
 gboolean
 device_property_get_ex(
        Device * self,
@@ -1453,31 +1414,60 @@ device_listen(
     }
 }
 
-gboolean
+int
 device_accept(
     Device *self,
     DirectTCPConnection **conn,
-    ProlongProc prolong,
-    gpointer prolong_data)
+    int    *cancelled,
+    GMutex *abort_mutex,
+    GCond  *abort_cond)
 {
     DeviceClass *klass;
 
     klass = DEVICE_GET_CLASS(self);
     if(klass->accept) {
-       return (klass->accept)(self, conn, prolong, prolong_data);
+       return (klass->accept)(self, conn, cancelled, abort_mutex, abort_cond);
     } else {
        device_set_error(self,
-           stralloc(_("Unimplemented method")),
+           g_strdup(_("Unimplemented method")),
            DEVICE_STATUS_DEVICE_ERROR);
-       return FALSE;
+       return 1;
     }
 }
 
-gboolean
+
+int
+device_connect(
+    Device *self,
+    gboolean for_writing,
+    DirectTCPAddr *addrs,
+    DirectTCPConnection **conn,
+    int    *cancelled,
+    GMutex *abort_mutex,
+    GCond  *abort_cond)
+{
+    DeviceClass *klass;
+
+    klass = DEVICE_GET_CLASS(self);
+    if(klass->connect) {
+       return (klass->connect)(self, for_writing, addrs, conn, cancelled,
+                               abort_mutex, abort_cond);
+    } else {
+       device_set_error(self,
+           g_strdup(_("Unimplemented method")),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return 1;
+    }
+}
+
+int
 device_write_from_connection(
     Device *self,
     guint64 size,
-    guint64 *actual_size)
+    guint64 *actual_size,
+    int    *cancelled,
+    GMutex *abort_mutex,
+    GCond  *abort_cond)
 {
     DeviceClass *klass;
 
@@ -1487,20 +1477,25 @@ device_write_from_connection(
     g_assert(IS_WRITABLE_ACCESS_MODE(self->access_mode));
 
     if(klass->write_from_connection) {
-       return (klass->write_from_connection)(self, size, actual_size);
+       return (klass->write_from_connection)(self, size, actual_size,
+                                             cancelled,
+                                             abort_mutex, abort_cond);
     } else {
        device_set_error(self,
            stralloc(_("Unimplemented method")),
            DEVICE_STATUS_DEVICE_ERROR);
-       return FALSE;
+       return 1;
     }
 }
 
-gboolean
+int
 device_read_to_connection(
     Device *self,
     guint64 size,
-    guint64 *actual_size)
+    guint64 *actual_size,
+    int    *cancelled,
+    GMutex *abort_mutex,
+    GCond  *abort_cond)
 {
     DeviceClass *klass;
 
@@ -1509,12 +1504,13 @@ device_read_to_connection(
 
     klass = DEVICE_GET_CLASS(self);
     if(klass->read_to_connection) {
-       return (klass->read_to_connection)(self, size, actual_size);
+       return (klass->read_to_connection)(self, size, actual_size,
+                                          cancelled, abort_mutex, abort_cond);
     } else {
        device_set_error(self,
            stralloc(_("Unimplemented method")),
            DEVICE_STATUS_DEVICE_ERROR);
-       return FALSE;
+       return 1;
     }
 }