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() */