Processing attribute values

The code fragment below declares an example routine, attr_display_values, which prints the values of an attribute as text. attr_display_values calls two other utility routines to perform its work:

.

/*
 ** attr_display_values()
 **   Writes an attribute's values to the specified text
 **   file.
 **
 ** Parameters
 **   attr_metadata -- address of the CS_ATTRIBUTE structure that
 **      contains metadata for the attribute.
 **   attr_vals -- address of an array of CS_ATTRVALUE structures.
 **       This function assumes length is attr_metadata->attr_numvals
 **       and value syntax is attr_metadata->attr_syntax.
 **   outfile -- Open FILE handle to write to.
 **
 ** Returns
 **   CS_SUCCEED or CS_FAIL.
 */
CS_RETCODE 
 attr_display_values(attr_metadata, attr_vals, outfile)
 CS_ATTRIBUTE       *attr_metadata;
 CS_ATTRVALUE       *attr_vals;
 FILE               *outfile;
 {
     CS_INT              i;
     CS_CHAR             outbuf[CS_MAX_DS_STRING * 3];
     CS_RETCODE          ret;
 
     /*
     ** Print each value.
     */
     for (i = 0; i < attr_metadata->attr_numvals; i++)
     {
         ret = attr_val_as_string(attr_metadata, attr_vals + i,
                                  outbuf, CS_MAX_DS_STRING * 3, NULL);
         if (ret != CS_SUCCEED)
         {
             ex_error("attr_display_values: attr_val_as_string() failed.");
             return CS_FAIL;
         }
         fprintf(outfile, "\t%s\n", outbuf);
     }
 
     return CS_SUCCEED;
 
 } /* attr_display_values() */
/*
 ** attr_val_as_string() -- Convert the contents of a CS_ATTRVALUE union to
 **   a printable string.
 **
 ** Parameters
 **   attr_metadata -- The CS_ATTRIBUTE structure containing metadata
 **       for the attribute value.
 **   val -- Pointer to the CS_ATTRVALUE union.
 **   buffer -- Address of the buffer to receive the converted value.
 **   buflen -- Length of *buffer in bytes.
 **   outlen -- If supplied, will be set to the number of bytes written
 **      to *buffer.
 **
 ** Returns
 **   CS_SUCCEED or CS_FAIL.
 */
CS_RETCODE
 attr_val_as_string(attr_metadata, val, buffer, buflen, outlen)
 CS_ATTRIBUTE       *attr_metadata;
 CS_ATTRVALUE       *val;
 CS_CHAR            *buffer;
 CS_INT              buflen;
 CS_INT             *outlen;
 {
     CS_CHAR             outbuf[CS_MAX_DS_STRING * 4];
     CS_CHAR             scratch[CS_MAX_DS_STRING];
     CS_RETCODE          ret;
if (buflen == 0 || buffer == NULL)
     {
         return CS_FAIL;
     }
     if (outlen != NULL)
     {
         *outlen = 0;
     }
switch ((int)attr_metadata->attr_syntax)
     {
     case CS_ATTR_SYNTAX_STRING:
         sprintf(outbuf, "%.*s",
                 (int)(val->value_string.str_length),
                 val->value_string.str_buffer);
         break;
 
     case CS_ATTR_SYNTAX_BOOLEAN:
         sprintf(outbuf, "%s",
                 val->value_boolean == CS_TRUE ? "True" : "False");
         break;
case CS_ATTR_SYNTAX_INTEGER:
     case CS_ATTR_SYNTAX_ENUMERATION:
 
        /*
         ** Some enumerated or integer attribute values should be converted
         ** into an english-language equivalent. attr_enum_english_name()
         ** contains all the logic to convert #define's into human
         ** language.
         */
         ret = attr_enum_english_name((CS_INT)(val->value_enumeration),
                                      &(attr_metadata->attr_type),
                                      scratch, CS_MAX_DS_STRING, NULL);
         if (ret != CS_SUCCEED)
         {
             ex_error("attr_val_as_string: attr_enum_english_name() failed.");
             return CS_FAIL;
         }
         sprintf(outbuf, "%s", scratch);
         break;
case CS_ATTR_SYNTAX_TRANADDR:
          /*
         ** The access type is an enumerated value. Get an english language
         ** string for it.
         */
         switch ((int)(val->value_tranaddr.addr_accesstype))
         {
         case CS_ACCESS_CLIENT:
             sprintf(scratch, "client");
             break;
         case CS_ACCESS_ADMIN:
             sprintf(scratch, "administrative");
             break;
         case CS_ACCESS_MGMTAGENT:
             sprintf(scratch, "management agent");
             break;
         default:
             sprintf(scratch, "%ld", 
                     (long)(val->value_tranaddr.addr_accesstype));
             break;
         }
sprintf(outbuf, 
             "Access type '%s'; Transport type '%s'; Address '%s'",
                 scratch,
                 val->value_tranaddr.addr_trantype.str_buffer,
                 val->value_tranaddr.addr_tranaddress.str_buffer);
 
         break;
case CS_ATTR_SYNTAX_OID:
         sprintf(outbuf, "%.*s",
                 (int)(val->value_oid.oid_length),
                 val->value_oid.oid_buffer);
         break;
 
     default:
         sprintf(outbuf, "Unknown attribute value syntax");
         break;
 
     } /* switch */
if (strlen(outbuf) + 1 > buflen || buffer == NULL)
     {
         return CS_FAIL;
     }
     else
     {
         sprintf(buffer, "%s", outbuf);
         if (outlen != NULL)
         {
             *outlen = strlen(outbuf) + 1;
         }
     }
 
     return CS_SUCCEED;
 
 } /* attr_val_as_string() */
/*
 ** attr_enum_english_name()
 **   Based on the attribute type, associate an english phrase with
 **   a CS_INT value. Use this function to get meaningful names for
 **   CS_ATTR_SYNTAX_ENUMERATION or CS_ATTR_SYNTAX_INTEGER attribute
 **   values.
 **
 **   If the attribute type represents a quantity and not a numeric code,
 **   then the value is converted to the string representation of the
 **   number. Unknown codes are handled the same way.
 **
 ** Parameters
 **   enum_val -- The integer value to convert to a string.
 **   attr_type -- Pointer to an OID structure containing the OID string
 **      that tells the attribute's type.
 **   buffer -- Address of the buffer to receive the converted value.
 **   buflen -- Length of *buffer in bytes.
 **   outlen -- If supplied, will be set to the number of bytes written
 **      to *buffer.
 **
 ** Returns
 **   CS_SUCCEED or CS_FAIL
 */
CS_RETCODE
 attr_enum_english_name(enum_val, attr_type, buffer, buflen, outlen)
 CS_INT              enum_val;
 CS_OID             *attr_type;
 CS_CHAR            *buffer;
 CS_INT              buflen;
 CS_INT             *outlen;
 {
     CS_CHAR             outbuf[CS_MAX_DS_STRING];
if (buffer == NULL || buflen <= 0)
     {
         return CS_FAIL;
     }
     if (outlen != NULL)
     {
         *outlen = 0;
     }
     /*
     ** Server version number.
     */
     if (match_OID(attr_type, CS_OID_ATTRVERSION))
     {
         sprintf(outbuf, "%ld", (long)enum_val);
     }
     /*
     ** Server's status.
     */
     else if (match_OID(attr_type, CS_OID_ATTRSTATUS))
     {
         switch ((int)enum_val)
         {
         case CS_STATUS_ACTIVE:
             sprintf(outbuf, "running");
             break;
         case CS_STATUS_STOPPED:
             sprintf(outbuf, "stopped");
             break;
         case CS_STATUS_FAILED:
             sprintf(outbuf, "failed");
             break;
         case CS_STATUS_UNKNOWN:
             sprintf(outbuf, "unknown");
             break;
         default:
             sprintf(outbuf, "%ld", (long)enum_val);
             break;
         }
     }
     /*
     ** Anything else is either an enumerated type that we don't know
     ** about, or it really is just a number. We print the numeric value.
     */
     else
     {
         sprintf(outbuf, "%ld", (long)enum_val);
     }
     /*
     ** Transfer output to the caller's buffer.
     */
     if (strlen(outbuf) + 1 > buflen || buffer == NULL)
     {
         return CS_FAIL;
     }
     else
     {
         sprintf(buffer, "%s", outbuf);
         if (outlen != NULL)
         {
             *outlen = strlen(outbuf) + 1;
         }
     }
 return CS_SUCCEED;
 } /* attr_enum_english_name() */