/* If ME_CONFIG_FILE is defined, use that as the base name for appweb.conf. Otherwise, use "programName.conf". Search order is: "."/BASE ME_SERVER_ROOT/BASE EXE/../BASE EXE/../appweb.conf */ static int findAppwebConf() { char *base, *filename; if (ME_CONFIG_FILE) { base = sclone(ME_CONFIG_FILE); } else { base = mprJoinPathExt(mprGetAppName(), ".conf"); } #if !ME_ROM filename = base; if (!mprPathExists(filename, R_OK)) { filename = mprJoinPath(app->home, base); if (!mprPathExists(filename, R_OK)) { filename = mprJoinPath(mprGetPathParent(mprGetAppDir()), base); if (!mprPathExists(filename, R_OK)) { filename = mprJoinPath(mprGetPathParent(mprGetAppDir()), "appweb.conf"); if (!mprPathExists(filename, R_OK)) { mprError("Cannot find config file %s", base); return MPR_ERR_CANT_OPEN; } } } } #endif app->configFile = filename; return 0; }
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 int findConfig() { char *base, *filename; base = sclone("http.json"); filename = base; if (!mprPathExists(filename, R_OK)) { filename = mprJoinPath(mprGetPathParent(mprGetAppDir()), base); if (!mprPathExists(filename, R_OK)) { filename = mprJoinPath(mprGetPathParent(mprGetAppDir()), base); if (!mprPathExists(filename, R_OK)) { mprError("Cannot find config file %s", base); return MPR_ERR_CANT_OPEN; } } } app->configFile = filename; return 0; }
static char *getSearchPath(cchar *dir) { #if WIN // bin : . return sfmt("%s" MPR_SEARCH_SEP ".", dir); #else // bin : /usr/lib/appweb/bin : /usr/lib/appweb/lib : lib : . char *libDir = mprJoinPath(mprGetPathParent(dir), BLD_LIB_NAME); return sfmt("%s" MPR_SEARCH_SEP "%s" MPR_SEARCH_SEP ".", dir, mprSamePath(BLD_BIN_PREFIX, dir) ? BLD_LIB_PREFIX: libDir); #endif }
static bool installService() { SC_HANDLE svc, mgr; char cmd[MPR_MAX_FNAME], key[MPR_MAX_FNAME]; int serviceType; mgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (! mgr) { mprUserError("Can't open service manager"); return 0; } /* Install this app as a service */ svc = OpenService(mgr, app->serviceName, SERVICE_ALL_ACCESS); if (svc == NULL) { serviceType = SERVICE_WIN32_OWN_PROCESS; if (app->createConsole) { serviceType |= SERVICE_INTERACTIVE_PROCESS; } GetModuleFileName(0, cmd, sizeof(cmd)); svc = CreateService(mgr, app->serviceName, app->serviceTitle, SERVICE_ALL_ACCESS, serviceType, SERVICE_DISABLED, SERVICE_ERROR_NORMAL, cmd, NULL, NULL, "", NULL, NULL); if (! svc) { mprUserError("Can't create service: 0x%x == %d", GetLastError(), GetLastError()); CloseServiceHandle(mgr); return 0; } } CloseServiceHandle(svc); CloseServiceHandle(mgr); /* Write a service description */ mprSprintf(key, sizeof(key), "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\" "Services\\%s", app->serviceName); if (mprWriteRegistry(key, "Description", SERVICE_DESCRIPTION) < 0) { return 0; } /* Write the home directory */ if (app->serviceHome == 0) { app->serviceHome = mprGetPathParent(mprGetAppDir()); } if (mprWriteRegistry(key, "HomeDir", app->serviceHome) < 0) { return 0; } /* Write the service args */ if (app->serviceArgs && *app->serviceArgs) { if (mprWriteRegistry(key, "Args", app->serviceArgs) < 0) { return 0; } } return 1; }
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; }
/* Tokens: ARCH Build architecture (x86_64) CC Compiler (cc) DEBUG Debug compilation options (-g, -Zi -Od) INC Include directory out/inc LIB Library directory (out/lib, xcode/VS: out/bin) LIBS Libraries required to link with ESP OBJ Name of compiled source (out/lib/view-MD5.o) OUT Output module (view_MD5.dylib) SHLIB Host Shared library (.lib, .so) SHOBJ Host Shared Object (.dll, .so) SRC Source code for view or controller (already templated) TMP Temp directory VS Visual Studio directory WINSDK Windows SDK directory */ char *espExpandCommand(cchar *command, cchar *source, cchar *module) { MprBuf *buf; MaAppweb *appweb; cchar *cp, *out; char *tmp; #if BLD_WIN_LIKE cchar *path; path = 0; #endif if (command == 0) { return 0; } out = mprTrimPathExt(module); buf = mprCreateBuf(-1, -1); appweb = MPR->appwebService; for (cp = command; *cp; ) { if (*cp == '$') { if (matchToken(&cp, "${ARCH}")) { /* Build architecture */ mprPutStringToBuf(buf, appweb->hostArch); #if BLD_WIN_LIKE } else if (matchToken(&cp, "${WINSDK}")) { path = mprReadRegistry("HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows", "CurrentInstallFolder"); path = strim(path, "\\", MPR_TRIM_END); mprPutStringToBuf(buf, path); } else if (matchToken(&cp, "${VS}")) { path = mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))); mprPutStringToBuf(buf, mprGetPortablePath(path)); #endif } else if (matchToken(&cp, "${CC}")) { /* Compiler */ #if BLD_WIN_LIKE // MOB - what about cross compilation path = mprJoinPath(mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))), "VC/bin/cl.exe"); mprPutStringToBuf(buf, mprGetPortablePath(path)); #else mprPutStringToBuf(buf, BLD_CC); #endif } else if (matchToken(&cp, "${DEBUG}")) { mprPutStringToBuf(buf, ESP_DEBUG); } else if (matchToken(&cp, "${INC}")) { /* Include directory (out/inc) */ mprPutStringToBuf(buf, mprResolvePath(mprGetAppDir(), "inc")); } else if (matchToken(&cp, "${LIB}")) { /* Library directory. IDE's use bin dir */ mprPutStringToBuf(buf, getOutDir(BLD_LIB_NAME)); } else if (matchToken(&cp, "${LIBS}")) { /* Required libraries to link. These may have nested ${TOKENS} */ mprPutStringToBuf(buf, espExpandCommand(ESP_LIBS, source, module)); } else if (matchToken(&cp, "${OBJ}")) { /* Output object with extension (.o) */ mprPutStringToBuf(buf, mprJoinPathExt(out, BLD_OBJ)); } else if (matchToken(&cp, "${OUT}")) { /* Output modules */ mprPutStringToBuf(buf, out); } else if (matchToken(&cp, "${SHLIB}")) { /* .lib */ mprPutStringToBuf(buf, appweb->hostOs); } else if (matchToken(&cp, "${SHOBJ}")) { /* .dll */ #ifdef BLD_HOST_SHOBJ // MOB - need this for bit mprPutStringToBuf(buf, BLD_HOST_SHOBJ); #else mprPutStringToBuf(buf, BLD_SHOBJ); #endif } else if (matchToken(&cp, "${SRC}")) { /* View (already parsed into C code) or controller source */ mprPutStringToBuf(buf, source); } else if (matchToken(&cp, "${TMP}")) { #if BLD_WIN_LIKE if ((tmp = getenv("TMP")) == 0) { tmp = getenv("TEMP"); } #else tmp = getenv("TMPDIR"); #endif mprPutStringToBuf(buf, tmp ? tmp : "."); #ifdef WIND_BASE } else if (matchToken(&cp, "${WIND_BASE}")) { mprPutStringToBuf(buf, WIND_BASE); #endif #ifdef WIND_HOME } else if (matchToken(&cp, "${WIND_HOME}")) { mprPutStringToBuf(buf, WIND_HOME); #endif #ifdef WIND_HOST_TYPE } else if (matchToken(&cp, "${WIND_HOST_TYPE}")) { mprPutStringToBuf(buf, WIND_HOST_TYPE); #endif #ifdef WIND_PLATFORM } else if (matchToken(&cp, "${WIND_PLATFORM}")) { mprPutStringToBuf(buf, WIND_PLATFORM); #endif #ifdef WIND_GNU_PATH } else if (matchToken(&cp, "${WIND_GNU_PATH}")) { mprPutStringToBuf(buf, WIND_GNU_PATH); #endif } else { mprPutCharToBuf(buf, *cp++); } } else { mprPutCharToBuf(buf, *cp++); } } mprAddNullToBuf(buf); return sclone(mprGetBufStart(buf)); }