/*
 *  Client access routine to the "cfgmgr" server.
 */

#if 0 //def __QNXNTO__

#include <errno.h>
#include <fcntl.h>
#include <sys/cfgmgr.h>
#include <sys/cfgmsg.h>
#include <unistd.h>

int cfgmgr_attach(const char *server)
{
	return(open((server != NULL) ? server : "/dev/cfg", O_ACCMODE));
}

int cfgmgr_detach(int server)
{
	return(close(server));
}

cfgkey_t cfgmgr_open(int server, cfgkey_t root, const char *key)
{
struct _cfgmgr_open		msg;
iov_t					siov[2];
int						klen;

	klen = (key != NULL) ? strlen(key) : 0;
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_OPEN_KEY;
	msg.root = root;
	msg.keylen = klen + 1;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	return(MsgSendv(server, siov, 2, NULL, 0));
}

cfgkey_t cfgmgr_create(int server, cfgkey_t root, const char *key)
{
struct _cfgmgr_open		msg;
iov_t					siov[2];
int						klen;

	klen = (key != NULL) ? strlen(key) : 0;
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_CREATE_KEY;
	msg.root = root;
	msg.keylen = klen + 1;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	return(MsgSendv(server, siov, 2, NULL, 0));
}

int cfgmgr_close(int server, cfgkey_t key)
{
struct _cfgmgr_close	msg;

	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg);
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_CLOSE_KEY;
	msg.root = key;
	return(MsgSend(server, &msg, sizeof(msg), NULL, 0));
}

int cfgmgr_import(int server, cfgkey_t root, const char *key, int absolute, const char *file)
{
struct _cfgmgr_import	msg;
iov_t					siov[3];
int						klen, flen;

	klen = (key != NULL) ? strlen(key) : 0;
	flen = strlen(file);
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1 + flen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_IMPORT;
	msg.root = root;
	msg.absolute = absolute;
	msg.keylen = klen + 1;
	msg.pathlen = flen + 1;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&siov[2], file, flen + 1);
	return(MsgSendv(server, siov, 3, NULL, 0));
}

int cfgmgr_export(int server, cfgkey_t root, const char *key, int absolute, const char *file)
{
struct _cfgmgr_export	msg;
iov_t					siov[3];
int						klen, flen;

	klen = (key != NULL) ? strlen(key) : 0;
	flen = strlen(file);
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1 + flen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_EXPORT;
	msg.root = root;
	msg.absolute = absolute;
	msg.keylen = klen + 1;
	msg.pathlen = flen + 1;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&siov[2], file, flen + 1);
	return(MsgSendv(server, siov, 3, NULL, 0));
}

int cfgmgr_graft(int server, cfgkey_t root, const char *key, const char *file, int mode)
{
struct _cfgmgr_graft	msg;
iov_t					siov[3];
int						klen, flen;

	klen = (key != NULL) ? strlen(key) : 0;
	flen = strlen(file);
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1 + flen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_GRAFT;
	msg.root = root;
	msg.mode = mode;
	msg.keylen = klen + 1;
	msg.pathlen = flen + 1;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&siov[2], file, flen + 1);
	return(MsgSendv(server, siov, 3, NULL, 0));
}

int cfgmgr_prune(int server, cfgkey_t root, const char *key)
{
	return(errno = ENOSYS, -1);
}

int cfgmgr_read(int server, cfgkey_t root, const char *key, const char *name, int *type, void *data, int *len)
{
union _cfgmgr_read	msg;
iov_t				siov[3], riov[2];
int					klen, nlen;

	klen = (key != NULL) ? strlen(key) : 0;
	nlen = (name != NULL) ? strlen(name) : 0;
	msg.i.hdr.i.type = _IO_MSG;
	msg.i.hdr.i.combine_len = sizeof(msg) + klen + 1 + nlen + 1;
	msg.i.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.i.hdr.i.subtype = CFGMGR_MSG_READ;
	msg.i.root = root;
	msg.i.keylen = klen + 1;
	msg.i.namelen = nlen + 1;
	SETIOV(&siov[0], &msg.i, sizeof(msg.i));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&siov[2], (name != NULL) ? name : "", nlen + 1);
	SETIOV(&riov[0], &msg.o, sizeof(msg.o));
	SETIOV(&riov[1], data, (data == NULL || len == NULL) ? 0 : *len);
	if (MsgSendv(server, siov, 3, riov, 2) == -1)
		return(-1);
	if (data != NULL && len != NULL && *len < msg.o.length)
		return(errno = E2BIG, -1);
	if (type != NULL)
		*type = msg.o.type;
	if (len != NULL)
		*len = msg.o.length;
	return(0);
}

#if 0
char *cfgmgr_read_string(int server, cfgkey_t root, const char *key, const char *name, char *data, int len, char *dflt)
{
	//int cfgmgr_read(server, root, key, name, int *type, void *data, int *len)
}

int cfgmgr_read_int(int server, cfgkey_t root, const char *key, const char *name, int dflt)
{
	//int cfgmgr_read(server, root, key, name, int *type, void *data, int *len)
}
#endif

int cfgmgr_write(int server, cfgkey_t root, const char *key, const char *name, int type, void *data, int len)
{
struct _cfgmgr_write	msg;
iov_t					siov[4];
int						klen, nlen;

	klen = (key != NULL) ? strlen(key) : 0;
	nlen = (name != NULL) ? strlen(name) : 0;
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1 + nlen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = CFGMGR_MSG_WRITE;
	msg.root = root;
	msg.keylen = klen + 1;
	msg.namelen = nlen + 1;
	msg.type = type;
	msg.length = len;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&siov[2], (name != NULL) ? name : "", nlen + 1);
	SETIOV(&siov[3], data, len);
	return(MsgSendv(server, siov, 4, NULL, 0));
}

static int enumerate(int server, int message, cfgkey_t root, const char *key, int index, char *name, int nmlen)
{
struct _cfgmgr_enum		msg;
iov_t					siov[2], riov[1];
int						klen;

	klen = (key != NULL) ? strlen(key) : 0;
	msg.hdr.i.type = _IO_MSG;
	msg.hdr.i.combine_len = sizeof(msg) + klen + 1;
	msg.hdr.i.mgrid = _IOMGR_CFGMGR;
	msg.hdr.i.subtype = message;
	msg.root = root;
	msg.keylen = klen + 1;
	msg.index = index;
	msg.namelen = nmlen;
	SETIOV(&siov[0], &msg, sizeof(msg));
	SETIOV(&siov[1], (key != NULL) ? key : "", klen + 1);
	SETIOV(&riov[0], name, nmlen);
	return(MsgSendv(server, siov, 2, riov, 1));
}

int cfgmgr_enum_key(int server, cfgkey_t root, const char *key, int index, char *name, int nmlen)
{
	return(enumerate(server, CFGMGR_MSG_ENUM_KEY, root, key, index, name, nmlen));
}

int cfgmgr_enum_value(int server, cfgkey_t root, const char *key, int index, char *name, int nmlen)
{
	return(enumerate(server, CFGMGR_MSG_ENUM_VALUE, root, key, index, name, nmlen));
}
#endif
