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

📄 s3-device.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 3 页
字号:
        case ACCESS_WRITE:            /* delete all files */            last_file = find_last_file(self);            if (last_file < 0) return FALSE;            for (file = 0; file <= last_file; file++) {                if (!delete_file(self, file)) return FALSE;            }            /* write a new amanda header */            if (!write_amanda_header(self, label, timestamp)) {                return FALSE;            }            break;        case ACCESS_APPEND:            return seek_to_end(self);            break;        case ACCESS_NULL:            g_assert_not_reached();    }    g_assert(pself->access_mode == mode);    return TRUE;}/* }}} */static gboolean s3_device_property_get(Device * p_self, DevicePropertyId id,                                       GValue * val) {    S3Device * self;    const DevicePropertyBase * base;    self = S3_DEVICE(p_self);    g_return_val_if_fail(self != NULL, FALSE);    base = device_property_get_by_id(id);    g_return_val_if_fail(self != NULL, FALSE);        g_value_unset_init(val, base->type);        if (id == PROPERTY_S3_SECRET_KEY) {        if (self->secret_key != NULL) {            g_value_set_string(val, self->secret_key);            return TRUE;        } else {            return FALSE;        }    } else if (id == PROPERTY_S3_ACCESS_KEY) {        if (self->access_key != NULL) {            g_value_set_string(val, self->access_key);            return TRUE;        } else {            return FALSE;        }    }#ifdef WANT_DEVPAY    else if (id == PROPERTY_S3_USER_TOKEN) {        if (self->user_token != NULL) {            g_value_set_string(val, self->user_token);            return TRUE;        } else {            return FALSE;        }    }#endif /* WANT_DEVPAY */    else if (id == PROPERTY_VERBOSE) {        g_value_set_boolean(val, self->verbose);        return TRUE;    } else {        /* chain up */        if (parent_class->property_get) {            return (parent_class->property_get)(p_self, id, val);        } else {            return FALSE;        }    }    g_assert_not_reached();}static gboolean s3_device_property_set(Device * p_self, DevicePropertyId id,                                       GValue * val) {    S3Device * self;    const DevicePropertyBase * base;    self = S3_DEVICE(p_self);    g_return_val_if_fail(self != NULL, FALSE);    base = device_property_get_by_id(id);    g_return_val_if_fail(self != NULL, FALSE);    g_return_val_if_fail(G_VALUE_HOLDS(val, base->type), FALSE);    if (id == PROPERTY_S3_SECRET_KEY) {        if (p_self->access_mode != ACCESS_NULL)            return FALSE;        amfree(self->secret_key);        self->secret_key = g_value_dup_string(val);        device_clear_volume_details(p_self);        return TRUE;    } else if (id == PROPERTY_S3_ACCESS_KEY) {        if (p_self->access_mode != ACCESS_NULL)            return FALSE;        amfree(self->access_key);        self->access_key = g_value_dup_string(val);        device_clear_volume_details(p_self);        return TRUE;    }#ifdef WANT_DEVPAY    else if (id == PROPERTY_S3_USER_TOKEN) {        if (p_self->access_mode != ACCESS_NULL)            return FALSE;        amfree(self->user_token);        self->user_token = g_value_dup_string(val);        device_clear_volume_details(p_self);        return TRUE;    }#endif /* WANT_DEVPAY */    else if (id == PROPERTY_VERBOSE) {        self->verbose = g_value_get_boolean(val);	/* Our S3 handle may not yet have been instantiated; if so, it will	 * get the proper verbose setting when it is created */	if (self->s3)	    s3_verbose(self->s3, self->verbose);	return TRUE;    } else {        if (parent_class->property_set) {            return (parent_class->property_set)(p_self, id, val);        } else {            return FALSE;        }    }    g_assert_not_reached();}/* functions for writing *//* {{{ s3_device_start_file */static gbooleans3_device_start_file (Device *pself, const dumpfile_t *jobInfo) {    S3Device *self = S3_DEVICE(pself);    char *amanda_header;    int header_size;    gboolean header_fits, result;    char *key;    g_return_val_if_fail (self != NULL, FALSE);    /* Build the amanda header. */    amanda_header = device_build_amanda_header(pself, jobInfo,                                               &header_size, &header_fits);    g_return_val_if_fail(amanda_header != NULL, FALSE);    g_return_val_if_fail(header_fits, FALSE);    /* set the file and block numbers correctly */    pself->file = (pself->file > 0)? pself->file+1 : 1;    pself->block = 0;    pself->in_file = TRUE;    /* write it out as a special block (not the 0th) */    key = special_file_to_key(self, "filestart", pself->file);    result = s3_upload(self->s3, self->bucket, key, amanda_header, header_size);    g_free(amanda_header);    g_free(key);    if (!result) {        fprintf(stderr, _("While writing filestart header: %s\n"),                s3_strerror(self->s3));        return FALSE;    }    return TRUE;}/* }}} *//* {{{ s3_device_write_block */static gbooleans3_device_write_block (Device * pself, guint size, gpointer data,                         gboolean last_block) {    gboolean result;    char *filename;    S3Device * self = S3_DEVICE(pself);;    g_assert (self != NULL);    g_assert (data != NULL);        filename = file_and_block_to_key(self, pself->file, pself->block);    result = s3_upload(self->s3, self->bucket, filename, data, size);    g_free(filename);    if (!result) {        fprintf(stderr, _("While writing data block to S3: %s\n"),                s3_strerror(self->s3));        return FALSE;    }    pself->block++;    /* if this is the last block, finish the file */    if (last_block) {        return s3_device_finish_file(pself);    }    return TRUE;}/* }}} *//* {{{ s3_device_finish_file */static gbooleans3_device_finish_file (Device * pself) {    /* we're not in a file anymore */    pself->in_file = FALSE;    return TRUE;}/* }}} *//* {{{ s3_device_recycle_file */static gbooleans3_device_recycle_file(Device *pself, guint file) {    S3Device *self = S3_DEVICE(pself);    return delete_file(self, file);}/* }}} *//* functions for reading *//* {{{ s3_device_seek_file */static dumpfile_t*s3_device_seek_file(Device *pself, guint file) {    S3Device *self = S3_DEVICE(pself);    gboolean result;    char *key;    gpointer buf;    guint buf_size;    dumpfile_t *amanda_header;    pself->file = file;    pself->block = 0;    pself->in_file = TRUE;    /* read it in */    key = special_file_to_key(self, "filestart", pself->file);    result = s3_read(self->s3, self->bucket, key, &buf, &buf_size, S3_DEVICE_MAX_BLOCK_SIZE);    g_free(key);     if (!result) {        guint response_code;        s3_error_code_t s3_error_code;        s3_error(self->s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL);        /* if it's an expected error (not found), check what to do. */        if (response_code == 404 && s3_error_code == S3_ERROR_NoSuchKey) {            int next_file;            pself->file = -1;            pself->in_file = FALSE;            next_file = find_next_file(self, pself->file);            if (next_file > 0) {                /* Note short-circut of dispatcher. */                return s3_device_seek_file(pself, next_file);            } else if (next_file == 0) {                /* No next file. Check if we are one past the end. */                key = special_file_to_key(self, "filestart", pself->file - 1);                result = s3_read(self->s3, self->bucket, key, &buf, &buf_size,                                 S3_DEVICE_MAX_BLOCK_SIZE);                g_free(key);                if (result) {                    return make_tapeend_header();                } else {                    return NULL;                }            }        } else {            /* An error occured finding out if we are the last file. */            return NULL;        }    }       /* and make a dumpfile_t out of it */    g_assert(buf != NULL);    amanda_header = g_new(dumpfile_t, 1);    fh_init(amanda_header);    parse_file_header(buf, amanda_header, buf_size);    g_free(buf);    switch (amanda_header->type) {        case F_DUMPFILE:        case F_CONT_DUMPFILE:        case F_SPLIT_DUMPFILE:            return amanda_header;        default:            fprintf(stderr,                    _("Invalid amanda header while reading file header\n"));            g_free(amanda_header);            return NULL;    }}/* }}} *//* {{{ s3_device_seek_block */static gbooleans3_device_seek_block(Device *pself, guint64 block) {    pself->block = block;    return TRUE;}/* }}} *//* {{{ s3_device_read_block */static ints3_device_read_block (Device * pself, gpointer data, int *size_req) {    S3Device * self = S3_DEVICE(pself);    char *key;    gpointer buf;    gboolean result;    guint buf_size;    g_assert (self != NULL);    /* get the file*/    key = file_and_block_to_key(self, pself->file, pself->block);    g_assert(key != NULL);    if (self->cached_key && (0 == strcmp(key, self->cached_key))) {        /* use the cached copy and clear the cache */        buf = self->cached_buf;        buf_size = self->cached_size;        self->cached_buf = NULL;        g_free(self->cached_key);        self->cached_key = NULL;    } else {        /* clear the cache and actually download the file */        if (self->cached_buf) {            g_free(self->cached_buf);            self->cached_buf = NULL;        }        if (self->cached_key) {            g_free(self->cached_key);            self->cached_key = NULL;        }        result = s3_read(self->s3, self->bucket, key, &buf, &buf_size, S3_DEVICE_MAX_BLOCK_SIZE);        if (!result) {            guint response_code;            s3_error_code_t s3_error_code;            s3_error(self->s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL);            g_free(key);            key = NULL;            /* if it's an expected error (not found), just return -1 */            if (response_code == 404 && s3_error_code == S3_ERROR_NoSuchKey) {                pself->is_eof = TRUE;                return -1;            }            /* otherwise, log it and return FALSE */            fprintf(stderr, _("While reading data block from S3: %s\n"),                    s3_strerror(self->s3));            return -1;        }    }    /* INVARIANT: cache is NULL */    g_assert(self->cached_buf == NULL);    g_assert(self->cached_key == NULL);    /* now see how the caller wants to deal with that */    if (data == NULL || *size_req < 0 || buf_size > (guint)*size_req) {        /* A size query or short buffer -- load the cache and return the size*/        self->cached_buf = buf;        self->cached_key = key;        self->cached_size = buf_size;        *size_req = buf_size;        return 0;    } else {        /* ok, all checks are passed -- copy the data */        *size_req = buf_size;        g_memmove(data, buf, buf_size);        g_free(key);        g_free(buf);        /* move on to the next block */        pself->block++;        return buf_size;    }}/* }}} */

⌨️ 快捷键说明

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