136 lines
3.7 KiB
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.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
|
||
|
*/
|