The example fragment below contains the code for the attr_get_by_type example utility routine. attr_get_by_type takes an OID string that specifies the desired attribute type, searches for the desired attribute in the directory object’s attribute set, and returns the attribute’s metadata and values if they are found.
/*
** get_attr_by_type()
** Get metadata and attribute values for a given attribute type.
**
** Parameters
** ds_object -- Pointer to a valid CS_DS_OBJECT hidden structure.
** attr_type_str -- Null-terminated string containing the OID for the
** desired attribute type.
** attr_metadata -- Pointer to a CS_ATTRIBUTE structure to
** fill in.
** p_attrvals -- Address of a CS_ATTRVALUE union pointer.
** If successful, this routine allocates an array
** of size attr_metadata->numvalues, retrieves values into
** it, and returns the array address in *p_attr_values.
** NOTE: The caller must free this array when it is no longer
** needed.
**
** Returns
** CS_FAIL if no attribute of the specified type was found.
** CS_SUCCEED for success.
*/
CS_RETCODE
attr_get_by_type(ds_object, attr_type_str, attr_metadata, p_attrvals)
CS_DS_OBJECT *ds_object;
CS_CHAR *attr_type_str;
CS_ATTRIBUTE *attr_metadata;
CS_ATTRVALUE **p_attrvals;
{
CS_RETCODE ret;
CS_INT num_attrs;
CS_INT cur_attr;
CS_INT outlen;
CS_INT buflen;
CS_BOOL found = CS_FALSE;
/*
** Check input pointers. If not NULL, make them fail safe.
*/
if (attr_metadata == NULL || p_attrvals == NULL)
{
return CS_FAIL;
}
attr_metadata->attr_numvals = 0;
*p_attrvals = NULL;
/*
** Get number of attributes.
*/
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_NUMATTR, CS_UNUSED,
(CS_VOID *)#_attrs, CS_SIZEOF(num_attrs),
NULL);
if (ret != CS_SUCCEED)
{
ex_error("attr_get_by_type: get number of attributes failed.");
return CS_FAIL;
}
/*
** Look for the matching attribute, get the values if found.
*/
for (cur_attr = 1;
cur_attr <= num_attrs && found != CS_TRUE;
cur_attr++)
{
/*
** Get the attribute's metadata.
*/
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_ATTRIBUTE, cur_attr,
(CS_VOID *)attr_metadata,
CS_SIZEOF(CS_ATTRIBUTE), NULL);
if (ret != CS_SUCCEED)
{
ex_error("attr_get_by_type: get attribute failed.");
return CS_FAIL;
}
/*
** Check for a match.
*/
if (match_OID(&(attr_metadata->attr_type), attr_type_str))
{
found = CS_TRUE;
/*
** Get the values -- we first allocate an array of
** CS_ATTRVALUE unions.
*/
*p_attrvals = (CS_ATTRVALUE *) malloc(sizeof(CS_ATTRVALUE)
* (attr_metadata->attr_numvals));
if (p_attrvals == NULL)
{
ex_error("attr_get_by_type: out of memory!");
return CS_FAIL;
}
buflen = CS_SIZEOF(CS_ATTRVALUE) * (attr_metadata->attr_numvals);
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_ATTRVALS, cur_attr,
(CS_VOID *)(*p_attrvals), buflen, &outlen);
if (ret != CS_SUCCEED)
{
ex_error("attr_get_by_type: get attribute values failed.");
free(*p_attrvals);
*p_attrvals = NULL;
attr_metadata->attr_numvals = 0;
return CS_FAIL;
}
}
}
/*
** Got the attribute.
*/
if (found == CS_TRUE)
{
return CS_SUCCEED;
}
/*
** Not found.
*/
attr_metadata->attr_numvals = 0;
return CS_FAIL;
} /* attr_get_by_type() */
/*
** match_OID()
** Compare a pre-defined OID string to the contents of a
** CS_OID structure.
**
** Parameters
** oid -- Pointer to a CS_OID structure. OID->oid_length should be
** the length of the string, not including any null-terminator.
** oid_string -- Null-terminated OID string to compare.
**
** Returns
** Non-zero if contents of oid->oid_buffer matches contents
** of oid_string.
*/
int match_OID(oid, oid_string)
CS_OID *oid;
CS_CHAR *oid_string;
{
return ((strncmp(oid_string, oid->oid_buffer, oid->oid_length) == 0)
&& ((oid->oid_length == strlen(oid_string))));
} /* match_OID() */