From 2cda77ecda9c93a03329256744b19a237f92b810 Mon Sep 17 00:00:00 2001 From: Bryan Ischo Date: Mon, 11 Aug 2008 11:21:12 +0000 Subject: * Incorporated fixes submitted by Bryan Donlan : - Fixed missing return statement after error in S3_list_bucket - Fixed integer types in string functions - Added flags to S3_initialize(), and be sure to call curl_global_init() and curl_global_cleanup() * Changed s3 utility to use path-style URI as default, but to refuse to create a bucket which fails virtual-host-style validation unless the -f (--force) option is passed to s3 * Allow S3_initialize() to be called more than once with no side effects, as long as S3_deinitialize() is called the same number of times when libs3 is being shut down --- src/bucket.c | 1 + src/general.c | 15 +++++++++++++-- src/request.c | 19 ++++++++++++++----- src/s3.c | 60 +++++++++++++++++++++++++++++++++++++++++------------------ 4 files changed, 70 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/bucket.c b/src/bucket.c index 5500c85..47f0ce2 100644 --- a/src/bucket.c +++ b/src/bucket.c @@ -646,6 +646,7 @@ void S3_list_bucket(const S3BucketContext *bucketContext, const char *prefix, if (!urlEncode(encoded, value, 1024)) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ + return; \ } \ string_buffer_append(queryParams, encoded, strlen(encoded), \ fit); \ diff --git a/src/general.c b/src/general.c index 7ea458a..329b0a0 100644 --- a/src/general.c +++ b/src/general.c @@ -36,6 +36,8 @@ #include "simplexml.h" #include "util.h" +static int initializeCountG = 0; + typedef struct S3Mutex CRYPTO_dynlock_value; static struct S3Mutex **pLocksG; @@ -135,8 +137,13 @@ S3Status S3_initialize(const char *userAgentInfo, S3MutexCreateCallback *mutexCreateCallback, S3MutexLockCallback *mutexLockCallback, S3MutexUnlockCallback *mutexUnlockCallback, - S3MutexDestroyCallback *mutexDestroyCallback) + S3MutexDestroyCallback *mutexDestroyCallback, + int flags) { + if (initializeCountG++) { + return S3StatusOK; + } + mutexCreateCallbackG = mutexCreateCallback; mutexLockCallbackG = mutexLockCallback; mutexUnlockCallbackG = mutexUnlockCallback; @@ -165,7 +172,7 @@ S3Status S3_initialize(const char *userAgentInfo, CRYPTO_set_dynlock_lock_callback(dynlock_lock); CRYPTO_set_dynlock_destroy_callback(dynlock_destroy); - S3Status status = request_api_initialize(userAgentInfo); + S3Status status = request_api_initialize(userAgentInfo, flags); if (status != S3StatusOK) { deinitialize_locks(); return status; @@ -177,6 +184,10 @@ S3Status S3_initialize(const char *userAgentInfo, void S3_deinitialize() { + if (--initializeCountG) { + return; + } + request_api_deinitialize(); deinitialize_locks(); diff --git a/src/request.c b/src/request.c index a64c7ae..6dabdfe 100644 --- a/src/request.c +++ b/src/request.c @@ -480,12 +480,15 @@ static S3Status compose_standard_headers(const RequestParams *params, if (params->getConditions && (params->startByte || params->byteCount)) { if (params->byteCount) { snprintf(values->rangeHeader, sizeof(values->rangeHeader), - "Range: bytes=%llu-%llu", params->startByte, - (params->startByte + params->byteCount - 1)); + "Range: bytes=%llu-%llu", + (unsigned long long) params->startByte, + (unsigned long long) (params->startByte + + params->byteCount - 1)); } else { snprintf(values->rangeHeader, sizeof(values->rangeHeader), - "Range: bytes=%llu-", params->startByte); + "Range: bytes=%llu-", + (unsigned long long) params->startByte); } } else { @@ -865,7 +868,7 @@ static S3Status setup_curl(Request *request, if (params->httpRequestType == HttpRequestTypePUT) { char header[256]; snprintf(header, sizeof(header), "Content-Length: %llu", - params->toS3CallbackTotalSize); + (unsigned long long) params->toS3CallbackTotalSize); request->headers = curl_slist_append(request->headers, header); request->headers = curl_slist_append(request->headers, "Transfer-Encoding:"); @@ -1034,8 +1037,14 @@ static void request_release(Request *request) } -S3Status request_api_initialize(const char *userAgentInfo) +S3Status request_api_initialize(const char *userAgentInfo, int flags) { + if (curl_global_init(CURL_GLOBAL_ALL & + ~((flags & S3_INIT_WINSOCK) ? 0 : CURL_GLOBAL_WIN32)) + != CURLE_OK) { + return S3StatusInternalError; + } + if (!(requestStackMutexG = mutex_create())) { return S3StatusFailedToCreateMutex; } diff --git a/src/s3.c b/src/s3.c index 18d91cf..8d1ff55 100644 --- a/src/s3.c +++ b/src/s3.c @@ -57,9 +57,10 @@ extern int fileno(FILE *); // Command-line options, saved as globals ------------------------------------ +static int forceG = 0; static int showResponsePropertiesG = 0; static S3Protocol protocolG = S3ProtocolHTTPS; -static S3UriStyle uriStyleG = S3UriStyleVirtualHost; +static S3UriStyle uriStyleG = S3UriStylePath; static int retriesG = 5; @@ -132,7 +133,8 @@ static char errorDetailsG[4096] = { 0 }; static void S3_init() { S3Status status; - if ((status = S3_initialize("s3", 0, 0, 0, 0, 0)) != S3StatusOK) { + if ((status = S3_initialize("s3", 0, 0, 0, 0, 0, S3_INIT_ALL)) + != S3StatusOK) { fprintf(stderr, "Failed to initialize libs3: %s\n", S3_get_status_name(status)); exit(-1); @@ -158,9 +160,10 @@ static void usageExit(FILE *out) "\n Options:\n" "\n" " Command Line:\n" -"\n" -" -p/--path-style : use path-style URIs (default is " - "virtual-host-style)\n" +"\n" +" -f/--force : force operation despite warnings\n" +" -h/--vhost-style : use virtual-host-style URIs (default is " + "path-style)\n" " -u/--unencrypted : unencrypted (use HTTP instead of HTTPS)\n" " -s/--show-properties : show response properties on stdout\n" " -r/--retries : retry retryable failures this number of times\n" @@ -655,7 +658,8 @@ static int should_retry() static struct option longOptionsG[] = { - { "path-style", no_argument, 0, 'p' }, + { "force", no_argument, 0, 'f' }, + { "vhost-style", no_argument, 0, 'h' }, { "unencrypted", no_argument, 0, 'u' }, { "show-proerties", no_argument, 0, 's' }, { "retries", required_argument, 0, 'r' }, @@ -684,7 +688,8 @@ static S3Status responsePropertiesCallback print_nonnull("Request-Id", requestId); print_nonnull("Request-Id-2", requestId2); if (properties->contentLength > 0) { - printf("Content-Length: %lld\n", properties->contentLength); + printf("Content-Length: %lld\n", + (unsigned long long) properties->contentLength); } print_nonnull("Server", server); print_nonnull("ETag", eTag); @@ -913,6 +918,16 @@ static void create_bucket(int argc, char **argv, int optind) const char *bucketName = argv[optind++]; + if (!forceG && (S3_validate_bucket_name + (bucketName, S3UriStyleVirtualHost) != S3StatusOK)) { + fprintf(stderr, "\nWARNING: Bucket name is not valid for " + "virtual-host style URI access.\n"); + fprintf(stderr, "Bucket not created. Use -f option to force the " + "bucket to be created despite\n"); + fprintf(stderr, "this warning.\n\n"); + exit(-1); + } + const char *locationConstraint = 0; S3CannedAcl cannedAcl = S3CannedAclPrivate; while (optind < argc) { @@ -1079,7 +1094,7 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker, printf("\nKey: %s\n", content->key); printf("Last Modified: %s\n", timebuf); printf("ETag: %s\n", content->eTag); - printf("Size: %llu\n", content->size); + printf("Size: %llu\n", (unsigned long long) content->size); if (content->ownerId) { printf("Owner ID: %s\n", content->ownerId); } @@ -1092,10 +1107,11 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker, gmtime(&(content->lastModified))); char sizebuf[16]; if (content->size < 100000) { - sprintf(sizebuf, "%5lld", content->size); + sprintf(sizebuf, "%5llu", (unsigned long long) content->size); } else if (content->size < (1024 * 1024)) { - sprintf(sizebuf, "%4lldK", content->size / 1024); + sprintf(sizebuf, "%4lluK", + ((unsigned long long) content->size) / 1024ULL); } else if (content->size < (10 * 1024 * 1024)) { float f = content->size; @@ -1103,7 +1119,9 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker, sprintf(sizebuf, "%1.2fM", f); } else if (content->size < (1024 * 1024 * 1024)) { - sprintf(sizebuf, "%4lldM", content->size / (1024 * 1024)); + sprintf(sizebuf, "%4lluM", + ((unsigned long long) content->size) / + (1024ULL * 1024ULL)); } else { float f = (content->size / 1024); @@ -1319,7 +1337,8 @@ static int putObjectDataCallback(int bufferSize, char *buffer, if (data->contentLength && !data->noStatus) { // Avoid a weird bug in MingW, which won't print the second integer // value properly when it's in the same call, so print separately - printf("%llu bytes remaining ", data->contentLength); + printf("%llu bytes remaining ", + (unsigned long long) data->contentLength); printf("(%d%% complete) ...\n", (int) (((data->originalContentLength - data->contentLength) * 100) / @@ -1408,7 +1427,8 @@ static void put_object(int argc, char **argv, int optind) else if (!strncmp(param, X_AMZ_META_PREFIX, X_AMZ_META_PREFIX_LEN)) { if (metaPropertiesCount == S3_MAX_METADATA_COUNT) { fprintf(stderr, "\nERROR: Too many x-amz-meta- properties, " - "limit %d: %s\n", S3_MAX_METADATA_COUNT, param); + "limit %lu: %s\n", + (unsigned long) S3_MAX_METADATA_COUNT, param); usageExit(stderr); } char *name = &(param[X_AMZ_META_PREFIX_LEN]); @@ -1559,7 +1579,7 @@ static void put_object(int argc, char **argv, int optind) } else if (data.contentLength) { fprintf(stderr, "\nERROR: Failed to read remaining %llu bytes from " - "input\n", data.contentLength); + "input\n", (unsigned long long) data.contentLength); } S3_deinitialize(); @@ -1654,7 +1674,8 @@ static void copy_object(int argc, char **argv, int optind) else if (!strncmp(param, X_AMZ_META_PREFIX, X_AMZ_META_PREFIX_LEN)) { if (metaPropertiesCount == S3_MAX_METADATA_COUNT) { fprintf(stderr, "\nERROR: Too many x-amz-meta- properties, " - "limit %d: %s\n", S3_MAX_METADATA_COUNT, param); + "limit %lu: %s\n", + (unsigned long) S3_MAX_METADATA_COUNT, param); usageExit(stderr); } char *name = &(param[X_AMZ_META_PREFIX_LEN]); @@ -2252,7 +2273,7 @@ int main(int argc, char **argv) // Parse args while (1) { int index = 0; - int c = getopt_long(argc, argv, "pusr:", longOptionsG, &index); + int c = getopt_long(argc, argv, "fhusr:", longOptionsG, &index); if (c == -1) { // End of options @@ -2260,8 +2281,11 @@ int main(int argc, char **argv) } switch (c) { - case 'p': - uriStyleG = S3UriStylePath; + case 'f': + forceG = 1; + break; + case 'h': + uriStyleG = S3UriStyleVirtualHost; break; case 'u': protocolG = S3ProtocolHTTP; -- cgit v1.2.1