int cmd_mb(int argc, char **argv) { int ret; char opt; char *bucket; char *resource; dpl_canned_acl_t canned_acl = DPL_CANNED_ACL_PRIVATE; int Aflag = 0; int i; dpl_location_constraint_t location_constraint = DPL_LOCATION_CONSTRAINT_US_STANDARD; int Lflag = 0; var_set("status", "1", VAR_CMD_SET, NULL); optind = 0; while ((opt = getopt(argc, argv, usage_getoptstr(mb_usage))) != -1) switch (opt) { case 'l': location_constraint = dpl_location_constraint(optarg); if (-1 == location_constraint) { fprintf(stderr, "bad location constraint '%s'\n", optarg); return SHELL_CONT; } break ; case 'L': Lflag = 1; break ; case 'a': canned_acl = dpl_canned_acl(optarg); if (-1 == canned_acl) { fprintf(stderr, "bad canned acl '%s'\n", optarg); return SHELL_CONT; } break ; case 'A': Aflag = 1; break ; case '?': default: usage_help(&mb_cmd); return SHELL_CONT; } argc -= optind; argv += optind; if (1 == Aflag) { for (i = 0;i < DPL_N_CANNED_ACL;i++) printf("%s\n", dpl_canned_acl_str(i)); return SHELL_CONT; } if (1 == Lflag) { for (i = 0;i < DPL_N_LOCATION_CONSTRAINT;i++) printf("%s\n", dpl_location_constraint_str(i)); return SHELL_CONT; } if (1 != argc) { usage_help(&mb_cmd); return SHELL_CONT; } bucket = argv[0]; resource = "/"; ret = dpl_make_bucket(ctx, bucket, location_constraint, canned_acl); if (DPL_SUCCESS != ret) { fprintf(stderr, "status: %s (%d)\n", dpl_status_str(ret), ret); return SHELL_CONT; } var_set("status", "0", VAR_CMD_SET, NULL); return SHELL_CONT; }
/** * build headers from request * * @param req * @param headersp * * @return */ dpl_status_t dpl_s3_req_build(const dpl_req_t *req, dpl_s3_req_mask_t req_mask, dpl_dict_t **headersp) { dpl_dict_t *headers = NULL; int ret, ret2; const char *method = dpl_method_str(req->method); char resource_ue[DPL_URL_LENGTH(strlen(req->resource) + (req->subresource ? strlen(req->subresource) : 0)) + 1]; DPL_TRACE(req->ctx, DPL_TRACE_REQ, "req_build method=%s bucket=%s resource=%s subresource=%s", method, req->bucket, req->resource, req->subresource); //resource if ('/' != req->resource[0]) { resource_ue[0] = '/'; dpl_url_encode(req->resource, resource_ue + 1); } else { resource_ue[0] = '/'; //some servers do not like encoded slash dpl_url_encode(req->resource + 1, resource_ue + 1); } // Append subresource if (req->subresource) { dpl_url_encode("?", resource_ue + strlen(resource_ue)); dpl_url_encode(req->subresource, resource_ue + strlen(resource_ue)); } headers = dpl_dict_new(13); if (NULL == headers) { ret = DPL_ENOMEM; goto end; } /* * per method headers */ if (DPL_METHOD_GET == req->method || DPL_METHOD_HEAD == req->method) { if (req->range_enabled) { ret2 = dpl_add_range_to_headers(&req->range, headers); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } ret2 = add_conditions_to_headers(&req->condition, headers, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } else if (DPL_METHOD_PUT == req->method || DPL_METHOD_POST == req->method) { char buf[64]; if (NULL != req->cache_control) { ret2 = dpl_dict_add(headers, "Cache-Control", req->cache_control, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != req->content_disposition) { ret2 = dpl_dict_add(headers, "Content-Disposition", req->content_disposition, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (NULL != req->content_encoding) { ret2 = dpl_dict_add(headers, "Content-Encoding", req->content_encoding, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (req->behavior_flags & DPL_BEHAVIOR_MD5) { MD5_CTX ctx; u_char digest[MD5_DIGEST_LENGTH]; char b64_digest[DPL_BASE64_LENGTH(MD5_DIGEST_LENGTH) + 1]; u_int b64_digest_len; if (!req->data_enabled) { ret = DPL_EINVAL; goto end; } MD5_Init(&ctx); MD5_Update(&ctx, req->data_buf, req->data_len); MD5_Final(digest, &ctx); b64_digest_len = dpl_base64_encode(digest, MD5_DIGEST_LENGTH, (u_char *) b64_digest); b64_digest[b64_digest_len] = 0; ret2 = dpl_dict_add(headers, "Content-MD5", b64_digest, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (req->data_enabled) { snprintf(buf, sizeof (buf), "%u", req->data_len); ret2 = dpl_dict_add(headers, "Content-Length", buf, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } if (NULL != req->content_type) { ret2 = dpl_dict_add(headers, "Content-Type", req->content_type, 0); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } if (req->behavior_flags & DPL_BEHAVIOR_EXPECT) { ret2 = dpl_dict_add(headers, "Expect", "100-continue", 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } if (DPL_CANNED_ACL_UNDEF != req->canned_acl) { char *str; str = dpl_canned_acl_str(req->canned_acl); if (NULL == str) { ret = DPL_FAILURE; goto end; } ret2 = dpl_dict_add(headers, "x-amz-acl", str, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } ret2 = add_metadata_to_headers(req->metadata, headers); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (DPL_STORAGE_CLASS_UNDEF != req->storage_class) { char *str; str = dpl_storage_class_str(req->storage_class); if (NULL == str) { ret = DPL_FAILURE; goto end; } ret2 = dpl_dict_add(headers, "x-amz-storage-class", str, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } /* * copy */ if (req_mask & DPL_S3_REQ_COPY) { ret2 = add_source_to_headers(req, headers); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (DPL_COPY_DIRECTIVE_UNDEF != req->copy_directive) { char *str; switch (req->copy_directive) { case DPL_COPY_DIRECTIVE_UNDEF: case DPL_COPY_DIRECTIVE_COPY: case DPL_COPY_DIRECTIVE_LINK: case DPL_COPY_DIRECTIVE_SYMLINK: case DPL_COPY_DIRECTIVE_MOVE: case DPL_COPY_DIRECTIVE_MKDENT: case DPL_COPY_DIRECTIVE_RMDENT: case DPL_COPY_DIRECTIVE_MVDENT: ret = DPL_ENOTSUPP; goto end; case DPL_COPY_DIRECTIVE_METADATA_REPLACE: str = "REPLACE"; break ; } ret2 = dpl_dict_add(headers, "x-amz-metadata-directive", str, 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } ret2 = add_conditions_to_headers(&req->copy_source_condition, headers, 1); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } } } else if (DPL_METHOD_DELETE == req->method) { //XXX todo x-amz-mfa } else { ret = DPL_EINVAL; goto end; } /* * common headers */ if (req->behavior_flags & DPL_BEHAVIOR_KEEP_ALIVE) { ret2 = dpl_dict_add(headers, "Connection", "Keep-Alive", 0); if (DPL_SUCCESS != ret2) { ret = DPL_ENOMEM; goto end; } } ret2 = add_date_to_headers(headers); if (DPL_SUCCESS != ret2) { ret = ret2; goto end; } if (NULL != headersp) { *headersp = headers; headers = NULL; //consume it } ret = DPL_SUCCESS; end: if (NULL != headers) dpl_dict_free(headers); return ret; }
int cmd_put(int argc, char **argv) { int ret; char opt; dpl_canned_acl_t canned_acl = DPL_CANNED_ACL_PRIVATE; int Aflag = 0; int i; int fd = -1; dpl_dict_t *metadata = NULL; char *local_file = NULL; char *remote_file = NULL; dpl_vfile_t *vfile = NULL; size_t block_size = 64*1024; ssize_t cc; struct stat st; int kflag = 0; char *buf; var_set("status", "1", VAR_CMD_SET, NULL); optind = 0; while ((opt = getopt(argc, argv, usage_getoptstr(put_usage))) != -1) switch (opt) { case 'k': kflag = 1; break ; case 'm': metadata = dpl_parse_metadata(optarg); if (NULL == metadata) { fprintf(stderr, "error parsing metadata\n"); return SHELL_CONT; } break ; case 'a': canned_acl = dpl_canned_acl(optarg); if (-1 == canned_acl) { fprintf(stderr, "bad canned acl '%s'\n", optarg); return SHELL_CONT; } break ; case 'A': Aflag = 1; break ; case '?': default: usage_help(&put_cmd); return SHELL_CONT; } argc -= optind; argv += optind; if (1 == Aflag) { for (i = 0;i < DPL_N_CANNED_ACL;i++) printf("%s\n", dpl_canned_acl_str(i)); return SHELL_CONT; } if (2 == argc) { char *p, *p2; local_file = argv[0]; remote_file = argv[1]; p = index(remote_file, ':'); if (NULL != p) { p++; if (!strcmp(p, "")) { p2 = rindex(local_file, '/'); if (NULL != p2) { p2++; strcat(remote_file, p2); } else { strcat(remote_file, local_file); } } } } else if (1 == argc) { local_file = argv[0]; remote_file = rindex(local_file, '/'); if (NULL != remote_file) remote_file++; else remote_file = local_file; } else { usage_help(&put_cmd); return SHELL_CONT; } fd = open(local_file, O_RDONLY); if (-1 == fd) { perror("open"); goto end; } buf = alloca(block_size); ret = fstat(fd, &st); if (-1 == ret) { perror("fstat"); return SHELL_CONT; } ret = dpl_openwrite(ctx, remote_file, DPL_VFILE_FLAG_CREAT | (1 == kflag ? DPL_VFILE_FLAG_ENCRYPT : DPL_VFILE_FLAG_MD5), metadata, canned_acl, st.st_size, &vfile); if (DPL_SUCCESS != ret) { fprintf(stderr, "status: %s (%d)\n", dpl_status_str(ret), ret); return SHELL_CONT; } while (1) { cc = read(fd, buf, block_size); if (-1 == cc) { perror("read"); return -1; } if (0 == cc) { break ; } ret = dpl_write(vfile, buf, cc); if (DPL_SUCCESS != ret) { fprintf(stderr, "write failed\n"); return SHELL_CONT; } if (1 == hash) { fprintf(stderr, "#"); fflush(stderr); } } ret = dpl_close(vfile); if (DPL_SUCCESS != ret) { fprintf(stderr, "close failed %s (%d)\n", dpl_status_str(ret), ret); return SHELL_CONT; } vfile = NULL; var_set("status", "0", VAR_CMD_SET, NULL); end: if (-1 != fd) close(fd); if (NULL != metadata) dpl_dict_free(metadata); if (NULL != vfile) dpl_close(vfile); return SHELL_CONT; }