#include <mgid/mgid.h>

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

The mgid system, originally designed for hosting servers (, 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.


const char *
MGI_Version (void)

MGI_Init (int flags)

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.


MGI_InitDescriptor (MGI *mgi)

MGI_FreeDescriptor (MGI *mgi)

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

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)

MGI_FreeList (MGI_List *list)

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.


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.

MGI_ReadUint8 (MGI_Data *md)

MGI_ReadSint8 (MGI_Data *md)

MGI_ReadUint16 (MGI_Data *md)

MGI_ReadSint16 (MGI_Data *md)

MGI_ReadUint32 (MGI_Data *md)

MGI_ReadSint32 (MGI_Data *md)

MGI_ReadArray (MGI_Data *md, int *count)

MGI_ReadFixedArray (MGI_Data *md, int count)

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

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

MGI_ReadScalar (MGI_Data *md, char **buf)

MGI_ReadScalarBin (MGI_Data *md, void **buf)

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.

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);

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);


The mgid client library is derived from libcsoftadm, originally developed in 1999 at hosting ( ElectronTubeStore