emehta-contrib/os_testcmd.c

136 lines
3.7 KiB
C

/*
* Copyright (c) 2006 Jilles Tjoelker, et al
* Rights to this code are as documented in doc/LICENSE.
*
* Calls a command without a user_t.
*
*/
#include "atheme-compat.h"
DECLARE_MODULE_V1
(
"contrib/os_testcmd", false, _modinit, _moddeinit,
PACKAGE_STRING,
"Atheme Development Group <http://www.atheme.org>"
);
struct testcmddata
{
sourceinfo_t *prevsi;
bool got_result;
};
static void os_cmd_testcmd(sourceinfo_t *si, int parc, char *parv[]);
static void testcmd_command_fail(sourceinfo_t *si, faultcode_t code, const char *message);
static void testcmd_command_success_nodata(sourceinfo_t *si, const char *message);
static void testcmd_command_success_string(sourceinfo_t *si, const char *result, const char *message);
command_t os_testcmd = { "TESTCMD", "Executes a command without a user_t.",
AC_NONE, 3, os_cmd_testcmd, { .path = "contrib/testcmd" } };
struct sourceinfo_vtable testcmd_vtable = {
.description = "testcmd",
.cmd_fail = testcmd_command_fail,
.cmd_success_nodata = testcmd_command_success_nodata,
.cmd_success_string = testcmd_command_success_string
};
void _modinit(module_t *m)
{
service_named_bind_command("operserv", &os_testcmd);
}
void _moddeinit(module_unload_intent_t intent)
{
service_named_unbind_command("operserv", &os_testcmd);
}
static void testcmd_command_fail(sourceinfo_t *si, faultcode_t code, const char *message)
{
struct testcmddata *udata = si->callerdata;
command_success_nodata(udata->prevsi, "Command failed with fault %d, \"%s\"", code, message);
udata->got_result = true;
}
static void testcmd_command_success_nodata(sourceinfo_t *si, const char *message)
{
struct testcmddata *udata = si->callerdata;
if (udata->got_result)
command_success_nodata(udata->prevsi, "More comment \"%s\"", message);
else
command_success_nodata(udata->prevsi, "Command succeeded with no data, \"%s\"", message);
udata->got_result = true;
}
static void testcmd_command_success_string(sourceinfo_t *si, const char *result, const char *message)
{
struct testcmddata *udata = si->callerdata;
command_success_nodata(udata->prevsi, "Command succeeded with string \"%s\", \"%s\"", result, message);
udata->got_result = true;
}
static void os_cmd_testcmd(sourceinfo_t *si, int parc, char *parv[])
{
service_t *svs;
command_t *cmd;
sourceinfo_t newsi;
struct testcmddata udata;
int newparc;
char *newparv[256];
if (parc < 2)
{
command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "TESTCMD");
command_fail(si, fault_needmoreparams, "Syntax: TESTCMD <service> <command> [arguments]");
return;
}
svs = service_find_nick(parv[0]);
if (svs == NULL)
{
command_fail(si, fault_nosuch_target, "No such service \2%s\2", parv[0]);
return;
}
if (svs->commands == NULL)
{
command_fail(si, fault_noprivs, "Service \2%s\2 has no commands", svs->nick);
return;
}
cmd = command_find(svs->commands, parv[1]);
if (cmd == NULL)
{
command_fail(si, fault_nosuch_key, "No such command \2%s\2 in service \2%s\2", parv[1], svs->nick);
return;
}
udata.prevsi = si;
udata.got_result = false;
memset(newparv, '\0', sizeof newparv);
if (parc >= 3)
newparc = sjtoken(parv[2], ';', newparv);
else
newparc = 0;
memset(&newsi, '\0', sizeof newsi);
newsi.smu = si->smu;
if (si->su != NULL)
newsi.sourcedesc = si->su->ip != NULL ? si->su->ip : si->su->host;
else
newsi.sourcedesc = si->sourcedesc;
newsi.service = svs;
newsi.v = &testcmd_vtable;
newsi.callerdata = &udata;
command_exec(svs, &newsi, cmd, newparc, newparv);
if (!udata.got_result)
command_success_nodata(si, "Command returned without giving a result");
}
/* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
* vim:ts=8
* vim:sw=8
* vim:noexpandtab
*/