Files
ncpfs/lib/ds/classes.c
ncpfs archive import b34e88bda5 Import ncpfs 2.2.6
2026-04-28 20:40:00 +02:00

825 lines
20 KiB
C

/*
classes.c
Copyright (C) 2000 Petr Vandrovec
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Revision history:
1.00 2000, May 4 Petr Vandrovec <vandrove@vc.cvut.cz>
Initial version.
1.01 2000, May 6 Petr Vandrovec <vandrove@vc.cvut.cz>
Added NWDSGetClassItem, NWDSGetClassItemCount.
1.02 2000, May 7 Petr Vandrovec <vandrove@vc.cvut.cz>
Added NWDSBeginClassItem, NWDSDefineClass, NWDSPutClassItem,
NWDSRemoveClassDef, NWDSListContainableClasses,
NWDSModifyClassDef, NWDSReadAttrDef, NWDSGetAttrDef,
NWDSDefineAttr, NWDSRemoveAttrDef.
*/
#include <ncp/nwcalls.h>
#include "nwnet_i.h"
#include <string.h>
#define CLASSDEF_ASN 0x0001
#define CLASSDEF_TIMES 0x0002
#define CLASSDEF_ITEMS 0x0004
static NWDSCCODE __NWDSReadClassDefV0(
NWCONN_HANDLE conn,
nuint infoType,
nuint allClasses,
Buf_T* classNames,
nuint32* iterHandle,
Buf_T* classDefs
) {
static const nuint infoType2cmd[] = {
0,
CLASSDEF_ASN | CLASSDEF_ITEMS,
CLASSDEF_ASN | CLASSDEF_ITEMS,
CLASSDEF_ASN,
CLASSDEF_ASN | CLASSDEF_ITEMS,
CLASSDEF_ASN | CLASSDEF_TIMES | CLASSDEF_ITEMS
};
NW_FRAGMENT rq_frag[2];
NW_FRAGMENT rp_frag[2];
nuint8 rq_b[20];
nuint8 rp_b[8];
NWDSCCODE dserr;
size_t rq_frags;
if (!classDefs)
return ERR_NULL_POINTER;
DSET_LH(rq_b, 0, 0);
DSET_LH(rq_b, 4, *iterHandle);
DSET_LH(rq_b, 8, infoType);
DSET_LH(rq_b, 12, allClasses);
if (allClasses || !classNames) {
DSET_LH(rq_b, 16, 0);
rq_frag[0].fragSize = 20;
rq_frags = 1;
} else {
if (classNames->operation != DSV_READ_CLASS_DEF)
return ERR_BAD_VERB;
rq_frag[0].fragSize = 16;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(classNames, &rq_frag[1].fragSize);
rq_frags = 2;
}
rq_frag[0].fragAddr.ro = rq_b;
NWDSBufStartPut(classDefs, DSV_READ_CLASS_DEF);
if (infoType > 5)
infoType = 1;
classDefs->cmdFlags = infoType2cmd[infoType];
rp_frag[0].fragAddr.rw = rp_b;
rp_frag[0].fragSize = 8;
rp_frag[1].fragAddr.rw = NWDSBufPutPtrLen(classDefs, &rp_frag[1].fragSize);
dserr = NWCFragmentRequest(conn, DSV_READ_CLASS_DEF, rq_frags, rq_frag,
2, rp_frag, NULL);
if (dserr)
return dserr;
if (rp_frag[1].fragSize < 4)
return ERR_INVALID_SERVER_RESPONSE;
if (DVAL_LH(rp_b, 4) != infoType) {
/* FIXME: __NWDSCloseIterationHandle(conn, DVAL_LH(rp_b, 0), DSV_READ_CLASS_DEF); */
return ERR_INVALID_SERVER_RESPONSE;
}
*iterHandle = DVAL_LH(rp_b, 0);
NWDSBufPutSkip(classDefs, rp_frag[1].fragSize);
NWDSBufFinishPut(classDefs);
return 0;
}
NWDSCCODE NWDSReadClassDef(
NWDSContextHandle ctx,
nuint infoType,
nuint allClasses,
Buf_T* classNames,
nuint32* iterHandle,
Buf_T* classDefs
) {
NWCONN_HANDLE conn;
nuint32 lh;
NWDSCCODE dserr;
struct wrappedIterationHandle* ih;
if (*iterHandle == NO_MORE_ITERATIONS) {
dserr = __NWDSGetConnection(ctx, &conn);
if (dserr)
return dserr;
ih = NULL;
lh = NO_MORE_ITERATIONS;
} else {
ih = __NWDSIHLookup(*iterHandle, DSV_READ_CLASS_DEF);
if (!ih)
return ERR_INVALID_HANDLE;
conn = ih->conn;
lh = ih->iterHandle;
}
dserr = __NWDSReadClassDefV0(conn, infoType, allClasses, classNames, &lh, classDefs);
if (ih)
return __NWDSIHUpdate(ih, dserr, lh, iterHandle);
return __NWDSIHCreate(dserr, conn, 0, lh, DSV_READ_CLASS_DEF, iterHandle);
}
NWDSCCODE NWDSGetClassDefCount(
UNUSED( NWDSContextHandle ctx),
Buf_T* buf,
NWObjectCount* classDefCount
) {
NWDSCCODE dserr;
nuint32 tmp;
if (!buf)
return ERR_NULL_POINTER;
if (buf->bufFlags & NWDSBUFT_INPUT)
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_READ_CLASS_DEF:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (classDefCount)
*classDefCount = tmp;
return 0;
}
NWDSCCODE NWDSGetClassDef(
NWDSContextHandle ctx,
Buf_T* buf,
NWDSChar* className,
Class_Info_T* classInfo
) {
NWDSCCODE dserr;
nuint32 tmp;
if (!buf)
return ERR_NULL_POINTER;
if (buf->bufFlags & NWDSBUFT_INPUT)
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_READ_CLASS_DEF:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSBufCtxString(ctx, buf, className, MAX_SCHEMA_NAME_BYTES, NULL);
if (dserr)
return dserr;
if (buf->cmdFlags & CLASSDEF_ASN) {
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (classInfo) {
classInfo->classFlags = tmp;
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
classInfo->asn1ID.length = tmp;
if (tmp > MAX_ASN1_NAME)
return NWE_BUFFER_OVERFLOW;
dserr = NWDSBufGet(buf, classInfo->asn1ID.data, tmp);
} else {
dserr = NWDSBufSkipBuffer(buf);
}
if (dserr)
return dserr;
}
return dserr;
}
NWDSCCODE NWDSGetClassItemCount(
UNUSED( NWDSContextHandle ctx),
Buf_T* buf,
NWObjectCount* itemCount
) {
NWDSCCODE dserr;
nuint32 tmp;
if (!buf)
return ERR_NULL_POINTER;
if (buf->bufFlags & NWDSBUFT_INPUT)
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_READ_CLASS_DEF:
case DSV_LIST_CONTAINABLE_CLASSES:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (itemCount)
*itemCount = tmp;
return 0;
}
NWDSCCODE NWDSGetClassItem(
NWDSContextHandle ctx,
Buf_T* buf,
NWDSChar* item
) {
NWDSCCODE dserr;
if (!buf)
return ERR_NULL_POINTER;
if (buf->bufFlags & NWDSBUFT_INPUT)
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_READ_CLASS_DEF:
case DSV_LIST_CONTAINABLE_CLASSES:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSBufCtxString(ctx, buf, item, MAX_SCHEMA_NAME_BYTES, NULL);
if (dserr)
return dserr;
return 0;
}
NWDSCCODE NWDSPutClassItem(
NWDSContextHandle ctx,
Buf_T* buf,
const NWDSChar* item
) {
NWDSCCODE dserr;
if (!buf)
return ERR_NULL_POINTER;
if (!(buf->bufFlags & NWDSBUFT_INPUT))
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_DEFINE_CLASS:
if (!buf->attrCountPtr)
return ERR_BAD_VERB;
break;
/* DSV_READ_ATTR_DEF should not be there... NWDSPutAttrName
should be used with NWDSReadAttrDef */
case DSV_READ_ATTR_DEF:
case DSV_READ_CLASS_DEF:
case DSV_MODIFY_CLASS_DEF:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSCtxBufString(ctx, buf, item);
if (dserr)
return dserr;
DSET_LH(buf->attrCountPtr, 0, DVAL_LH(buf->attrCountPtr, 0) + 1);
return 0;
}
NWDSCCODE NWDSBeginClassItem(
UNUSED( NWDSContextHandle ctx),
Buf_T* buf
) {
NWDSCCODE dserr;
nuint8* p;
if (!buf)
return ERR_NULL_POINTER;
if (!(buf->bufFlags & NWDSBUFT_INPUT))
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_DEFINE_CLASS:
break;
default:
return ERR_BAD_VERB;
}
p = buf->curPos;
dserr = NWDSBufPutLE32(buf, 0);
if (dserr)
return dserr;
buf->attrCountPtr = p;
return 0;
}
static inline NWDSCCODE __NWDSFindSchemaServer(
NWDSContextHandle ctx,
NWCONN_HANDLE* conn
) {
NWObjectID id;
return __NWDSResolveName2w(ctx, L"[Root]",
DS_RESOLVE_WRITEABLE | DS_RESOLVE_V0, conn, &id);
}
static NWDSCCODE __NWDSDefineClassV0(
NWCONN_HANDLE conn,
const Class_Info_T* classInfo,
Buf_T* className,
Buf_T* classItems
) {
NW_FRAGMENT rq_frag[4];
nuint8 rq_b[8];
nuint8 rq_b2[4 + MAX_ASN1_NAME];
size_t asnlen;
size_t asnlen2;
if (!classInfo || !classItems)
return ERR_NULL_POINTER;
asnlen = classInfo->asn1ID.length;
if (asnlen > MAX_ASN1_NAME)
return NWE_BUFFER_OVERFLOW;
DSET_LH(rq_b, 0, 0); /* version */
DSET_LH(rq_b, 4, classInfo->classFlags);
DSET_LH(rq_b2, 0, asnlen);
memcpy(rq_b2 + 4, classInfo->asn1ID.data, asnlen);
asnlen2 = ROUNDPKT(asnlen);
if (asnlen2 > asnlen)
memset(rq_b2 + 4 + asnlen, 0, asnlen2 - asnlen);
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 8;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(className, &rq_frag[1].fragSize);
rq_frag[2].fragAddr.ro = rq_b2;
rq_frag[2].fragSize = 4 + asnlen2;
rq_frag[3].fragAddr.ro = NWDSBufRetrieve(classItems, &rq_frag[3].fragSize);
return NWCFragmentRequest(conn, DSV_DEFINE_CLASS, 4, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSDefineClass(
NWDSContextHandle ctx,
const NWDSChar* className,
const Class_Info_T* classInfo,
Buf_T* classItems
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
nuint8 rq[4 + MAX_SCHEMA_NAME_BYTES];
Buf_T rqb;
NWDSSetupBuf(&rqb, rq, sizeof(rq));
dserr = NWDSCtxBufString(ctx, &rqb, className);
if (dserr)
return dserr;
dserr = __NWDSFindSchemaServer(ctx, &conn);
if (dserr)
return dserr;
dserr = __NWDSDefineClassV0(conn, classInfo, &rqb, classItems);
NWCCCloseConn(conn);
return dserr;
}
static NWDSCCODE __NWDSRemoveClassDefV0(
NWCONN_HANDLE conn,
Buf_T* className
) {
NW_FRAGMENT rq_frag[2];
nuint8 rq_b[4];
DSET_LH(rq_b, 0, 0); /* version */
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 4;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(className, &rq_frag[1].fragSize);
return NWCFragmentRequest(conn, DSV_REMOVE_CLASS_DEF, 2, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSRemoveClassDef(
NWDSContextHandle ctx,
const NWDSChar* className
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
nuint8 rq[4 + MAX_SCHEMA_NAME_BYTES];
Buf_T rqb;
NWDSSetupBuf(&rqb, rq, sizeof(rq));
dserr = NWDSCtxBufString(ctx, &rqb, className);
if (dserr)
return dserr;
dserr = __NWDSFindSchemaServer(ctx, &conn);
if (dserr)
return dserr;
dserr = __NWDSRemoveClassDefV0(conn, &rqb);
NWCCCloseConn(conn);
return dserr;
}
static NWDSCCODE __NWDSModifyClassDefV0(
NWCONN_HANDLE conn,
Buf_T* className,
Buf_T* optionalAttrs
) {
NW_FRAGMENT rq_frag[3];
nuint8 rq_b[4];
if (!optionalAttrs)
return ERR_NULL_POINTER;
if (optionalAttrs->operation != DSV_MODIFY_CLASS_DEF)
return ERR_BAD_VERB;
DSET_LH(rq_b, 0, 0); /* version */
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 4;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(className, &rq_frag[1].fragSize);
rq_frag[2].fragAddr.ro = NWDSBufRetrieve(optionalAttrs, &rq_frag[2].fragSize);
return NWCFragmentRequest(conn, DSV_MODIFY_CLASS_DEF, 3, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSModifyClassDef(
NWDSContextHandle ctx,
const NWDSChar* className,
Buf_T* optionalAttrs
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
nuint8 rq[4 + MAX_SCHEMA_NAME_BYTES];
Buf_T rqb;
NWDSSetupBuf(&rqb, rq, sizeof(rq));
dserr = NWDSCtxBufString(ctx, &rqb, className);
if (dserr)
return dserr;
dserr = __NWDSFindSchemaServer(ctx, &conn);
if (dserr)
return dserr;
dserr = __NWDSModifyClassDefV0(conn, &rqb, optionalAttrs);
NWCCCloseConn(conn);
return dserr;
}
static NWDSCCODE __NWDSListContainableClassesV0(
NWCONN_HANDLE conn,
nuint32* iterHandle,
NWObjectID objID,
Buf_T* containableClasses
) {
NW_FRAGMENT rq_frag[1];
NW_FRAGMENT rp_frag[2];
nuint8 rq_b[12];
nuint8 rp_b[4];
NWDSCCODE dserr;
if (!containableClasses)
return ERR_NULL_POINTER;
DSET_LH(rq_b, 0, 0);
DSET_LH(rq_b, 4, *iterHandle);
DSET_HL(rq_b, 8, objID);
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 12;
NWDSBufStartPut(containableClasses, DSV_LIST_CONTAINABLE_CLASSES);
rp_frag[0].fragAddr.rw = rp_b;
rp_frag[0].fragSize = 4;
rp_frag[1].fragAddr.rw = NWDSBufPutPtrLen(containableClasses, &rp_frag[1].fragSize);
dserr = NWCFragmentRequest(conn, DSV_LIST_CONTAINABLE_CLASSES,
1, rq_frag, 2, rp_frag, NULL);
if (dserr)
return dserr;
if (rp_frag[1].fragSize < 4)
return ERR_INVALID_SERVER_RESPONSE;
*iterHandle = DVAL_LH(rp_b, 0);
NWDSBufPutSkip(containableClasses, rp_frag[1].fragSize);
NWDSBufFinishPut(containableClasses);
return 0;
}
NWDSCCODE NWDSListContainableClasses(
NWDSContextHandle ctx,
const NWDSChar* parentName,
nuint32* iterHandle,
Buf_T* containableClasses
) {
NWCONN_HANDLE conn;
NWObjectID objID;
nuint32 lh;
NWDSCCODE dserr;
struct wrappedIterationHandle* ih;
if (*iterHandle == NO_MORE_ITERATIONS) {
dserr = NWDSResolveName2(ctx, parentName,
DS_RESOLVE_READABLE | DS_RESOLVE_V0, &conn,
&objID);
if (dserr)
return dserr;
ih = NULL;
lh = NO_MORE_ITERATIONS;
} else {
ih = __NWDSIHLookup(*iterHandle, DSV_LIST_CONTAINABLE_CLASSES);
if (!ih)
return ERR_INVALID_HANDLE;
conn = ih->conn;
objID = ih->objectID;
lh = ih->iterHandle;
}
dserr = __NWDSListContainableClassesV0(conn, &lh, objID, containableClasses);
if (ih)
return __NWDSIHUpdate(ih, dserr, lh, iterHandle);
return __NWDSIHCreate(dserr, conn, objID, lh, DSV_LIST_CONTAINABLE_CLASSES, iterHandle);
}
#define ATTRDEF_SYNTAXID 0x0001
#define ATTRDEF_TIMES 0x0002
static NWDSCCODE __NWDSReadAttrDefV0(
NWCONN_HANDLE conn,
nuint32* iterHandle,
nuint infoType,
nuint allAttrs,
Buf_T* attrNames,
Buf_T* attrDefs
) {
static const nuint it2cmd[] = {
0,
ATTRDEF_SYNTAXID,
ATTRDEF_SYNTAXID | ATTRDEF_TIMES
};
NW_FRAGMENT rq_frag[2];
NW_FRAGMENT rp_frag[2];
nuint8 rq_b[20];
nuint8 rp_b[8];
NWDSCCODE dserr;
size_t rq_frags;
if (!attrDefs)
return ERR_NULL_POINTER;
DSET_LH(rq_b, 0, 0);
DSET_LH(rq_b, 4, *iterHandle);
DSET_LH(rq_b, 8, infoType);
DSET_LH(rq_b, 12, allAttrs);
rq_frag[0].fragAddr.ro = rq_b;
if (allAttrs || !attrNames) {
DSET_LH(rq_b, 16, 0);
rq_frag[0].fragSize = 20;
rq_frags = 1;
} else {
if (attrNames->operation != DSV_READ_ATTR_DEF)
return ERR_BAD_VERB;
rq_frag[0].fragSize = 16;
rq_frags = 2;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(attrNames, &rq_frag[1].fragSize);
}
NWDSBufStartPut(attrDefs, DSV_READ_ATTR_DEF);
if (infoType > 2)
attrDefs->cmdFlags = ATTRDEF_SYNTAXID;
else
attrDefs->cmdFlags = it2cmd[infoType];
rp_frag[0].fragAddr.rw = rp_b;
rp_frag[0].fragSize = 8;
rp_frag[1].fragAddr.rw = NWDSBufPutPtrLen(attrDefs, &rp_frag[1].fragSize);
dserr = NWCFragmentRequest(conn, DSV_READ_ATTR_DEF, rq_frags, rq_frag,
2, rp_frag, NULL);
if (dserr)
return dserr;
if (rp_frag[1].fragSize < 4)
return ERR_INVALID_SERVER_RESPONSE;
if (infoType != DVAL_LH(rp_b, 4))
return ERR_INVALID_SERVER_RESPONSE;
*iterHandle = DVAL_LH(rp_b, 0);
NWDSBufPutSkip(attrDefs, rp_frag[1].fragSize);
NWDSBufFinishPut(attrDefs);
return 0;
}
NWDSCCODE NWDSReadAttrDef(
NWDSContextHandle ctx,
nuint infoType,
nuint allAttrs,
Buf_T* attrNames,
nuint32* iterHandle,
Buf_T* attrDefs
) {
NWCONN_HANDLE conn;
nuint32 lh;
NWDSCCODE dserr;
struct wrappedIterationHandle* ih;
if (*iterHandle == NO_MORE_ITERATIONS) {
dserr = __NWDSGetConnection(ctx, &conn);
if (dserr)
return dserr;
ih = NULL;
lh = NO_MORE_ITERATIONS;
} else {
ih = __NWDSIHLookup(*iterHandle, DSV_READ_ATTR_DEF);
if (!ih)
return ERR_INVALID_HANDLE;
conn = ih->conn;
lh = ih->iterHandle;
}
dserr = __NWDSReadAttrDefV0(conn, &lh, infoType, allAttrs, attrNames, attrDefs);
if (ih)
return __NWDSIHUpdate(ih, dserr, lh, iterHandle);
return __NWDSIHCreate(dserr, conn, 0, lh, DSV_READ_ATTR_DEF, iterHandle);
}
NWDSCCODE NWDSGetAttrDef(
NWDSContextHandle ctx,
Buf_T* buf,
NWDSChar* attrName,
Attr_Info_T* attrInfo
) {
NWDSCCODE dserr;
nuint32 tmp;
if (!buf)
return ERR_NULL_POINTER;
if (buf->bufFlags & NWDSBUFT_INPUT)
return ERR_BAD_VERB;
switch (buf->operation) {
case DSV_READ_ATTR_DEF:
break;
default:
return ERR_BAD_VERB;
}
dserr = NWDSBufCtxString(ctx, buf, attrName, MAX_SCHEMA_NAME_BYTES, NULL);
if (dserr)
return dserr;
if (buf->cmdFlags & ATTRDEF_SYNTAXID) {
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (attrInfo)
attrInfo->attrFlags = tmp;
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (attrInfo)
attrInfo->attrSyntaxID = tmp;
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (attrInfo)
attrInfo->attrLower = tmp;
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
if (attrInfo)
attrInfo->attrUpper = tmp;
if (attrInfo) {
dserr = NWDSBufGetLE32(buf, &tmp);
if (dserr)
return dserr;
attrInfo->asn1ID.length = tmp;
if (tmp > MAX_ASN1_NAME)
return NWE_BUFFER_OVERFLOW;
dserr = NWDSBufGet(buf, attrInfo->asn1ID.data, tmp);
} else {
dserr = NWDSBufSkipBuffer(buf);
}
if (dserr)
return dserr;
} else if (attrInfo) {
attrInfo->attrFlags = 0;
attrInfo->attrSyntaxID = SYN_UNKNOWN;
attrInfo->attrLower = 0;
attrInfo->attrUpper = 0;
attrInfo->asn1ID.length = 0;
}
return dserr;
}
static NWDSCCODE __NWDSDefineAttrV0(
NWCONN_HANDLE conn,
const Attr_Info_T* attrInfo,
Buf_T* attrName
) {
NW_FRAGMENT rq_frag[3];
nuint8 rq_b[8];
nuint8 rq_b2[16 + MAX_ASN1_NAME];
size_t asnlen;
size_t asnlen2;
if (!attrInfo)
return ERR_NULL_POINTER;
asnlen = attrInfo->asn1ID.length;
if (asnlen > MAX_ASN1_NAME)
return NWE_BUFFER_OVERFLOW;
DSET_LH(rq_b, 0, 0); /* version */
DSET_LH(rq_b, 4, attrInfo->attrFlags);
DSET_LH(rq_b2, 0, attrInfo->attrSyntaxID);
DSET_LH(rq_b2, 4, attrInfo->attrLower);
DSET_LH(rq_b2, 8, attrInfo->attrUpper);
DSET_LH(rq_b2, 12, asnlen);
memcpy(rq_b2 + 16, attrInfo->asn1ID.data, asnlen);
asnlen2 = ROUNDPKT(asnlen);
if (asnlen2 > asnlen)
memset(rq_b2 + 4 + asnlen, 0, asnlen2 - asnlen);
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 8;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(attrName, &rq_frag[1].fragSize);
rq_frag[2].fragAddr.ro = rq_b2;
rq_frag[2].fragSize = 16 + asnlen2;
return NWCFragmentRequest(conn, DSV_DEFINE_ATTR, 3, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSDefineAttr(
NWDSContextHandle ctx,
const NWDSChar* attrName,
const Attr_Info_T* attrInfo
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
nuint8 rq[4 + MAX_SCHEMA_NAME_BYTES];
Buf_T rqb;
NWDSSetupBuf(&rqb, rq, sizeof(rq));
dserr = NWDSCtxBufString(ctx, &rqb, attrName);
if (dserr)
return dserr;
dserr = __NWDSFindSchemaServer(ctx, &conn);
if (dserr)
return dserr;
dserr = __NWDSDefineAttrV0(conn, attrInfo, &rqb);
NWCCCloseConn(conn);
return dserr;
}
static NWDSCCODE __NWDSRemoveAttrDefV0(
NWCONN_HANDLE conn,
Buf_T* attrName
) {
NW_FRAGMENT rq_frag[2];
nuint8 rq_b[4];
DSET_LH(rq_b, 0, 0); /* version */
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 4;
rq_frag[1].fragAddr.ro = NWDSBufRetrieve(attrName, &rq_frag[1].fragSize);
return NWCFragmentRequest(conn, DSV_REMOVE_ATTR_DEF, 2, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSRemoveAttrDef(
NWDSContextHandle ctx,
const NWDSChar* attrName
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
nuint8 rq[4 + MAX_SCHEMA_NAME_BYTES];
Buf_T rqb;
NWDSSetupBuf(&rqb, rq, sizeof(rq));
dserr = NWDSCtxBufString(ctx, &rqb, attrName);
if (dserr)
return dserr;
dserr = __NWDSFindSchemaServer(ctx, &conn);
if (dserr)
return dserr;
dserr = __NWDSRemoveAttrDefV0(conn, &rqb);
NWCCCloseConn(conn);
return dserr;
}
static NWDSCCODE __NWDSSyncSchemaV0(
NWCONN_HANDLE conn,
nuint32 flags,
nuint32a timev
) {
NW_FRAGMENT rq_frag[1];
nuint8 rq_b[12];
DSET_LH(rq_b, 0, 0); /* version */
DSET_LH(rq_b, 4, flags);
DSET_LH(rq_b, 8, timev);
rq_frag[0].fragAddr.ro = rq_b;
rq_frag[0].fragSize = 12;
return NWCFragmentRequest(conn, DSV_SYNC_SCHEMA, 1, rq_frag, 0, NULL, NULL);
}
NWDSCCODE NWDSSyncSchema(
NWDSContextHandle ctx,
const NWDSChar* serverName,
nuint32a seconds
) {
NWDSCCODE dserr;
NWCONN_HANDLE conn;
dserr = NWDSOpenConnToNDSServer(ctx, serverName, &conn);
if (dserr)
return dserr;
dserr = __NWDSSyncSchemaV0(conn, 0, seconds);
NWCCCloseConn(conn);
return dserr;
}