1 |
/** |
2 |
* os_testcmd.C: Calls a command without a user_t. |
3 |
* |
4 |
* Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team |
5 |
* Rights to this code are as documented in COPYING. |
6 |
* |
7 |
* |
8 |
* Portions of this file were derived from sources bearing the following license: |
9 |
* Copyright © 2006 Jilles Tjoelker, et al |
10 |
* Rights to this code are as documented in doc/pod/license.pod. |
11 |
* |
12 |
* $Id: os_testcmd.C,v 1.5 2007-09-16 18:54:43 pippijn Exp $ |
13 |
*/ |
14 |
|
15 |
#include "atheme.h" |
16 |
#include <ermyth/module.h> |
17 |
|
18 |
static char const rcsid[] = "$Id: os_testcmd.C,v 1.5 2007-09-16 18:54:43 pippijn Exp $"; |
19 |
|
20 |
REGISTER_MODULE ("operserv/testcmd", false, "The Ermyth Team <http://ermyth.xinutec.org>"); |
21 |
|
22 |
struct testcmddata |
23 |
{ |
24 |
sourceinfo_t *prevsi; |
25 |
bool got_result; |
26 |
}; |
27 |
|
28 |
static void os_cmd_testcmd (sourceinfo_t *si, int parc, char *parv[]); |
29 |
|
30 |
static void testcmd_command_fail (sourceinfo_t *si, fault::code code, char const * const message); |
31 |
static void testcmd_command_success_nodata (sourceinfo_t *si, char const * const message); |
32 |
static void testcmd_command_success_string (sourceinfo_t *si, char const * const result, char const * const message); |
33 |
|
34 |
command_t const os_testcmd = { "TESTCMD", "Executes a command without a user_t.", AC_NONE, 3, os_cmd_testcmd }; |
35 |
|
36 |
E cmdvec os_cmdtree; |
37 |
E helpvec os_helptree; |
38 |
|
39 |
sourceinfo_vtable testcmd_vtable = { "testcmd", testcmd_command_fail, testcmd_command_success_nodata, testcmd_command_success_string }; |
40 |
|
41 |
bool |
42 |
_modinit (module *m) |
43 |
{ |
44 |
os_cmdtree << os_testcmd; |
45 |
help_addentry (os_helptree, "TESTCMD", "help/operserv/testcmd", NULL); |
46 |
|
47 |
return true; |
48 |
} |
49 |
|
50 |
void |
51 |
_moddeinit () |
52 |
{ |
53 |
os_cmdtree >> os_testcmd; |
54 |
help_delentry (os_helptree, "TESTCMD"); |
55 |
} |
56 |
|
57 |
static void |
58 |
testcmd_command_fail (sourceinfo_t *si, fault::code code, char const * const message) |
59 |
{ |
60 |
testcmddata *udata = static_cast<testcmddata *> (si->callerdata); |
61 |
|
62 |
command_success_nodata (udata->prevsi, "Command failed with fault %d, \"%s\"", code, message); |
63 |
udata->got_result = true; |
64 |
} |
65 |
|
66 |
static void |
67 |
testcmd_command_success_nodata (sourceinfo_t *si, char const * const message) |
68 |
{ |
69 |
testcmddata *udata = static_cast<testcmddata *> (si->callerdata); |
70 |
|
71 |
if (udata->got_result) |
72 |
command_success_nodata (udata->prevsi, "More comment \"%s\"", message); |
73 |
else |
74 |
command_success_nodata (udata->prevsi, "Command succeeded with no data, \"%s\"", message); |
75 |
udata->got_result = true; |
76 |
} |
77 |
|
78 |
static void |
79 |
testcmd_command_success_string (sourceinfo_t *si, char const * const result, char const * const message) |
80 |
{ |
81 |
testcmddata *udata = static_cast<testcmddata *> (si->callerdata); |
82 |
|
83 |
command_success_nodata (udata->prevsi, "Command succeeded with string \"%s\", \"%s\"", result, message); |
84 |
udata->got_result = true; |
85 |
} |
86 |
|
87 |
static void |
88 |
os_cmd_testcmd (sourceinfo_t *si, int parc, char *parv[]) |
89 |
{ |
90 |
service_t *svs; |
91 |
command_t const *cmd; |
92 |
sourceinfo_t newsi; |
93 |
testcmddata udata; |
94 |
int newparc; |
95 |
char *newparv[256]; |
96 |
|
97 |
if (parc < 2) |
98 |
{ |
99 |
command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "TESTCMD"); |
100 |
command_fail (si, fault::needmoreparams, "Syntax: TESTCMD <service> <command> [arguments]"); |
101 |
return; |
102 |
} |
103 |
|
104 |
svs = find_service (parv[0]); |
105 |
if (svs == NULL) |
106 |
{ |
107 |
command_fail (si, fault::nosuch_target, "No such service \2%s\2", parv[0]); |
108 |
return; |
109 |
} |
110 |
if (svs->cmdtree == NULL) |
111 |
{ |
112 |
command_fail (si, fault::noprivs, "Service \2%s\2 has no commands", svs->name); |
113 |
return; |
114 |
} |
115 |
cmd = svs->cmdtree->find (parv[1]); |
116 |
if (cmd == NULL) |
117 |
{ |
118 |
command_fail (si, fault::nosuch_key, "No such command \2%s\2 in service \2%s\2", parv[1], svs->name); |
119 |
return; |
120 |
} |
121 |
udata.prevsi = si; |
122 |
udata.got_result = false; |
123 |
memset (newparv, '\0', sizeof newparv); |
124 |
if (parc >= 3) |
125 |
newparc = sjtoken (parv[2], ';', newparv); |
126 |
else |
127 |
newparc = 0; |
128 |
memset (&newsi, '\0', sizeof newsi); |
129 |
newsi.smu = si->smu; |
130 |
if (si->su != NULL) |
131 |
newsi.sourcedesc = si->su->ip[0] != '\0' ? si->su->ip : si->su->host; |
132 |
else |
133 |
newsi.sourcedesc = si->sourcedesc; |
134 |
newsi.service = svs; |
135 |
newsi.v = &testcmd_vtable; |
136 |
newsi.callerdata = &udata; |
137 |
cmd->exec (svs, &newsi, newparc, newparv); |
138 |
if (!udata.got_result) |
139 |
command_success_nodata (si, "Command returned without giving a result"); |
140 |
} |