#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; }