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;}