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

📄 device.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 3 页
字号:
    g_return_if_fail (IS_DEVICE (self));    g_assert(selfp->property_list != NULL);    g_assert(selfp->property_response != NULL);    /* Delete it if it already exists. */    for(i = 0; i < selfp->property_list->len; i ++) {        if (g_array_index(selfp->property_list,                          DeviceProperty, i).base->ID == prop->base->ID) {            g_array_remove_index_fast(selfp->property_list, i);            break;        }    }    g_array_append_val(selfp->property_list, *prop);        if (response != NULL) {        PropertyResponse * property_response;                g_return_if_fail(G_IS_VALUE(response));                property_response = malloc(sizeof(*property_response));        property_response->access = prop->access;        bzero(&(property_response->response),              sizeof(property_response->response));        g_value_init(&(property_response->response),                     G_VALUE_TYPE(response));        g_value_copy(response, &(property_response->response));                g_hash_table_insert(selfp->property_response,                            GINT_TO_POINTER(prop->base->ID),                            property_response);    }}const DeviceProperty * device_property_get_list (Device * self){	g_return_val_if_fail (self != NULL, (const DeviceProperty * )0);	g_return_val_if_fail (IS_DEVICE (self), (const DeviceProperty * )0);        return (const DeviceProperty*) selfp->property_list->data;}guint device_write_min_size(Device * self) {    GValue g_tmp;    int block_size, min_block_size;        bzero(&g_tmp, sizeof(g_tmp));    device_property_get(self, PROPERTY_BLOCK_SIZE, &g_tmp);    block_size = g_value_get_int(&g_tmp);    g_value_unset(&g_tmp);    if (block_size > 0) {        return block_size;    }    /* variable block size */    device_property_get(self, PROPERTY_MIN_BLOCK_SIZE, &g_tmp);    min_block_size = g_value_get_uint(&g_tmp);    g_value_unset(&g_tmp);    return min_block_size;}guint device_write_max_size(Device * self) {    GValue g_tmp;    int block_size, max_block_size;        bzero(&g_tmp, sizeof(g_tmp));    device_property_get(self, PROPERTY_BLOCK_SIZE, &g_tmp);    block_size = g_value_get_int(&g_tmp);    g_value_unset(&g_tmp);    if (block_size > 0) {        return block_size;    }    /* variable block size */    device_property_get(self, PROPERTY_MAX_BLOCK_SIZE, &g_tmp);    max_block_size = g_value_get_uint(&g_tmp);    g_value_unset(&g_tmp);    return max_block_size;}guint device_read_max_size(Device * self) {    GValue g_tmp;        bzero(&g_tmp, sizeof(g_tmp));    if (device_property_get(self, PROPERTY_READ_BUFFER_SIZE, &g_tmp)) {        guint rval = g_value_get_uint(&g_tmp);        g_value_unset(&g_tmp);        return rval;    } else {        return device_write_max_size(self);    }}char * device_build_amanda_header(Device * self, const dumpfile_t * info,                                  int * size, gboolean * oneblock) {    char *amanda_header;    unsigned int min_header_length;    unsigned int header_buffer_size;    min_header_length = device_write_min_size(self);    amanda_header = build_header(info, min_header_length);    header_buffer_size = MAX(min_header_length, strlen(amanda_header)+1);    if (size != NULL)        *size = header_buffer_size;    if (oneblock != NULL)        *oneblock = (header_buffer_size <=  device_write_max_size(self));    return amanda_header;}dumpfile_t * make_tapestart_header(Device * self, char * label,                                   char * timestamp) {    dumpfile_t * rval;    g_return_val_if_fail(label != NULL, NULL);    rval = malloc(sizeof(*rval));    fh_init(rval);    rval->type = F_TAPESTART;    amfree(self->volume_time);    if (get_timestamp_state(timestamp) == TIME_STATE_REPLACE) {        self->volume_time = get_proper_stamp_from_time(time(NULL));    } else {        self->volume_time = g_strdup(timestamp);    }    strncpy(rval->datestamp, self->volume_time, sizeof(rval->datestamp));    strncpy(rval->name, label, sizeof(rval->name));    return rval;}dumpfile_t * make_tapeend_header(void) {    dumpfile_t * rval;    char * timestamp;    rval = malloc(sizeof(*rval));    rval->type = F_TAPEEND;    timestamp = get_timestamp_from_time(time(NULL));    strncpy(rval->datestamp, timestamp, sizeof(rval->datestamp));    amfree(timestamp);    return rval;}/* Try setting max/fixed blocksize on a device. Check results, fallback, and * print messages for problems. */static void try_set_blocksize(Device * device, guint blocksize,                              gboolean try_max_first) {    GValue val;    gboolean success;    bzero(&val, sizeof(val));    g_value_init(&val, G_TYPE_UINT);    g_value_set_uint(&val, blocksize);    if (try_max_first) {        success = device_property_set(device,                                      PROPERTY_MAX_BLOCK_SIZE,                                      &val);        if (!success) {            g_fprintf(stderr, "Setting MAX_BLOCK_SIZE to %u "                    "not supported for device %s.\n"                    "trying BLOCK_SIZE instead.\n",                    blocksize, device->device_name);        } else {            g_value_unset(&val);            return;        }    }    g_value_unset(&val);    g_value_init(&val, G_TYPE_INT);    g_value_set_int(&val, blocksize);    success = device_property_set(device,                                  PROPERTY_BLOCK_SIZE,                                  &val);    if (!success) {        g_fprintf(stderr, "Setting BLOCK_SIZE to %u "                "not supported for device %s.\n",                blocksize, device->device_name);    }    g_value_unset(&val);}/* A GHFunc (callback for g_hash_table_foreach) */static void set_device_property(gpointer key_p, gpointer value_p,                                   gpointer user_data_p) {    char * property_s = key_p;    char * value_s = value_p;    Device * device = user_data_p;    const DevicePropertyBase* property_base;    GValue property_value;    g_return_if_fail(IS_DEVICE(device));    g_return_if_fail(property_s != NULL);    g_return_if_fail(value_s != NULL);    property_base = device_property_get_by_name(property_s);    if (property_base == NULL) {        /* Nonexistant property name. */        g_fprintf(stderr, _("Unknown device property name %s.\n"), property_s);        return;    }        bzero(&property_value, sizeof(property_value));    g_value_init(&property_value, property_base->type);    if (!g_value_set_from_string(&property_value, value_s)) {        /* Value type could not be interpreted. */        g_fprintf(stderr,                _("Could not parse property value %s for property type %s.\n"),                value_s, g_type_name(property_base->type));        return;    } else {        g_assert (G_VALUE_HOLDS(&property_value, property_base->type));    }    if (!device_property_set(device, property_base->ID, &property_value)) {        /* Device rejects property. */        g_fprintf(stderr, _("Could not set property %s to %s on device %s.\n"),                property_base->name, value_s, device->device_name);        return;    }}/* Set up first-run properties, including DEVICE_MAX_VOLUME_USAGE property * based on the tapetype. */void device_set_startup_properties_from_config(Device * device) {    char * tapetype_name = getconf_str(CNF_TAPETYPE);    if (tapetype_name != NULL) {        tapetype_t * tapetype = lookup_tapetype(tapetype_name);        if (tapetype != NULL) {            GValue val;            guint64 length;            guint blocksize_kb;            gboolean success;            bzero(&val, sizeof(GValue));            if (tapetype_seen(tapetype, TAPETYPE_LENGTH)) {		length = tapetype_get_length(tapetype);                g_value_init(&val, G_TYPE_UINT64);                g_value_set_uint64(&val, length * 1024);                /* If this fails, it's not really an error. */                device_property_set(device, PROPERTY_MAX_VOLUME_USAGE, &val);                g_value_unset(&val);            }            if (tapetype_seen(tapetype, TAPETYPE_READBLOCKSIZE)) {		blocksize_kb = tapetype_get_readblocksize(tapetype);                g_value_init(&val, G_TYPE_UINT);                g_value_set_uint(&val, blocksize_kb * 1024);                success = device_property_set(device,                                              PROPERTY_READ_BUFFER_SIZE,                                              &val);                g_value_unset(&val);                if (!success) {                    g_fprintf(stderr, "Setting READ_BUFFER_SIZE to %llu "                            "not supported for device %s.\n",                            1024*(long long unsigned int)blocksize_kb,			    device->device_name);                }            }            if (tapetype_seen(tapetype, TAPETYPE_BLOCKSIZE)) {		blocksize_kb = tapetype_get_blocksize(tapetype);                try_set_blocksize(device, blocksize_kb * 1024,                                  !tapetype_get_file_pad(tapetype));            }        }    }    g_hash_table_foreach(getconf_proplist(CNF_DEVICE_PROPERTY),                         set_device_property, device);}void device_clear_volume_details(Device * device) {    if (device == NULL || device->access_mode != ACCESS_NULL) {        return;    }    amfree(device->volume_label);    amfree(device->volume_time);}/* Here we put default implementations of virtual functions. Since   this class is virtual, many of these functions offer at best   incomplete functionality. But they do offer the useful commonality   that all devices can expect to need. *//* This function only updates access_mode, volume_label, and volume_time. */static gbooleandefault_device_start (Device * self, DeviceAccessMode mode, char * label,                      char * timestamp) {    if (mode != ACCESS_WRITE && self->volume_label == NULL) {        if (device_read_label(self) != READ_LABEL_STATUS_SUCCESS)            return FALSE;    } else if (mode == ACCESS_WRITE) {        self->volume_label = newstralloc(self->volume_label, label);        self->volume_time = newstralloc(self->volume_time, timestamp);    }    self->access_mode = mode;    return TRUE;}static gboolean default_device_open_device(Device * self,                                           char * device_name) {    DeviceProperty prop;    guint i;    self->device_name = stralloc(device_name);    prop.base = &device_property_canonical_name;    prop.access = PROPERTY_ACCESS_GET_MASK;    for(i = 0; i < selfp->property_list->len; i ++) {        if (g_array_index(selfp->property_list,                          DeviceProperty, i).base->ID == prop.base->ID) {            return TRUE;        }    }    /* If we got here, the property was not registered. */    device_add_property(self, &prop, NULL);    return TRUE;}/* This default implementation does very little. */static gbooleandefault_device_finish (Device * self) {    self->access_mode = ACCESS_NULL;    return TRUE;}/* This function updates the file, in_file, and block attributes. */static gbooleandefault_device_start_file (Device * self,                           const dumpfile_t * jobInfo G_GNUC_UNUSED) {    self->in_file = TRUE;    if (self->file <= 0)        self->file = 1;    else        self->file ++;    self->block = 0;    return TRUE;}/* This function lies: It updates the block number and maybe calls   device_finish_file(), but returns FALSE. */static gbooleandefault_device_write_block(Device * self, guint size G_GNUC_UNUSED,                           gpointer data G_GNUC_UNUSED, gboolean last_block) {    self->block ++;    if (last_block)        device_finish_file(self);    return FALSE;}/* This function lies: It updates the block number, but returns   -1. */static intdefault_device_read_block(Device * self, gpointer buf G_GNUC_UNUSED,                          int * size G_GNUC_UNUSED) {    self->block ++;    return -1;

⌨️ 快捷键说明

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