All pastes #139661 Raw Edit

Untitled

public cpp v1 · immutable
#139661 ·published 2006-08-20 02:19 UTC
rendered paste body
#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <string>#include <list>#include "bzfsAPI.h"BZ_GET_PLUGIN_VERSIONint sshSock;std::string cmdLine;std::string sendBuf;std::string recvBuf;void sendCommand(std::string command, std::list<std::string> args) {	char hex[5];	for (std::string::iterator i = command.begin(); i != command.end(); i++) {		sendBuf += '%';		sprintf(hex, "%-2.2X", *i);		sendBuf.append(hex);	}	for (std::list<std::string>::iterator j = args.begin(); j != args.end(); j++) {		sendBuf += '|';		for (std::string::iterator k = j->begin(); k != j->end(); k++) {			sendBuf += '%' ;			sprintf(hex, "%-2.2X", *k);			sendBuf.append(hex);		}	}	sendBuf += '\n';}void doCommand(std::string command, std::list<std::string> args) {	/*	if (command == "command1") do_1();	else if (command == "command2") do_2();	*/	printf("Command: %s with %i Arguments\n", command.c_str(), args.size());}void parseCommand(std::string line) {	if (line == "") return;		int arg = -1;	std::string curString;	std::string command;	std::list<std::string> args;		line += '|';	for (std::string::iterator i = line.begin(); i != line.end(); i++) {		switch (*i) {			case '|': {				if (arg) command = curString;				else args.push_back(curString);				curString = "";				arg = 0;			}			break;			case '%': {				char hex[3];				hex[2] = '\0';								if (++i != line.end() && (hex[0] = *i) && ++i != line.end() && (hex[1] = *i)) {					unsigned int value;										sscanf(hex, "%X", &value);					curString += char(value);				}				else i = line.end();			}			break;			case '+':				curString += ' ';			break;			default:				curString += *i;		}	}	doCommand(command, args);}int spawn (const char* commandLine) {	int sv[2];	socketpair(AF_UNIX, SOCK_STREAM, 0, sv);		sendBuf = "";	recvBuf = "";		std::list<std::string> args;	args.push_back(bz_getPublicAddr().c_str());	args.push_back("0");	args.push_back(bz_getPublicDescription().c_str());	args.push_back("0");	args.push_back("");	args.push_back("");	sendCommand("server-add", args);		if (!fork()) {		dup2(sv[1], 0);		dup2(sv[1], 1);				close(sv[0]);		close(sv[1]);				execl("/bin/sh", "sh", "-c", commandLine, NULL);	}	close(sv[1]);	return(sv[0]);}void bufSock() {	int n;	char r;	while ((n = recv(sshSock, &r, 1, MSG_DONTWAIT)) > 0) {		if (r == '\n') { parseCommand(recvBuf); recvBuf = ""; }		else recvBuf += r;	}	if (n < 0 && errno == EPIPE) {		close(sshSock);		sshSock = spawn(cmdLine.c_str());	}		n = send(sshSock, sendBuf.c_str(), sendBuf.length(), 0);	if (n >= 0) sendBuf = sendBuf.substr(n);	else if (errno == EPIPE) {		close(sshSock);		sshSock = spawn(cmdLine.c_str());	}}class BZFX : public bz_EventHandler{public:	virtual void process (bz_EventData *eventData)	{		switch (eventData->eventType) {			case bz_eTickEvent: {				std::list<std::string> args;				args.push_back(bz_getPublicAddr().c_str());				args.push_back(bz_getPublicDescription().c_str());				args.push_back("0");				sendCommand("server-update", args);								bufSock();			}			break;		}	}};BZFX bzfx;BZF_PLUGIN_CALL int bz_Load (const char* commandLine) {	cmdLine = commandLine;		sshSock = spawn(cmdLine.c_str());		bz_registerEvent(bz_eTickEvent, &bzfx);		bz_debugMessage(4,"BZFX plugin loaded");	return 0;}BZF_PLUGIN_CALL int bz_Unload () {	bz_removeEvent(bz_eTickEvent, &bzfx);		std::list<std::string> args;	sendCommand("server-remove", args);	const char* data = sendBuf.c_str();	int left = sendBuf.length();	int total = 0;	while (left > 0) {		int n = send(sshSock, data + total, left, 0);		if (n == -1)			break;				total += n;		left -= n;	}	close(sshSock);		bz_debugMessage(4,"BZFX plugin unloaded");	return 0;}