|
|
|
@@ -2,6 +2,7 @@
|
|
|
|
|
#include <Xmd/StringMap.h>
|
|
|
|
|
#include <Xmd/Map.h>
|
|
|
|
|
#include <Xmd/Buffer.h>
|
|
|
|
|
#include <Xmd/Error.h>
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
@@ -15,8 +16,10 @@ typedef struct {
|
|
|
|
|
int references;
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
XmdReplicantVersion version;
|
|
|
|
|
XmdReplicantCreate create;
|
|
|
|
|
XmdReplicantFnVersion version;
|
|
|
|
|
XmdReplicantFnConstruct construct;
|
|
|
|
|
XmdReplicantFnDestruct destruct;
|
|
|
|
|
XmdReplicantFnCreate create;
|
|
|
|
|
} symbols;
|
|
|
|
|
} XmdReplicantSource;
|
|
|
|
|
|
|
|
|
@@ -31,8 +34,8 @@ static void XmdReplicantHandleDestroy (
|
|
|
|
|
Widget replicant,
|
|
|
|
|
XtPointer clientData,
|
|
|
|
|
XtPointer callData);
|
|
|
|
|
static void XmdReplicantStateSave (XmdReplicantState *state);
|
|
|
|
|
static void XmdReplicantStateLoad (XmdReplicantState *state);
|
|
|
|
|
static XmdError XmdReplicantStateSave (XmdReplicantState *state);
|
|
|
|
|
static XmdError XmdReplicantStateLoad (XmdReplicantState *state);
|
|
|
|
|
static XmdReplicantState *XmdReplicantStateNew ();
|
|
|
|
|
static void XmdReplicantStateFree (XmdReplicantState *state);
|
|
|
|
|
static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name);
|
|
|
|
@@ -41,6 +44,7 @@ static XmdReplicantSource *XmdReplicantSourceGet (ConstString name);
|
|
|
|
|
static String XmdReplicantScanDir (
|
|
|
|
|
ConstString path,
|
|
|
|
|
ConstString name);
|
|
|
|
|
static void XmdReplicantEnsure ();
|
|
|
|
|
|
|
|
|
|
static const String defaultReplicantPath =
|
|
|
|
|
"/usr/lib/Xmd/replicants:"
|
|
|
|
@@ -80,6 +84,7 @@ static void XmdReplicantHandleDestroy (
|
|
|
|
|
) {
|
|
|
|
|
(void)(replicant);
|
|
|
|
|
(void)(callData);
|
|
|
|
|
XmdReplicantEnsure();
|
|
|
|
|
|
|
|
|
|
XmdReplicantState *state = clientData;
|
|
|
|
|
if (state == NULL) return;
|
|
|
|
@@ -104,12 +109,15 @@ String XmdReplicantResolveName (ConstString rawName) {
|
|
|
|
|
char ch = *list;
|
|
|
|
|
if (dirBuffer == NULL) dirBuffer = XmdBufferNew(char);
|
|
|
|
|
|
|
|
|
|
XmdBufferPush(dirBuffer, &ch);
|
|
|
|
|
if (ch == ':' || ch == 0) {
|
|
|
|
|
char null = 0;
|
|
|
|
|
XmdBufferPush(dirBuffer, &null);
|
|
|
|
|
String dir = XmdBufferBreak(dirBuffer);
|
|
|
|
|
dirBuffer = NULL;
|
|
|
|
|
file = XmdReplicantScanDir(dir, name);
|
|
|
|
|
XtFree(dir);
|
|
|
|
|
} else {
|
|
|
|
|
XmdBufferPush(dirBuffer, &ch);
|
|
|
|
|
}
|
|
|
|
|
list ++;
|
|
|
|
|
}
|
|
|
|
@@ -172,12 +180,13 @@ static Bool writeMapValue (
|
|
|
|
|
return True;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void XmdReplicantStateSave (XmdReplicantState *state) {
|
|
|
|
|
static XmdError XmdReplicantStateSave (XmdReplicantState *state) {
|
|
|
|
|
FILE *file = fopen(state->file, "w");
|
|
|
|
|
if (file == NULL) return;
|
|
|
|
|
if (file == NULL) return XmdErrorCantOpenFile;
|
|
|
|
|
fprintf(file, "[%s]\n", state->sourceName);
|
|
|
|
|
XmdStringMapIterate(state->map, writeMapValue, file);
|
|
|
|
|
fclose(file);
|
|
|
|
|
return XmdErrorNone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static String readEscapedMapString (FILE *file, char delimiter) {
|
|
|
|
@@ -208,23 +217,42 @@ static String readEscapedMapString (FILE *file, char delimiter) {
|
|
|
|
|
return XmdBufferBreak(string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void XmdReplicantStateLoad (XmdReplicantState *state) {
|
|
|
|
|
FILE *file = fopen(state->file, "w");
|
|
|
|
|
if (file == NULL) return;
|
|
|
|
|
static XmdError XmdReplicantStateLoad (XmdReplicantState *state) {
|
|
|
|
|
if (state->sourceName != NULL) XtFree(state->sourceName);
|
|
|
|
|
state->sourceName = NULL;
|
|
|
|
|
|
|
|
|
|
int ch = 0;
|
|
|
|
|
while (isspace((ch == fgetc(file))));
|
|
|
|
|
if (ch != '[') return;
|
|
|
|
|
FILE *file = fopen(state->file, "r");
|
|
|
|
|
if (file == NULL) {
|
|
|
|
|
return XmdErrorFileNotFound;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int ch = ' ';
|
|
|
|
|
while (isspace(ch)) ch = fgetc(file);
|
|
|
|
|
if (ch != '[') {
|
|
|
|
|
fclose(file);
|
|
|
|
|
return XmdErrorBadSyntax;
|
|
|
|
|
}
|
|
|
|
|
state->sourceName = readEscapedMapString(file, ']');
|
|
|
|
|
ch = fgetc(file);
|
|
|
|
|
if (ch != '\n') return;
|
|
|
|
|
if (ch != '\n') {
|
|
|
|
|
fclose(file);
|
|
|
|
|
return XmdErrorBadSyntax;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
String key = readEscapedMapString(file, '=');
|
|
|
|
|
String value = readEscapedMapString(file, '\n');
|
|
|
|
|
XmdStringMapSet(state->map, key, value);
|
|
|
|
|
XtFree(key);
|
|
|
|
|
if (value == NULL) break;
|
|
|
|
|
if (value == NULL) {
|
|
|
|
|
if (key == NULL) {
|
|
|
|
|
fclose(file);
|
|
|
|
|
return XmdErrorNone;
|
|
|
|
|
} else {
|
|
|
|
|
fclose(file);
|
|
|
|
|
return XmdErrorBadSyntax;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -276,18 +304,30 @@ static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name) {
|
|
|
|
|
XtFree(path);
|
|
|
|
|
if (source->handle == NULL) goto fail;
|
|
|
|
|
|
|
|
|
|
/* find symbols */
|
|
|
|
|
String versionName = NULL;
|
|
|
|
|
XtAsprintf(&versionName, "%s_XmdReplicantVersion", name);
|
|
|
|
|
source->symbols.version = (XmdReplicantVersion) (
|
|
|
|
|
dlsym(source->handle, versionName));
|
|
|
|
|
XtFree(versionName);
|
|
|
|
|
/* find symbols */
|
|
|
|
|
String symbolName = NULL;
|
|
|
|
|
XtAsprintf(&symbolName, "%s_XmdReplicantVersion", name);
|
|
|
|
|
source->symbols.version = (XmdReplicantFnVersion) (
|
|
|
|
|
dlsym(source->handle, symbolName));
|
|
|
|
|
XtFree(symbolName);
|
|
|
|
|
if (source->symbols.version == NULL) goto fail;
|
|
|
|
|
String createName = NULL;
|
|
|
|
|
XtAsprintf(&createName, "%s_XmdReplicantCreate", name);
|
|
|
|
|
source->symbols.create = (XmdReplicantCreate) (
|
|
|
|
|
dlsym(source->handle, createName));
|
|
|
|
|
XtFree(createName);
|
|
|
|
|
|
|
|
|
|
XtAsprintf(&symbolName, "%s_XmdReplicantConstruct", name);
|
|
|
|
|
source->symbols.construct = (XmdReplicantFnConstruct) (
|
|
|
|
|
dlsym(source->handle, symbolName));
|
|
|
|
|
XtFree(symbolName);
|
|
|
|
|
if (source->symbols.construct == NULL) goto fail;
|
|
|
|
|
|
|
|
|
|
XtAsprintf(&symbolName, "%s_XmdReplicantDestruct", name);
|
|
|
|
|
source->symbols.destruct = (XmdReplicantFnDestruct) (
|
|
|
|
|
dlsym(source->handle, symbolName));
|
|
|
|
|
XtFree(symbolName);
|
|
|
|
|
if (source->symbols.destruct == NULL) goto fail;
|
|
|
|
|
|
|
|
|
|
XtAsprintf(&symbolName, "%s_XmdReplicantCreate", name);
|
|
|
|
|
source->symbols.create = (XmdReplicantFnCreate) (
|
|
|
|
|
dlsym(source->handle, symbolName));
|
|
|
|
|
XtFree(symbolName);
|
|
|
|
|
if (source->symbols.create == NULL) goto fail;
|
|
|
|
|
|
|
|
|
|
/* check if the version matches */
|
|
|
|
@@ -307,6 +347,8 @@ static void XmdReplicantSourceClose (XmdReplicantSource *source) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) {
|
|
|
|
|
XmdReplicantEnsure();
|
|
|
|
|
|
|
|
|
|
/* check to see if it has already been loaded */
|
|
|
|
|
XmdReplicantSource *source = XmdStringMapGet(resident, name);
|
|
|
|
|
if (source != NULL) return source;
|
|
|
|
@@ -316,7 +358,9 @@ static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static String XmdReplicantScanDir (ConstString path, ConstString name) {
|
|
|
|
|
DIR *dir = opendir(path);
|
|
|
|
|
DIR *dir = opendir(path);
|
|
|
|
|
if (dir == NULL) return NULL;
|
|
|
|
|
|
|
|
|
|
String result = NULL;
|
|
|
|
|
while (1) {
|
|
|
|
|
struct dirent *entry = readdir(dir);
|
|
|
|
@@ -330,3 +374,9 @@ static String XmdReplicantScanDir (ConstString path, ConstString name) {
|
|
|
|
|
closedir(dir);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void XmdReplicantEnsure () {
|
|
|
|
|
if (resident == NULL) {
|
|
|
|
|
resident = XmdStringMapNew();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|