diff options
Diffstat (limited to 'src/general.c')
-rw-r--r-- | src/general.c | 804 |
1 files changed, 402 insertions, 402 deletions
diff --git a/src/general.c b/src/general.c index 861c289..1e23812 100644 --- a/src/general.c +++ b/src/general.c @@ -34,442 +34,442 @@ static int initializeCountG = 0; S3Status S3_initialize(const char *userAgentInfo, int flags) { - if (initializeCountG++) { - return S3StatusOK; - } + if (initializeCountG++) { + return S3StatusOK; + } - return request_api_initialize(userAgentInfo, flags); + return request_api_initialize(userAgentInfo, flags); } void S3_deinitialize() { - if (--initializeCountG) { - return; - } + if (--initializeCountG) { + return; + } - request_api_deinitialize(); + request_api_deinitialize(); } const char *S3_get_status_name(S3Status status) { - switch (status) { -#define handlecase(s) \ - case S3Status##s: \ - return #s - - handlecase(OK); - handlecase(InternalError); - handlecase(OutOfMemory); - handlecase(Interrupted); - handlecase(InvalidBucketNameTooLong); - handlecase(InvalidBucketNameFirstCharacter); - handlecase(InvalidBucketNameCharacter); - handlecase(InvalidBucketNameCharacterSequence); - handlecase(InvalidBucketNameTooShort); - handlecase(InvalidBucketNameDotQuadNotation); - handlecase(QueryParamsTooLong); - handlecase(FailedToInitializeRequest); - handlecase(MetaDataHeadersTooLong); - handlecase(BadMetaData); - handlecase(BadContentType); - handlecase(ContentTypeTooLong); - handlecase(BadMD5); - handlecase(MD5TooLong); - handlecase(BadCacheControl); - handlecase(CacheControlTooLong); - handlecase(BadContentDispositionFilename); - handlecase(ContentDispositionFilenameTooLong); - handlecase(BadContentEncoding); - handlecase(ContentEncodingTooLong); - handlecase(BadIfMatchETag); - handlecase(IfMatchETagTooLong); - handlecase(BadIfNotMatchETag); - handlecase(IfNotMatchETagTooLong); - handlecase(HeadersTooLong); - handlecase(KeyTooLong); - handlecase(UriTooLong); - handlecase(XmlParseFailure); - handlecase(EmailAddressTooLong); - handlecase(UserIdTooLong); - handlecase(UserDisplayNameTooLong); - handlecase(GroupUriTooLong); - handlecase(PermissionTooLong); - handlecase(TargetBucketTooLong); - handlecase(TargetPrefixTooLong); - handlecase(TooManyGrants); - handlecase(BadGrantee); - handlecase(BadPermission); - handlecase(XmlDocumentTooLarge); - handlecase(NameLookupError); - handlecase(FailedToConnect); - handlecase(ServerFailedVerification); - handlecase(ConnectionFailed); - handlecase(AbortedByCallback); - handlecase(ErrorAccessDenied); - handlecase(ErrorAccountProblem); - handlecase(ErrorAmbiguousGrantByEmailAddress); - handlecase(ErrorBadDigest); - handlecase(ErrorBucketAlreadyExists); - handlecase(ErrorBucketAlreadyOwnedByYou); - handlecase(ErrorBucketNotEmpty); - handlecase(ErrorCredentialsNotSupported); - handlecase(ErrorCrossLocationLoggingProhibited); - handlecase(ErrorEntityTooSmall); - handlecase(ErrorEntityTooLarge); - handlecase(ErrorExpiredToken); - handlecase(ErrorIncompleteBody); - handlecase(ErrorIncorrectNumberOfFilesInPostRequest); - handlecase(ErrorInlineDataTooLarge); - handlecase(ErrorInternalError); - handlecase(ErrorInvalidAccessKeyId); - handlecase(ErrorInvalidAddressingHeader); - handlecase(ErrorInvalidArgument); - handlecase(ErrorInvalidBucketName); - handlecase(ErrorInvalidDigest); - handlecase(ErrorInvalidLocationConstraint); - handlecase(ErrorInvalidPayer); - handlecase(ErrorInvalidPolicyDocument); - handlecase(ErrorInvalidRange); - handlecase(ErrorInvalidSecurity); - handlecase(ErrorInvalidSOAPRequest); - handlecase(ErrorInvalidStorageClass); - handlecase(ErrorInvalidTargetBucketForLogging); - handlecase(ErrorInvalidToken); - handlecase(ErrorInvalidURI); - handlecase(ErrorKeyTooLong); - handlecase(ErrorMalformedACLError); - handlecase(ErrorMalformedXML); - handlecase(ErrorMaxMessageLengthExceeded); - handlecase(ErrorMaxPostPreDataLengthExceededError); - handlecase(ErrorMetadataTooLarge); - handlecase(ErrorMethodNotAllowed); - handlecase(ErrorMissingAttachment); - handlecase(ErrorMissingContentLength); - handlecase(ErrorMissingSecurityElement); - handlecase(ErrorMissingSecurityHeader); - handlecase(ErrorNoLoggingStatusForKey); - handlecase(ErrorNoSuchBucket); - handlecase(ErrorNoSuchKey); - handlecase(ErrorNotImplemented); - handlecase(ErrorNotSignedUp); - handlecase(ErrorOperationAborted); - handlecase(ErrorPermanentRedirect); - handlecase(ErrorPreconditionFailed); - handlecase(ErrorRedirect); - handlecase(ErrorRequestIsNotMultiPartContent); - handlecase(ErrorRequestTimeout); - handlecase(ErrorRequestTimeTooSkewed); - handlecase(ErrorRequestTorrentOfBucketError); - handlecase(ErrorSignatureDoesNotMatch); - handlecase(ErrorSlowDown); - handlecase(ErrorTemporaryRedirect); - handlecase(ErrorTokenRefreshRequired); - handlecase(ErrorTooManyBuckets); - handlecase(ErrorUnexpectedContent); - handlecase(ErrorUnresolvableGrantByEmailAddress); - handlecase(ErrorUserKeyMustBeSpecified); - handlecase(ErrorUnknown); - handlecase(HttpErrorMovedTemporarily); - handlecase(HttpErrorBadRequest); - handlecase(HttpErrorForbidden); - handlecase(HttpErrorNotFound); - handlecase(HttpErrorConflict); - handlecase(HttpErrorUnknown); - } - - return "Unknown"; + switch (status) { +#define handlecase(s) \ + case S3Status##s: \ + return #s + + handlecase(OK); + handlecase(InternalError); + handlecase(OutOfMemory); + handlecase(Interrupted); + handlecase(InvalidBucketNameTooLong); + handlecase(InvalidBucketNameFirstCharacter); + handlecase(InvalidBucketNameCharacter); + handlecase(InvalidBucketNameCharacterSequence); + handlecase(InvalidBucketNameTooShort); + handlecase(InvalidBucketNameDotQuadNotation); + handlecase(QueryParamsTooLong); + handlecase(FailedToInitializeRequest); + handlecase(MetaDataHeadersTooLong); + handlecase(BadMetaData); + handlecase(BadContentType); + handlecase(ContentTypeTooLong); + handlecase(BadMD5); + handlecase(MD5TooLong); + handlecase(BadCacheControl); + handlecase(CacheControlTooLong); + handlecase(BadContentDispositionFilename); + handlecase(ContentDispositionFilenameTooLong); + handlecase(BadContentEncoding); + handlecase(ContentEncodingTooLong); + handlecase(BadIfMatchETag); + handlecase(IfMatchETagTooLong); + handlecase(BadIfNotMatchETag); + handlecase(IfNotMatchETagTooLong); + handlecase(HeadersTooLong); + handlecase(KeyTooLong); + handlecase(UriTooLong); + handlecase(XmlParseFailure); + handlecase(EmailAddressTooLong); + handlecase(UserIdTooLong); + handlecase(UserDisplayNameTooLong); + handlecase(GroupUriTooLong); + handlecase(PermissionTooLong); + handlecase(TargetBucketTooLong); + handlecase(TargetPrefixTooLong); + handlecase(TooManyGrants); + handlecase(BadGrantee); + handlecase(BadPermission); + handlecase(XmlDocumentTooLarge); + handlecase(NameLookupError); + handlecase(FailedToConnect); + handlecase(ServerFailedVerification); + handlecase(ConnectionFailed); + handlecase(AbortedByCallback); + handlecase(ErrorAccessDenied); + handlecase(ErrorAccountProblem); + handlecase(ErrorAmbiguousGrantByEmailAddress); + handlecase(ErrorBadDigest); + handlecase(ErrorBucketAlreadyExists); + handlecase(ErrorBucketAlreadyOwnedByYou); + handlecase(ErrorBucketNotEmpty); + handlecase(ErrorCredentialsNotSupported); + handlecase(ErrorCrossLocationLoggingProhibited); + handlecase(ErrorEntityTooSmall); + handlecase(ErrorEntityTooLarge); + handlecase(ErrorExpiredToken); + handlecase(ErrorIncompleteBody); + handlecase(ErrorIncorrectNumberOfFilesInPostRequest); + handlecase(ErrorInlineDataTooLarge); + handlecase(ErrorInternalError); + handlecase(ErrorInvalidAccessKeyId); + handlecase(ErrorInvalidAddressingHeader); + handlecase(ErrorInvalidArgument); + handlecase(ErrorInvalidBucketName); + handlecase(ErrorInvalidDigest); + handlecase(ErrorInvalidLocationConstraint); + handlecase(ErrorInvalidPayer); + handlecase(ErrorInvalidPolicyDocument); + handlecase(ErrorInvalidRange); + handlecase(ErrorInvalidSecurity); + handlecase(ErrorInvalidSOAPRequest); + handlecase(ErrorInvalidStorageClass); + handlecase(ErrorInvalidTargetBucketForLogging); + handlecase(ErrorInvalidToken); + handlecase(ErrorInvalidURI); + handlecase(ErrorKeyTooLong); + handlecase(ErrorMalformedACLError); + handlecase(ErrorMalformedXML); + handlecase(ErrorMaxMessageLengthExceeded); + handlecase(ErrorMaxPostPreDataLengthExceededError); + handlecase(ErrorMetadataTooLarge); + handlecase(ErrorMethodNotAllowed); + handlecase(ErrorMissingAttachment); + handlecase(ErrorMissingContentLength); + handlecase(ErrorMissingSecurityElement); + handlecase(ErrorMissingSecurityHeader); + handlecase(ErrorNoLoggingStatusForKey); + handlecase(ErrorNoSuchBucket); + handlecase(ErrorNoSuchKey); + handlecase(ErrorNotImplemented); + handlecase(ErrorNotSignedUp); + handlecase(ErrorOperationAborted); + handlecase(ErrorPermanentRedirect); + handlecase(ErrorPreconditionFailed); + handlecase(ErrorRedirect); + handlecase(ErrorRequestIsNotMultiPartContent); + handlecase(ErrorRequestTimeout); + handlecase(ErrorRequestTimeTooSkewed); + handlecase(ErrorRequestTorrentOfBucketError); + handlecase(ErrorSignatureDoesNotMatch); + handlecase(ErrorSlowDown); + handlecase(ErrorTemporaryRedirect); + handlecase(ErrorTokenRefreshRequired); + handlecase(ErrorTooManyBuckets); + handlecase(ErrorUnexpectedContent); + handlecase(ErrorUnresolvableGrantByEmailAddress); + handlecase(ErrorUserKeyMustBeSpecified); + handlecase(ErrorUnknown); + handlecase(HttpErrorMovedTemporarily); + handlecase(HttpErrorBadRequest); + handlecase(HttpErrorForbidden); + handlecase(HttpErrorNotFound); + handlecase(HttpErrorConflict); + handlecase(HttpErrorUnknown); + } + + return "Unknown"; } S3Status S3_validate_bucket_name(const char *bucketName, S3UriStyle uriStyle) { - int virtualHostStyle = (uriStyle == S3UriStyleVirtualHost); - int len = 0, maxlen = virtualHostStyle ? 63 : 255; - const char *b = bucketName; - - int hasDot = 0; - int hasNonDigit = 0; - - while (*b) { - if (len == maxlen) { - return S3StatusInvalidBucketNameTooLong; - } - else if (isalpha(*b)) { - len++, b++; - hasNonDigit = 1; - } - else if (isdigit(*b)) { - len++, b++; - } - else if (len == 0) { - return S3StatusInvalidBucketNameFirstCharacter; - } - else if (*b == '_') { - /* Virtual host style bucket names cannot have underscores */ - if (virtualHostStyle) { - return S3StatusInvalidBucketNameCharacter; - } - len++, b++; - hasNonDigit = 1; - } - else if (*b == '-') { - /* Virtual host style bucket names cannot have .- */ - if (virtualHostStyle && (b > bucketName) && (*(b - 1) == '.')) { - return S3StatusInvalidBucketNameCharacterSequence; - } - len++, b++; - hasNonDigit = 1; - } - else if (*b == '.') { - /* Virtual host style bucket names cannot have -. */ - if (virtualHostStyle && (b > bucketName) && (*(b - 1) == '-')) { - return S3StatusInvalidBucketNameCharacterSequence; - } - len++, b++; - hasDot = 1; - } - else { - return S3StatusInvalidBucketNameCharacter; - } - } - - if (len < 3) { - return S3StatusInvalidBucketNameTooShort; - } - - /* It's not clear from Amazon's documentation exactly what 'IP address - style' means. In its strictest sense, it could mean 'could be a valid - IP address', which would mean that 255.255.255.255 would be invalid, - wherase 256.256.256.256 would be valid. Or it could mean 'has 4 sets - of digits separated by dots'. Who knows. Let's just be really - conservative here: if it has any dots, and no non-digit characters, - then we reject it */ - if (hasDot && !hasNonDigit) { - return S3StatusInvalidBucketNameDotQuadNotation; - } - - return S3StatusOK; + int virtualHostStyle = (uriStyle == S3UriStyleVirtualHost); + int len = 0, maxlen = virtualHostStyle ? 63 : 255; + const char *b = bucketName; + + int hasDot = 0; + int hasNonDigit = 0; + + while (*b) { + if (len == maxlen) { + return S3StatusInvalidBucketNameTooLong; + } + else if (isalpha(*b)) { + len++, b++; + hasNonDigit = 1; + } + else if (isdigit(*b)) { + len++, b++; + } + else if (len == 0) { + return S3StatusInvalidBucketNameFirstCharacter; + } + else if (*b == '_') { + /* Virtual host style bucket names cannot have underscores */ + if (virtualHostStyle) { + return S3StatusInvalidBucketNameCharacter; + } + len++, b++; + hasNonDigit = 1; + } + else if (*b == '-') { + /* Virtual host style bucket names cannot have .- */ + if (virtualHostStyle && (b > bucketName) && (*(b - 1) == '.')) { + return S3StatusInvalidBucketNameCharacterSequence; + } + len++, b++; + hasNonDigit = 1; + } + else if (*b == '.') { + /* Virtual host style bucket names cannot have -. */ + if (virtualHostStyle && (b > bucketName) && (*(b - 1) == '-')) { + return S3StatusInvalidBucketNameCharacterSequence; + } + len++, b++; + hasDot = 1; + } + else { + return S3StatusInvalidBucketNameCharacter; + } + } + + if (len < 3) { + return S3StatusInvalidBucketNameTooShort; + } + + /* It's not clear from Amazon's documentation exactly what 'IP address + style' means. In its strictest sense, it could mean 'could be a valid + IP address', which would mean that 255.255.255.255 would be invalid, + wherase 256.256.256.256 would be valid. Or it could mean 'has 4 sets + of digits separated by dots'. Who knows. Let's just be really + conservative here: if it has any dots, and no non-digit characters, + then we reject it */ + if (hasDot && !hasNonDigit) { + return S3StatusInvalidBucketNameDotQuadNotation; + } + + return S3StatusOK; } typedef struct ConvertAclData { - char *ownerId; - int ownerIdLen; - char *ownerDisplayName; - int ownerDisplayNameLen; - int *aclGrantCountReturn; - S3AclGrant *aclGrants; - - string_buffer(emailAddress, S3_MAX_GRANTEE_EMAIL_ADDRESS_SIZE); - string_buffer(userId, S3_MAX_GRANTEE_USER_ID_SIZE); - string_buffer(userDisplayName, S3_MAX_GRANTEE_DISPLAY_NAME_SIZE); - string_buffer(groupUri, 128); - string_buffer(permission, 32); + char *ownerId; + int ownerIdLen; + char *ownerDisplayName; + int ownerDisplayNameLen; + int *aclGrantCountReturn; + S3AclGrant *aclGrants; + + string_buffer(emailAddress, S3_MAX_GRANTEE_EMAIL_ADDRESS_SIZE); + string_buffer(userId, S3_MAX_GRANTEE_USER_ID_SIZE); + string_buffer(userDisplayName, S3_MAX_GRANTEE_DISPLAY_NAME_SIZE); + string_buffer(groupUri, 128); + string_buffer(permission, 32); } ConvertAclData; static S3Status convertAclXmlCallback(const char *elementPath, - const char *data, int dataLen, - void *callbackData) + const char *data, int dataLen, + void *callbackData) { - ConvertAclData *caData = (ConvertAclData *) callbackData; - - int fit; - - if (data) { - if (!strcmp(elementPath, "AccessControlPolicy/Owner/ID")) { - caData->ownerIdLen += - snprintf(&(caData->ownerId[caData->ownerIdLen]), - S3_MAX_GRANTEE_USER_ID_SIZE - caData->ownerIdLen - 1, - "%.*s", dataLen, data); - if (caData->ownerIdLen >= S3_MAX_GRANTEE_USER_ID_SIZE) { - return S3StatusUserIdTooLong; - } - } - else if (!strcmp(elementPath, "AccessControlPolicy/Owner/" - "DisplayName")) { - caData->ownerDisplayNameLen += - snprintf(&(caData->ownerDisplayName - [caData->ownerDisplayNameLen]), - S3_MAX_GRANTEE_DISPLAY_NAME_SIZE - - caData->ownerDisplayNameLen - 1, - "%.*s", dataLen, data); - if (caData->ownerDisplayNameLen >= - S3_MAX_GRANTEE_DISPLAY_NAME_SIZE) { - return S3StatusUserDisplayNameTooLong; - } - } - else if (!strcmp(elementPath, - "AccessControlPolicy/AccessControlList/Grant/" - "Grantee/EmailAddress")) { - // AmazonCustomerByEmail - string_buffer_append(caData->emailAddress, data, dataLen, fit); - if (!fit) { - return S3StatusEmailAddressTooLong; - } - } - else if (!strcmp(elementPath, - "AccessControlPolicy/AccessControlList/Grant/" - "Grantee/ID")) { - // CanonicalUser - string_buffer_append(caData->userId, data, dataLen, fit); - if (!fit) { - return S3StatusUserIdTooLong; - } - } - else if (!strcmp(elementPath, - "AccessControlPolicy/AccessControlList/Grant/" - "Grantee/DisplayName")) { - // CanonicalUser - string_buffer_append(caData->userDisplayName, data, dataLen, fit); - if (!fit) { - return S3StatusUserDisplayNameTooLong; - } - } - else if (!strcmp(elementPath, - "AccessControlPolicy/AccessControlList/Grant/" - "Grantee/URI")) { - // Group - string_buffer_append(caData->groupUri, data, dataLen, fit); - if (!fit) { - return S3StatusGroupUriTooLong; - } - } - else if (!strcmp(elementPath, - "AccessControlPolicy/AccessControlList/Grant/" - "Permission")) { - // Permission - string_buffer_append(caData->permission, data, dataLen, fit); - if (!fit) { - return S3StatusPermissionTooLong; - } - } - } - else { - if (!strcmp(elementPath, "AccessControlPolicy/AccessControlList/" - "Grant")) { - // A grant has just been completed; so add the next S3AclGrant - // based on the values read - if (*(caData->aclGrantCountReturn) == S3_MAX_ACL_GRANT_COUNT) { - return S3StatusTooManyGrants; - } - - S3AclGrant *grant = &(caData->aclGrants - [*(caData->aclGrantCountReturn)]); - - if (caData->emailAddress[0]) { - grant->granteeType = S3GranteeTypeAmazonCustomerByEmail; - strcpy(grant->grantee.amazonCustomerByEmail.emailAddress, - caData->emailAddress); - } - else if (caData->userId[0] && caData->userDisplayName[0]) { - grant->granteeType = S3GranteeTypeCanonicalUser; - strcpy(grant->grantee.canonicalUser.id, caData->userId); - strcpy(grant->grantee.canonicalUser.displayName, - caData->userDisplayName); - } - else if (caData->groupUri[0]) { - if (!strcmp(caData->groupUri, - "http://acs.amazonaws.com/groups/global/" - "AuthenticatedUsers")) { - grant->granteeType = S3GranteeTypeAllAwsUsers; - } - else if (!strcmp(caData->groupUri, - "http://acs.amazonaws.com/groups/global/" - "AllUsers")) { - grant->granteeType = S3GranteeTypeAllUsers; - } - else if (!strcmp(caData->groupUri, - "http://acs.amazonaws.com/groups/s3/" - "LogDelivery")) { - grant->granteeType = S3GranteeTypeLogDelivery; - } - else { - return S3StatusBadGrantee; - } - } - else { - return S3StatusBadGrantee; - } - - if (!strcmp(caData->permission, "READ")) { - grant->permission = S3PermissionRead; - } - else if (!strcmp(caData->permission, "WRITE")) { - grant->permission = S3PermissionWrite; - } - else if (!strcmp(caData->permission, "READ_ACP")) { - grant->permission = S3PermissionReadACP; - } - else if (!strcmp(caData->permission, "WRITE_ACP")) { - grant->permission = S3PermissionWriteACP; - } - else if (!strcmp(caData->permission, "FULL_CONTROL")) { - grant->permission = S3PermissionFullControl; - } - else { - return S3StatusBadPermission; - } - - (*(caData->aclGrantCountReturn))++; - - string_buffer_initialize(caData->emailAddress); - string_buffer_initialize(caData->userId); - string_buffer_initialize(caData->userDisplayName); - string_buffer_initialize(caData->groupUri); - string_buffer_initialize(caData->permission); - } - } - - return S3StatusOK; + ConvertAclData *caData = (ConvertAclData *) callbackData; + + int fit; + + if (data) { + if (!strcmp(elementPath, "AccessControlPolicy/Owner/ID")) { + caData->ownerIdLen += + snprintf(&(caData->ownerId[caData->ownerIdLen]), + S3_MAX_GRANTEE_USER_ID_SIZE - caData->ownerIdLen - 1, + "%.*s", dataLen, data); + if (caData->ownerIdLen >= S3_MAX_GRANTEE_USER_ID_SIZE) { + return S3StatusUserIdTooLong; + } + } + else if (!strcmp(elementPath, "AccessControlPolicy/Owner/" + "DisplayName")) { + caData->ownerDisplayNameLen += + snprintf(&(caData->ownerDisplayName + [caData->ownerDisplayNameLen]), + S3_MAX_GRANTEE_DISPLAY_NAME_SIZE - + caData->ownerDisplayNameLen - 1, + "%.*s", dataLen, data); + if (caData->ownerDisplayNameLen >= + S3_MAX_GRANTEE_DISPLAY_NAME_SIZE) { + return S3StatusUserDisplayNameTooLong; + } + } + else if (!strcmp(elementPath, + "AccessControlPolicy/AccessControlList/Grant/" + "Grantee/EmailAddress")) { + // AmazonCustomerByEmail + string_buffer_append(caData->emailAddress, data, dataLen, fit); + if (!fit) { + return S3StatusEmailAddressTooLong; + } + } + else if (!strcmp(elementPath, + "AccessControlPolicy/AccessControlList/Grant/" + "Grantee/ID")) { + // CanonicalUser + string_buffer_append(caData->userId, data, dataLen, fit); + if (!fit) { + return S3StatusUserIdTooLong; + } + } + else if (!strcmp(elementPath, + "AccessControlPolicy/AccessControlList/Grant/" + "Grantee/DisplayName")) { + // CanonicalUser + string_buffer_append(caData->userDisplayName, data, dataLen, fit); + if (!fit) { + return S3StatusUserDisplayNameTooLong; + } + } + else if (!strcmp(elementPath, + "AccessControlPolicy/AccessControlList/Grant/" + "Grantee/URI")) { + // Group + string_buffer_append(caData->groupUri, data, dataLen, fit); + if (!fit) { + return S3StatusGroupUriTooLong; + } + } + else if (!strcmp(elementPath, + "AccessControlPolicy/AccessControlList/Grant/" + "Permission")) { + // Permission + string_buffer_append(caData->permission, data, dataLen, fit); + if (!fit) { + return S3StatusPermissionTooLong; + } + } + } + else { + if (!strcmp(elementPath, "AccessControlPolicy/AccessControlList/" + "Grant")) { + // A grant has just been completed; so add the next S3AclGrant + // based on the values read + if (*(caData->aclGrantCountReturn) == S3_MAX_ACL_GRANT_COUNT) { + return S3StatusTooManyGrants; + } + + S3AclGrant *grant = &(caData->aclGrants + [*(caData->aclGrantCountReturn)]); + + if (caData->emailAddress[0]) { + grant->granteeType = S3GranteeTypeAmazonCustomerByEmail; + strcpy(grant->grantee.amazonCustomerByEmail.emailAddress, + caData->emailAddress); + } + else if (caData->userId[0] && caData->userDisplayName[0]) { + grant->granteeType = S3GranteeTypeCanonicalUser; + strcpy(grant->grantee.canonicalUser.id, caData->userId); + strcpy(grant->grantee.canonicalUser.displayName, + caData->userDisplayName); + } + else if (caData->groupUri[0]) { + if (!strcmp(caData->groupUri, + "http://acs.amazonaws.com/groups/global/" + "AuthenticatedUsers")) { + grant->granteeType = S3GranteeTypeAllAwsUsers; + } + else if (!strcmp(caData->groupUri, + "http://acs.amazonaws.com/groups/global/" + "AllUsers")) { + grant->granteeType = S3GranteeTypeAllUsers; + } + else if (!strcmp(caData->groupUri, + "http://acs.amazonaws.com/groups/s3/" + "LogDelivery")) { + grant->granteeType = S3GranteeTypeLogDelivery; + } + else { + return S3StatusBadGrantee; + } + } + else { + return S3StatusBadGrantee; + } + + if (!strcmp(caData->permission, "READ")) { + grant->permission = S3PermissionRead; + } + else if (!strcmp(caData->permission, "WRITE")) { + grant->permission = S3PermissionWrite; + } + else if (!strcmp(caData->permission, "READ_ACP")) { + grant->permission = S3PermissionReadACP; + } + else if (!strcmp(caData->permission, "WRITE_ACP")) { + grant->permission = S3PermissionWriteACP; + } + else if (!strcmp(caData->permission, "FULL_CONTROL")) { + grant->permission = S3PermissionFullControl; + } + else { + return S3StatusBadPermission; + } + + (*(caData->aclGrantCountReturn))++; + + string_buffer_initialize(caData->emailAddress); + string_buffer_initialize(caData->userId); + string_buffer_initialize(caData->userDisplayName); + string_buffer_initialize(caData->groupUri); + string_buffer_initialize(caData->permission); + } + } + + return S3StatusOK; } S3Status S3_convert_acl(char *aclXml, char *ownerId, char *ownerDisplayName, - int *aclGrantCountReturn, S3AclGrant *aclGrants) + int *aclGrantCountReturn, S3AclGrant *aclGrants) { - ConvertAclData data; - - data.ownerId = ownerId; - data.ownerIdLen = 0; - data.ownerId[0] = 0; - data.ownerDisplayName = ownerDisplayName; - data.ownerDisplayNameLen = 0; - data.ownerDisplayName[0] = 0; - data.aclGrantCountReturn = aclGrantCountReturn; - data.aclGrants = aclGrants; - *aclGrantCountReturn = 0; - string_buffer_initialize(data.emailAddress); - string_buffer_initialize(data.userId); - string_buffer_initialize(data.userDisplayName); - string_buffer_initialize(data.groupUri); - string_buffer_initialize(data.permission); - - // Use a simplexml parser - SimpleXml simpleXml; - simplexml_initialize(&simpleXml, &convertAclXmlCallback, &data); - - S3Status status = simplexml_add(&simpleXml, aclXml, strlen(aclXml)); - - simplexml_deinitialize(&simpleXml); - - return status; + ConvertAclData data; + + data.ownerId = ownerId; + data.ownerIdLen = 0; + data.ownerId[0] = 0; + data.ownerDisplayName = ownerDisplayName; + data.ownerDisplayNameLen = 0; + data.ownerDisplayName[0] = 0; + data.aclGrantCountReturn = aclGrantCountReturn; + data.aclGrants = aclGrants; + *aclGrantCountReturn = 0; + string_buffer_initialize(data.emailAddress); + string_buffer_initialize(data.userId); + string_buffer_initialize(data.userDisplayName); + string_buffer_initialize(data.groupUri); + string_buffer_initialize(data.permission); + + // Use a simplexml parser + SimpleXml simpleXml; + simplexml_initialize(&simpleXml, &convertAclXmlCallback, &data); + + S3Status status = simplexml_add(&simpleXml, aclXml, strlen(aclXml)); + + simplexml_deinitialize(&simpleXml); + + return status; } 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; - } + switch (status) { + case S3StatusNameLookupError: + case S3StatusFailedToConnect: + case S3StatusConnectionFailed: + case S3StatusErrorInternalError: + case S3StatusErrorOperationAborted: + case S3StatusErrorRequestTimeout: + return 1; + default: + return 0; + } } |