SYNOPSIS
#include <mgid/mgid.h>

DESCRIPTION
The mgid client library provides a lightweight interface to the mgid, daemon.

The mgid system, originally designed for csoft.net hosting servers (http://www.csoft.net/), is a privilege-separated daemon which provides administrative control to users on a multi-user Unix system (or a redundant array of systems). The mgid client library communicates with the mgid daemon over a Unix socket or a network connection.

Applications can send queries to the mgid daemon using MGI_QueryList() and MGI_QueryData().

The protocol allows two types of queries: List queries expect the server to return either an error code, or an array of text strings (possibly containing valid UTF-8). Data queries expect the server to return structured binary data.

INITIALIZATION

const char *
MGI_Version (void)

int
MGI_Init (int flags)

void
MGI_Destroy (void)

const char *
MGI_GetError (void)



The MGI_Version() function returns a string containing the mgid library version. Note that the negotiation with the server will fail if the major version number does not match.

The MGI_Init() function initializes the mgid library. MGI_Destroy() releases resources allocated by the mgid library.

The MGI_GetError() function retrieves an error message string if an error has occured.

CLIENT/SERVER PROTOCOL

void
MGI_InitDescriptor (MGI *mgi)

void
MGI_FreeDescriptor (MGI *mgi)

int
MGI_Connect (MGI *mgi, const char *hostname, const char *port, const char *username, const char *password)

void
MGI_Disconnect (MGI *mgi)

MGI_List *
MGI_QueryList (MGI *mgi, const char *module, ...)

MGI_List *
MGI_QueryListv (MGI *mgi, const char *module, int argc, char **argv)

MGI_Data *
MGI_QueryData (MGI *mgi, const char *module, ...)

MGI_Data *
MGI_QueryDatav (MGI *mgi, const char *module, int argc, char **argv)

void
MGI_FreeList (MGI_List *list)

void
MGI_FreeData (MGI_Data *data)




The MGI_InitDescriptor() function initializes a MGI structure, which is used to describe a connection with a server. MGI_FreeDescriptor() frees this structure.

MGI_Connect() establishes a connection to the specified server, using the specified login information. If successful, the function returns 0, otherwise -1.

MGI_Disconnect() closes a connection with a server.

Note that it is unnecessary to call MGI_Connect() and MGI_Disconnect() unless you wish to establish a persistent connection to the server. MGI_QueryList() and MGI_QueryData() will try to establish (or re-establish) a connection when necessary.

The MGI_QueryList() and MGI_QueryListv() functions send a LIST query to the specified server module. If the query fails, NULL is returned and the error given by the server can be retrieved using MGI_GetError(). If the query succeeds, a MGI_List structure containing a dynamically-allocated array of strings will be returned. It has the following layout:
typedef struct mgi_list {
	int    argc;		/* Number of items */
	char **argv;		/* Array of items */
} MGI_List;

The MGI_QueryData() and MGI_QueryDatav() functions send a MIME query to the specified server module. If the query fails, NULL is returned. If the query succeeds, the following structure is returned:
typedef struct mgi_data {
	char type[48];		/* MIME type */
	size_t len;		/* Length of data */
	size_t pos;		/* Offset for MGI_Read*() */
	char *data;		/* Data */
} MGI_Data;

The type field contains a standard MIME type such as text/plain, but more frequently application-specific types (for example application/x-mgi-user-list) will be used. len is the total number of bytes and pos determines the current position when MGI_Read*() functions are used.

MGI_FreeList() and MGI_FreeData() frees resources allocated for a MGI_List() and MGI_Data() structure, respectively.

STRUCTURED DATA QUERIES


The following functions are used to facilitate decoding of structured data queries. They read some type of data from the buffer, and advance the MGI_Data offset accordingly.


Uint8
MGI_ReadUint8 (MGI_Data *md)

Sint8
MGI_ReadSint8 (MGI_Data *md)

Uint16
MGI_ReadUint16 (MGI_Data *md)

Sint16
MGI_ReadSint16 (MGI_Data *md)

Uint32
MGI_ReadUint32 (MGI_Data *md)

Sint32
MGI_ReadSint32 (MGI_Data *md)

int
MGI_ReadArray (MGI_Data *md, int *count)

int
MGI_ReadFixedArray (MGI_Data *md, int count)

int
MGI_CopyScalar (MGI_Data *md, char *buf, size_t buf_size)

int
MGI_CopyScalarBin (MGI_Data *md, void *buf, size_t buf_size)

int
MGI_ReadScalar (MGI_Data *md, char **buf)

int
MGI_ReadScalarBin (MGI_Data *md, void **buf)

int
MGI_DumpToFile (MGI_Data *md, const char *file)




The MGI_ReadUint*() and MGI_ReadSint*() functions read integer data and convert from network byte order to host byte order.

MGI_ReadArray() expects a code indicating that the following data is actually an array, and returns an item count in count. It does not actually read the contents of the array, and is mostly used to facilitate debugging and make code more explicit. It returns 0 on success and -1 on failure.

MGI_ReadFixedArray() does the same as MGI_ReadArray() except that it expects a specific count of items. If the count is not matched, the function returns -1.

MGI_ReadScalar() expects a code indicating that the following data is a scalar (as in Perl), allocates memory for, and reads its contents, which are returned into s. It returns 0 on success and -1 on failure.

The MGI_DumpToFile() utility routine dumps the raw binary data into the specified file and returns 0 on success, -1 on failure.

EXAMPLES
The following uses MGI_QueryList() to fetch a list of CSV-style items:
MGI_List *MyList;
int i;

if ((MyList = MGI_QueryList(&mgi, "MyModule", "list", NULL))
    == NULL) {
	errx(1, "Query failed: %s", MGI_GetError());
}
for (i = 0; i < MyList->argc; i++) {
	char *s = MyList->argv[i];
	char *field1 = strsep(&s, ":");
	char *field2 = strsep(&s, ":");

	printf("Item: %s, %s\\n", field1, field2);
}
MGI_FreeList(MyList);

A more efficient way to retrieve structured data is using a binary query with the MGI_QueryData() function:
MGI_Data *MyData;
int i, count;

if ((MyData = MGI_QueryData(&mgi, "MyModule", "list", NULL))
    == NULL) {
	errx(1, "Query failed: %s", MGI_GetError());
}

count = (int)MGI_ReadUint32(mgi);
for (i = 0; i < count; i++){
	char field1[32], field2[32];

	MGI_CopyScalar(mgi, field1, sizeof(field1));
	MGI_CopyScalar(mgi, field2, sizeof(field2));
	printf("Item: %s, %s\\n", field1, field2);
}
MGI_FreeData(MyData);

SEE ALSO
mgid

HISTORY
The mgid client library is derived from libcsoftadm, originally developed in 1999 at csoft.net hosting (http://www.csoft.net)

(c) 2016 Hypertriton Inc.
Hosted on OpenBSD servers at Csoft.net in NYC.
Sponsored by ElectronTubeStore.com.
Hosted by Csoft.net Sponsored by ElectronTubeStore.com