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

   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. */

/*********************************************************************
   NDSBROWS.C
**********************************************************************

   Description:

   Take a name context (either from command line or default)
   and use NWDSList to return a list of subordinates below it.
   NWDSGetObjectCount and NWDSGetObjectName are used to extract
   the results from the output buffer.

   Syntax: NDSBROWS [ name context ]

   List of objects subordinate to default name context or the
   name context entered on the command line

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

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

/* cleanup functions and globals */
void   FreeContext(NWDSContextHandle context);      
void   FreeUnicodeTables();
nbool8 bbDoLogout = N_FALSE;

void main(int argc, char *argv[])
{
   NWDSContextHandle   context;
   nint32              lIterationHandle = NO_MORE_ITERATIONS;
   Object_Info_T       objectInfo;
   pBuf_T              pBuf;
   NWDSCCODE           ccode;
   nuint32             luObjectCount, luAttrCount;
   nstr8               strObjectName[MAX_DN_CHARS+1];
   nstr8               strContext[MAX_DN_CHARS+1];
   nstr8               strUserName[NW_MAX_USER_NAME_LEN];
   nstr8               strUserPassword[50];
   nuint               i;
   LCONV               lConvInfo;

   /* 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 NDS Context */
   context = NWDSCreateContext();
   if(context == (NWDSContextHandle)ERR_CONTEXT_CREATION)
   {
      printf("\nNWDSCreateContext failed.");
      FreeUnicodeTables();
   }

   /*  Must authenticate if not already authenticated to NDS
       (which will always be the case if this example is 
       compiled and run as an NLM). */
   if(!NWIsDSAuthenticated())
   {
      printf("\nMust authenticate to NDS");
      printf("\nEnter User Name: ");
      gets(strUserName);
      printf("Enter User Password: ");
      gets(strUserPassword);

      ccode = NWDSLogin(context, 0, strUserName, strUserPassword, 0);
      if(ccode)
      {
         printf("\nNWDSLogin returned %i", ccode);
         FreeUnicodeTables();
      }
      else
      {  /* If example logs in, it will also log out */
         bbDoLogout = N_TRUE;
      }
   }

   /* Check user input */
   if(2 == argc)
   {
      /* If entered, set context from the command line */
      ccode = NWDSSetContext(context, DCK_NAME_CONTEXT, argv[1]);
      if(ccode < 0)  /* if negative, NWDSSetContext was unsuccessful*/
      {
         printf("\nNWDSSetContext returned %X", ccode);
         FreeContext(context);
      }
   }

   /* Read back and print the context.  It should either be the
      default context or the context entered at the command line. */
   ccode = NWDSGetContext(context, DCK_NAME_CONTEXT, strContext);
   if(ccode)
   {
      printf("\nNWDSGetContext returned %X");
      FreeContext(context);
   }
   else
      printf("\nNDS Context:  %s", strContext);

   /*  Allocate space for the output buffer to hold the information */
   ccode = NWDSAllocBuf((size_t)DEFAULT_MESSAGE_LEN, &pBuf);
   if(ccode)
   {
      printf("\nNWDSAllocBuf returned %X", ccode);
      FreeContext(context);
   }

   /*  Loop while there are iterations */
   do
   {
      ccode = NWDSList(context, "", &lIterationHandle, pBuf);
      if(ccode)
      {
         printf("\nNWDSList returned %X - object not found", ccode);
         break;
      }

      /* Determine the number of subordinate objects contained in the
         result buffer */
      ccode = NWDSGetObjectCount(context, pBuf, &luObjectCount);
      if (ccode)
         break;
      printf("\nObjects found under \"%s\":\n", strContext);

      /*   loop while there are objects in buffer */
      for(i = 0; i < luObjectCount; i++)
      {
         /* Get the objectName whose information is at the current
            position in the output buffer */
         ccode = NWDSGetObjectName(context, pBuf, strObjectName,
                                   &luAttrCount, &objectInfo);
         if (ccode)
         {
            printf("\nNWDSGetObjectName returned %X", ccode);
            break;
         }

         /* Print out the object's name */
         printf("\n%d. %s", (i + 1), strObjectName);
      }

   /* if there's more data to retrieve, loop back */
   } while(lIterationHandle != NO_MORE_ITERATIONS);

   /* Clean up, normal termination */
   NWDSFreeBuf(pBuf);
   if(bbDoLogout)
      NWDSLogout(context);
   NWDSFreeContext(context);
   NWFreeUnicodeTables();
}

/* Clean up and exit, called on error condition only */
void FreeContext(NWDSContextHandle context)
{
   if(bbDoLogout)
      NWDSLogout(context);
   NWDSFreeContext(context);
   FreeUnicodeTables();
}

void FreeUnicodeTables()
{
   NWFreeUnicodeTables();
   exit(1);
}  
