return(scm_reverse(ret));
}
+static SCM scm_dc_checkproto(SCM resp, SCM version)
+{
+ int ver;
+
+ SCM_ASSERT(SCM_SMOB_PREDICATE(resptype, resp), resp, SCM_ARG1, "dc-checkproto");
+ if(version == SCM_UNDEFINED)
+ {
+ ver = DC_LATEST;
+ } else {
+ SCM_ASSERT(SCM_INUMP(version), version, SCM_ARG2, "dc-checkproto");
+ ver = SCM_INUM(version);
+ }
+ if(dc_checkprotocol(((struct respsmob *)SCM_SMOB_DATA(resp))->resp, ver))
+ return(SCM_BOOL_F);
+ else
+ return(SCM_BOOL_T);
+}
+
static size_t resp_free(SCM respsmob)
{
struct respsmob *data;
scm_c_define_gsubr("dc-qcmd", 1, 1, 0, scm_dc_qcmd);
scm_c_define_gsubr("dc-loginasync", 2, 1, 0, scm_dc_loginasync);
scm_c_define_gsubr("dc-lexsexpr", 1, 0, 0, scm_dc_lexsexpr);
+ scm_c_define_gsubr("dc-checkproto", 1, 1, 0, scm_dc_checkproto);
+ scm_c_define("dc-latest", SCM_MAKINUM(DC_LATEST));
resptype = scm_make_smob_type("dc-resp", sizeof(struct respsmob));
scm_set_smob_free(resptype, resp_free);
scm_set_smob_print(resptype, resp_print);
(define-module (dolcon ui))
-(export dc-connect dc-disconnect dc-connected dc-select dc-getresp dc-extract dc-intresp dc-qcmd dc-loginasync dc-lexsexpr)
+(export dc-connect dc-disconnect dc-connected dc-select dc-getresp dc-extract dc-intresp dc-qcmd dc-loginasync dc-lexsexpr dc-checkproto)
(load-extension "libdolcon-guile" "init_guiledc")
errsym)))
(define-public dc-must-connect
- (lambda args
- (let* ((fd (apply dc-connect args)) (resp (dc-extract (do ((resp (dc-getresp) (dc-getresp)))
- ((and resp
- (equal? (cdr (assoc 'cmd (dc-extract resp))) ".connect"))
- resp)
- (dc-select)))))
- (if (= (cdr (assoc 'code resp)) 200)
- fd
+ (lambda (host . version)
+ (let* ((fd (dc-connect host))
+ (ores (do ((resp (dc-getresp) (dc-getresp)))
+ ((and resp
+ (equal? (cdr (assoc 'cmd (dc-extract resp))) ".connect"))
+ resp)
+ (dc-select)))
+ (resp (dc-extract ores)))
+ (if (not (= (cdr (assoc 'code resp)) 201))
(throw 'bad-return (cdr (assoc 'code resp)) (cadr (assoc 'resp resp)))
+ (if (dc-checkproto ores (if (pair? version) (car version) dc-latest))
+ fd
+ (throw 'bad-protocol ores))
)
)
)
select()
return result[0]
-def mustconnect(host, port = -1):
+def mustconnect(host, revision = latest):
"""A convenience function for connect.
This function will connect to the given host, perform a select
any of these steps fail, an exception is raised. If successful,
the file descriptor for the server connection is returned.
"""
- fd = connect(host, port)
+ fd = connect(host)
while True:
resp = getresp()
if resp is not None and resp.getcmd() == u".connect":
break
select()
- if resp.getcode() != 200:
+ if resp.getcode() != 201:
raise RuntimeError, resp.intresp()[0][0]
+ if not checkproto(resp, revision):
+ raise RuntimeError, resp
return fd
-def cnl(host = None, port = -1, useauthless = True, **kw):
+def cnl(host = None, useauthless = True, revision = latest, **kw):
"""A convenience function for connect and loginasync.
This function will connect to the given server, or the server in
host = os.getenv("DCSERVER")
if host is None:
host = "localhost"
- fd = mustconnect(host, port)
+ fd = mustconnect(host, revision)
err, reason = login(useauthless, **kw)
if err != "success":
raise RuntimeError, (err, reason)
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 = 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"},
"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();
}