?? zdmwrite.c
字號:
VtStorageCtx storageCtx,
VtTransportCtx transportCtx,
VoltZDRLocationList *locationList,
char **address,
unsigned int *addressLen
)
{
int status, status2;
unsigned int index, maxIndex, recipCount, voteCount, sameIdentity;
UInt32 lenLo, lenHi;
VoltPolicyCtx *pCtx = (VoltPolicyCtx *)policyCtx;
VtIdentityObject getId;
VtItem *getDefLocation = (VtItem *)0;
VtItem *getDefDomain = (VtItem *)0;
unsigned char* defaultDomain = (unsigned char*)0;
VtDistrictObject defaultZDMDistrict = (VtDistrictObject)0;
VtItem *votedLocation;
VtItem *location;
int isSenderLocation;
unsigned int count;
unsigned int theTag, lengthLen, valueLen;
int isSenderRecipient = 0;
VtItem senderLocation;
unsigned int recipientCount;
VtMpIntCtx mpIntCtx = (VtMpIntCtx)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Logic.
* 1. Does at least one of the recipients use a ZDR location?
* yes, move on to step 2.
* no, move on to step 6.
*
* 2. At least one of the recipients has a ZDR location. Do all
* recipients use the same ZDR location?
* yes, return that location.
* no, move on to step 3.
*
* 3. At least one of the recipients has a ZDR location, but not
* all share the same location. Do some recipients have no ZDR
* location, but all others specify the same location?
* yes, use the ZDR location the recipients share.
* no, move on to step 4.
*
* 4. There are multiple ZDR locations among the recipients. Is
* there a default location in the (sender's) policy?
* yes, use the default location.
* no, move on to step 5.
*
* 5. There are multiple ZDR locations among the recipients and no
* default location in the policy. Take a "vote". Does one location
* appear among the recipients more than any other location?
* yes, return that location.
* no, return the first location recorded.
*
* 6. There are no ZDR locations among the recipients. Is there a
* default location in the (sender's) policy?
* yes, return that location
* no, move on to step 7.
*
* 7. There are no ZDR locations among the recipients and there is
* no default location in the policy. Does the sender have a ZDR
* location?
* yes, return that location.
* no, return an error, we cannot build a ZDM message.
*/
do
{
Z2Memset(&senderLocation, 0, sizeof(senderLocation));
/* Get the ZDR location of each recipient.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityListCount (
writeCtx->recipListRef, &recipCount, &maxIndex);
if (status != 0)
break;
for (index = 0; index <= maxIndex; ++index)
{
/* To get a ZDR location, get an identity, get the district from
* that identity, get the district extensions from that district,
* and get the ZDR location extension from the extension list.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityListIdentity (
writeCtx->recipListRef, index, &getId);
if (status == VT_ERROR_NO_ID_AT_INDEX)
continue;
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = GetZDRLocationFromIdentity (
libCtx, getId, policyCtx, storageCtx, transportCtx, &location);
if (status != 0)
break;
/* Is this the sender? If so, set a flag so we know that the
* sender is also a recipient.
*/
VoltIsSameIdentity (getId, writeCtx->senderIdRef, &sameIdentity);
if (sameIdentity != 0)
{
isSenderRecipient = 1;
if (location != (VtItem*)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeTagAndLen (
libCtx, location->data, location->len, &theTag, &lengthLen,
&lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
senderLocation.data = (unsigned char *)Z2Malloc (valueLen, 0);
if (senderLocation.data == (unsigned char *)0)
break;
Z2Memcpy (senderLocation.data, location->data + lengthLen + 1, valueLen);
senderLocation.len = valueLen;
}
}
if (location != (VtItem *)0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = AddToLocationList (
libCtx, getId, location, locationList);
if (status != 0)
break;
}
}
if (status != 0)
break;
/* If none of the recipients' districts support ZDM, then we
* shouldn't send a ZDM, since none of them will be able to read it.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NO_ZDM_LOCATION;
if (locationList->count == 0)
break;
/* If all of the recipients use the same location, then we use that
* as the ZDM location. We need this to handle the case where all
* the recipients and the sender have the same location. There's
* another test below after voting that catches the case where
* all the recipients (not including the sender) have the same
* location.
*/
if (locationList->count == locationList->locationCount[0])
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = CopyZDRLocation (
libCtx, &locationList->location[0], address, addressLen);
break;
}
/* If the sender is also a recipient, we have the sender's ZDR
* location already. If not, get it now. If there is one, the
* sender will be included in the Form's Select list.
*/
if (isSenderRecipient == 0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = GetSenderZDRLocationAlloc (
libCtx, obj, writeCtx, policyCtx, storageCtx, transportCtx,
&senderLocation);
if (status != 0)
break;
}
/* Figure out which location is used by the majority of the
* recipients. We'll use the final vote count to determine
* if all of the recipients (not including the sender) use
* the same district. If that's the case we'll use that
* district (i.e. case 2 in the logic described above).
* Otherwise we'll continue on to check the default ZDM
* location. If there's no default location, then we'll
* use the majority location determined here.
*/
votedLocation = (VtItem*)0;
voteCount = 0;
for (index = 0; index < locationList->count; ++index)
{
location = &locationList->location[index];
count = locationList->locationCount[index];
isSenderLocation = (location->len == senderLocation.len) &&
(Z2Memcmp(location->data, senderLocation.data, location->len) == 0);
if (!isSenderLocation && (count > voteCount))
{
votedLocation = location;
voteCount = count;
}
}
/* Figure out how many recipients we have (not including the sender)
*/
recipientCount = locationList->count;
if (isSenderRecipient)
recipientCount--;
/* If all the recipients (not including the sender) are using the
* same district, then use it.
*/
if ((voteCount > 0) && (voteCount == recipientCount))
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = CopyZDRLocation (
libCtx, votedLocation, address, addressLen);
break;
}
/* We don't have a location yet, get the default location from the
* policy. The value that's stored in client policy is the domain
* name of the district whose location we want to use, so we need
* to translate from the domain name to the district to the ZDM
* location.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = pCtx->PolicyGetInfoAlloc (
policyCtx, VOLT_POLICY_GET_DEFAULT_ZDR_LOCATION,
(Pointer)0, (Pointer *)&getDefDomain);
if ( (status != 0) && (status != VT_ERROR_POLICY_NOT_SUPPORTED) )
break;
if ( (getDefDomain != (VtItem *)0) && (getDefDomain->len > 0) )
{
/* Copy the VtItem domain name over to null-terminated string */
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
defaultDomain = Z3Malloc(getDefDomain->len + 1);
if (defaultDomain == (unsigned char*)0)
break;
Z2Memcpy(defaultDomain, getDefDomain->data, getDefDomain->len);
defaultDomain[getDefDomain->len] = 0;
/* If there's a problem retrieving the default ZDM location,
* we convert the error to the INVALID_ZDM_LOCATION error.
*/
status = VT_ERROR_INVALID_ZDM_LOCATION;
if (writeCtx->senderIdRef != (VtIdentityObject)0)
mpIntCtx = writeCtx->senderIdRef->mpCtx;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status2 = VtCreateDistrictObject (
libCtx,
(mpIntCtx != 0) ? VtDistrictImplMpCtx : VtDistrictImplBasic,
(Pointer)mpIntCtx, &defaultZDMDistrict);
if (status2 != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status2 = VtSetDistrictParam (
defaultZDMDistrict, VtDistrictParamDomainName,
(Pointer) defaultDomain);
if (status2 != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status2 = VtObtainIBEParams(defaultZDMDistrict, policyCtx,
storageCtx, transportCtx);
if (status2 != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status2 = GetZDRLocationFromDistrict(libCtx, defaultZDMDistrict,
&getDefLocation);
if (status2 != 0)
break;
if (getDefLocation != (VtItem*)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeTagAndLen (
libCtx, getDefLocation->data, getDefLocation->len, &theTag, &lengthLen,
&lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
*address = (char *)Z2Malloc (valueLen, 0);
if (*address == (char *)0)
break;
Z2Memcpy (*address, getDefLocation->data + lengthLen + 1, valueLen);
*addressLen = valueLen;
}
break;
}
if (votedLocation != (VtItem*)0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = CopyZDRLocation (libCtx, votedLocation, address, addressLen);
break;
}
/* Use the sender's location as the final try. If the sender's district
* doesn't have ZDM enabled, then we return an error.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NO_ZDM_LOCATION;
if (senderLocation.data == (unsigned char *)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = CopyZDRLocation (
libCtx, &senderLocation, address, addressLen);
} while (0);
Z2Free (senderLocation.data);
if (getDefDomain != (VtItem *)0)
pCtx->PolicyGetInfoFree (policyCtx, (Pointer)getDefDomain);
Z2Free (defaultDomain);
VtDestroyDistrictObject(&defaultZDMDistrict);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libCtx, obj, status, 0, errorType,
(char *)0, "GetFormAddressAlloc", fnctLine, (char *)0)
return (status);
}
static int CopyZDRLocation (
VoltLibCtx *libCtx,
VtItem *location,
char **address,
unsigned int *addressLen
)
{
char *newVal = (char *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
VOLT_SET_FNCT_LINE (fnctLine)
newVal = (char *)Z2Malloc (location->len, 0);
if (newVal != (char *)0)
{
Z2Memcpy (newVal, location->data, location->len);
*address = newVal;
*addressLen = location->len;
return (0);
}
VOLT_LOG_ERROR_INFO (
libCtx, 0, VT_ERROR_MEMORY, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "CopyZDRLocation", fnctLine, (char *)0)
return (VT_ERROR_MEMORY);
}
static int AddToLocationList (
VoltLibCtx *libCtx,
VtIdentityObject idToAdd,
VtItem *location,
VoltZDRLocationList *locationList
)
{
int status;
unsigned int index, theTag, lengthLen, valueLen;
UInt32 lenLo, lenHi;
unsigned char *value;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Add the id to the list of selections.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
locationList->recipientSelections = (VtIdentityObject *)Z2Realloc (
locationList->recipientSelections,
(locationList->count + 1) * sizeof (VtIdentityObject));
if (locationList->recipientSelections == (VtIdentityObject *)0)
break;
locationList->recipientSelections[locationList->count] = idToAdd;
/* The location returned is TLV of some encoding.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeTagAndLen (
libCtx, location->data, location->len, &theTag, &lengthLen,
&lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
value = location->data + (lengthLen + 1);
/* First, is this a location already logged?
*/
for (index = 0; index < locationList->count; ++index)
{
if (valueLen != locationList->location[index].len)
continue;
if (Z2Memcmp (
value, locationList->location[index].data, valueLen) == 0)
break;
}
/* If we broke out before the end, we found a match.
*/
if (index < locationList->count)
{
/* Increment the count of this location.
*/
locationList->locationCount[index] =
locationList->locationCount[index] + 1;
}
/* Add this location to the list.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
locationList->location = (VtItem *)Z2Realloc (
locationList->location, (locationList->count + 1) * sizeof (VtItem));
if (locationList->location == (VtItem *)0)
break;
locationList->location[locationList->count].data = value;
locationList->location[locationList->count].len = valueLen;
VOLT_SET_FNCT_LINE (fnctLine)
locationList->locationCount = (unsigned int *)Z2Realloc (
locationList->locationCount,
(locationList->count + 1) * sizeof (unsigned int));
if (locationList->locationCount == (unsigned int *)0)
break;
locationList->locationCount[locationList->count] = 1;
locationList->count = locationList->count + 1;
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libCtx, 0, status, 0, errorType,
(char *)0, "AddToLocationList", fnctLine, (char *)0)
return (status);
}
static int GetSenderZDRLocationAlloc (
VoltLibCtx *libCtx,
VoltSecureMailObject *obj,
VoltSecureMailWriteCtx *writeCtx,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -