energymech/src/python.c
2018-04-04 06:04:58 +02:00

972 lines
27 KiB
C

/*
EnergyMech, IRC bot software
Copyright (c) 2009 Nemesis128 <stnsls@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Python scripting backend for Energymech
by Nemesis128 <stnsls@gmail.com>
*/
#define PYTHON_C
#include "config.h"
#ifdef PYTHON
#include "defines.h"
#include "structs.h"
#include "global.h"
#include "h.h"
#include "text.h"
#include "mcmd.h"
#define PYVAR_guid 0
#define PYVAR_currentnick 1
#define PYVAR_botnick 2
#define PYVAR_wantnick 3
#define PYVAR_userhost 4
#define PYVAR_server 5
#define PYVAR_nextserver 6
#define PYVAR_currentchan 7
#if PY_MAJOR_VERSION >= 3
char *python_unicode2char(PyUnicodeObject *obj)
{ /* try to get a valid char* from PyUnicode object.
returned str must be free'd afterwards. */
int sz = PyUnicode_GET_SIZE(obj);
wchar_t *wcs = (wchar_t*) malloc(sizeof(wchar_t) * sz);
PyUnicode_AsWideChar(obj, wcs, sz);
char *cs = (char*) malloc(sizeof(char) * (sz + 1));
wcstombs(cs, wcs, sz);
cs[sz] = '\0';
free(wcs);
return cs;
}
#endif /* Py3k */
static PyObject *python_error; /* emech exception object */
static PyObject *python_getvar(PyObject *self, PyObject *args)
{ /* get some global var */
#ifdef DEBUG
if (!current)
{
PyErr_SetString(python_error, "(python_getvar) No current bot?!");
return NULL;
}
#endif /* DEBUG */
int vartype;
if (!PyArg_ParseTuple(args, "i", &vartype))
return NULL;
switch (vartype)
{
case PYVAR_guid:
return Py_BuildValue("i", current ? current->guid : -1);
case PYVAR_currentnick:
return Py_BuildValue("s", CurrentNick);
case PYVAR_botnick:
return Py_BuildValue("s", current && current->nick ? current->nick : "");
case PYVAR_wantnick:
return Py_BuildValue("s", current && current->wantnick ? current->wantnick : "");
case PYVAR_userhost:
return Py_BuildValue("s", current && current->userhost ? current->userhost : "");
case PYVAR_server:
return Py_BuildValue("i", current && current->server ? current->server : -1);
case PYVAR_nextserver:
return Py_BuildValue("i", current && current->nextserver ? current->nextserver : -1);
case PYVAR_currentchan:
return Py_BuildValue("s", current && current->activechan ? current->activechan->name : "");
default:
PyErr_SetString(python_error, "(python_getvar) invalid var");
return NULL;
}
}
/* From channel.c */
static PyObject *python_is_chanuser(PyObject *self, PyObject *args, PyObject *keywds)
/* Return True if $nick is on $chan, else False */
{
char *chan, *nick;
static char *kwlist[] = {"chan", "nick", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss", kwlist, &chan, &nick))
return NULL;
Chan *ch = (Chan*) find_channel(chan, CHAN_ANY);
if (!ch) Py_RETURN_FALSE;
ChanUser *cu = find_chanuser(ch, nick);
if (!cu) Py_RETURN_FALSE;
Py_RETURN_TRUE;
}
#if 0
static PyObject *python_do_join(PyObject *self, PyObject *args, PyObject *keywds)
/* Join a channel */
{
char *from, *to="", *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|i", kwlist,
&from, &rest, &cmdaccess))
return NULL;
do_join(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_part(PyObject *self, PyObject *args, PyObject *keywds)
/* Part a channel */
{
char *from, *to, *rest="";
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss", kwlist, &from, &to))
return NULL;
do_part(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_cycle(PyObject *self, PyObject *args, PyObject *keywds)
/* Cycle a channel */
{
char *from, *to, *rest="";
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss", kwlist, &from, &to))
return NULL;
do_cycle(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_wall(PyObject *self, PyObject *args, PyObject *keywds)
/* Wall */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_wall(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_mode(PyObject *self, PyObject *args, PyObject *keywds)
/* Mode */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_mode(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_invite(PyObject *self, PyObject *args, PyObject *keywds)
/* Invite */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_invite(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_sayme(PyObject *self, PyObject *args, PyObject *keywds)
/* Say /me */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_sayme(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_topic(PyObject *self, PyObject *args, PyObject *keywds)
/* Set topic */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_topic(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_idle(PyObject *self, PyObject *args, PyObject *keywds)
/* Check idle time */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_idle(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
#endif /* 0 */
static PyObject *python_find_nuh(PyObject *self, PyObject *args, PyObject *keywds)
/* Find nuh */
{
char *nick, *nuh;
static char *kwlist[] = {"nick", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s", kwlist, &nick))
return NULL;
nuh = find_nuh(nick);
if (nuh == NULL) Py_RETURN_NONE;
else return Py_BuildValue("s", nuh);
}
/* From core.c */
#if 0
static PyObject *python_do_die(PyObject *self, PyObject *args, PyObject *keywds)
{
char *from="", *to="", *rest="";
int cmdaccess=0;
static char *kwlist[] = {"from", "rest", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|s", kwlist, &from, &rest))
return NULL;
do_die(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_shutdown(PyObject *self, PyObject *args, PyObject *keywds)
{
char *from="", *to="", *rest="";
int cmdaccess=0;
static char *kwlist[] = {"from", "rest", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|s", kwlist, &from, &rest))
return NULL;
do_shutdown(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
static PyObject *python_do_server(PyObject *self, PyObject *args, PyObject *keywds)
/* Connect server */
{
char *from, *to, *rest;
int cmdaccess = 100;
static char *kwlist[] = {"from", "to", "rest", "cmdaccess", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sss|i", kwlist,
&from, &to, &rest, &cmdaccess))
return NULL;
do_server(from, to, rest, cmdaccess);
Py_RETURN_NONE;
}
#endif /* 0 */
PyObject *python_hook(PyObject *self, PyObject *args, PyObject *keywds)
{
Hook *hook;
HookTimer hooktimer;
PyObject *cb, *funcname;
char *type, *command, *cbname;
int guid = 0, mode, sz1, sz2;
static char *kwlist[] = {"type", "command", "callback", "guid", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ssO|i", kwlist,
&type, &command, &cb, &guid))
return NULL;
/* check callback function */
if (!PyFunction_Check(cb))
{
PyErr_SetString(python_error, "(python_hook) callback is not a function");
return NULL;
}
funcname = PyObject_GetAttrString(cb, "__name__"); /* new ref */
if (!funcname)
{
PyErr_SetString(python_error, "(python_hook) cant get function name");
return NULL;
}
#if PY_MAJOR_VERSION >= 3
cbname = python_unicode2char((PyUnicodeObject*) funcname);
#else
cbname = PyString_AsString(funcname); /* not a copy! */
#endif /* Py3k */
mode = strlen(type);
sz1 = strlen(command);
sz2 = strlen(cbname);
if (!mode || !sz1 || !sz2)
{
Py_DECREF(funcname);
#if PY_MAJOR_VERSION >= 3
free(cbname);
#endif /* Py3k */
PyErr_SetString(python_error, "(python_hook) invalid params");
return NULL;
}
if (!stringcasecmp(type, "command"))
mode = HOOK_COMMAND;
else
if (!stringcasecmp(type, "dcc_complete"))
mode = HOOK_DCC_COMPLETE;
else
if (!stringcasecmp(type, "parse"))
mode = HOOK_PARSE;
else
if (!stringcasecmp(type, "timer"))
{
if (compile_timer(&hooktimer, command) < 0)
{
Py_DECREF(funcname);
#if PY_MAJOR_VERSION >= 3
free(cbname);
#endif /* Py3k */
PyErr_SetString(python_error, "(python_hook) cant compile timer");
return NULL;
}
mode = HOOK_TIMER;
sz1 = sizeof(HookTimer);
}
else
{
Py_DECREF(funcname);
#if PY_MAJOR_VERSION >= 3
free(cbname);
#endif /* Py3k */
PyErr_SetString(python_error, "(python_hook) invalid hook type");
return NULL;
}
set_mallocdoer(python_hook);
hook = (Hook*) Calloc(sizeof(Hook) + sz1 + sz2);
hook->guid = guid;
hook->flags = mode;
hook->next = hooklist;
hooklist = hook;
hook->type.any = (void*) (stringcpy(hook->self, cbname) + 1);
switch(mode)
{
case HOOK_COMMAND:
case HOOK_PARSE:
stringcpy(hook->type.command, command);
hook->func = python_parse_jump;
break;
default:
/* case HOOK_TIMER: */
memcpy(hook->type.timer, &hooktimer, sizeof(HookTimer));
hook->func = python_timer_jump;
break;
}
#ifdef DEBUG
debug("(python_hook) hooked %s `%s' --> %s\n",
nullstr(type), nullstr(command), nullstr(cbname));
#endif /* DEBUG */
Py_DECREF(funcname);
#if PY_MAJOR_VERSION >= 3
free(cbname);
#endif /* Py3k */
Py_RETURN_NONE;
}
PyObject *python_unhook(PyObject *self, PyObject *args, PyObject *keywds)
{
return Py_BuildValue("i", 1);
}
int python_parse_jump(char *from, char *rest, Hook *hook)
{
int i;
PyObject *mainmod, *cb, *res;
#ifdef DEBUG
debug("(python_parse_jump) %s %s %s\n",
nullstr(hook->self), nullstr(from), nullstr(rest));
#endif /* DEBUG */
if (from)
nickcpy(CurrentNick, from);
else
*CurrentNick = 0;
/* get callback object */
mainmod = PyImport_AddModule("__main__");
if (!mainmod)
{
#ifdef DEBUG
debug("(python_parse_jump) cant get main module\n");
#endif /* DEBUG */
return 0; /* python exception has been set */
}
cb = PyDict_GetItemString(PyModule_GetDict(mainmod), hook->self);
if (!PyFunction_Check(cb))
{
#ifdef DEBUG
debug("(python_parse_jump) invalid callback function\n");
#endif /* DEBUG */
return 0;
}
/* call our function */
res = PyObject_CallFunction(cb, "ss", from, rest); /* new ref */
#if PY_MAJOR_VERSION >= 3
i = PyLong_AsLong(res);
#else
i = PyInt_AS_LONG(res);
#endif /* Py3k */
#ifdef DEBUG
debug("(python_parse_jump) result = %d\n", i);
#endif
Py_DECREF(res);
return i;
}
int python_timer_jump(Hook *hook)
{
return 0;
}
#ifdef DCC_FILE
void python_dcc_complete(Client *client, int cps)
{
PyObject *mainmod = NULL, *cb, *res;
Hook *hook;
for (hook = hooklist; hook; hook = hook->next)
{
if (hook->flags == HOOK_DCC_COMPLETE &&
hook->guid && current && hook->guid == current->guid)
{
/* get callback object */
if (!mainmod)
mainmod = PyImport_AddModule("__main__");
if (!mainmod)
{
#ifdef DEBUG
debug("(python_dcc_complete) cant get main module\n");
#endif /* DEBUG */
return; /* python exception has been set */
}
cb = PyDict_GetItemString(PyModule_GetDict(mainmod), hook->self);
if (!PyFunction_Check(cb))
{
#ifdef DEBUG
debug("(python_dcc_complete) invalid callback function\n");
#endif /* DEBUG */
return;
}
/* call our function */
res = PyObject_CallFunction(cb, "ssi",
client->whom, client->filename, cps); /* new ref */
#ifdef DEBUG
#if PY_MAJOR_VERSION >= 3
debug("(python_dcc_complete) result = %d\n", PyLong_AsLong(res));
#else
debug("(python_dcc_complete) result = %d\n", PyInt_AS_LONG(res));
#endif /* Py3k */
#endif /* DEBUG */
Py_DECREF(res);
}
}
}
#endif /* DCC_FILE */
PyObject *python_userlevel(PyObject *self, PyObject *args, PyObject *keywds)
{
#ifdef DEBUG
if (!current)
{
PyErr_SetString(python_error, "(python_userlevel) No current bot?!");
return NULL;
}
#endif /* DEBUG */
char *nuh, *chan;
int n;
static char *kwlist[] = {"nuh", "chan", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|s", kwlist, &nuh, &chan))
return NULL;
n = get_useraccess(nuh, chan);
return Py_BuildValue("i", n);
}
PyObject *python_to_server(PyObject *self, PyObject *args, PyObject *keywds)
{
#ifdef DEBUG
if (!current)
{
PyErr_SetString(python_error, "(python_to_server) No current bot?!");
return NULL;
}
#endif /* DEBUG */
Strp *sp, **pp;
char *line;
int sendqmax = -1, n, sz;
static char *kwlist[] = {"line", "sendqmax", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|i", kwlist, &line, &sendqmax))
return NULL;
#ifdef DEBUG
debug("(python_to_server) max = %i; line = %s\n", sendqmax, line);
#endif /* DEBUG */
sz = strlen(line);
if (sendqmax >= 0)
{
n = 0;
pp = &current->sendq;
while (*pp)
{
n++;
pp = &(*pp)->next;
}
if (sendqmax && n >= sendqmax) n = -n;
else
if (sz)
{
make_strp(pp,line);
}
}
else
{
if ((n = write(current->sock, line, sz)) < 0)
{
#ifdef DEBUG
debug("(python_to_server) {%i} errno = %i\n", current->sock, errno);
#endif /* DEBUG */
close(current->sock);
current->sock = -1;
current->connect = CN_NOSOCK;
PyErr_SetString(python_error, "Socket error");
return NULL;
}
current->sendq_time += 2;
}
return Py_BuildValue("i", n);
}
PyObject *python_to_file(PyObject *self, PyObject *args, PyObject *keywds)
{
int fd, r;
char *txt;
static char *kwlist[] = {"fd", "text", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "is", kwlist, &fd, &txt))
return NULL;
r = write(fd, txt, strlen(txt));
return Py_BuildValue("i", r);
}
#ifdef DCC_FILE
static PyObject *python_dcc_sendfile(PyObject *self, PyObject *args, PyObject *keywds)
{
char *filename, *target;
int sz;
static char *kwlist[] = {"file", "target", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss", kwlist, &filename, &target))
return NULL;
if ((sz = dcc_sendfile(target, filename)) < 0)
{
PyErr_SetString(python_error, "(python_dcc_sendfile) error!");
return NULL;
}
return Py_BuildValue("i", sz);
}
#endif /* DCC_FILE */
#ifdef DEBUG
PyObject *python_debug(PyObject *self, PyObject *args)
{
PyObject *o;
if (!PyArg_ParseTuple(args, "O", &o))
return NULL;
o = PyObject_Repr(o);
if (!o)
{
debug("(python_debug) object has no __repr__ method\n");
Py_RETURN_NONE;
}
#if PY_MAJOR_VERSION >= 3
char *cs;
cs = python_unicode2char((PyUnicodeObject*) o);
debug("(python_debug) %s\n", cs);
free(cs);
#else
debug("(python_debug) %s\n", PyString_AsString(o));
#endif /* Py3k */
Py_RETURN_NONE;
}
#endif /* DEBUG */
#ifdef RAWDNS
int python_dns_jump(char *host, char *resolved, Hook *hook)
{
PyObject *mainmod, *cb, *res;
int i = 0;
#ifdef DEBUG
debug("(python_dns_jump) %s %s %s\n",
nullstr(hook->self), nullstr(host), nullstr(resolved));
#endif /* DEBUG */
/* get callback object */
mainmod = PyImport_AddModule("__main__");
if (!mainmod)
{
#ifdef DEBUG
debug("(python_dns_jump) cant get main module\n");
#endif /* DEBUG */
return 0; /* python exception has been set */
}
cb = PyDict_GetItemString(PyModule_GetDict(mainmod), hook->self);
if (!PyFunction_Check(cb))
{
#ifdef DEBUG
debug("(python_dns_jump) invalid callback function\n");
#endif /* DEBUG */
return 0;
}
/* call our function */
res = PyObject_CallFunction(cb, "ss", host, resolved); /* new ref */
#if PY_MAJOR_VERSION >= 3
i = PyLong_AsLong(res);
#else
i = PyInt_AS_LONG(res);
#endif /* Py3k */
#ifdef DEBUG
debug("(python_dns_jump) result = %d\n", i);
#endif /* DEBUG */
Py_DECREF(res);
return i;
}
static PyObject *python_dns(PyObject *self, PyObject *args, PyObject *keywds)
{
PyObject *cb, *funcname;
Hook *hook;
char *host, *cbname;
static char *kwlist[] = {"host", "callback", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "sO", kwlist, host, cb))
return NULL;
/* check callback function */
if (!PyFunction_Check(cb))
{
PyErr_SetString(python_error, "(python_dns) callback is not a function");
return NULL;
}
funcname = PyObject_GetAttrString(cb, "__name__"); /* new ref */
if (!funcname)
{
PyErr_SetString(python_error, "(python_dns) cant get function name");
return NULL;
}
#if PY_MAJOR_VERSION >= 3
cbname = python_unicode2char((PyUnicodeObject*) funcname);
#else
cbname = PyString_AsString(funcname); /* not a copy! */
#endif /* Py3k */
#ifdef DEBUG
debug("(python_dns) resolving: %s (callback %s)\n", host, cbname);
#endif /* DEBUG */
set_mallocdoer(python_dns);
hook = (Hook*)Calloc(sizeof(Hook) + strlen(host));
hook->guid = (current) ? current->guid : 0;
hook->flags = HOOK_DNS;
hook->next = hooklist;
hooklist = hook;
hook->type.host = stringcpy(hook->self, cbname) + 1;
stringcpy(hook->type.host, host);
hook->func = python_dns_jump;
rawdns(host);
#if PY_MAJOR_VERSION >= 3
free(cbname);
#endif /* Py3k */
Py_DECREF(funcname);
Py_RETURN_NONE;
}
#endif /* RAWDNS */
static PyObject *python_execute(PyObject *self, PyObject *args)
{
PyObject *cmd, *from, *to, *rest;
char *c_cmd, *c_from, *c_to, *c_rest;
int cmdaccess, i;
void (*found)(char*, const char*,char*, const int) = NULL;
if (!PyArg_ParseTuple(args, "OOOOi", &cmd, &from, &to, &rest, &cmdaccess))
return NULL;
/* check for 4 strings */
#if PY_MAJOR_VERSION >= 3
if (!PyUnicode_CheckExact(cmd)
|| !(PyUnicode_CheckExact(from))/* || Py_None == from)*/
|| !PyUnicode_CheckExact(to)
|| !PyUnicode_CheckExact(rest))
#else
if (!PyString_CheckExact(cmd)
|| !(PyString_CheckExact(from))/* || Py_None == from)*/
|| !PyString_CheckExact(to)
|| !PyString_CheckExact(rest))
#endif /* Py3k */
{
PyErr_SetString(python_error, "(python_execute) invalid arguments");
return NULL;
}
/* extract vars */
#if PY_MAJOR_VERSION >= 3
c_cmd = python_unicode2char((PyUnicodeObject*) cmd);
if (from != Py_None) c_from = python_unicode2char((PyUnicodeObject*) from);
c_to = python_unicode2char((PyUnicodeObject*) to);
c_rest = python_unicode2char((PyUnicodeObject*) rest);
#else
c_cmd = PyString_AsString(cmd); /* not a copy */
if (from != Py_None) c_from = PyString_AsString(from);
c_to = PyString_AsString(to);
c_rest = PyString_AsString(rest);
#endif /* Py3k */
/*
if (from == Py_None)
{
from = LocalBot..;
}*/
/* check command exists */
for (i = 0; mcmd[i].name; ++i)
{
if (!stringcmp(mcmd[i].name, c_cmd))
{
found = mcmd[i].func;
break;
}
}
if (!found)
{
#ifdef DEBUG
debug("(python_execute) squeeze me (%s) !?!\n", c_cmd);
#endif /* DEBUG */
#if PY_MAJOR_VERSION >= 3
free(c_cmd); if (from != Py_None) free(c_from); free(c_to); free(c_rest);
#endif /* Py3k */
Py_RETURN_NONE;
}
#ifdef DEBUG
debug("(python_execute) (%s) (%s) (%s) (%s) (%d)\n", c_cmd, c_from, c_to, c_rest, cmdaccess);
#endif /* DEBUG */
(*found)(c_from, c_to, c_rest, cmdaccess);
#if PY_MAJOR_VERSION >= 3
free(c_cmd); if (from != Py_None) free(c_from); free(c_to); free(c_rest);
#endif /* Py3k */
Py_RETURN_NONE;
}
static struct PyMethodDef pythonMethods[] =
{
{"getvar", (PyCFunction) python_getvar, METH_VARARGS, "Get variable"},
{"userlevel", (PyCFunction) python_userlevel, METH_VARARGS|METH_KEYWORDS, "User level"},
/* From channel.c */
{"is_chanuser", (PyCFunction) python_is_chanuser, METH_VARARGS|METH_KEYWORDS, "Check nick is in channel"},
#if 0
{"join", (PyCFunction) python_do_join, METH_VARARGS|METH_KEYWORDS, "Join a channel"},
{"part", (PyCFunction) python_do_part, METH_VARARGS|METH_KEYWORDS, "Part a channel"},
{"cycle", (PyCFunction) python_do_cycle, METH_VARARGS|METH_KEYWORDS, "Cycle a channel"},
{"wall", (PyCFunction) python_do_wall, METH_VARARGS|METH_KEYWORDS, "Do wall"},
{"mode", (PyCFunction) python_do_mode, METH_VARARGS|METH_KEYWORDS, "Do mode"},
{"invite", (PyCFunction) python_do_invite, METH_VARARGS|METH_KEYWORDS, "Do invite"},
{"sayme", (PyCFunction) python_do_sayme, METH_VARARGS|METH_KEYWORDS, "Do sayme"},
{"topic", (PyCFunction) python_do_topic, METH_VARARGS|METH_KEYWORDS, "Do topic"},
{"idle", (PyCFunction) python_do_idle, METH_VARARGS|METH_KEYWORDS, "Do idle"},
#endif /* 0 */
{"find_nuh", (PyCFunction) python_find_nuh, METH_VARARGS|METH_KEYWORDS, "Find nuh"},
/* From core.c */
#if 0
{"die", (PyCFunction) python_do_die, METH_VARARGS|METH_KEYWORDS, "Die"},
{"shutdown", (PyCFunction) python_do_shutdown, METH_VARARGS|METH_KEYWORDS, "Shutdown"},
{"server", (PyCFunction) python_do_server, METH_VARARGS|METH_KEYWORDS, "Connect server"},
#endif /* 0 */
/* Scripting stuff */
{"hook", (PyCFunction) python_hook, METH_VARARGS|METH_KEYWORDS, "Create hook"},
{"unhook", (PyCFunction) python_unhook, METH_VARARGS|METH_KEYWORDS, "Destroy hook"},
#ifdef DCC_FILE
{"dcc_sendfile", (PyCFunction) python_dcc_sendfile, METH_VARARGS|METH_KEYWORDS, "DCC send file"},
#endif /* DCC_FILE */
{"to_server", (PyCFunction) python_to_server, METH_VARARGS|METH_KEYWORDS, "Write line to server"},
{"to_file", (PyCFunction) python_to_file, METH_VARARGS|METH_KEYWORDS, "Write text to file"},
#ifdef DEBUG
{"debug", (PyCFunction) python_debug, METH_VARARGS, "Emech debug"},
#endif /* DEBUG */
#ifdef RAWDNS
{"dns", (PyCFunction) python_dns, METH_VARARGS|METH_KEYWORDS, "DNS"},
#endif /* RAWDNS */
{"execute", (PyCFunction) python_execute, METH_VARARGS, "Execute internal command"},
{NULL, NULL, 0, NULL} /* sentinel */
};
#if PY_MAJOR_VERSION >= 3
struct PyModuleDef pythonModule =
{
PyModuleDef_HEAD_INIT,
"emech", /* module name */
"EnergyMech", /* module docstring */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
pythonMethods
};
#endif /* Py3k */
PyMODINIT_FUNC pythonInit(void)
{
PyObject *m;
#if PY_MAJOR_VERSION == 3
if ((m = PyModule_Create(&pythonModule)) == NULL)
return NULL;
#else
m = Py_InitModule4("emech", pythonMethods,
"EnergyMech", (PyObject*) NULL, PYTHON_API_VERSION);
#endif /* Py3k */
python_error = PyErr_NewException("emech.Error", NULL, NULL);
Py_INCREF(python_error);
PyModule_AddObject(m, "Error", python_error);
#ifdef DEBUG
PyModule_AddIntConstant(m, "define_debug", 1);
#else
PyModule_AddIntConstant(m, "define_debug", 0);
#endif /* DEBUG */
PyModule_AddStringConstant(m, "HOOK_COMMAND", "command");
PyModule_AddStringConstant(m, "HOOK_PARSE", "parse");
PyModule_AddStringConstant(m, "HOOK_TIMER", "timer");
PyModule_AddStringConstant(m, "DCC_COMPLETE", "dcc_complete");
PyModule_AddIntConstant(m, "OK", 0);
PyModule_AddIntConstant(m, "ERROR", 1);
PyModule_AddIntConstant(m, "GUID", PYVAR_guid);
PyModule_AddIntConstant(m, "CURRENTNICK", PYVAR_currentnick);
PyModule_AddIntConstant(m, "BOTNICK", PYVAR_botnick);
PyModule_AddIntConstant(m, "WANTNICK", PYVAR_wantnick);
PyModule_AddIntConstant(m, "USERHOST", PYVAR_userhost);
PyModule_AddIntConstant(m, "SERVER", PYVAR_server);
PyModule_AddIntConstant(m, "NEXTSERVER", PYVAR_nextserver);
PyModule_AddIntConstant(m, "CURRENTCHAN", PYVAR_currentchan);
PyModule_AddStringConstant(m, "VERSION", (char *)VERSION);
PyModule_AddStringConstant(m, "SRCDATE", (char *)SRCDATE);
PyModule_AddStringConstant(m, "BOTCLASS", (char *)BOTCLASS);
if (PyErr_Occurred())
{
PyErr_Print();
Py_FatalError("Cant initialize module emech!");
}
#if PY_MAJOR_VERSION >= 3
return m;
#endif /* Py3k */
}
void init_python(void)
{
if (Py_IsInitialized()) return;
PyImport_AppendInittab((char*) "emech", pythonInit);
#if PY_MAJOR_VERSION >= 3
Py_SetProgramName(L"energymech");
wchar_t *argv2[] = {L""};
#else
Py_SetProgramName("energymech");
char *argv2[] = {""};
#endif /* Py3k */
Py_Initialize();
PySys_SetArgv(1, argv2);
}
#ifdef PLEASE_HACK_MY_SHELL
void do_python(COMMAND_ARGS)
{
init_python();
int res = PyRun_SimpleString(rest);
to_user(from, "python command %s", (res == 0) ? "executed ok" : "failed");
}
#endif /* PLEASE_HACK_MY_SHELL */
void do_pythonscript(COMMAND_ARGS)
{
init_python();
FILE *f = fopen(rest, "r");
if (f == NULL)
{
to_user(from, "python script %s not existing or unreadable", rest);
return;
}
int res = PyRun_SimpleFileEx(f, rest, 1);
to_user(from,"python script %s", (res == 0) ? "loaded ok" : "failed to load");
}
void free_python(void)
{
if (Py_IsInitialized()) Py_Finalize();
}
#endif /* PYTHON */