#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <xr/ThreadsMsg.h>
#define stdout XR←MSG←STDOUT
/* truncated VERSIONSTAMPPREFIX used to avoid conflicts with mimosamakedo looking for versionstamps. -mdw 12/7/88 */
#define VERSIONSTAMPPREFIX "@(#)mob←versio"
typedef void (*InstallFunc)();
static char * XR←getModuleName();
typedef struct LoadStruct {
struct LoadStruct *next;
char *file←name;
InstallFunc load←Func;
InstallFunc run←Func;
InstallFunc unload←Func;
} LoadeeRecord;
typedef LoadeeRecord *Loadee;
Loadee loadees;
void XR←run←command();
char *get←nth←word();
static int silentLoading = 1;
int
XR←load←command (command)
char *command;
{
/* Currently expects the following procedures in the file:
"XR←install←Filename", "XR←run←Filename", and "XR←unload←Filename"
where Filename has been stripped of any suffixes or prefixes. */
char *lastchancename;
char *file;
char *arg, *modulename, *XR←strip();
char func[128];
void XR←install←command();
Loadee new ;
int check←load = 0;
int nodebugger = 0;
int argno;
file = get←nth←word(command, 1);
modulename = NULL;
new = (Loadee)malloc(sizeof(LoadeeRecord));
new->file←name = (char *)malloc(strlen(file)+1);
strcpy(new->file←name, file);
lastchancename = file;
lastchancename = XR←strip(lastchancename);
argno = 2;
arg = get←nth←word(XR←GetCurrentCommand(), argno++);
while (arg[0]) {
if (arg[0] == '-') {
switch(arg[1]) {
case 'q': {
check←load = 1;
break;
}
case 'd': {
nodebugger = 1;
break;
}
default: {
XR←FPrintF (stdout, "Unrecognized load switch: %s. Ignored.\n", arg);
break;
}
}
} else { /* does not begin with '-' */
if (modulename) {
XR←FPrintF (stdout, "Unrecognized load argument: %s. Ignored.\n", arg);
} else {
modulename = arg;
}
}
arg = get←nth←word(XR←GetCurrentCommand(), argno++);
}
cpb←printf("Loading file %s", new->file←name);
if (nodebugger) {
cpb←printf(" (no debugging).\n");
} else {
cpb←printf(".\n");
}
if (load←file(new->file←name, NULL, check←load, nodebugger) == NULL) {
cpb←printf("No action taken for file '%s'.\n", new->file←name);
return 0;
}
if (! modulename) {
cpb←printf("Trying to derive module name from version stamp.\n");
modulename = XR←getModuleName();
};
if (! modulename) {
cpb←printf("Deriving module name from filename.\n");
modulename = lastchancename;
}
cpb←printf("Using module name '%s'.\n", modulename);
strcpy(func, "←XR←install←"); strcat(func, modulename);
if (((new->load←Func = (InstallFunc)get←sym←val(func)) == NULL)
&& ((new->load←Func = (InstallFunc)get←sym←val("←XR←install")) == NULL)) {
cpb←printf("Could not find 'XR←install' or '%s'.\n", func);
}
strcpy(func, "←XR←run←"); strcat(func, modulename);
if (((new->run←Func = (InstallFunc)get←sym←val(func)) == NULL)
&& ((new->run←Func = (InstallFunc)get←sym←val("←XR←run")) == NULL)) {
cpb←printf("Could not find 'XR←run' or '%s'.\n", func);
}
strcpy(func, "←XR←unload←"); strcat(func, modulename);
new->unload←Func = (InstallFunc)get←sym←val(func);
new->next = loadees;
loadees = new;
if (!(strncmp(command, "loadonly", 8) == 0)) {
char *fake;
fake = (char *)calloc(strlen(new->file←name)+20, 1);
strcat(fake, "fake ");
strcat(fake, new->file←name);
XR←install←command(fake);
} else {
cpb←printf("Loaded only--installation proc not called.\n");
}
return 1;
};
void
XR←install←command(command)
char *command;
{
char *file;
Loadee loadee = loadees;
file = get←nth←word(command, 1);
while (loadee != NULL) {
if (strcmp(file, loadee->file←name) == 0) {
if (loadee->load←Func == NULL) {
cpb←printf(" %s has no load function.", file);
} else {
loadee->load←Func();
XR←VerboseCommit();
};
cpb←printf(" %s has been installed.\n", file);
return;
};
loadee = loadee->next;
}; /* while */
cpb←printf(" %s has not been installed. ", file);
}
static void
request←command(file)
char *file;
{
char *command;
Loadee loadee = loadees;
while (loadee != NULL) {
if (strcmp(file, loadee->file←name) == 0) {
XR←FPrintF (stdout, " %s already loaded.\n", file);
return; };
loadee = loadee->next;
}; /* while */
command = (char *)calloc(strlen(file)+20, 1);
strcat(command, "fake←command ");
strcat(command, file);
XR←load←command(command);
}
void
XR←loadAndRun←command(command)
char *command;
{
char *cmd←rememberer;
cmd←rememberer = (char *)malloc(strlen(command) + 1);
strcpy(cmd←rememberer, command);
if (XR←load←command(command))
XR←run←command(cmd←rememberer);
}
void
XR←run←command(command)
char *command;
{
char *file;
Loadee loadee = loadees;
file = get←nth←word(command, 1);
while (loadee != NULL) {
if (strcmp(file, loadee->file←name) == 0) {
if (loadee->run←Func == NULL) {
cpb←printf(" %s has no function 'run'.\n", file);
} else {
cpb←printf(" running %s.\n", file);
loadee->run←Func();
}
return;
}
loadee = loadee->next;
} /* while */
cpb←printf(" %s has not been run.\n", file);
}
static void
unload←command(command)
char *command;
{
char *file;
Loadee loadee = loadees;
file = get←nth←word(command, 1);
while (loadee != NULL) {
if (strcmp(file, loadee->file←name) == 0) {
if (loadee->unload←Func == NULL) {
XR←FPrintF (stdout, " %s has no function 'unload'.\n", file);
} else loadee->unload←Func();
return; };
loadee = loadee->next;
}; /* while */
cpb←printf(" %s has not been loaded.\n", file);
};
static void
dbxtoolCommand ()
{
char num[128];
char name[128], filename[128];
int pid;
XR←FPrintF (stdout, "No auto-debugger available.\n");
}; /* debugCommand */
verboseloading()
{
silentLoading = 0;
}
silentloading()
{
silentLoading = 1;
}
typedef (*procpointer)();
static (*install←command←ptr)() = (procpointer)XR←install←command;
static (*run←command←ptr)() = (procpointer)XR←run←command;
static (*loadAndRun←command←ptr)() = (procpointer)XR←loadAndRun←command;
static (*load←command←ptr)() = (procpointer)XR←load←command;
static (*unload←command←ptr)() = (procpointer)unload←command;
static (*dbxtoolCommand←ptr)() = (procpointer)dbxtoolCommand;
static (*verboseloading←ptr)() = (procpointer)verboseloading;
static (*silentloading←ptr)() = (procpointer)silentloading;
static
XR←run()
{
XR←register("i", &install←command←ptr, "install a previously loaded Cedar module", 0);
XR←register("install", &install←command←ptr, "install a previously loaded Cedar module", 0);
XR←register("loadandrun", &loadAndRun←command←ptr, "load and then run a Cedar module (takes -d or -q switch after filename)", 0);
XR←register("lr", &loadAndRun←command←ptr, "load and then run a Cedar module (takes -d or -q switch after filename)", 0);
XR←register("l", &load←command←ptr, "load a Cedar module (takes -d or -q switch after filename)", 0);
XR←register("load", &load←command←ptr, "load a Cedar module (takes -d or -q switch after filename)", 0);
XR←register("loadonly", &load←command←ptr, "load a Cedar module (takes -d or -q switch after filename)", 0);
XR←register("r", &run←command←ptr, "run a previously loaded Cedar module", 0);
XR←register("run", &run←command←ptr, "run a previously loaded Cedar module", 0);
XR←register("unload", &unload←command←ptr, "unload a previously loaded Cedar module (unimplemented).", 0);
XR←register("dbx", &dbxtoolCommand←ptr, "start running a dbxtool pointed at the current cedarboot.", 0);
XR←register("debug", &dbxtoolCommand←ptr, "start running a dbxtool pointed at the current cedarboot.", 0);
XR←register("silentloading", &silentloading←ptr, "go about the business of dynamic loading quietly.", 0);
XR←register("verboseloading", &verboseloading←ptr, "print lots of messages about what is happening during dynamic loading.", 0);
}
XR←run←cmds()
{
XR←run();
}
cpb←printf(fmt, a, b, c, d, e, f, g, h)
{
if (! silentLoading) {
XR←FPrintF (stdout, fmt, a, b, c, d, e, f, g, h);
}
}
static char *
XR←getModuleName()
{
char *lastblank;
char *lastdot;
char *addr;
char *stamp;
if ((addr = (char *)get←sym←val("←versionStamp")) == 0) {
cpb←printf("Mimosa version stamp not found.\n");
return 0;
}
stamp = strdup(addr);
if (strncmp(stamp, VERSIONSTAMPPREFIX, strlen(VERSIONSTAMPPREFIX)) != 0) {
stamp[strlen(VERSIONSTAMPPREFIX)] = '\0';
cpb←printf("Mimosa version stamp starts with '%s': not in proper form.\n", stamp);
return 0;
}
lastblank = strrchr(stamp, ' ') + 1;
lastdot = strrchr(lastblank, '.');
if (lastdot) {
*lastdot = '\0';
}
cpb←printf("Found name in version stamp. ");
return lastblank;
}