Kaydet (Commit) 36e5b94c authored tarafından Suleyman Poyraz's avatar Suleyman Poyraz

Added full support python3-api for iksemel. Should be write tests

üst 796cdd8a
......@@ -50,9 +50,6 @@ config.h.in
.libs/
#Iks test files
test/tst-*
#Iks compiled files
doc/iksemel
include/config.h
......@@ -60,6 +57,15 @@ include/stamp-h1
tools/ikslint
tools/iksperf
tools/iksroster
test/tst-dom
test/tst-filter
test/tst-iks
test/tst-ikstack
test/tst-jid
test/tst-sha
test/tst-md5
test/tst-sax
#Makefile files
Makefile
......
......@@ -2,7 +2,7 @@
Author
======
Gurer Ozen <madcat@e-kolay.net>
Gurer Ozen <meduketto at gmail.com>
Contributions
......
This diff is collapsed.
2011-10-18 Gurer
* python/: Python bindings and test scripts
2011-10-10 Gurer
* iks.c: iks_string() returns nul terminated strings for cdata nodes
2011-10-07 Gurer
* sax.c: Fix handling of ending ]] sequences in CDATA sections
bug report and patch by oscarvdbosch
* tst-sax.c: Test coverage for fixed bug
2011-10-06 Gurer
* configure.ac: without-openssl and without-gnutls options added
2011-10-06 Gurer
* configure.ac: Check openssl, it is preferred over gnutls
* tls-openssl.c: TLS backend for the openssl library
2011-10-05 Gurer
* md5.c: Fix padding for multiples of 64 bytes
* tst-md5.c: Test coverage for fixed bug
2009-08-30 Gurer
* configure.ac: use pkgconfig for checking gnutls
* INSTALL: updated by the autoreconf call
* README: gnutls dependency is mentioned
2009-08-07 Gurer
* tls-gnutls.c: support timeout value in tls_recv
2009-08-06 Gurer
* iksemel.h: new ikstls structure and definitions
* tls-gnutls.c: new file, GNUTLS implemantation moved here
* stream.c: TLS code is abstracted with new TLS interface
2009-07-25 Gurer
* version bump to 1.5 after the release
2009-07-22 Gurer
* io-posix.c: send/recv now handles EAGAIN/EINTR.
2009-07-21 Gurer
* tst-md5.c: MD5 test improved with examples from RFC1321
* iksroster.c: Plain text auth option patch from issue tracker.
2009-07-20 Gurer
* tst-sax.c: Fix a va_arg bug with 64bit platforms.
2009-07-18 Gurer
* sax.c: Fix attribute array out-of-bounds condition.
* iksperf.c: Fix a warning, and use size_t instead of int.
2009-07-04 Gurer
* md5.c: use iks_malloc/free like everywhere else.
(reported by Vinay Deshpande)
* stream.c: don't leak locally processed challenge node.
2009-04-02 Gurer
* sax.c: utf8 validation bug is fixed. Some valid utf8
sequences were not allowed before. Security check is moved
after sequence end point, so position of IKS_BADXML errors
are changed.
* tst-sax.c: test case for validation bug added.
2009-03-31 Gurer
* Patch by Timothy Lee:
sax.c: Whitespace between "attr, =, value" is valid now.
tst-sax.c: I also added a simple test for that.
2007-08-10 Gurer
* version bump to 1.4 after the release
......
......@@ -8,8 +8,8 @@ before sending patches to the iksemel, since it is implicitly assumed that
your patches are also submitted under the LGPL license.
Roadmap:
========
General Idea:
=============
Main goal of the iksemel is removing complexity from programs using the
library and the library itself. This is the reason why only a subset of XML
......@@ -18,33 +18,6 @@ implemented when we found ways to implement them without adding
too much complexity to the iksemel code. Somewhat external standarts
(XPath, XQuery, XSLT, vs) will probably not make it into the iksemel.
* validation
I think easiest way to add this feature is writing another parser based on the
sax parser which parses a dtd (either from sax parser's markup callback which
needs to be implemented or from an external source via iks_vsax_set_dtd() call)
and checks the arguments of sax callbacks. Using it via dom or stream parsers
can require some clever tricks. there are also xml schemas. they are easy to parse
(it is xml anyway) but can be hard to apply.
* utf16
There are two sides of this. Improving parser to accept utf16 can be relatively
easy. But on the client side things can get confusing. What will be the default
character set used by iks_new(), iks_insert_cdata() and similar functions? and
how they will allow other charsets to be used. Supporting more than utf8 and
utf16 is more difficult. Hopefully there is no immediate need for this. Jabber
uses only utf8 and you can use iconv if you are using another charset in your
application. Btw, there is also byte order issue which is silly. Inventor of BOM
crap must be killed.
* jabber roster
Roster handling generally depends on the UI system used. But I think a generic
roster handler which parses roster result, pushes, presence changes and
allows application to access and display this data can be useful. Challenge
here is making it UI independent and extensible by the application.
File Layout:
============
......
This diff is collapsed.
......@@ -2,7 +2,11 @@
## Process this file with automake to produce Makefile.in
##
SUBDIRS = include src tools test doc
if DO_PYTHON
python_d = python
endif
SUBDIRS = include src tools $(python_d) test doc
EXTRA_DIST = HACKING iksemel.pc.in
......
V1.4 (2018-02-18)
* Lookuping the codes and start new developing
* Added iks_set_cdata function
* Write a pyiks.c module for using iksemel in python
V1.5 (upcoming release)
* You can now use OpenSSL or GNUTLS as the TLS back-end (compile time option).
* Python bindings. You can use iksemel from Python as an XMPP client library
or as a very fast and memory efficient XML parser.
V1.4 (2009-07-25)
* Some previously rejected valid UTF8 sequences are now accepted.
* Whitespace is allowed between attribute name, equal sign and value.
* Small fixes all around (see ChangeLog).
V1.3 (2007-08-02)
* Project is moved to
......
iksemel 1.4
Copyright (c) 2000-2007 Gurer Ozen <madcat@e-kolay.net>
Copyright (c) 2000-2007 Gurer Ozen
Copyright (c) 2016-2018 Suleyman Poyraz (Zaryob)
Introduction:
-------------
......
This file contains a simple list of TODO items.
More general ideas can be found in the roadmap part of the file HACKING.
(in order of importance)
==> 1.5 release, abi/api compatible, will be released in a few months
* parser: &#1234; and &#xA25F; like entities must be unescaped.
==> 1.6 release abi/api compatible, early 2010
* rewrite sax parser for better performance and correctness
* xml pretty printer
* file stream based xml printer
==> 2.0 release, major abi/api changes
* offer a high level jabber api for managing connection details
* input/output modules for encodings (utf8/16), compression (zlib,bzip2),
and source (file, memory, network stream).
==> ideas
* packet filter or a generic xml filter? something like a simplified xpath?
* a separate utf8 validator function can be useful
* utf8 <-> utf16 conversion functions can be useful
* add python and ruby module files
* add programming support into cpp
anything else? :-)
File mode changed from 100644 to 100755
......@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE(iksemel,1.4)
AM_INIT_AUTOMAKE(iksemel,1.5)
AM_CONFIG_HEADER(include/config.h)
AC_CANONICAL_HOST
......@@ -13,6 +13,7 @@ AC_PROG_INSTALL
AC_CHECK_TOOL(OBJDUMP, objdump, :)
AM_PROG_LIBTOOL
AC_LANG_C
PKG_PROG_PKG_CONFIG
dnl Checks for header files
AC_HEADER_STDC
......@@ -33,10 +34,10 @@ esac
dnl Check for posix io
AC_ARG_ENABLE(default-io,
[ --disable-default-io disable builtin socket transport code ],
defio=$enableval, defio=yes)
AS_HELP_STRING([--disable-default-io],[disable builtin socket transport code]),
defio=$enableval, defio=yes)
if test "$defio" = yes; then
AC_DEFINE(USE_DEFAULT_IO,1,[Define this is you want default transport])
AC_DEFINE(USE_DEFAULT_IO,1,[Define this is you want default transport])
fi
AM_CONDITIONAL(DO_POSIX, test "x$defio" = "xyes")
......@@ -45,8 +46,6 @@ AC_SEARCH_LIBS(recv,socket)
AC_CHECK_FUNCS(getopt_long)
AC_CHECK_FUNCS(getaddrinfo)
dnl AM_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls"))
dnl Check -Wall flag of GCC
if test "x$GCC" = "xyes"; then
if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
......@@ -54,6 +53,84 @@ if test "x$GCC" = "xyes"; then
fi
fi
dnl Options for overriding TLS checks
AC_ARG_WITH([openssl],
AS_HELP_STRING([--without-openssl],[disable checking for openssl]),
[with_openssl=$enableval],
[with_openssl=yes]
)
AC_ARG_WITH([gnutls],
AS_HELP_STRING([--without-gnutls],[disable checking for GNU TLS]),
[with_gnutls=$enableval],
[with_gnutls=yes]
)
dnl Check OpenSSL
if test "x$with_openssl" = "xyes"; then
PKG_CHECK_MODULES([OPENSSL], openssl >= 0.9.8, have_openssl=yes, have_openssl=no)
if test "x$have_openssl" = "xyes"; then
LIBOPENSSL_CFLAGS="$OPENSSL_CFLAGS"
LIBOPENSSL_LIBS="$OPENSSL_LIBS"
AC_SUBST(LIBOPENSSL_CFLAGS)
AC_SUBST(LIBOPENSSL_LIBS)
AC_DEFINE(HAVE_OPENSSL, 1, [whether to use OpenSSL support.])
fi
fi
dnl Check GNU TLS
if test "x$with_gnutls" = "xyes"; then
if test "x$have_openssl" != "xyes"; then
PKG_CHECK_MODULES([GNUTLS], gnutls >= 2.0.0, have_gnutls=yes, have_gnutls=no)
if test "x$have_gnutls" = "xyes"; then
LIBGNUTLS_CFLAGS="$GNUTLS_CFLAGS"
LIBGNUTLS_LIBS="$GNUTLS_LIBS"
AC_SUBST(LIBGNUTLS_CFLAGS)
AC_SUBST(LIBGNUTLS_LIBS)
AC_DEFINE(HAVE_GNUTLS, 1, [whether to use GnuTSL support.])
fi
fi
fi
dnl Option for overriding Python check
AC_ARG_ENABLE([python],
AS_HELP_STRING([--disable-python],[disable checking for Python bindings]),
[with_python=$enableval],
[with_python=yes]
)
dnl a macro to check for ability to create python extensions
dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
dnl function also defines PYTHON_INCLUDES
AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
[AC_REQUIRE([AM_PATH_PYTHON])
AC_MSG_CHECKING(for headers required to compile python extensions)
dnl deduce PYTHON_INCLUDES
py_prefix=`$PYTHON -c "import sys; print(sys.prefix)"`
py_exec_prefix=`$PYTHON -c "import sys; print(sys.exec_prefix)"`
PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
if test "$py_prefix" != "$py_exec_prefix"; then
PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
fi
AC_SUBST(PYTHON_INCLUDES)
dnl check if the headers exist:
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
AC_TRY_CPP([#include <Python.h>],dnl
[AC_MSG_RESULT(found)
$1],dnl
[AC_MSG_RESULT(not found)
$2])
CPPFLAGS="$save_CPPFLAGS"
])
dnl Check Python for binding
if test "x$with_python" = "xyes"; then
with_python=no
AM_PATH_PYTHON([3.2], , [:])
AM_CHECK_PYTHON_HEADERS(with_python=yes,[AC_MSG_ERROR(could not find Python headers)])
fi
AM_CONDITIONAL([DO_PYTHON], [test "x$with_python" = "xyes"])
dnl Generating makefiles
AC_CONFIG_FILES([
Makefile
......@@ -61,6 +138,7 @@ iksemel.pc
src/Makefile
include/Makefile
tools/Makefile
python/Makefile
test/Makefile
doc/Makefile
])
......
##
## Process this file with automake to produce Makefile.in
##
INCLUDES = -I$(top_srcdir)/include $(PYTHON_INCLUDES)
pyexec_LTLIBRARIES = iksemel.la
iksemel_la_LIBADD = $(top_builddir)/src/libiksemel.la
iksemel_la_SOURCES = pyiksemel.c stream.c jid.c document.c node.c exceptions.c
iksemel_la_CFLAGS = $(CFLAGS) -fno-strict-aliasing -Wunused-variable -Wunused-function -Wincompatible-pointer-types
iksemel_la_LDFLAGS = -avoid-version -module -export-symbols-regex initiksemel
#include "exceptions.h"
#include "document.h"
#include "node.h"
/* Document */
static PyTypeObject Document_type = {
PyVarObject_HEAD_INIT(NULL,0)
"iksemel.Node", /* tp_name */
sizeof(Document), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Document_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"XML doc object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0 /* tp_new */
};
/* Iterator */
static PyTypeObject Iter_type = {
PyVarObject_HEAD_INIT(NULL,0)
"iksemel.Iter", /* tp_name */
sizeof(Iter), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"XML iter object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)Iter_iter, /* tp_iter */
(iternextfunc)Iter_next,/* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0 /* tp_new */
};
static void
Document_dealloc(Document *self)
{
if (self->document) iks_delete(self->document);
PyTypeObject* ob_type(PyObject *self);
}
static PyObject *
Iter_iter(Iter *self)
{
Py_INCREF(self);
return (PyObject *)self;
}
static PyObject *
Iter_next(Iter *self)
{
iks *node;
node = self->node;
if (!node) return NULL;
if (self->tags) {
self->node = iks_next_tag(node);
if (self->node && self->tagname) {
while (self->node && (strcmp(self->tagname, iks_name(self->node)) != 0)) {
self->node = iks_next_tag(self->node);
}
}
} else {
self->node = iks_next(node);
}
return new_node(self->doc, node);
}
static PyObject *
new_node(Document *doc, iks *xml)
{
Node *node;
int ref = 1;
if (!xml) return PyErr_NoMemory();
if (!doc) {
doc = PyObject_New(Document, &Document_type);
doc->document = xml;
ref = 0;
}
node = PyObject_New(Node, &Node_type);
node->doc = doc;
if (ref) {
Py_INCREF(doc);
}
node->node = xml;
return (PyObject *)node;
}
static PyObject *
Document_parse(PyObject *self, PyObject *args)
{
char *file;
iks *doc;
int e;
if (!PyArg_ParseTuple(args, "s", &file))
return NULL;
e = iks_load(file, &doc);
switch (e) {
case IKS_OK:
break;
case IKS_NOMEM:
return PyErr_NoMemory();
case IKS_BADXML:
exceptions_parse();
default:
return PyErr_SetFromErrnoWithFilename(PyExc_OSError, file);
}
return new_node(NULL, doc);
}
static PyObject *
Document_parseString(PyObject *self, PyObject *args)
{
iks *doc;
char *str;
int e;
if (!PyArg_ParseTuple(args, "s", &str))
return NULL;
doc = iks_tree(str, 0, &e);
if (!doc) {
if (e == IKS_NOMEM) {
return PyErr_NoMemory();
} else {
exceptions_parse();
return NULL;
}
}
return new_node(NULL, doc);
}
static PyObject *
Document_newDocument(PyObject *self, PyObject *args)
{
iks *doc;
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
doc = iks_new(name);
return new_node(NULL, doc);
}
void
Setup_Document(PyObject *module)
{
Document_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&Document_type) < 0) return;
Py_INCREF(&Document_type);
Iter_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&Iter_type) < 0) return;
Py_INCREF(&Iter_type);
}
#ifndef DOCUMENT_H
#define DOCUMENT_H 1
#include <Python.h>
#include "iksemel.h"
/*** Document ***/
typedef struct {
PyObject_HEAD
iks *document;
} Document;
static PyTypeObject Document_type;
static void Document_dealloc(Document *self);
static PyObject *Document_parse(PyObject *self, PyObject *args);
static PyObject *Document_parseString(PyObject *self, PyObject *args);
static PyObject *Document_newDocument(PyObject *self, PyObject *args);
/*** Iterator ***/
typedef struct {
PyObject_HEAD
Document *doc;
iks *node;
int tags;
char *tagname;
} Iter;
static PyTypeObject Iter_type;
static PyObject *Iter_iter(Iter *self);
static PyObject *Iter_next(Iter *self);
static PyObject *new_node(Document *doc, iks *xml);
/*** Setup ***/
void Setup_Document(PyObject *module);
#endif /* DOCUMENT_H */
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include "exceptions.h"
void
Setup_Exception(PyObject *module)
{
ParseError = PyErr_NewException("iksemel.ParseError", NULL, NULL);
Py_INCREF(ParseError);
PyModule_AddObject(module, "ParseError", ParseError);
NotTag = PyErr_NewException("iksemel.NotTag", NULL, NULL);
Py_INCREF(NotTag);
PyModule_AddObject(module, "NotTag", NotTag);
NotData = PyErr_NewException("iksemel.NotData", NULL, NULL);
Py_INCREF(NotData);
PyModule_AddObject(module, "NotData", NotData);
NotStream = PyErr_NewException("iksemel.NotStream", NULL, NULL);
Py_INCREF(NotStream);
PyModule_AddObject(module, "NotStream", NotStream);
}
// FIXME: provide err, lineno, etc
PyObject *
exceptions_parse(void)
{
PyErr_SetNone(ParseError);
return NULL;
}
// FIXME: more info on error type
PyObject *
exceptions_object_notdata(int e)
{
PyErr_SetNone(NotData);
return NULL;
}
PyObject *
exceptions_object_nottag(int e)
{
PyErr_SetNone(NotTag);
return NULL;
}
PyObject *
exceptions_stream(int e)
{
PyErr_SetNone(NotStream);
return NULL;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H 1
#include <Python.h>
/*** Objects ***/
static PyObject *ParseError;
static PyObject *NotTag;
static PyObject *NotData;
static PyObject *NotStream;
/*** Exceptions ***/
PyObject *exceptions_parse(void);
PyObject *exceptions_stream(int e);
PyObject *exceptions_object(int e);
/*** Setup ***/
void Setup_Exception(PyObject *module);
#endif /* EXCEPTIONS_H */
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include "jid.h"
#include <structmember.h>
// NOTE: This class uses custom implementation of JID parsing
// instead of the iks_id_new from jabber.c
//
static PyMemberDef JID_members[] = {
{ "local", T_OBJECT_EX, offsetof(JID, local), 0, "localpart" },
{ "domain", T_OBJECT_EX, offsetof(JID, domain), 0, "domainpart" },
{ "resource", T_OBJECT_EX, offsetof(JID, resource), 0, "resourcepart" },
{ NULL }
};
static PyTypeObject JID_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"iksemel.JID", /* tp_name */
sizeof(JID), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)JID_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
(reprfunc)JID_str, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"iksemel JID object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
JID_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)JID_init, /* tp_init */
0, /* tp_alloc */
0 /* tp_new */
};
static int
JID_init(JID *self, PyObject *args, PyObject *kwargs)
{
char *str;
char *d;
char *r;
self->local = NULL;
self->domain = NULL;
self->resource = NULL;
if (!PyArg_ParseTuple(args, "s", &str))
return -1;
/* skip scheme */
if (strncmp("jabber:", str, 7) == 0) str += 7;
if (strncmp("xmpp:", str, 5) == 0) str += 5;
d = strchr (str, '@');
r = strchr(str, '/');
if (d) {
self->local = Py_BuildValue("s#", str, d - str);
str = d + 1;
} else {
Py_INCREF(Py_None);
self->local = Py_None;
}
if (r) {
self->resource = Py_BuildValue("s", r + 1);
self->domain = Py_BuildValue("s#", str, r - str);
} else {
Py_INCREF(Py_None);
self->resource = Py_None;
self->domain = Py_BuildValue("s", str);
}
return 0;
}
static PyObject *
JID_str(JID *self)
{
char *local = "";
char *localsep = "";
char *domain;
char *resourcesep = "";
char *resource = "";
if (self->local && self->local != Py_None) {
local = PyBytes_AsString(self->local);
if (!local) return NULL;
localsep = "@";
}
domain = PyBytes_AsString(self->domain);
if (!domain) return NULL;
if (self->resource && self->resource != Py_None) {
resource = PyBytes_AsString(self->resource);
if (!resource) return NULL;
resourcesep = "/";
}
return PyBytes_FromFormat("%s%s%s%s%s", local, localsep, domain, resourcesep, resource);
}
static void
JID_dealloc(JID *self)
{
if (self->local) { Py_DECREF(self->local); }
if (self->domain) { Py_DECREF(self->domain); }
if (self->resource) { Py_DECREF(self->resource); }
PyTypeObject* ob_type(PyObject *self);
}
void
Setup_JID(PyObject *module)
{
JID_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&JID_type) < 0) return;
Py_INCREF(&JID_type);
PyModule_AddObject(module, "JID", (PyObject *) &JID_type);
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#ifndef JID_H
#define JID_H 1
#include <Python.h>
#include "iksemel.h"
typedef struct {
PyObject_HEAD
PyObject *local;
PyObject *domain;
PyObject *resource;
} JID;
static PyTypeObject JID_type;
static int JID_init(JID *self, PyObject *args, PyObject *kwargs);
static int JID_init(JID *self, PyObject *args, PyObject *kwargs);
static PyObject *JID_str(JID *self);
static void JID_dealloc(JID *self);
/*** Setup ***/
void Setup_JID(PyObject *module);
#endif /* JID_H */
This diff is collapsed.
#ifndef NODE_H
#define NODE_H 1
#include <Python.h>
#include "iksemel.h"
/*** Setup ***/
void Setup_Node(PyObject *module);
/*** Types ***/
typedef struct {
PyObject_HEAD
Document *doc;
iks *node;
} Node;
static PyTypeObject Node_type;
#endif /* NODE_H */
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
/*
** Copyright (c) 2016 Suleyman Poyraz
**
** 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 the
** Free Software Foundation; either version 3 of the License, or (at your
** option) any later version. Please read the COPYING file.
*/
#include <Python.h>
#include "iksemel.h"
#include "document.h"
#include "exceptions.h"
#include "node.h"
#include "stream.h"
#include "jid.h"
PyObject *iksemel_module;
/*** Module Functions ***/
static PyMethodDef methods[] = {
{ "parse", Document_parse, METH_VARARGS,
"Parse given XML file and generate document tree."},
{ "parseString", Document_parseString, METH_VARARGS,
"Parse given XML string and generate document tree."},
{ "newDocument", Document_newDocument, METH_VARARGS,
"Create a new document with given root tag name."},
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef iksemelmodule ={
PyModuleDef_HEAD_INIT,
"iksemel",
NULL,
-1,
methods
};
__attribute__((visibility("default")))
PyMODINIT_FUNC
PyInit_iksemel(void)
{
PyObject *m;
m = PyModule_Create(&iksemelmodule);
Setup_Document(m);
Setup_Exception(m);
Setup_Node(m);
Setup_Stream(m);
Setup_JID(m);
iksemel_module = m;
return m;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include "exceptions.h"
#include "document.h"
#include "stream.h"
/*** Stream ***/
static PyMethodDef Stream_methods[] = {
{ "connect", (PyCFunction) Stream_connect, METH_KEYWORDS, "Connect stream to an XMPP server" },
{ "fileno", (PyCFunction) Stream_fileno, METH_NOARGS, "Return file descriptor of the socket" },
{ "send", (PyCFunction) Stream_send, METH_VARARGS, "Send stanzas to server" },
{ "recv", (PyCFunction) Stream_recv, METH_NOARGS, "Read data from server" },
{ NULL }
};
static PyTypeObject Stream_type = {
PyVarObject_HEAD_INIT(NULL,0)
"iksemel.Stream", /* tp_name */
sizeof(Stream), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Stream_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"iksemel stream object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Stream_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Stream_init, /* tp_init */
0, /* tp_alloc */
0 /* tp_new */
};
static void
start_sasl(Stream *self, enum ikssasltype type)
{
PyObject *hook;
PyObject *ret;
PyObject *o;
char *local;
char *pw;
o = PyObject_GetAttrString(self->jid, "local");
if (!o) return;
local = PyBytes_AsString(o);
if (!local) {
Py_DECREF(o);
return;
}
hook = PyObject_GetAttrString((PyObject *) self, "ask_password");
if (!hook) {
Py_DECREF(o);
return;
}
ret = PyObject_CallObject(hook, NULL);
Py_DECREF(hook);
if (!ret) {
Py_DECREF(o);
return;
}
pw = PyBytes_AsString(ret);
if (!pw) {
Py_DECREF(ret);
Py_DECREF(o);
return;
}
iks_start_sasl(self->parser, type, local, pw);
Py_DECREF(ret);
Py_DECREF(o);
}
static void
make_bind(Stream *self)
{
iks *x, *y, *z;
PyObject *o;
char *resource;
o = PyObject_GetAttrString(self->jid, "resource");
if (!o) return;
resource = PyBytes_AsString(o);
if (!resource) {
PyErr_Clear();
resource = "iksemel";
}
x = iks_new("iq");
iks_insert_attrib(x, "type", "set");
y = iks_insert(x, "bind");
iks_insert_attrib(y, "xmlns", IKS_NS_XMPP_BIND);
z = iks_insert(y, "resource");
iks_insert_cdata(z, resource, 0);
iks_send(self->parser, x);
iks_delete(x);
Py_DECREF(o);
}
static void
on_features(Stream *self, iks *node)
{
iks *x;
self->features = iks_stream_features(node);
if (self->use_sasl) {
if (self->use_tls && !iks_is_secure(self->parser)) return;
if (self->authorized) {
if (self->features & IKS_STREAM_BIND) {
make_bind(self);
}
if (self->features & IKS_STREAM_SESSION) {
x = iks_make_session();
iks_insert_attrib(x, "id", "auth");
iks_send(self->parser, x);
iks_delete(x);
}
} else {
if (self->features & IKS_STREAM_SASL_MD5)
start_sasl(self, IKS_SASL_DIGEST_MD5);
else if (self->features & IKS_STREAM_SASL_PLAIN)
start_sasl(self, IKS_SASL_PLAIN);
}
}
}
static void
on_success(Stream *self, iks *node)
{
PyObject *o;
char *domain;
o = PyObject_GetAttrString(self->jid, "domain");
if (!o) return;
domain = PyBytes_AsString(o);
if (!domain) {
Py_DECREF(o);
return;
}
self->authorized = 1;
iks_send_header(self->parser, domain);
Py_DECREF(o);
}
static int
on_stream(Stream *self, int type, iks *node)
{
PyObject *hook;
PyObject *doc;
PyObject *ret;
// iks *x;
switch (type) {
case IKS_NODE_NORMAL:
if (strcmp("stream:features", iks_name(node)) == 0) {
on_features(self, node);
} else if (strcmp("success", iks_name(node)) == 0) {
on_success(self, node);
}
#if 0
case IKS_NODE_START:
if (!iks_is_secure(self->parser)) {
iks_start_tls(self->parser);
break;
}
if (!self->use_sasl) {
x = iks_make_auth (, , NULL);
iks_insert_attrib (x, "id", "auth");
iks_send (self->parser, x);
iks_delete (x);
}
break;
#endif
hook = PyObject_GetAttrString((PyObject *) self, "on_stanza");
if (hook) {
doc = Document_parseString(NULL, node);
if (!doc) {
Py_DECREF(hook);
return IKS_NOMEM;
}
ret = PyObject_CallFunctionObjArgs(hook, doc, NULL);
Py_DECREF(hook);
// FIXME: handle error
if (ret == NULL) {
Py_DECREF(ret);
return IKS_HOOK;
}
}
}
if (node) iks_delete (node);
return IKS_OK;
}
void
on_log(Stream *self, const char *data, size_t size, int is_incoming)
{
PyObject *hook;
PyObject *args;
PyObject *ret;
PyObject *b;
hook = PyObject_GetAttrString((PyObject *) self, "on_xml");
if (hook) {
b = Py_False;
if (is_incoming) b = Py_True;
args = Py_BuildValue("s#O", data, size, b);
if (args) {
ret = PyObject_CallObject(hook, args);
if (ret) { Py_DECREF(ret); }
Py_DECREF(args);
}
Py_DECREF(hook);
}
}
static int
Stream_init(Stream *self, PyObject *args, PyObject *kwargs)
{
PyObject *hook;
self->jid = NULL;
self->parser = iks_stream_new (
IKS_NS_CLIENT,
self,
(iksStreamHook *) on_stream
);
self->features = 0;
self->authorized = 0;
self->use_sasl = 1;
self->use_tls = 1;
hook = PyObject_GetAttrString((PyObject *) self, "on_xml");
if (hook) {
iks_set_log_hook(self->parser, (iksLogHook *) on_log);
Py_DECREF(hook);
}
return 0;
}
static PyObject *
Stream_connect(Stream *self, PyObject *args, PyObject *kwargs)
{
PyObject *o;
char *host;
int e;
o = PyMapping_GetItemString(kwargs, "tls");
if (o) {
if (PyObject_IsTrue(o)) {
self->use_tls = 1;
} else {
self->use_tls = 0;
}
}
PyErr_Clear();
o = PyMapping_GetItemString(kwargs, "sasl");
if (o) {
if (PyObject_IsTrue(o)) {
self->use_sasl = 1;
} else {
self->use_sasl = 0;
}
}
PyErr_Clear();
o = PyMapping_GetItemString(kwargs, "jid");
if (!o) {
PyErr_SetString(PyExc_TypeError, "jid keyword argument is required");
return NULL;
}
Py_INCREF(o);
self->jid = o;
o = PyObject_GetAttrString(self->jid, "domain");
if (!o) return NULL;
host = PyBytes_AsString(o);
if (!host) {
Py_DECREF(o);
return NULL;
}
e = iks_connect_tcp(self->parser, host, IKS_JABBER_PORT);
if (e) {
return exceptions_stream(e);
}
Py_DECREF(o);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
Stream_fileno(Stream *self)
{
return Py_BuildValue("i", iks_fd(self->parser));
}
static PyObject *
Stream_send(Stream *self, PyObject *args)
{
int e;
PyObject *s;
char *str;
if (!PyArg_ParseTuple(args, "O", &s))
return NULL;
s = PyObject_Str(s);
if (s) {
str = PyBytes_AsString(s);
if (str) {
e = iks_send_raw(self->parser, str);
if (e) {
Py_DECREF(s);
return exceptions_stream(e);
}
}
Py_DECREF(s);
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
Stream_recv(Stream *self)
{
int e;
e = iks_recv(self->parser, 0);
if (e) {
return exceptions_stream(e);
}
Py_INCREF(Py_None);
return Py_None;
}
static void
Stream_dealloc(Stream *self)
{
if (self->jid) { Py_DECREF(self->jid); }
iks_parser_delete(self->parser);
PyTypeObject* ob_type(PyObject *self);
}
void
Setup_Stream(PyObject *module)
{
Stream_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&Stream_type) < 0) return;
Py_INCREF(&Stream_type);
PyModule_AddObject(module, "Stream", (PyObject *) &Stream_type);
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2011 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#ifndef STREAM_H
#define STREAM_H 1
#include <Python.h>
#include "iksemel.h"
/*** Types ***/
typedef struct {
PyObject_HEAD
PyObject *jid;
iksparser *parser;
int features;
int authorized;
int use_sasl;
int use_tls;
} Stream;
static PyTypeObject Stream_type;
static PyObject *Stream_connect(Stream *self, PyObject *args, PyObject *kwargs);
static PyObject *Stream_fileno(Stream *self);
static PyObject *Stream_send(Stream *self, PyObject *args);
static PyObject *Stream_recv(Stream *self);
static void Stream_dealloc(Stream *self);
static int Stream_init(Stream *self, PyObject *args, PyObject *kwargs);
/*** Setup ***/
void Setup_Stream(PyObject *module);
#endif /* STREAM_H */
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2003 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "iksemel.h"
iks *my_x;
int nr_tests;
#define PR_TEST printf ("DOM test %d:\n", nr_tests)
void
document (char *xml)
{
enum ikserror err;
iksparser *p;
nr_tests++;
if (my_x) iks_delete (my_x);
p = iks_dom_new (&my_x);
err = iks_parse (p, xml, 0, 1);
switch (err) {
case IKS_OK:
break;
case IKS_NOMEM:
PR_TEST;
puts ("Not enough memory.");
exit (1);
case IKS_BADXML:
PR_TEST;
printf ("Invalid xml at byte %ld in\n[%s]\n", iks_nr_bytes (p), xml);
exit (1);
case IKS_HOOK:
PR_TEST;
puts ("Hook.");
}
iks_parser_delete (p);
}
void
tag (char *name, ...)
{
iks *x;
va_list ap;
x = my_x;
va_start (ap, name);
while (1) {
char *name = iks_name (x);
char *tmp = va_arg (ap, char*);
if (NULL == tmp) break;
x = iks_find (x, tmp);
if (!x) {
PR_TEST;
printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
exit (1);
}
}
if (!x || NULL == iks_find (x, name)) {
PR_TEST;
printf ("Tag <%s> is not a child of tag <%s>\n", name, iks_name (x));
exit (1);
}
va_end (ap);
}
void
cdata (char *data, ...)
{
iks *x;
va_list ap;
x = my_x;
va_start (ap, data);
while (1) {
char *name = iks_name (x);
char *tmp = va_arg (ap, char*);
if (NULL == tmp) break;
x = iks_find (x, tmp);
if (!x) {
PR_TEST;
printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
exit (1);
}
}
if (iks_strcmp ( iks_cdata (iks_child (x)), data) != 0) {
PR_TEST;
printf ("CDATA [%s] not found.\n", data);
exit (1);
}
va_end (ap);
}
void
attrib (char *att, char *val, ...)
{
iks *x;
va_list ap;
x = my_x;
va_start (ap, val);
while (1) {
char *name = iks_name (x);
char *tmp = va_arg (ap, char*);
if (NULL == tmp) break;
x = iks_find (x, tmp);
if (!x) {
PR_TEST;
printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
exit (1);
}
}
if (iks_strcmp (val, iks_find_attrib (x, att)) != 0) {
PR_TEST;
printf ("Attribute '%s' not found.\n", att);
exit (1);
}
va_end (ap);
}
void
string (char *xml)
{
char *tmp;
tmp = iks_string (iks_stack (my_x), my_x);
if (iks_strcmp (tmp, xml) != 0) {
PR_TEST;
printf ("Result: %s\n", tmp);
printf ("Expected: %s\n", xml);
exit (1);
}
}
static char buf[] =
"<presence id='JCOM_11' to='lala@j.org' type='available'><status>"
"&quot; &lt;online&amp;dangerous&gt; &quot;</status>meow<a><b c='d'/>"
"</a><test/></presence>";
int main (int argc, char *argv[])
{
document ("<atag></atag>");
string ("<atag/>");
document ("<test>lala<b>bold</b>blablabla<a><c/></a></test>");
tag ("b", 0);
tag ("c", "a", 0);
string ("<test>lala<b>bold</b>blablabla<a><c/></a></test>");
document (buf);
cdata ("\" <online&dangerous> \"", "status", 0);
attrib ("c", "d", "a", "b", 0);
tag ("test", 0);
string (buf);
return 0;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2003 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <assert.h>
#include "iksemel.h"
struct {
iksfilter *f;
char *xml;
int nr;
iksFilterHook *hook[20];
int nr_hook;
iksFilterHook *call[20];
int nr_call;
} tester;
void
document (char *xml)
{
tester.nr++;
tester.xml = xml;
tester.nr_hook = 0;
}
void
hook (iksFilterHook *hk)
{
tester.hook[tester.nr_hook++] = hk;
}
void
debug (void)
{
int i;
printf ("Filter test %d:\n", tester.nr);
if (tester.nr_hook) {
puts ("Expected hook order:");
for (i = 0; i < tester.nr_hook; i++) {
printf (" ");
tester.hook[i] (NULL, NULL);
}
} else {
puts("No hooks expected.");
}
if (tester.nr_call) {
puts ("Hook order:");
for (i = 0; i < tester.nr_call; i++) {
printf (" ");
tester.call[i] (NULL, NULL);
}
} else {
puts("No hooks called.");
}
exit (1);
}
void
test (void)
{
iksparser *prs;
iks *x;
int i;
tester.nr_call = 0;
prs = iks_dom_new (&x);
iks_parse (prs, tester.xml, strlen (tester.xml), 1);
iks_parser_delete (prs);
iks_filter_packet (tester.f, iks_packet (x));
iks_delete (x);
if (tester.nr_call != tester.nr_hook) debug ();
for (i = 0; i < tester.nr_hook; i++) {
if (tester.call[i] != tester.hook[i]) debug ();
}
}
#define DEBUG(x) if (NULL == pak) { puts ( (x) ); return IKS_FILTER_PASS; }
int
on_msg (void *user_data, ikspak *pak)
{
DEBUG ("on_msg");
assert (IKS_PAK_MESSAGE == pak->type);
tester.call[tester.nr_call++] = on_msg;
return IKS_FILTER_PASS;
}
int
on_iq (void *user_data, ikspak *pak)
{
DEBUG ("on_iq");
assert (IKS_PAK_IQ == pak->type);
tester.call[tester.nr_call++] = on_iq;
return IKS_FILTER_PASS;
}
int
on_iq_result (void *user_data, ikspak *pak)
{
DEBUG ("on_iq_result");
assert (IKS_PAK_IQ == pak->type);
assert (IKS_TYPE_RESULT == pak->subtype);
tester.call[tester.nr_call++] = on_iq_result;
return IKS_FILTER_PASS;
}
int
on_iq_result_id_auth (void *user_data, ikspak *pak)
{
DEBUG ("on_iq_result_id_auth");
assert (IKS_PAK_IQ == pak->type);
assert (IKS_TYPE_RESULT == pak->subtype);
assert (iks_strcmp (pak->id, "auth") == 0);
tester.call[tester.nr_call++] = on_iq_result_id_auth;
return IKS_FILTER_PASS;
}
int
on_id_auth (void *user_data, ikspak *pak)
{
DEBUG ("on_id_auth");
assert (iks_strcmp (pak->id, "auth") == 0);
tester.call[tester.nr_call++] = on_id_auth;
return IKS_FILTER_PASS;
}
int
on_from_patrician (void *user_data, ikspak *pak)
{
DEBUG ("on_from_patrician");
assert (iks_strcmp (pak->from->partial, "patrician@morpork.gov") == 0);
tester.call[tester.nr_call++] = on_from_patrician;
return IKS_FILTER_PASS;
}
int
on_msg_chat_from_patrician (void *user_data, ikspak *pak)
{
DEBUG ("on_msg_chat_from_patrician");
assert (pak->type == IKS_PAK_MESSAGE);
assert (pak->subtype == IKS_TYPE_CHAT);
assert (iks_strcmp (pak->from->partial, "patrician@morpork.gov") == 0);
tester.call[tester.nr_call++] = on_msg_chat_from_patrician;
return IKS_FILTER_PASS;
}
int
on_id_albatros (void *user_data, ikspak *pak)
{
DEBUG ("on_id_albatros");
assert (iks_strcmp (pak->id, "albatros") == 0);
tester.call[tester.nr_call++] = on_id_albatros;
return IKS_FILTER_PASS;
}
int
on_from_dean (void *user_data, ikspak *pak)
{
DEBUG ("on_from_dean");
assert (iks_strcmp (pak->from->partial, "dean@unseen.edu") == 0);
tester.call[tester.nr_call++] = on_from_dean;
return IKS_FILTER_PASS;
}
int
main (int argc, char *argv[])
{
tester.f = iks_filter_new ();
iks_filter_add_rule (tester.f, on_msg, 0,
IKS_RULE_TYPE, IKS_PAK_MESSAGE,
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_iq, 0,
IKS_RULE_TYPE, IKS_PAK_IQ,
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_iq_result, 0,
IKS_RULE_TYPE, IKS_PAK_IQ,
IKS_RULE_SUBTYPE, IKS_TYPE_RESULT,
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_iq_result_id_auth, 0,
IKS_RULE_TYPE, IKS_PAK_IQ,
IKS_RULE_SUBTYPE, IKS_TYPE_RESULT,
IKS_RULE_ID, "auth",
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_id_auth, 0,
IKS_RULE_ID, "auth",
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_from_dean, 0,
IKS_RULE_FROM_PARTIAL, "dean@unseen.edu",
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_from_patrician, 0,
IKS_RULE_FROM_PARTIAL, "patrician@morpork.gov",
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_msg_chat_from_patrician, 0,
IKS_RULE_TYPE, IKS_PAK_MESSAGE,
IKS_RULE_SUBTYPE, IKS_TYPE_CHAT,
IKS_RULE_FROM_PARTIAL, "patrician@morpork.gov",
IKS_RULE_DONE);
iks_filter_add_rule (tester.f, on_id_albatros, 0,
IKS_RULE_ID, "albatros",
IKS_RULE_DONE);
document ("<message from='dean@unseen.edu' id='1234'><body>Born to Rune.</body></message>");
hook (on_from_dean);
hook (on_msg);
test ();
document ("<presence from='librarian@unseen.edu' show='away'/>");
test ();
document ("<message from='rincewind@unseen.edu' type='chat' id='albatros'><body>yaaargh</body></message>");
hook (on_id_albatros);
hook (on_msg);
test ();
document ("<iq type='get' from='rincewind@unseen.edu'><query xmlns='jabber:time'/></iq>");
hook (on_iq);
test ();
document ("<message from='patrician@morpork.gov'><body>so you admit it?</body></message>");
hook (on_from_patrician);
hook (on_msg);
test ();
document ("<iq type='result' from='rincewind@unseen.edu'><query xmlns='jabber:version'><name>cabbar</name><version>1.0</version></query></iq>");
hook (on_iq_result);
hook (on_iq);
test ();
document ("<presence from='dean@unseen.edu/psi' type='unavailable'/>");
hook (on_from_dean);
test ();
document ("<message from='patrician@morpork.gov' type='chat' id='albatros'><body>hmm</body></message>");
hook (on_id_albatros);
hook (on_msg_chat_from_patrician);
hook (on_from_patrician);
hook (on_msg);
test ();
document ("<iq type='result' id='auth'/>");
hook (on_iq_result_id_auth);
hook (on_id_auth);
hook (on_iq_result);
hook (on_iq);
test ();
iks_filter_delete (tester.f);
return 0;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2003 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "iksemel.h"
int main (int argc, char *argv[])
{
static char xml[] =
"<iq type='result' to='ydobon@jabber.org'><query xmlns='jabber:iq:version'>"
"<name>TestClient</name><os>SuxOS 2000</os><version><stable solidity='rock'/>"
"1.2.0 patchlevel 2</version></query></iq>";
static char xml2[] =
"<Ni><C/>lala<br/><A/>Hello World<B/></Ni>";
iks *x, *y, *z;
char *t;
setlocale (LC_ALL, "");
x = iks_new ("iq");
iks_insert_attrib (x, "type", "resultypo");
iks_insert_attrib (x, "type", "result");
iks_insert_attrib (x, "to", "ydobon@jabber.org");
y = iks_new_within ("query", iks_stack (x));
iks_insert_cdata (iks_insert (y, "name"), "TestClient", 10);
iks_insert_cdata (iks_insert (y, "os"), "SuxOS", 0);
z = iks_insert (y, "version");
iks_insert (z, "stable");
iks_insert_cdata (z, "1.2", 3);
iks_insert_cdata (z, ".0 patchlevel 2", 0);
iks_insert_node (x, y);
z = iks_find (y, "os");
iks_insert_attrib (z, "error", "yes");
iks_insert_attrib (z, "error", NULL);
iks_insert_cdata (z, " 2000", 5);
z = iks_next (z);
z = iks_find (z, "stable");
iks_insert_attrib (z, "solidity", "rock");
z = iks_parent (iks_parent (z));
iks_insert_attrib (z, "xmlns", "jabber:iq:version");
t = iks_string (iks_stack (x), x);
if(!t || strcmp(t, xml) != 0) {
printf("Result: %s\n", t);
printf("Expected: %s\n", xml);
return 1;
}
iks_delete(x);
x = iks_new ("Ni");
y = iks_insert (x, "br");
z = iks_prepend_cdata (y, "lala", 4);
iks_prepend (z, "C");
z = iks_insert_cdata (x, "Hello", 5);
y = iks_append (z, "B");
iks_prepend (z, "A");
iks_append_cdata (z, " ", 1);
iks_prepend_cdata (y, "World", 5);
t = iks_string (iks_stack (x), x);
if(!t || strcmp(t, xml2) != 0) {
printf("Result: %s\n", t);
printf("Expected: %s\n", xml2);
return 1;
}
iks_delete(x);
return 0;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2004 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iksemel.h"
struct align_test { char a; double b; };
#define DEFAULT_ALIGNMENT ((size_t) ((char *) &((struct align_test *) 0)->b - (char *) 0))
#define ALIGN_MASK ( DEFAULT_ALIGNMENT - 1 )
const char buf[] = "1234567890abcdefghijklmnopqrstuv";
void
test_stack (int cs)
{
ikstack *s;
char *mem, *old;
int i;
s = iks_stack_new (cs, cs);
old = NULL;
for (i = 0; i < strlen (buf); i++) {
iks_stack_strdup (s, buf, i);
mem = iks_stack_alloc (s, i);
if (((unsigned long) mem) & ALIGN_MASK) {
printf ("ikstack bug, addr %p should be a multiply of %d\n",
mem, DEFAULT_ALIGNMENT);
exit (1);
}
memset (mem, 'x', i);
old = iks_stack_strcat (s, old, 0, buf + i, 1);
}
if (strcmp (old, buf) != 0) {
printf ("ikstack strcat bug:\nExpected: %s\n Result: %s\n", buf, old);
exit (1);
}
iks_stack_delete (s);
}
int main (int argc, char *argv[])
{
test_stack (0);
test_stack (16);
test_stack (237);
test_stack (1024);
return 0;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2003 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "iksemel.h"
ikstack *my_stack;
void
print_id (iksid *id)
{
printf (" Full: [%s]\n Partial: [%s]\n User: [%s]\n Server: [%s]\n Resource: [%s]\n",
id->full, id->partial, id->user, id->server, id->resource);
}
#define BUG(x) { print_id ( (x) ); exit (1); }
void
test_id (char *id, char *partial, char *user, char *server, char *resource)
{
iksid *a;
a = iks_id_new (my_stack, id);
if ((a->partial || partial) && iks_strcmp (a->partial, partial) != 0) BUG(a);
if ((a->user || user) && iks_strcmp (a->user, user) != 0) BUG(a);
if ((a->server || server) && iks_strcmp (a->server, server) != 0) BUG(a);
if ((a->resource || resource) && iks_strcmp (a->resource, resource) != 0) BUG(a);
}
void
test_cmp (char *stra, char *strb, int parts, int diff)
{
iksid *a, *b;
a = iks_id_new (my_stack, stra);
b = iks_id_new (my_stack, strb);
if (diff != iks_id_cmp (a, b, parts)) exit (1);
}
int main (int argc, char *argv[])
{
my_stack = iks_stack_new (1024, 1024);
test_id ("jabber:madcat@jabber.org/cabbar", "madcat@jabber.org", "madcat", "jabber.org", "cabbar");
test_id ("bob@silent.org", "bob@silent.org", "bob", "silent.org", NULL);
test_cmp ("dante@jabber.org/hell", "dante@jabber.org/heaven", IKS_ID_PARTIAL, 0);
test_cmp ("madcat@jabber.org/cabbar", "madcat@jabber.org/jabberx", IKS_ID_FULL, IKS_ID_RESOURCE);
test_cmp ("dean@unseen.edu/pda", "librarian@unseen.edu/jabberx", IKS_ID_FULL, IKS_ID_USER | IKS_ID_RESOURCE);
test_cmp ("patrician@morpork.gov/gabber", "cohen@guild.org/gsm", IKS_ID_FULL, IKS_ID_FULL);
test_cmp ("peter@family.com", "peter@family.com/clam", IKS_ID_PARTIAL, 0);
iks_stack_delete (my_stack);
return 0;
}
/* iksemel (XML parser for Jabber)
** Copyright (C) 2004 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iksemel.h"
int main (int argc, char *argv[])
{
struct lala {
char *str;
char *hash;
} known_hashes[] = {
// Taken from http://tools.ietf.org/html/rfc1321
{ "", "d41d8cd98f00b204e9800998ecf8427e" },
{ "a", "0cc175b9c0f1b6a831c399e269772661" },
{ "abc", "900150983cd24fb0d6963f7d28e17f72" },
{ "message digest", "f96b697d7cb7938d525a2f31aaf161d0" },
{ "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a" },
// Reported bug for 64 byte (or any multiples) sized inputs
{ "0123456789012345678901234567890123456789012345678901234567890123",
"7f7bfd348709deeaace19e3f535f8c54" },
// More checks around the block size for testing the padding
{ "012345678901234567890123456789012345678901234567890123456789012",
"c5e256437e758092dbfe06283e489019"
},
{ "01234567890123456789012345678901234567890123456789012345678901",
"10f0b5ba92a04c7502dec778490a9acb"
},
{ "01234567890123456789012345678901234567890123456789012345678901234",
"beb9f48bc802ca5ca043bcc15e219a5a"
},
{ NULL, NULL }
};
int i = 0;
char buf[33];
while (known_hashes[i].str) {
iks_md5 (known_hashes[i].str, buf);
if (strcmp (buf, known_hashes[i].hash) != 0) {
printf("MD5 hash of \"%s\"\n", known_hashes[i].str);
printf(" Result: %s\n", buf);
printf(" Expected: %s\n", known_hashes[i].hash);
return 1;
}
i++;
}
return 0;
}
This diff is collapsed.
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2003 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iksemel.h"
int main (int argc, char *argv[])
{
struct lala {
char *str;
char *hash;
} known_hashes[] = {
{ "abc", "a9993e364706816aba3e25717850c26c9cd0d89d" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
{ NULL, NULL }
};
int i = 0;
char buf[42];
while (known_hashes[i].str) {
iks_sha (known_hashes[i].str, buf);
if (strcmp (buf, known_hashes[i].hash) != 0) {
printf("SHA1 hash of \"%s\"\n", known_hashes[i].str);
printf(" Result: %s\n", buf);
printf(" Expected: %s\n", known_hashes[i].hash);
return 1;
}
i++;
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment