/*
* Dolda Connect - Modular multiuser Direct Connect-style client
- * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
+ * Copyright (C) 2004 Fredrik Tolf <fredrik@dolda2000.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
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);
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);
}
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;
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;
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';
}
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);
}
case DC_LOGIN_ERR_AUTHFAIL:
errstr = "authfail";
break;
+ default:
+ errstr = "unknown";
+ break;
}
pyerr = PyString_FromString(errstr);
if(reason == NULL)
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"},
"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}
};
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();
}