]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/mod-python.c
mod-python: handle error states in emb_send_target_notice better
[irc/evilnet/x3.git] / src / mod-python.c
index 7aa92f015bad117a16bfdabb43f52c7a124751a0..29a933932c39bf9186739d2814d006a568ece3b9 100644 (file)
@@ -90,11 +90,17 @@ emb_dump(UNUSED_ARG(PyObject *self), PyObject *args)
 
     if(!PyArg_ParseTuple(args, "s:dump", &buf ))
         return NULL;
+
     safestrncpy(linedup, buf, sizeof(linedup));
+
     if(parse_line(linedup, 1)) {
         irc_raw(buf);
         ret = 1;
+    } else {
+        PyErr_SetString(PyExc_Exception, "invalid protocol message");
+        return NULL;
     }
+
     return Py_BuildValue("i", ret);
 }
 
@@ -114,11 +120,18 @@ emb_send_target_privmsg(UNUSED_ARG(PyObject *self), PyObject *args)
 
     if(!PyArg_ParseTuple(args, "sss:reply", &servicenick, &channel, &buf ))
         return NULL;
+
+    if (buf == NULL || strlen(buf) == 0) {
+        PyErr_SetString(PyExc_Exception, "invalid empty message");
+        return NULL;
+    }
+
     if(!(service = service_find(servicenick))) {
-        /* TODO: generate python exception here */
+        PyErr_SetString(PyExc_Exception, "no such service nick");
         return NULL;
     }
-    send_target_message(5, channel, service->bot, "%s", buf);
+
+    ret = send_target_message(5, channel, service->bot, "%s", buf);
     return Py_BuildValue("i", ret);
 }
 
@@ -135,64 +148,92 @@ emb_send_target_notice(UNUSED_ARG(PyObject *self), PyObject *args)
 
     struct service *service;
 
-
     if(!PyArg_ParseTuple(args, "sss:reply", &servicenick, &target, &buf ))
         return NULL;
+
+    if (buf == NULL || strlen(buf) == 0) {
+        PyErr_SetString(PyExc_Exception, "invalid empty message");
+        return NULL;
+    }
+
     if(!(service = service_find(servicenick))) {
-        /* TODO: generate python exception here */
+        PyErr_SetString(PyExc_Exception, "no such service nick");
         return NULL;
     }
-    send_target_message(4, target, service->bot, "%s", buf);
+
+    ret = send_target_message(4, target, service->bot, "%s", buf);
+
     return Py_BuildValue("i", ret);
 }
 
+static PyObject*
+pyobj_from_usernode(struct userNode* user) {
+    unsigned int n;
+    struct modeNode *mn;
+    PyObject* pChanList = PyTuple_New(user->channels.used);
+
+    for (n=0; n < user->channels.used; n++) {
+        mn = user->channels.list[n];
+        PyTuple_SetItem(pChanList, n, Py_BuildValue("s", mn->channel->name));
+    }
+
+    return Py_BuildValue("{"
+            "s: s, " /* nick */
+            "s: s, " /* ident */
+            "s: s, " /* info */
+            "s: s, " /* hostname */
+            "s: s, " /* ip */
+            "s: s, " /* fakehost */
+            "s: s, " /* sethost */
+            "s: s, " /* crypthost */
+            "s: s, " /* cryptip */
+#ifdef WITH_PROTOCOL_P10
+            "s: s, " /* numeric */
+#endif /* WITH_PROTOCOL_P10 */
+            "s: i, " /* loc */
+            "s: i, " /* no_notice */
+            "s: s, " /* mark */
+            "s: s, " /* version_reply */
+            "s: s, " /* account */
+            "s: O}", /* channels */
+            "nick", user->nick,
+            "ident", user->ident,
+            "info", user->info,
+            "hostname", user->hostname,
+            "ip", irc_ntoa(&user->ip),
+            "fakehost", user->fakehost,
+            "sethost", user->sethost,
+            "crypthost", user->crypthost,
+            "cryptip", user->cryptip,
+#ifdef WITH_PROTOCOL_P10
+            "numeric", user->numeric,
+#endif /* WITH_PROTOCOL_P10 */
+            "loc", user->loc,
+            "no_notice", user->no_notice,
+            "mark", user->mark,
+            "version_reply", user->version_reply,
+            "account", user->handle_info ? user->handle_info->handle : NULL,
+            "channels", pChanList);
+}
+
 static PyObject*
 emb_get_user(UNUSED_ARG(PyObject *self), PyObject *args)
 {
     /* Get a python object containing everything x3 knows about a user, by nick.
         usage: _svc.get_user(<nick>)
     */
-    char *nick;
+    char const* nick;
     struct userNode *user;
-    struct modeNode *mn;
-    unsigned int n;
-    PyObject* pChanList;
-
 
     if(!PyArg_ParseTuple(args, "s", &nick))
         return NULL;
+
     if(!(user = GetUserH(nick))) {
-        /* TODO: generate python exception here */
+        PyErr_SetString(PyExc_Exception, "no such user");
         return NULL;
     }
-    pChanList = PyTuple_New(user->channels.used);
-    for(n=0;n<user->channels.used;n++) {
-        mn = user->channels.list[n];
-        PyTuple_SetItem(pChanList, n, Py_BuildValue("s", mn->channel->name));
-    }
-    return Py_BuildValue("{s:s,s:s,s:s,s:s,s:s"   /* format strings. s=string, i=int */
-                         ",s:s,s:s,s:s,s:s,s:s"   /* (format is key:value)  O=object */
-                         ",s:i,s:i,s:s,s:s,s:s"   /* blocks of 5 for readability     */
-                         "s:O}", 
-
-                         "nick", user->nick,
-                         "ident", user->ident,
-                         "info", user->info,
-                         "hostname", user->hostname,
-                         "ip", irc_ntoa(&user->ip),
-
-                         "fakehost", user->fakehost,
-                         "sethost", user->sethost,
-                         "crypthost", user->crypthost,
-                         "cryptip", user->cryptip,
-                         "numeric", user->numeric, /* TODO: only ifdef WITH_PROTOCOL_P10 */
-
-                         "loc", user->loc,
-                         "no_notice", user->no_notice,
-                         "mark", user->mark,
-                         "version_reply", user->version_reply,
-                         "account", user->handle_info?user->handle_info->handle:NULL,
-                         "channels", pChanList);
+
+    return pyobj_from_usernode(user);
 }
 
 static PyObject*
@@ -707,6 +748,10 @@ int python_load() {
     pName = PyString_FromString(modpython_conf.main_module);
     base_module = PyImport_Import(pName);
     Py_DECREF(pName);
+
+    Py_XDECREF(handler_object);
+    handler_object = NULL;
+
     if(base_module != NULL) {
         handler_object = python_new_handler_object();
         if(handler_object) {