Esempio n. 1
0
int APIENTRY WinMain(HINSTANCE inst, HINSTANCE junk, char *args, int junk2)
{
    char    dir[MPR_MAX_FNAME], moduleBuf[MPR_MAX_FNAME], tmp[MPR_MAX_FNAME];
    char    *cp;
    int     errflg, sleepMsecs, removeOk;

    errflg = 0;
    sleepMsecs = 0;
    removeOk = 0;

	/*
	 *	Get the directory above bin
 	 */
    GetModuleFileName(0, moduleBuf, sizeof(moduleBuf) - 1);
    mprGetDirName(tmp, sizeof(tmp), moduleBuf);
    mprGetDirName(dir, sizeof(dir), tmp);
    _chdir(dir);

    if (args && *args) {
        if (strstr(args, "-r") != 0) {
            removeOk++;
        }
        if ((cp = strstr(args, "-s")) != 0) {
            do {
                cp++;
            } while (isspace(*cp));
            sleepMsecs = atoi(cp) * 1000;
        }
    }

    /*
     *  We use removeOk to ensure that someone just running the program won't 
     *  do anything bad.
     */
    if (errflg || !removeOk) {
        fprintf(stderr, "Bad Usage");
        return FALSE;
    }   

    cleanup();

    /*
     *  Some products (services) take a while to exit. This is a convenient
     *  way to pause before removing
     */
    if (sleepMsecs) {
        printf("sleeping for %d msec\n", sleepMsecs);
        Sleep(sleepMsecs);
    }

    return 0;
}
Esempio n. 2
0
File: os.cpp Progetto: OPSF/uClinux
void MprCmd::setCwd(char *fileName)
{
	char	dirBuf[MPR_MAX_FNAME];

	mprGetDirName(dirBuf, sizeof(dirBuf), fileName);
	cwd = mprStrdup(dirBuf);
}
Esempio n. 3
0
int Mpr::loadDll(char *path, char *fnName, void *arg, void **handlePtr)
{
	MprDllEntryProc	fn;
	char			localPath[MPR_MAX_FNAME], dir[MPR_MAX_FNAME];
    void			*handle;
	char			*cp;
	int				rc;

	mprAssert(path && *path);
	mprAssert(fnName && *fnName);

	mprGetDirName(dir, sizeof(dir), path);
	mprSetModuleSearchPath(dir);

	mprStrcpy(localPath, sizeof(localPath), path);
	//	TODO - good to have a x-platform method for this.
	for (cp = localPath; *cp; cp++) {
		if (*cp == '/') {
			*cp = '\\';
		}
	}

    if ((handle = GetModuleHandle(mprGetBaseName(localPath))) == 0) {
		if ((handle = LoadLibraryEx(localPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
			char cwd[1024], *env;
			getcwd(cwd, sizeof(cwd) - 1);
			env = getenv("PATH");
			mprLog(0, "ERROR %d\n", GetLastError());
			mprLog(0, "Can't load %s\nReason: \"%d\"\n", path, mprGetOsError());
			mprLog(0, "CWD %s\n PATH %s\n", cwd, env);
			return MPR_ERR_CANT_OPEN;
		}
    }

	fn = (MprDllEntryProc) GetProcAddress((HINSTANCE) handle, fnName);
	if (fn == 0) {
		FreeLibrary((HINSTANCE) handle);
		mprLog(0, "Can't load %s\nReason: can't find function \"%s\"\n", 
			localPath, fnName);
		return MPR_ERR_NOT_FOUND;
	}
	mprLog(MPR_INFO, "Loading DLL %s\n", path);

	if ((rc = (fn)(arg)) < 0) {
		FreeLibrary((HINSTANCE) handle);
		mprError(MPR_L, MPR_LOG, "Initialization for %s failed.", path);
		return MPR_ERR_CANT_INITIALIZE;
	}
	if (handlePtr) {
		*handlePtr = handle;
	}
	return rc;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
	time_t		now;
	struct tm	*t;
	char		path[2048], cwd[2048], dirName[2048], parent[2048];
	char		*ext, *previous, *cp;
	int 		errors, c, j, i, levels, upLevel, incJava;

	errors = 0;
	program = mprGetBaseName(argv[0]);
	quiet = 0;

	while ((c = getopt(argc, argv, "?I:o:q")) != EOF) {
		switch(c) {
		case 'I':
			if (numIncludeDir >= MAX_INC) {
				fprintf(stderr, "Too many include directories\n");
				exit(1);
			}
			includeDir[numIncludeDir++] = strdup(optarg);
			break;
	
		case 'q':
			quiet++;
			break;

		case '?':
			errors++;
			break;
		}
	}
	if (errors) {
		fprintf(stderr, 
			"%s: usage: [-q] [-I includeDir] files...\n", program);
		exit(2);
	}

	includeDir[numIncludeDir++] = strdup(".");
#if !WIN && !_WIN32
	includeDir[numIncludeDir++] = strdup("/usr/include");
#endif

	openSignals();
	if ((fp = fopen("make.dep", "w")) == 0) {
		fprintf(stderr, "Cant open make.dep\n");
		exit(255);
	}

	now = time(0);
	t = localtime(&now);
	fprintf(fp, "#\n#	make.dep -- Makefile dependencies. Generated by genDepend.\n#\n\n");

	getcwd(cwd, sizeof(cwd));
	mapDelimiters(cwd);

	fprintf(fp, "all: compile\n\n");

	fprintf(fp, "BLD_TOP := ");
	strcpy(dirName, cwd);

	for (i = 0, levels = 0; *dirName; i++) {
		sprintf(path, "%s/build/make/make.rules", dirName);
		if (access(path, R_OK) == 0) {
			break;
		}
		mprGetDirName(parent, sizeof(parent), dirName);
		strcpy(dirName, parent);
		if (i > 0) {
			fprintf(fp, "/..");
		} else {
			fprintf(fp, "..");
		}
		levels++;
	}
	if (i == 0) {
		fprintf(fp, ".");
	}
	fprintf(fp, "\n");

	/*
	 *	Extract a src path for Java. Go up N levels less one for the "java"
	 *	directory.
	 */
	strcpy(dirName, cwd);
	cp = &dirName[strlen(dirName) - 1];
	for (upLevel = 1; upLevel < levels && cp > dirName; cp--) {
		if (*cp == '/') {
			upLevel++;
		}
	}

	if (levels > 1) {
		if (cp[0] != '\0' && cp[1] != '\0' && cp[2] != '\0') {
			cp += 2;
		}
		if (*cp == '\0') {
			cp = ".";
		}
		fprintf(fp, "SRC_PATH := %s\n\n", cp);

	} else {
		fprintf(fp, "SRC_PATH := .\n\n");
	}

	fprintf(fp, "#\n#	Read the build configuration settings and make"
				"variable definitions.\n#\n"); 
	fprintf(fp, "include $(BLD_TOP)/buildConfig.make\n\n");

	incJava = 0;
	for (i = optind; i < argc; i++) {
		if (strstr(argv[i], ".java") != 0 && strcmp(argv[i], "*.java") != 0) {
			incJava++;
			// fprintf(fp, "include $(BLD_TOP)/build/make/make.java\n");
			break;
		}
	}
	if (incJava) {
		fprintf(fp, "HAS_JAVA = 1\n\n");
	}

	fprintf(fp, "SRC =");
	for (i = optind; i < argc; i++) {
		if (access(argv[i], R_OK) != 0) {
			continue;
		}
		strncpy(path, argv[i], sizeof(path));
		fprintf(fp, " \\\n\t%s", mprGetBaseName(path));
	}
	fprintf(fp, "\n\n");

	fprintf(fp, "PROCESSED_SRC =");
	for (i = optind; i < argc; i++) {
		if (access(argv[i], R_OK) != 0) {
			continue;
		}
		strncpy(path, argv[i], sizeof(path));
		ext = mapExtension(path);
		if (strcmp(ext, ".java") == 0) {
			fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/src/$(SRC_PATH)/%s", 
				mprGetBaseName(argv[i]));
		}
	}
	fprintf(fp, "\n\n");

	fprintf(fp, "FILES =");
	for (i = optind; i < argc; i++) {
		if (access(argv[i], R_OK) != 0) {
			continue;
		}
		strncpy(path, argv[i], sizeof(path));
		ext = mapExtension(path);
		if (strcmp(ext, ".java") == 0) {
			fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/classes/$(SRC_PATH)/%s", 
				mprGetBaseName(path));
		} else {
			fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/%s", mprGetBaseName(path));
		}
	}
	fprintf(fp, "\n");

	for (i = optind; !finished && i < argc; i++) {
		if (*argv[i] == '*') {
			continue;
		}
		strcpy(path, argv[i]);
		ext = mapExtension(path);
		if (strcmp(ext, ".java") == 0) {
			fprintf(fp, "\n$(BLD_OBJ_DIR)/classes/$(SRC_PATH)/%s: ", 
				mprGetBaseName(path));
		} else {
			fprintf(fp, "\n$(BLD_OBJ_DIR)/%s: ", mprGetBaseName(path));
		}

		numDependencies = 0;
		findDependencies(fp, argv[i]);
		qsort(dependencies, numDependencies, sizeof(char*), depSort);

		previous = "";
		for (j = 0; j < numDependencies; j++) {
			if (strcmp(previous, dependencies[j]) != 0) {
				fprintf(fp, " \\\n\t%s", dependencies[j]);
			}
			previous = dependencies[j];
		}
		for (j = 0; j < numDependencies; j++) {
			free(dependencies[j]);
		}
		fprintf(fp, "\n");
	}

	fprintf(fp, "\n#\n#	Read the Makefile rules\n#\n");
	fprintf(fp, "include $(BLD_TOP)/build/make/make.rules\n\n");

	fprintf(fp, "ifeq ($(BUILDING_CROSS),1)\n");
	fprintf(fp, "	include $(BLD_TOP)/build/make/make.os.$(BLD_HOST_OS)\n");
	fprintf(fp, "else\n");
	fprintf(fp, "	include $(BLD_TOP)/build/make/make.os.$(BLD_BUILD_OS)\n");
	fprintf(fp, "endif\n\n");

	fclose(fp);

	return 0;
}
Esempio n. 5
0
static int findDependencies(FILE *fp, char *fname)
{
	FILE	*ifp;
	char	path[2048], buf[8192], dirName[2048];
	char	*cp, *ep;
	int		line, i, j;

	if ((ifp = fopen(fname, "r")) == 0) {
		if (!quiet) {
			fprintf(stderr, "Cant open %s\n", fname);
		}
		return -1;
	}

	for (line = 0; ! feof(ifp); line++) {
		if (fgets(buf, sizeof(buf), ifp) == 0)
			break;
		cp = buf;
		if (*cp++ != '#') {
			continue;
		}
		while (*cp == '\t' || *cp == ' ') {
			cp++;
		}
		if (*cp != 'i' || strncmp(cp, "include", 7)) {
			continue;
		}
		cp += 7;

		while (*cp == '\t' || *cp == ' ' || *cp == '\"') {
			cp++;
		}
		//
		//	Skip system headers
		//
		if (*cp == '<') {
			continue;
		}

		ep = cp;
		while (isalnum((unsigned char) *ep) || *ep == '_' || *ep == '.' || *ep == '/' || *ep == '-') {
			ep++;
		}
		*ep = '\0';

		strcpy(buf, cp);
		if (buf[0] == '/' || (buf[0] == '.' && buf[1] == '.')) {
			if (access(buf, R_OK) < 0) {
				if (!quiet) {
					fprintf(stderr, "Cant find include %s\n", buf);
				}
				continue;
			}

		} else {
			//
			//	First search relative to the including file
			//
			mprGetDirName(dirName, sizeof(dirName), fname);
			if (*dirName) {
				sprintf(path, "%s/%s", dirName, buf);
			} else {
				strcpy(path, dirName);
			}
			if (access(path, R_OK) < 0) {
				for (j = 0; j < numIncludeDir; j++) {
					sprintf(path, "%s/%s", includeDir[j], buf);
					if (access(path, R_OK) == 0) {
						break;
					}
				}
				if (j == numIncludeDir) {
					if (!quiet) {
						fprintf(stderr, "Cant find include %s in %s at %d\n", 
							buf, fname, line);
					}
					continue;
				}
			}
		}

		if (numDependencies >= MAX_DEPEND) {
			fprintf(stderr, "Too many dependencies\n");
		} else {
			for (i = 0; i < numDependencies; i++) {
				if (strcmp(path, dependencies[i]) == 0)
					break;
			}
			if (i == numDependencies) {
				dependencies[numDependencies++] = strdup(path);
				findDependencies(fp, path);
			}
		}
	}
	fclose(ifp);

	return 0;
}
Esempio n. 6
0
File: os.cpp Progetto: OPSF/uClinux
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
static int locateServerRoot(char *path)
{
#if BLD_FEATURE_CONFIG_PARSE && !BLD_FEATURE_ROMFS

	if (serverRoot == 0) {
		MprFileInfo	info;
		char		searchPath[MPR_MAX_FNAME * 8], pathBuf[MPR_MAX_FNAME];
		char 		cwd[MPR_MAX_FNAME];
		char		*tok, *searchBuf;

		//
		//	No explicit server root switch was supplied so search for 
		//	"mime.types" in the search path:
		//		.
		//		..
		//		../productName
		//		../../productName
		//	For windows, we also do:
		//		modDir							(where the exe was loaded from)
		//		modDir/..  
		//		modDir/../productName  
		//		modDir/../../productName 
		//	For all:
		//		BLD_PREFIX
		//
#if WIN || WINCE
		char modDir[MPR_MAX_FNAME], modPath[MPR_MAX_FNAME];
		char module[MPR_MAX_FNAME];

		//
		//	Initially change directory to where the exe lives
		//
		GetModuleFileName(0, module, sizeof(module));
		mprGetDirName(modDir, sizeof(modDir), module);
		mprGetFullPathName(modPath, sizeof(modPath), modDir);

#if WIN
		/* NOTE: use tabs not spaces between items */
		mprSprintf(searchPath, sizeof(searchPath), 
			".	..	../%s	../../%s	"
			"%s	%s/..	%s/../%s	%s/../../%s	%s",
			BLD_PRODUCT, BLD_PRODUCT,
			modPath, modPath, modPath, BLD_PRODUCT, modPath, BLD_PRODUCT, BLD_PREFIX);
#else
		/* NOTE: use tabs not spaces between items */
		mprSprintf(searchPath, sizeof(searchPath), 
			"%s	%s	../%s	../../%s	"
			"%s/..	%s/../%s",
			MPR_STORAGE, modPath, BLD_PRODUCT, BLD_PRODUCT,
			modPath, modPath, modPath);
#endif
#else
		mprSprintf(searchPath, sizeof(searchPath), 
			".	..	../%s	../../%s	%s",
			BLD_PRODUCT, BLD_PRODUCT, BLD_PREFIX);
#endif
		
		getcwd(cwd, sizeof(cwd) - 1);
		mprLog(3, "Root search path %s, cwd %s\n", searchPath, cwd);

		searchBuf = mprStrdup(searchPath);
		path = mprStrTok(searchBuf, "\t", &tok);
		while (path) {
			mprSprintf(pathBuf, sizeof(pathBuf), "%s/mime.types", path);
			mprLog(4, "Searching for %s\n", pathBuf);
			if (fileSystem->stat(pathBuf, &info) == 0) {
				break;
			}
			path = mprStrTok(0, "\t", &tok);
		}
		if (path == 0) {
			mprError(MPR_L, MPR_USER, 
				"Can't find suitable server root directory\n"
				"Using search path %s, and current directory %s\n"
				"Ensure you have adequate permissions to access the required "
				"directories.\n", searchPath, cwd);
			mprFree(searchBuf);
			return MPR_ERR_CANT_ACCESS;
		}
		server->setServerRoot(path);
		mprFree(searchBuf);

	} else {

		//
		//	Must program the server up for the server root. It will convert this
		//	path to an absolute path which we reassign to our notion of
		//	serverRoot.
		//
		server->setServerRoot(path);
	}
	serverRoot = server->getServerRoot();

#endif

#if !BLD_FEATURE_ROMFS
	chdir(serverRoot);
#endif
	return 0;
}
Esempio n. 10
0
int main(int argc, char *argv[])
{
    char        path[2048], cwd[2048], dirName[2048], parent[2048];
    char        *ext, *previous, *cp, *argp;
    int         errors, j, i, levels, upLevel, incJava, nextArg;

    errors = 0;
    program = mprGetBaseName(argv[0]);
    quiet = 0;

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }
        if (strncmp(argp, "-I", 2) == 0) {
            if (numIncludeDir >= MAX_INC) {
                fprintf(stderr, "Too many include directories\n");
                exit(1);
            }
            includeDir[numIncludeDir++] = strdup(&argp[2]);

        } else if (strcmp(argp, "-q") == 0) {
            quiet++;
        }
    }
    if (errors) {
        fprintf(stderr, "%s: usage: [-q] [-I includeDir] files...\n", program);
        exit(2);
    }

    includeDir[numIncludeDir++] = strdup(".");
#if !BLD_WIN_LIKE && !_WIN32
    includeDir[numIncludeDir++] = strdup("/usr/include");
#endif

    openSignals();
    if ((fp = fopen("make.newdep", "w")) == 0) {
        fprintf(stderr, "Cant open make.newdep\n");
        exit(255);
    }
    fprintf(fp, "#\n#   .makedep -- Makefile dependencies. Generated by edep.\n#\n\n");

    if (getcwd(cwd, sizeof(cwd)) == 0) {
        fprintf(stderr, "Can't get working directory");
        exit(255);
    }
    mapDelimiters(cwd);

    fprintf(fp, "all: compile\n\n");

    fprintf(fp, "BLD_TOP := ");
    strcpy(dirName, cwd);

    for (i = 0, levels = 0; *dirName; i++) {
        sprintf(path, "%s/build/make/make.rules", dirName);
        if (access(path, R_OK) == 0) {
            break;
        }
        mprGetDirName(parent, sizeof(parent), dirName);
        strcpy(dirName, parent);
        if (i > 0) {
            fprintf(fp, "/..");
        } else {
            fprintf(fp, "..");
        }
        levels++;
    }
    if (i == 0) {
        fprintf(fp, ".");
    }
    fprintf(fp, "\n");

    /*
     *  Extract a src path for Java. Go up N levels less one for the "java" directory.
     */
    strcpy(dirName, cwd);
    cp = &dirName[strlen(dirName) - 1];
    for (upLevel = 1; upLevel < levels && cp > dirName; cp--) {
        if (*cp == '/') {
            upLevel++;
        }
    }

    if (levels > 1) {
        if (cp[0] != '\0' && cp[1] != '\0' && cp[2] != '\0') {
            cp += 2;
        }
        if (*cp == '\0') {
            cp = ".";
        }
        fprintf(fp, "SRC_PATH := %s\n\n", cp);

    } else {
        fprintf(fp, "SRC_PATH := .\n\n");
    }

    fprintf(fp, "#\n#   Read the build configuration settings and make variable definitions.\n#\n"); 
    fprintf(fp, "include $(BLD_TOP)/buildConfig.make\n\n");

    incJava = 0;
    for (i = nextArg; i < argc; i++) {
        if (strstr(argv[i], ".java") != 0 && strcmp(argv[i], "*.java") != 0) {
            incJava++;
            /* fprintf(fp, "include $(BLD_TOP)/build/make/make.java\n"); */
            break;
        }
    }
    if (incJava) {
        fprintf(fp, "HAS_JAVA = 1\n\n");
    }

    fprintf(fp, "SRC =");
    for (i = nextArg; i < argc; i++) {
        if (access(argv[i], R_OK) != 0) {
            continue;
        }
        strncpy(path, argv[i], sizeof(path));
        fprintf(fp, " \\\n\t%s", mprGetBaseName(path));
    }
    fprintf(fp, "\n\n");

    fprintf(fp, "PROCESSED_SRC =");
    for (i = nextArg; i < argc; i++) {
        if (access(argv[i], R_OK) != 0) {
            continue;
        }
        strncpy(path, argv[i], sizeof(path));
        ext = mapExtension(path);
        if (strcmp(ext, ".java") == 0) {
            fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/src/$(SRC_PATH)/%s", 
                mprGetBaseName(argv[i]));
        }
    }
    fprintf(fp, "\n\n");

    fprintf(fp, "OBJECTS =");
    for (i = nextArg; i < argc; i++) {
        if (access(argv[i], R_OK) != 0) {
            continue;
        }
        strncpy(path, argv[i], sizeof(path));
        ext = mapExtension(path);
        if (strcmp(ext, ".java") == 0) {
            fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/classes/$(SRC_PATH)/%s", 
                mprGetBaseName(path));
        } else {
            fprintf(fp, " \\\n\t$(BLD_OBJ_DIR)/%s", mprGetBaseName(path));
        }
    }
    fprintf(fp, "\n");

    for (i = nextArg; !finished && i < argc; i++) {
        if (*argv[i] == '*') {
            continue;
        }
        strcpy(path, argv[i]);
        ext = mapExtension(path);
        if (strcmp(ext, ".java") == 0) {
            fprintf(fp, "\n$(BLD_OBJ_DIR)/classes/$(SRC_PATH)/%s: ", 
                mprGetBaseName(path));
        } else {
            fprintf(fp, "\n$(BLD_OBJ_DIR)/%s: ", mprGetBaseName(path));
        }

        numDependencies = 0;
        findDependencies(fp, argv[i]);
        qsort(dependencies, numDependencies, sizeof(char*), depSort);

        previous = "";
        for (j = 0; j < numDependencies; j++) {
            if (strcmp(previous, dependencies[j]) != 0) {
                fprintf(fp, " \\\n\t%s", dependencies[j]);
            }
            previous = dependencies[j];
        }
        for (j = 0; j < numDependencies; j++) {
            free(dependencies[j]);
        }
        fprintf(fp, "\n");
    }

    fprintf(fp, "\n#\n# Read the Makefile rules\n#\n");
    fprintf(fp, "include $(BLD_TOP)/build/make/make.rules\n\n");

    fprintf(fp, "ifeq ($(BUILDING_CROSS),1)\n");
    fprintf(fp, "   include $(BLD_TOP)/build/make/make.$(BLD_HOST_OS)\n");
    fprintf(fp, "else\n");
    fprintf(fp, "   include $(BLD_TOP)/build/make/make.$(BLD_BUILD_OS)\n");
    fprintf(fp, "endif\n\n");

    fclose(fp);

    unlink("make.dep");
    unlink(".makedep");
    if (rename("make.newdep", ".makedep") != 0) {
        fprintf(stderr, "Cant rename make.newdep to .makedep\n");
        exit(255);
    }

    return 0;
}
Esempio n. 11
0
int MprCmd::start(char *program, char **argv, char **envp, MprCmdProc fn, 
	void *fnData, int userFlags)
{
	char		dir[MPR_MAX_FNAME];
	int			pid, i, err;

	mprAssert(program != 0);
	mprAssert(argv != 0);
	mprLog(4, log, "start: %s\n", program);

	reset();

	flags |= (userFlags & MPR_CMD_USER_FLAGS);

	for (i = 0; argv[i]; i++) {
		mprLog(6, log, "    arg[%d]: %s\n", i, argv[i]);
	}
	if (envp) {
		for (i = 0; envp[i]; i++) {
			mprLog(6, log, "    envp[%d]: %s\n", i, envp[i]);
		}
	}

	if (access(program, X_OK) < 0) {
		mprLog(5, log, "start: can't access %s, errno %d\n", 
			program, mprGetOsError());
		return MPR_ERR_CANT_ACCESS;
	}

	data = fnData;
	cmdDoneProc = fn;
	reapIndex = -1;

	//
	//	Create the child
	//
	pid = vfork();

	if (pid < 0) {
		mprLog(0, log, "Can't fork a new process to run %s\n", program);
		return MPR_ERR_CANT_INITIALIZE;

	} else if (pid == 0) {
		//
		//	Child
		//
		umask(022);
		if (flags & MPR_CMD_NEW_SESSION) {
			setsid();
		}
		if (flags & MPR_CMD_CHDIR) {
			if (cwd) {
				chdir(cwd);
			} else {
				mprGetDirName(dir, sizeof(dir), program);
				chdir(dir);
			}
		}

		//	
		//	FUTURE -- could chroot as a security feature (perhaps cgi-bin)
		//
		if (files.clientFd[MPR_CMD_OUT] >= 0) {
			dup2(files.clientFd[MPR_CMD_OUT], 0);	// Client stdin
		} else {
			close(0);
		}
		if (files.clientFd[MPR_CMD_IN] >= 0) {
			dup2(files.clientFd[MPR_CMD_IN], 1);	// Client stdout
			dup2(files.clientFd[MPR_CMD_IN], 2);	// Client stderr
		} else {
			close(1);
			close(2);
		}

		//
		//	FUTURE -- need to get a better max file limit than this
		//
		for (i = 3; i < 128; i++) {
			close(i);
		}

		if (envp) {
			execve(program, argv, envp);
		} else {
			//
			//	Do this rather than user execv to avoid errors in valgrind
			//
			char	*env[2];
	
			env[0] = "_appweb=1";
			env[1] = 0;
			execve(program, argv, (char**) &env);
		}

		err = errno;
		getcwd(dir, sizeof(dir));
		mprStaticPrintf("Can't exec %s, err %d, cwd %s\n", program, err, dir);
		mprAssert(0);
		exit(-(MPR_ERR_CANT_INITIALIZE));

	} else {

		//
		//	Close the client handles
		//
		for (i = 0; i < MPR_CMD_MAX_FD; i++) {
			if (files.clientFd[i] >= 0) {
				close(files.clientFd[i]);
				files.clientFd[i] = -1;
			}
		}

		data = fnData;
		cmdDoneProc = fn;
		process = (ulong) pid;

		if (flags & MPR_CMD_DETACHED) {
			process = 0;
			return 0;

		} else if (flags & MPR_CMD_WAIT) {
			waitForChild(INT_MAX);
			if (getExitCode() < 0) {
				return MPR_ERR_BAD_STATE;
			}
			return exitStatus;

		} else {
			mprGetMpr()->cmdService->startWatcher();
		}
	}
	return 0;
}
Esempio n. 12
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;
}