#include #include #include #include #include #include #include "bzfsAPI.h" BZ_GET_PLUGIN_VERSION int sshSock; std::string cmdLine; std::string sendBuf; void sendCommand(std::string command, std::list 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::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'; } int spawn (const char* commandLine) { int sv[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, sv); sendBuf = ""; std::list 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]); } class BZFX : public bz_EventHandler { public: virtual void process (bz_EventData *eventData) { switch (eventData->eventType) { case bz_eTickEvent: { std::list args; args.push_back(bz_getPublicAddr().c_str()); args.push_back(bz_getPublicDescription().c_str()); args.push_back("0"); sendCommand("server-update", args); char recvBuf[256]; recv(sshSock, &recvBuf, 255, MSG_DONTWAIT); int 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()); } } 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 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; }