X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fpython%2Fdolmod.c;h=c8df522502ed655d07268e1855d4e9d20b5f2208;hb=b23dedf9f35fe5ff61f0f826ed1b2753ad78db2f;hp=edae7ae702ef416d14e90a19fe2f7012aa36146c;hpb=fbe30a6da13729c16770608bb5a7f11d79b22fb2;p=doldaconnect.git diff --git a/lib/python/dolmod.c b/lib/python/dolmod.c index edae7ae..c8df522 100644 --- a/lib/python/dolmod.c +++ b/lib/python/dolmod.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * 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 @@ -90,6 +90,9 @@ static PyObject *resp_intresp(struct respobj *self) case 3: PyList_SetItem(sl, i, PyFloat_FromDouble(ires->argv[i].val.flnum)); break; + case 4: + PyList_SetItem(sl, i, PyLong_FromLongLong(ires->argv[i].val.lnum)); + break; } } dc_freeires(ires); @@ -134,14 +137,13 @@ static struct respobj *makeresp(struct dc_response *resp) static PyObject *mod_connect(PyObject *self, PyObject *args) { char *host; - int port; - port = -1; - if(!PyArg_ParseTuple(args, "s|i", &host, &port)) + host = NULL; + if(!PyArg_ParseTuple(args, "|s", &host)) return(NULL); if(fd >= 0) dc_disconnect(); - if((fd = dc_connect(host, port)) < 0) { + if((fd = dc_connect(host)) < 0) { PyErr_SetFromErrno(PyExc_OSError); return(NULL); } @@ -190,11 +192,11 @@ static PyObject *mod_select(PyObject *self, PyObject *args) return(NULL); } if(((pfd.revents & POLLIN) && dc_handleread()) || ((pfd.revents & POLLOUT) && dc_handlewrite())) { - if(errno == 0) { - fd = -1; + fd = -1; + if(errno == 0) Py_RETURN_FALSE; - } PyErr_SetFromErrno(PyExc_OSError); + return(NULL); } if(ret > 0) Py_RETURN_TRUE; @@ -233,7 +235,7 @@ static int qcmd_cb(struct dc_response *resp) static PyObject *mod_qcmd(PyObject *self, PyObject *args, PyObject *kwargs) { - int i, tag; + int i; wchar_t **toks, *tok, *cmd; size_t tokssize, toksdata, toksize; PyObject *c, *n, *cb, *ret; @@ -241,12 +243,15 @@ static PyObject *mod_qcmd(PyObject *self, PyObject *args, PyObject *kwargs) toks = NULL; tokssize = toksdata = 0; cmd = NULL; + ret = NULL; for(i = 0; i < PySequence_Size(args); i++) { - c = PySequence_GetItem(args, i); + if((c = PySequence_GetItem(args, i)) == NULL) + goto out; if(!PyUnicode_Check(c)) { n = PyUnicode_FromObject(c); Py_DECREF(c); - c = n; + if((c = n) == NULL) + goto out; } tok = smalloc((toksize = (PyUnicode_GetSize(c) + 1)) * sizeof(*tok)); tok[PyUnicode_AsWideChar((PyUnicodeObject *)c, tok, toksize)] = L'\0'; @@ -258,23 +263,26 @@ static PyObject *mod_qcmd(PyObject *self, PyObject *args, PyObject *kwargs) } if(cmd == NULL) { PyErr_SetString(PyExc_TypeError, "qcmd needs at least 1 argument"); - return(NULL); + goto out; } addtobuf(toks, NULL); ret = NULL; if(PyMapping_HasKeyString(kwargs, "cb")) { cb = PyMapping_GetItemString(kwargs, "cb"); if(PyCallable_Check(cb)) { - ret = PyInt_FromLong(dc_queuecmd(qcmd_cb, cb, cmd, L"%%a", toks, NULL)); + ret = PyInt_FromLong(dc_queuecmd(qcmd_cb, cb, cmd, L"%a", toks, NULL)); } else { PyErr_SetString(PyExc_TypeError, "Callback must be callable"); Py_DECREF(cb); } } else { - ret = PyInt_FromLong(dc_queuecmd(NULL, NULL, cmd, L"%%a", toks, NULL)); + ret = PyInt_FromLong(dc_queuecmd(NULL, NULL, cmd, L"%a", toks, NULL)); } + +out: dc_freewcsarr(toks); - free(cmd); + if(cmd != NULL) + free(cmd); return(ret); } @@ -302,6 +310,9 @@ static void login_cb(int err, wchar_t *reason, PyObject *cb) case DC_LOGIN_ERR_AUTHFAIL: errstr = "authfail"; break; + default: + errstr = "unknown"; + break; } pyerr = PyString_FromString(errstr); if(reason == NULL) @@ -376,6 +387,34 @@ static PyObject *mod_lexsexpr(PyObject *self, PyObject *args) return(ret); } +static PyObject *mod_wantwrite(PyObject *self) +{ + if(dc_wantwrite()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +static PyObject *mod_checkproto(PyObject *self, PyObject *args) +{ + PyObject *tmp; + struct respobj *resp; + int version; + + version = DC_LATEST; + if(!PyArg_ParseTuple(args, "O|i", &tmp, &version)) + return(NULL); + if(!PyObject_TypeCheck(tmp, &resptype)) { + PyErr_SetString(PyExc_TypeError, "first argument must be a response object"); + return(NULL); + } + resp = (struct respobj *)tmp; + if(dc_checkprotocol(resp->resp, version)) + Py_RETURN_FALSE; + else + Py_RETURN_TRUE; +} + static PyMethodDef methods[] = { {"connect", mod_connect, METH_VARARGS, "Connect to a Dolda Connect server"}, @@ -393,6 +432,10 @@ static PyMethodDef methods[] = { "Perform an asynchronous login procedure"}, {"lexsexpr", mod_lexsexpr, METH_VARARGS, "Use a standard algorithm to lex a search expression"}, + {"wantwrite", (PyCFunction)mod_wantwrite, METH_NOARGS, + "Return a boolean indicating whether there is output to be fed to the server"}, + {"checkproto", (PyCFunction)mod_checkproto, METH_VARARGS, + "Check so that the connect stanza returned by the server indicates support for the correct revision of the protocol"}, {NULL, NULL, 0, NULL} }; @@ -405,5 +448,6 @@ PyMODINIT_FUNC initdolmod(void) m = Py_InitModule("dolmod", methods); Py_INCREF(&resptype); PyModule_AddObject(m, "Response", (PyObject *)&resptype); + PyModule_AddObject(m, "latest", Py_BuildValue("i", DC_LATEST)); dc_init(); }