⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2005 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 library 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. *  * 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. *  * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com *//* The Device API abstracts device workings, interaction, properties, and * capabilities from the rest of the Amanda code base. It supports * pluggable modules for different kinds of devices. */#include "amanda.h"#include "conffile.h"#include <regex.h>#include "device.h"#include "queueing.h"#include "property.h"#include "null-device.h"#include "timestamp.h"#include "vfs-device.h"#include "util.h"#ifdef WANT_TAPE_DEVICE#include "tape-device.h"#endif#include "rait-device.h"#ifdef WANT_S3_DEVICE  #include "s3-device.h"#endifstatic GHashTable* driverList = NULL;void device_api_init(void) {    g_type_init();    amanda_thread_init();    device_property_init();    driverList = g_hash_table_new(g_str_hash, g_str_equal);    /* register other types and devices. */    null_device_register();    vfs_device_register();#ifdef WANT_TAPE_DEVICE    tape_device_register();#endif    rait_device_register();#ifdef WANT_S3_DEVICE    s3_device_register();#endif}void register_device(DeviceFactory factory,                     const char ** device_prefix_list) {    char ** tmp;    g_assert(driverList != NULL);    g_assert(factory != NULL);    g_return_if_fail(device_prefix_list != NULL);    g_return_if_fail(*device_prefix_list != NULL);    tmp = (char**)device_prefix_list;    while (*tmp != NULL) {        g_hash_table_insert(driverList, *tmp, (gpointer)factory);        tmp ++;    }}static DeviceFactory lookup_device_factory(const char *device_name) {    gpointer key, value;    g_assert(driverList != NULL);    if (g_hash_table_lookup_extended(driverList, device_name, &key, &value)) {        return (DeviceFactory)value;    } else {        return NULL;    }}static const GFlagsValue read_label_status_flags_values[] = {    { READ_LABEL_STATUS_SUCCESS,      "READ_LABEL_STATUS_SUCCESS",      "Success" },    { READ_LABEL_STATUS_DEVICE_MISSING,      "READ_LABEL_STATUS_DEVICE_MISSING",      "Device not found" },    { READ_LABEL_STATUS_DEVICE_ERROR,      "READ_LABEL_STATUS_DEVICE_ERROR",      "Device error" },    { READ_LABEL_STATUS_VOLUME_MISSING,      "READ_LABEL_STATUS_VOLUME_MISSING",      "Volume not found" },    { READ_LABEL_STATUS_VOLUME_UNLABELED,      "READ_LABEL_STATUS_VOLUME_UNLABELED",      "Volume not labeled" },    { READ_LABEL_STATUS_VOLUME_ERROR,      "READ_LABEL_STATUS_VOLUME_ERROR",      "Volume error" },    { 0, NULL, NULL }};GType read_label_status_flags_get_type(void) {    static GType type = 0;    if (G_UNLIKELY(type == 0)) {        type = g_flags_register_static("ReadLabelStatusFlags",                                       read_label_status_flags_values);    }    return type;}/* Device class definition starts here. */struct DevicePrivate_s {    /* This is the return value of the device_get_property_list()       method. */    GArray *property_list;    GHashTable * property_response;};/* This holds the default response to a particular property. */typedef struct {    PropertyAccessFlags access;    GValue response;} PropertyResponse;#define selfp (self->private)/* here are local prototypes, so we can make function pointers. */static void device_init (Device * o) G_GNUC_UNUSED;static void device_class_init (DeviceClass * c) G_GNUC_UNUSED;static void property_response_free(PropertyResponse *o);static gboolean default_device_open_device(Device * self, char * device_name);static gboolean default_device_finish(Device * self);static gboolean default_device_start(Device * self, DeviceAccessMode mode,                                     char * label, char * timestamp);static gboolean default_device_start_file (Device * self,                                           const dumpfile_t * jobinfo);static gboolean default_device_write_block (Device * self, guint size,                                            gpointer data, gboolean last);static gboolean default_device_write_from_fd(Device *self, int fd);static gboolean default_device_finish_file (Device * self);static dumpfile_t* default_device_seek_file (Device * self, guint file);static gboolean default_device_seek_block (Device * self, guint64 block);static int default_device_read_block (Device * self, gpointer buffer,                                      int * size);static gboolean default_device_read_to_fd(Device *self, int fd);static gboolean default_device_property_get(Device * self, DevicePropertyId ID,                                            GValue * value);/* pointer to the class of our parent */static GObjectClass *parent_class = NULL;GTypedevice_get_type (void){    static GType type = 0;        if G_UNLIKELY(type == 0) {        static const GTypeInfo info = {            sizeof (DeviceClass),            (GBaseInitFunc) NULL,            (GBaseFinalizeFunc) NULL,            (GClassInitFunc) device_class_init,            (GClassFinalizeFunc) NULL,            NULL /* class_data */,            sizeof (Device),            0 /* n_preallocs */,            (GInstanceInitFunc) device_init,            NULL        };                type = g_type_register_static (G_TYPE_OBJECT, "Device", &info,                                       (GTypeFlags)G_TYPE_FLAG_ABSTRACT);    }        return type;}static void device_finalize(GObject *obj_self) {    Device *self G_GNUC_UNUSED = DEVICE (obj_self);    if(G_OBJECT_CLASS(parent_class)->finalize)        (* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);    /* Here we call device_finish() if it hasn't been done       yet. Subclasses may need to do this same check earlier. */    if (self->access_mode != ACCESS_NULL) {        device_finish(self);    }    amfree(self->device_name);    amfree(self->volume_label);    amfree(self->volume_time);    g_array_free(selfp->property_list, TRUE);    g_hash_table_destroy(selfp->property_response);    amfree(self->private);}static void device_init (Device * self G_GNUC_UNUSED){    self->private = malloc(sizeof(DevicePrivate));    self->device_name = NULL;    self->access_mode = ACCESS_NULL;    self->is_eof = FALSE;    self->file = -1;    self->block = 0;    self->in_file = FALSE;    self->volume_label = NULL;    self->volume_time = NULL;    selfp->property_list = g_array_new(TRUE, FALSE, sizeof(DeviceProperty));    selfp->property_response =        g_hash_table_new_full(g_direct_hash,                              g_direct_equal,                              NULL,                              (GDestroyNotify) property_response_free);}static void device_class_init (DeviceClass * c G_GNUC_UNUSED){    GObjectClass *g_object_class G_GNUC_UNUSED = (GObjectClass*) c;        parent_class = g_type_class_ref (G_TYPE_OBJECT);        c->open_device = default_device_open_device;    c->finish = default_device_finish;    c->read_label = NULL;    c->start = default_device_start;    c->start_file = default_device_start_file;    c->write_block = default_device_write_block;    c->write_from_fd = default_device_write_from_fd;    c->finish_file = default_device_finish_file;    c->seek_file = default_device_seek_file;    c->seek_block = default_device_seek_block;    c->read_block = default_device_read_block;    c->read_to_fd = default_device_read_to_fd;    c->property_get = default_device_property_get;    c->property_set = NULL;    c->recycle_file = NULL;    g_object_class->finalize = device_finalize;}static void property_response_free(PropertyResponse * resp) {    g_value_unset(&(resp->response));    amfree(resp);}static char *regex_message(int result, regex_t *regex) {    char * rval;    size_t size;    size = regerror(result, regex, NULL, 0);    rval = malloc(size);    regerror(result, regex, rval, size);    return rval;}static gbooleanhandle_device_regex(const char * user_name, char ** driver_name,                    char ** device) {    regex_t regex;    int reg_result;    regmatch_t pmatch[3];    static const char * regex_string = "^([a-z0-9]+):(.*)$";    bzero(&regex, sizeof(regex));    reg_result = regcomp(&regex, regex_string, REG_EXTENDED | REG_ICASE);    if (reg_result != 0) {        char * message = regex_message(reg_result, &regex);        g_fprintf(stderr, "Error compiling regular expression \"%s\": %s\n",               regex_string, message);        amfree(message);        return FALSE;    }    reg_result = regexec(&regex, user_name, 3, pmatch, 0);    if (reg_result != 0 && reg_result != REG_NOMATCH) {        char * message = regex_message(reg_result, &regex);        g_fprintf(stderr, "Error applying regular expression \"%s\" to string \"%s\":\n"               "%s\n", user_name, regex_string, message);        regfree(&regex);        return FALSE;    } else if (reg_result == REG_NOMATCH) {#ifdef WANT_TAPE_DEVICE        g_fprintf(stderr, "\"%s\" uses deprecated device naming convention; \n"                "using \"tape:%s\" instead.\n",                user_name, user_name);        *driver_name = stralloc("tape");        *device = stralloc(user_name);#else /* !WANT_TAPE_DEVICE */        g_fprintf(stderr, "\"%s\" is not a valid device name.\n", user_name);	regfree(&regex);	return FALSE;#endif /* WANT_TAPE_DEVICE */    } else {        *driver_name = find_regex_substring(user_name, pmatch[1]);        *device = find_regex_substring(user_name, pmatch[2]);    }    regfree(&regex);    return TRUE;}Device* device_open (char * device_name){    char *device_driver_name = NULL;    char *device_node_name = NULL;    DeviceFactory factory;    Device *device;    g_return_val_if_fail (device_name != NULL, NULL);    if (driverList == NULL) {        g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,              "device_open() called without device_api_init()!\n");        g_assert_not_reached();    }    if (!handle_device_regex(device_name, &device_driver_name, &device_node_name)) {        amfree(device_driver_name);        amfree(device_node_name);        return NULL;    }    factory = lookup_device_factory(device_driver_name);    if (factory == NULL) {        g_fprintf(stderr, "Device driver %s is not known.\n",                device_driver_name);        amfree(device_driver_name);        amfree(device_node_name);        return NULL;    }    device = factory(device_driver_name, device_node_name);    amfree(device_driver_name);    amfree(device_node_name);    return device;}void device_add_property (Device * self, DeviceProperty * prop, GValue * response){    unsigned int i;    g_return_if_fail (self != NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -