X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/0076604e09f9e18ebca0576703dd83fa8f2c953a..b39754f763284af8fc45de2d5b734b2ce072b8c7:/src/mod-python.c diff --git a/src/mod-python.c b/src/mod-python.c index 4b64e17..80c9401 100644 --- a/src/mod-python.c +++ b/src/mod-python.c @@ -36,6 +36,7 @@ #include "mail.h" #include "timeq.h" #include "compat.h" +#include "nickserv.h" /* TODO notes * @@ -83,40 +84,19 @@ struct _tuple_dict_extra { size_t* extra; }; -static int _dict_iter_get_users(char const* key, UNUSED_ARG(void* data), void* extra) { - PyObject* tmp; - struct _tuple_dict_extra* real_extra = (struct _tuple_dict_extra*)extra; - - if ((tmp = PyString_FromString(key)) == NULL) - return 1; - - if (PyTuple_SetItem(real_extra->data, *(int*)real_extra->extra, tmp)) { - Py_DECREF(tmp); - return 1; - } - - *real_extra->extra = *real_extra->extra + 1; - - return 0; -} - -static int _dict_iter_get_channels(char const* key, UNUSED_ARG(void* data), void* extra) { - PyObject* tmp; - struct _tuple_dict_extra* real_extra = (struct _tuple_dict_extra*)extra; +static void pyobj_release_tuple(PyObject* tuple, size_t n) { + size_t i; - if ((tmp = PyString_FromString(key)) == NULL) - return 1; + if (tuple == NULL) + return; - if (PyTuple_SetItem(real_extra->data, *(int*)real_extra->extra, tmp)) { - Py_DECREF(tmp); - return 1; - } + for (i = 0; i < n; ++i) + Py_XDECREF(PyTuple_GET_ITEM(tuple, i)); - *real_extra->extra = *real_extra->extra + 1; - return 0; + Py_XDECREF(tuple); } -static int _dict_iter_get_servers(char const* key, UNUSED_ARG(void* data), void* extra) { +static int _dict_iter_fill_tuple(char const* key, UNUSED_ARG(void* data), void* extra) { PyObject* tmp; struct _tuple_dict_extra* real_extra = (struct _tuple_dict_extra*)extra; @@ -132,96 +112,58 @@ static int _dict_iter_get_servers(char const* key, UNUSED_ARG(void* data), void* return 0; } -/* get a tuple with all users in it */ static PyObject* -emb_get_users(UNUSED_ARG(PyObject *self), PyObject *args) { +pyobj_from_dict_t(dict_t d) { PyObject* retval; - PyObject* tmp; - size_t num_clients, n = 0, i; + size_t n = 0; struct _tuple_dict_extra extra; - if (!PyArg_ParseTuple(args, "")) - return NULL; - - num_clients = dict_size(clients); - retval = PyTuple_New(num_clients); - if (retval == NULL) + if ((retval = PyTuple_New(dict_size(d))) == NULL) return NULL; extra.extra = &n; extra.data = retval; - if (dict_foreach(clients, _dict_iter_get_users, (void*)&extra) != NULL) { - for (i = 0; i < n; ++i) { - tmp = PyTuple_GetItem(retval, i); - PyTuple_SET_ITEM(retval, i, NULL); - Py_DECREF(tmp); - } - Py_DECREF(retval); + if (dict_foreach(d, _dict_iter_fill_tuple, (void*)&extra) != NULL) { + pyobj_release_tuple(retval, n); return NULL; } return retval; } -/* get a tuple with all channels in it */ +/* get a tuple with all users in it */ static PyObject* -emb_get_channels(UNUSED_ARG(PyObject* self), PyObject* args) { - PyObject* retval; - PyObject* tmp; - size_t num_channels, n = 0, i; - struct _tuple_dict_extra extra; - +emb_get_users(UNUSED_ARG(PyObject *self), PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - num_channels = dict_size(channels); - retval = PyTuple_New(num_channels); - if (retval == NULL) - return NULL; - - extra.extra = &n; - extra.data = retval; + return pyobj_from_dict_t(clients); +} - if (dict_foreach(channels, _dict_iter_get_channels, (void*)&extra) != NULL) { - for (i = 0; i < n; ++i) { - tmp = PyTuple_GetItem(retval, i); - PyTuple_SET_ITEM(retval, i, NULL); - Py_DECREF(tmp); - } - Py_DECREF(retval); +/* get a tuple with all channels in it */ +static PyObject* +emb_get_channels(UNUSED_ARG(PyObject* self), PyObject* args) { + if (!PyArg_ParseTuple(args, "")) return NULL; - } - return retval; + return pyobj_from_dict_t(channels); } static PyObject* emb_get_servers(UNUSED_ARG(PyObject* self), PyObject* args) { - PyObject* retval; - PyObject* tmp; - size_t n = 0, i; - struct _tuple_dict_extra extra; - if (!PyArg_ParseTuple(args, "")) return NULL; - retval = PyTuple_New(dict_size(servers)); - - extra.extra = &n; - extra.data = retval; + return pyobj_from_dict_t(servers); +} - if (dict_foreach(servers, _dict_iter_get_servers, (void*)&extra) != NULL) { - for (i = 0; i < n; ++i) { - tmp = PyTuple_GetItem(retval, i); - PyTuple_SET_ITEM(retval, i, NULL); - Py_DECREF(tmp); - } - Py_DECREF(retval); +static PyObject* +emb_get_accounts(UNUSED_ARG(PyObject* self), PyObject* args) { + if (!PyArg_ParseTuple(args, "")) return NULL; - } - return retval; + return pyobj_from_dict_t(nickserv_handle_dict); } static PyObject* @@ -315,7 +257,7 @@ emb_send_target_notice(UNUSED_ARG(PyObject *self), PyObject *args) static PyObject* pyobj_from_usernode(struct userNode* user) { - unsigned int n, i; + unsigned int n; struct modeNode *mn; PyObject* retval = NULL; PyObject* pChanList = PyTuple_New(user->channels.used); @@ -370,12 +312,7 @@ pyobj_from_usernode(struct userNode* user) { cleanup: Py_XDECREF(retval); - for (i = 0; i < n; ++i) { - retval = PyTuple_GetItem(pChanList, i); - PyTuple_SET_ITEM(pChanList, i, NULL); - Py_XDECREF(retval); - } - Py_DECREF(pChanList); + pyobj_release_tuple(pChanList, n); return NULL; } @@ -461,13 +398,7 @@ pyobj_from_server(struct server* srv) { cleanup: Py_XDECREF(retval); - - for (n = 0; n < idx; ++n) { - tmp = PyTuple_GetItem(users, n); - PyTuple_SetItem(users, n, NULL); - Py_DECREF(tmp); - } - Py_DECREF(users); + pyobj_release_tuple(users, idx); return NULL; } @@ -493,6 +424,82 @@ emb_get_server(UNUSED_ARG(PyObject* self), PyObject* args) { return pyobj_from_server(srv); } +static PyObject* +pyobj_from_modelist(struct modeList* mode) { + size_t n; + PyObject* tmp; + PyObject* retval = PyTuple_New(mode->used); + + if (retval == NULL) + return NULL; + + for (n = 0; n < mode->used; ++n) { + struct modeNode* mn = mode->list[n]; + tmp = PyString_FromString(mn->user->nick); + if (tmp == NULL) { + pyobj_release_tuple(retval, n); + return NULL; + } + + if (PyTuple_SetItem(retval, n, tmp)) { + pyobj_release_tuple(retval, n); + return NULL; + } + } + + return retval; +} + +static PyObject* +pyobj_from_banlist(struct banList* bans) { + size_t n; + struct banNode* bn; + PyObject* tmp; + PyObject* retval = PyTuple_New(bans->used); + + if (retval == NULL) + return NULL; + + for (n = 0; n < bans->used; ++n) { + bn = bans->list[n]; + + tmp = Py_BuildValue("{s:s,s:s,s:l}", + "ban", bn->ban, "who", bn->who, "set", bn->set); + + if (tmp == NULL || PyTuple_SetItem(retval, n, tmp)) { + pyobj_release_tuple(retval, n); + return NULL; + } + } + + return retval; +} + +static PyObject* +pyobj_from_exemptlist(struct exemptList* exmp) { + size_t n; + struct exemptNode* en; + PyObject* tmp; + PyObject* retval = PyTuple_New(exmp->used); + + if (retval == NULL) + return NULL; + + for (n = 0; n < exmp->used; ++n) { + en = exmp->list[n]; + + tmp = Py_BuildValue("{s:s,s:s,s:l}", + "ban", en->exempt, "who", en->who, "set", en->set); + + if (tmp == NULL || PyTuple_SetItem(retval, n, tmp)) { + pyobj_release_tuple(retval, n); + return NULL; + } + } + + return retval; +} + static PyObject* emb_get_channel(UNUSED_ARG(PyObject *self), PyObject *args) { @@ -501,10 +508,10 @@ emb_get_channel(UNUSED_ARG(PyObject *self), PyObject *args) */ char *name; struct chanNode *channel; - unsigned int n; - PyObject *pChannelMembers; - PyObject *pChannelBans; - PyObject *pChannelExempts; + PyObject *pChannelMembers = NULL; + PyObject *pChannelBans = NULL; + PyObject *pChannelExempts = NULL; + PyObject *retval = NULL; if(!PyArg_ParseTuple(args, "s", &name)) @@ -516,37 +523,21 @@ emb_get_channel(UNUSED_ARG(PyObject *self), PyObject *args) } /* build tuple of nicks in channel */ - pChannelMembers = PyTuple_New(channel->members.used); - for(n=0;n < channel->members.used;n++) { - struct modeNode *mn = channel->members.list[n]; - PyTuple_SetItem(pChannelMembers, n, Py_BuildValue("s", mn->user->nick)); - } + pChannelMembers = pyobj_from_modelist(&channel->members); + if (pChannelMembers == NULL) + goto cleanup; /* build tuple of bans */ - pChannelBans = PyTuple_New(channel->banlist.used); - for(n=0; n < channel->banlist.used;n++) { - struct banNode *bn = channel->banlist.list[n]; - PyTuple_SetItem(pChannelBans, n, - Py_BuildValue("{s:s,s:s,s:i}", - "ban", bn->ban, - "who", bn->who, - "set", bn->set) - ); - } + pChannelBans = pyobj_from_banlist(&channel->banlist); + if (pChannelBans == NULL) + goto cleanup; /* build tuple of exempts */ - pChannelExempts = PyTuple_New(channel->exemptlist.used); - for(n=0; n < channel->exemptlist.used;n++) { - struct exemptNode *en = channel->exemptlist.list[n]; - PyTuple_SetItem(pChannelExempts, n, - Py_BuildValue("{s:s,s:s,s:i}", - "ban", en->exempt, - "who", en->who, - "set", en->set) - ); - } + pChannelExempts = pyobj_from_exemptlist(&channel->exemptlist); + if (pChannelExempts == NULL) + goto cleanup; - return Py_BuildValue("{s:s,s:s,s:s,s:i" + retval = Py_BuildValue("{s:s,s:s,s:s,s:i" ",s:i,s:i,s:O,s:O,s:O}", "name", channel->name, @@ -560,6 +551,18 @@ emb_get_channel(UNUSED_ARG(PyObject *self), PyObject *args) "bans", pChannelBans, "exempts", pChannelExempts ); + if (retval == NULL) + goto cleanup; + + return retval; + +cleanup: + Py_XDECREF(retval); + pyobj_release_tuple(pChannelExempts, channel->exemptlist.used); + pyobj_release_tuple(pChannelBans, channel->banlist.used); + pyobj_release_tuple(pChannelMembers, channel->members.used); + + return NULL; } static PyObject* @@ -696,6 +699,7 @@ static PyMethodDef EmbMethods[] = { {"get_server", emb_get_server, METH_VARARGS, "Get details about a server"}, {"get_servers", emb_get_servers, METH_VARARGS, "Get all server names"}, {"get_account", emb_get_account, METH_VARARGS, "Get details about an account"}, + {"get_accounts", emb_get_accounts, METH_VARARGS, "Get all nickserv accounts"}, {"get_info", emb_get_info, METH_VARARGS, "Get various misc info about x3"}, /* null terminator */ {NULL, NULL, 0, NULL}