To create new wiki account, please join us on #znc at Libera.Chat and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.

Develop

From ZNC
Jump to navigation Jump to search

Helps developers with compiling Modules and searching the Header files for function headers. It is an Modification of the Shell module. Useful if you are developing & debugging on a remote machine.

Modified by User:Nero

Usage

Commands

  • /znc buildmod <modulename>

Compiles a Module

  • /znc header <search term>

Searches for substring in List or Lists all

Example

[18:37:30] <Nero> buildmod version
[18:37:31] <*status> Building "version.so"... [ ok ]
[19:03:20] <Nero> buildmod develop
[19:03:21] <*status> Building "develop.so"... [ ok ]

Sourcecode

/*
 * Modification of the Shell-Module. by Nero.
 * Copyright (C) 2004-2009  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "User.h"
#include "Client.h"
#include "znc.h"
#include "ZNCString.h"

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>

// Forward Declaration
class CDevelopMod;

class CShellSock : public CExecSock {
public:
	CShellSock(CDevelopMod* pShellMod, CClient* pClient, const CString& sExec) : CExecSock() {
		EnableReadLine();
		m_pParent = pShellMod;
		m_pClient = pClient;

		if (Execute(sExec) == -1) {
			CString s = "Failed to execute: ";
			s += strerror(errno);
			ReadLine(s);
			return;
		}

		// Get rid of that write fd, we aren't going to use it
		// (And clients expecting input will fail this way).
		close(GetWSock());
		SetWSock(open("/dev/null", O_WRONLY));
	}
	// These next two function's bodies are at the bottom of the file since they reference CDevelopMod
	virtual void ReadLine(const CString& sData);
	virtual void Disconnected();

	CDevelopMod*	m_pParent;

private:
	CClient*	m_pClient;
};

class CDevelopMod : public CModule {
public:
	MODCONSTRUCTOR(CDevelopMod) {
	}

	virtual ~CDevelopMod() {
		vector<CZNCSock*> vSocks = m_pManager->FindSocksByName("DEVSHELL");

		for (unsigned int a = 0; a < vSocks.size(); a++) {
			m_pManager->DelSockByAddr(vSocks[a]);
		}
	}

	virtual bool OnLoad(const CString& sArgs, CString& sMessage)
	{
		if (!m_pUser->IsAdmin()) {
			sMessage = "You must be admin to use the development module";
			return false;
		}
		return true;
	}

	virtual EModRet OnStatusCommand(CString& sCommand) {
		CString sCmdName = sCommand.Token(0).AsLower();
		if (sCmdName == "buildmod") {
			m_pManager->AddSock(new CShellSock(this, m_pClient, "cd " + CZNC::Get().GetHomePath() + "/.znc/modules && znc-buildmod " + sCommand.Token(1) + ".cpp"), "DEVSHELL");
			return HALT;
		} else if (sCmdName == "header") {
			m_pManager->AddSock(new CShellSock(this, m_pClient, "grep '" + sCommand.Token(1) + "' -i /usr/include/znc/*"), "DEVSHELL");
			return HALT;
		} else if (sCmdName == "help") {
			PutStatus("develop: buildmod <name>, header <search term>");
		}
		return CONTINUE;
	}

	void PutShell(const CString& sLine) {
		PutStatus(sLine);
		CString sCmd;
	}
};

void CShellSock::ReadLine(const CString& sData) {
	CString sLine = sData;

	sLine.TrimRight("\r\n");
	sLine.Replace("\t", "    ");

	m_pParent->SetClient(m_pClient);
	m_pParent->PutShell(sLine);
	m_pParent->SetClient(NULL);
}

void CShellSock::Disconnected() {
	// If there is some incomplete line in the buffer, read it
	// (e.g. echo echo -n "hi" triggered this)
	CString &sBuffer = GetInternalReadBuffer();
	if (!sBuffer.empty())
		ReadLine(sBuffer);

	m_pParent->SetClient(m_pClient);
	m_pParent->SetClient(NULL);
}

MODULEDEFS(CDevelopMod, "Allows to Compile Modules")