void ejsLexRestoreInputState(Ejs *ep, EjsInput *state) { EjsInput *ip; int i; mprAssert(ep); mprAssert(state); ip = ep->input; mprAssert(ip); ip->tokbuf = state->tokbuf; ip->tokServp = state->tokServp; ip->tokEndp = state->tokEndp; ip->tokSize = state->tokSize; ip->script = state->script; ip->scriptServp = state->scriptServp; ip->scriptSize = state->scriptSize; ip->putBackIndex = state->putBackIndex; for (i = 0; i < ip->putBackIndex; i++) { mprFree(ip->putBack[i].token); ip->putBack[i].id = state->putBack[i].id; ip->putBack[i].token = mprStrdup(state->putBack[i].token); } mprFree(ip->line); ip->line = mprMalloc(state->lineLength); mprStrcpy(ip->line, state->lineLength, state->line); ip->lineColumn = state->lineColumn; ip->lineNumber = state->lineNumber; ip->lineLength = state->lineLength; }
int MprBuf::grow() { uchar *newbuf; if (maxsize >= 0 && buflen >= maxsize) { return 0; } if (growBy < 0) { // // User supplied buffer // return 0; } newbuf = (uchar*) mprMalloc(buflen + growBy); if (buf) { memcpy(newbuf, buf, buflen); mprFree(buf); } buflen += growBy; end = newbuf + (end - buf); start = newbuf + (start - buf); buf = newbuf; endbuf = &buf[buflen]; // // Increase growBy to reduce overhead // growBy *= 2; return 1; }
void ejsLexSaveInputState(Ejs *ep, EjsInput *state) { EjsInput *ip; int i; mprAssert(ep); ip = ep->input; mprAssert(ip); *state = *ip; for (i = 0; i < ip->putBackIndex; i++) { state->putBack[i].token = mprStrdup(ip->putBack[i].token); state->putBack[i].id = ip->putBack[i].id; } for (; i < EJS_TOKEN_STACK; i++) { state->putBack[i].token = 0; } state->line = mprMalloc(ip->lineLength); mprStrcpy(state->line, ip->lineLength, ip->line); state->lineColumn = ip->lineColumn; state->lineNumber = ip->lineNumber; state->lineLength = ip->lineLength; }
static DynLock *sslCreateDynLock(const char *file, int line) { DynLock *dl; dl = (DynLock*) mprMalloc(sizeof(DynLock)); dl->mutex = new MprMutex(); return dl; }
int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt, va_list args) { char *buf; int count; buf = mprMalloc(maxSize + 1); count = mtVsprintf(buf, maxSize, fmt, args); *msgbuf = buf; return count; }
MprArray *mprCreateArray() { MprArray *array; int size; array = (MprArray*) mprMalloc(sizeof(MprArray)); if (array == 0) { return 0; } memset(array, 0, sizeof(MprArray)); size = MPR_ARRAY_INCR * sizeof(void*); array->handles = (void**) mprMalloc(size); if (array->handles == 0) { mprFree(array); return 0; } memset(array->handles, 0, size); array->max = MPR_ARRAY_INCR; array->used = 0; return array; }
int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...) { va_list args; char *buf; int count; va_start(args, fmt); buf = mprMalloc(maxSize + 1); count = mtVsprintf(buf, maxSize, fmt, args); *msgbuf = buf; va_end(args); return count; }
//////////////////////////////////////////////////////////////////////////////// // // This is called from Http::start after all the modules are loaded. // The code here is global for this handler and is not required per handler // instance. // int MaOpenSslModule::start() { RandBuf randBuf; static int once = 0; // // Depending on the order in the configuration file, we will get called // by the module mechanism and by OpenSslConfig::start(). But we only // want to run once. // if (once++ > 0) { return 0; } randBuf.pid = getpid(); randBuf.time = (int) time(0); randBuf.msec = (int) mprGetTime(0); RAND_seed((void*) &randBuf, sizeof(randBuf)); #if SOLARIS || LINUX || MACOSX || FREEBSD mprLog(6, "OpenSsl: Before calling RAND_load_file\n"); RAND_load_file("/dev/urandom", 256); mprLog(6, "OpenSsl: After calling RAND_load_file\n"); #endif #if BLD_FEATURE_MULTITHREAD numLocks = CRYPTO_num_locks(); locks = (MprMutex**) mprMalloc(numLocks * sizeof(MprMutex*)); for (int i = 0; i < numLocks; i++) { locks[i] = new MprMutex(); } CRYPTO_set_id_callback(sslThreadId); CRYPTO_set_locking_callback(sslStaticLock); CRYPTO_set_dynlock_create_callback(sslCreateDynLock); CRYPTO_set_dynlock_destroy_callback(sslDestroyDynLock); CRYPTO_set_dynlock_lock_callback(sslDynLock); #endif #if WIN // _fmode=_O_BINARY; // CRYPTO_malloc_init(); // SSLC_add_all_algorithms(); #else OpenSSL_add_all_algorithms(); #endif SSL_library_init(); return 0; }
int ejsLexOpenScript(Ejs *ep, char *script) { EjsInput *ip; mprAssert(ep); mprAssert(script); if ((ip = mprMalloc(sizeof(EjsInput))) == NULL) { return -1; } memset(ip, 0, sizeof(*ip)); ip->next = ep->input; ep->input = ip; ip->procName = ep->proc?ep->proc->procName:NULL; /* * Create the parse token buffer and script buffer */ ip->tokbuf = mprMalloc(EJS_PARSE_INCR); ip->tokSize = EJS_PARSE_INCR; ip->tokServp = ip->tokbuf; ip->tokEndp = ip->tokbuf; ip->script = mprStrdup(script); ip->scriptSize = strlen(script); ip->scriptServp = ip->script; ip->lineNumber = 1; ip->lineLength = 0; ip->lineColumn = 0; ip->line = NULL; ip->putBackIndex = -1; return 0; }
void MprBuf::setBuf(int initialSize, int max) { mprAssert(initialSize > 0); if (buf && growBy > 0) { mprFree(buf); } buf = (uchar*) mprMalloc(initialSize); growBy = initialSize; maxsize = max; buflen = initialSize; endbuf = &buf[buflen]; start = buf; end = buf; *start = '\0'; }
int mprReadRegistry(char *key, char *name, char **buf, int max) { HKEY top, h; char *value; ulong type, size; mprAssert(key && *key); mprAssert(buf); // // Get the registry hive // if ((key = getHive(key, &top)) == 0) { return MPR_ERR_CANT_ACCESS; } if (RegOpenKeyEx(top, key, 0, KEY_READ, &h) != ERROR_SUCCESS) { return MPR_ERR_CANT_ACCESS; } // // Get the type // if (RegQueryValueEx(h, name, 0, &type, 0, &size) != ERROR_SUCCESS) { RegCloseKey(h); return MPR_ERR_CANT_READ; } if (type != REG_SZ && type != REG_EXPAND_SZ) { RegCloseKey(h); return MPR_ERR_BAD_TYPE; } value = (char*) mprMalloc(size); if ((int) size > max) { RegCloseKey(h); return MPR_ERR_WONT_FIT; } if (RegQueryValueEx(h, name, 0, &type, (uchar*) value, &size) != ERROR_SUCCESS) { delete value; RegCloseKey(h); return MPR_ERR_CANT_READ; } RegCloseKey(h); *buf = value; return 0; }
int MprCmd::start(char *program, char **argv, char **envp, MprCmdProc completionFn, void *fnData, int userFlags) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo; char dirBuf[MPR_MAX_FNAME], *systemRoot; char *envBuf, **ep, *cmdBuf, **ap, *destp, *cp, *dir, *key; char progBuf[MPR_MAX_STRING], *localArgv[2], *saveArg0; int argc, len, inheritFiles; mprAssert(program); mprAssert(argv); reset(); flags |= (userFlags & MPR_CMD_USER_FLAGS); exitStatus = -1; mprStrcpy(progBuf, sizeof(progBuf), program); progBuf[sizeof(progBuf) - 1] = '\0'; program = progBuf; // // Sanitize the command line (program name only) // for (cp = program; *cp; cp++) { if (*cp == '/') { *cp = '\\'; } else if (*cp == '\r' || *cp == '\n') { *cp = ' '; } } if (*program == '"') { if ((cp = strrchr(++program, '"')) != 0) { *cp = '\0'; } } saveArg0 = argv[0]; if (argv == 0) { argv = localArgv; argv[1] = 0; } argv[0] = program; // // Determine the command line length and arg count // argc = 0; for (len = 0, ap = argv; *ap; ap++) { len += strlen(*ap) + 1 + 2; // Space and possible quotes argc++; } cmdBuf = (char*) mprMalloc(len + 1); cmdBuf[len] = '\0'; // // Add quotes to all args that have spaces in them including "program" // destp = cmdBuf; for (ap = &argv[0]; *ap; ) { cp = *ap; if ((strchr(cp, ' ') != 0) && cp[0] != '\"') { *destp++ = '\"'; strcpy(destp, cp); destp += strlen(cp); *destp++ = '\"'; } else { strcpy(destp, cp); destp += strlen(cp); } if (*++ap) { *destp++ = ' '; } } *destp = '\0'; mprAssert((int) strlen(destp) < (len - 1)); mprAssert(cmdBuf[len] == '\0'); argv[0] = saveArg0; envBuf = 0; if (envp) { for (len = 0, ep = envp; *ep; ep++) { len += strlen(*ep) + 1; } key = "SYSTEMROOT"; systemRoot = getenv(key); if (systemRoot) { len += strlen(key) + 1 + strlen(systemRoot) + 1; } envBuf = (char*) mprMalloc(len + 2); // Win requires two nulls destp = envBuf; for (ep = envp; *ep; ep++) { strcpy(destp, *ep); mprLog(6, log, "Set CGI variable: %s\n", destp); destp += strlen(*ep) + 1; } strcpy(destp, key); destp += strlen(key); *destp++ = '='; strcpy(destp, systemRoot); destp += strlen(systemRoot) + 1; *destp++ = '\0'; *destp++ = '\0'; // WIN requires two nulls } memset(&startInfo, 0, sizeof(startInfo)); startInfo.cb = sizeof(startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; if (flags & MPR_CMD_SHOW) { startInfo.wShowWindow = SW_SHOW; } else { startInfo.wShowWindow = SW_HIDE; } // // CMD_OUT is stdin for the client. CMD_IN is stdout for the client // if (files.clientFd[MPR_CMD_OUT] > 0) { startInfo.hStdInput = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_OUT]); } if (files.clientFd[MPR_CMD_IN] > 0) { startInfo.hStdOutput = (HANDLE)_get_osfhandle(files.clientFd[MPR_CMD_IN]); } #if UNUSED if (files.clientFd[MPR_CMD_ERR] > 0) { startInfo.hStdError = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_ERR]); } #endif #if UNUSED SECURITY_ATTRIBUTES secAtt; memset(&secAtt, 0, sizeof(secAtt)); secAtt.nLength = sizeof(SECURITY_ATTRIBUTES); secAtt.bInheritHandle = TRUE; #endif if (userFlags & MPR_CMD_CHDIR) { if (cwd) { dir = cwd; } else { mprGetDirName(dirBuf, sizeof(dirBuf), argv[0]); dir = dirBuf; } } else { dir = 0; } inheritFiles = (flags & MPR_CMD_STDIO_MADE) ? 1 : 0; flags &= ~(MPR_CMD_STDIO_MADE); mprLog(5, log, "Running: %s\n", cmdBuf); if (! CreateProcess(0, cmdBuf, 0, 0, inheritFiles, CREATE_NEW_CONSOLE, envBuf, dir, &startInfo, &procInfo)) { mprError(MPR_L, MPR_LOG, "Can't create process: %s, %d", cmdBuf, mprGetOsError()); return MPR_ERR_CANT_CREATE; } process = (int) procInfo.hProcess; // // Wait for the child to initialize // WaitForInputIdle((HANDLE) process, 1000); if (procInfo.hThread != 0) { CloseHandle(procInfo.hThread); } mprFree(cmdBuf); mprFree(envBuf); cmdDoneProc = completionFn; data = fnData; if (flags & MPR_CMD_DETACHED) { CloseHandle((HANDLE) process); process = 0; } else if (userFlags & MPR_CMD_WAIT) { waitForChild(INT_MAX); if (getExitCode() < 0) { return MPR_ERR_BAD_STATE; } return exitStatus; } else { mprGetMpr()->cmdService->startWatcher(); } return 0; }
static int mprCoreStrcat(int alloc, char **destp, int destMax, int existingLen, const char *delim, const char *src, va_list args) { va_list ap; char *dest, *dp; const char *str; int sepLen, addBytes, required; mprAssert(destp); mprAssert(destMax > 0); mprAssert(src); dest = *destp; sepLen = (delim) ? strlen(delim) : 0; va_copy(ap, args); addBytes = 0; str = src; while (str) { addBytes += strlen(str) + sepLen; str = va_arg(ap, const char*); } va_end(ap); if (existingLen > 0) { addBytes += sepLen; } required = existingLen + addBytes + 1; if (required >= destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (alloc) { if (dest == 0) { dest = (char*) mprMalloc(required); } else { dest = (char*) mprRealloc(dest, required); } } else { dest = (char*) *destp; } dp = &dest[existingLen]; if (delim) { strcpy(dp, delim); dp += sepLen; } if (addBytes > 0) { va_copy(ap, args); str = src; while (str) { strcpy(dp, str); dp += strlen(str); str = va_arg(ap, char*); if (delim && str) { strcpy(dp, delim); dp += sepLen; } } va_end(ap); } else if (dest == 0) {
int MaCgiHandler::run(MaRequest *rq) { MprVar *vp, *variables; char **argv, **envv, **ep, *fileName, *baseName; int i, index, argc, numItems; if (rq->getFlags() & MPR_HTTP_POST_REQUEST && rq->getRemainingContent() > 0) { // // When all the post data is received the run method will be recalled // by the postData method. // return MPR_HTTP_HANDLER_FINISHED_PROCESSING; } argv = 0; variables = 0; argc = 0; hitCount++; rq->setResponseCode(200); rq->setHeaderFlags(MPR_HTTP_DONT_CACHE, 0); rq->insertDataStream(rq->getDynBuf()); // // Build the commmand line arguments // argc = 1; // argv[0] == programName buildArgs(&argc, &argv, cmd, rq); fileName = argv[0]; rq->setResponseMimeType("text/html"); baseName = mprGetBaseName(fileName); if (strncmp(baseName, "nph-", 4) == 0) { cgiFlags |= MPR_CGI_NON_PARSED_HEADER; } if (strlen(baseName) > 4 && strcmp(&baseName[strlen(baseName) - 4], "-nph") == 0) { cgiFlags |= MPR_CGI_NON_PARSED_HEADER; } // // Build environment variables // variables = rq->getVariables(); numItems = rq->getNumEnvProperties() + 1; // // Export the PATH and LD_LIBRARY_PATH also if Unix // #if BLD_HOST_UNIX numItems += 2; #endif envv = (char**) mprMalloc((numItems + 1) * sizeof(char*)); index = 0; for (i = 0; i < MA_HTTP_OBJ_MAX; i++) { if (variables[i].type == MPR_TYPE_OBJECT) { vp = mprGetFirstProperty(&variables[i], MPR_ENUM_DATA); while (vp) { mprAllocSprintf(&envv[index], MPR_HTTP_MAX_HEADER, "%s=%s", vp->name, vp->string); index++; vp = mprGetNextProperty(&variables[i], vp, MPR_ENUM_DATA); } } } #if BLD_HOST_UNIX { char *cp; if ((cp = getenv("PATH")) != 0) { mprAllocSprintf(&envv[index++], MPR_MAX_FNAME, "PATH=%s", cp); } if ((cp = getenv("LD_LIBRARY_PATH")) != 0) { mprAllocSprintf(&envv[index++], MPR_MAX_FNAME, "LD_LIBRARY_PATH=%s", cp); } } #endif mprAllocSprintf(&envv[index++], MPR_MAX_FNAME, "REDIRECT_STATUS=302"); envv[index] = 0; mprAssert(index <= numItems); mprLog(4, log, "%d: running program: %s\n", rq->getFd(), fileName); if (cmd->start(fileName, argv, envv, cgiOutputData, (void*) rq, MPR_CMD_CHDIR) < 0) { rq->requestError(503, "Can't run CGI process: %s, URI %s", rq->getScriptName(), rq->getOriginalUri()); rq->finishRequest(); goto exit; } exit: for (i = 0; i < argc; i++) { mprFree(argv[i]); } for (ep = envv; *ep; ep++) { mprFree(*ep); } mprFree(argv); mprFree(envv); return MPR_HTTP_HANDLER_FINISHED_PROCESSING; }
// // Algorithm originally in the GoAhead WebServer. // int MaUrl::parse(char *url) { char *tok, *cp, *portStr, *last_delim, *hostbuf, *portbuf; char *htmlExt = "html"; int c, len, ulen; mprAssert(url && *url); if (parsedUrlBuf) { mprFree(parsedUrlBuf); } ulen = strlen(url); // // Allocate a single buffer to hold all the cracked fields. // Store host, port and url strings (3 nulls). // len = ulen * 2 + MAX_PORT_LEN + 3; parsedUrlBuf = (char*) mprMalloc(len * sizeof(char)); portbuf = &parsedUrlBuf[len - MAX_PORT_LEN - 1]; hostbuf = &parsedUrlBuf[ulen+1]; strcpy(parsedUrlBuf, url); url = parsedUrlBuf; // // Defaults for missing ULR fields // strcpy(portbuf, "80"); portStr = portbuf; uri = "/"; proto = "http"; host = "localhost"; query = ""; ext = htmlExt; if (strncmp(url, "http://", 7) == 0) { tok = &url[7]; tok[-3] = '\0'; proto = url; host = tok; for (cp = tok; *cp; cp++) { if (*cp == '/') { break; } if (*cp == ':') { *cp++ = '\0'; portStr = cp; tok = cp; } } if ((cp = strchr(tok, '/')) != NULL) { c = *cp; *cp = '\0'; mprStrcpy(hostbuf, ulen + 1, host); mprStrcpy(portbuf, MAX_PORT_LEN, portStr); *cp = c; host = hostbuf; portStr = portbuf; uri = cp; tok = cp; } } else { uri = url; tok = url; } // // Split off the query string. // if ((cp = strchr(tok, '?')) != NULL) { *cp++ = '\0'; query = cp; uri = tok; tok = query; } // // Split off fragment identifier. // if ((cp = strchr(tok, '#')) != NULL) { *cp++ = '\0'; if (*query == 0) { uri = tok; } } // // FUTURE -- this logic could be improved // if ((cp = strrchr(uri, '.')) != NULL) { if ((last_delim = strrchr(uri, '/')) != NULL) { if (last_delim > cp) { ext = htmlExt; } else { ext = cp + 1; #if WIN mprStrLower(ext); #endif } } else { ext = cp + 1; #if WIN mprStrLower(ext); #endif } } else { if (uri[strlen(uri) - 1] == '/') { ext = htmlExt; } } port = atoi(portStr); return 0; }
struct hostent *mprGetHostByName(char *name) { Mpr *mpr; struct hostent *hp; mpr = mprGetMpr(); hp = new hostent; memset(hp, 0, sizeof(struct hostent)); mpr->lock(); #if VXWORKS struct in_addr inaddr; inaddr.s_addr = (ulong) hostGetByName(name); if (inaddr.s_addr < 0) { mpr->unlock(); mprAssert(0); return 0; } hp->h_addrtype = AF_INET; hp->h_length = sizeof(int); hp->h_name = mprStrdup(name); hp->h_addr_list = 0; hp->h_aliases = 0; hp->h_addr_list = new char*[2]; hp->h_addr_list[0] = (char *) mprMalloc(sizeof(struct in_addr)); memcpy(&hp->h_addr_list[0], &inaddr, hp->h_length); hp->h_addr_list[1] = 0; #else struct hostent *ip; int count, i; #undef gethostbyname ip = gethostbyname(name); if (ip == 0) { mpr->unlock(); return 0; } hp->h_addrtype = ip->h_addrtype; hp->h_length = ip->h_length; hp->h_name = mprStrdup(ip->h_name); hp->h_addr_list = 0; hp->h_aliases = 0; for (count = 0; ip->h_addr_list[count] != 0; ) { count++; } if (count > 0) { count++; hp->h_addr_list = new char*[count]; for (i = 0; ip->h_addr_list[i] != 0; i++) { memcpy(&hp->h_addr_list[i], &ip->h_addr_list[i], ip->h_length); } hp->h_addr_list[i] = 0; } for (count = 0; ip->h_aliases[count] != 0; ) { count++; } if (count > 0) { count++; hp->h_aliases = new char*[count]; for (i = 0; ip->h_aliases[i] != 0; i++) { hp->h_aliases[i] = mprStrdup(ip->h_aliases[i]); } hp->h_aliases[i] = 0; } #endif mpr->unlock(); return hp; }
EspRequest *espCreateRequest(EspHandle webServerRequestHandle, char *uri, MprVar *variables) { EspRequest *ep; MprVar *global; #if BLD_FEATURE_LEGACY_API MprVar *np; char keyBuf[ESP_MAX_HEADER]; int i; #endif mprAssert(variables); ep = (EspRequest*)mprMalloc(sizeof(EspRequest)); if (ep == 0) { return 0; } memset(ep, 0, sizeof(EspRequest)); ep->requestHandle = webServerRequestHandle; ep->esp = esp; ep->uri = mprStrdup(uri); ep->docPath = 0; ep->variables = variables; /* * The handle passed to ejsOpenEngine is passed to every C function * called by JavaScript. */ ep->eid = ejsOpenEngine((EjsHandle) ep, (EjsHandle) webServerRequestHandle); if (ep->eid < 0) { mprFree(ep); return 0; } /* * All these copies and SetProperties will only copy references * They will increments the object ref counts. */ mprCopyVar(&variables[ESP_GLOBAL_OBJ], ejsGetGlobalObject(ep->eid), MPR_SHALLOW_COPY); mprCopyVar(&variables[ESP_LOCAL_OBJ], ejsGetLocalObject(ep->eid), MPR_SHALLOW_COPY); global = &variables[ESP_GLOBAL_OBJ]; mprCreateProperty(global, "application", &variables[ESP_APPLICATION_OBJ]); mprCreateProperty(global, "cookies", &variables[ESP_COOKIES_OBJ]); mprCreateProperty(global, "files", &variables[ESP_FILES_OBJ]); mprCreateProperty(global, "form", &variables[ESP_FORM_OBJ]); mprCreateProperty(global, "headers", &variables[ESP_HEADERS_OBJ]); mprCreateProperty(global, "request", &variables[ESP_REQUEST_OBJ]); // // FUTURE -- could server be shared across all requests for a given host // and be made read-only. // mprCreateProperty(global, "server", &variables[ESP_SERVER_OBJ]); #if BLD_FEATURE_SESSION mprCreateProperty(global, "session", &variables[ESP_SESSION_OBJ]); #endif #if BLD_FEATURE_LEGACY_API /* * DEPRECATED: 2.0 * Define variables as globals. headers[] are prefixed with "HTTP_". * NOTE: MaRequest::setVar does not copy into globals, whereas espSetVar * does if legacy_api is defined. So variables pre-defined by MaRequest * must be copied here into globals[]. * * NOTE: if a variable is in session[] and in form[], the form[] will * override being later in the variables[] list. Use mprSetProperty * instead of mprCreateProperty to cover for this case. */ for (i = 0; i < ESP_OBJ_MAX; i++) { if (i == ESP_GLOBAL_OBJ || i == ESP_LOCAL_OBJ) { continue; } if (variables[i].type != MPR_TYPE_OBJECT) { continue; } np = mprGetFirstProperty(&variables[i], MPR_ENUM_DATA); while (np) { if (i == ESP_HEADERS_OBJ) { mprSprintf(keyBuf, sizeof(keyBuf) - 1, "HTTP_%s", np->name); mprSetProperty(global, keyBuf, np); } else { mprSetProperty(global, np->name, np); } np = mprGetNextProperty(&variables[i], np, MPR_ENUM_DATA); } } #endif return ep; }
static int buildScript(EspRequest *ep, char **jsBuf, char *input, char **errMsg) { EspParse parse; char path[MPR_MAX_FNAME], dir[MPR_MAX_FNAME], incPath[MPR_MAX_FNAME]; char *incBuf, *incText; int state, tid, len, rc, maxScriptSize, incSize; mprAssert(ep); mprAssert(jsBuf); mprAssert(input); rc = 0; len = 0; state = ESP_STATE_BEGIN; if (errMsg) { *errMsg = 0; } memset(&parse, 0, sizeof(parse)); parse.token = (char*) mprMalloc(ESP_TOK_INCR); if (parse.token == 0) { return MPR_ERR_CANT_ALLOCATE; } parse.token[0] = '\0'; parse.tokLen = ESP_TOK_INCR; parse.endp = &parse.token[parse.tokLen - 1]; parse.tokp = parse.token; parse.inBuf = input; parse.inp = parse.inBuf; maxScriptSize = esp->maxScriptSize; tid = getEspToken(state, &parse); while (tid != ESP_TOK_EOF && len >= 0) { switch (tid) { default: case ESP_TOK_ERR: mprFree(parse.token); return MPR_ERR_BAD_SYNTAX; case ESP_TOK_LITERAL: len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, "write(\"", parse.token, "\");\n", (void*) 0); break; case ESP_TOK_ATAT: /* * Trick to get undefined variables to evaluate to "". * Catenate with "" to cause toString to run. */ len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, "write(\"\" + ", parse.token, ");\n", (void*) 0); break; case ESP_TOK_EQUALS: len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, "write(\"\" + ", parse.token, ");\n", (void*) 0); state = ESP_STATE_IN_ESP_TAG; break; case ESP_TOK_START_ESP: state = ESP_STATE_IN_ESP_TAG; tid = getEspToken(state, &parse); while (tid != ESP_TOK_EOF && tid != ESP_TOK_EOF && tid != ESP_TOK_END_ESP && len >= 0) { len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, parse.token, (void*) 0); tid = getEspToken(state, &parse); } state = ESP_STATE_BEGIN; break; case ESP_TOK_END_ESP: state = ESP_STATE_BEGIN; break; case ESP_TOK_INCLUDE: if (parse.token[0] == '/') { mprStrcpy(incPath, sizeof(incPath), parse.token); } else { mprGetDirName(dir, sizeof(dir), ep->uri); mprSprintf(incPath, sizeof(incPath), "%s/%s", dir, parse.token); } if (esp->mapToStorage(ep->requestHandle, path, sizeof(path), incPath, 0) < 0) { mprAllocSprintf(errMsg, MPR_MAX_STRING, "Can't find include file: %s", path); rc = MPR_ERR_CANT_OPEN; break; } if (esp->readFile(ep->requestHandle, &incText, &incSize, path) < 0) { mprAllocSprintf(errMsg, MPR_MAX_STRING, "Can't read include file: %s", path); rc = MPR_ERR_CANT_READ; break; } incText[incSize] = '\0'; /* * Recurse and process the include script */ incBuf = 0; if ((rc = buildScript(ep, &incBuf, incText, errMsg)) < 0) { mprFree(incText); mprFree(parse.token); return rc; } len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, incBuf, (void*) 0); mprFree(incText); mprFree(incBuf); state = ESP_STATE_IN_ESP_TAG; break; } tid = getEspToken(state, &parse); } mprFree(parse.token); if (len < 0) { mprAllocSprintf(errMsg, MPR_MAX_STRING, "Script token is too big in %s.\nConfigured maximum is %d.", path, maxScriptSize); return MPR_ERR_WONT_FIT; } return rc; }
static int fetch(MaClient *client, char *method, char *url, char *data, int len) { struct stat sbuf; FILE *fp; MaUrl *parsedUrl; char *header, *content, *diffBuf, *msg; char path[MPR_MAX_PATH], dir[MPR_MAX_PATH], urlBuf[MPR_HTTP_MAX_URL]; char tmp[MPR_MAX_PATH]; int i, code, rc, contentLen, mark, elapsed, c; fp = 0; lock(); fetchCount++; unlock(); if (url == 0) { return MPR_ERR_BAD_ARGS; } if (*url == '/') { mprSprintf(urlBuf, sizeof(urlBuf), "http://127.0.0.1%s", url); url = urlBuf; } else if ((strstr(url, "http://")) == 0) { mprSprintf(urlBuf, sizeof(urlBuf), "http://%s", url); url = urlBuf; } mprLog(MPR_DEBUG, tMod, "fetch: %s %s\n", method, url); mark = mprGetTime(0); if (mprStrCmpAnyCase(method, "GET") == 0) { rc = client->getRequest(url); } else if (mprStrCmpAnyCase(method, "HEAD") == 0) { rc = client->headRequest(url); } else if (mprStrCmpAnyCase(method, "OPTIONS") == 0) { rc = client->optionsRequest(url); } else if (mprStrCmpAnyCase(method, "POST") == 0) { rc = client->postRequest(url, data, len); } else if (mprStrCmpAnyCase(method, "TRACE") == 0) { rc = client->traceRequest(url); } if (rc < 0) { return MPR_ERR_CANT_OPEN; } code = client->getResponseCode(); content = client->getResponseContent(&contentLen); header = client->getResponseHeader(); msg = client->getResponseMessage(); elapsed = mprGetTime(0) - mark; if (code == 200 || code == 302) { mprLog(6, tMod, "Response code %d, content len %d, header: \n%s\n", code, contentLen, header); } else { mprLog(2, tMod, "Response code %d, content len %d, header: \n%s\n%s", code, contentLen, header, content); mprError(MPR_L, MPR_USER, "Can't retrieve \"%s\" (%d), %s", url, code, msg); return MPR_ERR_CANT_READ; } if (cmpDir) { client->getParsedUrl(&parsedUrl); mprSprintf(path, sizeof(path), "%s%s", cmpDir, parsedUrl->uri); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } if (stat(path, &sbuf) < 0) { mprError(MPR_L, MPR_USER, "Can't access %s", path); return MPR_ERR_CANT_ACCESS; } if (sbuf.st_mode & S_IFDIR) { strcpy(tmp, path); mprSprintf(path, sizeof(path), "%s/_DEFAULT_.html", tmp); } if (stat(path, &sbuf) < 0) { mprError(MPR_L, MPR_USER, "Can't access %s", path); return MPR_ERR_CANT_ACCESS; } if ((int) sbuf.st_size != contentLen) { mprError(MPR_L, MPR_USER, "Failed comparison for %s" "ContentLen %d, size %d\n", url, contentLen, sbuf.st_size); return MPR_ERR_CANT_ACCESS; } if ((fp = fopen(path, "r" MPR_BINARY)) == 0) { mprError(MPR_L, MPR_USER, "Can't open %s", path); return MPR_ERR_CANT_OPEN; } diffBuf = (char*) mprMalloc(contentLen); if ((int) fread(diffBuf, 1, contentLen, fp) != contentLen) { mprError(MPR_L, MPR_USER, "Can't read content from %s", path); return MPR_ERR_CANT_READ; } for (i = 0; i < contentLen; i++) { if (diffBuf[i] != content[i]) { mprError(MPR_L, MPR_USER, "Failed comparison for %s" "At byte %d: %x vs %x\n", i, (uchar) diffBuf[i], (uchar) content[i]); return MPR_ERR_GENERAL; } } fclose(fp); mprFree(diffBuf); } if (writeDir) { client->getParsedUrl(&parsedUrl); mprSprintf(path, sizeof(path), "%s%s", writeDir, parsedUrl->uri); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } mprGetDirName(dir, sizeof(dir), path); mprMakeDir(dir); if (stat(path, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) { strcpy(tmp, path); mprSprintf(path, sizeof(path), "%s/_DEFAULT_.html", tmp); } if ((fp = fopen(path, "w" MPR_BINARY)) == 0) { mprError(MPR_L, MPR_USER, "Can't open %s", path); return MPR_ERR_CANT_OPEN; } if (outputHeader) { if (fputs(header, fp) != EOF) { mprError(MPR_L, MPR_USER, "Can't write header to %s", path); return MPR_ERR_CANT_WRITE; } fputc('\n', fp); } if ((int) fwrite(content, 1, contentLen, fp) != contentLen) { mprError(MPR_L, MPR_USER, "Can't write content to %s", path); return MPR_ERR_CANT_WRITE; } fclose(fp); } lock(); if (trace) { if (strstr(url, "http://") != 0) { url += 7; } if ((fetchCount % 100) == 1) { if (fetchCount == 1 || (fetchCount % 2500) == 1) { if (fetchCount > 1) { mprPrintf("\n"); } mprPrintf( " Count Fd Thread Op Code Bytes Time Url\n"); } mprPrintf("%8d %4d %7s %4s %5d %7d %5.2f %s\n", fetchCount - 1, client->getFd(), #if BLD_FEATURE_MULTITHREAD mprGetCurrentThreadName(), #else "", #endif method, code, contentLen, elapsed / 1000.0, url); } } if (outputHeader) { mprPrintf("%s\n", header); } if (!quietMode) { for (i = 0; i < contentLen; i++) { if (!isprint((uchar) content[i]) && content[i] != '\n' && content[i] != '\r' && content[i] != '\t') { break; } } if (contentLen > 0) { if (i != contentLen && 0) { mprPrintf("Content has non-printable data\n"); } else { // mprPrintf("Length of content %d\n", contentLen); for (i = 0; i < contentLen; i++) { c = (uchar) content[i]; if (isprint((uchar) c) || isspace((uchar) c)) { putchar(content[i]); } else { mprPrintf("0x%x", c); } } fflush(stdout); } } } unlock(); if (singleStep) { mprPrintf("Pause: "); read(0, (char*) &rc, 1); } return 0; }
int MprTestSession::setupTests(MprTestResult *result, Mpr *mpr, int argc, char *argv[], char *switches) { char switchBuf[80]; char *programName, *argp; int errflg, c, i, l; #if BLD_FEATURE_LOG char *logSpec; #endif this->mpr = mpr; programName = mprGetBaseName(argv[0]); errflg = 0; #if BLD_FEATURE_LOG logSpec = "stdout:1"; logger = new MprLogToFile(); #endif switchBuf[0] = '\0'; mprStrcat(switchBuf, sizeof(switchBuf), 0, "cDeg:i:l:n:msT:t:v?", switches, (void*) 0); MprCmdLine cmdLine(argc, argv, switchBuf); while ((c = cmdLine.next(&argp)) != EOF) { switch(c) { case 'c': result->setContinueOnFailures(1); break; case 'D': mprSetDebugMode(1); result->setDebugOnFailures(1); break; case 'e': needEventsThread = 1; break; case 'g': testGroups->parse(argp); break; case 'i': iterations = atoi(argp); break; case 'l': #if BLD_FEATURE_LOG logSpec = argp; #endif break; case 'n': l = atoi(argp); if (l == 0) { sessionLevel = MPR_BASIC; } else if (l == 1) { sessionLevel = MPR_THOROUGH; } else { sessionLevel = MPR_DEDICATED; } break; case 'm': mprRequestMemStats(1); break; case 's': result->setSingleStep(1); break; case 't': i = atoi(argp); if (i <= 0 || i > 100) { mprFprintf(MPR_STDERR, "%s: Bad number of threads (0-100)\n", programName); exit(2); } #if BLD_FEATURE_MULTITHREAD numThreads = i; #endif break; case 'T': #if BLD_FEATURE_MULTITHREAD poolThreads = atoi(argp); #endif break; case 'v': verbose++; break; default: // // Ignore args we don't understand // break; case '?': errflg++; break; } } if (errflg) { mprFprintf(MPR_STDERR, "usage: %s [-cDemsv] [-g groups] [-i iterations] " "[-l logSpec] [-n testLevel] [-T poolThreads] [-t threads]\n", programName); exit(2); } #if !BLD_FEATURE_MULTITHREAD needEventsThread = 0; #endif #if BLD_FEATURE_LOG mpr->addListener(logger); mpr->setLogSpec(logSpec); #endif initSignals(); this->argc = argc; this->argv = argv; this->firstArg = cmdLine.firstArg(); #if BLD_FEATURE_MULTITHREAD mpr->setMaxPoolThreads(poolThreads); #endif if (mpr->start(needEventsThread ? MPR_SERVICE_THREAD : 0) < 0) { return MPR_ERR_CANT_INITIALIZE; } result->adjustThreadCount(numThreads); result->setVerbosity(verbose); if (result->getListenerCount() == 0) { result->addListener(new MprTestListener("__default__")); } if (verbose) { mprFprintf(MPR_STDOUT, "Testing: iterations %d, threads %d, pool %d, service thread %d\n", iterations, numThreads, poolThreads, needEventsThread); } // // Use current session object for the main thread // sessions = (MprTestSession**) mprMalloc(sizeof(MprTestSession*) * numThreads); sessions[0] = this; if (sessions[0]->initializeClasses(result) < 0) { exit(3); } #if BLD_FEATURE_MULTITHREAD // // Now clone this session object for all other threads // for (i = 1; i < numThreads; i++) { char tName[64]; sessions[i] = this->newSession(); sessions[i]->setResult(result); sessions[i]->cloneSettings(this); mprSprintf(tName, sizeof(tName), "test.%d", i); } #endif return 0; }
int MprCmd::start(char *program, char **argv, char **envp, MprCmdProc fn, void *fnData, int userFlags) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo; char dirBuf[MPR_MAX_FNAME]; char *envBuf, **ep, *cmdBuf, **ap, *destp, *cp, *dir; char progBuf[MPR_MAX_STRING], *localArgv[2], *saveArg0; int argc, i, len, inheritFiles; mprAssert(program); mprAssert(argv); flags &= ~(MPR_CMD_WAITED | MPR_CMD_RUNNING); flags |= (userFlags & MPR_CMD_USER_FLAGS); exitStatus = -1; mprStrcpy(progBuf, sizeof(progBuf), program); progBuf[sizeof(progBuf) - 1] = '\0'; program = progBuf; // // Sanitize the command line (program name only) // for (cp = program; *cp; cp++) { if (*cp == '/') { *cp = '\\'; } else if (*cp == '\r' || *cp == '\n') { *cp = ' '; } } if (*program == '"') { if ((cp = strrchr(++program, '"')) != 0) { *cp = '\0'; } } saveArg0 = argv[0]; if (argv == 0) { argv = localArgv; argv[1] = 0; } argv[0] = program; // // Determine the command line length and arg count // argc = 0; for (len = 0, ap = argv; *ap; ap++) { len += strlen(*ap) + 1 + 2; // Space and possible quotes argc++; } cmdBuf = (char*) mprMalloc(len + 1); cmdBuf[len] = '\0'; // // Add quotes to all args that have spaces in them including "program" // destp = cmdBuf; for (ap = &argv[0]; *ap; ) { cp = *ap; if ((strchr(cp, ' ') != 0) && cp[0] != '\"') { *destp++ = '\"'; strcpy(destp, cp); destp += strlen(cp); *destp++ = '\"'; } else { strcpy(destp, cp); destp += strlen(cp); } if (*++ap) { *destp++ = ' '; } } *destp = '\0'; mprAssert((int) strlen(destp) < (len - 1)); mprAssert(cmdBuf[len] == '\0'); argv[0] = saveArg0; envBuf = 0; if (envp) { for (len = 0, ep = envp; *ep; ep++) { len += strlen(*ep) + 1; } envBuf = (char*) mprMalloc(len + 2); // Win requires two nulls destp = envBuf; for (ep = envp; *ep; ep++) { strcpy(destp, *ep); mprLog(6, log, "Set CGI variable: %s\n", destp); destp += strlen(*ep) + 1; } *destp++ = '\0'; *destp++ = '\0'; // WIN requires two nulls } memset(&startInfo, 0, sizeof(startInfo)); startInfo.cb = sizeof(startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; if (flags & MPR_CMD_SHOW) { startInfo.wShowWindow = SW_SHOW; } else { startInfo.wShowWindow = SW_HIDE; } if (files.clientFd[MPR_CMD_IN] > 0) { startInfo.hStdInput = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_IN]); } if (files.clientFd[MPR_CMD_OUT] > 0) { startInfo.hStdOutput = (HANDLE)_get_osfhandle(files.clientFd[MPR_CMD_OUT]); } if (files.clientFd[MPR_CMD_ERR] > 0) { startInfo.hStdError = (HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_ERR]); } #if UNUSED SECURITY_ATTRIBUTES secAtt; memset(&secAtt, 0, sizeof(secAtt)); secAtt.nLength = sizeof(SECURITY_ATTRIBUTES); secAtt.bInheritHandle = TRUE; #endif if (userFlags & MPR_CMD_CHDIR) { if (cwd) { dir = cwd; } else { mprGetDirName(dirBuf, sizeof(dirBuf), argv[0]); dir = dirBuf; } } else { dir = 0; } inheritFiles = (flags & MPR_CMD_STDIO_MADE) ? 1 : 0; mprLog(5, log, "Running: %s\n", cmdBuf); if (! CreateProcess(0, cmdBuf, 0, 0, inheritFiles, CREATE_NEW_CONSOLE, envBuf, dir, &startInfo, &procInfo)) { mprError(MPR_L, MPR_LOG, "Can't create process: %s, %d", cmdBuf, mprGetOsError()); return MPR_ERR_CANT_CREATE; } handle = (long) procInfo.hProcess; pid = procInfo.dwProcessId; if (procInfo.hThread != 0) { CloseHandle(procInfo.hThread); } for (i = 0; i < MPR_CMD_MAX_FD; i++) { if (files.clientFd[i] >= 0) { close(files.clientFd[i]); files.clientFd[i] = -1; } } if (cmdBuf) { mprFree(cmdBuf); } if (envBuf) { mprFree(envBuf); } if (userFlags & MPR_CMD_WAIT) { waitForChild(INT_MAX); for (i = 0; i < MPR_CMD_MAX_FD; i++) { if (files.serverFd[i] >= 0) { close(files.serverFd[i]); files.serverFd[i] = -1; } } return exitStatus; } lock(); outputDataProc = fn; data = fnData; flags |= MPR_CMD_RUNNING; if (1 || ! mpr->getAsyncSelectMode()) { timer = new MprTimer(MPR_TIMEOUT_CMD_WAIT, singleThreadedOutputData, (void*) this); #if FUTURE // // Want non blocking reads if we are in single-threaded mode. // Can't use this yet as we are holding a Request lock and so blocking // in a read stops everything. Need proper Async I/O in windows. // if (mprGetMpr()->poolService->getMaxPoolThreads() == 0) { } else { task = new MprTask(multiThreadedOutputData, (void*) this); task->start(); } #endif } unlock(); return 0; }