/********************************************************************

   Copyright (c) 1996 Novell, Inc.  All Rights Reserved.

   With respect to this file, Novell hereby grants to Developer a 
   royalty-free, non-exclusive license to include this sample code 
   and derivative binaries in its product. Novell grants to Developer 
   worldwide distribution rights to market, distribute or sell this 
   sample code file and derivative binaries as a component of 
   Developer's product(s).  Novell shall have no obligations to 
   Developer or Developer's customers with respect to this code.

   DISCLAIMER:

   Novell disclaims and excludes any and all express, implied, and 
   statutory warranties, including, without limitation, warranties 
   of good title, warranties against infringement, and the implied 
   warranties of merchantability and fitness for a particular purpose.  
   Novell does not warrant that the software will satisfy customer's 
   requirements or that the licensed works are without defect or error 
   or that the operation of the software will be uninterrupted.  
   Novell makes no warranties respecting any technical services or 
   support tools provided under the agreement, and disclaims all other 
   warranties, including the implied warranties of merchantability and 
   fitness for a particular purpose. */

/*********************************************************************
   RDATTDEF.C
**********************************************************************

   Description:

   This example reads the definition of an attribute taken from
   the command line.  The attribute definition is read using
   NWDSReadAttrDef.  Show how to set up an input buffer for a read
   attribute operation and how to use NWDSGetAttrCount and
   NWDSGetAttrDef to extract results from the output buffer.

   syntax: RDATTDEF <attribute name>

   This example requires a valid attribute name already
   defined in directory services.

********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <nwnet.h>
#include <nwcalls.h>
#include <nwlocale.h>

/* cleanup functions */
void FreeBufs(pBuf_T pIBuf,pBuf_T pOBuf, NWDSContextHandle context);
void FreeBuf(pBuf_T pBuf, NWDSContextHandle context);
void FreeContext(NWDSContextHandle context);     
void FreeUnicodeTables();                        

void main(int argc, char *argv[])
{
   NWDSContextHandle  context;
   nint32             lIterationHandle;
   pBuf_T             pInBuf;
   pBuf_T             pOutBuf;
   Attr_Info_T        attrInfo;
   NWDSCCODE          ccode;
   nuint32            luTotalAttr;
   nstr8              strAttrName[MAX_SCHEMA_NAME_CHARS];
   nuint              i;
   LCONV              lConvInfo;

   if(argc != 2)
   {
      printf("\nUsage   :  RDATTDEF  <attribute name>");
      printf("\nExample :  RDATTDEF   SURNAME");
      exit(1);
   }

   /*  Initialize NWCalls and unicode tables */
   ccode = NWCallsInit(NULL,NULL);
   if(ccode)
   {
      printf("\nNWCallsInit returned %X", ccode);
      exit(1);
   }

   NWLlocaleconv(&lConvInfo);

   ccode = NWInitUnicodeTables(lConvInfo.country_id,
                               lConvInfo.code_page);
   if(ccode)
   {
      printf("\nNWInitUnicodeTables returned %X", ccode);
      exit(1);
   }

   /* Create an NDS Context */
   ccode= NWDSCreateContextHandle(&context);
   if(ccode)
   {
      printf("\nNWDSCreateContextHandle failed");
      FreeUnicodeTables();
   }

   ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &pInBuf);
   if(ccode)
   {
      printf("\nNWDSAllocBuf returned %X", ccode);
      FreeContext(context);
   }

   ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &pOutBuf);
   if(ccode)
   {
      printf("\nNWDSAllocBuf returned %X", ccode);
      FreeBuf(pInBuf, context);
   }

   /* Initialize the input buffer for a read attribute definition
      operation as shown by the second argument. */
   ccode = NWDSInitBuf(context, DSV_READ_ATTR_DEF, pInBuf);
   if(ccode)
   {
      printf("\nNWDSInitBuf returned %X", ccode);
      FreeBufs(pInBuf, pOutBuf, context);
   }

   /* Put the name of the attribute we want to see (taken at the
      command line) into the input buffer */
   ccode = NWDSPutAttrName(context, pInBuf, argv[1]);
   if(ccode)
   {
      printf("\nNWDSPutAttrName returned %X", ccode);
      FreeBufs(pInBuf, pOutBuf, context);
   }

   lIterationHandle = NO_MORE_ITERATIONS;  /* set up read loop */

   /* Call NWDSReadAttrDef to read the definition for the
      attribute specified in the input buffer */
   ccode = NWDSReadAttrDef(context,
            DS_ATTR_DEFS,    /* infoType, attribute definitions    */
            FALSE,           /* allAttrs = false, passing in one   */
            pInBuf,          /* through this buffer (strAttrNames) */
            &lIterationHandle,
            pOutBuf);
   if(ccode)
   {
      printf("\nNWDSReadAttrDef returned %X", ccode);
      FreeBufs(pInBuf, pOutBuf, context);
   }

   /* Set luTotalAttr to number of attributes in buffer */
   ccode = NWDSGetAttrCount(context, pOutBuf, &luTotalAttr);
   if(ccode)
   {
      printf("\nNWDSGetAttrCount returned %X", ccode);
      FreeBufs(pInBuf, pOutBuf, context);
   }

   /* Loop for each attribute */
   for(i = 0; i < luTotalAttr; i++)
   {
      /* Get the definition from the buffer - set strAttrName to
         the name of the attribute definition, and attrInfo to the
         additional information about the attribute type */
      ccode =NWDSGetAttrDef(context, pOutBuf, strAttrName, &attrInfo);
      if(ccode)
      {
         printf("\nNWDSGetAttrCount returned %X", ccode);
         FreeBufs(pInBuf, pOutBuf, context);
      }
   }  /* end for loop */

   /*   Print the pAttr_Info_T structure (defined in nwdsbuft.h) */
   printf("\n%s Attribute", strAttrName);
   printf("\n-------------------------");
   printf("\nFlags:       0x%lx", attrInfo.attrFlags);
   printf("\nSyntax ID:   %ld",   attrInfo.attrSyntaxID);
   printf("\nLower limit: %ld",   attrInfo.attrLower);
   printf("\nUpper limit: %ld\n", attrInfo.attrUpper);

   /* Clean up, normal termination */
   NWDSFreeBuf(pInBuf);
   NWDSFreeBuf(pOutBuf);
   NWDSFreeContext(context);
   NWFreeUnicodeTables();

}

/* Clean up and exit, called on error condition only */
void FreeBufs(pBuf_T pIBuf, pBuf_T pOBuf, NWDSContextHandle context)
{
   NWDSFreeBuf(pIBuf);
   FreeBuf(pOBuf, context);
}

void FreeBuf(pBuf_T pBuf, NWDSContextHandle context)
{
   NWDSFreeBuf(pBuf);
   FreeContext(context);
}

void FreeContext(NWDSContextHandle context)
{
   NWDSFreeContext(context);
   FreeUnicodeTables();
}
void FreeUnicodeTables()
{
   NWFreeUnicodeTables();
   exit(1);
} 
