Import ncpfs 2.2.1
This commit is contained in:
821
lib/ds/classes.c
Normal file
821
lib/ds/classes.c
Normal file
@@ -0,0 +1,821 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
#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;
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user