PUBLIC int maSetPlatform(cchar *platformPath) { MaAppweb *appweb; MprDirEntry *dp; cchar *platform, *dir, *junk, *appwebExe; int next, i, notrace; appweb = MPR->appwebService; notrace = !platformPath; if (!platformPath) { platformPath = appweb->localPlatform; } appweb->platform = appweb->platformDir = 0; platform = mprGetPathBase(platformPath); if (mprPathExists(platformPath, X_OK) && mprIsPathDir(platformPath)) { appweb->platform = platform; appweb->platformDir = sclone(platformPath); } else if (smatch(platform, appweb->localPlatform)) { /* If running inside an appweb source tree, locate the platform directory */ appwebExe = mprJoinPath(mprGetAppDir(), "appweb" BIT_EXE); if (mprPathExists(appwebExe, R_OK)) { appweb->platform = appweb->localPlatform; appweb->platformDir = mprGetPathParent(mprGetAppDir()); } else { /* Check installed appweb */ appwebExe = BIT_VAPP_PREFIX "/bin/appweb" BIT_EXE; if (mprPathExists(appwebExe, R_OK)) { appweb->platform = appweb->localPlatform; appweb->platformDir = sclone(BIT_VAPP_PREFIX); } } } /* Last chance. Search up the tree for a similar platform directory. This permits specifying a partial platform like "vxworks" without architecture and profile. */ if (!appweb->platformDir) { dir = mprGetCurrentPath(); for (i = 0; !mprSamePath(dir, "/") && i < 64; i++) { for (ITERATE_ITEMS(mprGetPathFiles(dir, 0), dp, next)) { if (dp->isDir && sstarts(mprGetPathBase(dp->name), platform)) { appweb->platform = mprGetPathBase(dp->name); appweb->platformDir = mprJoinPath(dir, dp->name); break; } } dir = mprGetPathParent(dir); } }
static void testResolvePath(MprTestGroup *gp) { #if FUTURE char *path, *absPath, *out; out = mprGetAbsPath("../out"); assert(smatch(mprResolvePath(out, mprGetCurrentPath()), "../src/test")); #endif }
/* Security checks. Make sure we are staring with a safe environment */ static int checkEnvironment(cchar *program) { #if ME_UNIX_LIKE char *home; home = mprGetCurrentPath(); if (unixSecurityChecks(program, home) < 0) { return -1; } app->pathVar = sjoin("PATH=", getenv("PATH"), ":", mprGetAppDir(), NULL); putenv(app->pathVar); #endif return 0; }
/* Get the current working directory function get dir(): Path */ static EjsPath *app_dir(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { return ejsCreatePathFromAsc(ejs, mprGetCurrentPath(ejs)); }
static void testRelPath(MprTestGroup *gp) { char *path, *absPath; path = mprGetRelPath("Makefile", 0); assert(strcmp(path, "Makefile") == 0); path = mprNormalizePath("../a.b"); assert(strcmp(path, "../a.b") == 0); path = mprGetRelPath("/", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("//", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/tmp", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Unknown/someone/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Users/mob/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath("/Users/mob/././../mob/junk", 0); assert(mprIsPathRel(path)); assert(strncmp(path, "../", 3) == 0); path = mprGetRelPath(".", 0); assert(strcmp(path, ".") == 0); path = mprGetRelPath("..", 0); assert(strcmp(path, "..") == 0); path = mprGetRelPath("/Users/mob/github/admin", 0); assert(sstarts(path, "..")); path = mprGetRelPath("/Users/mob/git", 0); path = mprGetRelPath("/Users/mob/git/mpr/test", 0); /* Can't really test the result of this */ absPath = mprGetAbsPath("Makefile"); assert(mprIsPathAbs(absPath)); path = mprGetRelPath(absPath, 0); assert(!mprIsPathAbs(path)); assert(strcmp(path, "Makefile") == 0); #if FUTURE // MOB - problem in that we don't know the cwd when testMpr runs // Test relative to an origin out = mprGetAbsPath("../../out"); cwd = mprGetCurrentPath(); assert(smatch(mprGetRelPath(cwd, out), "../src/test")); #endif }
PUBLIC int mprLoadNativeModule(MprModule *mp) { MprModuleEntry fn; MprPath info; char *at; void *handle; assert(mp); /* Search the image incase the module has been statically linked */ #ifdef RTLD_DEFAULT handle = RTLD_DEFAULT; #else #ifdef RTLD_MAIN_ONLY handle = RTLD_MAIN_ONLY; #else handle = 0; #endif #endif if (!mp->entry || !dlsym(handle, mp->entry)) { if ((at = mprSearchForModule(mp->path)) == 0) { mprError("Cannot find module \"%s\", cwd: \"%s\", search path \"%s\"", mp->path, mprGetCurrentPath(), mprGetModuleSearchPath()); return MPR_ERR_CANT_ACCESS; } mp->path = at; mprGetPathInfo(mp->path, &info); mp->modified = info.mtime; mprLog(2, "Loading native module %s", mprGetPathBase(mp->path)); if ((handle = dlopen(mp->path, RTLD_LAZY | RTLD_GLOBAL)) == 0) { mprError("Cannot load module %s\nReason: \"%s\"", mp->path, dlerror()); return MPR_ERR_CANT_OPEN; } mp->handle = handle; } else if (mp->entry) { mprLog(2, "Activating native module %s", mp->name); } if (mp->entry) { if ((fn = (MprModuleEntry) dlsym(handle, mp->entry)) != 0) { if ((fn)(mp->moduleData, mp) < 0) { mprError("Initialization for module %s failed", mp->name); dlclose(handle); return MPR_ERR_CANT_INITIALIZE; } } else { mprError("Cannot load module %s\nReason: can't find function \"%s\"", mp->path, mp->entry); dlclose(handle); return MPR_ERR_CANT_READ; } } return 0; }
MAIN(appweb, int argc, char **argv) { Mpr *mpr; MaHttp *http; cchar *ipAddrPort, *documentRoot, *argp, *logSpec; char *configFile, *ipAddr, *homeDir, *timeText, *ejsPrefix, *ejsPath, *changeRoot; int workers, outputVersion, argind, port; documentRoot = 0; changeRoot = ejsPrefix = ejsPath = 0; ipAddrPort = 0; ipAddr = 0; port = -1; logSpec = 0; server = 0; outputVersion = 0; workers = -1; configFile = BLD_FEATURE_CONFIG_FILE; homeDir = BLD_FEATURE_SERVER_ROOT; mpr = mprCreate(argc, argv, memoryFailure); argc = mpr->argc; argv = mpr->argv; #if BLD_FEATURE_ROMFS extern MprRomInode romFiles[]; mprSetRomFileSystem(mpr, romFiles); #endif if (osInit(mpr) < 0) { exit(2); } if (mprStart(mpr, 0) < 0) { mprUserError(mpr, "Can't start MPR for %s", mprGetAppName(mpr)); mprFree(mpr); return MPR_ERR_CANT_INITIALIZE; } for (argind = 1; argind < argc; argind++) { argp = argv[argind]; if (*argp != '-') { break; } if (strcmp(argp, "--config") == 0) { if (argind >= argc) { return printUsage(mpr); } configFile = argv[++argind]; #if BLD_UNIX_LIKE } else if (strcmp(argp, "--chroot") == 0) { if (argind >= argc) { return printUsage(mpr); } changeRoot = mprGetAbsPath(mpr, argv[++argind]); #endif } else if (strcmp(argp, "--debug") == 0 || strcmp(argp, "-D") == 0 || strcmp(argp, "-d") == 0 || strcmp(argp, "--debugger") == 0) { mprSetDebugMode(mpr, 1); } else if (strcmp(argp, "--ejs") == 0) { if (argind >= argc) { return printUsage(mpr); } ejsPrefix = mprStrdup(mpr, argv[++argind]); if ((ejsPath = strchr(ejsPrefix, ':')) != 0) { *ejsPath++ = '\0'; } ejsPath = mprGetAbsPath(mpr, ejsPath); } else if (strcmp(argp, "--home") == 0) { if (argind >= argc) { return printUsage(mpr); } homeDir = mprGetAbsPath(mpr, argv[++argind]); if (chdir((char*) homeDir) < 0) { mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir); exit(2); } } else if (strcmp(argp, "--log") == 0 || strcmp(argp, "-l") == 0) { if (argind >= argc) { return printUsage(mpr); } logSpec = argv[++argind]; maStartLogging(mpr, logSpec); } else if (strcmp(argp, "--name") == 0 || strcmp(argp, "-n") == 0) { if (argind >= argc) { return printUsage(mpr); } mprSetAppName(mpr, argv[++argind], 0, 0); } else if (strcmp(argp, "--threads") == 0) { if (argind >= argc) { return printUsage(mpr); } workers = atoi(argv[++argind]); } else if (strcmp(argp, "--verbose") == 0 || strcmp(argp, "-v") == 0) { maStartLogging(mpr, "stdout:2"); } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { outputVersion++; } else { mprPrintfError(mpr, "Unknown switch \"%s\"\n", argp); printUsage(mpr); exit(2); } } if (argc > argind) { if (argc > (argind + 2)) { return printUsage(mpr); } ipAddrPort = argv[argind++]; if (argc > argind) { documentRoot = argv[argind++]; } else { documentRoot = "."; } } if (outputVersion) { mprPrintf(mpr, "%s %s-%s\n", mprGetAppTitle(mpr), BLD_VERSION, BLD_NUMBER); exit(0); } if (ipAddrPort) { mprParseIp(mpr, ipAddrPort, &ipAddr, &port, MA_SERVER_DEFAULT_PORT_NUM); } else { #if BLD_FEATURE_CONFIG_PARSE if (configFile == 0) { configFile = mprStrcat(mpr, -1, mprGetAppName(mpr), ".conf", NULL); } if (!mprPathExists(mpr, configFile, R_OK)) { mprPrintfError(mpr, "Can't open config file %s\n", configFile); exit(2); } #else return printUsage(mpr); #endif #if !BLD_FEATURE_ROMFS if (homeDir == 0) { homeDir = mprGetPathParent(mpr, configFile); if (chdir((char*) homeDir) < 0) { mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir); exit(2); } } #endif } homeDir = mprGetCurrentPath(mpr); if (checkEnvironment(mpr, argv[0], homeDir) < 0) { exit(3); } #if BLD_UNIX_LIKE if (changeRoot) { homeDir = mprGetAbsPath(mpr, changeRoot); if (chdir(homeDir) < 0) { mprError(mpr, "%s: Can't change directory to %s", homeDir); exit(4); } if (chroot(homeDir) < 0) { if (errno == EPERM) { mprError(mpr, "%s: Must be super user to use the --chroot option", mprGetAppName(mpr)); } else { mprError(mpr, "%s: Can't change change root directory to %s, errno %d", mprGetAppName(mpr), homeDir, errno); } exit(5); } } #endif /* * Create the top level HTTP service and default HTTP server. Set the initial server root to "." */ http = maCreateHttp(mpr); if (http == 0) { mprUserError(mpr, "Can't create HTTP service for %s", mprGetAppName(mpr)); return MPR_ERR_CANT_INITIALIZE; } server = maCreateServer(http, "default", ".", 0, -1); if (server == 0) { mprUserError(mpr, "Can't create HTTP server for %s", mprGetAppName(mpr)); return MPR_ERR_CANT_INITIALIZE; } if (maConfigureServer(mpr, http, server, configFile, ipAddr, port, documentRoot) < 0) { /* mprUserError(mpr, "Can't configure the server, exiting."); */ exit(6); } if (mpr->ipAddr) { mprLog(mpr, 2, "Server IP address %s", mpr->ipAddr); } timeText = mprFormatLocalTime(mpr, mprGetTime(mpr)); mprLog(mpr, 1, "Started at %s", timeText); mprFree(timeText); #if BLD_FEATURE_EJS if (ejsPrefix) { createEjsAlias(mpr, http, server, ejsPrefix, ejsPath); } #endif #if BLD_FEATURE_MULTITHREAD if (workers >= 0) { mprSetMaxWorkers(http, workers); } #endif #if BLD_WIN_LIKE if (!ejsPrefix) { writePort(server->defaultHost); } #endif if (maStartHttp(http) < 0) { mprUserError(mpr, "Can't start HTTP service, exiting."); exit(7); } #if BLD_FEATURE_MULTITHREAD mprLog(mpr, 1, "HTTP services are ready with max %d worker threads", mprGetMaxWorkers(mpr)); #else mprLog(mpr, 1, "HTTP services are ready (single-threaded)"); #endif /* * Service I/O events until instructed to exit */ while (!mprIsExiting(mpr)) { mprServiceEvents(mpr->dispatcher, -1, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); } /* * Signal a graceful shutdown */ mprLog(http, 1, "Exiting ..."); maStopHttp(http); mprLog(http, 1, "Exit complete"); #if VXWORKS if (mprStop(mpr)) { mprFree(mpr); } #endif return 0; }
MAIN(appweb, int argc, char **argv, char **envp) { Mpr *mpr; cchar *argp, *jail; char *logSpec; int argind, status, verbose; jail = 0; verbose = 0; logSpec = 0; if ((mpr = mprCreate(argc, argv, MPR_USER_EVENTS_THREAD)) == NULL) { exit(1); } mprSetAppName(BIT_PRODUCT, BIT_TITLE, BIT_VERSION); /* Allocate the top level application object. ManageApp is the GC manager function and is called by the GC to mark references in the app object. */ if ((app = mprAllocObj(AppwebApp, manageApp)) == NULL) { exit(2); } mprAddRoot(app); mprAddStandardSignals(); app->mpr = mpr; app->configFile = sclone("appweb.conf"); app->home = mprGetCurrentPath(); app->documents = app->home; argc = mpr->argc; argv = (char**) mpr->argv; for (argind = 1; argind < argc; argind++) { argp = argv[argind]; if (*argp != '-') { break; } if (smatch(argp, "--config") || smatch(argp, "--conf")) { if (argind >= argc) { usageError(); } app->configFile = sclone(argv[++argind]); #if BIT_UNIX_LIKE } else if (smatch(argp, "--chroot")) { if (argind >= argc) { usageError(); } jail = mprGetAbsPath(argv[++argind]); #endif } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) { mprSetDebugMode(1); } else if (smatch(argp, "--exe")) { if (argind >= argc) { usageError(); } mpr->argv[0] = mprGetAbsPath(argv[++argind]); mprSetAppPath(mpr->argv[0]); mprSetModuleSearchPath(NULL); } else if (smatch(argp, "--home")) { if (argind >= argc) { usageError(); } app->home = mprGetAbsPath(argv[++argind]); if (chdir(app->home) < 0) { mprError("%s: Cannot change directory to %s", mprGetAppName(), app->home); exit(4); } } else if (smatch(argp, "--log") || smatch(argp, "-l")) { if (argind >= argc) { usageError(); } logSpec = argv[++argind]; } else if (smatch(argp, "--name") || smatch(argp, "-n")) { if (argind >= argc) { usageError(); } mprSetAppName(argv[++argind], 0, 0); } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) { verbose++; } else if (smatch(argp, "--version") || smatch(argp, "-V")) { mprPrintf("%s-%s\n", BIT_VERSION, BIT_BUILD_NUMBER); exit(0); } else { if (!smatch(argp, "?")) { mprError("Unknown switch \"%s\"", argp); } usageError(); exit(5); } } if (logSpec) { mprStartLogging(logSpec, 1); mprSetCmdlineLogging(1); } else if (verbose) { mprStartLogging(sfmt("stderr:%d", verbose + 1), 1); mprSetCmdlineLogging(1); } /* Start the multithreaded portable runtime (MPR) */ if (mprStart() < 0) { mprError("Cannot start MPR for %s", mprGetAppName()); mprDestroy(MPR_EXIT_DEFAULT); return MPR_ERR_CANT_INITIALIZE; } if (checkEnvironment(argv[0]) < 0) { exit(6); } if (findAppwebConf() < 0) { exit(7); } if (jail && changeRoot(jail) < 0) { exit(8); } /* Open the sockets to listen on */ if (createEndpoints(argc - argind, &argv[argind]) < 0) { return MPR_ERR_CANT_INITIALIZE; } /* Start HTTP services */ if (maStartAppweb(app->appweb) < 0) { mprError("Cannot start HTTP service, exiting."); exit(9); } /* Service I/O events until instructed to exit */ while (!mprIsStopping()) { mprServiceEvents(-1, 0); } status = mprGetExitStatus(); mprLog(1, "Stopping Appweb ..."); maStopAppweb(app->appweb); mprDestroy(MPR_EXIT_DEFAULT); return status; }
MAIN(http, int argc, char **argv, char **envp) { Mpr *mpr; cchar *argp; char *logSpec, *traceSpec; int argind; logSpec = 0; traceSpec = 0; if ((mpr = mprCreate(argc, argv, MPR_USER_EVENTS_THREAD)) == NULL) { exit(1); } if ((app = mprAllocObj(App, manageApp)) == NULL) { exit(2); } mprAddRoot(app); mprAddStandardSignals(); if (httpCreate(HTTP_CLIENT_SIDE | HTTP_SERVER_SIDE) < 0) { exit(2); } app->mpr = mpr; app->home = mprGetCurrentPath(); argc = mpr->argc; argv = (char**) mpr->argv; for (argind = 1; argind < argc; argind++) { argp = argv[argind]; if (*argp != '-') { break; } if (smatch(argp, "--config") || smatch(argp, "--conf")) { if (argind >= argc) { usageError(); } app->configFile = sclone(argv[++argind]); } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) { mprSetDebugMode(1); } else if (smatch(argp, "--log") || smatch(argp, "-l")) { if (argind >= argc) { usageError(); } logSpec = argv[++argind]; } else if (smatch(argp, "--name") || smatch(argp, "-n")) { if (argind >= argc) { usageError(); } mprSetAppName(argv[++argind], 0, 0); } else if (smatch(argp, "--show") || smatch(argp, "-s")) { app->show = 1; } else if (smatch(argp, "--trace") || smatch(argp, "-t")) { if (argind >= argc) { usageError(); } traceSpec = argv[++argind]; } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) { if (!logSpec) { logSpec = sfmt("stderr:2"); } if (!traceSpec) { traceSpec = sfmt("stderr:2"); } } else if (smatch(argp, "--version") || smatch(argp, "-V")) { mprPrintf("%s\n", ME_VERSION); exit(0); } else if (*argp == '-' && isdigit((uchar) argp[1])) { if (!logSpec) { logSpec = sfmt("stderr:%d", (int) stoi(&argp[1])); } if (!traceSpec) { traceSpec = sfmt("stderr:%d", (int) stoi(&argp[1])); } } else if (smatch(argp, "-?") || scontains(argp, "-help")) { usageError(); exit(3); } else if (*argp == '-') { mprLog("error http", 0, "Unknown switch \"%s\"", argp); usageError(); exit(4); } } if (logSpec) { mprStartLogging(logSpec, MPR_LOG_CMDLINE); } if (traceSpec) { httpStartTracing(traceSpec); } if (mprStart() < 0) { mprLog("error http", 0, "Cannot start MPR"); mprDestroy(); return MPR_ERR_CANT_INITIALIZE; } if (argc == argind && !app->configFile) { if (findConfig() < 0) { exit(5); } } if (createEndpoints(argc - argind, &argv[argind]) < 0) { return MPR_ERR_CANT_INITIALIZE; } if (httpStartEndpoints() < 0) { mprLog("error http", 0, "Cannot start HTTP service, exiting."); exit(6); } if (app->show) { httpLogRoutes(0, 0); } mprServiceEvents(-1, 0); mprLog("info http", 1, "Stopping http-server ..."); mprDestroy(); return mprGetExitStatus(); }
/* * Get the current working directory * * function get dir(): Path */ static EjsVar *currentDir(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv) { return (EjsVar*) ejsCreatePathAndFree(ejs, mprGetCurrentPath(ejs)); }
static int startProcess(MprCmd *cmd) { MprCmdFile *files; int rc, i, err; files = cmd->files; /* * Create the child */ cmd->pid = vfork(); if (cmd->pid < 0) { mprError(cmd, "start: can't fork a new process to run %s, errno %d", cmd->program, mprGetOsError()); return MPR_ERR_CANT_INITIALIZE; } else if (cmd->pid == 0) { /* * Child */ umask(022); if (cmd->flags & MPR_CMD_NEW_SESSION) { setsid(); } if (cmd->dir) { if (chdir(cmd->dir) < 0) { mprLog(cmd, 0, "cmd: Can't change directory to %s", cmd->dir); return MPR_ERR_CANT_INITIALIZE; } } if (cmd->flags & MPR_CMD_IN) { if (files[MPR_CMD_STDIN].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDIN].clientFd, 0); close(files[MPR_CMD_STDIN].fd); } else { close(0); } } if (cmd->flags & MPR_CMD_OUT) { if (files[MPR_CMD_STDOUT].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDOUT].clientFd, 1); close(files[MPR_CMD_STDOUT].fd); } else { close(1); } } if (cmd->flags & MPR_CMD_ERR) { if (files[MPR_CMD_STDERR].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDERR].clientFd, 2); close(files[MPR_CMD_STDERR].fd); } else { close(2); } } cmd->forkCallback(cmd->forkData); if (cmd->env) { rc = execve(cmd->program, cmd->argv, fixenv(cmd)); } else { rc = execv(cmd->program, cmd->argv); } err = errno; mprPrintfError(cmd, "Can't exec %s, err %d, cwd %s\n", cmd->program, err, mprGetCurrentPath(cmd)); /* * Use _exit to avoid flushing I/O any other I/O. */ _exit(-(MPR_ERR_CANT_INITIALIZE)); } else { /* * Close the client handles */ for (i = 0; i < MPR_CMD_MAX_PIPE; i++) { if (files[i].clientFd >= 0) { close(files[i].clientFd); files[i].clientFd = -1; } } } rc = 0; return rc; }
PUBLIC int mprLoadNativeModule(MprModule *mp) { MprModuleEntry fn; void *handle; assert(mp); if ((handle = (HANDLE) MPR->appInstance) == 0) { handle = GetModuleHandle(NULL); } if (!handle || !mp->entry || !GetProcAddress(handle, mp->entry)) { #if ME_STATIC mprLog("error mpr", 0, "Cannot load module %s, product built static", mp->name); return MPR_ERR_BAD_STATE; #else MprPath info; char *at, *baseName; if ((at = mprSearchForModule(mp->path)) == 0) { mprLog("error mpr", 0, "Cannot find module \"%s\", cwd=\"%s\", search=\"%s\"", mp->path, mprGetCurrentPath(), mprGetModuleSearchPath()); return MPR_ERR_CANT_ACCESS; } mp->path = at; mprGetPathInfo(mp->path, &info); mp->modified = info.mtime; baseName = mprGetPathBase(mp->path); mprLog("info mpr", 4, "Loading native module %s", baseName); if ((handle = LoadLibrary(wide(mp->path))) == 0) { mprLog("error mpr", 0, "Cannot load module %s, errno=\"%d\"", mp->path, mprGetOsError()); return MPR_ERR_CANT_READ; } mp->handle = handle; #endif /* !ME_STATIC */ } else if (mp->entry) { mprLog("info mpr", 4, "Activating native module %s", mp->name); } if (mp->entry) { if ((fn = (MprModuleEntry) GetProcAddress((HINSTANCE) handle, mp->entry)) == 0) { mprLog("error mpr", 0, "Cannot load module %s, cannot find function \"%s\"", mp->name, mp->entry); FreeLibrary((HINSTANCE) handle); return MPR_ERR_CANT_ACCESS; } if ((fn)(mp->moduleData, mp) < 0) { mprLog("error mpr", 0, "Initialization for module %s failed", mp->name); FreeLibrary((HINSTANCE) handle); return MPR_ERR_CANT_INITIALIZE; } } return 0; }