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

  %name: binderyJNI.c %
  %version: 7 %
  %date_modified: Thu Dec 18 12:06:57 1997 %

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

  THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL PROPRIETARY
  AND TRADE SECRET INFORMATION OF NOVELL, INC. ACCESS  TO  THIS  WORK IS
  RESTRICTED TO (I) NOVELL, INC.  EMPLOYEES WHO HAVE A NEED TO  KNOW HOW
  TO  PERFORM  TASKS WITHIN  THE SCOPE  OF  THEIR   ASSIGNMENTS AND (II)
  ENTITIES OTHER  THAN  NOVELL, INC.  WHO  HAVE ENTERED INTO APPROPRIATE
  LICENSE   AGREEMENTS.  NO  PART  OF  THIS WORK MAY BE USED, PRACTICED,
  PERFORMED COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED,  RECAST, TRANSFORMED
  OR ADAPTED  WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC.  ANY USE
  OR EXPLOITATION  OF  THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE
  PERPETRATOR  TO CRIMINAL AND CIVIL LIABILITY.

****************************************************************************/
#include <jni.h>
#include <sys_api.h>
#include <nwcalls.h>
#include "com_novell_service_jncpv2_cal_CalJNI.h"
#include <nwsync.h>
#include <nwapidef.h>
#include <nwbindry.h>
#include "JNIString.h"
#include "binderyJNI.h"

#ifdef N_PLAT_NLM
#include <nwthread.h>
#include <nwadv.h>
#endif


#define MAX_PASSWORD_LEN   129
#define MAX_BINDERY_OBJECT_NAME_LEN 49    // 48 chars + NULL


JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWAddObjectToSet
(   JNIEnv *env,
      jclass obj,
      jint     connHandle,
      jstring  objName,
      jint     objType,
      jstring  propertyName,
      jstring  memberName,
      jint     memberType
)
{
   NWCCODE ccode;
   nstr8 cObjectName[  MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName[MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cMemberName[  MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;
   punicode uniMemberName;

   // Convert Java variables into 'C' variable

   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);
   uniMemberName = (punicode) (*env)->GetStringChars(env,memberName,0);

   ccode = __UnicodeToLocalStr(
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr(
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr(
               cMemberName,
               sizeof(cMemberName),
               uniMemberName,
               (*env)->GetStringLength(env,memberName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWAddObjectToSet(
               connHandle,             //in
               cObjectName,            //in
               (nuint16)objType,       //in
               cPropertyName,          //in
               cMemberName,            //in
               (nuint16)memberType );  //in

EXIT:

   // Only you can help prevent memory leaks
   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);
   (*env)->ReleaseStringChars(env,memberName,uniMemberName);

   return(ccode);
}  // end AddObjectToSet()

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWChangeObjectSecurity
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jint     newObjSecurity
)
{
   NWCCODE ccode;
   nstr8 cObjectName[MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);

   ccode = __UnicodeToLocalStr(
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWChangeObjectSecurity (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,    //in
               (nuint8)newObjSecurity);     //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWChangePropertySecurity
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jstring  propertyName,
   jint     newPropertySecurity
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWChangePropertySecurity (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,    //in
               cPropertyName,       //in
               (nuint8)newPropertySecurity);   //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWCloseBindery
(
   JNIEnv *env,
   jclass obj,
   jint   connHandle
)
{
   return(NWCloseBindery((NWCONN_HANDLE) connHandle));
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWCreateObject
(
  JNIEnv    *env,
  jclass    obj,
  jint      connHandle,
  jstring   objName,
  jint      objType,
  jint      objFlags,
  jint      objSecurity
)
{
   NWCCODE ccode;
   nstr8 cObjectName[MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWCreateObject (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,             //in
               (nuint8)objFlags,            //in
               (nuint8)objSecurity);        //in

EXIT:

   // Only you can help prevent memory leaks
   (*env)->ReleaseStringChars(env,objName,uniObjectName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWCreateProperty
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,    //in
   jstring  objName,      //in
   jint     objType,       //in
   jstring  propertyName, //in
   jint     propertyFlags, //in
   jint     propertySecurity //in
)

{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWCreateProperty (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,             //in
               cPropertyName,       //in
               (nuint8)propertyFlags,       //in
               (nuint8)propertySecurity);   //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);

   return(ccode);
}


JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWDeleteObject
(
   JNIEnv   *env,
   jclass   javaObj,
   jint     connHandle,
   jstring  objName,
   jint     objType
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWDeleteObject (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType);            //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWDeleteObjectFromSet
(
  JNIEnv    *env,
  jclass    obj,
  jint      connHandle,
  jstring   objName,
  jint      objType,
  jstring   propertyName,
  jstring   memberName,
  jint      memberType
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cMemberName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;
   punicode uniMemberName;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);
   uniMemberName = (punicode) (*env)->GetStringChars(env,memberName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cMemberName,
               sizeof(cMemberName),
               uniMemberName,
               (*env)->GetStringLength(env,memberName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWDeleteObjectFromSet (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,             //in
               cPropertyName,       //in
               cMemberName,         //in
               (nuint16)memberType);         //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,memberName,uniPropertyName);
   (*env)->ReleaseStringChars(env,propertyName,uniMemberName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWDeleteProperty
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jstring  propertyName
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;

   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWDeleteProperty (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,             //in
               cPropertyName);      //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWDisallowObjectPassword
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jstring  disallowedPassword
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPassword [MAX_PASSWORD_LEN];
   punicode uniObjectName;
   punicode uniPassword;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPassword = (punicode) (*env)->GetStringChars(env,disallowedPassword,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPassword,
               sizeof(cPassword),
               uniPassword,
               (*env)->GetStringLength(env,disallowedPassword));
   if (ccode != 0)
      goto EXIT;

   ccode = NWDisallowObjectPassword (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,    //in
               cPassword);          //in

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,disallowedPassword,uniPassword);

   return((jint)ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetBinderyAccessLevel
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jobject  accessLevel,
   jobject  objID
)
{
   NWRCODE ccode;
   nuint8 buAccessLevel;
   nuint32 luObjID;

   ccode = NWGetBinderyAccessLevel (
               (NWCONN_HANDLE) connHandle,
               &buAccessLevel,
               &luObjID);

   if (ccode == 0)
   {
      jclass cls;
      jmethodID mid;

      if (accessLevel != NULL)
      {
         cls = (*env)->GetObjectClass(env, accessLevel);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, accessLevel, mid, (jint) buAccessLevel);
      }

      if (objID != NULL)
      {
         cls = (*env)->GetObjectClass(env, objID);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objID, mid, (jint) luObjID);
      }
   }

   return ((jint) ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectDiskSpaceLeft
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jint     objID,
   jobject  systemElapsedTime,
   jobject  unusedDiskBlocks,
   jobject  restrictionEnforced
)
{
   NWRCODE ccode;
   nuint32 luSysElapsedTime;
   nuint32 luUnusedDiskBlocks;
   nuint8 buRestrictionEnforced;

   ccode = NWGetObjectDiskSpaceLeft (
               (NWCONN_HANDLE) connHandle,
               (nuint32) objID,
               &luSysElapsedTime,
               &luUnusedDiskBlocks,
               &buRestrictionEnforced);

   if (0 == ccode)
   {  // Copy 'C' variable back into Java variable
      jclass cls;
      jmethodID mid;

      if (NULL != systemElapsedTime)
      {
         cls = (*env)->GetObjectClass(env, systemElapsedTime);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, systemElapsedTime, mid,
               (jint) luSysElapsedTime);
      }

      if (NULL != unusedDiskBlocks)
      {
         cls = (*env)->GetObjectClass(env, unusedDiskBlocks);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, unusedDiskBlocks, mid,
               (jint) luUnusedDiskBlocks);
      }

      if (NULL != restrictionEnforced)
      {
         cls = (*env)->GetObjectClass(env, restrictionEnforced);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, restrictionEnforced, mid,
               (jint) buRestrictionEnforced);
      }
   }

   return ((jint) ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectID
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle, //in
   jstring  objName,    //in
   jint     objType,    //in
   jobject  objID       //IntegerBuffer, out
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   nuint32 luObjectID;

   // Convert Java variable into 'C' variable
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWGetObjectID (
               connHandle,
               cObjectName,      // Use 'C' variable
               (nuint16) objType,
               &luObjectID);     // Save results in 'C' variable

   if (0 == ccode)
   {  // Copy 'C' variable back into Java variable
      jclass cls;
      jmethodID mid;

      cls = (*env)->GetObjectClass(env, objID);
      mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
      if (0 == mid)
         return(-1);
      (*env)->CallVoidMethod(env, objID, mid, (jint) luObjectID);
   }

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);

   return (ccode);
}  // NWGetObjectID ()

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectName
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,  //in
   jint     objID,       //in
   jobject  objName,     //out
   jobject  objType      //out
)
{
   NWCCODE ccode;
   nstr8 cObjName [NW_MAX_USER_NAME_LEN];
   nuint16 cObjType;

   ccode = NWGetObjectName (
                  (NWCONN_HANDLE) connHandle,
                  (nuint32) objID,
                  cObjName,
                  &cObjType);

   // Translate the object name and type back to Java before returning
   if (0 == ccode)
   {  // Need to reflect all of the C stuff to Java
      jstring javaString;
      jclass cls;
      jmethodID mid;

      if (NULL != objName)       // Copy back the object name into objName
      {
         unicode uniBuf[NW_MAX_USER_NAME_LEN];

         ccode = __LocalToJavaStr (
                     env,
                     &javaString,
                     uniBuf,
                     cObjName);
         if (ccode != 0)
            return ((jint) ccode);

         cls = (*env)->GetObjectClass(env, objName);
         mid = (*env)->GetMethodID(env, cls, "append","(Ljava/lang/String;)Ljava/lang/StringBuffer;");
         if (0 == mid)
            return(-1);
         (*env)->CallObjectMethod(env, objName, mid, javaString);
      }
      if (NULL != objType)       // Copy back the object type into objType
      {
         cls = (*env)->GetObjectClass(env, objType);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objType, mid, (jint) cObjType);
      }
   }

   return ((jint) ccode);
} /* ...NWGetObjectName () */

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWIsObjectInSet
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jstring  propertyName,
   jstring  memberName,
   jint     memberType
)
{
   NWCCODE ccode;
   nstr8 cObjectName[MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName[MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cMemberName[MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName;
   punicode uniPropertyName;
   punicode uniMemberName;

   // Convert Java variables into 'C' variable

   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);
   uniMemberName = (punicode) (*env)->GetStringChars(env,memberName,0);

   ccode = __UnicodeToLocalStr(
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr(
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr(
               cMemberName,
               sizeof(cMemberName),
               uniMemberName,
               (*env)->GetStringLength(env,memberName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWIsObjectInSet(
               connHandle,             //in
               cObjectName,            //in
               (nuint16)objType,       //in
               cPropertyName,          //in
               cMemberName,            //in
               (nuint16)memberType );  //in

EXIT:

   // Only you can help prevent memory leaks
   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);
   (*env)->ReleaseStringChars(env,memberName,uniMemberName);

   return(ccode);
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWOpenBindery
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle
)
{
   return(NWOpenBindery((NWCONN_HANDLE) connHandle));
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWReadPropertyValue
(
   JNIEnv      *env,
   jclass      obj,
   jint        connHandle,
   jstring     objName,
   jint        objType,
   jstring     propertyName,
   jint        segmentNum,
   jbyteArray  segmentData,   //out
   jobject     moreSegments,  //out
   jobject     flags          //out,optional
)
{
   NWRCODE ccode;
   nstr8 cObjectName[MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName[MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName, uniPropertyName;
   jbyte *body;
   nuint8 buMoreSegments;
   nuint8 buFlags;

   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   body = (*env)->GetByteArrayElements(env,segmentData,0);

   /* Just in case buMoreSegments isn't zeroed by the native when done,
    * make sure we sent it as zero.                                     ***/

   buMoreSegments = 0;

   ccode = NWReadPropertyValue (
               (NWCONN_HANDLE) connHandle, // in
               cObjectName,         // in
               (nuint16) objType,   // in
               cPropertyName,       // in
               (nuint8) segmentNum, // in
               (pnuint8) body,      // out s/b 128 bytes
               &buMoreSegments,     // out
               &buFlags);           // out

   // store the array back to Java by releasing it
   (*env)->ReleaseByteArrayElements(env,segmentData,body,0);

   if (0 == ccode)
   {
      jclass cls;
      jmethodID mid;

      cls = (*env)->GetObjectClass(env, moreSegments);
      mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
      if (0 == mid)
         return(-1);
      (*env)->CallVoidMethod(env, moreSegments, mid, (jint) buMoreSegments);

      if (flags != NULL)
      {
         cls = (*env)->GetObjectClass(env, flags);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, flags, mid, (jint) buFlags);
      }
   }

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);

   return(ccode);
}  // end ReadPropertyValue


JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWRenameObject
(
   JNIEnv      *env,
   jclass      obj,
   jint        connHandle,
   jstring     oldObjName,
   jstring     newObjName,
   jint        objType
)
{
   NWCCODE ccode;
   nstr8 cOldObjName[MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cNewObjName[MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniOldObjName, uniNewObjName;

   // Convert Java variable into 'C' variable
   uniOldObjName = (punicode) (*env)->GetStringChars(env,oldObjName,0);
   uniNewObjName = (punicode) (*env)->GetStringChars(env,newObjName,0);

   ccode = __UnicodeToLocalStr (
               cOldObjName,
               sizeof(cOldObjName),
               uniOldObjName,
               (*env)->GetStringLength(env,oldObjName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cNewObjName,
               sizeof(cNewObjName),
               uniNewObjName,
               (*env)->GetStringLength(env,newObjName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWRenameObject (
               (NWCONN_HANDLE) connHandle,   //in
               cOldObjName,         //in
               cNewObjName,         //in
               (nuint16) objType);  //in

EXIT:

   (*env)->ReleaseStringChars(env,oldObjName,uniOldObjName);
   (*env)->ReleaseStringChars(env,newObjName,uniNewObjName);

   return(ccode);
}

/* The following 3 NWGetObjectNames* functions must be called via a function
*  pointer on the NLM platform, so we can link with old NLM's
*/
#ifdef N_PLAT_NLM
SLPFunctionTable funcTable;
int useSLPCalls = 0;
char *symbols[3] = { "NWGetObjectNamesBeginA",
                     "NWGetObjectNamesNextA",
                     "NWGetObjectNamesEndA" };

void __InitSLPCalls(void)
{
   nint32 NLMHandle = GetNLMHandle();

   funcTable.begin = (NWGetObjectNamesBeginA_fp)ImportSymbol(NLMHandle, symbols[0]);
   funcTable.next = (NWGetObjectNamesNextA_fp)ImportSymbol(NLMHandle, symbols[1]);
   funcTable.end = (NWGetObjectNamesEndA_fp)ImportSymbol(NLMHandle, symbols[2]);
   if(funcTable.begin == NULL || funcTable.next == NULL || funcTable.end == NULL)
      useSLPCalls = 0;
   else
      useSLPCalls = 1;
}

void __CleanupSLPCalls(void)
{
   nint32 NLMHandle = GetNLMHandle();
   if(funcTable.begin != NULL)
      UnimportSymbol(NLMHandle, symbols[0]);
   if(funcTable.next != NULL)
      UnimportSymbol(NLMHandle, symbols[1]);
   if(funcTable.end != NULL)
      UnimportSymbol(NLMHandle, symbols[2]);
}
#endif

JNIEXPORT jboolean JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_areSLPCallsAvailable
(
   JNIEnv *env,
   jclass obj
)
{
   #ifdef N_PLAT_NLM
   return useSLPCalls;
   #else
   return 1;
   #endif
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectNamesBeginA
(
	JNIEnv  *env,
	jclass  obj,
	jint    type,
	jobject handle
)
{
   jclass cls;
   jmethodID mid;
   NWCCODE ccode;
   nuint32 cHandle;

   #ifdef N_PLAT_NLM
   ccode = funcTable.begin(type, &cHandle);
   #else
   ccode = NWGetObjectNamesBeginA(type, &cHandle);
   #endif

   if(ccode == 0)
   {
     cls = (*env)->GetObjectClass(env, handle);
     mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
     if (0 == mid)
        return(-1);
     (*env)->CallVoidMethod(env, handle, mid, (jint)cHandle);
   }
   return ccode;
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectNamesNextA
(
   JNIEnv   *env,
   jclass   obj,
   jobject  handle,
   jobject  bufLen,
   jobject  buffer
)
{
   jclass cls;
   jmethodID mid;
   NWCCODE ccode;
   nuint32 cHandle, cBufLen;
   pnstr buf = NULL;

   cls = (*env)->GetObjectClass(env, handle);
   mid = (*env)->GetMethodID(env, cls, "intValue","()I");
   if (0 == mid)
      return(-1);
   cHandle = (nuint32) (*env)->CallIntMethod(env, handle, mid);

   cls = (*env)->GetObjectClass(env, bufLen);
   mid = (*env)->GetMethodID(env, cls, "intValue","()I");
   if (0 == mid)
      return(-1);
   cBufLen = (nuint32) (*env)->CallIntMethod(env, bufLen, mid);
   buf = sysMalloc(cBufLen);

   #ifdef N_PLAT_NLM
   ccode = funcTable.next(cHandle, &cBufLen, buf);
   #else
   ccode = NWGetObjectNamesNextA(cHandle, &cBufLen, buf);
   #endif

   if(ccode == NWE_BUFFER_OVERFLOW)
   {
      cls = (*env)->GetObjectClass(env, bufLen);
      mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
      if(0 == mid)
      {  ccode=-1; goto EXIT; }
      (*env)->CallVoidMethod(env, bufLen, mid, (jint)cBufLen);
   }
   else if(ccode == 0)
   {
      jstring objName = (*env)->NewStringUTF(env, buf);
      cls = (*env)->GetObjectClass(env, buffer);
      mid = (*env)->GetMethodID(env, cls, "setLength", "(I)V");
      if(0 == mid)
      {  ccode=-1; goto EXIT; }
      (*env)->CallVoidMethod(env, buffer, mid, 0);

      mid = (*env)->GetMethodID(env, cls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
      if(0 == mid)
      {  ccode=-1; goto EXIT; }
      (*env)->CallObjectMethod(env, buffer, mid, objName);
   }

   EXIT:
   if(buf)
      sysFree(buf);
   return ccode;
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWGetObjectNamesEndA
(
   JNIEnv   *env,
   jclass   obj,
   jobject  handle
)
{
   jclass cls;
   jmethodID mid;
   nuint32 cHandle;

   cls = (*env)->GetObjectClass(env, handle);
   mid = (*env)->GetMethodID(env, cls, "intValue","()I");
   if (0 == mid)
      return(-1);
   cHandle = (nuint32) (*env)->CallIntMethod(env, handle, mid);

   #ifdef N_PLAT_NLM
   return funcTable.end(cHandle);
   #else
   return NWGetObjectNamesEndA(cHandle);
   #endif
}

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWScanObject
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,        // in
   jstring  searchName,        // in
   jint     searchType,        // in
   jobject  objID,             // out, optional, IntegerBuffer
   jobject  objName,           // out, optional, StringBuffer
   jobject  objType,           // out, optional, IntegerBuffer
   jobject  hasPropertiesFlag, // out, optional, IntegerBuffer
   jobject  objFlags,          // out, optional, IntegerBuffer
   jobject  objSecurity        // out, optional, IntegerBuffer
)
{
   NWCCODE ccode;
   nstr8   cSearchName [MAX_BINDERY_OBJECT_NAME_LEN];
   nuint32 cObjectID;
   nstr8   cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nuint16 cObjectType;
   nuint8  cHasPropertiesFlag;
   nuint8  cObjectFlags;
   nuint8  cObjectSecurity;
   punicode uniSearchName;
   jclass      cls;
   jmethodID   mid;

   if (NULL != objID)
   {
      cls = (*env)->GetObjectClass(env, objID);
      mid = (*env)->GetMethodID(env, cls, "intValue","()I");
      if (0 == mid)
         return(-1);
      cObjectID = (nuint32) (*env)->CallIntMethod(env, objID, mid);
   }
   else
      cObjectID = (nuint32) -1;

   uniSearchName = (punicode) (*env)->GetStringChars(env,searchName,0);

   ccode = __UnicodeToLocalStr (
               cSearchName,
               sizeof(cSearchName),
               uniSearchName,
               (*env)->GetStringLength(env,searchName));
   if (ccode != 0)
      goto EXIT;

   ccode = NWScanObject (
               (NWCONN_HANDLE) connHandle,
               cSearchName,         // Use 'C' variable
               (nuint16) searchType,
               &cObjectID,          // Save results in 'C' variable
               cObjectName,         // Save results in 'C' variable
               &cObjectType,        // Save results in 'C' variable
               &cHasPropertiesFlag, // Save results in 'C' variable
               &cObjectFlags,       // Save results in 'C' variable
               &cObjectSecurity);   // Save results in 'C' variable

   if (0 == ccode)
   {  // Need to convert 'C' variables back into Java variables
      if (NULL != objID)
      {
         cls = (*env)->GetObjectClass(env, objID);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objID, mid, (jint) cObjectID);
      }

      if (NULL != objName)
      {
         jstring jObjName;
         unicode uniBuf[sizeof(cObjectName)];

         ccode = __LocalToJavaStr (
                     env,
                     &jObjName,
                     uniBuf,
                     cObjectName);
         if (ccode != 0)
            goto EXIT;

         cls = (*env)->GetObjectClass(env, objName);
         mid = (*env)->GetMethodID(env, cls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
         if (0 == mid)
            return(-1);
         (*env)->CallObjectMethod(env, objName, mid, jObjName);
      }

      if (NULL != objType)
      {
         cls = (*env)->GetObjectClass(env, objType);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objType, mid, (jint) cObjectType);
      }

      if (NULL != hasPropertiesFlag)
      {
         cls = (*env)->GetObjectClass(env, hasPropertiesFlag);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, hasPropertiesFlag, mid, (jint) cHasPropertiesFlag);
      }

      if (NULL != objFlags)
      {
         cls = (*env)->GetObjectClass(env, objFlags);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objFlags, mid, (jint) cObjectFlags);
      }

      if (NULL != objSecurity)
      {
         cls = (*env)->GetObjectClass(env, objSecurity);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, objSecurity, mid, (jint) cObjectSecurity);
      }
   }

EXIT:

   (*env)->ReleaseStringChars(env,searchName,uniSearchName);

   return ((jint) ccode);
} // NWScanObject ()

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWScanProperty
(
   JNIEnv   *env,
   jclass   obj,
   jint     connHandle,
   jstring  objName,
   jint     objType,
   jstring  searchPropertyName,
   jobject  iterHandle,          // out, IntegerBuffer
   jobject  propertyName,        // out, StringBuffer
   jobject  propertyFlags,       // out, IntegerBuffer
   jobject  propertySecurity,    // out, IntegerBuffer
   jobject  valueAvailable,      // out, IntegerBuffer
   jobject  moreFlag             // out, IntegerBuffer
)
{
   NWRCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cSearchPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName, uniSearchPropertyName;
   nuint32 cIterHandle;
   nuint8 cPropertyFlags;
   nuint8 cPropertySecurity;
   nuint8 cValueAvailable;
   nuint8 cMoreFlag;
   jclass      cls;
   jmethodID   mid;

   //convert java objName to C cObjName (strings)
   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniSearchPropertyName = (punicode) (*env)->GetStringChars(env,
         searchPropertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cSearchPropertyName,
               sizeof(cSearchPropertyName),
               uniSearchPropertyName,
               (*env)->GetStringLength(env,searchPropertyName));
   if (ccode != 0)
      goto EXIT;

   if (NULL != iterHandle)
   {
      cls = (*env)->GetObjectClass(env, iterHandle);
      mid = (*env)->GetMethodID(env, cls, "intValue", "()I");
      if (0 == mid)
         return(-1);
      cIterHandle = (nuint32) (*env)->CallIntMethod(env, iterHandle, mid);
   }
   else
      cIterHandle = (nuint32) -1;

   /* Just in case cMoreFlag isn't zeroed by the native when done (which we
    * know from experience can happen) make sure we sent it as zero.    ***/

   cMoreFlag = 0;

   ccode = NWScanProperty (
               connHandle,             // in
               cObjectName,            // in
               (nuint16) objType,      // in
               cSearchPropertyName,    // in
               &cIterHandle,           // in/out
               cPropertyName,          // out
               &cPropertyFlags,        // out
               &cPropertySecurity,     // out
               &cValueAvailable,       // out
               &cMoreFlag);            // out

   /* Because ScanProp doesn't set the moreFlag to 0 until you scan PAST the
    * last property, and because it will also set the ccode to non-0 on that
    * call, you need to move the moreFlag into the java variable every time. */

   cls = (*env)->GetObjectClass(env, moreFlag);
   mid = (*env)->GetMethodID(env, cls, "setValue", "(I)V");
   if (0 == mid)
      return(-1);
   (*env)->CallVoidMethod(env, moreFlag, mid, (jint) cMoreFlag);

   if (0 == ccode)
   {
      if (iterHandle != NULL)
      {
         cls = (*env)->GetObjectClass(env, iterHandle);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, iterHandle, mid, (jint) cIterHandle);
      }

      if (propertyName != NULL)
      {
         unicode uniBuf[sizeof(cPropertyName)];
         jstring jPropertyName;

         ccode = __LocalToJavaStr (
                     env,
                     &jPropertyName,
                     uniBuf,
                     cPropertyName);
         if (ccode != 0)
            goto EXIT;

         cls = (*env)->GetObjectClass(env, propertyName);
         mid = (*env)->GetMethodID(env, cls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
         if (0 == mid)
            return(-1);
         (*env)->CallObjectMethod(env, propertyName, mid, jPropertyName);
      }

      if (propertyFlags != NULL)
      {
         cls = (*env)->GetObjectClass(env, propertyFlags);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, propertyFlags, mid, (jint) cPropertyFlags);
      }

      if (propertySecurity != NULL)
      {
         cls = (*env)->GetObjectClass(env, propertySecurity);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, propertySecurity, mid, (jint) cPropertySecurity);
      }

      if (valueAvailable != NULL)
      {
         cls = (*env)->GetObjectClass(env, valueAvailable);
         mid = (*env)->GetMethodID(env, cls, "setValue","(I)V");
         if (0 == mid)
            return(-1);
         (*env)->CallVoidMethod(env, valueAvailable, mid, (jint) cValueAvailable);
      }
   }

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,searchPropertyName,uniSearchPropertyName);

   return(ccode);
}  // end ScanProperty

JNIEXPORT jint JNICALL
Java_com_novell_service_jncpv2_cal_CalJNI_NWWritePropertyValue
(
   JNIEnv      *env,
   jclass      obj,
   jint        connHandle,
   jstring     objName,      // in
   jint        objType,      // in
   jstring     propertyName, // in
   jint        segmentNum,   // in
   jbyteArray  segmentData,  // in
   jboolean    moreSegments  // in
)
{
   NWCCODE ccode;
   nstr8 cObjectName [MAX_BINDERY_OBJECT_NAME_LEN];
   nstr8 cPropertyName [MAX_BINDERY_OBJECT_NAME_LEN];
   punicode uniObjectName, uniPropertyName;
   nuint8 cMoreSegments;
   jbyte *body;

   uniObjectName = (punicode) (*env)->GetStringChars(env,objName,0);
   uniPropertyName = (punicode) (*env)->GetStringChars(env,propertyName,0);

   ccode = __UnicodeToLocalStr (
               cObjectName,
               sizeof(cObjectName),
               uniObjectName,
               (*env)->GetStringLength(env,objName));
   if (ccode != 0)
      goto EXIT;

   ccode = __UnicodeToLocalStr (
               cPropertyName,
               sizeof(cPropertyName),
               uniPropertyName,
               (*env)->GetStringLength(env,propertyName));
   if (ccode != 0)
      goto EXIT;

   body = (*env)->GetByteArrayElements(env,segmentData,0);

   if (moreSegments != 0)
      cMoreSegments = 0xFF;
   else
      cMoreSegments = 0;

   ccode = NWWritePropertyValue (
               connHandle,          //in
               cObjectName,         //in
               (nuint16)objType,    //in
               cPropertyName,       //in
               (nuint8)segmentNum,  //in
               (pnuint8)body,       //in s/b 128 bytes of byte
               cMoreSegments);      //in

   (*env)->ReleaseByteArrayElements(env,segmentData,body,0);

EXIT:

   (*env)->ReleaseStringChars(env,objName,uniObjectName);
   (*env)->ReleaseStringChars(env,propertyName,uniPropertyName);

   return(ccode);
}
