static dpl_vec_t * get_canonical_headers(dpl_dict_t *headers) { int bucket; dpl_vec_t *canonical_headers; dpl_dict_var_t *header; canonical_headers = dpl_vec_new(1, 0); if (canonical_headers == NULL) return NULL; for (bucket = 0; bucket < headers->n_buckets; bucket++) { header = headers->buckets[bucket]; while (header != NULL) { dpl_status_t ret; assert(header->val->type == DPL_VALUE_STRING); ret = dpl_vec_add(canonical_headers, header); if (ret != DPL_SUCCESS) { dpl_vec_free(canonical_headers); return NULL; } header = header->prev; } } dpl_vec_sort(canonical_headers, var_cmp); return canonical_headers; }
static dpl_status_t insert_query_params_in_vec(dpl_vec_t *params, const dpl_dict_t *query_params, unsigned char encode_url) { int bucket; for (bucket = 0; bucket < query_params->n_buckets; bucket++) { dpl_dict_var_t *param = query_params->buckets[bucket]; while (param != NULL) { size_t new_size; dpl_dict_var_t *new_param; dpl_status_t ret; new_param = (dpl_dict_var_t *) malloc (sizeof (dpl_dict_var_t)); if (new_param == NULL) return DPL_FAILURE; if (encode_url) new_size = DPL_URL_LENGTH(strlen(param->key)) + 1; else new_size = strlen(param->key) + 1; new_param->key = (char *) malloc(new_size); if (new_param->key == NULL) { free(new_param); return DPL_FAILURE; } if (encode_url) dpl_url_encode(param->key, new_param->key); else strcpy(new_param->key, param->key); new_param->val = dpl_value_dup(param->val); if (new_param->val == NULL) { free(new_param->key); free(new_param); return DPL_FAILURE; } if (encode_url) { ret = dpl_sbuf_url_encode(new_param->val->string); if (ret != DPL_SUCCESS) { dpl_value_free(new_param->val); free(new_param->key); free(new_param); return DPL_FAILURE; } } dpl_vec_add(params, new_param); param = param->prev; } } return DPL_SUCCESS; }
static dpl_status_t parse_list_bucket_content(xmlNode *node, dpl_vec_t *vec) { xmlNode *tmp; dpl_object_t *object = NULL; int ret; object = malloc(sizeof (*object)); if (NULL == object) goto bad; memset(object, 0, sizeof (*object)); for (tmp = node; NULL != tmp; tmp = tmp->next) { if (tmp->type == XML_ELEMENT_NODE) { DPRINTF("name: %s\n", tmp->name); if (!strcmp((char *) tmp->name, "Key")) { object->path = strdup((char *) tmp->children->content); if (NULL == object->path) goto bad; } else if (!strcmp((char *) tmp->name, "LastModified")) { object->last_modified = dpl_iso8601totime((char *) tmp->children->content); } else if (!strcmp((char *) tmp->name, "Size")) { object->size = strtoull((char *) tmp->children->content, NULL, 0); } } else if (tmp->type == XML_TEXT_NODE) { DPRINTF("content: %s\n", tmp->content); } } ret = dpl_vec_add(vec, object); if (DPL_SUCCESS != ret) goto bad; return DPL_SUCCESS; bad: if (NULL != object) dpl_object_free(object); return DPL_FAILURE; }
static dpl_status_t parse_list_all_my_buckets_bucket(xmlNode *node, dpl_vec_t *vec) { xmlNode *tmp; dpl_bucket_t *bucket = NULL; int ret; bucket = malloc(sizeof (*bucket)); if (NULL == bucket) goto bad; memset(bucket, 0, sizeof (*bucket)); for (tmp = node; NULL != tmp; tmp = tmp->next) { if (tmp->type == XML_ELEMENT_NODE) { DPRINTF("name: %s\n", tmp->name); if (!strcmp((char *) tmp->name, "Name")) { bucket->name = strdup((char *) tmp->children->content); if (NULL == bucket->name) goto bad; } if (!strcmp((char *) tmp->name, "CreationDate")) { bucket->creation_time = dpl_iso8601totime((char *) tmp->children->content); } } else if (tmp->type == XML_TEXT_NODE) { DPRINTF("content: %s\n", tmp->content); } } ret = dpl_vec_add(vec, bucket); if (DPL_SUCCESS != ret) goto bad; return DPL_SUCCESS; bad: if (NULL != bucket) dpl_bucket_free(bucket); return DPL_FAILURE; }
static dpl_status_t parse_list_bucket_common_prefixes(xmlNode *node, dpl_vec_t *vec) { xmlNode *tmp; dpl_common_prefix_t *common_prefix = NULL; int ret; common_prefix = malloc(sizeof (*common_prefix)); if (NULL == common_prefix) goto bad; memset(common_prefix, 0, sizeof (*common_prefix)); for (tmp = node; NULL != tmp; tmp = tmp->next) { if (tmp->type == XML_ELEMENT_NODE) { DPRINTF("name: %s\n", tmp->name); if (!strcmp((char *) tmp->name, "Prefix")) { common_prefix->prefix = strdup((char *) tmp->children->content); if (NULL == common_prefix->prefix) goto bad; } } else if (tmp->type == XML_TEXT_NODE) { DPRINTF("content: %s\n", tmp->content); } } ret = dpl_vec_add(vec, common_prefix); if (DPL_SUCCESS != ret) goto bad; return DPL_SUCCESS; bad: if (NULL != common_prefix) dpl_common_prefix_free(common_prefix); return DPL_FAILURE; }
dpl_status_t dpl_cdmi_parse_list_bucket(dpl_ctx_t *ctx, const char *buf, int len, const char *prefix, dpl_vec_t *objects, dpl_vec_t *common_prefixes) { int ret, ret2; json_tokener *tok = NULL; json_object *obj = NULL; json_object *children = NULL; int n_children, i; dpl_common_prefix_t *common_prefix = NULL; dpl_object_t *object = NULL; // write(1, buf, len); tok = json_tokener_new(); if (NULL == tok) { ret = DPL_ENOMEM; goto end; } obj = json_tokener_parse_ex(tok, buf, len); if (NULL == obj) { ret = DPL_FAILURE; goto end; } children = json_object_object_get(obj, "children"); if (NULL == children) { ret = DPL_FAILURE; goto end; } if (json_type_array != json_object_get_type(children)) { ret = DPL_FAILURE; goto end; } n_children = json_object_array_length(children); for (i = -1;i < n_children;i++) { char name[1024]; int name_len; if (-1 == i) { // add the directory itself to the list snprintf(name, sizeof (name), "%s", NULL != prefix ? prefix : "/"); } else { json_object *child = json_object_array_get_idx(children, i); if (json_type_string != json_object_get_type(child)) { ret = DPL_FAILURE; goto end; } snprintf(name, sizeof (name), "%s%s", NULL != prefix ? prefix : "", json_object_get_string(child)); } name_len = strlen(name); if (name_len > 0 && name[name_len-1] == '/') { //this is a directory common_prefix = malloc(sizeof (*common_prefix)); if (NULL == common_prefix) { ret = DPL_ENOMEM; goto end; } memset(common_prefix, 0, sizeof (*common_prefix)); common_prefix->prefix = strdup(name); if (NULL == common_prefix->prefix) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_vec_add(common_prefixes, common_prefix); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } common_prefix = NULL; } else { object = malloc(sizeof (*object)); if (NULL == object) { ret = DPL_ENOMEM; goto end; } memset(object, 0, sizeof (*object)); object->path = strdup(name); if (NULL == object->path) { ret = DPL_ENOMEM; goto end; } if (name_len > 0 && name[name_len-1] == '?') { //this is a symbolic link: remove final '?' object->path[name_len - 1] = '\0'; } ret2 = dpl_vec_add(objects, object); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } object = NULL; } } ret = DPL_SUCCESS; end: if (NULL != common_prefix) dpl_common_prefix_free(common_prefix); if (NULL != object) dpl_object_free(object); if (NULL != obj) json_object_put(obj); if (NULL != tok) json_tokener_free(tok); return ret; }
static dpl_status_t dpl_s3_make_signature_v2(dpl_ctx_t *ctx, const char *method, const char *bucket, const char *resource, const char *subresource, char *date, dpl_dict_t *headers, char *buf, unsigned int len, unsigned int *lenp) { char *p; char *value; int ret; p = buf; //method DPL_APPEND_STR(method); DPL_APPEND_STR("\n"); //md5 if (headers != NULL) { value = dpl_dict_get_value(headers, "Content-MD5"); if (NULL != value) DPL_APPEND_STR(value); } DPL_APPEND_STR("\n"); //content type if (headers != NULL) { value = dpl_dict_get_value(headers, "Content-Type"); if (NULL != value) DPL_APPEND_STR(value); } DPL_APPEND_STR("\n"); //expires or date if (date != NULL) DPL_APPEND_STR(date); DPL_APPEND_STR("\n"); //x-amz headers if (headers != NULL) { int bucket; dpl_dict_var_t *var; dpl_vec_t *vec; int i; vec = dpl_vec_new(2, 2); if (NULL == vec) return DPL_ENOMEM; for (bucket = 0; bucket < headers->n_buckets; bucket++) { for (var = headers->buckets[bucket];var;var = var->prev) { if (!strncmp(var->key, "x-amz-", 6) && strcmp(var->key, "x-amz-date")) { assert(DPL_VALUE_STRING == var->val->type); ret = dpl_vec_add(vec, var); if (DPL_SUCCESS != ret) { dpl_vec_free(vec); return DPL_FAILURE; } } } } dpl_vec_sort(vec, var_cmp); for (i = 0;i < vec->n_items;i++) { var = (dpl_dict_var_t *) dpl_vec_get(vec, i); if (var == NULL) continue; assert(DPL_VALUE_STRING == var->val->type); DPL_APPEND_STR(var->key); DPL_APPEND_STR(":"); DPL_APPEND_STR(dpl_sbuf_get_str(var->val->string)); DPL_APPEND_STR("\n"); } dpl_vec_free(vec); } //resource if (NULL != bucket) { DPL_APPEND_STR("/"); DPL_APPEND_STR(bucket); } if (NULL != resource) DPL_APPEND_STR(resource); if (NULL != subresource) { DPL_APPEND_STR("?"); DPL_APPEND_STR(subresource); } if (NULL != lenp) *lenp = p - buf; return DPL_SUCCESS; }
dpl_status_t dpl_posix_list_bucket(dpl_ctx_t *ctx, const char *bucket, const char *prefix, const char *delimiter, const int max_keys, dpl_vec_t **objectsp, dpl_vec_t **common_prefixesp, char **locationp) { DIR *dir = NULL; dpl_status_t ret, ret2; int iret; char path[MAXPATHLEN]; char objpath[MAXPATHLEN]; struct dirent entry, *entryp; struct stat st; dpl_vec_t *common_prefixes = NULL; dpl_vec_t *objects = NULL; dpl_common_prefix_t *common_prefix = NULL; dpl_object_t *object = NULL; char buf[MAXPATHLEN]; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); if (strcmp(delimiter, "/")) { ret = DPL_EINVAL; goto end; } snprintf(path, sizeof (path), "/%s/%s", ctx->base_path ? ctx->base_path : "", prefix ? prefix : ""); dir = opendir(path); if (NULL == dir) { ret = dpl_posix_map_errno(); perror("opendir"); goto end; } objects = dpl_vec_new(2, 2); if (NULL == objects) { ret = DPL_ENOMEM; goto end; } common_prefixes = dpl_vec_new(2, 2); if (NULL == common_prefixes) { ret = DPL_ENOMEM; goto end; } while (1) { iret = readdir_r(dir, &entry, &entryp); if (0 != iret) { ret = dpl_posix_map_errno(); perror("readdir"); goto end; } if (!entryp) break ; if (!strcmp(entryp->d_name, ".") || !strcmp(entryp->d_name, "..")) continue ; DPL_TRACE(ctx, DPL_TRACE_BACKEND, "%s", entryp->d_name); if (entryp->d_type == DT_DIR) { //this is a directory snprintf(buf, sizeof (buf), "%s%s/", prefix ? prefix : "", entryp->d_name); common_prefix = malloc(sizeof (*common_prefix)); if (NULL == common_prefix) { ret = DPL_ENOMEM; goto end; } memset(common_prefix, 0, sizeof (*common_prefix)); common_prefix->prefix = strdup(buf); if (NULL == common_prefix->prefix) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_vec_add(common_prefixes, common_prefix); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } common_prefix = NULL; } else { snprintf(buf, sizeof (buf), "%s%s", prefix ? prefix : "", entryp->d_name); object = malloc(sizeof (*object)); if (NULL == object) { ret = DPL_ENOMEM; goto end; } memset(object, 0, sizeof (*object)); object->path = strdup(buf); if (NULL == object->path) { ret = DPL_ENOMEM; goto end; } snprintf(objpath, sizeof(objpath), "/%s/%s", ctx->base_path ? ctx->base_path : "", object->path); iret = stat(objpath, &st); if (0 != iret) { // It might be a broken link -> ENOENT, not an error, size=0 if (errno != ENOENT) { // Do not map errno here, since it makes the whole listing fail, // and we don't want to thwart the meaning of the error for the directory. perror("stat"); ret = DPL_FAILURE; goto end; } st.st_size = 0; } object->size = st.st_size; object->last_modified = st.st_mtime; switch (entryp->d_type) { case DT_BLK: object->type = DPL_FTYPE_BLKDEV; break ; case DT_CHR: object->type = DPL_FTYPE_CHRDEV; break ; case DT_DIR: object->type = DPL_FTYPE_DIR; break ; case DT_FIFO: object->type = DPL_FTYPE_FIFO; break ; case DT_LNK: object->type = DPL_FTYPE_SYMLINK; break ; case DT_SOCK: object->type = DPL_FTYPE_SOCKET; break ; case DT_REG: object->type = DPL_FTYPE_REG; break ; case DT_UNKNOWN: default: object->type = DPL_FTYPE_UNDEF; break ; } ret2 = dpl_vec_add(objects, object); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } object = NULL; } } if (NULL != objectsp) { *objectsp = objects; objects = NULL; //consume it } if (NULL != common_prefixesp) { *common_prefixesp = common_prefixes; common_prefixes = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != object) free(object); if (NULL != common_prefix) free(common_prefix); if (NULL != objects) dpl_vec_objects_free(objects); if (NULL != common_prefixes) dpl_vec_common_prefixes_free(common_prefixes); if (NULL != dir) closedir(dir); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }
dpl_status_t dpl_posix_list_bucket(dpl_ctx_t *ctx, const char *bucket, const char *prefix, const char *delimiter, const int max_keys, dpl_vec_t **objectsp, dpl_vec_t **common_prefixesp, char **locationp) { DIR *dir = NULL; dpl_status_t ret, ret2; int iret; char path[MAXPATHLEN]; struct dirent entry, *entryp; dpl_vec_t *common_prefixes = NULL; dpl_vec_t *objects = NULL; dpl_common_prefix_t *common_prefix = NULL; dpl_object_t *object = NULL; char buf[MAXPATHLEN]; DPL_TRACE(ctx, DPL_TRACE_BACKEND, ""); if (strcmp(delimiter, "/")) { ret = DPL_EINVAL; goto end; } snprintf(path, sizeof (path), "/%s/%s", ctx->base_path ? ctx->base_path : "", prefix ? prefix : ""); dir = opendir(path); if (NULL == dir) { perror("opendir"); ret = DPL_FAILURE; goto end; } objects = dpl_vec_new(2, 2); if (NULL == objects) { ret = DPL_ENOMEM; goto end; } common_prefixes = dpl_vec_new(2, 2); if (NULL == common_prefixes) { ret = DPL_ENOMEM; goto end; } while (1) { iret = readdir_r(dir, &entry, &entryp); if (0 != iret) { perror("readdir"); ret = DPL_FAILURE; goto end; } if (!entryp) break ; if (!strcmp(entryp->d_name, ".") || !strcmp(entryp->d_name, "..")) continue ; DPL_TRACE(ctx, DPL_TRACE_BACKEND, "%s", entryp->d_name); if (entryp->d_type == DT_DIR) { //this is a directory snprintf(buf, sizeof (buf), "%s%s/", prefix ? prefix : "", entryp->d_name); common_prefix = malloc(sizeof (*common_prefix)); if (NULL == common_prefix) { ret = DPL_ENOMEM; goto end; } memset(common_prefix, 0, sizeof (*common_prefix)); common_prefix->prefix = strdup(buf); if (NULL == common_prefix->prefix) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_vec_add(common_prefixes, common_prefix); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } common_prefix = NULL; } else { snprintf(buf, sizeof (buf), "%s%s", prefix ? prefix : "", entryp->d_name); object = malloc(sizeof (*object)); if (NULL == object) { ret = DPL_ENOMEM; goto end; } memset(object, 0, sizeof (*object)); object->path = strdup(buf); if (NULL == object->path) { ret = DPL_ENOMEM; goto end; } ret2 = dpl_vec_add(objects, object); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } object = NULL; } } if (NULL != objectsp) { *objectsp = objects; objects = NULL; //consume it } if (NULL != common_prefixesp) { *common_prefixesp = common_prefixes; common_prefixes = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != object) free(object); if (NULL != common_prefix) free(common_prefix); if (NULL != objects) dpl_vec_objects_free(objects); if (NULL != common_prefixes) dpl_vec_common_prefixes_free(common_prefixes); if (NULL != dir) closedir(dir); DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret); return ret; }