static dpl_status_t dpl_vdir_opendir(dpl_ctx_t *ctx, char *bucket, dpl_ino_t ino, void **dir_hdlp) { dpl_dir_t *dir; int ret, ret2; DPL_TRACE(ctx, DPL_TRACE_VDIR, "opendir bucket=%s ino=%s", bucket, ino.key); dir = malloc(sizeof (*dir)); if (NULL == dir) { ret = DPL_FAILURE; goto end; } memset(dir, 0, sizeof (*dir)); dir->ctx = ctx; dir->ino = ino; //AWS prefers NULL for listing the root dir ret2 = dpl_list_bucket(ctx, bucket, !strcmp(ino.key, "") ? NULL : ino.key, ctx->delim, &dir->files, &dir->directories); if (DPL_SUCCESS != ret2) { DPLERR(0, "list_bucket failed %s:%s", bucket, ino.key); ret = DPL_FAILURE; goto end; } //printf("%s:%s n_files=%d n_dirs=%d\n", bucket, ino.key, dir->files->n_items, dir->directories->n_items); if (NULL != dir_hdlp) *dir_hdlp = dir; DPL_TRACE(dir->ctx, DPL_TRACE_VDIR, "dir_hdl=%p", dir); ret = DPL_SUCCESS; end: if (DPL_SUCCESS != ret) { if (NULL != dir->files) dpl_vec_objects_free(dir->files); if (NULL != dir->directories) dpl_vec_common_prefixes_free(dir->directories); if (NULL != dir) free(dir); } DPL_TRACE(ctx, DPL_TRACE_VDIR, "ret=%d", ret); return ret; }
dpl_status_t dpl_cdmi_put_buffered(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_dict_t *metadata, const dpl_sysmd_t *sysmd, unsigned int data_len, dpl_conn_t **connp) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_chunk_t chunk; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_PUT); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } chunk.buf = NULL; chunk.len = data_len; dpl_req_set_chunk(req, &chunk); //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); dpl_req_set_object_type(req, object_type); dpl_req_add_behavior(req, DPL_BEHAVIOR_EXPECT); if (NULL != metadata) { ret2 = dpl_req_add_metadata(req, metadata); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { if (NULL != headers_reply) //possible if continue succeeded connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "IN", data_len); if (NULL != connp) { *connp = conn; conn = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_list_bucket(dpl_ctx_t *ctx, const char *bucket, const char *prefix, const char *delimiter, dpl_vec_t **objectsp, dpl_vec_t **common_prefixesp) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; dpl_vec_t *common_prefixes = NULL; dpl_vec_t *objects = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); ret2 = dpl_req_set_resource(req, NULL != prefix ? prefix : "/"); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_set_object_type(req, DPL_FTYPE_DIR); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "OUT", data_len); objects = dpl_vec_new(2, 2); if (NULL == objects) { ret = DPL_FAILURE; goto end; } common_prefixes = dpl_vec_new(2, 2); if (NULL == common_prefixes) { ret = DPL_FAILURE; goto end; } ret = dpl_cdmi_parse_list_bucket(ctx, data_buf, data_len, prefix, objects, common_prefixes); if (DPL_SUCCESS != ret) { ret = DPL_FAILURE; goto end; } 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 != objects) dpl_vec_objects_free(objects); if (NULL != common_prefixes) dpl_vec_common_prefixes_free(common_prefixes); if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_delete(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_req_t *req = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_DELETE); ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "REQUEST", "DELETE", 0); ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_get_buffered(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_condition_t *condition, dpl_header_func_t header_func, dpl_buffer_func_t buffer_func, void *cb_arg) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; dpl_dict_t *headers_request = NULL; dpl_req_t *req = NULL; struct get_conven gc; memset(&gc, 0, sizeof (gc)); gc.header_func = header_func; gc.buffer_func = buffer_func; gc.cb_arg = cb_arg; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_add_behavior(req, DPL_BEHAVIOR_HTTP_COMPAT); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } //bucket emulation ret2 = dpl_dict_add(headers_request, "X-Scality-Bucket", bucket, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); gc.connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply_buffered(conn, 1, cb_get_header, cb_get_buffer, &gc); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); gc.connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } //caller is responsible for logging the event ret = DPL_SUCCESS; end: if (NULL != conn) { if (1 == gc.connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
dpl_status_t dpl_cdmi_get(dpl_ctx_t *ctx, const char *bucket, const char *resource, const char *subresource, dpl_ftype_t object_type, const dpl_condition_t *condition, char **data_bufp, unsigned int *data_lenp, dpl_dict_t **metadatap) { char *host; int ret, ret2; dpl_conn_t *conn = NULL; char header[1024]; u_int header_len; struct iovec iov[10]; int n_iov = 0; int connection_close = 0; char *data_buf = NULL; u_int data_len; dpl_dict_t *headers_request = NULL; dpl_dict_t *headers_reply = NULL; dpl_dict_t *metadata = NULL; dpl_req_t *req = NULL; req = dpl_req_new(ctx); if (NULL == req) { ret = DPL_ENOMEM; goto end; } dpl_req_set_method(req, DPL_METHOD_GET); if (NULL != bucket) { ret2 = dpl_req_set_bucket(req, bucket); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = dpl_req_set_resource(req, resource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != subresource) { ret2 = dpl_req_set_subresource(req, subresource); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != condition) { dpl_req_set_condition(req, condition); } //contact default host dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING); dpl_req_set_object_type(req, object_type); //build request ret2 = dpl_cdmi_req_build(req, &headers_request, NULL, NULL); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } host = dpl_dict_get_value(headers_request, "Host"); if (NULL == host) { ret = DPL_FAILURE; goto end; } conn = dpl_conn_open_host(ctx, host, ctx->port); if (NULL == conn) { ret = DPL_FAILURE; goto end; } ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len); if (DPL_SUCCESS != ret2) { ret = DPL_FAILURE; goto end; } iov[n_iov].iov_base = header; iov[n_iov].iov_len = header_len; n_iov++; //final crlf iov[n_iov].iov_base = "\r\n"; iov[n_iov].iov_len = 2; n_iov++; ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout); if (DPL_SUCCESS != ret2) { DPLERR(1, "writev failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } ret2 = dpl_read_http_reply(conn, 1, &data_buf, &data_len, &headers_reply); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; goto end; } else { DPLERR(0, "read http answer failed"); connection_close = 1; ret = DPL_ENOENT; //mapped to 404 goto end; } } else { connection_close = dpl_connection_close(ctx, headers_reply); } (void) dpl_log_event(ctx, "DATA", "OUT", data_len); if (NULL != data_bufp) { *data_bufp = data_buf; data_buf = NULL; //consume it } if (NULL != data_lenp) *data_lenp = data_len; if (NULL != metadatap) { *metadatap = metadata; metadata = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != data_buf) free(data_buf); if (NULL != conn) { if (1 == connection_close) dpl_conn_terminate(conn); else dpl_conn_release(conn); } if (NULL != metadata) dpl_dict_free(metadata); if (NULL != headers_reply) dpl_dict_free(headers_reply); if (NULL != headers_request) dpl_dict_free(headers_request); if (NULL != req) dpl_req_free(req); DPRINTF("ret=%d\n", ret); return ret; }
static dpl_status_t dpl_mkgen(dpl_ctx_t *ctx, char *locator, dpl_status_t (*cb)(dpl_ctx_t *, char *, dpl_ino_t, const char *)) { char *dir_name = NULL; dpl_ino_t parent_ino; int ret, ret2; char *nlocator = NULL; int delim_len = strlen(ctx->delim); char *bucket, *path; dpl_ino_t cur_ino; DPL_TRACE(ctx, DPL_TRACE_VDIR, "mkdir locator=%s", locator); nlocator = strdup(locator); if (NULL == nlocator) { ret = DPL_ENOMEM; goto end; } path = index(nlocator, ':'); if (NULL != path) { bucket = nlocator; *path++ = 0; } else { bucket = ctx->cur_bucket; path = nlocator; } cur_ino = dpl_cwd(ctx, bucket); ret2 = dpl_namei(ctx, path, bucket, cur_ino, &parent_ino, NULL, NULL); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { dir_name = dpl_strrstr(path, ctx->delim); if (NULL != dir_name) { *dir_name = 0; dir_name += delim_len; //fetch parent directory ret2 = dpl_namei(ctx, !strcmp(path, "") ? ctx->delim : path, bucket, cur_ino, NULL, &parent_ino, NULL); if (DPL_SUCCESS != ret2) { DPLERR(0, "dst parent dir resolve failed %s: %s\n", path, dpl_status_str(ret2)); ret = ret2; goto end; } } else { parent_ino = cur_ino; dir_name = path; } } else { DPLERR(0, "path resolve failed %s: %s (%d)\n", path, dpl_status_str(ret2), ret2); ret = ret2; goto end; } } else { ret = DPL_EEXIST; goto end; } ret2 = cb(ctx, bucket, parent_ino, dir_name); if (0 != ret2) { DPLERR(0, "mkdir failed"); ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != nlocator) free(nlocator); return ret; }
dpl_status_t dpl_chdir(dpl_ctx_t *ctx, char *locator) { int ret, ret2; dpl_ino_t obj_ino; dpl_ftype_t obj_type; char *nlocator = NULL; dpl_ino_t cur_ino; char *nbucket; char *path, *bucket; DPL_TRACE(ctx, DPL_TRACE_VDIR, "chdir locator=%s", locator); nlocator = strdup(locator); if (NULL == nlocator) { ret = DPL_ENOMEM; goto end; } path = index(nlocator, ':'); if (NULL != path) { bucket = nlocator; *path++ = 0; } else { bucket = ctx->cur_bucket; path = nlocator; } cur_ino = dpl_cwd(ctx, bucket); ret2 = dpl_namei(ctx, path, bucket, cur_ino, NULL, &obj_ino, &obj_type); if (0 != ret2) { DPLERR(0, "path resolve failed %s: %s (%d)", path, dpl_status_str(ret2), ret2); ret = ret2; goto end; } if (DPL_FTYPE_DIR != obj_type) { DPLERR(0, "not a directory"); ret = DPL_EINVAL; goto end; } if (strcmp(bucket, ctx->cur_bucket)) { nbucket = strdup(bucket); if (NULL == nbucket) { ret = DPL_ENOMEM; goto end; } free(ctx->cur_bucket); ctx->cur_bucket = nbucket; } ret2 = dpl_dict_add(ctx->cwds, ctx->cur_bucket, obj_ino.key, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != nlocator) free(nlocator); return ret; }
/** * open a directory * * @param ctx * @param locator [bucket:]path * @param dir_hdlp * * @return */ dpl_status_t dpl_opendir(dpl_ctx_t *ctx, char *locator, void **dir_hdlp) { int ret, ret2; dpl_ino_t obj_ino; dpl_ftype_t obj_type; char *nlocator = NULL; char *bucket, *path; dpl_ino_t cur_ino; DPL_TRACE(ctx, DPL_TRACE_VDIR, "opendir locator=%s", locator); nlocator = strdup(locator); if (NULL == nlocator) { ret = DPL_ENOMEM; goto end; } path = index(nlocator, ':'); if (NULL != path) { bucket = nlocator; *path++ = 0; } else { bucket = ctx->cur_bucket; path = nlocator; } cur_ino = dpl_cwd(ctx, bucket); ret2 = dpl_namei(ctx, path, bucket, cur_ino, NULL, &obj_ino, &obj_type); if (0 != ret2) { DPLERR(0, "path resolve failed %s", path); ret = ret2; goto end; } if (DPL_FTYPE_REG == obj_type) { DPLERR(0, "cannot list a file"); ret = DPL_EINVAL; goto end; } ret2 = dpl_vdir_opendir(ctx, bucket, obj_ino, dir_hdlp); if (DPL_SUCCESS != ret2) { DPLERR(0, "unable to open %s:%s", bucket, obj_ino.key); ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != nlocator) free(nlocator); return ret; }
static dpl_status_t dpl_vdir_lookup(dpl_ctx_t *ctx, char *bucket, dpl_ino_t parent_ino, const char *obj_name, dpl_ino_t *obj_inop, dpl_ftype_t *obj_typep) { int ret, ret2; dpl_vec_t *files = NULL; dpl_vec_t *directories = NULL; int i; dpl_ino_t obj_ino; dpl_ftype_t obj_type; int delim_len = strlen(ctx->delim); int obj_name_len = strlen(obj_name); memset(&obj_ino, 0, sizeof (obj_ino)); DPL_TRACE(ctx, DPL_TRACE_VDIR, "lookup bucket=%s parent_ino=%s obj_name=%s", bucket, parent_ino.key, obj_name); if (!strcmp(obj_name, ".")) { if (NULL != obj_inop) *obj_inop = parent_ino; if (NULL != obj_typep) *obj_typep = DPL_FTYPE_DIR; ret = DPL_SUCCESS; goto end; } else if (!strcmp(obj_name, "..")) { char *p, *p2; if (!strcmp(parent_ino.key, "")) { //silent success for root dir if (NULL != obj_inop) *obj_inop = DPL_ROOT_INO; if (NULL != obj_typep) *obj_typep = DPL_FTYPE_DIR; ret = DPL_SUCCESS; goto end; } obj_ino = parent_ino; p = dpl_strrstr(obj_ino.key, ctx->delim); if (NULL == p) { fprintf(stderr, "parent key shall contain delim %s\n", ctx->delim); ret = DPL_FAILURE; goto end; } p -= delim_len; for (p2 = p;p2 > obj_ino.key;p2--) { if (!strncmp(p2, ctx->delim, delim_len)) { DPRINTF("found delim\n"); p2 += delim_len; break ; } } *p2 = 0; if (NULL != obj_inop) *obj_inop = obj_ino; if (NULL != obj_typep) *obj_typep = DPL_FTYPE_DIR; ret = DPL_SUCCESS; goto end; } //AWS do not like "" as a prefix ret2 = dpl_list_bucket(ctx, bucket, !strcmp(parent_ino.key, "") ? NULL : parent_ino.key, ctx->delim, &files, &directories); if (DPL_SUCCESS != ret2) { DPLERR(0, "list_bucket failed %s:%s", bucket, parent_ino.key); ret = DPL_FAILURE; goto end; } for (i = 0;i < files->n_items;i++) { dpl_object_t *obj = (dpl_object_t *) files->array[i]; int key_len; char *p; p = dpl_strrstr(obj->key, ctx->delim); if (NULL != p) p += delim_len; else p = obj->key; DPRINTF("cmp obj_key=%s obj_name=%s\n", p, obj_name); if (!strcmp(p, obj_name)) { DPRINTF("ok\n"); key_len = strlen(obj->key); if (key_len >= DPL_MAXNAMLEN) { DPLERR(0, "key is too long"); ret = DPL_FAILURE; goto end; } memcpy(obj_ino.key, obj->key, key_len); obj_ino.key[key_len] = 0; if (key_len >= delim_len && !strcmp(obj->key + key_len - delim_len, ctx->delim)) obj_type = DPL_FTYPE_DIR; else obj_type = DPL_FTYPE_REG; if (NULL != obj_inop) *obj_inop = obj_ino; if (NULL != obj_typep) *obj_typep = obj_type; ret = DPL_SUCCESS; goto end; } } for (i = 0;i < directories->n_items;i++) { dpl_common_prefix_t *prefix = (dpl_common_prefix_t *) directories->array[i]; int key_len; char *p, *p2; p = dpl_strrstr(prefix->prefix, ctx->delim); if (NULL == p) { fprintf(stderr, "prefix %s shall contain delim %s\n", prefix->prefix, ctx->delim); continue ; } DPRINTF("p='%s'\n", p); p -= delim_len; for (p2 = p;p2 > prefix->prefix;p2--) { DPRINTF("p2='%s'\n", p2); if (!strncmp(p2, ctx->delim, delim_len)) { DPRINTF("found delim\n"); p2 += delim_len; break ; } } key_len = p - p2 + 1; DPRINTF("cmp (prefix=%s) prefix=%.*s obj_name=%s\n", prefix->prefix, key_len, p2, obj_name); if (key_len == obj_name_len && !strncmp(p2, obj_name, obj_name_len)) { DPRINTF("ok\n"); key_len = strlen(prefix->prefix); if (key_len >= DPL_MAXNAMLEN) { DPLERR(0, "key is too long"); ret = DPL_FAILURE; goto end; } memcpy(obj_ino.key, prefix->prefix, key_len); obj_ino.key[key_len] = 0; obj_type = DPL_FTYPE_DIR; if (NULL != obj_inop) *obj_inop = obj_ino; if (NULL != obj_typep) *obj_typep = obj_type; ret = DPL_SUCCESS; goto end; } } ret = DPL_ENOENT; end: if (NULL != files) dpl_vec_objects_free(files); if (NULL != directories) dpl_vec_common_prefixes_free(directories); DPL_TRACE(ctx, DPL_TRACE_VDIR, "ret=%d", ret); return ret; }
static dpl_status_t dpl_vdir_readdir(void *dir_hdl, dpl_dirent_t *dirent) { dpl_dir_t *dir = (dpl_dir_t *) dir_hdl; char *name; int name_len; int key_len; int delim_len = strlen(dir->ctx->delim); DPL_TRACE(dir->ctx, DPL_TRACE_VDIR, "readdir dir_hdl=%p files_cursor=%d directories_cursor=%d", dir_hdl, dir->files_cursor, dir->directories_cursor); memset(dirent, 0, sizeof (*dirent)); if (dir->files_cursor >= dir->files->n_items) { if (dir->directories_cursor >= dir->directories->n_items) { DPLERR(0, "beyond cursors"); return DPL_ENOENT; } else { dpl_common_prefix_t *prefix; prefix = (dpl_common_prefix_t *) dir->directories->array[dir->directories_cursor]; key_len = strlen(prefix->prefix); name = prefix->prefix + strlen(dir->ino.key); name_len = strlen(name); if (name_len >= DPL_MAXNAMLEN) { DPLERR(0, "name is too long"); return DPL_FAILURE; } memcpy(dirent->name, name, name_len); dirent->name[name_len] = 0; if (key_len >= DPL_MAXPATHLEN) { DPLERR(0, "key is too long"); return DPL_FAILURE; } memcpy(dirent->ino.key, prefix->prefix, key_len); dirent->ino.key[key_len] = 0; dirent->type = DPL_FTYPE_DIR; dirent->last_modified = 0; //? dirent->size = 0; dir->directories_cursor++; return DPL_SUCCESS; } } else { dpl_object_t *obj; obj = (dpl_object_t *) dir->files->array[dir->files_cursor]; key_len = strlen(obj->key); name = obj->key + strlen(dir->ino.key); name_len = strlen(name); if (!strcmp(name, "/") || !strcmp(name, "")) { memcpy(dirent->name, ".", 1); dirent->name[1] = 0; } else { if (name_len >= DPL_MAXNAMLEN) { DPLERR(0, "name is too long"); return DPL_FAILURE; } memcpy(dirent->name, name, name_len); dirent->name[name_len] = 0; } if (key_len >= DPL_MAXPATHLEN) { DPLERR(0, "key is too long"); return DPL_FAILURE; } memcpy(dirent->ino.key, obj->key, key_len); dirent->ino.key[key_len] = 0; if (key_len >= delim_len && !strcmp(obj->key + key_len - delim_len, dir->ctx->delim)) dirent->type = DPL_FTYPE_DIR; else dirent->type = DPL_FTYPE_REG; dirent->last_modified = obj->last_modified; dirent->size = obj->size; dir->files_cursor++; return DPL_SUCCESS; } }
dpl_status_t dpl_rmdir(dpl_ctx_t *ctx, char *locator) { int ret, ret2; char *dir_name = NULL; dpl_ino_t parent_ino; int delim_len = strlen(ctx->delim); char *nlocator = NULL; char *bucket, *path; dpl_ino_t cur_ino; DPL_TRACE(ctx, DPL_TRACE_VDIR, "rmdir locator=%s", locator); nlocator = strdup(locator); if (NULL == nlocator) { ret = DPL_ENOMEM; goto end; } path = index(nlocator, ':'); if (NULL != path) { bucket = nlocator; *path++ = 0; } else { bucket = ctx->cur_bucket; path = nlocator; } cur_ino = dpl_cwd(ctx, bucket); dir_name = dpl_strrstr(path, ctx->delim); if (NULL != dir_name) dir_name += delim_len; else dir_name = path; ret2 = dpl_namei(ctx, path, bucket, cur_ino, &parent_ino, NULL, NULL); if (DPL_SUCCESS != ret2) { DPLERR(0, "path resolved failed"); ret = ret2; goto end; } ret2 = dpl_vdir_rmdir(ctx, bucket, parent_ino, dir_name); if (DPL_SUCCESS != ret2) { DPLERR(0, "rmdir failed"); ret = ret2; goto end; } ret = DPL_SUCCESS; end: if (NULL != nlocator) free(nlocator); return ret; }