diff options
author | Bryan Ischo <bryan@ischo.com> | 2008-07-21 12:28:51 +0000 |
---|---|---|
committer | Bryan Ischo <bryan@ischo.com> | 2008-07-21 12:28:51 +0000 |
commit | 8a2f22506a4e3a8f07356aaa3a223428243acda4 (patch) | |
tree | 50a226caf30348afc47a227295f85511f2692c0d /src | |
parent | 5b2d5978bfea855912ba38e32985cee8c0f35a89 (diff) | |
download | ceph-libs3-8a2f22506a4e3a8f07356aaa3a223428243acda4.tar.gz |
* Removed http response code from complete callback (libs3 users should only
care about the actual response code)
* Cleaned up some stuff
* Added S3_status_is_retryable
Diffstat (limited to 'src')
-rw-r--r-- | src/acl.c | 18 | ||||
-rw-r--r-- | src/bucket.c | 39 | ||||
-rw-r--r-- | src/general.c | 23 | ||||
-rw-r--r-- | src/object.c | 9 | ||||
-rw-r--r-- | src/request.c | 128 | ||||
-rw-r--r-- | src/request_context.c | 23 | ||||
-rw-r--r-- | src/s3.c | 223 | ||||
-rw-r--r-- | src/service.c | 9 | ||||
-rw-r--r-- | src/simplexml.c | 2 |
9 files changed, 255 insertions, 219 deletions
@@ -73,7 +73,6 @@ static S3Status getAclDataCallback(int bufferSize, const char *buffer, static void getAclCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { @@ -87,8 +86,7 @@ static void getAclCompleteCallback(S3Status requestStatus, } (*(gaData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - gaData->callbackData); + (requestStatus, s3ErrorDetails, gaData->callbackData); free(gaData); } @@ -103,8 +101,7 @@ void S3_get_acl(const S3BucketContext *bucketContext, const char *key, // Create the callback data GetAclData *gaData = (GetAclData *) malloc(sizeof(GetAclData)); if (!gaData) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -259,15 +256,13 @@ static int setAclDataCallback(int bufferSize, char *buffer, void *callbackData) static void setAclCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { SetAclData *paData = (SetAclData *) callbackData; (*(paData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - paData->callbackData); + (requestStatus, s3ErrorDetails, paData->callbackData); free(paData); } @@ -281,14 +276,13 @@ void S3_set_acl(const S3BucketContext *bucketContext, const char *key, { if (aclGrantCount > S3_MAX_ACL_GRANT_COUNT) { (*(handler->completeCallback)) - (S3StatusTooManyAclGrants, 0, 0, callbackData); + (S3StatusTooManyAclGrants, 0, callbackData); return; } SetAclData *data = (SetAclData *) malloc(sizeof(SetAclData)); if (!data) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -299,7 +293,7 @@ void S3_set_acl(const S3BucketContext *bucketContext, const char *key, sizeof(data->aclXmlDocument)); if (status != S3StatusOK) { free(data); - (*(handler->completeCallback))(status, 0, 0, callbackData); + (*(handler->completeCallback))(status, 0, callbackData); return; } diff --git a/src/bucket.c b/src/bucket.c index 4150b20..cca60e0 100644 --- a/src/bucket.c +++ b/src/bucket.c @@ -81,7 +81,6 @@ static S3Status testBucketDataCallback(int bufferSize, const char *buffer, static void testBucketCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { @@ -93,8 +92,7 @@ static void testBucketCompleteCallback(S3Status requestStatus, tbData->locationConstraint); (*(tbData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - tbData->callbackData); + (requestStatus, s3ErrorDetails, tbData->callbackData); simplexml_deinitialize(&(tbData->simpleXml)); @@ -113,8 +111,7 @@ void S3_test_bucket(S3Protocol protocol, S3UriStyle uriStyle, TestBucketData *tbData = (TestBucketData *) malloc(sizeof(TestBucketData)); if (!tbData) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -122,7 +119,7 @@ void S3_test_bucket(S3Protocol protocol, S3UriStyle uriStyle, (&(tbData->simpleXml), &testBucketXmlCallback, tbData); if (status != S3StatusOK) { free(tbData); - (*(handler->completeCallback))(status, 0, 0, callbackData); + (*(handler->completeCallback))(status, 0, callbackData); return; } @@ -214,15 +211,13 @@ static int createBucketDataCallback(int bufferSize, char *buffer, static void createBucketCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { CreateBucketData *cbData = (CreateBucketData *) callbackData; (*(cbData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - cbData->callbackData); + (requestStatus, s3ErrorDetails, cbData->callbackData); free(cbData); } @@ -238,8 +233,7 @@ void S3_create_bucket(S3Protocol protocol, const char *accessKeyId, CreateBucketData *cbData = (CreateBucketData *) malloc(sizeof(CreateBucketData)); if (!cbData) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -325,15 +319,13 @@ static S3Status deleteBucketPropertiesCallback static void deleteBucketCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { DeleteBucketData *dbData = (DeleteBucketData *) callbackData; (*(dbData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - dbData->callbackData); + (requestStatus, s3ErrorDetails, dbData->callbackData); free(dbData); } @@ -349,8 +341,7 @@ void S3_delete_bucket(S3Protocol protocol, S3UriStyle uriStyle, DeleteBucketData *dbData = (DeleteBucketData *) malloc(sizeof(DeleteBucketData)); if (!dbData) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -612,7 +603,6 @@ static S3Status listBucketDataCallback(int bufferSize, const char *buffer, static void listBucketCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { @@ -624,8 +614,7 @@ static void listBucketCompleteCallback(S3Status requestStatus, } (*(lbData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - lbData->callbackData); + (requestStatus, s3ErrorDetails, lbData->callbackData); free(lbData); } @@ -646,27 +635,27 @@ void S3_list_bucket(const S3BucketContext *bucketContext, const char *prefix, string_buffer_append(queryParams, &sep, 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ - (S3StatusQueryParamsTooLong, 0, 0, callbackData); \ + (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ string_buffer_append(queryParams, name "=", \ sizeof(name "=") - 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ - (S3StatusQueryParamsTooLong, 0, 0, callbackData); \ + (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ sep = '&'; \ char encoded[3 * 1024]; \ if (!urlEncode(encoded, value, 1024)) { \ (*(handler->responseHandler.completeCallback)) \ - (S3StatusQueryParamsTooLong, 0, 0, callbackData); \ + (S3StatusQueryParamsTooLong, 0, callbackData); \ } \ string_buffer_append(queryParams, encoded, strlen(encoded), \ fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ - (S3StatusQueryParamsTooLong, 0, 0, callbackData); \ + (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ } while (0) @@ -693,7 +682,7 @@ void S3_list_bucket(const S3BucketContext *bucketContext, const char *prefix, if (!lbData) { (*(handler->responseHandler.completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (S3StatusOutOfMemory, 0, callbackData); return; } @@ -702,7 +691,7 @@ void S3_list_bucket(const S3BucketContext *bucketContext, const char *prefix, if (status != S3StatusOK) { free(lbData); (*(handler->responseHandler.completeCallback)) - (status, 0, 0, callbackData); + (status, 0, callbackData); return; } diff --git a/src/general.c b/src/general.c index 4915b0e..39e5cd8 100644 --- a/src/general.c +++ b/src/general.c @@ -173,7 +173,7 @@ const char *S3_get_status_name(S3Status status) return #s handlecase(OK); - handlecase(Failure); + handlecase(InternalError); handlecase(OutOfMemory); handlecase(Interrupted); handlecase(FailedToCreateMutex); @@ -216,6 +216,10 @@ const char *S3_get_status_name(S3Status status) handlecase(BadAclGrantee); handlecase(BadAclPermission); handlecase(AclXmlDocumentTooLarge); + handlecase(NameLookupError); + handlecase(FailedToConnect); + handlecase(ConnectionFailed); + handlecase(AbortedByCallback); handlecase(ErrorAccessDenied); handlecase(ErrorAccountProblem); handlecase(ErrorAmbiguousGrantByEmailAddress); @@ -562,3 +566,20 @@ S3Status S3_convert_acl(char *aclXml, char *ownerId, char *ownerDisplayName, return S3StatusOK; } + + +int S3_status_is_retryable(S3Status status) +{ + switch (status) { + case S3StatusNameLookupError: + case S3StatusFailedToConnect: + case S3StatusConnectionFailed: + case S3StatusErrorInternalError: + case S3StatusErrorOperationAborted: + case S3StatusErrorRequestTimeout: + return 1; + default: + return 0; + } +} + diff --git a/src/object.c b/src/object.c index d0d3696..41bd373 100644 --- a/src/object.c +++ b/src/object.c @@ -137,7 +137,6 @@ static S3Status copyObjectDataCallback(int bufferSize, const char *buffer, static void copyObjectCompleteCallback(S3Status requestStatus, - int httpResponseCode, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { @@ -153,8 +152,7 @@ static void copyObjectCompleteCallback(S3Status requestStatus, } (*(coData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - coData->callbackData); + (requestStatus, s3ErrorDetails, coData->callbackData); simplexml_deinitialize(&(coData->simpleXml)); @@ -173,8 +171,7 @@ void S3_copy_object(const S3BucketContext *bucketContext, const char *key, CopyObjectData *data = (CopyObjectData *) malloc(sizeof(CopyObjectData)); if (!data) { - (*(handler->completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData); return; } @@ -182,7 +179,7 @@ void S3_copy_object(const S3BucketContext *bucketContext, const char *key, (&(data->simpleXml), ©ObjectXmlCallback, data); if (status != S3StatusOK) { free(data); - (*(handler->completeCallback))(status, 0, 0, callbackData); + (*(handler->completeCallback))(status, 0, callbackData); return; } diff --git a/src/request.c b/src/request.c index 27c8869..1ca6122 100644 --- a/src/request.c +++ b/src/request.c @@ -109,32 +109,24 @@ typedef struct RequestComputedValues // Called whenever we detect that the request headers have been completely // processed; which happens either when we get our first read/write callback, -// or the request is finished being procesed -static S3Status request_headers_done(Request *request) +// or the request is finished being procesed. Returns nonzero on success, +// zero on failure. +static void request_headers_done(Request *request) { if (request->propertiesCallbackMade) { - return S3StatusOK; + return; } request->propertiesCallbackMade = 1; - // Get the http response code - if (curl_easy_getinfo(request->curl, CURLINFO_RESPONSE_CODE, - &(request->httpResponseCode)) != CURLE_OK) { - request->httpResponseCode = 0; - } - response_headers_handler_done(&(request->responseHeadersHandler), request->curl); if (request->propertiesCallback) { - return (*(request->propertiesCallback)) + request->status = (*(request->propertiesCallback)) (&(request->responseHeadersHandler.responseProperties), request->callbackData); } - else { - return S3StatusOK; - } } @@ -158,16 +150,26 @@ static size_t curl_read_func(void *ptr, size_t size, size_t nmemb, void *data) int len = size * nmemb; - if (request_headers_done(request) != S3StatusOK) { - return 0; + request_headers_done(request); + + if (request->status != S3StatusOK) { + return CURL_READFUNC_ABORT; } if (request->toS3Callback) { - return (*(request->toS3Callback)) + int ret = (*(request->toS3Callback)) (len, (char *) ptr, request->callbackData); + if (ret < 0) { + request->status = S3StatusAbortedByCallback; + return CURL_READFUNC_ABORT; + } + else { + return ret; + } } else { - return 0; + request->status = S3StatusInternalError; + return CURL_READFUNC_ABORT; } } @@ -179,28 +181,36 @@ static size_t curl_write_func(void *ptr, size_t size, size_t nmemb, int len = size * nmemb; - if (request_headers_done(request) != S3StatusOK) { + request_headers_done(request); + + if (request->status != S3StatusOK) { return 0; } + // Get the http response code + int httpResponseCode = 0; + if (curl_easy_getinfo(request->curl, CURLINFO_RESPONSE_CODE, + &(httpResponseCode)) != CURLE_OK) { + // Not able to get the HTTP response code - error + request->status = S3StatusInternalError; + } // On HTTP error, we expect to parse an HTTP error response - if ((request->httpResponseCode < 200) || - (request->httpResponseCode > 299)) { - return ((error_parser_add(&(request->errorParser), - (char *) ptr, len) == S3StatusOK) ? len : 0); + else if ((httpResponseCode < 200) || (httpResponseCode > 299)) { + request->status = error_parser_add + (&(request->errorParser), (char *) ptr, len); } - // If there was a callback registered, make it - if (request->fromS3Callback) { + else if (request->fromS3Callback) { request->status = (*(request->fromS3Callback)) (len, (char *) ptr, request->callbackData); - return (request->status == S3StatusOK) ? len : 0; } // Else, consider this an error - S3 has sent back data when it was not // expected else { - return 0; + request->status = S3StatusInternalError; } + + return ((request->status == S3StatusOK) ? len : 0); } @@ -545,7 +555,7 @@ static void canonicalize_amz_headers(RequestComputedValues *values) // - folding repeated headers into single lines, and // - folding multiple lines // - removing the space after the colon - int lastHeaderLen, i; + int lastHeaderLen = 0, i; char *buffer = values->canonicalizedAmzHeaders; for (i = 0; i < values->amzHeadersCount; i++) { const char *header = sortedHeaders[i]; @@ -690,7 +700,7 @@ static S3Status compose_auth_header(const RequestParams *params, BIO_write(base64, md, md_len); if (BIO_flush(base64) != 1) { BIO_free_all(base64); - return S3StatusFailure; + return S3StatusInternalError; } BUF_MEM *base64mem; BIO_get_mem_ptr(base64, &base64mem); @@ -779,9 +789,10 @@ static S3Status setup_curl(Request *request, curl_easy_setopt_safe(CURLOPT_READFUNCTION, &curl_read_func); curl_easy_setopt_safe(CURLOPT_READDATA, request); // xxx the following does not work in some versions of CURL. - // CURL is retarded in how it defines large offsets, only using + // CURL is retarded in how it defines large offsets, using only // 32 bits sometimes, when it should always use 64 via int64_t - curl_easy_setopt_safe(CURLOPT_INFILESIZE_LARGE, params->toS3CallbackTotalSize); + curl_easy_setopt_safe(CURLOPT_INFILESIZE_LARGE, + params->toS3CallbackTotalSize); // Set write callback and data curl_easy_setopt_safe(CURLOPT_WRITEFUNCTION, &curl_write_func); @@ -1046,7 +1057,7 @@ void request_perform(const RequestParams *params, S3RequestContext *context) S3Status status; #define return_status(status) \ - (*(params->completeCallback))(status, 0, 0, params->callbackData); \ + (*(params->completeCallback))(status, 0, params->callbackData); \ return // These will hold the computed values @@ -1093,8 +1104,8 @@ void request_perform(const RequestParams *params, S3RequestContext *context) // If a RequestContext was provided, add the request to the curl multi if (context) { - switch (curl_multi_add_handle(context->curlm, request->curl)) { - case CURLM_OK: + CURLMcode code = curl_multi_add_handle(context->curlm, request->curl); + if (code == CURLM_OK) { if (context->requests) { request->prev = context->requests->prev; request->next = context->requests; @@ -1104,23 +1115,20 @@ void request_perform(const RequestParams *params, S3RequestContext *context) else { context->requests = request->next = request->prev = request; } - break; - default: - // This isn't right. Figure this out. - // xxx todo - more specific errors - return_status(S3StatusFailure); - request_release(request); + } + else { + if (request->status == S3StatusOK) { + request->status = (code == CURLM_OUT_OF_MEMORY) ? + S3StatusOutOfMemory : S3StatusInternalError; + } + request_finish(request); } } // Else, perform the request immediately else { - switch (curl_easy_perform(request->curl)) { - case CURLE_OK: - break; - default: - // xxx todo - more specific errors - request->status = S3StatusFailure; - break; + CURLcode code = curl_easy_perform(request->curl); + if ((code != CURLE_OK) && (request->status == S3StatusOK)) { + request->status = request_curl_code_to_status(code); } // Finish the request, ensuring that all callbacks have been made, and // also releases the request @@ -1133,8 +1141,8 @@ void request_finish(Request *request) { // If we haven't detected this already, we now know that the headers are // definitely done being read in - (void) request_headers_done(request); - + request_headers_done(request); + // If there was no error processing the request, then possibly there was // an S3 error parsed, which should be converted into the request status if (request->status == S3StatusOK) { @@ -1143,8 +1151,28 @@ void request_finish(Request *request) } (*(request->completeCallback)) - (request->status, request->httpResponseCode, - &(request->errorParser.s3ErrorDetails), request->callbackData); + (request->status, &(request->errorParser.s3ErrorDetails), + request->callbackData); request_release(request); } + + +S3Status request_curl_code_to_status(CURLcode code) +{ + switch (code) { + case CURLE_OUT_OF_MEMORY: + return S3StatusOutOfMemory; + case CURLE_COULDNT_RESOLVE_PROXY: + case CURLE_COULDNT_RESOLVE_HOST: + return S3StatusNameLookupError; + case CURLE_COULDNT_CONNECT: + return S3StatusFailedToConnect; + case CURLE_WRITE_ERROR: + case CURLE_OPERATION_TIMEDOUT: + return S3StatusConnectionFailed; + default: + return S3StatusInternalError; + } +} + diff --git a/src/request_context.c b/src/request_context.c index 69a6f37..aced7a7 100644 --- a/src/request_context.c +++ b/src/request_context.c @@ -107,7 +107,7 @@ S3Status S3_runonce_request_context(S3RequestContext *requestContext, case CURLM_OUT_OF_MEMORY: return S3StatusOutOfMemory; default: - return S3StatusFailure; + return S3StatusInternalError; } CURLMsg *msg; @@ -116,12 +116,12 @@ S3Status S3_runonce_request_context(S3RequestContext *requestContext, if ((msg->msg != CURLMSG_DONE) || (curl_multi_remove_handle(requestContext->curlm, msg->easy_handle) != CURLM_OK)) { - return S3StatusFailure; + return S3StatusInternalError; } Request *request; if (curl_easy_getinfo(msg->easy_handle, CURLOPT_PRIVATE, - (char **) &request) != CURLE_OK) { - return S3StatusFailure; + (char *) &request) != CURLE_OK) { + return S3StatusInternalError; } // Remove the request from the list of requests if (request->prev == request->next) { @@ -136,15 +136,10 @@ S3Status S3_runonce_request_context(S3RequestContext *requestContext, request->prev->next = request->next; request->next->prev = request->prev; } - // Make response complete callback - switch (msg->data.result) { - case CURLE_OK: - request->status = S3StatusOK; - break; - // xxx todo fill the rest in - default: - request->status = S3StatusFailure; - break; + if ((msg->data.result != CURLE_OK) && + (request->status == S3StatusOK)) { + request->status = request_curl_code_to_status + (msg->data.result); } // Finish the request, ensuring that all callbacks have been made, // and also releases the request @@ -161,5 +156,5 @@ S3Status S3_get_request_context_fdsets(S3RequestContext *requestContext, { return ((curl_multi_fdset(requestContext->curlm, readFdSet, writeFdSet, exceptFdSet, maxFd) == CURLM_OK) ? - S3StatusOK : S3StatusFailure); + S3StatusOK : S3StatusInternalError); } @@ -62,8 +62,8 @@ static const char *secretAccessKeyG = 0; // Request results, saved as globals ----------------------------------------- -static int statusG = 0, httpResponseCodeG = 0; -static const S3ErrorDetails *errorG = 0; +static int statusG = 0; +static char errorDetailsG[4096] = { 0 }; // Option prefixes ----------------------------------------------------------- @@ -179,33 +179,12 @@ static void S3_init() static void printError() { if (statusG < S3StatusErrorAccessDenied) { - fprintf(stderr, "ERROR: %s\n", S3_get_status_name(statusG)); + fprintf(stderr, "\nERROR: %s\n", S3_get_status_name(statusG)); } else { - fprintf(stderr, "ERROR: S3 returned an unexpected error:\n"); - fprintf(stderr, " HTTP Code: %d\n", httpResponseCodeG); - fprintf(stderr, " S3 Error: %s\n", S3_get_status_name(statusG)); - if (errorG) { - if (errorG->message) { - fprintf(stderr, " Message: %s\n", errorG->message); - } - if (errorG->resource) { - fprintf(stderr, " Resource: %s\n", errorG->resource); - } - if (errorG->furtherDetails) { - fprintf(stderr, " Further Details: %s\n", - errorG->furtherDetails); - } - if (errorG->extraDetailsCount) { - printf(" Extra Details:\n"); - int i; - for (i = 0; i < errorG->extraDetailsCount; i++) { - fprintf(stderr, " %s: %s\n", - errorG->extraDetails[i].name, - errorG->extraDetails[i].value); - } - } - } + fprintf(stderr, "\nERROR: S3 returned an unexpected error:\n"); + fprintf(stderr, " %s\n", S3_get_status_name(statusG)); + fprintf(stderr, "%s\n", errorDetailsG); } } @@ -262,7 +241,7 @@ static uint64_t convertInt(const char *str, const char *paramName) while (*str) { if (!isdigit(*str)) { - fprintf(stderr, "ERROR: Nondigit in %s parameter: %c\n", + fprintf(stderr, "\nERROR: Nondigit in %s parameter: %c\n", paramName, *str); usageExit(stderr); } @@ -469,10 +448,10 @@ static time_t parseIso8601Time(const char *str) // Group Authenticated AWS Users permission // Group All Users permission // permission is one of READ, WRITE, READ_ACP, WRITE_ACP, FULL_CONTROL -static S3Status convert_simple_acl(char *aclXml, char *ownerId, - char *ownerDisplayName, - int *aclGrantCountReturn, - S3AclGrant *aclGrants) +static int convert_simple_acl(char *aclXml, char *ownerId, + char *ownerDisplayName, + int *aclGrantCountReturn, + S3AclGrant *aclGrants) { *aclGrantCountReturn = 0; *ownerId = 0; @@ -484,7 +463,7 @@ static S3Status convert_simple_acl(char *aclXml, char *ownerId, aclXml++; \ } \ if (require_more && !*aclXml) { \ - return S3StatusFailure; \ + return 0; \ } \ } while (0) @@ -527,7 +506,7 @@ static S3Status convert_simple_acl(char *aclXml, char *ownerId, } if (*aclGrantCountReturn == S3_MAX_ACL_GRANT_COUNT) { - return S3StatusFailure; + return 0; } S3AclGrant *grant = &(aclGrants[(*aclGrantCountReturn)++]); @@ -558,11 +537,11 @@ static S3Status convert_simple_acl(char *aclXml, char *ownerId, aclXml += (sizeof("All Users") - 1); } else { - return S3StatusFailure; + return 0; } } else { - return S3StatusFailure; + return 0; } SKIP_SPACE(1); @@ -590,7 +569,7 @@ static S3Status convert_simple_acl(char *aclXml, char *ownerId, } } - return S3StatusOK; + return 1; } @@ -614,11 +593,11 @@ static S3Status responsePropertiesCallback return S3StatusOK; } -#define print_nonnull(name, field) \ - do { \ +#define print_nonnull(name, field) \ + do { \ if (properties-> field) { \ printf("%s: %s\n", name, properties-> field); \ - } \ + } \ } while (0) print_nonnull("Request-Id", requestId); @@ -649,16 +628,38 @@ static S3Status responsePropertiesCallback // This callback does the same thing for every request type: saves the status // and error stuff in global variables -static void responseCompleteCallback(S3Status status, int httpResponseCode, +static void responseCompleteCallback(S3Status status, const S3ErrorDetails *error, void *callbackData) { statusG = status; - httpResponseCodeG = httpResponseCode; - // xxx todo - copy this instead of assigning it, since we are not supposed - // to rely on the value passed into this callback after the callback has - // completed. Be sure to free errorG at the end of the program. - errorG = error; + // Compose the error details message now, although we might not use it. + // Can't just save a pointer to [error] since it's not guaranteed to last + // beyond this callback + int len = 0; + if (error->message) { + len += snprintf(&(errorDetailsG[len]), sizeof(errorDetailsG) - len, + " Message: %s\n", error->message); + } + if (error->resource) { + len += snprintf(&(errorDetailsG[len]), sizeof(errorDetailsG) - len, + " Resource: %s\n", error->resource); + } + if (error->furtherDetails) { + len += snprintf(&(errorDetailsG[len]), sizeof(errorDetailsG) - len, + " Further Details: %s\n", error->furtherDetails); + } + if (error->extraDetailsCount) { + len += snprintf(&(errorDetailsG[len]), sizeof(errorDetailsG) - len, + "%s", " Extra Details:\n"); + int i; + for (i = 0; i < error->extraDetailsCount; i++) { + len += snprintf(&(errorDetailsG[len]), + sizeof(errorDetailsG) - len, " %s: %s\n", + error->extraDetails[i].name, + error->extraDetails[i].value); + } + } } @@ -760,14 +761,14 @@ static void test_bucket(int argc, char **argv, int optind) { // test bucket if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket\n"); usageExit(stderr); } const char *bucketName = argv[optind++]; if (optind != argc) { - fprintf(stderr, "ERROR: Extraneous parameter: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Extraneous parameter: %s\n", argv[optind]); usageExit(stderr); } @@ -821,7 +822,7 @@ static void test_bucket(int argc, char **argv, int optind) static void create_bucket(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket\n"); usageExit(stderr); } @@ -849,12 +850,12 @@ static void create_bucket(int argc, char **argv, int optind) cannedAcl = S3CannedAclAuthenticatedRead; } else { - fprintf(stderr, "ERROR: Unknown canned ACL: %s\n", val); + fprintf(stderr, "\nERROR: Unknown canned ACL: %s\n", val); usageExit(stderr); } } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -885,14 +886,14 @@ static void create_bucket(int argc, char **argv, int optind) static void delete_bucket(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket\n"); usageExit(stderr); } const char *bucketName = argv[optind++]; if (optind != argc) { - fprintf(stderr, "ERROR: Extraneous parameter: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Extraneous parameter: %s\n", argv[optind]); usageExit(stderr); } @@ -967,7 +968,8 @@ static S3Status listBucketCallback(int isTruncated, const char *nextMarker, nextMarker = contents[contentsCount - 1].key; } if (nextMarker) { - snprintf(data->nextMarker, sizeof(data->nextMarker), "%s", nextMarker); + snprintf(data->nextMarker, sizeof(data->nextMarker), "%s", + nextMarker); } else { data->nextMarker[0] = 0; @@ -1115,7 +1117,8 @@ static void list(int argc, char **argv, int optind) else if (!strncmp(param, MAXKEYS_PREFIX, MAXKEYS_PREFIX_LEN)) { maxkeys = convertInt(&(param[MAXKEYS_PREFIX_LEN]), "maxkeys"); } - else if (!strncmp(param, ALL_DETAILS_PREFIX, ALL_DETAILS_PREFIX_LEN)) { + else if (!strncmp(param, ALL_DETAILS_PREFIX, + ALL_DETAILS_PREFIX_LEN)) { const char *ad = &(param[ALL_DETAILS_PREFIX_LEN]); if (!strcasecmp(ad, "true") || !strcasecmp(ad, "yes") || !strcmp(ad, "1")) { @@ -1126,7 +1129,7 @@ static void list(int argc, char **argv, int optind) bucketName = param; } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -1200,7 +1203,8 @@ typedef struct put_object_callback_data static int putObjectDataCallback(int bufferSize, char *buffer, void *callbackData) { - put_object_callback_data *data = (put_object_callback_data *) callbackData; + put_object_callback_data *data = + (put_object_callback_data *) callbackData; int ret = 0; @@ -1232,7 +1236,7 @@ static int putObjectDataCallback(int bufferSize, char *buffer, static void put_object(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket/key\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket/key\n"); usageExit(stderr); } @@ -1242,7 +1246,8 @@ static void put_object(int argc, char **argv, int optind) slash++; } if (!*slash || !*(slash + 1)) { - fprintf(stderr, "ERROR: Invalid bucket/key name: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Invalid bucket/key name: %s\n", + argv[optind]); usageExit(stderr); } *slash++ = 0; @@ -1270,7 +1275,7 @@ static void put_object(int argc, char **argv, int optind) contentLength = convertInt(&(param[CONTENT_LENGTH_PREFIX_LEN]), "contentLength"); if (contentLength > (5LL * 1024 * 1024 * 1024)) { - fprintf(stderr, "ERROR: contentLength must be no greater " + fprintf(stderr, "\nERROR: contentLength must be no greater " "than 5 GB\n"); usageExit(stderr); } @@ -1298,14 +1303,14 @@ static void put_object(int argc, char **argv, int optind) else if (!strncmp(param, EXPIRES_PREFIX, EXPIRES_PREFIX_LEN)) { expires = parseIso8601Time(&(param[EXPIRES_PREFIX_LEN])); if (expires < 0) { - fprintf(stderr, "ERROR: Invalid expires time " + fprintf(stderr, "\nERROR: Invalid expires time " "value; ISO 8601 time format required\n"); usageExit(stderr); } } else if (!strncmp(param, X_AMZ_META_PREFIX, X_AMZ_META_PREFIX_LEN)) { if (metaPropertiesCount == S3_MAX_METADATA_COUNT) { - fprintf(stderr, "ERROR: Too many x-amz-meta- properties, " + fprintf(stderr, "\nERROR: Too many x-amz-meta- properties, " "limit %d: %s\n", S3_MAX_METADATA_COUNT, param); usageExit(stderr); } @@ -1315,7 +1320,7 @@ static void put_object(int argc, char **argv, int optind) value++; } if (!*value || !*(value + 1)) { - fprintf(stderr, "ERROR: Invalid parameter: %s\n", param); + fprintf(stderr, "\nERROR: Invalid parameter: %s\n", param); usageExit(stderr); } *value++ = 0; @@ -1337,7 +1342,7 @@ static void put_object(int argc, char **argv, int optind) cannedAcl = S3CannedAclAuthenticatedRead; } else { - fprintf(stderr, "ERROR: Unknown canned ACL: %s\n", val); + fprintf(stderr, "\nERROR: Unknown canned ACL: %s\n", val); usageExit(stderr); } } @@ -1349,7 +1354,7 @@ static void put_object(int argc, char **argv, int optind) } } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -1365,7 +1370,8 @@ static void put_object(int argc, char **argv, int optind) struct stat statbuf; // Stat the file to get its length if (stat(filename, &statbuf) == -1) { - fprintf(stderr, "ERROR: Failed to stat file %s: ", filename); + fprintf(stderr, "\nERROR: Failed to stat file %s: ", + filename); perror(0); exit(-1); } @@ -1373,7 +1379,8 @@ static void put_object(int argc, char **argv, int optind) } // Open the file if (!(data.infile = fopen(filename, "r"))) { - fprintf(stderr, "ERROR: Failed to open input file %s: ", filename); + fprintf(stderr, "\nERROR: Failed to open input file %s: ", + filename); perror(0); exit(-1); } @@ -1390,7 +1397,7 @@ static void put_object(int argc, char **argv, int optind) break; } if (!growbuffer_append(&(data.gb), buffer, amtRead)) { - fprintf(stderr, "ERROR: Out of memory while reading " + fprintf(stderr, "\nERROR: Out of memory while reading " "stdin\n"); exit(-1); } @@ -1451,7 +1458,7 @@ static void put_object(int argc, char **argv, int optind) printError(); } else if (data.contentLength) { - fprintf(stderr, "ERROR: Failed to read remaining %llu bytes from " + fprintf(stderr, "\nERROR: Failed to read remaining %llu bytes from " "input\n", data.contentLength); } @@ -1464,7 +1471,7 @@ static void put_object(int argc, char **argv, int optind) static void copy_object(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: source bucket/key\n"); + fprintf(stderr, "\nERROR: Missing parameter: source bucket/key\n"); usageExit(stderr); } @@ -1474,7 +1481,7 @@ static void copy_object(int argc, char **argv, int optind) slash++; } if (!*slash || !*(slash + 1)) { - fprintf(stderr, "ERROR: Invalid source bucket/key name: %s\n", + fprintf(stderr, "\nERROR: Invalid source bucket/key name: %s\n", argv[optind]); usageExit(stderr); } @@ -1484,7 +1491,8 @@ static void copy_object(int argc, char **argv, int optind) const char *sourceKey = slash; if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: destination bucket/key\n"); + fprintf(stderr, "\nERROR: Missing parameter: " + "destination bucket/key\n"); usageExit(stderr); } @@ -1494,7 +1502,7 @@ static void copy_object(int argc, char **argv, int optind) slash++; } if (!*slash || !*(slash + 1)) { - fprintf(stderr, "ERROR: Invalid destination bucket/key name: %s\n", + fprintf(stderr, "\nERROR: Invalid destination bucket/key name: %s\n", argv[optind]); usageExit(stderr); } @@ -1537,7 +1545,7 @@ static void copy_object(int argc, char **argv, int optind) else if (!strncmp(param, EXPIRES_PREFIX, EXPIRES_PREFIX_LEN)) { expires = parseIso8601Time(&(param[EXPIRES_PREFIX_LEN])); if (expires < 0) { - fprintf(stderr, "ERROR: Invalid expires time " + fprintf(stderr, "\nERROR: Invalid expires time " "value; ISO 8601 time format required\n"); usageExit(stderr); } @@ -1545,7 +1553,7 @@ 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, "ERROR: Too many x-amz-meta- properties, " + fprintf(stderr, "\nERROR: Too many x-amz-meta- properties, " "limit %d: %s\n", S3_MAX_METADATA_COUNT, param); usageExit(stderr); } @@ -1555,7 +1563,7 @@ static void copy_object(int argc, char **argv, int optind) value++; } if (!*value || !*(value + 1)) { - fprintf(stderr, "ERROR: Invalid parameter: %s\n", param); + fprintf(stderr, "\nERROR: Invalid parameter: %s\n", param); usageExit(stderr); } *value++ = 0; @@ -1578,13 +1586,13 @@ static void copy_object(int argc, char **argv, int optind) cannedAcl = S3CannedAclAuthenticatedRead; } else { - fprintf(stderr, "ERROR: Unknown canned ACL: %s\n", val); + fprintf(stderr, "\nERROR: Unknown canned ACL: %s\n", val); usageExit(stderr); } anyPropertiesSet = 1; } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -1654,14 +1662,14 @@ static S3Status getObjectDataCallback(int bufferSize, const char *buffer, size_t wrote = fwrite(buffer, 1, bufferSize, outfile); - return (wrote < bufferSize) ? S3StatusFailure : S3StatusOK; + return (wrote < bufferSize) ? S3StatusAbortedByCallback : S3StatusOK; } static void get_object(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket/key\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket/key\n"); usageExit(stderr); } @@ -1671,7 +1679,8 @@ static void get_object(int argc, char **argv, int optind) slash++; } if (!*slash || !*(slash + 1)) { - fprintf(stderr, "ERROR: Invalid bucket/key name: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Invalid bucket/key name: %s\n", + argv[optind]); usageExit(stderr); } *slash++ = 0; @@ -1695,7 +1704,7 @@ static void get_object(int argc, char **argv, int optind) ifModifiedSince = parseIso8601Time (&(param[IF_MODIFIED_SINCE_PREFIX_LEN])); if (ifModifiedSince < 0) { - fprintf(stderr, "ERROR: Invalid ifModifiedSince time " + fprintf(stderr, "\nERROR: Invalid ifModifiedSince time " "value; ISO 8601 time format required\n"); usageExit(stderr); } @@ -1706,7 +1715,7 @@ static void get_object(int argc, char **argv, int optind) ifNotModifiedSince = parseIso8601Time (&(param[IF_NOT_MODIFIED_SINCE_PREFIX_LEN])); if (ifNotModifiedSince < 0) { - fprintf(stderr, "ERROR: Invalid ifNotModifiedSince time " + fprintf(stderr, "\nERROR: Invalid ifNotModifiedSince time " "value; ISO 8601 time format required\n"); usageExit(stderr); } @@ -1727,7 +1736,7 @@ static void get_object(int argc, char **argv, int optind) (&(param[BYTE_COUNT_PREFIX_LEN]), "byteCount"); } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -1748,14 +1757,14 @@ static void get_object(int argc, char **argv, int optind) } if (!outfile) { - fprintf(stderr, "ERROR: Failed to open output file %s: ", + fprintf(stderr, "\nERROR: Failed to open output file %s: ", filename); perror(0); exit(-1); } } else if (showResponsePropertiesG) { - fprintf(stderr, "ERROR: get -s requires a filename parameter\n"); + fprintf(stderr, "\nERROR: get -s requires a filename parameter\n"); usageExit(stderr); } else { @@ -1810,7 +1819,7 @@ static void get_object(int argc, char **argv, int optind) static void head_object(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket/key\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket/key\n"); usageExit(stderr); } @@ -1824,7 +1833,8 @@ static void head_object(int argc, char **argv, int optind) slash++; } if (!*slash || !*(slash + 1)) { - fprintf(stderr, "ERROR: Invalid bucket/key name: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Invalid bucket/key name: %s\n", + argv[optind]); usageExit(stderr); } *slash++ = 0; @@ -1833,7 +1843,7 @@ static void head_object(int argc, char **argv, int optind) const char *key = slash; if (optind != argc) { - fprintf(stderr, "ERROR: Extraneous parameter: %s\n", argv[optind]); + fprintf(stderr, "\nERROR: Extraneous parameter: %s\n", argv[optind]); usageExit(stderr); } @@ -1870,7 +1880,7 @@ static void head_object(int argc, char **argv, int optind) void get_acl(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket[/key]\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket[/key]\n"); usageExit(stderr); } @@ -1898,7 +1908,8 @@ void get_acl(int argc, char **argv, int optind) if (!strncmp(param, FILENAME_PREFIX, FILENAME_PREFIX_LEN)) { filename = &(param[FILENAME_PREFIX_LEN]); } - else if (!strncmp(param, ALL_DETAILS_PREFIX, ALL_DETAILS_PREFIX_LEN)) { + else if (!strncmp(param, ALL_DETAILS_PREFIX, + ALL_DETAILS_PREFIX_LEN)) { const char *ad = &(param[ALL_DETAILS_PREFIX_LEN]); if (!strcasecmp(ad, "true") || !strcasecmp(ad, "yes") || !strcmp(ad, "1")) { @@ -1906,7 +1917,7 @@ void get_acl(int argc, char **argv, int optind) } } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -1927,14 +1938,14 @@ void get_acl(int argc, char **argv, int optind) } if (!outfile) { - fprintf(stderr, "ERROR: Failed to open output file %s: ", + fprintf(stderr, "\nERROR: Failed to open output file %s: ", filename); perror(0); exit(-1); } } else if (showResponsePropertiesG) { - fprintf(stderr, "ERROR: getacl -s requires a filename parameter\n"); + fprintf(stderr, "\nERROR: getacl -s requires a filename parameter\n"); usageExit(stderr); } else { @@ -2045,7 +2056,7 @@ void get_acl(int argc, char **argv, int optind) void set_acl(int argc, char **argv, int optind) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket[/key]\n"); + fprintf(stderr, "\nERROR: Missing parameter: bucket[/key]\n"); usageExit(stderr); } @@ -2073,7 +2084,7 @@ void set_acl(int argc, char **argv, int optind) filename = &(param[FILENAME_PREFIX_LEN]); } else { - fprintf(stderr, "ERROR: Unknown param: %s\n", param); + fprintf(stderr, "\nERROR: Unknown param: %s\n", param); usageExit(stderr); } } @@ -2082,7 +2093,8 @@ void set_acl(int argc, char **argv, int optind) if (filename) { if (!(infile = fopen(filename, "r"))) { - fprintf(stderr, "ERROR: Failed to open input file %s: ", filename); + fprintf(stderr, "\nERROR: Failed to open input file %s: ", + filename); perror(0); exit(-1); } @@ -2100,10 +2112,9 @@ void set_acl(int argc, char **argv, int optind) // Parse it int aclGrantCount; S3AclGrant aclGrants[S3_MAX_ACL_GRANT_COUNT]; - S3Status status = convert_simple_acl(aclBuf, ownerId, ownerDisplayName, - &aclGrantCount, aclGrants); - if (status != S3StatusOK) { - fprintf(stderr, "ERROR: Failed to parse ACLs\n"); + if (!convert_simple_acl(aclBuf, ownerId, ownerDisplayName, + &aclGrantCount, aclGrants)) { + fprintf(stderr, "\nERROR: Failed to parse ACLs\n"); fclose(infile); exit(-1); } @@ -2163,7 +2174,7 @@ int main(int argc, char **argv) showResponsePropertiesG = 1; break; default: - fprintf(stderr, "ERROR: Unknown options: -%c\n", c); + fprintf(stderr, "\nERROR: Unknown options: -%c\n", c); // Usage exit usageExit(stderr); } @@ -2171,7 +2182,7 @@ int main(int argc, char **argv) // The first non-option argument gives the operation to perform if (optind == argc) { - fprintf(stderr, "\nERROR: Missing argument: command\n\n"); + fprintf(stderr, "\n\nERROR: Missing argument: command\n\n"); usageExit(stderr); } @@ -2188,7 +2199,8 @@ int main(int argc, char **argv) } secretAccessKeyG = getenv("S3_SECRET_ACCESS_KEY"); if (!secretAccessKeyG) { - fprintf(stderr, "Missing environment variable: S3_SECRET_ACCESS_KEY\n"); + fprintf(stderr, + "Missing environment variable: S3_SECRET_ACCESS_KEY\n"); return -1; } @@ -2203,7 +2215,8 @@ int main(int argc, char **argv) } else if (!strcmp(command, "delete")) { if (optind == argc) { - fprintf(stderr, "ERROR: Missing parameter: bucket or bucket/key\n"); + fprintf(stderr, + "\nERROR: Missing parameter: bucket or bucket/key\n"); usageExit(stderr); } char *val = argv[optind]; diff --git a/src/service.c b/src/service.c index 664e4e9..1e97d96 100644 --- a/src/service.c +++ b/src/service.c @@ -110,15 +110,14 @@ static S3Status dataCallback(int bufferSize, const char *buffer, } -static void completeCallback(S3Status requestStatus, int httpResponseCode, +static void completeCallback(S3Status requestStatus, const S3ErrorDetails *s3ErrorDetails, void *callbackData) { XmlCallbackData *cbData = (XmlCallbackData *) callbackData; (*(cbData->responseCompleteCallback)) - (requestStatus, httpResponseCode, s3ErrorDetails, - cbData->callbackData); + (requestStatus, s3ErrorDetails, cbData->callbackData); simplexml_deinitialize(&(cbData->simpleXml)); @@ -136,7 +135,7 @@ void S3_list_service(S3Protocol protocol, const char *accessKeyId, (XmlCallbackData *) malloc(sizeof(XmlCallbackData)); if (!data) { (*(handler->responseHandler.completeCallback)) - (S3StatusOutOfMemory, 0, 0, callbackData); + (S3StatusOutOfMemory, 0, callbackData); return; } @@ -145,7 +144,7 @@ void S3_list_service(S3Protocol protocol, const char *accessKeyId, if (status != S3StatusOK) { free(data); (*(handler->responseHandler.completeCallback)) - (status, 0, 0, callbackData); + (status, 0, callbackData); return; } diff --git a/src/simplexml.c b/src/simplexml.c index a96bbde..db88df6 100644 --- a/src/simplexml.c +++ b/src/simplexml.c @@ -187,7 +187,7 @@ S3Status simplexml_add(SimpleXml *simpleXml, const char *data, int dataLen) if (!simpleXml->xmlParser && (!(simpleXml->xmlParser = xmlCreatePushParserCtxt (&saxHandlerG, simpleXml, 0, 0, 0)))) { - return S3StatusFailure; + return S3StatusInternalError; } if (xmlParseChunk((xmlParserCtxtPtr) simpleXml->xmlParser, |