📄 s3-device.c
字号:
next_file = -1; } if (file < next_file && file > last_file) { next_file = file; } } return last_file;}/* }}} *//* {{{ delete_file */static gbooleandelete_file(S3Device *self, int file){ gboolean result; GSList *keys; char *my_prefix = g_strdup_printf("%sf%08x-", self->prefix, file); result = s3_list_keys(self->s3, self->bucket, my_prefix, NULL, &keys); if (!result) { fprintf(stderr, _("While listing S3 keys: %s\n"), s3_strerror(self->s3)); return FALSE; } /* this will likely be a *lot* of keys */ for (; keys; keys = g_slist_remove(keys, keys->data)) { if (self->verbose) g_debug(_("Deleting %s"), (char*)keys->data); if (!s3_delete(self->s3, self->bucket, keys->data)) { fprintf(stderr, _("While deleting key '%s': %s\n"), (char*)keys->data, s3_strerror(self->s3)); g_slist_free(keys); return FALSE; } } return TRUE;}/* }}} *//* * Class mechanics *//* {{{ s3_device_register */void s3_device_register(void){ static const char * device_prefix_list[] = { "s3", NULL }; g_assert(s3_init()); register_device(s3_device_factory, device_prefix_list);}/* }}} *//* {{{ s3_device_get_type */GTypes3_device_get_type(void){ static GType type = 0; if G_UNLIKELY(type == 0) { static const GTypeInfo info = { sizeof (S3DeviceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) s3_device_class_init, (GClassFinalizeFunc) NULL, NULL /* class_data */, sizeof (S3Device), 0 /* n_preallocs */, (GInstanceInitFunc) s3_device_init, NULL }; type = g_type_register_static (TYPE_DEVICE, "S3Device", &info, (GTypeFlags)0); } return type;}/* }}} *//* {{{ s3_device_init */static void s3_device_init(S3Device * self){ Device * o; DeviceProperty prop; GValue response; self->initializing = TRUE; /* Register property values */ o = (Device*)(self); bzero(&response, sizeof(response)); prop.base = &device_property_concurrency; prop.access = PROPERTY_ACCESS_GET_MASK; g_value_init(&response, CONCURRENCY_PARADIGM_TYPE); g_value_set_enum(&response, CONCURRENCY_PARADIGM_SHARED_READ); device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_streaming; g_value_init(&response, STREAMING_REQUIREMENT_TYPE); g_value_set_enum(&response, STREAMING_REQUIREMENT_NONE); device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_block_size; g_value_init(&response, G_TYPE_INT); g_value_set_int(&response, -1); /* indicates a variable block size; see below */ device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_min_block_size; g_value_init(&response, G_TYPE_UINT); g_value_set_uint(&response, S3_DEVICE_MIN_BLOCK_SIZE); device_add_property(o, &prop, &response); prop.base = &device_property_max_block_size; g_value_set_uint(&response, S3_DEVICE_MAX_BLOCK_SIZE); device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_appendable; g_value_init(&response, G_TYPE_BOOLEAN); g_value_set_boolean(&response, TRUE); device_add_property(o, &prop, &response); prop.base = &device_property_partial_deletion; g_value_set_boolean(&response, TRUE); device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_canonical_name; g_value_init(&response, G_TYPE_STRING); g_value_set_static_string(&response, "s3:"); device_add_property(o, &prop, &response); g_value_unset(&response); prop.base = &device_property_medium_access_type; g_value_init(&response, MEDIA_ACCESS_MODE_TYPE); g_value_set_enum(&response, MEDIA_ACCESS_MODE_READ_WRITE); device_add_property(o, &prop, &response); g_value_unset(&response); prop.access = PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START; prop.base = &device_property_s3_secret_key; device_add_property(o, &prop, NULL); prop.base = &device_property_s3_access_key; device_add_property(o, &prop, NULL);#ifdef WANT_DEVPAY prop.base = &device_property_s3_user_token; device_add_property(o, &prop, NULL);#endif}/* }}} *//* {{{ s3_device_class_init */static void s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED){ GObjectClass *g_object_class = (GObjectClass*) c; DeviceClass *device_class = (DeviceClass *)c; parent_class = g_type_class_ref (TYPE_DEVICE); device_class->open_device = s3_device_open_device; device_class->read_label = s3_device_read_label; device_class->start = s3_device_start; device_class->start_file = s3_device_start_file; device_class->write_block = s3_device_write_block; device_class->finish_file = s3_device_finish_file; device_class->seek_file = s3_device_seek_file; device_class->seek_block = s3_device_seek_block; device_class->read_block = s3_device_read_block; device_class->recycle_file = s3_device_recycle_file; device_class->property_set = s3_device_property_set; device_class->property_get = s3_device_property_get; g_object_class->finalize = s3_device_finalize;}/* }}} *//* {{{ s3_device_factory */static Device* s3_device_factory(char * device_type, char * device_name){ Device *rval; S3Device * s3_rval; g_assert(0 == strcmp(device_type, "s3")); rval = DEVICE(g_object_new(TYPE_S3_DEVICE, NULL)); s3_rval = (S3Device*)rval; if (!device_open_device(rval, device_name)) { g_object_unref(rval); return NULL; } else { s3_rval->initializing = FALSE; return rval; } }/* }}} *//* * Virtual function overrides *//* {{{ s3_device_open_device */static gboolean s3_device_open_device(Device *pself, char *device_name){ S3Device *self = S3_DEVICE(pself); char * name_colon; g_return_val_if_fail(self != NULL, FALSE); /* Device name may be bucket/prefix, to support multiple volumes in a * single bucket. */ name_colon = index(device_name, '/'); if (name_colon == NULL) { self->bucket = g_strdup(device_name); self->prefix = g_strdup(""); } else { self->bucket = g_strndup(device_name, name_colon - device_name); self->prefix = g_strdup(name_colon + 1); } if (self->bucket == NULL || self->bucket[0] == '\0') { fprintf(stderr, _("Empty bucket name in device %s.\n"), device_name); amfree(self->bucket); amfree(self->prefix); return FALSE; } g_debug(_("S3 driver using bucket '%s', prefix '%s'"), self->bucket, self->prefix); /* default value */ self->verbose = FALSE; if (parent_class->open_device) { parent_class->open_device(pself, device_name); } return TRUE;}/* }}} *//* {{{ s3_device_finalize */static void s3_device_finalize(GObject * obj_self) { S3Device *self = S3_DEVICE (obj_self); if(G_OBJECT_CLASS(parent_class)->finalize) (* G_OBJECT_CLASS(parent_class)->finalize)(obj_self); if(self->s3) s3_free(self->s3); if(self->bucket) g_free(self->bucket); if(self->prefix) g_free(self->prefix);}/* }}} */static gboolean setup_handle(S3Device * self, G_GNUC_UNUSED gboolean silent) { if (self->s3 == NULL) { if (self->access_key == NULL) { if (!silent) fprintf(stderr, _("No S3 access key specified\n")); return FALSE; } if (self->secret_key == NULL) { if (!silent) fprintf(stderr, _("No S3 secret key specified\n")); return FALSE; }#ifdef WANT_DEVPAY if (self->user_token == NULL) { if (!silent) fprintf(stderr, _("No S3 user token specified\n")); return FALSE; }#endif self->s3 = s3_open(self->access_key, self->secret_key#ifdef WANT_DEVPAY , self->user_token#endif ); if (self->s3 == NULL) { fprintf(stderr, "Internal error creating S3 handle.\n"); return FALSE; } } s3_verbose(self->s3, self->verbose); return TRUE;}/* {{{ s3_device_read_label */static ReadLabelStatusFlagss3_device_read_label(Device *pself) { S3Device *self = S3_DEVICE(pself); char *key; gpointer buf; guint buf_size; dumpfile_t amanda_header; if (!setup_handle(self, self->initializing)) return READ_LABEL_STATUS_DEVICE_ERROR; key = special_file_to_key(self, "tapestart", -1); if (!s3_read(self->s3, self->bucket, key, &buf, &buf_size, S3_DEVICE_MAX_BLOCK_SIZE)) { 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), just return FALSE */ if (response_code == 404 && (s3_error_code == S3_ERROR_NoSuchKey || s3_error_code == S3_ERROR_NoSuchBucket)) { g_debug(_("Amanda header not found while reading tapestart header (this is expected for empty tapes)")); return READ_LABEL_STATUS_VOLUME_UNLABELED; } /* otherwise, log it and return */ fprintf(stderr, _("While trying to read tapestart header: %s\n"), s3_strerror(self->s3)); return READ_LABEL_STATUS_DEVICE_ERROR; } g_assert(buf != NULL); fh_init(&amanda_header); parse_file_header(buf, &amanda_header, buf_size); g_free(buf); if (amanda_header.type != F_TAPESTART) { fprintf(stderr, _("Invalid amanda header\n")); return READ_LABEL_STATUS_VOLUME_ERROR; } amfree(pself->volume_label); pself->volume_label = g_strdup(amanda_header.name); amfree(pself->volume_time); pself->volume_time = g_strdup(amanda_header.datestamp); return READ_LABEL_STATUS_SUCCESS;}/* }}} *//* {{{ s3_device_start */static gboolean s3_device_start (Device * pself, DeviceAccessMode mode, char * label, char * timestamp) { S3Device * self; int file, last_file; self = S3_DEVICE(pself); g_return_val_if_fail (self != NULL, FALSE); if (!setup_handle(self, FALSE)) return FALSE; /* try creating the bucket, in case it doesn't exist */ if (mode != ACCESS_READ && !s3_make_bucket(self->s3, self->bucket)) { 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 isn't an expected error (bucket already exists), * return FALSE */ if (response_code != 409 || s3_error_code != S3_ERROR_BucketAlreadyExists) { fprintf(stderr, _("While creating new S3 bucket: %s\n"), s3_strerror(self->s3)); return FALSE; } } /* call up to the parent (Device) to set access_mode, volume_label, * and volume_time, either from the arguments (ACCESS_WRITE) or by * reading from the 0th file (otherwise) */ if (parent_class->start) if (!parent_class->start((Device*)self, mode, label, timestamp)) return FALSE; /* take care of any dirty work for this mode */ switch (mode) { case ACCESS_READ: break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -