Files
ncpfs/lib/o_ndslib.c
2026-04-28 20:56:03 +02:00

274 lines
5.8 KiB
C

/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Revision history:
1.00 1999, November 20 Petr Vandrovec <vandrove@vc.cvut.cz>
Mark these calls obsolete.
Modify them to use new API.
*/
#define NCP_OBSOLETE
extern int bindery_only;
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include "nwnet_i.h"
int strlen_u(const uni_char *s) {
return unilen(s);
}
uni_char getchr_u(const uni_char* s) {
return WVAL_LH((const void*)s, 0);
}
void strcpy_uc(char *d, const uni_char *s) {
while ((*d++ = getchr_u(s++)) != 0);
}
void strcpy_cu(uni_char *d, const char *s) {
do {
WSET_LH((void*)(d++), 0, *s);
} while (*s++);
}
long nds_get_server_name(struct ncp_conn *conn, uni_char **server_name) {
NWDSContextHandle ctx;
NWDSCCODE err;
void* outbuf;
u_int32_t flags;
outbuf = malloc(4096);
if (!outbuf)
return ENOMEM;
err = NWDSCreateContextHandle(&ctx);
if (err)
goto q_mem;
flags = 0;
err = NWDSSetContext(ctx, DCK_FLAGS, &flags);
if (err)
goto q_ctx;
err = NWDSGetServerDN(ctx, conn, outbuf);
if (!err) {
*server_name = outbuf;
NWDSFreeContext(ctx);
return 0;
}
q_ctx:;
NWDSFreeContext(ctx);
q_mem:;
free(outbuf);
return err;
}
long nds_get_tree_name(struct ncp_conn *conn, char *name, int name_buf_len) {
char buf[MAX_TREE_NAME_CHARS+1];
if (bindery_only) return -1;
if (!NWIsDSServer(conn, buf))
return -1;
if (name) {
size_t size;
char* p;
p = strchr(buf, '\0') - 1;
while ((p >= buf) && (*p == '_'))
p--;
size = p - buf + 1;
if (size >= (size_t)name_buf_len)
return -1;
memcpy(name, buf, size);
name[size] = 0;
}
return 0;
}
/* for login */
long nds_resolve_name(struct ncp_conn *conn, int flags, uni_char *entry_name,
int *entry_id, int *remote, UNUSED(struct sockaddr *serv_addr), size_t *addr_len) {
NWDSCCODE err;
NWDSContextHandle ctx;
u_int32_t ctxflags;
u_int32_t replytype;
Buf_T* rp;
err = NWDSCreateContextHandle(&ctx);
if (err)
return err;
flags = 0;
err = NWDSSetContext(ctx, DCK_FLAGS, &ctxflags);
if (err)
goto q_ctx;
err = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &rp);
if (err)
goto q_ctx;
err = NWDSResolveNameInt(ctx, conn, DS_RESOLVE_V0, flags, (const NWDSChar*)entry_name, rp);
if (err)
goto q_buf;
err = NWDSBufGetLE32(rp, &replytype);
if (err)
goto q_buf;
switch (replytype) {
case DS_RESOLVE_REPLY_LOCAL_ENTRY:
{
NWObjectID ID;
err = NWDSBufGetID(rp, &ID);
if (!err) {
if (entry_id)
*entry_id = ID;
if (remote)
*remote = 0;
}
}
break;
case DS_RESOLVE_REPLY_REMOTE_ENTRY:
{
NWObjectID ID;
nuint32 dummy;
err = NWDSBufGetID(rp, &ID);
if (err)
goto q_buf;
if (entry_id)
*entry_id = ID;
err = NWDSBufGetLE32(rp, &dummy);
if (err)
goto q_buf;
if (remote)
*remote = 1;
/* we do not support address passing... use NWDSResolveName instead */
if (addr_len)
*addr_len = 0;
break;
}
break;
default:
err = ERR_INVALID_SERVER_RESPONSE;
break;
}
q_buf:;
NWDSFreeBuf(rp);
q_ctx:;
NWDSFreeContext(ctx);
return err;
}
long nds_read(struct ncp_conn *conn, u_int32_t obj_id, uni_char *propname,
u_int32_t* type, void **outbuf, size_t *outlen) {
NWDSContextHandle ctx;
NWDSCCODE err;
u_int32_t flags;
Buf_T* attr;
Buf_T* rp;
u_int32_t iterHandle = NO_MORE_ITERATIONS;
NWObjectCount cnt;
enum SYNTAX synt;
size_t size;
Octet_String_T* buf;
err = NWDSCreateContextHandle(&ctx);
if (err)
return err;
flags = 0;
err = NWDSSetContext(ctx, DCK_FLAGS, &flags);
if (err)
goto q_ctx;
err = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &attr);
if (err)
goto q_ctx;
err = NWDSInitBuf(ctx, DSV_READ, attr);
if (err)
goto q_attr;
err = NWDSPutAttrName(ctx, attr, (const NWDSChar*)propname);
if (err)
goto q_attr;
err = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &rp);
if (err)
goto q_attr;
err = __NWDSReadV1(conn, 0, obj_id, DS_ATTRIBUTE_VALUES, 0, attr, &iterHandle, NULL, rp);
if (err)
goto q_rp;
err = NWDSGetAttrCount(ctx, rp, &cnt);
if (err)
goto q_rp;
/* we asked for one attribute, so we expect one attribute */
if (cnt != 1) {
err = ERR_INVALID_SERVER_RESPONSE;
goto q_rp;
}
err = NWDSGetAttrName(ctx, rp, NULL, &cnt, &synt);
if (err)
goto q_rp;
/* we do not support multivalued attributes */
if (cnt != 1) {
err = ERR_INVALID_SERVER_RESPONSE;
goto q_rp;
}
if (type)
*type = synt;
/* retrieve it as raw string */
err = NWDSComputeAttrValSize(ctx, rp, SYN_OCTET_STRING, &size);
if (err)
goto q_rp;
buf = (Octet_String_T*)malloc(size);
if (!buf) {
err = ENOMEM;
goto q_rp;
}
err = NWDSGetAttrVal(ctx, rp, SYN_OCTET_STRING, buf);
if (err) {
free(buf);
goto q_rp;
}
if (outlen)
*outlen = buf->length;
/* move buffer to the start of allocated region */
if (outbuf) {
*outbuf = buf;
memmove(buf, buf->data, buf->length);
} else {
free(buf);
}
q_rp:;
NWDSFreeBuf(rp);
q_attr:
NWDSFreeBuf(attr);
q_ctx:
NWDSFreeContext(ctx);
return err;
}
/* this lives in ndslib.c... for now...
long nds_login_auth(
struct ncp_conn *conn,
const char *user,
const char *pwd);
*/