Пример #1
0
/*
 *  Process the requests
 */
static void processing()
{
    if (chunkSize) {
        mprAddItem(headers, mprCreateKeyPair(headers, "X-Appweb-Chunk-Size", chunkSize));
    }
#if BLD_FEATURE_MULTITHREAD
    {
        MprThread   *tp;
        int         j;

        activeLoadThreads = loadThreads;
        for (j = 0; j < loadThreads; j++) {
            char name[64];
            mprSprintf(name, sizeof(name), "http.%d", j);
            tp = mprCreateThread(mpr, name, threadMain, mpr, MPR_NORMAL_PRIORITY, 0); 
            mprStartThread(tp);
        }
    }
#else
    threadMain(mpr, NULL);
#endif
}
Пример #2
0
int MprLogToFile::setLogSpec(char *path, int size)
{
	struct stat	sbuf;
	char		bak[MPR_MAX_FNAME];

	if (logFd >= 0) {
		close(logFd);
	}

	maxSize = size * 1024 * 1024;			// Convert to bytes
	logFileName = mprStrdup(path);

	if (strcmp(logFileName, "stdout") == 0) {
		logFd = MPR_STDOUT;

	} else {
		if (stat(logFileName, &sbuf) >= 0) {
			mprSprintf(bak, sizeof(bak), "%s.old", logFileName);
			if (access(bak, R_OK) == 0) {
				unlink(bak);
			}
			rename(logFileName, bak);
#if VXWORKS
			//
			//	VxWorks FTP file system does not succeed with renames
			//
			if (access(logFileName, R_OK) == 0) {
				unlink(logFileName);
			}
			
#endif
		}
		logFd = open(logFileName, O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0666);
		if (logFd < 0) {
			return MPR_ERR_CANT_OPEN;
		}
	}
	return 0;
}
Пример #3
0
static pid_t readPid()
{
	Mpr		*mpr;
	char	pidPath[MPR_MAX_FNAME];
	pid_t	pid;
	int		fd;

	mpr = mprGetMpr();
	mprSprintf(pidPath, MPR_MAX_FNAME, "%s/.%s_pid.log", 
		mpr->getInstallDir(), mpr->getAppName());

	if ((fd = open(pidPath, O_RDONLY, 0666)) < 0) {
		mprLog(MPR_DEBUG, "Could not read a pid from %s\n", pidPath);
		return -1;
	}
	if (read(fd, &pid, sizeof(pid)) != sizeof(pid)) {
		mprLog(MPR_DEBUG, "Read from file %s failed\n", pidPath);
		close(fd);
		return -1;
	}
	close(fd);
	return pid;
}
Пример #4
0
/*
    Write the port so the monitor can manage
 */ 
static int writePort(MaServer *server)
{
    HttpHost    *host;
    char        numBuf[16], *path;
    int         fd, len;

    host = mprGetFirstItem(server->http->hosts);
    //  TODO - should really go to a BLD_LOG_DIR
    path = mprJoinPath(mprGetAppDir(), "../.port.log");
    if ((fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0) {
        mprError("Could not create port file %s", path);
        return MPR_ERR_CANT_CREATE;
    }
    mprSprintf(numBuf, sizeof(numBuf), "%d", host->port);

    len = (int) strlen(numBuf);
    numBuf[len++] = '\n';
    if (write(fd, numBuf, len) != len) {
        mprError("Write to file %s failed", path);
        return MPR_ERR_CANT_WRITE;
    }
    close(fd);
    return 0;
}
Пример #5
0
int maWriteGroupFile(MaServer *server, MaAuth *auth, char *path)
{
    MprHash         *hp;
    MprFile         *file;
    MaGroup         *gp;
    char            buf[MPR_MAX_STRING], *tempFile, *name;
    int             next;

    tempFile = mprGetTempPath(server, NULL);
    if ((file = mprOpen(auth, tempFile, O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0444)) == 0) {
        mprError(server, "Can't open %s", tempFile);
        mprFree(tempFile);
        return MPR_ERR_CANT_OPEN;
    }
    mprFree(tempFile);

    hp = mprGetNextHash(auth->groups, 0);
    while (hp) {
        gp = (MaGroup*) hp->data;
        mprSprintf(buf, sizeof(buf), "%d: %x: %s: ", gp->enabled, gp->acl, gp->name);
        mprWrite(file, buf, (int) strlen(buf));
        for (next = 0; (name = mprGetNextItem(gp->users, &next)) != 0; ) {
            mprWrite(file, name, (int) strlen(name));
        }
        mprWrite(file, "\n", 1);
        hp = mprGetNextHash(auth->groups, hp);
    }
    mprFree(file);

    unlink(path);
    if (rename(tempFile, path) < 0) {
        mprError(server, "Can't create new %s", path);
        return MPR_ERR_CANT_WRITE;
    }
    return 0;
}
Пример #6
0
static int configureViaApi()
{
	MaHostAddress 	*address;
	MaHost			*host;
	MprList			*listens;
	MaListen		*lp;
	MprHashTable	*hostAddresses;
	MaDir			*dir;
	MaAlias			*ap;
	MaLocation		*loc;
	char			*cp, *docRootPath;
	char			addrBuf[MPR_MAX_IP_ADDR_PORT], pathBuf[MPR_MAX_FNAME];
	int				port;

	mprLog(MPR_CONFIG, "Configuration via Command Line\n");

#if BLD_FEATURE_ROMFS
	mprLog(MPR_CONFIG, "Server Root \"%s\" in ROM\n", serverRoot);
	docRootPath = mprStrdup(docRoot);
#else
	//
	//	Set the document root. Is relative to the server root unless an absolute path is used.
	//	
#if WIN
	if (*docRoot != '/' && docRoot[1] != ':' && docRoot[2] != '/') 
#elif WINCE
	if (*docRoot != '\\' && docRoot != '/')
#else
	if (*docRoot != '/')
#endif
	{
        if (*docRoot) {
            mprAllocSprintf(&docRootPath, MPR_MAX_FNAME, "%s/%s", serverRoot, docRoot);
        } else {
            docRootPath = mprStrdup(serverRoot);
        }
	} else {
		docRootPath = mprStrdup(docRoot);
	}
#endif // BLD_FEATURE_ROMFS

	mprLog(MPR_CONFIG, "Document Root \"%s\"\n", docRootPath);

	//
	//	Setup the listening addresses. If only a port is specified, listen on
	//	all interfaces. If only the IP address is specified without a port,
	//	then default to port 80. IF autoScan is on, scan for a free port
	//	starting from the base address.
	//
	listens = server->getListens();

	port = MA_SERVER_DEFAULT_PORT_NUM;
	if ((cp = strchr(ipAddr, ':')) != 0) {
		*cp++ = '\0';
		port = atoi(cp);
		if (port <= 0 || port > 65535) {
			mprError(MPR_L, MPR_USER, "Bad listen port number %d", port);
			return MPR_ERR_BAD_SYNTAX;
		}
		if (autoScan) {
			port = findFreePort(ipAddr, port);
		}
		listens->insert(new MaListen(ipAddr, port, 0));

	} else {
		if (isdigit((uchar) *ipAddr) && strchr(ipAddr, '.') == 0) {
			port = atoi(ipAddr);
			if (port <= 0 || port > 65535) {
				mprError(MPR_L, MPR_USER, "Bad listen port number %d", port);
				return MPR_ERR_BAD_SYNTAX;
			}
			if (autoScan) {
				port = findFreePort("", port);
			}
			listens->insert(new MaListen("", port));

		} else {
			if (autoScan) {
				port = findFreePort(ipAddr, MA_SERVER_DEFAULT_PORT_NUM);
			}
			listens->insert(new MaListen(ipAddr, port));
		}
	}
	mprFree(ipAddr);
	ipAddr = 0;

	host = server->newHost(docRootPath);
	if (host == 0) {
		return MPR_ERR_CANT_OPEN;
	}

	//
	//	Add the default server listening addresses to the HostAddress hash.
	//	FUTURE -- this should be moved into newHost
	//
	hostAddresses = server->getHostAddresses();
	lp = (MaListen*) listens->getFirst();
	while (lp) {
		mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", lp->getIpAddr(), 
			lp->getPort());
		address = (MaHostAddress*) hostAddresses->lookup(addrBuf);
		if (address == 0) {
			address = new MaHostAddress(addrBuf);
			hostAddresses->insert(address);
		}
		mprLog(MPR_CONFIG, "Listening for HTTP on %s\n", addrBuf);
		address->insertVhost(new MaVhost(host));
		lp = (MaListen*) listens->getNext(lp);
		mprFree(ipAddr);
		ipAddr = mprStrdup(addrBuf);
	}

	//
	//	Setup a module search path that works for production and developement.
	//
#if BLD_FEATURE_DLL
	char	searchPath[MPR_MAX_FNAME];
	mprSprintf(searchPath, sizeof(searchPath), 
			"./lib ../lib ../lib/modules ../../lib ../../lib/modules %s/lib", BLD_PREFIX);
	host->setModuleDirs(searchPath);
#endif

	//
	//	Load all possible modules
	//
#if BLD_FEATURE_AUTH_MODULE
	//
	//	Handler must be added first to authorize all requests.
	//
	if (server->loadModule("auth") == 0) {
		host->addHandler("authHandler", "");
	}
#endif
#if BLD_FEATURE_UPLOAD_MODULE
	//
	//	Must be after auth and before ESP, EGI.
	//
	if (server->loadModule("upload") == 0) {
		host->addHandler("uploadHandler", "");
	}
#endif
#if BLD_FEATURE_CGI_MODULE
	if (server->loadModule("cgi") == 0) {
		host->addHandler("cgiHandler", ".cgi .cgi-nph .bat .cmd .pl .py");
	}
#endif
#if BLD_FEATURE_EGI_MODULE
	if (server->loadModule("egi") == 0) {
		host->addHandler("egiHandler", ".egi");
	}
#endif
#if BLD_FEATURE_ESP_MODULE
	if (server->loadModule("esp") == 0) {
		host->addHandler("espHandler", ".esp .asp");
	}
#endif
#if BLD_FEATURE_C_API_MODULE
	server->loadModule("capi");
#endif
#if BLD_FEATURE_GACOMPAT_MODULE
	server->loadModule("compat");
#endif
#if BLD_FEATURE_SSL_MODULE
	server->loadModule("ssl");
#endif
	//
	//	Only load one of matrixSsl / openssl
	//
#if BLD_FEATURE_OPENSSL_MODULE
	server->loadModule("openSsl");
#elif BLD_FEATURE_MATRIXSSL_MODULE
	server->loadModule("matrixSsl");
#endif
#if BLD_FEATURE_PHP5_MODULE
	if (server->loadModule("php5") == 0) {
		host->addHandler("php5Handler", ".php");
	}
#endif
#if BLD_FEATURE_COPY_MODULE
	//
	//	Handler must be added last to be the catch all
	//
	if (server->loadModule("copy") == 0) {
		host->addHandler("copyHandler", "");
	}
#endif

	//
	//	Create the top level directory
	//
	dir = new MaDir(host);
	dir->setPath(docRootPath);
	host->insertDir(dir);

	//
	//	Add cgi-bin
	//
	mprSprintf(pathBuf, sizeof(pathBuf), "%s/cgi-bin", serverRoot);
	ap = new MaAlias("/cgi-bin/", pathBuf);
	mprLog(4, "ScriptAlias \"/cgi-bin/\":\n\t\t\t\"%s\"\n", pathBuf);
	host->insertAlias(ap);
	loc = new MaLocation(dir->getAuth());
	loc->setPrefix("/cgi-bin/");
	loc->setHandler("cgiHandler");
	host->insertLocation(loc);

	mprFree(docRootPath);
	return 0;
}
Пример #7
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;
}
Пример #8
0
static int realMain(MprCmdLine *cmdLine)
{
	MaHttp		*http;
	char        portNumBuf[MPR_MAX_IP_PORT];
	char		*argp, *logSpec;
	int			c, errflg, kill, poolThreads, outputVersion;

	mprSetMemHandler(memoryFailure);
	mprCreateMemHeap(0, 16 * 1024, MAXINT);
	program = mprGetBaseName(cmdLine->getArgv()[0]);

	poolThreads = -1;
	kill = errflg = 0;
	logSpec = 0;
	outputVersion = 0;
	autoScan = 1;
	background = 0;

	serverRoot = 0;
	docRoot = "web";

#if !WIN && !WINCE && !VXWORKS
	if (getuid()) {
		ipAddr = mprStrdup("4000");

	} else {
		mprSprintf(portNumBuf, sizeof(portNumBuf), "%d", 
			MA_SERVER_DEFAULT_PORT_NUM);
		ipAddr = mprStrdup(portNumBuf);
	}
#else
	mprSprintf(portNumBuf, sizeof(portNumBuf), "%d", 
		MA_SERVER_DEFAULT_PORT_NUM);
	    
	ipAddr = mprStrdup(portNumBuf);
#endif

	while ((c = cmdLine->next(&argp)) != EOF) {
		switch(c) {
		case 'A':
			autoScan = 0;
			break;

		case 'a':
			mprFree(ipAddr);
			ipAddr = mprStrdup(argp);
			break;
			
		case 'b':
			background++;
			break;

		case 'c':
			/* Ignored */
			break;

		case 'D':
			mprSetDebugMode(1);
			break;

		case 'd':
			docRoot = argp;
			break;

		case 'f':
#if BLD_FEATURE_CONFIG_PARSE
			configFile = argp;
			autoScan = 0;
#else
			errflg++;
#endif
			break;

		case 'k':
			kill++;
			logSpec = 0;
			break;

		case 'l':
			logSpec = (*argp) ? argp : 0;
			break;

		case 'm':
			mprRequestMemStats(1);
			break;

		case 'r':
			serverRoot = argp;
			break;
		
		case 't':
			poolThreads = atoi(argp);
			break;

			//
			//	FUTURE -- just for test. Will be removed
			//
		case 'w':
			writeFile = argp;
			break;

		case 'v':
			outputVersion++;
			break;
		
#if WIN && BLD_FEATURE_RUN_AS_SERVICE
		case 'i':
			serviceOp = MPR_INSTALL_SERVICE;
			if (strcmp(argp, "none") == 0) {
				serviceCmdLine = "";
			} else if (strcmp(argp, "default") == 0) {
				serviceCmdLine = "-b -c -f " BLD_PRODUCT ".conf";
			} else {
				serviceCmdLine = argp;
			}
			break;

		case 'g':
			serviceOp = MPR_GO_SERVICE;
			break;

		case 's':
			serviceOp = MPR_STOP_SERVICE;
			break;

		case 'u':
			serviceOp = MPR_UNINSTALL_SERVICE;
			break;

#endif
		default:
			errflg++;
			break;
		}
	}

	if (errflg) {
		printUsage(program);
		return MPR_ERR_BAD_SYNTAX;
	}	

	mp = new Mpr(program);
	mp->setAppName(BLD_PRODUCT);
	mp->setAppTitle(BLD_NAME);
	mp->setHeadless(isService || background);

#if BLD_HOST_UNIX || VXWORKS
	initSignals();
#endif

	if (kill) {
		mp->killMpr();
		delete mp;
		exit(0);
	}

	if (outputVersion) {
		printVersion();
		delete mp;
		exit(0);
	}

	//
	//	Create the top level HTTP service and default HTTP server
	//
	http = new MaHttp();
	server = new MaServer(http, "default");
	setupFileSystem();
	
	setLogging(logSpec);

	//
	//	Confirm the location of the server root
	//
	if (locateServerRoot(serverRoot) < 0) {
		mprError(MPR_L, MPR_USER, "Can't start server, exiting.");
		exit(2);
	}

	if (securityChecks(cmdLine->getArgv()[0]) < 0) {
		exit(3);
	}

#if WIN
#if BLD_FEATURE_RUN_AS_SERVICE
	if (serviceOp) {
		windowsServiceOps();
		delete mp;
		return 0;
	}
#endif
	if (windowsInit() < 0) {
		delete mp;
		return MPR_ERR_CANT_INITIALIZE;
	}
#endif

	//
	//	Start the MPR. This starts Timer, Socket and Pool services
	//
	if (mp->start(MPR_KILLABLE) < 0) {
		mprError(MPR_L, MPR_USER, "Can't start MPR for %s", mp->getAppTitle());
		delete mp;
		return MPR_ERR_CANT_INITIALIZE;
	}

	//
	//	Load the statically linked modules
	//
	maLoadStaticModules();

	if (setupServer(http, poolThreads) < 0) {
		mprError(MPR_L, MPR_USER, "Can't configure the server, exiting.");
		exit(6);
	}

#if BLD_FEATURE_CONFIG_SAVE
	if (writeFile) {
		server->saveConfig(writeFile);
		mprLog(0, "Configuration saved to %s\nExiting ...\n", writeFile);
		exit(0);
	}
#endif

	if (http->start() < 0) {
		mprError(MPR_L, MPR_USER, "Can't start server, exiting.");
		exit(7); 

	} else {
#if LINUX && BLD_FEATURE_RUN_AS_SERVICE
		if (background && mp->makeDaemon(1) < 0) {
			mprError(MPR_L, MPR_USER, "Could not run in the background");
		} else 
#endif
		{
#if BLD_FEATURE_MULTITHREAD
			mprLog(MPR_CONFIG, 
				"HTTP services are ready with %d pool threads\n",
				http->getLimits()->maxThreads);
#else
			mprLog(MPR_CONFIG, 
				"HTTP services are ready (single-threaded).\n");
#endif
		}
		mp->setHeadless(1);

		eventLoop();

		mprLog(MPR_WARN, "Stopping HTTP services.\n");
		http->stop();
	}

#if WIN
	if (trayIcon > 0) {
		closeTrayIcon();
	}
	if (trayTimer) {
		trayTimer->stop(MPR_TIMEOUT_STOP);
		trayTimer->dispose();
		trayTimer = 0;
	}
#endif

	mprLog(MPR_WARN, "Stopping MPR services.\n");
	mp->stop(0);
	maUnloadStaticModules();
	delete server;
	delete http;
	delete mp;

	mprFree(ipAddr);

#if BLD_FEATURE_ROMFS
	delete romFileSystem;
#endif

#if BLD_FEATURE_LOG
	mprLog(MPR_WARN, "Closing log.\n");
	if (logger) {
		delete logger;
	}
#if WIN
	if (dialog) {
		delete dialog;
	}
#endif
#endif
	return 0;
}
Пример #9
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;
}
Пример #10
0
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;
}
Пример #11
0
static void angel()
{
    PROCESS_INFORMATION procInfo;
    STARTUPINFO         startInfo;
    MprTime             mark;
    ulong               status;
    char                *dir, *homeDir, *serviceArgs;
    char                key[MPR_MAX_FNAME], path[MPR_MAX_FNAME], cmd[MPR_MAX_FNAME];
    int                 createFlags, restartWarned;

    servicePid = 0;
    createFlags = 0;
    restartWarned = 0;

#if USEFUL_FOR_DEBUG
    DebugBreak();
#endif

    /*
     *  Read the service home directory and args. Default to the current dir if none specified.
     */
    homeDir = 0;
    serviceArgs = 0;
    mprSprintf(key, sizeof(key), "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%s", serviceName);
    mprReadRegistry(mpr, &homeDir, MPR_MAX_FNAME, key, "HomeDir");
    mprReadRegistry(mpr, &serviceArgs, MPR_MAX_FNAME, key, "Args");

    /*
     *  Expect to find the service executable in the same directory as this angel program.
     */
    if (serviceProgram == 0) {
        GetModuleFileName(0, path, sizeof(path));
        dir = mprGetPathDir(mpr, path);
        mprSprintf(path, sizeof(path), "\"%s\\%s.exe\"", dir, BLD_PRODUCT);
        mprFree(dir);
    } else {
        mprSprintf(path, sizeof(path), "\"%s\"", serviceProgram);
    }

    if (serviceArgs && *serviceArgs) {
        mprSprintf(cmd, sizeof(cmd), "%s %s", path, serviceArgs);
    } else {
        mprSprintf(cmd, sizeof(cmd), "%s", path);
    }

    if (createConsole) {
        createFlags |= CREATE_NEW_CONSOLE;
    }

    mark = mprGetTime(mpr);

    while (! exiting) {

        if (mprGetElapsedTime(mpr, mark) > (3600 * 1000)) {
            mark = mprGetTime(mpr);
            restartCount = 0;
            restartWarned = 0;
        }

        if (servicePid == 0 && !serviceStopped) {
            if (restartCount >= RESTART_MAX) {
                if (! restartWarned) {
                    mprError(mpr, "Too many restarts for %s, %d in ths last hour", appTitle, restartCount);
                    restartWarned++;
                }
                /*
                 *  This is not a real heart-beat. We are only waiting till the service process exits.
                 */
                WaitForSingleObject(heartBeatEvent, heartBeatPeriod);
                continue;
            }

            memset(&startInfo, 0, sizeof(startInfo));
            startInfo.cb = sizeof(startInfo);

            /*
             *  Launch the process
             */
            if (! CreateProcess(0, cmd, 0, 0, FALSE, createFlags, 0, homeDir, &startInfo, &procInfo)) {
                mprError(mpr, "Can't create process: %s, %d", cmd, mprGetOsError());

            } else {
                servicePid = (int) procInfo.hProcess;
            }
            restartCount++;
        }
        WaitForSingleObject(heartBeatEvent, heartBeatPeriod);

        if (servicePid) {
            if (GetExitCodeProcess((HANDLE) servicePid, (ulong*) &status)) {
                if (status != STILL_ACTIVE) {
                    CloseHandle((HANDLE) servicePid);
                    servicePid = 0;
                }

            } else {
                CloseHandle((HANDLE) servicePid);
                servicePid = 0;
            }
        }
        if (verbose) {
            mprPrintf(mpr, "%s has exited with status %d\n", serviceProgram, status);
            mprPrintf(mpr, "%s will be restarted in 10 seconds\n", serviceProgram);
        }
    }
    mprFree(homeDir);
    mprFree(serviceArgs);
}
Пример #12
0
int	MprSocket::write(char *buf, int bufsize)
{
#if BLD_FEATURE_IPV6
	struct addrinfo 	hints, *res;
	struct sockaddr_storage	server6;
	char 				port_string[MPR_MAX_IP_PORT];
	int 				rc;
#endif				
	struct sockaddr_in	server;
	struct sockaddr 	*sa;
	MprSocklen 			addrlen;
	int					sofar, errCode, len, written;

	mprAssert(buf);
	mprAssert(bufsize >= 0);
	mprAssert((flags & MPR_SOCKET_CLOSED) == 0);

	addrlen = 0;
	sa = 0;

	lock();

	if (flags & (MPR_SOCKET_BROADCAST | MPR_SOCKET_DATAGRAM)) {
#if BLD_FEATURE_IPV6
		if (ipv6) {
			memset((char *) &hints, '\0', sizeof(hints));
			memset((char *) &server, '\0', sizeof(struct sockaddr_storage));
			
			mprSprintf(port_string, sizeof(port_string), "%d", port);

			hints.ai_socktype = SOCK_STREAM;
			hints.ai_flags = AI_NUMERICHOST;

			if (strcmp(ipAddr, "") == 0) {
				//	Note that IPv6 does not support broadcast, there is no
				//	255.255.255.255 equiv. Multicast can be used over a specific 
				//	link, but the user must provide that address plus %scope_id.
				unlock();
				return -1;
			}

			rc = getaddrinfo(ipAddr, port_string, &hints, &res);
			if (rc) {
				unlock();
				return -1;

			} else {
				memcpy(&server, res->ai_addr, res->ai_addrlen);
				addrlen = res->ai_addrlen;
				freeaddrinfo(res);
			}
			sa = (struct sockaddr*) &server6;

		} else 
#endif
		{
			memset((char*) &server, '\0', sizeof(struct sockaddr_in));
			addrlen = sizeof(struct sockaddr_in);
			server.sin_family = AF_INET;

			server.sin_port = htons((short) (port & 0xFFFF));
			if (strcmp(ipAddr, "") != 0) {
				server.sin_addr.s_addr = inet_addr(ipAddr);
			} else {
				server.sin_addr.s_addr = INADDR_ANY;
			}
			sa = (struct sockaddr*) &server;
		}
	}
	
		
	if (flags & MPR_SOCKET_EOF) {
		sofar = bufsize;

	} else {
		errCode = 0;
		len = bufsize;
		sofar = 0;
		while (len > 0) {
			if ((flags & MPR_SOCKET_BROADCAST) || 
					(flags & MPR_SOCKET_DATAGRAM)) {
				written = sendto(sock, &buf[sofar], len, MSG_NOSIGNAL, sa, addrlen);
			} else {
				written = send(sock, &buf[sofar], len, MSG_NOSIGNAL);
			}
			if (written < 0) {
				errCode = getError();
				if (errCode == EINTR) {
					mprLog(8, log, "%d: write: EINTR\n", sock);
					continue;
				} else if (errCode == EAGAIN || errCode == EWOULDBLOCK) {
					mprLog(8, log, "%d: write: EAGAIN returning %d\n", sock, sofar);
					unlock();
					return sofar;
				}
				mprLog(8, log, "%d: write: error %d\n", sock, -errCode);
				unlock();
				return -errCode;
			}
			len -= written;
			sofar += written;
		}
	}

	mprLog(8, log, "%d: write: %d bytes, ask %d, flags %x\n", sock, sofar, bufsize, flags);

	unlock();
	return sofar;
}
Пример #13
0
int main(int argc, char *argv[])
{
	double			elapsed;
	char			*programName, *argp, *logSpec;
	int				c, errflg, start;
#if BLD_FEATURE_LOG
	MprLogToFile	*logger;
#endif
#if BLD_FEATURE_MULTITHREAD
	MprThread		*threadp;
#endif

	programName = mprGetBaseName(argv[0]);
	method = "GET";
	fileList = cmpDir = writeDir = 0;
	verbose = continueOnErrors = outputHeader = errflg = 0;
	poolThreads = 4;			// Need at least one to run efficiently
	httpVersion = 1;			// HTTP/1.1
	success = 1;
	trace = 0;
	host = "localhost";
	logSpec = "stdout:1";
	postData = 0;
	postLen = 0;
	retries = MPR_HTTP_CLIENT_RETRIES;
	iterations = HTTP_DEFAULT_ITERATIONS;
	loadThreads = HTTP_DEFAULT_LOAD_THREADS;
	timeout = MPR_HTTP_CLIENT_TIMEOUT;

#if BLD_FEATURE_MULTITHREAD
	mutex = new MprMutex();
#endif

	//
	//	FUTURE: switch to GNU style --args with a better usage message
	//
	MprCmdLine	cmdLine(argc, argv, "bC:cDd:f:Hh:i:l:M:mqo:r:st:T:vV:w:");
	while ((c = cmdLine.next(&argp)) != EOF) {
		switch(c) {
		case 'b':
			benchmark++;
			break;

		case 'c':
			continueOnErrors++;
			break;

		case 'C':
			cmpDir = argp;
			break;

		case 'd':
			postData = argp;
			postLen = strlen(postData);
			break;

		case 'D':
			mprSetDebugMode(1);
			break;

		case 'f':
			fileList = argp;
			break;

		case 'h':
			host = argp;
			break;

		case 'H':
			outputHeader++;
			break;

		case 'i':
			iterations = atoi(argp);
			break;

		case 'l':
			logSpec = argp;
			break;

		case 'm':
			mprRequestMemStats(1);
			break;

		case 'M':
			method = argp;
			break;

		case 'o':
			timeout = atoi(argp);
			break;

		case 'q':
			quietMode++;
			break;

		case 'r':
			retries = atoi(argp);
			break;

		case 's':
			singleStep++;
			break;

		case 't':
			loadThreads = atoi(argp);
			break;

		case 'T':
			poolThreads = atoi(argp);
			break;

		case 'v':
			verbose++;
			trace++;
			break;

		case 'V':
			httpVersion = atoi(argp);
			break;

		case 'w':
			writeDir = argp;
			break;

		default:
			errflg++;
			break;
		}
	}
	if (writeDir && (loadThreads > 1)) {
		errflg++;
	}

	if (errflg) {
		mprFprintf(MPR_STDERR, 
			"usage: %s [-bcHMmqsTv] [-C cmpDir] [-d postData] [-f fileList]\n"
			"	[-i iterations] [-l logSpec] [-M method] [-o timeout]\n"
			"	[-h host] [-r retries] [-t threads] [-T poolThreads]\n"
			"	[-V httpVersion] [-w writeDir] [urls...]\n", programName);
		exit(2);
	}
	saveArgc = argc - cmdLine.firstArg();
	saveArgv = &argv[cmdLine.firstArg()];

	mpr = new Mpr(programName);

#if BLD_FEATURE_LOG
	tMod = new MprLogModule("httpClient");
	logger = new MprLogToFile();
	mpr->addListener(logger);
	if (mpr->setLogSpec(logSpec) < 0) {
		mprFprintf(MPR_STDERR, "Can't open log file %s\n", logSpec);
		exit(2);
	}
#endif

	//
	//	Alternatively, set the configuration manually
	//
	mpr->setAppTitle("Embedthis HTTP Client");
#if BLD_FEATURE_MULTITHREAD
	mpr->setMaxPoolThreads(poolThreads);
#endif

	//
	//	Start the Timer, Socket and Pool services
	//
	if (mpr->start(MPR_SERVICE_THREAD) < 0) {
		mprError(MPR_L, MPR_USER, "Can't start MPR for %s", mpr->getAppTitle());
		delete mpr;
		exit(2);
	}

	//
	//	Create extra test threads to run the tests as required. We use
	//	the main thread also (so start with j==1)
	//
	start = mprGetTime(0);
#if BLD_FEATURE_MULTITHREAD
	activeLoadThreads = loadThreads;
	for (int j = 1; j < loadThreads; j++) {
		char name[64];
		mprSprintf(name, sizeof(name), "t.%d", j - 1);
		threadp = new MprThread(doTests, MPR_NORMAL_PRIORITY, (void*) j, name); 
		threadp->start();
	}
#endif

	doTests(0, 0);

	//
	//	Wait for all the threads to complete (simple but effective). Keep 
	//	servicing events as we wind down.
	//
	while (activeLoadThreads > 1) {
		mprSleep(100);
	}

	if (benchmark && success) {
		elapsed = (mprGetTime(0) - start);
		if (fetchCount == 0) {
			elapsed = 0;
			fetchCount = 1;
		}
		mprPrintf("\tThreads %d, Pool Threads %d   \t%13.2f\t%12.2f\t%6d\n", 
			loadThreads, poolThreads, elapsed * 1000.0 / fetchCount, 
			elapsed / 1000.0, fetchCount);

		mprPrintf("\nTime elapsed:        %13.4f sec\n", elapsed / 1000.0);
		mprPrintf("Time per request:    %13.4f sec\n", elapsed / 1000.0 
			/ fetchCount);
		mprPrintf("Requests per second: %13.4f\n", fetchCount * 1.0 / 
			(elapsed / 1000.0));
	}
	if (! quietMode) {
		mprPrintf("\n");
	}

	mpr->stop(0);

#if BLD_FEATURE_MULTITHREAD
	delete mutex;
#endif
#if BLD_FEATURE_LOG
	delete tMod;
#endif

	delete mpr;
#if BLD_FEATURE_LOG
	delete logger;
#endif
	mprMemClose();
	return (success) ? 0 : 255;
}
Пример #14
0
int MprSocket::openServer(char *addr, int portNum, MprSocketAcceptProc acceptFn, 
						  void *data, int initialFlags)
{
#if BLD_FEATURE_IPV6
	struct addrinfo		hints, *res;
	struct sockaddr_storage	sockAddr6;
	char 				portNumString[MPR_MAX_IP_PORT];
	char 				addrBuf[MPR_MAX_IP_ADDR];
	char 				*bindName;
#endif
	struct sockaddr_in	sockAddr;
	struct sockaddr 	*sa;
	struct hostent		*hostent;
	MprSocklen 			addrlen;
	int					datagram, rc;

	mprAssert(addr);

	if (addr == 0 || *addr == '\0') {
		mprLog(6, log, "openServer: *:%d, flags %x\n", portNum, initialFlags);
	} else {
		mprLog(6, log, "openServer: %s:%d, flags %x\n", addr, portNum, initialFlags);
	}


#if BLD_FEATURE_IPV6

	if (addr[0] == '[') {
		ipv6 = 1;
		mprStrcpy(addrBuf, sizeof(addrBuf), &addr[1]);
		mprAssert(addrBuf[strlen(addrBuf) - 1] == ']');
		addrBuf[strlen(addrBuf) - 1] = '\0';
		addr = addrBuf;
	}

	if (ipv6) {
		memset((char *) &hints, '\0', sizeof(hints));
		memset((char *) &sockAddr6, '\0', sizeof(struct sockaddr_storage));

		mprSprintf(portNumString, sizeof(portNumString), "%d", portNum);

		hints.ai_socktype = SOCK_STREAM;
		hints.ai_family = AF_INET6;

		if (strcmp(addr, "") != 0) {
			bindName = addr;
		} else {
			bindName = NULL;
			hints.ai_flags |= AI_PASSIVE; 				/* Bind to 0.0.0.0 and :: */
														/* Sets to IN6ADDR_ANY_INIT */
		}
			
		rc = getaddrinfo(bindName, portNumString, &hints, &res);
		if (rc) {
			return MPR_ERR_CANT_OPEN;

		}
		sa = (struct sockaddr*) &sockAddr6;
		memcpy(sa, res->ai_addr, res->ai_addrlen);
		addrlen = res->ai_addrlen;
		freeaddrinfo(res);

	} else 
#endif
	{
		/*
		 *	TODO could we use getaddrinfo in all cases. ie. merge with IPV6 code
		 */
		memset((char *) &sockAddr, '\0', sizeof(struct sockaddr_in));
		addrlen = sizeof(struct sockaddr_in);
		sockAddr.sin_family = AF_INET;

		sockAddr.sin_port = htons((short) (portNum & 0xFFFF));
		if (strcmp(addr, "") != 0) {
			sockAddr.sin_addr.s_addr = inet_addr(addr);
			if (sockAddr.sin_addr.s_addr == INADDR_NONE) {
				hostent = mprGetHostByName(addr);
				if (hostent != 0) {
					memcpy((char*) &sockAddr.sin_addr, (char*) hostent->h_addr_list[0], 
						(size_t) hostent->h_length);
					mprFreeGetHostByName(hostent);
				} else {
					return MPR_ERR_NOT_FOUND;
				}
			}
		} else {
			sockAddr.sin_addr.s_addr = INADDR_ANY;
		}
		sa = (struct sockaddr*) &sockAddr;
	}

	lock();
	port = portNum;
	acceptCallback = acceptFn;
	acceptData = data;

	flags = (initialFlags & 
		(MPR_SOCKET_BROADCAST | MPR_SOCKET_DATAGRAM | MPR_SOCKET_BLOCK | 
		 MPR_SOCKET_LISTENER | MPR_SOCKET_NOREUSE | MPR_SOCKET_NODELAY));

	ipAddr = mprStrdup(addr);

	datagram = flags & MPR_SOCKET_DATAGRAM;

	//
	//	Create the O/S socket
	//
	sock = socket(sa->sa_family, datagram ? SOCK_DGRAM: SOCK_STREAM, 0);
	if (sock < 0) {
		unlock();
		return MPR_ERR_CANT_OPEN;
	}
#if !WIN && !WINCE && !VXWORKS
	fcntl(sock, F_SETFD, FD_CLOEXEC);		// Children won't inherit this fd
#endif

#if CYGWIN || LINUX || MACOSX || VXWORKS || FREEBSD
	if (!(flags & MPR_SOCKET_NOREUSE)) {
		rc = 1;
		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &rc, sizeof(rc));
	}
#endif

	rc = bind(sock, sa, addrlen);
	// rc = bind(sock, res->ai_addr, res->ai_addrlen);
	if (rc < 0) {
		int err = errno;
		err = err;
		::closesocket(sock);
		sock = -1;
		unlock();
		return MPR_ERR_CANT_OPEN;
	}

	if (! datagram) {
		flags |= MPR_SOCKET_LISTENER;
		if (listen(sock, SOMAXCONN) < 0) {
			::closesocket(sock);
			sock = -1;
			unlock();
			return MPR_ERR_CANT_OPEN;
		}
		handler = new MprSelectHandler(sock, MPR_SOCKET_READABLE, 
			(MprSelectProc) acceptProcWrapper, (void*) this, handlerPriority);
	}
	handlerMask |= MPR_SOCKET_READABLE;

//TODO - what about WINCE?
#if WIN
	//
	//	Delay setting reuse until now so that we can be assured that we
	//	have exclusive use of the port.
	//
	if (!(flags & MPR_SOCKET_NOREUSE)) {
		rc = 1;
		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &rc, sizeof(rc));
	}
#endif

	setBlockingMode((bool) (flags & MPR_SOCKET_BLOCK));

	//
	//	TCP/IP stacks have the No delay option (nagle algorithm) on by default.
	//
	if (flags & MPR_SOCKET_NODELAY) {
		setNoDelay(1);
	}
	unlock();
	return sock;
}
Пример #15
0
int MprSocket::openClient(char *addr, int portNum, int initialFlags)
{
#if BLD_FEATURE_IPV6
	struct addrinfo 	hints, *res;
	struct sockaddr_storage	remoteAddr6;
	char 				portNum_string[MPR_MAX_IP_PORT];
	char 				addrBuf[MPR_MAX_IP_ADDR];
#endif
	struct sockaddr_in	remoteAddr;
	struct hostent		*hostent;
	struct sockaddr 	*sa;
	MprSocklen			addrlen;
	int					broadcast, datagram, rc, err;

	mprLog(6, log, "openClient: %s:%d, flags %x\n", addr, portNum, 
		initialFlags);

#if BLD_FEATURE_IPV6
	if (addr[0] == '[') {
		ipv6 = 1;
		mprStrcpy(addrBuf, sizeof(addr), &addr[1]);
		mprAssert(addrBuf[strlen(addrBuf) - 2] == ']');
		addrBuf[strlen(addrBuf) - 2] = '\0';
		addr = addrBuf;
	} else {
        ipv6 = 0;
    }

	if (ipv6) {
		memset((char*) &hints, '\0', sizeof(hints));
		memset((char*) &remoteAddr6, '\0', sizeof(struct sockaddr_storage));

		mprSprintf(portNum_string, sizeof(portNum_string), "%d", portNum);

		hints.ai_socktype = SOCK_STREAM;

		rc = getaddrinfo(addr, portNum_string, &hints, &res);
		if (rc) {
			/* no need to unlock yet */
			return MPR_ERR_CANT_OPEN;

		}
		sa = (struct sockaddr*) &remoteAddr6;
		memcpy(sa, res->ai_addr, res->ai_addrlen);
		addrlen = res->ai_addrlen;
		freeaddrinfo(res);
		
	} else 
#endif
	{
		memset((char *) &remoteAddr, '\0', sizeof(struct sockaddr_in));
		remoteAddr.sin_family = AF_INET;
		remoteAddr.sin_port = htons((short) (portNum & 0xFFFF));
		sa = (struct sockaddr*) &remoteAddr;
		addrlen = sizeof(remoteAddr);
	}
		
	lock();
	port = portNum;
	flags = (initialFlags & 
		(MPR_SOCKET_BROADCAST | MPR_SOCKET_DATAGRAM | MPR_SOCKET_BLOCK | 
		 MPR_SOCKET_LISTENER | MPR_SOCKET_NOREUSE | MPR_SOCKET_NODELAY));

	//	Save copy of the address
	ipAddr = mprStrdup(addr);

#if BLD_FEATURE_IPV6
	if (!ipv6) {
		// Nothing here
	} else 
#endif
	{
		remoteAddr.sin_addr.s_addr = inet_addr(ipAddr);
		if (remoteAddr.sin_addr.s_addr == INADDR_NONE) {
			hostent = mprGetHostByName(ipAddr);
			if (hostent != 0) {
				memcpy((char*) &remoteAddr.sin_addr, (char*) hostent->h_addr_list[0], 
					(size_t) hostent->h_length);
				mprFreeGetHostByName(hostent);
			} else {
				unlock();
				return MPR_ERR_NOT_FOUND;
			}
		}
	}

	broadcast = flags & MPR_SOCKET_BROADCAST;
	if (broadcast) {
		flags |= MPR_SOCKET_DATAGRAM;
	}
	datagram = flags & MPR_SOCKET_DATAGRAM;

	//
	//	Create the O/S socket
	//
	sock = socket(sa->sa_family, datagram ? SOCK_DGRAM: SOCK_STREAM, 0);
	if (sock < 0) {
		err = getError();
		unlock();
		return -err;
	}
#if !WIN && !WINCE && !VXWORKS
	fcntl(sock, F_SETFD, FD_CLOEXEC);		// Children won't inherit this fd
#endif

	if (broadcast) {
		int	flag = 1;
		if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &flag, sizeof(flag)) < 0) {
			err = getError();
			::closesocket(sock);
			sock = -1;
			unlock();
			return -err;
		}
	}
 
	if (!datagram) {
		flags |= MPR_SOCKET_CONNECTING;
		rc = connect(sock, sa, addrlen);
		if (rc < 0) {
			err = getError();
			::closesocket(sock);
			sock = -1;
			unlock();
#if UNUSED
			//
			//	If the listen backlog is too high, ECONNREFUSED is returned
			//
			if (err == EADDRINUSE || err == ECONNREFUSED) {
				return MPR_ERR_BUSY;
			}
#endif
			return -err;
		}
	}

	setBlockingMode((bool) (flags & MPR_SOCKET_BLOCK));

	//
	//	TCP/IP stacks have the No delay option (nagle algorithm) on by default.
	//
	if (flags & MPR_SOCKET_NODELAY) {
		setNoDelay(1);
	}
	unlock();
	return sock;
}
Пример #16
0
static void outputLine(MaQueue *q, MprDirEntry *ep, cchar *path, int nameSize)
{
    MprPath     info;
    Dir         *dir;
    MprTime     when;
    MaHost      *host;
    char        *newPath, sizeBuf[16], timeBuf[48], *icon;
    struct tm   tm;
    bool        isDir;
    int         len;
    cchar       *ext, *mimeType;
    char        *dirSuffix;
    char        *months[] = { 
                    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
                };

    dir = q->stage->stageData;
    if (ep->size >= (1024*1024*1024)) {
        fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024 * 1024, "G");

    } else if (ep->size >= (1024*1024)) {
        fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024, "M");

    } else if (ep->size >= 1024) {
        fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024, "K");

    } else {
        mprSprintf(sizeBuf, sizeof(sizeBuf), "%6d", (int) ep->size);
    }

    newPath = mprJoinPath(q, path, ep->name);

    if (mprGetPathInfo(q, newPath, &info) < 0) {
        when = mprGetTime(q);
        isDir = 0;

    } else {
        isDir = info.isDir ? 1 : 0;
        when = (MprTime) info.mtime * MPR_TICKS_PER_SEC;
    }
    mprFree(newPath);

    if (isDir) {
        icon = "folder";
        dirSuffix = "/";
    } else {
        host = q->conn->host;
        ext = mprGetPathExtension(q, ep->name);
        if ((mimeType = maLookupMimeType(host, ext)) != 0) {
            if (strcmp(ext, "es") == 0 || strcmp(ext, "ejs") == 0 || strcmp(ext, "php") == 0) {
                icon = "text";
            } else if (strstr(mimeType, "text") != 0) {
                icon = "text";
            } else {
                icon = "compressed";
            }
        } else {
            icon = "compressed";
        }
        dirSuffix = "";
    }

    mprDecodeLocalTime(q, &tm, when);

    mprSprintf(timeBuf, sizeof(timeBuf), "%02d-%3s-%4d %02d:%02d",
        tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour,  tm.tm_min);

    len = (int) strlen(ep->name) + (int) strlen(dirSuffix);

    if (dir->fancyIndexing == 2) {

        maWrite(q, "<tr><td valign=\"top\">");
        maWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[   ]\", /></td>", icon);
        maWrite(q, "<td><a href=\"%s%s\">%s%s</a></td>", ep->name, dirSuffix, ep->name, dirSuffix);
        maWrite(q, "<td>%s</td><td>%s</td></tr>\r\n", timeBuf, sizeBuf);

    } else if (dir->fancyIndexing == 1) {

        maWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[   ]\", /> ", icon);
        maWrite(q, "<a href=\"%s%s\">%s%s</a>%-*s %17s %4s\r\n", ep->name, dirSuffix, ep->name, dirSuffix, 
            nameSize - len, "", timeBuf, sizeBuf);

    } else {
        maWrite(q, "<li><a href=\"%s%s\"> %s%s</a></li>\r\n", ep->name, dirSuffix, ep->name, dirSuffix);
    }
}
Пример #17
0
/*
 *  Sanitize args. Convert "/" to "\" and converting '\r' and '\n' to spaces, quote all args and put the program as argv[0].
 */
static int sanitizeArgs(MprCmd *cmd, int argc, char **argv, char **env)
{
#if VXWORKS
    cmd->argv = argv;
    cmd->argc = argc;
    cmd->env = 0;
#endif
#if BLD_UNIX_LIKE
    char    *cp;
    int     index, i, hasPath, hasLibPath;

    cmd->argv = argv;
    cmd->argc = argc;
    cmd->env = 0;

    if (env) {
        for (i = 0; env && env[i]; i++) {
            mprLog(cmd, 6, "cmd: env[%d]: %s", i, env[i]);
        }
        if ((cmd->env = mprAlloc(cmd, (i + 3) * (int) sizeof(char*))) == NULL) {
            return MPR_ERR_NO_MEMORY;
        }
        hasPath = hasLibPath = 0;
        for (index = i = 0; env && env[i]; i++) {
            mprLog(cmd, 6, "cmd: env[%d]: %s", i, env[i]);
            if (strncmp(env[i], "PATH=", 5) == 0) {
                hasPath++;
            } else if  (strncmp(env[i], LD_LIBRARY_PATH "=", 16) == 0) {
                hasLibPath++;
            }
            cmd->env[index++] = env[i];
        }

        /*
         *  Add PATH and LD_LIBRARY_PATH 
         */
        if (!hasPath && (cp = getenv("PATH")) != 0) {
            cmd->env[index++] = mprAsprintf(cmd, -1, "PATH=%s", cp);
        }
        if (!hasLibPath && (cp = getenv(LD_LIBRARY_PATH)) != 0) {
            cmd->env[index++] = mprAsprintf(cmd, -1, "%s=%s", LD_LIBRARY_PATH, cp);
        }
        cmd->env[index++] = '\0';
        for (i = 0; i < argc; i++) {
            mprLog(cmd, 4, "cmd: arg[%d]: %s", i, argv[i]);
        }
        for (i = 0; cmd->env[i]; i++) {
            mprLog(cmd, 4, "cmd: env[%d]: %s", i, cmd->env[i]);
        }
    }
#endif

#if BLD_WIN_LIKE
    char    *program, *SYSTEMROOT, **ep, **ap, *destp, *cp, *progBuf, *localArgv[2], *saveArg0, *PATH, *endp;
    int     i, len, hasPath, hasSystemRoot;

    mprAssert(argc > 0 && argv[0] != NULL);

    cmd->argv = argv;
    cmd->argc = argc;

    program = argv[0];
    progBuf = mprAlloc(cmd, (int) strlen(program) * 2 + 1);
    strcpy(progBuf, program);
    program = progBuf;

    for (cp = program; *cp; cp++) {
        if (*cp == '/') {
            *cp = '\\';
        } else if (*cp == '\r' || *cp == '\n') {
            *cp = ' ';
        }
    }
    if (*program == '\"') {
        if ((cp = strrchr(++program, '"')) != 0) {
            *cp = '\0';
        }
    }

    if (argv == 0) {
        argv = localArgv;
        argv[1] = 0;
        saveArg0 = program;
    } else {
        saveArg0 = argv[0];
    }
    /*
     *  Set argv[0] to the program name while creating the command line. Restore later
     */
    argv[0] = program;

    /*
     *  Determine the command line length and arg count
     */
    argc = 0;
    for (len = 0, ap = argv; *ap; ap++) {
        len += (int) strlen(*ap) + 1 + 2;         /* Space and possible quotes */
        argc++;
    }
    cmd->command = (char*) mprAlloc(cmd, len + 1);
    cmd->command[len] = '\0';
    
    /*
     *  Add quotes to all args that have spaces in them including "program"
     */
    destp = cmd->command;
    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';
    argv[0] = saveArg0;

    for (i = 0; i < argc; i++) {
        mprLog(cmd, 4, "cmd: arg[%d]: %s", i, argv[i]);
    }

    /*
     *  Now work on the environment. Windows has a block of null separated strings with a trailing null.
     */
    cmd->env = 0;
    if (env) {
        for (hasSystemRoot =  hasPath = len = 0, ep = env; ep && *ep; ep++) {
            len += (int) strlen(*ep) + 1;
            if (strncmp(*ep, "PATH=", 5) == 0) {
                hasPath++;
            } else if (strncmp(*ep, "SYSTEMROOT=", 11) == 0) {
                hasSystemRoot++;
            }
        }
        if (!hasSystemRoot && (SYSTEMROOT = getenv("SYSTEMROOT")) != 0) {
            len += 11 + (int) strlen(SYSTEMROOT) + 1;
        }
        if (!hasPath && (PATH = getenv("PATH")) != 0) {
            len += 5 + (int) strlen(PATH) + 1;
        }
        len += 2;       /* Windows requires 2 nulls for the block end */

        destp = (char*) mprAlloc(cmd, len);
        endp = &destp[len];
        cmd->env = (char**) destp;
        for (ep = env; ep && *ep; ep++) {
            mprLog(cmd, 4, "cmd: env[%d]: %s", i, *ep);
            strcpy(destp, *ep);
            mprLog(cmd, 7, "cmd: Set env variable: %s", destp);
            destp += strlen(*ep) + 1;
        }
        if (!hasSystemRoot) {
            mprSprintf(destp, endp - destp - 1, "SYSTEMROOT=%s", SYSTEMROOT);
            destp += 12 + strlen(SYSTEMROOT);
        }
        if (!hasPath) {
            mprSprintf(destp, endp - destp - 1, "PATH=%s", PATH);
            destp += 6 + strlen(PATH);
        }
        *destp++ = '\0';
        *destp++ = '\0';                        /* Windows requires two nulls */
        mprAssert(destp <= endp);
#if TEST
        for (cp = (char*) cmd->env; *cp; cp++) {
            print("ENV %s\n", cp);
            cp += strlen(cp);
        }
#endif
    }
#endif /* BLD_WIN_LIKE */
    return 0;
}
Пример #18
0
/*
    Build the command arguments. NOTE: argv is untrusted input.
 */
static void buildArgs(MaConn *conn, MprCmd *cmd, int *argcp, char ***argvp)
{
    MaRequest   *req;
    MaResponse  *resp;
    char        *fileName, **argv, status[8], *indexQuery, *cp, *tok;
    cchar       *actionProgram;
    int         argc, argind, len;

    req = conn->request;
    resp = conn->response;
    fileName = resp->filename;
    mprAssert(fileName);

    actionProgram = 0;
    argind = 0;
    argc = *argcp;

    if (resp->extension) {
        actionProgram = maGetMimeActionProgram(req->host, resp->extension);
        if (actionProgram != 0) {
            argc++;
        }
    }
    /*
        This is an Apache compatible hack for PHP 5.3
     */
    mprItoa(status, sizeof(status), MPR_HTTP_CODE_MOVED_TEMPORARILY, 10);
    mprAddHash(req->headers, "REDIRECT_STATUS", mprStrdup(req, status));

    /*
        Count the args for ISINDEX queries. Only valid if there is not a "=" in the query. 
        If this is so, then we must not have these args in the query env also?
     */
    indexQuery = req->parsedUri->query;
    if (indexQuery && !strchr(indexQuery, '=')) {
        argc++;
        for (cp = indexQuery; *cp; cp++) {
            if (*cp == '+') {
                argc++;
            }
        }
    } else {
        indexQuery = 0;
    }

#if BLD_WIN_LIKE || VXWORKS
{
    char    *bangScript, *cmdBuf, *program, *cmdScript;

    /*
        On windows we attempt to find an executable matching the fileName.
        We look for *.exe, *.bat and also do unix style processing "#!/program"
     */
    findExecutable(conn, &program, &cmdScript, &bangScript, fileName);
    mprAssert(program);

    if (cmdScript) {
        /*
            Cmd/Batch script (.bat | .cmd)
            Convert the command to the form where there are 4 elements in argv
            that cmd.exe can interpret.

                argv[0] = cmd.exe
                argv[1] = /Q
                argv[2] = /C
                argv[3] = ""script" args ..."
         */
        argc = 4;

        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        argv[argind++] = program;               /* Duped in findExecutable */
        argv[argind++] = mprStrdup(cmd, "/Q");
        argv[argind++] = mprStrdup(cmd, "/C");

        len = (int) strlen(cmdScript) + 2 + 1;
        cmdBuf = (char*) mprAlloc(cmd, len);
        mprSprintf(cmdBuf, len, "\"%s\"", cmdScript);
        argv[argind++] = cmdBuf;

        mprSetCmdDir(cmd, cmdScript);
        mprFree(cmdScript);
        /*  program will get freed when argv[] gets freed */
        
    } else if (bangScript) {
        /*
            Script used "#!/program". NOTE: this may be overridden by a mime
            Action directive.
         */
        argc++;     /* Adding bangScript arg */

        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        argv[argind++] = program;       /* Will get freed when argv[] is freed */
        argv[argind++] = bangScript;    /* Will get freed when argv[] is freed */
        mprSetCmdDir(cmd, bangScript);

    } else {
        /*
            Either unknown extension or .exe (.out) program.
         */
        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        if (actionProgram) {
            argv[argind++] = mprStrdup(cmd, actionProgram);
        }
        argv[argind++] = program;
    }
}
#else
    len = (argc + 1) * (int) sizeof(char*);
    argv = (char**) mprAlloc(cmd, len);
    memset(argv, 0, len);

    if (actionProgram) {
        argv[argind++] = mprStrdup(cmd, actionProgram);
    }
    argv[argind++] = mprStrdup(cmd, fileName);

#endif

    /*
        ISINDEX queries. Only valid if there is not a "=" in the query. If this is so, then we must not
        have these args in the query env also?
     */
    if (indexQuery) {
        indexQuery = mprStrdup(cmd, indexQuery);

        cp = mprStrTok(indexQuery, "+", &tok);
        while (cp) {
            argv[argind++] = mprEscapeCmd(resp, mprUrlDecode(resp, cp), 0);
            cp = mprStrTok(NULL, "+", &tok);
        }
    }
    
    mprAssert(argind <= argc);
    argv[argind] = 0;
    *argcp = argc;
    *argvp = argv;
}
Пример #19
0
/*
 *  Create the host addresses for a host. Called for hosts or for NameVirtualHost directives (host == 0).
 */
int maCreateHostAddresses(MaServer *server, MaHost *host, cchar *configValue)
{
    MaListen        *listen;
    MaHostAddress   *address;
    char            *ipAddrPort, *ipAddr, *value, *tok;
    char            addrBuf[MPR_MAX_IP_ADDR_PORT];
    int             next, port;

    address = 0;
    value = mprStrdup(server, configValue);
    ipAddrPort = mprStrTok(value, " \t", &tok);

    while (ipAddrPort) {
        if (mprStrcmpAnyCase(ipAddrPort, "_default_") == 0) {
            mprAssert(0);
            ipAddrPort = "*:*";
        }

        if (mprParseIp(server, ipAddrPort, &ipAddr, &port, -1) < 0) {
            mprError(server, "Can't parse ipAddr %s", ipAddrPort);
            continue;
        }
        mprAssert(ipAddr && *ipAddr);
        if (ipAddr[0] == '*') {
            ipAddr = mprStrdup(server, "");
        }

        /*
         *  For each listening endpiont,
         */
        for (next = 0; (listen = mprGetNextItem(server->listens, &next)) != 0; ) {
            if (port > 0 && port != listen->port) {
                continue;
            }
            if (listen->ipAddr[0] != '\0' && ipAddr[0] != '\0' && strcmp(ipAddr, listen->ipAddr) != 0) {
                continue;
            }

            /*
             *  Find the matching host address or create a new one
             */
            if ((address = maLookupHostAddress(server, listen->ipAddr, listen->port)) == 0) {
                address = maCreateHostAddress(server, listen->ipAddr, listen->port);
                mprAddItem(server->hostAddresses, address);
            }

            /*
             *  If a host is specified
             */
            if (host == 0) {
                maSetNamedVirtualHostAddress(address);

            } else {
                maInsertVirtualHost(address, host);
                if (listen->ipAddr[0] != '\0') {
                    mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", listen->ipAddr, listen->port);
                } else {
                    mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", ipAddr, listen->port);
                }
                maSetHostName(host, addrBuf);
            }
        }
        mprFree(ipAddr);
        ipAddrPort = mprStrTok(0, " \t", &tok);
    }

    if (host) {
        if (address == 0) {
            mprError(server, "No valid IP address for host %s", host->name);
            mprFree(value);
            return MPR_ERR_CANT_INITIALIZE;
        }
        if (maIsNamedVirtualHostAddress(address)) {
            maSetNamedVirtualHost(host);
        }
    }

    mprFree(value);

    return 0;
}
Пример #20
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;
}
Пример #21
0
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;
}
Пример #22
0
int MaHost::mapToStorage(MaRequest *rq, char *path, int pathLen, char *uri,
	int flags)
{
	MaAlias		*ap;
	MaDir		*dir;
	char		urlBuf[MPR_HTTP_MAX_URL];
	char		*base, *aliasName, *prefix;
	int			len, redirectCode, prefixLen;

	mprAssert(path);
	mprAssert(pathLen > 0);

	*path = '\0';

	lock();

	//
	//	FUTURE - Could optimize by having a hash lookup for alias prefixes.
	//
	ap = (MaAlias*) aliases.getFirst();
	while (ap) {
		aliasName = ap->getName();
		prefix = ap->getPrefix();
		prefixLen = ap->getPrefixLen();

		//
		//	Note that for Aliases with redirects, the aliasName is a URL and
		//	not a document path.
		//
		if (strncmp(prefix, uri, prefixLen) == 0) {
			redirectCode = ap->getRedirectCode();
			if (redirectCode) {
				if (flags & MPR_HTTP_REDIRECT) {
					rq->redirect(redirectCode, aliasName);
					rq->flushOutput(MPR_HTTP_FOREGROUND_FLUSH, 
						MPR_HTTP_FINISH_REQUEST);
				} else {
					mprStrcpy(path, pathLen, aliasName);
				}
				unlock();
				return 0;
			}

			base = &uri[prefixLen];
			while (*base == '/') {
				base++;
			}
			if (aliasName[strlen(aliasName) - 1] == '/') {
				len = mprSprintf(path, pathLen, "%s%s", aliasName, base);
			} else if (*base) {
				len = mprSprintf(path, pathLen, "%s/%s", aliasName, base);
			} else {
				len = mprStrcpy(path, pathLen, aliasName);
			}

			dir = 0;

			if (*base != '\0') {
				//
				//	There was some extra URI past the matching alias prefix 
				//	portion
				//
#if WIN
				//
				//	Windows will ignore trailing "." and " ". We must reject
				//	here as the URL probably won't match due to the trailing
				//	character and the copyHandler will return the unprocessed
				//	content to the user. Bad.
				//
				int lastc = base[strlen(base) - 1];
				if (lastc == '.' || lastc == ' ') {
					unlock();
					return MPR_ERR_CANT_ACCESS;
				}
#endif		
				unlock();
				return 0;

			} else {
				if (*prefix == '\0') {
					prefix = "/";
				}
				//
				//	The URL matched the alias exactly so we change the URI
				//	to match the prefix as we may have changed the extension
				//
				mprStrcpy(urlBuf, sizeof(urlBuf), prefix);

				MaUrl *url = rq->getUrl();

				if (strcmp(urlBuf, url->uri) != 0) {
					if (url->query && *url->query) {
						mprStrcat(urlBuf, sizeof(urlBuf), "?", url->query, 
							(void*) 0);
					}
					if (flags & MPR_HTTP_REMATCH) {
						rq->setUri(urlBuf);
						rq->parseUri();
					}
				}
			}

			if (flags & MPR_HTTP_REMATCH) {
				rq->deleteHandlers();
			}
			unlock();
			return 0;
		}
		ap = (MaAlias*) aliases.getNext(ap);
	}
	unlock();
	return MPR_ERR_NOT_FOUND;
}
Пример #23
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;
}
Пример #24
0
int MaClient::sendCore(char *method, char *requestUrl, char *postData, 
	int postLen)
{
	char	abuf[MPR_HTTP_MAX_PASS * 2], encDetails[MPR_HTTP_MAX_PASS * 2];
	char	*host;
	int		port, len, rc, nbytes;

	mprAssert(requestUrl && *requestUrl);

	lock();
	reset();

	mprLog(3, tMod, "sendCore: %s %s\n", method, requestUrl);

	this->method = mprStrdup(method);
	timestamp = mprGetTime(0);
	if (timeoutPeriod < 0) {
		timeoutPeriod = MPR_HTTP_CLIENT_TIMEOUT;
	}
	if (timeoutPeriod > 0) {
		if (!mprGetDebugMode()) {
			timer = new MprTimer(MPR_HTTP_TIMER_PERIOD, timeoutWrapper, 
				(void *) this);
		}
	}
	
	if (*requestUrl == '/') {
		url.parse(requestUrl);
		host = (proxyHost) ? proxyHost : defaultHost;
		port = (proxyHost) ? proxyPort : defaultPort;
	} else {
		url.parse(requestUrl);
		host = (proxyHost) ? proxyHost : url.host;
		port = (proxyHost) ? proxyPort : url.port;
	}

	if (sock) {
		if (port != currentPort || strcmp(host, currentHost) != 0) {
			//
			//	This request is for a different host or port. Must close socket.
			//
			sock->close(0);
			sock->dispose();
			sock = 0;
		}
	}

	if (sock == 0) {
		sock = new MprSocket();
		mprLog(3, tMod, "Opening new socket on: %s:%d\n", host, port);
		rc = sock->openClient(host, port, MPR_SOCKET_NODELAY);
		if (rc < 0) {
			mprLog(MPR_ERROR, tMod, "Can't open socket on %s:%d, %d\n", 
				host, port, rc);
			unlock();
			sock->dispose();
			sock = 0;
			return rc;
		}
		sock->setBufSize(-1, MPR_HTTP_CLIENT_BUFSIZE);
		currentHost = mprStrdup(host);
		currentPort = port;

	} else {
		mprLog(3, tMod, "Reusing Keep-Alive socket on: %s:%d\n", host, port);
	}

	//
	//	Remove this flush when pipelining is supported
	//
	inBuf->flush();
	fd = sock->getFd();

	if (proxyHost && *proxyHost) {
		if (url.query && *url.query) {
			outBuf->putFmt("%s http://%s:%d%s?%s HTTP/1.1\r\n",
				method, proxyHost, proxyPort, url.uri, url.query);
		} else {
			outBuf->putFmt("%s http://%s:%d%s HTTP/1.1\r\n",
				method, proxyHost, proxyPort, url.uri);
		}
	} else {
		if (url.query && *url.query) {
			outBuf->putFmt("%s %s?%s HTTP/1.1\r\n", method, url.uri, url.query);
		} else {
			outBuf->putFmt("%s %s HTTP/1.1\r\n", method, url.uri);
		}
	}

	if (serverAuthType) {
		if (strcmp(serverAuthType, "basic") == 0) {
			mprSprintf(abuf, sizeof(abuf), "%s:%s", user, password);
			maEncode64(encDetails, sizeof(encDetails), abuf);
			outBuf->putFmt("Authorization: %s %s\r\n", serverAuthType, 
				encDetails);

#if BLD_FEATURE_DIGEST
		} else if (strcmp(serverAuthType, "digest") == 0) {
			char	a1Buf[256], a2Buf[256], digestBuf[256];
			char	*ha1, *ha2, *digest, *qop;

			authNc++;
			if (secret == 0) {
				if (createSecret() < 0) {
					mprLog(MPR_ERROR, tMod, "Can't create secret\n");
					return MPR_ERR_CANT_INITIALIZE;
				}
			}
			mprFree(authCnonce);
			maCalcNonce(&authCnonce, secret, 0, realm);

			mprSprintf(a1Buf, sizeof(a1Buf), "%s:%s:%s", user, realm, password);
			ha1 = maMD5(a1Buf);

			mprSprintf(a2Buf, sizeof(a2Buf), "%s:%s", method, url.uri);
			ha2 = maMD5(a2Buf);

			qop = (serverQop) ? serverQop : (char*) "";
			if (mprStrCmpAnyCase(serverQop, "auth") == 0) {
				mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%08x:%s:%s:%s", 
					ha1, serverNonce, authNc, authCnonce, serverQop, ha2);

			} else if (mprStrCmpAnyCase(serverQop, "auth-int") == 0) {
				mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%08x:%s:%s:%s", 
					ha1, serverNonce, authNc, authCnonce, serverQop, ha2);

			} else {
				qop = "";
				mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%s", ha1, 
					serverNonce, ha2);
			}

			mprFree(ha1);
			mprFree(ha2);
			digest = maMD5(digestBuf);

			if (*qop == '\0') {
				outBuf->putFmt("Authorization: Digest "
					"username=\"%s\", realm=\"%s\", nonce=\"%s\", "
					"uri=\"%s\", response=\"%s\"\r\n",
					user, realm, serverNonce, url.uri, digest);

			} else if (strcmp(qop, "auth") == 0) {
				outBuf->putFmt("Authorization: Digest "
					"username=\"%s\", realm=\"%s\", domain=\"%s\", "
					"algorithm=\"MD5\", qop=\"%s\", cnonce=\"%s\", "
					"nc=\"%08x\", nonce=\"%s\", opaque=\"%s\", "
					"stale=\"FALSE\", uri=\"%s\", response=\"%s\"\r\n",
					user, realm, serverDomain, serverQop, authCnonce, authNc, 
					serverNonce, serverOpaque, url.uri, digest);

			} else if (strcmp(qop, "auth-int") == 0) {
				;
			}
			mprFree(digest);
#endif // BLD_FEATURE_HTTP_DIGEST
		}
	}

	outBuf->putFmt("Host: %s\r\n", host);
	outBuf->putFmt("User-Agent: %s\r\n", MPR_HTTP_CLIENT_NAME);
	if (userFlags & MPR_HTTP_KEEP_ALIVE) {
		outBuf->putFmt("Connection: Keep-Alive\r\n");
	} else {
		outBuf->putFmt("Connection: close\r\n");
	}
	if (postLen > 0) {
		outBuf->putFmt("Content-Length: %d\r\n", postLen);
	}
	if (postData) {
		outBuf->putFmt("Content-Type: application/x-www-form-urlencoded\r\n");
	}
	if (userHeaders) {
		outBuf->put(userHeaders);
	}
	outBuf->put("\r\n");
	outBuf->addNull();

	//
	//	Flush to the socket with any post data. Writes can fail because the
	//	server prematurely closes a keep-alive connection.
	//
	len = outBuf->getLength();
	if ((rc = sock->write(outBuf->getStart(), len)) != len) {
		flags |= MPR_HTTP_TERMINATED;
		unlock();
		mprLog(MPR_ERROR, tMod, 
			"Can't write to socket on %s:%d, %d\n", host, port, rc);
		return rc;
	}

#if BLD_DEBUG
	mprLog(3, MPR_RAW, tMod, "Request >>>>\n%s\n", outBuf->getStart());
#endif

	if (postData) {
		sock->setBlockingMode(1);
		for (len = 0; len < postLen; ) {
			nbytes = postLen - len;
			rc = sock->write(&postData[len], nbytes);
#if BLD_DEBUG
			mprLog(3, MPR_RAW, tMod, "POST DATA %s\n", &postData[len]);
#endif
			if (rc < 0) {
				unlock();
				mprLog(MPR_ERROR, tMod, 
					"Can't write post data to socket on %s:%d, %d\n", 
					host, port, rc);
				flags |= MPR_HTTP_TERMINATED;
				sock->dispose();
				sock = 0;
				return rc;
			}
			len += rc;
		}
		sock->setBlockingMode(0);
	}
	sock->setCallback(readEventWrapper, (void*) this, 0, MPR_READABLE);

	//
	//	If no callback, then we must block
	//
	if (callback == 0) {
		unlock();
		while (state != MPR_HTTP_CLIENT_DONE) {
			//
			//	If multithreaded and the events thread is not yet running,
			//	we still want to work.
			//
#if BLD_FEATURE_MULTITHREAD
			if (mprGetMpr()->isRunningEventsThread() &&
					mprGetMpr()->poolService->getMaxPoolThreads() > 0) {
				completeCond->waitForCond(250);
			} else
#endif
				mprGetMpr()->serviceEvents(1, 100);
		}
	} else {
		unlock();
	}
	return 0;
}
Пример #25
0
static void doTests(void *data, void *threadp)
#endif
{
	MprBuf		post;
	FILE		*fp;
	MaClient	*client;
	char		urlBuf[4096], urlBuf2[4096];
	char		postBuf[4096];
	char		*cp, *operation, *url, *tok;
	int			rc, j, line;

	fp = 0;

	client = new MaClient();
	client->setTimeout(timeout);
	client->setRetries(retries);
	if (httpVersion == 0) {
		client->setKeepAlive(0);
	}

	post.setBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_MAX_BODY);

	while (!mpr->isExiting() && success) {
		lock();
		if (fetchCount >= iterations) {
			unlock();
			break;
		}
		unlock();
		rc = 0;

		for (j = 0; j < saveArgc; j++) {
			url = saveArgv[j];
			if (*url == '/') {
				mprSprintf(urlBuf2, sizeof(urlBuf2), "%s%s", host, url);
				url = urlBuf2;
			}
			rc = fetch(client, method, url, postData, postLen);
			if (rc < 0 && !continueOnErrors) {
				success = 0;
				goto commonExit;
			}
		}
		if (fileList == 0) {
			continue;
		}
		fp = fopen(fileList, "rt");
		if (fp == 0) {
			mprError(MPR_L, MPR_USER, "Can't open %s", fileList);
			goto commonExit;
		}

		line = 0;
		while (fgets(urlBuf, sizeof(urlBuf), fp) != NULL && !mpr->isExiting()) {
			lock();
			if (fetchCount >= iterations) {
				unlock();
				break;
			}
			unlock();
			if ((cp = strchr(urlBuf, '\n')) != 0) {
				*cp = '\0';
			}
			operation = mprStrTok(urlBuf, " \t\n", &tok);
			url = mprStrTok(0, " \t\n", &tok);
	
			if (*url == '/') {
				mprSprintf(urlBuf2, sizeof(urlBuf2), "%s%s", host, url);
				url = urlBuf2;
			}

			if (strcmp(operation, "GET") == 0) {
				rc = fetch(client, operation, url, postData, postLen);

			} else if (strcmp(operation, "HEAD") == 0) {
				rc = fetch(client, operation, url, postData, postLen);

			} else if (strcmp(operation, "POST") == 0) {
				while (fgets(postBuf, sizeof(postBuf), fp) != NULL) {
					if (postBuf[0] != '\t') {
						break;
					}
					if (strlen(postBuf) == 1) {
						break;
					}
					post.put((uchar*) &postBuf[1], strlen(postBuf) - 2);
					post.addNull();
					if (post.getLength() >= (MPR_HTTP_MAX_BODY - 1)) {
						mprError(MPR_L, MPR_USER, "Bad post data on line %d",
							line);
						if (!continueOnErrors) {
							success = 0;
							fclose(fp);
							fp = 0;
							goto commonExit;
						}
					}
				}
				if (post.getLength() > 0) {
					rc = fetch(client, operation, url, post.getStart(), 
						post.getLength());
				} else {
					rc = fetch(client, operation, url, postBuf, postLen);
				}
				post.flush();

			} else {
				rc = -1;
				mprError(MPR_L, MPR_USER, "Bad operation on line %d", line);
			}
			if (rc < 0 && !continueOnErrors) {
				success = 0;
				fclose(fp);
				fp = 0;
				goto commonExit;
			}
		}
		fclose(fp);
		fp = 0;
	}

commonExit:

#if BLD_FEATURE_MULTITHREAD
	if (threadp) {
		lock();
		activeLoadThreads--;
		unlock();
	}
#endif

	delete client;
}
Пример #26
0
int MprLogService::setLogSpec(char *fileSpec)
{
	MprLogModule	*mp;
	MprLogListener	*lp;
	char			namBuf[MPR_MAX_FNAME];
	char			*spec, *cp, *sizeStr;
	int				maxSize;

	mprAssert(!logging);
#if BLD_FEATURE_MULTITHREAD
	if (mutex == 0) {
		mutex = new MprMutex();
	}
#endif
	lock();

	logging = 1;
	if (fileSpec == NULL || *fileSpec == '\0') {
		fileSpec = "trace.txt";
	}

	logSpec = mprStrdup(fileSpec);
	spec = mprStrdup(fileSpec);
	for (cp = spec; *cp; cp++) {
		if (*cp == ':' && isdigit(cp[1])) {
			break;
		}
	}

	maxSize = MPR_MAX_LOG_SIZE;
	if (*cp) {
		*cp++ = '\0';
		moduleSpecs = strchr(cp, ',');

		sizeStr = strchr(cp, '.');
		if (sizeStr != 0) {
			*sizeStr++ = '\0';
			maxSize = atoi(sizeStr);					// Size in MB
		}

		//
		//	Set all modules to the default trace level and then examine
		//	the modules spec to override specified modules
		//
		defaultLevel = atoi(cp);
		if (defaultLevel < 0) {
			defaultLevel = 0;
		}

		mp = (MprLogModule*) moduleList.getFirst();
		while (mp) {
			mp->setLevel(defaultLevel);
			mp = (MprLogModule*) moduleList.getNext(mp);
		}

		if (moduleSpecs) {
			moduleSpecs++;
			mp = (MprLogModule*) moduleList.getFirst();
			while (mp) {
				mprSprintf(namBuf, sizeof(namBuf), "%s:", mp->getName());
				if ((cp = strstr(moduleSpecs, namBuf)) != 0) {
					if ((cp = strchr(cp, ':')) != 0) {
						mp->setLevel(atoi(++cp));
					}
				}
				mp = (MprLogModule*) moduleList.getNext(mp);
			}
		}
	}
	if (spec != 0 && *spec != '\0') {
		lp = (MprLogListener*) listeners.getFirst();
		while (lp) {
			if (lp->setLogSpec(spec, maxSize) < 0) {
				mprFree(spec);
				unlock();
				return MPR_ERR_CANT_OPEN;
			}
			lp = (MprLogListener*) listeners.getNext(lp);
		}
	}
	mprFree(spec);
	unlock();
	return 0;
}
Пример #27
0
void Mpr::writeToOsLog(char *message, int flags)
{
	HKEY		hkey;
	void		*event;
	long		errorType;
	char		buf[MPR_MAX_STRING], msg[MPR_MAX_STRING];
	char		logName[MPR_MAX_STRING];
	char		*lines[9];
	char		*cp, *value;
	int			type;
	ulong		exists;
	static int	once = 0;

	mprStrcpy(buf, sizeof(buf), message);
	cp = &buf[strlen(buf) - 1];
	while (*cp == '\n' && cp > buf) {
		*cp-- = '\0';
	}

	if (flags & MPR_INFO) {
		type = EVENTLOG_INFORMATION_TYPE;
		mprSprintf(msg, MPR_MAX_STRING, "%s information: ", 
			Mpr::getAppName());

	} else if (flags == MPR_WARN) {
		type = EVENTLOG_WARNING_TYPE;
		mprSprintf(msg, MPR_MAX_STRING, "%s warning: ", Mpr::getAppName());

	} else {
		type = EVENTLOG_ERROR_TYPE;
		mprSprintf(msg, MPR_MAX_STRING, "%s error: %d", Mpr::getAppName(), 
			GetLastError());
	}

	lines[0] = msg;
	lines[1] = buf;
	lines[2] = lines[3] = lines[4] = lines[5] = 0;
	lines[6] = lines[7] = lines[8] = 0;

	if (once == 0) {
		//	Initialize the registry
		once = 1;
		mprSprintf(logName, sizeof(logName), 
			"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
			Mpr::getAppName());
		hkey = 0;

		if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, logName, 0, NULL, 0, 
				KEY_ALL_ACCESS, NULL, &hkey, &exists) == ERROR_SUCCESS) {

			value = "%SystemRoot%\\System32\\netmsg.dll";
			if (RegSetValueEx(hkey, "EventMessageFile", 0, REG_EXPAND_SZ, 
					(uchar*) value, strlen(value) + 1) != ERROR_SUCCESS) {
				RegCloseKey(hkey);
				return;
			}

			errorType = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
				EVENTLOG_INFORMATION_TYPE;
			if (RegSetValueEx(hkey, "TypesSupported", 0, REG_DWORD, 
					(uchar*) &errorType, sizeof(DWORD)) != ERROR_SUCCESS) {
				RegCloseKey(hkey);
				return;
			}
			RegCloseKey(hkey);
		}
	}

	event = RegisterEventSource(0, Mpr::getAppName());
	if (event) {
		//	
		//	3299 is the event number for the generic message in netmsg.dll.
		//	"%1 %2 %3 %4 %5 %6 %7 %8 %9" -- thanks Apache for the tip
		//
		ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, 3299, NULL, 
			sizeof(lines) / sizeof(char*), 0, (LPCSTR*) lines, 0);
		DeregisterEventSource(event);
	}
}
Пример #28
0
void MprLogService::error(char *file, int line, int flags, char *fmt, 
	va_list args)
{
	static int	recurseGate = 0;
	Mpr			*mpr;
	char		msg[MPR_MAX_LOG_STRING], buf[MPR_MAX_LOG_STRING];

	mpr = mprGetMpr();

	//
	//	Errors post close
	//
#if BLD_FEATURE_MULTITHREAD
	if (mutex == 0) {
		return;
	}
#endif

	lock();
	if (recurseGate > 0) {
		unlock();
		return;
	}
	recurseGate++;

	mprVsprintf(msg, sizeof(msg), fmt, args);

	if (flags & MPR_TRAP) {
		mprSprintf(buf, sizeof(buf), "Assertion %s, failed (%s:%d)\n",
			msg, file, line);
		output(defaultModule, flags, MPR_ERROR, buf);
		// 
		//	Break to the debugger
		//
		breakpoint(file, line);

	} else if (flags & MPR_LOG) {
		//
		//	Write to both the O/S log and to the trace log
		//
		mprSprintf(buf, sizeof(buf), "Error: %s\n", msg);
		output(defaultModule, flags, MPR_ERROR, buf);
		if (mpr) {
			mpr->writeToOsLog(buf, flags | MPR_INFO);
		}

	} else if (flags & MPR_USER) {
		mprSprintf(buf, sizeof(buf), "Error: %s\n", msg);
		output(defaultModule, flags, MPR_ERROR, buf);
		if (mpr) {
			mpr->writeToOsLog(buf, flags | MPR_WARN);
		}

	} else if (flags & MPR_ALERT) {
		// FUTURE -- TBD 

	} else {
		mprAssert(0);
	}

	recurseGate--;
	unlock();
}
Пример #29
0
static long msgProc(HWND hwnd, uint msg, uint wp, long lp)
{
    char    buf[MPR_MAX_FNAME];

    switch (msg) {
    case WM_DESTROY:
    case WM_QUIT:
        mprSignalExit(mpr);
        break;
    
    case APPWEB_MONITOR_MESSAGE:
        return monitorEvent(hwnd, wp, lp);

    case WM_COMMAND:
        switch (LOWORD(wp)) {
        case MA_MENU_STATUS:
            break;

        case MA_MENU_DOC:
            runBrowser("/doc/index.html");
            break;

        case MA_MENU_MANAGE:
            runBrowser("/index.html");
            break;

        case MA_MENU_START:
            startService();
            break;

        case MA_MENU_STOP:
            stopService();
            break;

        case MA_MENU_ABOUT:
            /*
             *  Single-threaded users beware. This blocks !!
             */
            mprSprintf(buf, sizeof(buf), "%s %s-%s", BLD_NAME, BLD_VERSION, BLD_NUMBER);
            MessageBoxEx(NULL, buf, mprGetAppTitle(mpr), MB_OK, 0);
            break;

        case MA_MENU_EXIT:
            /* 
             *  FUTURE
             *
             *  h = CreateDialog(appInst, MAKEINTRESOURCE(IDD_EXIT), appHwnd, dialogProc);
             *  ShowWindow(h, SW_SHOW);
             */
            PostMessage(hwnd, WM_QUIT, 0, 0L);
            break;

        default:
            return DefWindowProc(hwnd, msg, wp, lp);
        }
        break;

    default:
        return DefWindowProc(hwnd, msg, wp, lp);
    }
    return 0;
}
Пример #30
0
int main(int argc, char *argv[])
{
	char	*password, *passFile, *userName;
	char	*encodedPassword, *argp, *realm;
	char	passBuf[MPR_HTTP_MAX_PASS], buf[MPR_HTTP_MAX_PASS * 2];
	int		c, errflg, create, nextArg;
	bool	enable;

	programName = mprGetBaseName(argv[0]);
	userName = 0;
	create = errflg = 0;
	password = 0;
	enable = 1;

#if BLD_FEATURE_LOG
	MprLogService *ls = new MprLogService();
	ls->addListener(new MprLogToFile());
	ls->setLogSpec("stdout:0");
#endif

	MprCmdLine cmdLine(argc, argv, "cdep:");
	while ((c = cmdLine.next(&argp)) != EOF) {
		switch(c) {
		case 'c':
			create++;
			break;

		case 'e':
			enable = 1;
			break;

		case 'd':
			enable = 0;
			break;

		case 'p':
			password = argp;
			break;

		default:
			errflg++;
			break;
		}
	}
	nextArg = cmdLine.firstArg();
	if ((nextArg + 3) > argc) {
		errflg++;
	}

	if (errflg) {
		printUsage(argv[0]);
		exit(2);
	}	

	passFile = argv[nextArg++];
	realm = argv[nextArg++];
	userName = argv[nextArg++];

	if (!create) {
		if (readPassFile(passFile) < 0) {
			exit(2);
		}
		if (access(passFile, R_OK) != 0) {
			mprError(MPR_L, MPR_USER, "Can't find %s\n", passFile);
			exit(3);
		}
		if (access(passFile, W_OK) < 0) {
			mprError(MPR_L, MPR_USER, "Can't write to %s\n", passFile);
			exit(4);
		}
	} else {
		if (access(passFile, R_OK) == 0) {
			mprError(MPR_L, MPR_USER, "Can't create %s, already exists\n", 
				passFile);
			exit(5);
		}
	}

	if (password == 0) {
		password = getPassword(passBuf, sizeof(passBuf));
		if (password == 0) {
			exit(1);
		}
	}

	mprSprintf(buf, sizeof(buf), "%s:%s:%s", userName, realm, password);
	encodedPassword = maMD5(buf);

	addUser(userName, realm, encodedPassword, enable);

	if (updatePassFile(passFile) < 0) {
		exit(6);
	}
	mprFree(encodedPassword);
	
	return 0;
}