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

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

/*********************************************************************
   CRCLSDEF.C
**********************************************************************

   Description:

   This example uses NWDSDefineClass to create a new class
   definition,"International Person" with super class of "Person"
   and indicates the class to be an effective class.  The class
   has one optional attribute, "language".

   The input buffer is initialized for a define class operation.
   Class definitions are added to the buffer in this order -

      super classes,
      containment classes,
      naming attributes,
      mandatory attributes,
      optional attributes.

   This example requires that you authenticate to NDS with the
   necessary rights to add class definitions (if you haven't
   authenticated to NDS before running the example, the program
   will prompt for user input and perform the authentication).

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  /* memset() */
#include <nwcalls.h>
#include <nwnet.h>
#include <nwlocale.h>

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

void main(void)
{
   NWDSContextHandle   context;
   Class_Info_T        ClassInfo;
   pBuf_T              pClassBuf;
   NWDSCCODE           ccode;
   nstr8               strUserName[NW_MAX_USER_NAME_LEN];
   nstr8               strUserPassword[50];
   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 error %X \n", ccode);
      exit(1);
   }

   /* Create an NDS Context */
   ccode = NWDSCreateContextHandle(&context);
   if(ccode)
   {
      printf("\nNWDSCreateContextHandle 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).  Creating an NDS object
       requires SUPERVISOR rights. */
   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 %X", ccode);
         FreeContext(context);
      }
      else
      {  /* If example logs in, it will also log out */
         bbDoLogout = N_TRUE;
      }
   }

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

   /* Initialize the buffer for a define class operation */
   ccode = NWDSInitBuf(context, DSV_DEFINE_CLASS, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSInitBuf returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Set the Class_Info_T structure to be an effective class and
      set the asn1ID structure according to the rules specified in
      the asn.1 standard */

   ClassInfo.classFlags    = DS_EFFECTIVE_CLASS;
   ClassInfo.asn1ID.length = 8;
   memset(ClassInfo.asn1ID.data, 0x00, 8);

   /* Add class definitions to the input buffer by repeatedly
      calling NWDSBeginClassItem followed by NWDSPutClassItem
      (if one is being defined).  Define the super class =
      Organizational Person. */
   ccode = NWDSBeginClassItem(context, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSBeginClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   ccode = NWDSPutClassItem(context, pClassBuf,
                            "Organizational Person");
   if(ccode)
   {
      printf("\nNWDSPutClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Define no new containment classes */
   ccode = NWDSBeginClassItem(context, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSBeginClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Define no new naming attributes */
   ccode = NWDSBeginClassItem(context, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSBeginClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Define no new mandatory attributes */
   ccode = NWDSBeginClassItem(context, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSBeginClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Define optional attributes = Language */
   ccode = NWDSBeginClassItem(context, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSBeginClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   ccode = NWDSPutClassItem(context, pClassBuf, "Language");
   if(ccode)
   {
      printf("\nNWDSPutClassItem returned %X", ccode);
      FreeBuf(pClassBuf, context);
   }

   /* Create the definition */
   ccode = NWDSDefineClass(context, "International Person",
                           &ClassInfo, pClassBuf);
   if(ccode)
   {
      printf("\nNWDSDefineClass returned %X", ccode);
      printf("\nError defining new class");
      FreeBuf(pClassBuf, context);
   }
   else
      printf("\nClass \"International Person\" added to schema");

   /* Now remove the class so as not to leave the schema
      permanently modified */
   ccode = NWDSRemoveClassDef(context, "International Person");
   if(ccode)
      printf("\nNWDSRemoveClassDef returned %X", ccode);
   else
      printf("\nClass \"International Person\" removed from schema");

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

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

void FreeContext(NWDSContextHandle context)
{
   if(bbDoLogout)
      NWDSLogout(context);
   NWDSFreeContext(context);
   FreeUnicodeTables();
}

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