diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-06-23 14:32:07 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-06-23 14:32:07 +0000 |
| commit | ec576062be919237064a454f812ac1bfad12debc (patch) | |
| tree | 45d34bdffa67525c823d1d6ea2237d6d2da571c6 /src/pedro | |
| parent | Fix aliasing warnings in glib-list-iterators.h by adding G_GNUC_MAY_ALIAS (diff) | |
| download | inkscape-ec576062be919237064a454f812ac1bfad12debc.tar.gz inkscape-ec576062be919237064a454f812ac1bfad12debc.zip | |
Completely remove Inkboard
(bzr r10346)
Diffstat (limited to 'src/pedro')
37 files changed, 0 insertions, 14085 deletions
diff --git a/src/pedro/CMakeLists.txt b/src/pedro/CMakeLists.txt deleted file mode 100644 index c51090067..000000000 --- a/src/pedro/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -set(pedro_SRC - #empty.cpp - #geckoembed.cpp - pedroconfig.cpp - pedrodom.cpp - #pedrogui.cpp - #pedromain.cpp - pedroutil.cpp - pedroxmpp.cpp -) - -# add_inkscape_lib(pedro_LIB "${pedro_SRC}") -add_inkscape_source("${pedro_SRC}") diff --git a/src/pedro/Makefile.mingw b/src/pedro/Makefile.mingw deleted file mode 100644 index 81c3d6ef6..000000000 --- a/src/pedro/Makefile.mingw +++ /dev/null @@ -1,199 +0,0 @@ -########################################################################### -# -# -# Makefile for the Pedro mini-XMPP client -# -# Authors: -# Bob Jamison -# -# Copyright (C) 2005-2007 Bob Jamison -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# -########################################################################## -# FILE SEPARATORS -# $(S) will be set to one of these -########################################################################## -BSLASH := \\# -FSLASH := / - -########################################################################## -# SENSE ARCHITECTURE -########################################################################## -ifdef ComSpec -ARCH=win32 -else -ARCH=xlib -endif - -########################################################################## -# WIN32 SETTINGS -########################################################################## -ifeq ($(ARCH),win32) - -####### Where is your GTK directory? -GTK=c:/gtk210 - -####### Same thing, DOS style -GTKDOS=c:\gtk210 - -#SSL=openssl-0.9.8a -SSL=$(GTK) - - - -CFLAGS = -g -Wall -DHAVE_SSL \ --DRELAYTOOL_SSL="static const int libssl_is_present=1; static int __attribute__((unused)) libssl_symbol_is_present(char *s){ return 1; }" - -INC = -I. -I$(GTK)/include -I$(SSL)/include - - -LIBSC = -mconsole -L$(GTK)/lib -L$(SSL) -lssl -lcrypto -lgdi32 -lws2_32 -LIBS = -mwindows -L$(GTK)/lib -L$(SSL) -lssl -lcrypto -lgdi32 -lws2_32 - -RM = del -CP = copy -S = $(BSLASH) - - -all: test.exe pedro.exe - -GTKINC = -DGLIBMM_DLL \ --I$(GTK)/include/glibmm-2.4 -I$(GTK)/lib/glibmm-2.4/include \ --I$(GTK)/include/gtkmm-2.4 -I$(GTK)/lib/gtkmm-2.4/include \ --I$(GTK)/include/gdkmm-2.4 -I$(GTK)/lib/gdkmm-2.4/include \ --I$(GTK)/include/pangomm-1.4 -I$(GTK)/include/pangomm-1.4 \ --I$(GTK)/include/atkmm-1.6 -I$(GTK)/include/cairomm-1.0 \ --I$(GTK)/include/sigc++-2.0 -I$(GTK)/lib/sigc++-2.0/include \ --I$(GTK)/include/gtk-2.0 -I$(GTK)/lib/gtk-2.0/include \ --I$(GTK)/include/atk-1.0 -I$(GTK)/include/pango-1.0 \ --I$(GTK)/include/glib-2.0 -I$(GTK)/lib/glib-2.0/include \ --I$(GTK)/include/cairo - -####### Our Gtk libs -GTKLIBS = -L$(GTK)/lib \ --lgtkmm-2.4 -lgdkmm-2.4 -lglibmm-2.4 \ --latkmm-1.6 -lpangomm-1.4 -lsigc-2.0 \ --lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 \ --lgdk_pixbuf-2.0 -lm -lpangoft2-1.0 -lpangowin32-1.0 -lpango-1.0 \ --lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 - -endif - - -########################################################################## -# XLIB SETTINGS -########################################################################## -ifeq ($(ARCH),xlib) - -CFLAGS = -g -Wall -DHAVE_SSL -DHAVE_PTHREAD_H -XINC = -I/usr/X11R6/include -XLIB = -L/usr/X11R6/lib -lXrender -lX11 -INC = -I. -I.. $(XINC) -LIBS = $(XLIB) -lpthread -lssl -RM = rm -rf -CP = cp -S = $(FSLASH) -all: test pedro - -GTKINC += `pkg-config gtkmm-2.4 --cflags` -GTKLIBS += `pkg-config gtkmm-2.4 --libs` - -endif - - - -OBJ = \ -pedrodom.o \ -pedroxmpp.o \ -pedroconfig.o \ -pedroutil.o - - -GUIOBJ = \ -pedrogui.o \ -geckoembed.o \ -pedromain.o - - -TESTOBJ = \ -work/test.o \ -work/filesend.o \ -work/filerec.o \ -work/groupchat.o - -test.exe: libpedro.a work/test.o - $(CXX) -o $@ work/test.o libpedro.a $(LIBSC) -test: libpedro.a work/test.o - $(CXX) -o $@ work/test.o libpedro.a $(LIBSC) - -filesend.exe: libpedro.a work/filesend.o - $(CXX) -o $@ work/filesend.o libpedro.a $(LIBSC) -filesend: libpedro.a work/filesend.o - $(CXX) -o $@ work/filesend.o libpedro.a $(LIBSC) - -filerec.exe: libpedro.a work/filerec.o - $(CXX) -o $@ work/filerec.o libpedro.a $(LIBSC) -filerec: libpedro.a work/filerec.o - $(CXX) -o $@ work/filerec.o libpedro.a $(LIBSC) - -groupchat.exe: libpedro.a work/groupchat.o - $(CXX) -o $@ work/groupchat.o libpedro.a $(LIBSC) -groupchat: libpedro.a work/groupchat.o - $(CXX) -o $@ work/groupchat.o libpedro.a $(LIBSC) - -pedro.exe: libpedro.a $(GUIOBJ) - $(CXX) -o $@ pedromain.o pedrogui.o libpedro.a $(GTKLIBS) $(LIBS) -pedro: libpedro.a pedromain.o pedrogui.o - $(CXX) -o $@ pedromain.o pedrogui.o libpedro.a $(GTKLIBS) $(LIBS) - - -libpedro.a: $(OBJ) - ar crv libpedro.a $(OBJ) - -pedromain.o: pedromain.cpp - $(CXX) $(CFLAGS) $(INC) $(GTKINC) -c -o $@ $< - -pedrogui.o: pedrogui.cpp pedrogui.h - $(CXX) $(CFLAGS) $(INC) $(GTKINC) -c -o $@ $< - -geckoembed.o: geckoembed.cpp geckoembed.h - $(CXX) $(CFLAGS) $(INC) $(GTKINC) -c -o $@ $< - -.cpp.o: - $(CXX) $(CFLAGS) $(INC) -c -o $@ $< - -clean: - $(foreach a, $(OBJ), $(shell $(RM) $(subst /,$(S), $(a)))) - $(foreach a, $(GUIOBJ), $(shell $(RM) $(subst /,$(S), $(a)))) - $(foreach a, $(TESTOBJ), $(shell $(RM) $(subst /,$(S), $(a)))) - -$(RM) *.a - -$(RM) test - -$(RM) test.exe - -$(RM) filesend - -$(RM) filesend.exe - -$(RM) filerec - -$(RM) filerec.exe - -$(RM) groupchat - -$(RM) groupchat.exe - -$(RM) pedro - -$(RM) pedro.exe - -$(RM) core.* - -########################################################################### -# E N D O F F I L E -########################################################################### - diff --git a/src/pedro/Makefile_insert b/src/pedro/Makefile_insert deleted file mode 100644 index bc9d32fdb..000000000 --- a/src/pedro/Makefile_insert +++ /dev/null @@ -1,26 +0,0 @@ -## Makefile.am fragment sourced by src/Makefile.am. -# -# Pedro mini-XMPP client, used for Inkboard's Jabber functionality -# Author: Bob Jamison - -pedro/all: pedro/libpedro.a -pedro/clean: - rm -f pedro/libpedro.a $(pedro_libpedro_a_OBJECTS) - -pedro_SOURCES= \ - pedro/pedroconfig.cpp \ - pedro/pedroconfig.h \ - pedro/pedrodom.cpp \ - pedro/pedrodom.h \ - pedro/pedroutil.cpp \ - pedro/pedroutil.h \ - pedro/pedroxmpp.cpp \ - pedro/pedroxmpp.h - -if WITH_INKBOARD -temp_pedro_files = $(pedro_SOURCES) -endif - -pedro_libpedro_a_SOURCES = \ - pedro/empty.cpp \ - $(temp_pedro_files) diff --git a/src/pedro/certs/client.pem b/src/pedro/certs/client.pem deleted file mode 100644 index 06f2e6ce0..000000000 --- a/src/pedro/certs/client.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,6D3B09E4CA5421FF - -SaDJA2MhJ12ZmDxfGkSLhQgjYPEQYqVfs5b4DZTz+9pJqzuNxHrZZU43oArbWBdB -3DKc1THejbyHF2lY7xgPLk/5iax5r+CXesDKZroSliHyERBIOCUgDN6ecwvVGtYv -C8IhlwGPEXyxr59lyV37RjkSUVXYBqiRbLlNIcQtp5T6GkFe+yftOnv6/UADCLTS -Pu8xwkda1rf7dgPwYIKuk2SOTTe1VMDtWacRUGu8NteTJ4aiVaeeo9wdsKId5U2b -Z7NTJjOjvdXOLRonfkGvDXmrmN4eICks0bV0ZBtkULAfGjKNGs6riY+XNGKNRmjI -idRRB0za+EGorpiJ/vbe7n7uaFXIJlfqCwhTi4Up3mS8sR4tLHfmdjp85GV9P9B3 -xX3CHIeG5/EYDt0Qn1gRL5ODL/0O7nFGJslhcQUS6bMmcg9nSzhClTE2gREz0j9g -pwzvRpEkIl3Tw4niZLIX8fW2cEIyKTBMCCG2MDwHHgXRL3SUXkOGeitFefkcXN/z -/UWRS8XQcX7/lGWCiuEpgn+esoirjf8lFNVsx6OT0UXj3oBxGrz1iB/vpu/PMBVQ -JsbEPSh/ElHSDUItw2ytjJmkolRtM01b7cFj16ZxbHjinXWTIGZFWUYIlaeA2zHK -D/NRMFJwjrQYhjRgPqltvbw7M01Co7SNFBwSotARr36FBjsxbOH3F1jY6w+kXvJU -X5m83C9UONM2K7kkKYXbE2yW+kzJF2LFX0Uu4yDluxNG767/WwqiQSI63aIzNAPp -rSsaIMBSbVZia8q49gcvGyuvqBZpwm/PcZwr/PHJjvGs8hdU1ACmyQ== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIICFTCCAX4CAgECMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNVBAYTAlVTMRMwEQYD -VQQKEwpSVEZNLCBJbmMuMRkwFwYDVQQLExBXaWRnZXRzIERpdmlzaW9uMRgwFgYD -VQQDEw9UZXN0IENBMjAwMTA1MTcwHhcNMDEwNTE3MTYxMTM2WhcNMDQwMzA2MTYx -MTM2WjBOMQswCQYDVQQGEwJVUzETMBEGA1UEChMKUlRGTSwgSW5jLjEZMBcGA1UE -CxMQV2lkZ2V0cyBEaXZpc2lvbjEPMA0GA1UEAxMGY2xpZW50MIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQCHNWSoNh6msUwYGGd7TYQDsdSG0ao6QXaYjk+78ZyM -QeZUBu2dZFjG4wnzkKwrD4rp/J5PLR9AdxR72lb9AavEOKL2UDHJGsscZkGVw/bz -ZbxrKF2rvdpZSvKP1OhV1MOds/WTpRm1gcmVSoV5vLOMqVjzjHoxQ/+1zpjzMxWL -0wIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACTJhRR5tv8A7dc5+zmKR1Q/i8qE3Mrn -mp/MOXHfX+ifJ/w+twoc/yd4En+7pr+hGsiTofct1JOZDW9Akq/ZGu1+NpVRT7Cw -53EdMwpi7ArwZAsLIUBsKA7QmLTbdwjU5S7WlZ24eygZHyqZrK4Few+JuzlFkkoI -FIDCfinyz24m ------END CERTIFICATE----- diff --git a/src/pedro/certs/dh1024.pem b/src/pedro/certs/dh1024.pem deleted file mode 100644 index aa68d98ec..000000000 --- a/src/pedro/certs/dh1024.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIGHAoGBANmAnfkETuKHOCWaE+W+F3kM/e7z5A8hZb7OqwGMQrUOaBEAr4BWeZBn -G/87hhwZgNP69/KUchm714qd/PpOspCaUJ20x6PcmKujpAgca/f19HGMBjRawQMk -R9oaBwazuQT0l0rTTKmvpMEcrQQIcVWii3CZI56I56oqF8biGPD7AgEC ------END DH PARAMETERS----- diff --git a/src/pedro/certs/root.pem b/src/pedro/certs/root.pem deleted file mode 100644 index db0c59fbf..000000000 --- a/src/pedro/certs/root.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICIjCCAYugAwIBAgIBADANBgkqhkiG9w0BAQQFADBXMQswCQYDVQQGEwJVUzET -MBEGA1UEChMKUlRGTSwgSW5jLjEZMBcGA1UECxMQV2lkZ2V0cyBEaXZpc2lvbjEY -MBYGA1UEAxMPVGVzdCBDQTIwMDEwNTE3MB4XDTAxMDUxNzE2MDExNFoXDTA2MTIy -NTE2MDExNFowVzELMAkGA1UEBhMCVVMxEzARBgNVBAoTClJURk0sIEluYy4xGTAX -BgNVBAsTEFdpZGdldHMgRGl2aXNpb24xGDAWBgNVBAMTD1Rlc3QgQ0EyMDAxMDUx -NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmkX40warmH0+lnwD9YjsJhRz -ZX6qXadFry0y2trZ6gMs8Mv33IKPwOu8TE7V+3PESEtjI2wr8juV9OkbIPOm+td5 -M8+6vXyIW+JBo3ch99i0QMTf5/jTgsW+3IjV8yEdiGcZFp2NWKLRvZPq2VRbuF7R -1pvgcaRuBJ0wGOohwnsCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCUB8zMKIlX5io8 -TalbzH9Qke7BcvFAL+wp/5w1ToVsWkNrINSWKv6bl/jcqOD3aPhK7qhaeOU8ZWKL -PoPPCnRl9Wo+1JtsOO3qIgJP79Bl9ooLGahixF2v/gea5qNISjQvwYllLSa//APP -6kXHngO0RIRbiTBYHSkAzm6hDdsvVA== ------END CERTIFICATE----- diff --git a/src/pedro/certs/server.pem b/src/pedro/certs/server.pem deleted file mode 100644 index 87376dbf0..000000000 --- a/src/pedro/certs/server.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,5772A2A7BE34B611 - -1yJ+xAn4MudcIfXXy7ElYngJ9EohIh8yvcyVLmE4kVd0xeaL/Bqhvk25BjYCK5d9 -k1K8cjgnKEBjbC++0xtJxFSbUhwoKTLwn+sBoJDcFzMKkmJXXDbSTOaNr1sVwiAR -SnB4lhUcHguYoV5zlRJn53ft7t1mjB6RwGH+d1Zx6t95OqM1lnKqwekwmotVAWHj -ncu3N8qhmoPMppmzEv0fOo2/pK2WohcJykSeN5zBrZCUxoO0NBNEZkFUcVjR+KsA -1ZeI1mU60szqg+AoU/XtFcow8RtG1QZKQbbXzyfbwaG+6LqkHaWYKHQEI1546yWK -us1HJ734uUkZoyyyazG6PiGCYV2u/aY0i3qdmyDqTvmVIvve7E4glBrtDS9h7D40 -nPShIvOatoPzIK4Y0QSvrI3G1vTsIZT3IOZto4AWuOkLNfYS2ce7prOreF0KjhV0 -3tggw9pHdDmTjHTiIkXqheZxZ7TVu+pddZW+CuB62I8lCBGPW7os1f21e3eOD/oY -YPCI44aJvgP+zUORuZBWqaSJ0AAIuVW9S83Yzkz/tlSFHViOebyd8Cug4TlxK1VI -q6hbSafh4C8ma7YzlvqjMzqFifcIolcbx+1A6ot0UiayJTUra4d6Uc4Rbc9RIiG0 -jfDWC6aii9YkAgRl9WqSd31yASge/HDqVXFwR48qdlYQ57rcHviqxyrwRDnfw/lX -Mf6LPiDKEco4MKej7SR2kK2c2AgxUzpGZeAY6ePyhxbdhA0eY21nDeFd/RbwSc5s -eTiCCMr41OB4hfBFXKDKqsM3K7klhoz6D5WsgE6u3lDoTdz76xOSTg== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIICGDCCAYECAgEBMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNVBAYTAlVTMRMwEQYD -VQQKEwpSVEZNLCBJbmMuMRkwFwYDVQQLExBXaWRnZXRzIERpdmlzaW9uMRgwFgYD -VQQDEw9UZXN0IENBMjAwMTA1MTcwHhcNMDEwNTE3MTYxMDU5WhcNMDQwMzA2MTYx -MDU5WjBRMQswCQYDVQQGEwJVUzETMBEGA1UEChMKUlRGTSwgSW5jLjEZMBcGA1UE -CxMQV2lkZ2V0cyBEaXZpc2lvbjESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqG -SIb3DQEBAQUAA4GNADCBiQKBgQCiWhMjNOPlPLNW4DJFBiL2fFEIkHuRor0pKw25 -J0ZYHW93lHQ4yxA6afQr99ayRjMY0D26pH41f0qjDgO4OXskBsaYOFzapSZtQMbT -97OCZ7aHtK8z0ZGNW/cslu+1oOLomgRxJomIFgW1RyUUkQP1n0hemtUdCLOLlO7Q -CPqZLQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAIumUwl1OoWuyN2xfoBHYAs+lRLY -KmFLoI5+iMcGxWIsksmA+b0FLRAN43wmhPnums8eXgYbDCrKLv2xWcvKDP3mps7m -AMivwtu/eFpYz6J8Mo1fsV4Ys08A/uPXkT23jyKo2hMu8mywkqXCXYF2e+7pEeBr -dsbmkWK5NgoMl8eM ------END CERTIFICATE----- diff --git a/src/pedro/empty.cpp b/src/pedro/empty.cpp deleted file mode 100644 index 2f20405d6..000000000 --- a/src/pedro/empty.cpp +++ /dev/null @@ -1 +0,0 @@ -// empty file to generate a null object file; needed by some archiver tools diff --git a/src/pedro/geckoembed.cpp b/src/pedro/geckoembed.cpp deleted file mode 100644 index 8f979ad88..000000000 --- a/src/pedro/geckoembed.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <stdarg.h> - -#ifdef GECKO_EMBED - -#include "geckoembed.h" - - -namespace Pedro -{ - - - - - - - - - - - - - - - - - - - -} //namespace Pedro - -#endif /* GECKO_EMBED */ -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/geckoembed.h b/src/pedro/geckoembed.h deleted file mode 100644 index af3970006..000000000 --- a/src/pedro/geckoembed.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __GECKOEMBED_H__ -#define __GECKOEMBED_H__ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <stdarg.h> - - -namespace Pedro -{ - - -class GeckoEmbed -{ -public: - - GeckoEmbed() - { - init(); - } - - virtual ~GeckoEmbed() - { - } - - - -private: - - void init() - { - } - - -}; - - -} //namespace Pedro -#define __GECKOEMBED_H__ -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/icon/Thumbs.db b/src/pedro/icon/Thumbs.db Binary files differdeleted file mode 100644 index b1142522c..000000000 --- a/src/pedro/icon/Thumbs.db +++ /dev/null diff --git a/src/pedro/icon/available.png b/src/pedro/icon/available.png Binary files differdeleted file mode 100644 index e88ebd45b..000000000 --- a/src/pedro/icon/available.png +++ /dev/null diff --git a/src/pedro/icon/away.png b/src/pedro/icon/away.png Binary files differdeleted file mode 100644 index 9bb899869..000000000 --- a/src/pedro/icon/away.png +++ /dev/null diff --git a/src/pedro/icon/chat.png b/src/pedro/icon/chat.png Binary files differdeleted file mode 100644 index 84ac5945a..000000000 --- a/src/pedro/icon/chat.png +++ /dev/null diff --git a/src/pedro/icon/dnd.png b/src/pedro/icon/dnd.png Binary files differdeleted file mode 100644 index 25c7a6e5f..000000000 --- a/src/pedro/icon/dnd.png +++ /dev/null diff --git a/src/pedro/icon/error.png b/src/pedro/icon/error.png Binary files differdeleted file mode 100644 index 35febd2ba..000000000 --- a/src/pedro/icon/error.png +++ /dev/null diff --git a/src/pedro/icon/offline.png b/src/pedro/icon/offline.png Binary files differdeleted file mode 100644 index 06284fa30..000000000 --- a/src/pedro/icon/offline.png +++ /dev/null diff --git a/src/pedro/icon/xa.png b/src/pedro/icon/xa.png Binary files differdeleted file mode 100644 index 309da1cb3..000000000 --- a/src/pedro/icon/xa.png +++ /dev/null diff --git a/src/pedro/makefile.in b/src/pedro/makefile.in deleted file mode 100644 index 8c8831f09..000000000 --- a/src/pedro/makefile.in +++ /dev/null @@ -1,17 +0,0 @@ -# Convenience stub makefile to call the real Makefile. - -@SET_MAKE@ - -OBJEXT = @OBJEXT@ - -# Explicit so that it's the default rule. -all: - cd .. && $(MAKE) pedro/all - -clean %.a %.$(OBJEXT): - cd .. && $(MAKE) pedro/$@ - -.PHONY: all clean - -.SUFFIXES: -.SUFFIXES: .a .$(OBJEXT) diff --git a/src/pedro/mingwenv.bat b/src/pedro/mingwenv.bat deleted file mode 100644 index f9ec1e7c5..000000000 --- a/src/pedro/mingwenv.bat +++ /dev/null @@ -1,2 +0,0 @@ -set PATH=c:\mingw4\bin;%PATH%
-set RM=del
diff --git a/src/pedro/pedro.bat b/src/pedro/pedro.bat deleted file mode 100644 index 6cae5a26e..000000000 --- a/src/pedro/pedro.bat +++ /dev/null @@ -1,2 +0,0 @@ -set path=c:\gtk28\bin;%path%
-start pedro.exe
diff --git a/src/pedro/pedroconfig.cpp b/src/pedro/pedroconfig.cpp deleted file mode 100644 index 250674477..000000000 --- a/src/pedro/pedroconfig.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -/* -==================================================== -We are expecting an xml file with this format: - -<pedro> - - <!-- zero to many of these --> - <account> - <name>Jabber's Main Server</name> - <host>jabber.org</host> - <port>5222</port> - <username>myname</username> - <password>mypassword</password> - </account> - -</pedro> - - -==================================================== -*/ - - - -#include "pedroconfig.h" -#include "pedrodom.h" - -#include <stdio.h> -#include <cstring> -#include <string> -#include <cstdlib> -#include <stdlib.h> -#include <string.h> - -namespace Pedro -{ - - -static long getInt(const DOMString &s) -{ - char *start = (char *) s.c_str(); - char *end; - long val = strtol(start, &end, 10); - if (end == start) // did we read more than 1 digit? - val = 0L; - return val; -} - - - -bool XmppConfig::read(const DOMString &buffer) -{ - Parser parser; - - Element *root = parser.parse(buffer); - - if (!root) - { - error("Error in configuration syntax"); - return false; - } - - accounts.clear(); - - std::vector<Element *> mucElems = root->findElements("muc"); - if (mucElems.size() > 0) - { - Element *elem = mucElems[0]; - mucGroup = elem->getTagValue("group"); - mucHost = elem->getTagValue("host"); - mucNick = elem->getTagValue("nick"); - mucPassword = elem->getTagValue("password"); - } - - std::vector<Element *> accountElems = root->findElements("account"); - - for (unsigned int i=0 ; i<accountElems .size() ; i++) - { - XmppAccount account; - Element *elem = accountElems [i]; - - DOMString str = elem->getTagValue("name"); - if (str.size()==0) - str = "unnamed account"; - account.setName(str); - - str = elem->getTagValue("host"); - if (str.size()==0) - str = "jabber.org"; - account.setHost(str); - - str = elem->getTagValue("port"); - int port = (int) getInt(str); - if (port == 0) - port = 5222; - account.setPort(port); - - str = elem->getTagValue("username"); - if (str.size()==0) - str = "noname"; - account.setUsername(str); - - str = elem->getTagValue("password"); - if (str.size()==0) - str = "nopass"; - account.setPassword(str); - - accounts.push_back(account); - } - - - delete root; - - return true; -} - - - - - - -bool XmppConfig::readFile(const DOMString &fileName) -{ - - FILE *f = fopen(fileName.c_str(), "rb"); - if (!f) - { - error("Could not open configuration file '%s' for reading", - fileName.c_str()); - return false; - } - - DOMString buffer; - while (!feof(f)) - { - char ch = (char) fgetc(f); - buffer.push_back(ch); - } - fclose(f); - - if (!read(buffer)) - return false; - - return true; -} - - -DOMString XmppConfig::toXmlBuffer() -{ - - DOMString buf; - - char fmtbuf[32]; - - buf.append("<pedro>\n"); - buf.append(" <muc>\n"); - buf.append(" <group>"); - buf.append(mucGroup); - buf.append("</group>\n"); - buf.append(" <host>"); - buf.append(mucHost); - buf.append("</host>\n"); - buf.append(" <nick>"); - buf.append(mucNick); - buf.append("</nick>\n"); - buf.append(" <password>"); - buf.append(mucPassword); - buf.append("</password>\n"); - buf.append(" </muc>\n"); - - for (unsigned int i = 0 ; i<accounts.size() ; i++) - { - XmppAccount acc = accounts[i]; - buf.append(" <account>\n"); - buf.append(" <name>"); - buf.append(acc.getName()); - buf.append("</name>\n"); - buf.append(" <host>"); - buf.append(acc.getHost()); - buf.append("</host>\n"); - buf.append(" <port>"); - snprintf(fmtbuf, 31, "%d", acc.getPort()); - buf.append(fmtbuf); - buf.append("</port>\n"); - buf.append(" <username>"); - buf.append(acc.getUsername()); - buf.append("</username>\n"); - buf.append(" <password>"); - buf.append(acc.getPassword()); - buf.append("</password>\n"); - buf.append(" </account>\n"); - } - - buf.append("</pedro>\n"); - - return buf; -} - - - - -bool XmppConfig::writeFile(const DOMString &fileName) -{ - - FILE *f = fopen(fileName.c_str(), "wb"); - if (!f) - { - error("Could not open configuration file '%s' for writing", - fileName.c_str()); - return false; - } - - DOMString buffer = toXmlBuffer(); - char *s = (char *)buffer.c_str(); - size_t len = (size_t) strlen(s); //in case we have wide chars - - if (fwrite(s, 1, len, f) != len) - { - return false; - } - fclose(f); - - if (!read(buffer)) - return false; - - return true; -} - - -/** - * - */ -DOMString XmppConfig::getMucGroup() -{ - return mucGroup; -} - -/** - * - */ -void XmppConfig::setMucGroup(const DOMString &val) -{ - mucGroup = val; -} - -/** - * - */ -DOMString XmppConfig::getMucHost() -{ - return mucHost; -} - -/** - * - */ -void XmppConfig::setMucHost(const DOMString &val) -{ - mucHost = val; -} - -/** - * - */ -DOMString XmppConfig::getMucNick() -{ - return mucNick; -} - -/** - * - */ -void XmppConfig::setMucNick(const DOMString &val) -{ - mucNick = val; -} - -/** - * - */ -DOMString XmppConfig::getMucPassword() -{ - return mucPassword; -} - -/** - * - */ -void XmppConfig::setMucPassword(const DOMString &val) -{ - mucPassword = val; -} - - - -/** - * - */ -std::vector<XmppAccount> &XmppConfig::getAccounts() -{ - return accounts; -} - - -/** - * - */ -bool XmppConfig::accountAdd(const XmppAccount &account) -{ - DOMString name = account.getName(); - if (name.size() < 1) - return false; - if (accountExists(name)) - return false; - accounts.push_back(account); - return true; -} - - -/** - * - */ -bool XmppConfig::accountExists(const DOMString &accountName) -{ - if (accountName.size() < 1) - return false; - std::vector<XmppAccount>::iterator iter; - for (iter = accounts.begin() ; iter!= accounts.end() ; iter++) - { - if (iter->getName() == accountName) - return true; - } - return false; -} - - - -/** - * - */ -void XmppConfig::accountRemove(const DOMString &accountName) -{ - if (accountName.size() < 1) - return; - std::vector<XmppAccount>::iterator iter; - for (iter = accounts.begin() ; iter!= accounts.end() ; ) - { - if (iter->getName() == accountName) - iter = accounts.erase(iter); - else - iter++; - } -} - - -/** - * - */ -bool XmppConfig::accountFind(const DOMString &accountName, - XmppAccount &retVal) -{ - if (accountName.size() < 1) - return false; - std::vector<XmppAccount>::iterator iter; - for (iter = accounts.begin() ; iter!= accounts.end() ; iter++) - { - if (iter->getName() == accountName) - { - retVal = (*iter); - return true; - } - } - return false; -} - - - - - -} //namespace Pedro -//######################################################################## -//# E N D O F F I L E -//######################################################################## diff --git a/src/pedro/pedroconfig.h b/src/pedro/pedroconfig.h deleted file mode 100644 index be8c6c665..000000000 --- a/src/pedro/pedroconfig.h +++ /dev/null @@ -1,317 +0,0 @@ -#ifndef __PEDROCONFIG_H__ -#define __PEDROCONFIG_H__ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - - -#include "pedrodom.h" -#include "pedroxmpp.h" - -#include <vector> - - - -namespace Pedro -{ - - -/** - * Individual account record - */ -class XmppAccount -{ - -public: - - /** - * - */ - XmppAccount() - { init(); } - - /** - * - */ - XmppAccount(const XmppAccount &other) - { assign(other); } - - /** - * - */ - XmppAccount operator=(const XmppAccount &other) - { assign(other); return *this; } - - /** - * - */ - virtual ~XmppAccount() - {} - - - /** - * - */ - virtual DOMString getName() const - { return name; } - - /** - * - */ - virtual void setName(const DOMString &val) - { name = val; } - - /** - * - */ - virtual DOMString getHost() const - { return host; } - - /** - * - */ - virtual void setHost(const DOMString &val) - { host = val; } - - /** - * - */ - virtual int getPort() const - { return port; } - - /** - * - */ - virtual void setPort(int val) - { port = val; } - - /** - * - */ - virtual DOMString getUsername() const - { return username; } - - /** - * - */ - virtual void setUsername(const DOMString &val) - { username = val; } - - /** - * - */ - virtual DOMString getPassword() const - { return password; } - - /** - * - */ - virtual void setPassword(const DOMString &val) - { password = val; } - - - -private: - - void init() - { - name = "noname"; - host = "jabber.org"; - port = 5222; - username = "nobody"; - password = "nopass"; - } - - void assign(const XmppAccount &other) - { - name = other.name; - host = other.host; - port = other.port; - username = other.username; - password = other.password; - } - - DOMString name; - DOMString host; - int port; - DOMString username; - DOMString password; - -}; - - - -/** - * Configuration record - */ -class XmppConfig : XmppEventTarget -{ - -public: - - /** - * - */ - XmppConfig() - { init(); } - - /** - * - */ - XmppConfig(const XmppConfig &other) : XmppEventTarget(other) - { assign(other); } - - /** - * - */ - virtual XmppConfig &operator=(const XmppConfig &other) - { assign(other); return *this; } - - /** - * - */ - virtual ~XmppConfig() - {} - - - /** - * Parse a configuration xml chunk from a memory buffer - */ - virtual bool read(const DOMString &buffer); - - /** - * Parse a configuration file - */ - virtual bool readFile(const DOMString &fileName); - - /** - * Ouputs this object as a string formatted in XML - */ - virtual DOMString toXmlBuffer(); - - /** - * Write a configuration file - */ - virtual bool writeFile(const DOMString &fileName); - - /** - * - */ - virtual std::vector<XmppAccount> &getAccounts(); - - /** - * - */ - virtual DOMString getMucGroup(); - - /** - * - */ - virtual void setMucGroup(const DOMString &val); - - /** - * - */ - virtual DOMString getMucHost(); - - /** - * - */ - virtual void setMucHost(const DOMString &val); - - /** - * - */ - virtual DOMString getMucNick(); - - /** - * - */ - virtual void setMucNick(const DOMString &val); - - /** - * - */ - virtual DOMString getMucPassword(); - - /** - * - */ - virtual void setMucPassword(const DOMString &val); - - /** - * - */ - virtual bool accountAdd(const XmppAccount &account); - - /** - * - */ - virtual bool accountExists(const DOMString &accountName); - - /** - * - */ - virtual void accountRemove(const DOMString &accountName); - - /** - * - */ - bool accountFind(const DOMString &accountName, - XmppAccount &retVal); - - -private: - - void init() - { - } - - void assign(const XmppConfig &other) - { - accounts = other.accounts; - } - - //# Group stuff - DOMString mucGroup; - - DOMString mucHost; - - DOMString mucNick; - - DOMString mucPassword; - - std::vector<XmppAccount> accounts; - -}; - - - - -} //namespace Pedro - -#endif /* __PEDROCONFIG_H__ */ - -//######################################################################## -//# E N D O F F I L E -//######################################################################## diff --git a/src/pedro/pedrodom.cpp b/src/pedro/pedrodom.cpp deleted file mode 100644 index 1131e66b8..000000000 --- a/src/pedro/pedrodom.cpp +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Implementation of the Pedro mini-DOM parser and tree - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> - - -#include "pedrodom.h" - -namespace Pedro -{ - - - -//######################################################################## -//# E L E M E N T -//######################################################################## - -Element *Element::clone() -{ - Element *elem = new Element(name, value); - elem->parent = parent; - elem->attributes = attributes; - elem->namespaces = namespaces; - - ElementList::iterator iter; - for (iter = children.begin(); iter != children.end() ; iter++) - { - elem->addChild((*iter)->clone()); - } - return elem; -} - - -void Element::findElementsRecursive(std::vector<Element *>&res, const DOMString &name) -{ - if (getName() == name) - { - res.push_back(this); - } - for (unsigned int i=0; i<children.size() ; i++) - children[i]->findElementsRecursive(res, name); -} - -std::vector<Element *> Element::findElements(const DOMString &name) -{ - std::vector<Element *> res; - findElementsRecursive(res, name); - return res; -} - -DOMString Element::getAttribute(const DOMString &name) -{ - for (unsigned int i=0 ; i<attributes.size() ; i++) - if (attributes[i].getName() ==name) - return attributes[i].getValue(); - return ""; -} - -DOMString Element::getTagAttribute(const DOMString &tagName, const DOMString &attrName) -{ - ElementList elems = findElements(tagName); - if (elems.size() <1) - return ""; - DOMString res = elems[0]->getAttribute(attrName); - return res; -} - -DOMString Element::getTagValue(const DOMString &tagName) -{ - ElementList elems = findElements(tagName); - if (elems.size() <1) - return ""; - DOMString res = elems[0]->getValue(); - return res; -} - -void Element::addChild(Element *child) -{ - if (!child) - return; - child->parent = this; - children.push_back(child); -} - - -void Element::addAttribute(const DOMString &name, const DOMString &value) -{ - Attribute attr(name, value); - attributes.push_back(attr); -} - -void Element::addNamespace(const DOMString &prefix, const DOMString &namespaceURI) -{ - Namespace ns(prefix, namespaceURI); - namespaces.push_back(ns); -} - -void Element::writeIndentedRecursive(FILE *f, int indent) -{ - int i; - if (!f) - return; - //Opening tag, and attributes - for (i=0;i<indent;i++) - fputc(' ',f); - fprintf(f,"<%s",name.c_str()); - for (unsigned int i=0 ; i<attributes.size() ; i++) - { - fprintf(f," %s=\"%s\"", - attributes[i].getName().c_str(), - attributes[i].getValue().c_str()); - } - for (unsigned int i=0 ; i<namespaces.size() ; i++) - { - fprintf(f," xmlns:%s=\"%s\"", - namespaces[i].getPrefix().c_str(), - namespaces[i].getNamespaceURI().c_str()); - } - fprintf(f,">\n"); - - //Between the tags - if (value.size() > 0) - { - for (int i=0;i<indent;i++) - fputc(' ', f); - fprintf(f," %s\n", value.c_str()); - } - - for (unsigned int i=0 ; i<children.size() ; i++) - children[i]->writeIndentedRecursive(f, indent+2); - - //Closing tag - for (int i=0; i<indent; i++) - fputc(' ',f); - fprintf(f,"</%s>\n", name.c_str()); -} - -void Element::writeIndented(FILE *f) -{ - writeIndentedRecursive(f, 0); -} - -void Element::print() -{ - writeIndented(stdout); -} - - -//######################################################################## -//# P A R S E R -//######################################################################## - - - -typedef struct - { - char *escaped; - char value; - } EntityEntry; - -static EntityEntry entities[] = -{ - { "&" , '&' }, - { "<" , '<' }, - { ">" , '>' }, - { "'", '\'' }, - { """, '"' }, - { NULL , '\0' } -}; - - - -/** - * Removes whitespace from beginning and end of a string - */ -DOMString Parser::trim(const DOMString &s) -{ - if (s.size() < 1) - return s; - - //Find first non-ws char - unsigned int begin = 0; - for ( ; begin < s.size() ; begin++) - { - if (!isspace(s[begin])) - break; - } - - //Find first non-ws char, going in reverse - unsigned int end = s.size() - 1; - for ( ; end > begin ; end--) - { - if (!isspace(s[end])) - break; - } - //trace("begin:%d end:%d", begin, end); - - DOMString res = s.substr(begin, end-begin+1); - return res; -} - -void Parser::getLineAndColumn(long pos, long *lineNr, long *colNr) -{ - long line = 1; - long col = 1; - for (long i=0 ; i<pos ; i++) - { - XMLCh ch = parsebuf[i]; - if (ch == '\n' || ch == '\r') - { - col = 0; - line ++; - } - else - col++; - } - *lineNr = line; - *colNr = col; - -} - - -void Parser::error(char const *fmt, ...) -{ - long lineNr; - long colNr; - getLineAndColumn(currentPosition, &lineNr, &colNr); - va_list args; - fprintf(stderr, "xml error at line %ld, column %ld:", lineNr, colNr); - va_start(args,fmt); - vfprintf(stderr,fmt,args); - va_end(args) ; - fprintf(stderr, "\n"); -} - - - -int Parser::peek(long pos) -{ - if (pos >= parselen) - return -1; - currentPosition = pos; - int ch = parsebuf[pos]; - //printf("ch:%c\n", ch); - return ch; -} - - - -DOMString Parser::encode(const DOMString &str) -{ - DOMString ret; - for (unsigned int i=0 ; i<str.size() ; i++) - { - XMLCh ch = (XMLCh)str[i]; - if (ch == '&') - ret.append("&"); - else if (ch == '<') - ret.append("<"); - else if (ch == '>') - ret.append(">"); - else if (ch == '\'') - ret.append("'"); - else if (ch == '"') - ret.append("""); - else - ret.push_back(ch); - - } - return ret; -} - - -int Parser::match(long p0, const char *text) -{ - int p = p0; - while (*text) - { - if (peek(p) != *text) - return p0; - p++; text++; - } - return p; -} - - - -int Parser::skipwhite(long p) -{ - - while (p<parselen) - { - int p2 = match(p, "<!--"); - if (p2 > p) - { - p = p2; - while (p<parselen) - { - p2 = match(p, "-->"); - if (p2 > p) - { - p = p2; - break; - } - p++; - } - } - XMLCh b = peek(p); - if (!isspace(b)) - break; - p++; - } - return p; -} - -/* modify this to allow all chars for an element or attribute name*/ -int Parser::getWord(int p0, DOMString &buf) -{ - int p = p0; - while (p<parselen) - { - XMLCh b = peek(p); - if (b<=' ' || b=='/' || b=='>' || b=='=') - break; - buf.push_back(b); - p++; - } - return p; -} - -int Parser::getQuoted(int p0, DOMString &buf, int do_i_parse) -{ - - int p = p0; - if (peek(p) != '"' && peek(p) != '\'') - return p0; - p++; - - while ( p<parselen ) - { - XMLCh b = peek(p); - if (b=='"' || b=='\'') - break; - if (b=='&' && do_i_parse) - { - bool found = false; - for (EntityEntry *ee = entities ; ee->value ; ee++) - { - int p2 = match(p, ee->escaped); - if (p2>p) - { - buf.push_back(ee->value); - p = p2; - found = true; - break; - } - } - if (!found) - { - error("unterminated entity"); - return false; - } - } - else - { - buf.push_back(b); - p++; - } - } - return p; -} - -int Parser::parseVersion(int p0) -{ - //printf("### parseVersion: %d\n", p0); - - int p = p0; - - p = skipwhite(p0); - - if (peek(p) != '<') - return p0; - - p++; - if (p>=parselen || peek(p)!='?') - return p0; - - p++; - - DOMString buf; - - while (p<parselen) - { - XMLCh ch = peek(p); - if (ch=='?') - { - p++; - break; - } - buf.push_back(ch); - p++; - } - - if (peek(p) != '>') - return p0; - p++; - - //printf("Got version:%s\n",buf.c_str()); - return p; -} - -int Parser::parseDoctype(int p0) -{ - //printf("### parseDoctype: %d\n", p0); - - int p = p0; - p = skipwhite(p); - - if (p>=parselen || peek(p)!='<') - return p0; - - p++; - - if (peek(p)!='!' || peek(p+1)=='-') - return p0; - p++; - - DOMString buf; - while (p<parselen) - { - XMLCh ch = peek(p); - if (ch=='>') - { - p++; - break; - } - buf.push_back(ch); - p++; - } - - //printf("Got doctype:%s\n",buf.c_str()); - return p; -} - -int Parser::parseElement(int p0, Element *par,int depth) -{ - - int p = p0; - - int p2 = p; - - p = skipwhite(p); - - //## Get open tag - XMLCh ch = peek(p); - if (ch!='<') - return p0; - - p++; - - DOMString openTagName; - p = skipwhite(p); - p = getWord(p, openTagName); - //printf("####tag :%s\n", openTagName.c_str()); - p = skipwhite(p); - - //Add element to tree - Element *n = new Element(openTagName); - n->parent = par; - par->addChild(n); - - // Get attributes - if (peek(p) != '>') - { - while (p<parselen) - { - p = skipwhite(p); - ch = peek(p); - //printf("ch:%c\n",ch); - if (ch=='>') - break; - else if (ch=='/' && p<parselen+1) - { - p++; - p = skipwhite(p); - ch = peek(p); - if (ch=='>') - { - p++; - //printf("quick close\n"); - return p; - } - } - DOMString attrName; - p2 = getWord(p, attrName); - if (p2==p) - break; - //printf("name:%s",buf); - p=p2; - p = skipwhite(p); - ch = peek(p); - //printf("ch:%c\n",ch); - if (ch!='=') - break; - p++; - p = skipwhite(p); - // ch = parsebuf[p]; - // printf("ch:%c\n",ch); - DOMString attrVal; - p2 = getQuoted(p, attrVal, true); - p=p2+1; - //printf("name:'%s' value:'%s'\n",attrName.c_str(),attrVal.c_str()); - char *namestr = (char *)attrName.c_str(); - if (strncmp(namestr, "xmlns:", 6)==0) - n->addNamespace(attrName, attrVal); - else - n->addAttribute(attrName, attrVal); - } - } - - bool cdata = false; - - p++; - // ### Get intervening data ### */ - DOMString data; - while (p<parselen) - { - //# COMMENT - p2 = match(p, "<!--"); - if (!cdata && p2>p) - { - p = p2; - while (p<parselen) - { - p2 = match(p, "-->"); - if (p2 > p) - { - p = p2; - break; - } - p++; - } - } - - ch = peek(p); - //# END TAG - if (ch=='<' && !cdata && peek(p+1)=='/') - { - break; - } - //# CDATA - p2 = match(p, "<![CDATA["); - if (p2 > p) - { - cdata = true; - p = p2; - continue; - } - - //# CHILD ELEMENT - if (ch == '<') - { - p2 = parseElement(p, n, depth+1); - if (p2 == p) - { - /* - printf("problem on element:%s. p2:%d p:%d\n", - openTagName.c_str(), p2, p); - */ - return p0; - } - p = p2; - continue; - } - //# ENTITY - if (ch=='&' && !cdata) - { - bool found = false; - for (EntityEntry *ee = entities ; ee->value ; ee++) - { - int p2 = match(p, ee->escaped); - if (p2>p) - { - data.push_back(ee->value); - p = p2; - found = true; - break; - } - } - if (!found) - { - error("unterminated entity"); - return -1; - } - continue; - } - - //# NONE OF THE ABOVE - data.push_back(ch); - p++; - }/*while*/ - - - n->value = data; - //printf("%d : data:%s\n",p,data.c_str()); - - //## Get close tag - p = skipwhite(p); - ch = peek(p); - if (ch != '<') - { - error("no < for end tag\n"); - return p0; - } - p++; - ch = peek(p); - if (ch != '/') - { - error("no / on end tag"); - return p0; - } - p++; - ch = peek(p); - p = skipwhite(p); - DOMString closeTagName; - p = getWord(p, closeTagName); - if (openTagName != closeTagName) - { - error("Mismatched closing tag. Expected </%s>. Got '%s'.", - openTagName.c_str(), closeTagName.c_str()); - return p0; - } - p = skipwhite(p); - if (peek(p) != '>') - { - error("no > on end tag for '%s'", closeTagName.c_str()); - return p0; - } - p++; - // printf("close element:%s\n",closeTagName.c_str()); - p = skipwhite(p); - return p; -} - - - - -Element *Parser::parse(XMLCh *buf,int pos,int len) -{ - parselen = len; - parsebuf = buf; - Element *rootNode = new Element("root"); - pos = parseVersion(pos); - pos = parseDoctype(pos); - pos = parseElement(pos, rootNode, 0); - return rootNode; -} - - -Element *Parser::parse(const char *buf, int pos, int len) -{ - XMLCh *charbuf = new XMLCh[len + 1]; - long i = 0; - for ( ; i < len ; i++) - charbuf[i] = (XMLCh)buf[i]; - charbuf[i] = '\0'; - - Element *n = parse(charbuf, pos, len); - delete[] charbuf; - return n; -} - -Element *Parser::parse(const DOMString &buf) -{ - long len = (long)buf.size(); - XMLCh *charbuf = new XMLCh[len + 1]; - long i = 0; - for ( ; i < len ; i++) - charbuf[i] = (XMLCh)buf[i]; - charbuf[i] = '\0'; - - Element *n = parse(charbuf, 0, len); - delete[] charbuf; - return n; -} - -Element *Parser::parseFile(const DOMString &fileName) -{ - - //##### LOAD INTO A CHAR BUF, THEN CONVERT TO XMLCh - FILE *f = fopen(fileName.c_str(), "rb"); - if (!f) - return NULL; - - struct stat statBuf; - if (fstat(fileno(f),&statBuf)<0) - { - fclose(f); - return NULL; - } - long filelen = statBuf.st_size; - - //printf("length:%d\n",filelen); - XMLCh *charbuf = new XMLCh[filelen + 1]; - for (XMLCh *p=charbuf ; !feof(f) ; p++) - { - *p = (XMLCh)fgetc(f); - } - fclose(f); - charbuf[filelen] = '\0'; - - - /* - printf("nrbytes:%d\n",wc_count); - printf("buf:%ls\n======\n",charbuf); - */ - Element *n = parse(charbuf, 0, filelen); - delete [] charbuf; - return n; -} - - - - - - - -}//namespace Pedro - -#if 0 -//######################################################################## -//# T E S T -//######################################################################## - -bool doTest(char *fileName) -{ - Pedro::Parser parser; - - Pedro::Element *elem = parser.parseFile(fileName); - - if (!elem) - { - printf("Parsing failed\n"); - return false; - } - - elem->print(); - - delete elem; - - return true; -} - - - -int main(int argc, char **argv) -{ - if (argc != 2) - { - printf("usage: %s <xmlfile>\n", argv[0]); - return 1; - } - - if (!doTest(argv[1])) - return 1; - - return 0; -} - -#endif - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - - diff --git a/src/pedro/pedrodom.h b/src/pedro/pedrodom.h deleted file mode 100644 index 91ad21da2..000000000 --- a/src/pedro/pedrodom.h +++ /dev/null @@ -1,363 +0,0 @@ -#ifndef __PEDRODOM_H__ -#define __PEDRODOM_H__ -/* - * API for the Pedro mini-DOM parser and tree - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <glib.h> - -#include <string> -#include <vector> - - -namespace Pedro -{ - -typedef std::string DOMString; -typedef unsigned int XMLCh; - - -class Namespace -{ -public: - Namespace() - {} - - Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg) - { - prefix = prefixArg; - namespaceURI = namespaceURIArg; - } - - Namespace(const Namespace &other) - { - assign(other); - } - - Namespace &operator=(const Namespace &other) - { - assign(other); - return *this; - } - - virtual ~Namespace() - {} - - virtual DOMString getPrefix() - { return prefix; } - - virtual DOMString getNamespaceURI() - { return namespaceURI; } - -protected: - - void assign(const Namespace &other) - { - prefix = other.prefix; - namespaceURI = other.namespaceURI; - } - - DOMString prefix; - DOMString namespaceURI; - -}; - -class Attribute -{ -public: - Attribute() - {} - - Attribute(const DOMString &nameArg, const DOMString &valueArg) - { - name = nameArg; - value = valueArg; - } - - Attribute(const Attribute &other) - { - assign(other); - } - - Attribute &operator=(const Attribute &other) - { - assign(other); - return *this; - } - - virtual ~Attribute() - {} - - virtual DOMString getName() - { return name; } - - virtual DOMString getValue() - { return value; } - -protected: - - void assign(const Attribute &other) - { - name = other.name; - value = other.value; - } - - DOMString name; - DOMString value; - -}; - - -//#Define a list of elements. (Children, search results, etc) -class Element; -typedef std::vector<Element *> ElementList; - - - -class Element -{ -friend class Parser; - -public: - Element() - { - parent = NULL; - } - - Element(const DOMString &nameArg) - { - parent = NULL; - name = nameArg; - } - - Element(const DOMString &nameArg, const DOMString &valueArg) - { - parent = NULL; - name = nameArg; - value = valueArg; - } - - Element(const Element &other) - { - assign(other); - } - - Element &operator=(const Element &other) - { - assign(other); - return *this; - } - - virtual Element *clone(); - - virtual ~Element() - { - for (unsigned int i=0 ; i<children.size() ; i++) - delete children[i]; - } - - virtual DOMString getName() - { return name; } - - virtual DOMString getValue() - { return value; } - - Element *getParent() - { return parent; } - - Element *getFirstChild() - { return (children.size() == 0) ? NULL : children[0]; } - - ElementList getChildren() - { return children; } - - ElementList findElements(const DOMString &name); - - DOMString getAttribute(const DOMString &name); - - std::vector<Attribute> &getAttributes() - { return attributes; } - - DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName); - - DOMString getTagValue(const DOMString &tagName); - - void addChild(Element *child); - - void addAttribute(const DOMString &name, const DOMString &value); - - void addNamespace(const DOMString &prefix, const DOMString &namespaceURI); - - bool exists(const DOMString &name) - { return (findElements(name).size() > 0); } - - /** - * Prettyprint an XML tree to an output stream. Elements are indented - * according to element hierarchy. - * @param f a stream to receive the output - * @param elem the element to output - */ - void writeIndented(FILE *f); - - /** - * Prettyprint an XML tree to standard output. This is the equivalent of - * writeIndented(stdout). - * @param elem the element to output - */ - void print(); - -protected: - - void assign(const Element &other) - { - parent = other.parent; - children = other.children; - attributes = other.attributes; - namespaces = other.namespaces; - name = other.name; - value = other.value; - } - - void findElementsRecursive(std::vector<Element *>&res, const DOMString &name); - - void writeIndentedRecursive(FILE *f, int indent); - - Element *parent; - - ElementList children; - - std::vector<Attribute> attributes; - std::vector<Namespace> namespaces; - - DOMString name; - DOMString value; - -}; - - - - - -class Parser -{ -public: - /** - * Constructor - */ - Parser() - { init(); } - - virtual ~Parser() - {} - - /** - * Parse XML in a char buffer. - * @param buf a character buffer to parse - * @param pos position to start parsing - * @param len number of chars, from pos, to parse. - * @return a pointer to the root of the XML document; - */ - Element *parse(const char *buf,int pos,int len); - - /** - * Parse XML in a char buffer. - * @param buf a character buffer to parse - * @param pos position to start parsing - * @param len number of chars, from pos, to parse. - * @return a pointer to the root of the XML document; - */ - Element *parse(const DOMString &buf); - - /** - * Parse a named XML file. The file is loaded like a data file; - * the original format is not preserved. - * @param fileName the name of the file to read - * @return a pointer to the root of the XML document; - */ - Element *parseFile(const DOMString &fileName); - - /** - * Utility method to preprocess a string for XML - * output, escaping its entities. - * @param str the string to encode - */ - static DOMString encode(const DOMString &str); - - /** - * Removes whitespace from beginning and end of a string - */ - DOMString trim(const DOMString &s); - -private: - - void init() - { - keepGoing = true; - currentNode = NULL; - parselen = 0; - parsebuf = NULL; - currentPosition = 0; - } - - void getLineAndColumn(long pos, long *lineNr, long *colNr); - - void error(char const *fmt, ...) G_GNUC_PRINTF(2,3); - - int peek(long pos); - - int match(long pos, const char *text); - - int skipwhite(long p); - - int getWord(int p0, DOMString &buf); - - int getQuoted(int p0, DOMString &buf, int do_i_parse); - - int parseVersion(int p0); - - int parseDoctype(int p0); - - int parseElement(int p0, Element *par,int depth); - - Element *parse(XMLCh *buf,int pos,int len); - - bool keepGoing; - Element *currentNode; - long parselen; - XMLCh *parsebuf; - DOMString cdatabuf; - long currentPosition; - int colNr; - -}; - - - -}//namespace Pedro - - -#endif /* __PEDRODOM_H__ */ - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/pedrogui.cpp b/src/pedro/pedrogui.cpp deleted file mode 100644 index 38c66b407..000000000 --- a/src/pedro/pedrogui.cpp +++ /dev/null @@ -1,2757 +0,0 @@ -/* - * Simple demo GUI for the Pedro mini-XMPP client. - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pedrogui.h" - -#include <stdarg.h> - -namespace Pedro -{ - - - -//######################################################################### -//# I C O N S -//######################################################################### - -static const guint8 icon_available[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377" - "\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\37733" - "3\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0" - "\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377" - "\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377" - "\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377" - "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377" - "\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3" - "33\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377" - "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377" - "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377" - "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0"}; - - -static const guint8 icon_away[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" - "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\0\0\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377\377\377\377" - "\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377" - "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\0\0\377" - "\377\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0" - "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377" - "\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377" - "\377\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377" - "\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377" - "\377\0\0\0\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0" - "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\0\0\377" - "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" - "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0LLL\377333\377\0\0\0\377\0\0\0\377LLL\377\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0"}; - - -static const guint8 icon_chat[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377" - "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377" - "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733" - "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377" - "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377" - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff" - "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""33" - "3\377\377\377\0\377fff\377\377\377\0\377\0\0\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\377\377\0\377fff\377\0\0\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377" - "\0\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377\377\377" - "\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377" - "\0\0\0\377\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377\0\0\0\377" - "\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377" - "\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377333" - "\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377" - "\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377333\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0"}; - - -static const guint8 icon_dnd[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377" - "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377" - "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733" - "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377" - "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377" - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff" - "\377\377\377\0\377\377\377\0\377\377\377\0\377\177\0\0\377\177\0\0\377" - "\177\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" - "333\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\377\0\0\377\377" - "\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\377\377\0\377fff\377\177\0\0\377\377\377\377\377fff\377" - "\377\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377" - "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377fff\377\377\377" - "\377\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377" - "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377\377\0\0\377fff" - "\377\377\377\377\377fff\377\377\0\0\377\377\0\0\377\177\0\0\377\377\377" - "\377\0\377\377\377\0LLL\377\177\0\0\377\377\0\0\377fff\377\377\377\377" - "\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377\377" - "\0\377\377\377\0LLL\377333\377\177\0\0\377\377\377\377\377fff\377\377" - "\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0""333\377333\377\177\0\0\377\377\0\0\377" - "\377\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\0\377\377" - "\377\0\377\377\377\0"}; - - -static const guint8 icon_error[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\377\377\377\0\0\0\0\377\350\350\350\377333\377\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\350\350\350\377fff\377\0\0\0\377\350\350\350\377\350\350\350\377333" - "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\350\350\350\377\350\350\350\377\350\350\350\377\0\0\0\377\350\350\350" - "\377\350\350\350\377\350\350\350\377333\377\377\377\377\0\377\377\377" - "\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377\0\0\0\377\0" - "\0\0\377fff\377\350\350\350\377\350\350\350\377333\377\377\377\377\0" - "\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377" - "\0\0\0\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377333\377\377\377" - "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\0\0\0\377" - "\350\350\350\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3" - "33\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377\350\350\350\377" - "fff\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350" - "\377\0\0\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350" - "\377\350\350\350\377333\377\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0" - "\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0" - "\0\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"}; - - -static const guint8 icon_offline[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377" - "\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377" - "\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377" - "\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377" - "\377\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377" - "\377\377\377\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377" - "\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377" - "\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377" - "\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377333\377\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377" - "\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377" - "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377\377\377" - "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0" - "\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377" - "\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0" - "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"}; - - -static const guint8 icon_xa[] = -{ "" - /* Pixbuf magic (0x47646b50) */ - "GdkP" - /* length: header (24) + pixel_data (672) */ - "\0\0\2\270" - /* pixdata_type (0x1010002) */ - "\1\1\0\2" - /* rowstride (48) */ - "\0\0\0""0" - /* width (12) */ - "\0\0\0\14" - /* height (14) */ - "\0\0\0\16" - /* pixel_data: */ - "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377333\377" - "333\377\377\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377\377\377\0\377\377" - "\377\0\377\377\377\0\377333\377\377\0\0\377\377\377\377\0\377\377\377" - "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\0\0\377" - "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377\377\0\0" - "\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\177\0\0\377\377\0" - "\0\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377" - "\377\0\0\377\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\177\0\0\377\177\0\0" - "\377\177\0\0\377\377\0\0\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\262\262\262\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377" - "\377\377\177\0\0\377\177\0\0\377\377\377\377\377\262\262\262\377\0\0" - "\0\377\262\262\262\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377" - "\377\262\262\262\377\0\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377" - "\0\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0\0" - "\377\0\0\0\377\377\377\377\377\0\0\0\377\177\0\0\377\177\0\0\377\377" - "\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0" - "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\177" - "\0\0\377\377\377\377\0\177\0\0\377\262\262\262\377\0\0\0\377\262\262" - "\262\377\377\377\377\377\377\377\377\377\377\377\377\377\177\0\0\377" - "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\177\0\0\377\377" - "\377\377\377\377\377\377\377\177\0\0\377\177\0\0\377\177\0\0\377\177" - "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377333\377\0\0\0\377\0\0\0" - "\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" - "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377" - "333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" - "\377\0\377\377\377\0\377\377\377\0"}; - - -//######################################################################### -//# R O S T E R -//######################################################################### - - -void Roster::doubleClickCallback(const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col) -{ - Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(rosterColumns.userColumn); - //printf("Double clicked:%s\n", nick.c_str()); - if (parent) - parent->doChat(nick); - -} - -void Roster::chatCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(rosterColumns.userColumn); - //printf("Chat with:%s\n", nick.c_str()); - if (parent) - parent->doChat(nick); -} - -void Roster::sendFileCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(rosterColumns.userColumn); - //printf("Send file to:%s\n", nick.c_str()); - if (parent) - parent->doSendFile(nick); -} - -bool Roster::buttonPressCallback(GdkEventButton* event) -{ - if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) - { - Gtk::Widget *wid = uiManager->get_widget("/PopupMenu"); - Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid); - popupMenu->popup(event->button, event->time); - return true; - } - else - return false; -} - -bool Roster::doSetup() -{ - set_size_request(200,200); - - pixbuf_available = Gdk::Pixbuf::create_from_inline( - sizeof(icon_available), icon_available, false); - pixbuf_away = Gdk::Pixbuf::create_from_inline( - sizeof(icon_away), icon_away, false); - pixbuf_chat = Gdk::Pixbuf::create_from_inline( - sizeof(icon_chat), icon_chat, false); - pixbuf_dnd = Gdk::Pixbuf::create_from_inline( - sizeof(icon_dnd), icon_dnd, false); - pixbuf_error = Gdk::Pixbuf::create_from_inline( - sizeof(icon_error), icon_error, false); - pixbuf_offline = Gdk::Pixbuf::create_from_inline( - sizeof(icon_offline), icon_offline, false); - pixbuf_xa = Gdk::Pixbuf::create_from_inline( - sizeof(icon_xa), icon_xa, false); - - rosterView.setParent(this); - treeStore = Gtk::TreeStore::create(rosterColumns); - rosterView.set_model(treeStore); - - Gtk::CellRendererText *rend0 = new Gtk::CellRendererText(); - //rend0->property_background() = "gray"; - //rend0->property_foreground() = "black"; - rosterView.append_column("Group", *rend0); - Gtk::TreeViewColumn *col0 = rosterView.get_column(0); - col0->add_attribute(*rend0, "text", 0); - - Gtk::CellRendererPixbuf *rend1 = new Gtk::CellRendererPixbuf(); - rosterView.append_column("Status", *rend1); - Gtk::TreeViewColumn *col1 = rosterView.get_column(1); - col1->add_attribute(*rend1, "pixbuf", 1); - - Gtk::CellRendererText *rend2 = new Gtk::CellRendererText(); - rosterView.append_column("Item", *rend2); - Gtk::TreeViewColumn *col2 = rosterView.get_column(2); - col2->add_attribute(*rend2, "text", 2); - - Gtk::CellRendererText *rend3 = new Gtk::CellRendererText(); - rosterView.append_column("Name", *rend3); - Gtk::TreeViewColumn *col3 = rosterView.get_column(3); - col3->add_attribute(*rend3, "text", 3); - - Gtk::CellRendererText *rend4 = new Gtk::CellRendererText(); - rosterView.append_column("Subscription", *rend4); - Gtk::TreeViewColumn *col4 = rosterView.get_column(4); - col4->add_attribute(*rend4, "text", 4); - - rosterView.signal_row_activated().connect( - sigc::mem_fun(*this, &Roster::doubleClickCallback) ); - - add(rosterView); - set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - - //##### POPUP MENU - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - - actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") ); - - actionGroup->add( Gtk::Action::create("Chat", - Gtk::Stock::CONNECT, "Chat"), - sigc::mem_fun(*this, &Roster::chatCallback) ); - actionGroup->add( Gtk::Action::create("SendFile", - Gtk::Stock::CONNECT, "Send file"), - sigc::mem_fun(*this, &Roster::sendFileCallback) ); - - - uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - - Glib::ustring ui_info = - "<ui>" - " <popup name='PopupMenu'>" - " <menuitem action='Chat'/>" - " <menuitem action='SendFile'/>" - " </popup>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - - - show_all_children(); - - return true; -} - - -/** - * Clear the roster - */ -void Roster::clear() -{ - treeStore->clear(); -} - -/** - * Regenerate the roster - */ -void Roster::refresh() -{ - if (!parent) - return; - treeStore->clear(); - std::vector<XmppUser> items = parent->client.getRoster(); - - //## Add in tree fashion - DOMString lastGroup = ""; - Gtk::TreeModel::Row row = *(treeStore->append()); - row[rosterColumns.groupColumn] = ""; - for (unsigned int i=0 ; i<items.size() ; i++) - { - XmppUser user = items[i]; - if (user.group != lastGroup) - { - if (lastGroup.size()>0) - row = *(treeStore->append()); - row[rosterColumns.groupColumn] = user.group; - lastGroup = user.group; - } - Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline; - if (user.show == "available") - pb = pixbuf_available; - else if (user.show == "away") - pb = pixbuf_away; - else if (user.show == "chat") - pb = pixbuf_chat; - else if (user.show == "dnd") - pb = pixbuf_dnd; - else if (user.show == "xa") - pb = pixbuf_xa; - else - { - //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str()); - } - Gtk::TreeModel::Row childRow = *(treeStore->append(row.children())); - childRow[rosterColumns.statusColumn] = pb; - childRow[rosterColumns.userColumn] = user.jid; - childRow[rosterColumns.nameColumn] = user.nick; - childRow[rosterColumns.subColumn] = user.subscription; - } - rosterView.expand_all(); -} - -//######################################################################### -//# M E S S A G E L I S T -//######################################################################### - -bool MessageList::doSetup() -{ - set_size_request(400,200); - - messageListBuffer = Gtk::TextBuffer::create(); - messageList.set_buffer(messageListBuffer); - messageList.set_editable(false); - messageList.set_wrap_mode(Gtk::WRAP_WORD_CHAR); - - Glib::RefPtr<Gtk::TextBuffer::TagTable> table = - messageListBuffer->get_tag_table(); - Glib::RefPtr<Gtk::TextBuffer::Tag> color0 = - Gtk::TextBuffer::Tag::create("color0"); - color0->property_foreground() = "DarkGreen"; - color0->property_weight() = Pango::WEIGHT_BOLD; - table->add(color0); - Glib::RefPtr<Gtk::TextBuffer::Tag> color1 = - Gtk::TextBuffer::Tag::create("color1"); - color1->property_foreground() = "chocolate4"; - color1->property_weight() = Pango::WEIGHT_BOLD; - table->add(color1); - Glib::RefPtr<Gtk::TextBuffer::Tag> color2 = - Gtk::TextBuffer::Tag::create("color2"); - color2->property_foreground() = "red4"; - color2->property_weight() = Pango::WEIGHT_BOLD; - table->add(color2); - Glib::RefPtr<Gtk::TextBuffer::Tag> color3 = - Gtk::TextBuffer::Tag::create("color3"); - color3->property_foreground() = "MidnightBlue"; - color3->property_weight() = Pango::WEIGHT_BOLD; - table->add(color3); - Glib::RefPtr<Gtk::TextBuffer::Tag> color4 = - Gtk::TextBuffer::Tag::create("color4"); - color4->property_foreground() = "turquoise4"; - color4->property_weight() = Pango::WEIGHT_BOLD; - table->add(color4); - Glib::RefPtr<Gtk::TextBuffer::Tag> color5 = - Gtk::TextBuffer::Tag::create("color5"); - color5->property_foreground() = "OliveDrab"; - color5->property_weight() = Pango::WEIGHT_BOLD; - table->add(color5); - Glib::RefPtr<Gtk::TextBuffer::Tag> color6 = - Gtk::TextBuffer::Tag::create("color6"); - color6->property_foreground() = "purple4"; - color6->property_weight() = Pango::WEIGHT_BOLD; - table->add(color6); - Glib::RefPtr<Gtk::TextBuffer::Tag> color7 = - Gtk::TextBuffer::Tag::create("color7"); - color7->property_foreground() = "VioletRed4"; - color7->property_weight() = Pango::WEIGHT_BOLD; - table->add(color7); - - add(messageList); - set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - - - show_all_children(); - - return true; -} - -/** - * Clear all messages from the list - */ -void MessageList::clear() -{ - messageListBuffer->erase(messageListBuffer->begin(), - messageListBuffer->end()); -} - - -/** - * Post a message to the list - */ -void MessageList::postMessage(const DOMString &from, const DOMString &msg) -{ - DOMString out = "<"; - out.append(from); - out.append("> "); - - int val = 0; - for (unsigned int i=0 ; i<from.size() ; i++) - val += from[i]; - val = val % 8; - - char buf[16]; - sprintf(buf, "color%d", val); - DOMString tagName = buf; - - messageListBuffer->insert_with_tag( - messageListBuffer->end(), out, tagName); - messageListBuffer->insert(messageListBuffer->end(), msg); - messageListBuffer->insert(messageListBuffer->end(), "\n"); - //Gtk::Adjustment *adj = get_vadjustment(); - //adj->set_value(adj->get_upper()-adj->get_page_size()); - Glib::RefPtr<Gtk::TextBuffer::Mark> mark = - messageListBuffer->create_mark("temp", messageListBuffer->end()); - messageList.scroll_mark_onscreen(mark); - messageListBuffer->delete_mark(mark); -} - - - -//######################################################################### -//# U S E R L I S T -//######################################################################### -void UserList::doubleClickCallback(const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col) -{ - Glib::RefPtr<Gtk::TreeModel> model = userList.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(userListColumns.userColumn); - //printf("Double clicked:%s\n", nick.c_str()); - if (parent) - parent->doChat(nick); - -} - -void UserList::chatCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = userList.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(userListColumns.userColumn); - //printf("Chat with:%s\n", nick.c_str()); - if (parent) - parent->doChat(nick); -} - -void UserList::sendFileCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = userList.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString nick = iter->get_value(userListColumns.userColumn); - //printf("Send file to:%s\n", nick.c_str()); - if (parent) - parent->doSendFile(nick); -} - -bool UserList::buttonPressCallback(GdkEventButton* event) -{ - if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) - { - Gtk::Widget *wid = uiManager->get_widget("/PopupMenu"); - Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid); - popupMenu->popup(event->button, event->time); - return true; - } - else - return false; -} - -bool UserList::doSetup() -{ - set_size_request(200,200); - - setParent(NULL); - - pixbuf_available = Gdk::Pixbuf::create_from_inline( - sizeof(icon_available), icon_available, false); - pixbuf_away = Gdk::Pixbuf::create_from_inline( - sizeof(icon_away), icon_away, false); - pixbuf_chat = Gdk::Pixbuf::create_from_inline( - sizeof(icon_chat), icon_chat, false); - pixbuf_dnd = Gdk::Pixbuf::create_from_inline( - sizeof(icon_dnd), icon_dnd, false); - pixbuf_error = Gdk::Pixbuf::create_from_inline( - sizeof(icon_error), icon_error, false); - pixbuf_offline = Gdk::Pixbuf::create_from_inline( - sizeof(icon_offline), icon_offline, false); - pixbuf_xa = Gdk::Pixbuf::create_from_inline( - sizeof(icon_xa), icon_xa, false); - - userList.setParent(this); - userListStore = Gtk::ListStore::create(userListColumns); - userList.set_model(userListStore); - - Gtk::CellRendererPixbuf *rend0 = new Gtk::CellRendererPixbuf(); - userList.append_column("Status", *rend0); - Gtk::TreeViewColumn *col0 = userList.get_column(0); - col0->add_attribute(*rend0, "pixbuf", 0); - - Gtk::CellRendererText *rend1 = new Gtk::CellRendererText(); - //rend1->property_background() = "gray"; - //rend1->property_foreground() = "black"; - userList.append_column("User", *rend1); - Gtk::TreeViewColumn *col1 = userList.get_column(1); - col1->add_attribute(*rend1, "text", 1); - - userList.set_headers_visible(false); - - userList.signal_row_activated().connect( - sigc::mem_fun(*this, &UserList::doubleClickCallback) ); - - add(userList); - set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - - //##### POPUP MENU - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - - actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") ); - - actionGroup->add( Gtk::Action::create("Chat", - Gtk::Stock::CONNECT, "Chat"), - sigc::mem_fun(*this, &UserList::chatCallback) ); - actionGroup->add( Gtk::Action::create("SendFile", - Gtk::Stock::CONNECT, "Send file"), - sigc::mem_fun(*this, &UserList::sendFileCallback) ); - - - uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - - Glib::ustring ui_info = - "<ui>" - " <popup name='PopupMenu'>" - " <menuitem action='Chat'/>" - " <menuitem action='SendFile'/>" - " </popup>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - - show_all_children(); - - return true; -} - -/** - * Clear all messages from the list - */ -void UserList::clear() -{ - userListStore->clear(); -} - - -/** - * Add a user to the list - */ -void UserList::addUser(const DOMString &user, const DOMString &show) -{ - Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline; - if (show == "available") - pb = pixbuf_available; - else if (show == "away") - pb = pixbuf_away; - else if (show == "chat") - pb = pixbuf_chat; - else if (show == "dnd") - pb = pixbuf_dnd; - else if (show == "xa") - pb = pixbuf_xa; - else - { - //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str()); - } - Gtk::TreeModel::Row row = *(userListStore->append()); - row[userListColumns.userColumn] = user; - row[userListColumns.statusColumn] = pb; -} - - - - -//######################################################################### -//# C H A T W I N D O W -//######################################################################### -ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg) - : parent(par) -{ - jid = jidArg; - doSetup(); -} - -ChatWindow::~ChatWindow() -{ -} - -void ChatWindow::leaveCallback() -{ - hide(); - parent.chatDelete(jid); -} - - -void ChatWindow::hideCallback() -{ - hide(); - parent.chatDelete(jid); -} - - -void ChatWindow::textEnterCallback() -{ - DOMString str = inputTxt.get_text(); - if (str.size() > 0) - parent.client.message(jid, str); - inputTxt.set_text(""); - messageList.postMessage(parent.client.getJid(), str); -} - -bool ChatWindow::doSetup() -{ - DOMString title = "Private Chat - "; - title.append(jid); - set_title(title); - - set_size_request(500,300); - - signal_hide().connect( - sigc::mem_fun(*this, &ChatWindow::hideCallback) ); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL), - sigc::mem_fun(*this, &ChatWindow::leaveCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Leave'/>" - " </menu>" - " </menubar>" - "</ui>"; - - add(vbox); - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - vbox.pack_end(vPaned); - - vPaned.add1(messageList); - vPaned.add2(inputTxt); - - inputTxt.signal_activate().connect( - sigc::mem_fun(*this, &ChatWindow::textEnterCallback) ); - - show_all_children(); - - return true; -} - -bool ChatWindow::postMessage(const DOMString &data) -{ - messageList.postMessage(jid, data); - return true; -} - -//######################################################################### -//# G R O U P C H A T W I N D O W -//######################################################################### - -GroupChatWindow::GroupChatWindow(PedroGui &par, - const DOMString &groupJidArg, - const DOMString &nickArg) - : parent(par) -{ - groupJid = groupJidArg; - nick = nickArg; - doSetup(); -} - -GroupChatWindow::~GroupChatWindow() -{ -} - - -void GroupChatWindow::leaveCallback() -{ - parent.client.groupChatLeave(groupJid, nick); - hide(); - parent.groupChatDelete(groupJid, nick); -} - -void GroupChatWindow::hideCallback() -{ - parent.client.groupChatLeave(groupJid, nick); - hide(); - parent.groupChatDelete(groupJid, nick); -} - -void GroupChatWindow::textEnterCallback() -{ - DOMString str = inputTxt.get_text(); - if (str.size() > 0) - parent.client.groupChatMessage(groupJid, str); - inputTxt.set_text(""); -} - -bool GroupChatWindow::doSetup() -{ - DOMString title = "Group Chat - "; - title.append(groupJid); - set_title(title); - - userList.setParent(this); - - set_size_request(500,300); - - signal_hide().connect( - sigc::mem_fun(*this, &GroupChatWindow::hideCallback) ); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Leave", Gtk::Stock::CANCEL), - sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Leave'/>" - " </menu>" - " </menubar>" - "</ui>"; - - add(vbox); - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - vbox.pack_end(vPaned); - - vPaned.add1(hPaned); - vPaned.add2(inputTxt); - inputTxt.signal_activate().connect( - sigc::mem_fun(*this, &GroupChatWindow::textEnterCallback) ); - - - hPaned.add1(messageList); - hPaned.add2(userList); - - - show_all_children(); - - - return true; -} - -bool GroupChatWindow::receiveMessage(const DOMString &from, - const DOMString &data) -{ - messageList.postMessage(from, data); - return true; -} - -bool GroupChatWindow::receivePresence(const DOMString &fromNick, - bool presence, - const DOMString &show, - const DOMString &status) -{ - - DOMString presStr = ""; - presStr.append(fromNick); - if (!presence) - presStr.append(" left the group"); - else - { - if (show.size()<1) - presStr.append(" joined the group"); - else - { - presStr.append(" : "); - presStr.append(show); - } - } - - if (presStr != "xa") - messageList.postMessage("*", presStr); - - userList.clear(); - std::vector<XmppUser> memberList = - parent.client.groupChatGetUserList(groupJid); - for (unsigned int i=0 ; i<memberList.size() ; i++) - { - XmppUser user = memberList[i]; - userList.addUser(user.nick, user.show); - } - return true; -} - - -void GroupChatWindow::doChat(const DOMString &nick) -{ - printf("##Chat with %s\n", nick.c_str()); - DOMString fullJid = groupJid; - fullJid.append("/"); - fullJid.append(nick); - parent.doChat(fullJid); -} - -void GroupChatWindow::doSendFile(const DOMString &nick) -{ - printf("##Send file to %s\n", nick.c_str()); - DOMString fullJid = groupJid; - fullJid.append("/"); - fullJid.append(nick); - parent.doSendFile(fullJid); - -} - - - - -//######################################################################### -//# C O N F I G D I A L O G -//######################################################################### - - -void ConfigDialog::okCallback() -{ - Glib::ustring pass = passField.get_text(); - Glib::ustring newpass = newField.get_text(); - Glib::ustring confpass = confField.get_text(); - if ((pass.size() < 5 || pass.size() > 12 ) || - (newpass.size() < 5 || newpass.size() > 12 ) || - (confpass.size() < 5 || confpass.size()> 12 )) - { - Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - dlg.run(); - } - else if (newpass != confpass) - { - Gtk::MessageDialog dlg(*this, "New password and confirmation do not match", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - dlg.run(); - } - else - { - //response(Gtk::RESPONSE_OK); - hide(); - } -} - -void ConfigDialog::cancelCallback() -{ - //response(Gtk::RESPONSE_CANCEL); - hide(); -} - -void ConfigDialog::on_response(int response_id) -{ - if (response_id == Gtk::RESPONSE_OK) - okCallback(); - else - cancelCallback(); -} - -bool ConfigDialog::doSetup() -{ - set_title("Change Password"); - set_size_request(300,200); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"), - sigc::mem_fun(*this, &ConfigDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &ConfigDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Change'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(3, 2); - get_vbox()->pack_start(table); - - passLabel.set_text("Current Password"); - table.attach(passLabel, 0, 1, 0, 1); - passField.set_visibility(false); - passField.set_text(parent.client.getPassword()); - table.attach(passField, 1, 2, 0, 1); - - newLabel.set_text("New Password"); - table.attach(newLabel, 0, 1, 1, 2); - newField.set_visibility(false); - table.attach(newField, 1, 2, 1, 2); - - confLabel.set_text("Confirm New Password"); - table.attach(confLabel, 0, 1, 2, 3); - confField.set_visibility(false); - confField.signal_activate().connect( - sigc::mem_fun(*this, &ConfigDialog::okCallback) ); - table.attach(confField, 1, 2, 2, 3); - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - -//######################################################################### -//# P A S S W O R D D I A L O G -//######################################################################### - - -void PasswordDialog::okCallback() -{ - Glib::ustring pass = passField.get_text(); - Glib::ustring newpass = newField.get_text(); - Glib::ustring confpass = confField.get_text(); - if ((pass.size() < 5 || pass.size() > 12 ) || - (newpass.size() < 5 || newpass.size() > 12 ) || - (confpass.size() < 5 || confpass.size()> 12 )) - { - Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - dlg.run(); - } - else if (newpass != confpass) - { - Gtk::MessageDialog dlg(*this, "New password and confirmation do not match", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - dlg.run(); - } - else - { - //response(Gtk::RESPONSE_OK); - hide(); - } -} - -void PasswordDialog::cancelCallback() -{ - //response(Gtk::RESPONSE_CANCEL); - hide(); -} - -void PasswordDialog::on_response(int response_id) -{ - if (response_id == Gtk::RESPONSE_OK) - okCallback(); - else - cancelCallback(); -} - -bool PasswordDialog::doSetup() -{ - set_title("Change Password"); - set_size_request(300,200); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"), - sigc::mem_fun(*this, &PasswordDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &PasswordDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Change'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(3, 2); - get_vbox()->pack_start(table); - - passLabel.set_text("Current Password"); - table.attach(passLabel, 0, 1, 0, 1); - passField.set_visibility(false); - passField.set_text(parent.client.getPassword()); - table.attach(passField, 1, 2, 0, 1); - - newLabel.set_text("New Password"); - table.attach(newLabel, 0, 1, 1, 2); - newField.set_visibility(false); - table.attach(newField, 1, 2, 1, 2); - - confLabel.set_text("Confirm New Password"); - table.attach(confLabel, 0, 1, 2, 3); - confField.set_visibility(false); - confField.signal_activate().connect( - sigc::mem_fun(*this, &PasswordDialog::okCallback) ); - table.attach(confField, 1, 2, 2, 3); - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - -//######################################################################### -//# C H A T D I A L O G -//######################################################################### - - -void ChatDialog::okCallback() -{ - response(Gtk::RESPONSE_OK); - hide(); -} - -void ChatDialog::cancelCallback() -{ - response(Gtk::RESPONSE_CANCEL); - hide(); -} - - -bool ChatDialog::doSetup() -{ - set_title("Chat with User"); - set_size_request(300,200); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Chat", Gtk::Stock::CONNECT, "Chat"), - sigc::mem_fun(*this, &ChatDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &ChatDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Chat'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(2, 2); - get_vbox()->pack_start(table); - - userLabel.set_text("User"); - table.attach(userLabel, 0, 1, 0, 1); - //userField.set_text(""); - table.attach(userField, 1, 2, 0, 1); - - //userField.set_text(""); - table.attach(textField, 0, 2, 1, 2); - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - -//######################################################################### -//# G R O U P C H A T D I A L O G -//######################################################################### - - -void GroupChatDialog::okCallback() -{ - response(Gtk::RESPONSE_OK); - hide(); -} - -void GroupChatDialog::cancelCallback() -{ - response(Gtk::RESPONSE_CANCEL); - hide(); -} - - -bool GroupChatDialog::doSetup() -{ - set_title("Join Group Chat"); - set_size_request(300,200); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Join", Gtk::Stock::CONNECT, "Join Group"), - sigc::mem_fun(*this, &GroupChatDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &GroupChatDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Join'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(4, 2); - get_vbox()->pack_start(table); - - groupLabel.set_text("Group"); - table.attach(groupLabel, 0, 1, 0, 1); - groupField.set_text(parent.config.getMucGroup()); - table.attach(groupField, 1, 2, 0, 1); - - hostLabel.set_text("Host"); - table.attach(hostLabel, 0, 1, 1, 2); - hostField.set_text(parent.config.getMucHost()); - table.attach(hostField, 1, 2, 1, 2); - - nickLabel.set_text("Alt Name"); - table.attach(nickLabel, 0, 1, 2, 3); - nickField.set_text(parent.config.getMucNick()); - table.attach(nickField, 1, 2, 2, 3); - - passLabel.set_text("Password"); - table.attach(passLabel, 0, 1, 3, 4); - passField.set_visibility(false); - passField.set_text(parent.config.getMucPassword()); - table.attach(passField, 1, 2, 3, 4); - - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - - - - -//######################################################################### -//# C O N N E C T D I A L O G -//######################################################################### - - -void ConnectDialog::okCallback() -{ - response(Gtk::RESPONSE_OK); - hide(); -} - -void ConnectDialog::saveCallback() -{ - Gtk::Entry txtField; - Gtk::Dialog dlg("Account name", *this, true, true); - dlg.get_vbox()->pack_start(txtField); - txtField.signal_activate().connect( - sigc::bind(sigc::mem_fun(dlg, &Gtk::Dialog::response), - Gtk::RESPONSE_OK )); - dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dlg.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); - dlg.show_all_children(); - int ret = dlg.run(); - if (ret != Gtk::RESPONSE_OK) - return; - - Glib::ustring name = txtField.get_text(); - if (name.size() < 1) - { - parent.error("Account name too short"); - return; - } - - if (parent.config.accountExists(name)) - { - parent.config.accountRemove(name); - } - - XmppAccount account; - account.setName(name); - account.setHost(getHost()); - account.setPort(getPort()); - account.setUsername(getUser()); - account.setPassword(getPass()); - parent.config.accountAdd(account); - - refresh(); - - parent.configSave(); -} - -void ConnectDialog::cancelCallback() -{ - response(Gtk::RESPONSE_CANCEL); - hide(); -} - - -void ConnectDialog::doubleClickCallback( - const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col) -{ - Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString name = iter->get_value(accountColumns.nameColumn); - //printf("Double clicked:%s\n", name.c_str()); - XmppAccount account; - if (!parent.config.accountFind(name, account)) - return; - setHost(account.getHost()); - setPort(account.getPort()); - setUser(account.getUsername()); - setPass(account.getPassword()); - - response(Gtk::RESPONSE_OK); - hide(); -} - -void ConnectDialog::selectedCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString name = iter->get_value(accountColumns.nameColumn); - //printf("Single clicked:%s\n", name.c_str()); - XmppAccount account; - if (!parent.config.accountFind(name, account)) - return; - setHost(account.getHost()); - setPort(account.getPort()); - setUser(account.getUsername()); - setPass(account.getPassword()); -} - -void ConnectDialog::deleteCallback() -{ - Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model(); - Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection(); - Gtk::TreeModel::iterator iter = sel->get_selected(); - DOMString name = iter->get_value(accountColumns.nameColumn); - - parent.config.accountRemove(name); - refresh(); - parent.configSave(); - -} - - - -void ConnectDialog::buttonPressCallback(GdkEventButton* event) -{ - if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) - { - Gtk::Widget *wid = accountUiManager->get_widget("/PopupMenu"); - Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid); - popupMenu->popup(event->button, event->time); - } -} - - -bool ConnectDialog::doSetup() -{ - set_title("Connect"); - set_size_request(300,400); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Connect", - Gtk::Stock::CONNECT, "Connect"), - sigc::mem_fun(*this, &ConnectDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Save", - Gtk::Stock::CONNECT, "Save as account"), - sigc::mem_fun(*this, &ConnectDialog::saveCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", - Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &ConnectDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Connect'/>" - " <separator/>" - " <menuitem action='Save'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(6, 2); - get_vbox()->pack_start(table); - - parent.client.setHost("broadway.dynalias.com"); - parent.client.setPort(5222); - parent.client.setUsername(""); - parent.client.setPassword(""); - parent.client.setResource("pedroXmpp"); - - hostLabel.set_text("Host"); - table.attach(hostLabel, 0, 1, 0, 1); - hostField.set_text(parent.client.getHost()); - table.attach(hostField, 1, 2, 0, 1); - - portLabel.set_text("Port"); - table.attach(portLabel, 0, 1, 1, 2); - portSpinner.set_digits(0); - portSpinner.set_range(1, 65000); - portSpinner.set_value(parent.client.getPort()); - table.attach(portSpinner, 1, 2, 1, 2); - - userLabel.set_text("Username"); - table.attach(userLabel, 0, 1, 2, 3); - userField.set_text(parent.client.getUsername()); - table.attach(userField, 1, 2, 2, 3); - - passLabel.set_text("Password"); - table.attach(passLabel, 0, 1, 3, 4); - passField.set_visibility(false); - passField.set_text(parent.client.getPassword()); - passField.signal_activate().connect( - sigc::mem_fun(*this, &ConnectDialog::okCallback) ); - table.attach(passField, 1, 2, 3, 4); - - resourceLabel.set_text("Resource"); - table.attach(resourceLabel, 0, 1, 4, 5); - resourceField.set_text(parent.client.getResource()); - table.attach(resourceField, 1, 2, 4, 5); - - registerLabel.set_text("Register"); - table.attach(registerLabel, 0, 1, 5, 6); - registerButton.set_active(false); - table.attach(registerButton, 1, 2, 5, 6); - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - - //###################### - //# ACCOUNT LIST - //###################### - - - accountListStore = Gtk::ListStore::create(accountColumns); - accountView.set_model(accountListStore); - - accountView.signal_row_activated().connect( - sigc::mem_fun(*this, &ConnectDialog::doubleClickCallback) ); - - accountView.get_selection()->signal_changed().connect( - sigc::mem_fun(*this, &ConnectDialog::selectedCallback) ); - - accountView.append_column("Account", accountColumns.nameColumn); - accountView.append_column("Host", accountColumns.hostColumn); - - //accountView.signal_row_activated().connect( - // sigc::mem_fun(*this, &AccountDialog::connectCallback) ); - - accountScroll.add(accountView); - accountScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - - get_vbox()->pack_start(accountScroll); - - //##### POPUP MENU - accountView.signal_button_press_event().connect_notify( - sigc::mem_fun(*this, &ConnectDialog::buttonPressCallback) ); - - Glib::RefPtr<Gtk::ActionGroup> accountActionGroup = - Gtk::ActionGroup::create(); - - accountActionGroup->add( Gtk::Action::create("PopupMenu", "_Account") ); - - accountActionGroup->add( Gtk::Action::create("Delete", - Gtk::Stock::DELETE, "Delete"), - sigc::mem_fun(*this, &ConnectDialog::deleteCallback) ); - - - accountUiManager = Gtk::UIManager::create(); - - accountUiManager->insert_action_group(accountActionGroup, 0); - - Glib::ustring account_ui_info = - "<ui>" - " <popup name='PopupMenu'>" - " <menuitem action='Delete'/>" - " </popup>" - "</ui>"; - - accountUiManager->add_ui_from_string(account_ui_info); - //Gtk::Widget* accountMenuBar = uiManager->get_widget("/PopupMenu"); - //get_vbox()->pack_start(*accountMenuBar, Gtk::PACK_SHRINK); - - refresh(); - - show_all_children(); - - return true; -} - - -/** - * Regenerate the account list - */ -void ConnectDialog::refresh() -{ - accountListStore->clear(); - - std::vector<XmppAccount> accounts = parent.config.getAccounts(); - for (unsigned int i=0 ; i<accounts.size() ; i++) - { - XmppAccount account = accounts[i]; - Gtk::TreeModel::Row row = *(accountListStore->append()); - row[accountColumns.nameColumn] = account.getName(); - row[accountColumns.hostColumn] = account.getHost(); - } - accountView.expand_all(); -} - - - -//######################################################################### -//# F I L E S E N D D I A L O G -//######################################################################### - - -void FileSendDialog::okCallback() -{ - response(Gtk::RESPONSE_OK); - hide(); -} - -void FileSendDialog::cancelCallback() -{ - response(Gtk::RESPONSE_CANCEL); - hide(); -} - - -void FileSendDialog::buttonCallback() -{ - Gtk::FileChooserDialog dlg("Select a file to send", - Gtk::FILE_CHOOSER_ACTION_OPEN); - dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT) - { - fileName = dlg.get_filename(); - fileNameField.set_text(fileName); - } -} - -bool FileSendDialog::doSetup() -{ - set_title("Send file to user"); - set_size_request(400,150); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"), - sigc::mem_fun(*this, &FileSendDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &FileSendDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Send'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(2, 2); - get_vbox()->pack_start(table); - - jidLabel.set_text("User ID"); - table.attach(jidLabel, 0, 1, 0, 1); - jidField.set_text("inkscape"); - table.attach(jidField, 1, 2, 0, 1); - - selectFileButton.set_label("Select"); - selectFileButton.signal_clicked().connect( - sigc::mem_fun(*this, &FileSendDialog::buttonCallback) ); - table.attach(selectFileButton, 0, 1, 1, 2); - - fileName = ""; - fileNameField.set_text("No file selected"); - fileNameField.set_editable(false); - table.attach(fileNameField, 1, 2, 1, 2); - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - - -//######################################################################### -//# F I L E R E C E I V E D I A L O G -//######################################################################### - - -void FileReceiveDialog::okCallback() -{ - response(Gtk::RESPONSE_OK); - hide(); -} - -void FileReceiveDialog::cancelCallback() -{ - response(Gtk::RESPONSE_CANCEL); - hide(); -} - -void FileReceiveDialog::buttonCallback() -{ - Gtk::FileChooserDialog dlg("Select a file to save", - Gtk::FILE_CHOOSER_ACTION_SAVE); - dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT) - { - fileName = dlg.get_filename(); - fileNameField.set_text(fileName); - } -} - - -bool FileReceiveDialog::doSetup() -{ - set_title("File being sent by user"); - set_size_request(450,250); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"), - sigc::mem_fun(*this, &FileReceiveDialog::okCallback) ); - actionGroup->add( Gtk::Action::create("Cancel", Gtk::Stock::CANCEL, "Cancel"), - sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) ); - - - Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Send'/>" - " <separator/>" - " <menuitem action='Cancel'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - table.resize(6, 2); - get_vbox()->pack_start(table); - - jidLabel.set_text("User ID"); - table.attach(jidLabel, 0, 1, 0, 1); - jidField.set_text(jid); - jidField.set_editable(false); - table.attach(jidField, 1, 2, 0, 1); - - offeredLabel.set_text("File Offered"); - table.attach(offeredLabel, 0, 1, 1, 2); - offeredField.set_text(offeredName); - offeredField.set_editable(false); - table.attach(offeredField, 1, 2, 1, 2); - - descLabel.set_text("Description"); - table.attach(descLabel, 0, 1, 2, 3); - descField.set_text(desc); - descField.set_editable(false); - table.attach(descField, 1, 2, 2, 3); - - char buf[32]; - snprintf(buf, 31, "%ld", fileSize); - sizeLabel.set_text("Size"); - table.attach(sizeLabel, 0, 1, 3, 4); - sizeField.set_text(buf); - sizeField.set_editable(false); - table.attach(sizeField, 1, 2, 3, 4); - - hashLabel.set_text("MD5 Hash"); - table.attach(hashLabel, 0, 1, 4, 5); - hashField.set_text(hash); - hashField.set_editable(false); - table.attach(hashField, 1, 2, 4, 5); - - selectFileButton.set_label("Select"); - selectFileButton.signal_clicked().connect( - sigc::mem_fun(*this, &FileReceiveDialog::buttonCallback) ); - table.attach(selectFileButton, 0, 1, 5, 6); - - fileName = ""; - fileNameField.set_text("No file selected"); - fileNameField.set_editable(false); - table.attach(fileNameField, 1, 2, 5, 6); - - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - show_all_children(); - - return true; -} - - -//######################################################################### -//# M A I N W I N D O W -//######################################################################### - -PedroGui::PedroGui() -{ - doSetup(); -} - -PedroGui::~PedroGui() -{ - chatDeleteAll(); - groupChatDeleteAll(); -} - - -void PedroGui::error(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - gchar * buffer = g_strdup_vprintf(fmt, args); - va_end(args) ; - - Gtk::MessageDialog dlg(buffer, - false, - Gtk::MESSAGE_ERROR, - Gtk::BUTTONS_OK, - true); - dlg.run(); - g_free(buffer); -} - -void PedroGui::status(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - gchar * buffer = g_strdup_vprintf(fmt, args); - va_end(args) ; - messageList.postMessage("STATUS", buffer); - g_free(buffer); -} - -//################################ -//# CHAT WINDOW MANAGEMENT -//################################ -bool PedroGui::chatCreate(const DOMString &userJid) -{ - std::vector<ChatWindow *>::iterator iter; - for (iter=chats.begin() ; iter != chats.end() ; iter++) - { - if (userJid == (*iter)->getJid()) - return false; - } - ChatWindow *chat = new ChatWindow(*this, userJid); - chat->show(); - chats.push_back(chat); - return true; -} - -bool PedroGui::chatDelete(const DOMString &userJid) -{ - std::vector<ChatWindow *>::iterator iter; - for (iter=chats.begin() ; iter != chats.end() ; ) - { - if (userJid == (*iter)->getJid()) - { - delete(*iter); - iter = chats.erase(iter); - } - else - iter++; - } - return true; -} - -bool PedroGui::chatDeleteAll() -{ - std::vector<ChatWindow *>::iterator iter; - for (iter=chats.begin() ; iter != chats.end() ; ) - { - delete(*iter); - iter = chats.erase(iter); - } - return true; -} - -bool PedroGui::chatMessage(const DOMString &from, const DOMString &data) -{ - std::vector<ChatWindow *>::iterator iter; - for (iter=chats.begin() ; iter != chats.end() ; iter++) - { - if (from == (*iter)->getJid()) - { - (*iter)->postMessage(data); - return true; - } - } - ChatWindow *chat = new ChatWindow(*this, from); - chat->show(); - chats.push_back(chat); - chat->postMessage(data); - return true; -} - - -//################################ -//# GROUP CHAT WINDOW MANAGEMENT -//################################ - -bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick) -{ - std::vector<GroupChatWindow *>::iterator iter; - for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++) - { - if (groupJid == (*iter)->getGroupJid()) - return false; - } - GroupChatWindow *chat = new GroupChatWindow(*this, groupJid, nick); - chat->show(); - groupChats.push_back(chat); - return true; -} - - -bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick) -{ - std::vector<GroupChatWindow *>::iterator iter; - for (iter=groupChats.begin() ; iter != groupChats.end() ;) - { - if (groupJid == (*iter)->getGroupJid() && - nick == (*iter)->getNick()) - { - delete(*iter); - iter = groupChats.erase(iter); - } - else - iter++; - } - return true; -} - - -bool PedroGui::groupChatDeleteAll() -{ - std::vector<GroupChatWindow *>::iterator iter; - for (iter=groupChats.begin() ; iter != groupChats.end() ; ) - { - delete(*iter); - iter = groupChats.erase(iter); - } - return true; -} - - -bool PedroGui::groupChatMessage(const DOMString &groupJid, - const DOMString &from, const DOMString &data) -{ - std::vector<GroupChatWindow *>::iterator iter; - for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++) - { - if (groupJid == (*iter)->getGroupJid()) - { - (*iter)->receiveMessage(from, data); - } - } - return true; -} - -bool PedroGui::groupChatPresence(const DOMString &groupJid, - const DOMString &nick, bool presence, - const DOMString &show, - const DOMString &status) -{ - std::vector<GroupChatWindow *>::iterator iter; - for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++) - { - if (groupJid == (*iter)->getGroupJid()) - { - (*iter)->receivePresence(nick, presence, show, status); - } - } - return true; -} - -//################################ -//# EVENTS -//################################ - -/** - * - */ -void PedroGui::padlockEnable() -{ - padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION, - Gtk::ICON_SIZE_MENU); -} - -/** - * - */ -void PedroGui::padlockDisable() -{ - padlockIcon.clear(); -} - - -/** - * - */ -void PedroGui::handleConnectEvent() -{ - status("##### CONNECTED"); - actionEnable("Connect", false); - actionEnable("Chat", true); - actionEnable("GroupChat", true); - actionEnable("Disconnect", true); - actionEnable("RegPass", true); - actionEnable("RegCancel", true); - DOMString title = "Pedro - "; - title.append(client.getJid()); - set_title(title); -} - - -/** - * - */ -void PedroGui::handleDisconnectEvent() -{ - status("##### DISCONNECTED"); - actionEnable("Connect", true); - actionEnable("Chat", false); - actionEnable("GroupChat", false); - actionEnable("Disconnect", false); - actionEnable("RegPass", false); - actionEnable("RegCancel", false); - padlockDisable(); - DOMString title = "Pedro"; - set_title(title); - chatDeleteAll(); - groupChatDeleteAll(); - roster.clear(); -} - - -/** - * - */ -void PedroGui::doEvent(const XmppEvent &event) -{ - - int typ = event.getType(); - switch (typ) - { - case XmppEvent::EVENT_STATUS: - { - //printf("##### STATUS: %s\n", event.getData().c_str()); - status("%s", event.getData().c_str()); - break; - } - case XmppEvent::EVENT_ERROR: - { - //printf("##### ERROR: %s\n", event.getData().c_str()); - error("%s", event.getData().c_str()); - padlockDisable(); - break; - } - case XmppEvent::EVENT_SSL_STARTED: - { - padlockEnable(); - break; - } - case XmppEvent::EVENT_CONNECTED: - { - handleConnectEvent(); - break; - } - case XmppEvent::EVENT_DISCONNECTED: - { - handleDisconnectEvent(); - break; - } - case XmppEvent::EVENT_MESSAGE: - { - status("##### MESSAGE: %s\n", event.getFrom().c_str()); - chatMessage(event.getFrom(), event.getData()); - break; - } - case XmppEvent::EVENT_PRESENCE: - { - status("##### PRESENCE: %s\n", event.getFrom().c_str()); - roster.refresh(); - break; - } - case XmppEvent::EVENT_ROSTER: - { - status("##### ROSTER\n"); - roster.refresh(); - break; - } - case XmppEvent::EVENT_MUC_JOIN: - { - status("##### GROUP JOINED: %s\n", event.getGroup().c_str()); - break; - } - case XmppEvent::EVENT_MUC_MESSAGE: - { - //printf("##### MUC_MESSAGE: %s\n", event.getGroup().c_str()); - groupChatMessage(event.getGroup(), - event.getFrom(), event.getData()); - break; - } - case XmppEvent::EVENT_MUC_PRESENCE: - { - //printf("##### MUC_USER LIST: %s\n", event.getFrom().c_str()); - groupChatPresence(event.getGroup(), - event.getFrom(), - event.getPresence(), - event.getShow(), - event.getStatus()); - break; - } - case XmppEvent::EVENT_MUC_LEAVE: - { - status("##### GROUP LEFT: %s\n", event.getGroup().c_str()); - groupChatDelete(event.getGroup(), event.getFrom()); - break; - } - case XmppEvent::EVENT_FILE_RECEIVE: - { - status("##### FILE RECEIVE: %s\n", event.getFileName().c_str()); - doReceiveFile(event.getFrom(), event.getIqId(), event.getStreamId(), - event.getFileName(), event.getFileDesc(), - event.getFileSize(), event.getFileHash()); - break; - } - case XmppEvent::EVENT_REGISTRATION_NEW: - { - status("##### REGISTERED: %s at %s\n", - event.getTo().c_str(), event.getFrom().c_str()); - break; - } - case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS: - { - status("##### PASSWORD CHANGED: %s at %s\n", - event.getTo().c_str(), event.getFrom().c_str()); - break; - } - case XmppEvent::EVENT_REGISTRATION_CANCEL: - { - //client.disconnect(); - status("##### REGISTERATION CANCELLED: %s at %s\n", - event.getTo().c_str(), event.getFrom().c_str()); - break; - } - default: - { - printf("unknown event type: %d\n", typ); - break; - } - } - -} - -/** - * - */ -bool PedroGui::checkEventQueue() -{ - while (client.eventQueueAvailable() > 0) - { - XmppEvent evt = client.eventQueuePop(); - doEvent(evt); - } - - while( Gtk::Main::events_pending() ) - Gtk::Main::iteration(); - - return true; -} - - -//################## -//# COMMANDS -//################## -void PedroGui::doChat(const DOMString &jid) -{ - if (jid.size()>0) - { - chatCreate(jid); - return; - } - - FileSendDialog dlg(*this); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - chatCreate(dlg.getJid()); - } - -} - -void PedroGui::doSendFile(const DOMString &jid) -{ - FileSendDialog dlg(*this); - if (jid.size()>0) - dlg.setJid(jid); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - DOMString fileName = dlg.getFileName(); - printf("fileName:%s\n", fileName.c_str()); - DOMString offeredName = ""; - DOMString desc = ""; - client.fileSendBackground(jid, offeredName, fileName, desc); - } - -} - -void PedroGui::doReceiveFile( - const DOMString &jid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &offeredName, - const DOMString &desc, - long size, - const DOMString &hash - ) - -{ - FileReceiveDialog dlg(*this, jid, iqId, streamId, - offeredName, desc, size, hash); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - DOMString fileName = dlg.getFileName(); - printf("fileName:%s\n", fileName.c_str()); - client.fileReceiveBackground(jid, iqId, streamId, fileName, size, hash); - } - -} - - -//################## -//# CALLBACKS -//################## -void PedroGui::connectCallback() -{ - ConnectDialog dialog(*this); - int result = dialog.run(); - dialog.hide(); - if (result == Gtk::RESPONSE_OK) - { - client.setHost(dialog.getHost()); - client.setPort(dialog.getPort()); - client.setUsername(dialog.getUser()); - client.setPassword(dialog.getPass()); - client.setResource(dialog.getResource()); - client.setDoRegister(dialog.getRegister()); - client.connect(); - } -} - - - -void PedroGui::chatCallback() -{ - ChatDialog dialog(*this); - int result = dialog.run(); - dialog.hide(); - if (result == Gtk::RESPONSE_OK) - { - client.message(dialog.getUser(), dialog.getText()); - } -} - - - -void PedroGui::groupChatCallback() -{ - GroupChatDialog dialog(*this); - int result = dialog.run(); - dialog.hide(); - if (result != Gtk::RESPONSE_OK) - return; - DOMString groupJid = dialog.getGroup(); - groupJid.append("@"); - groupJid.append(dialog.getHost()); - if (client.groupChatExists(groupJid)) - { - error("Group chat %s already exists", groupJid.c_str()); - return; - } - groupChatCreate(groupJid, dialog.getNick()); - client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() ); - config.setMucGroup(dialog.getGroup()); - config.setMucHost(dialog.getHost()); - config.setMucNick(dialog.getNick()); - config.setMucPassword(dialog.getPass()); - - configSave(); -} - - -void PedroGui::disconnectCallback() -{ - client.disconnect(); -} - - -void PedroGui::quitCallback() -{ - Gtk::Main::quit(); -} - - -void PedroGui::fontCallback() -{ - Gtk::FontSelectionDialog dlg; - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - Glib::ustring fontName = dlg.get_font_name(); - Pango::FontDescription fontDesc(fontName); - modify_font(fontDesc); - } -} - -void PedroGui::colorCallback() -{ - Gtk::ColorSelectionDialog dlg; - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - Gdk::Color col = dlg.get_colorsel()->get_current_color(); - modify_bg(Gtk::STATE_NORMAL, col); - } -} - -void PedroGui::regPassCallback() -{ - PasswordDialog dlg(*this); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_OK) - { - DOMString newpass = dlg.getNewPass(); - client.inBandRegistrationChangePassword(newpass); - } -} - - -void PedroGui::regCancelCallback() -{ - Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?", - false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true); - int ret = dlg.run(); - if (ret == Gtk::RESPONSE_YES) - { - client.inBandRegistrationCancel(); - } -} - - - -void PedroGui::sendFileCallback() -{ - doSendFile(""); -} - - - -void PedroGui::aboutCallback() -{ - Gtk::AboutDialog dlg; - std::vector<Glib::ustring>authors; - authors.push_back("Bob Jamison"); - dlg.set_authors(authors); - DOMString comments = "A simple XMPP gui client "; - comments.append("Based on the Pedro XMPP client"); - dlg.set_comments(comments); - dlg.set_version("1.0"); - dlg.run(); -} - - - -void PedroGui::actionEnable(const DOMString &name, bool val) -{ - DOMString path = "/ui/MenuBar/"; - path.append(name); - Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path); - if (!action) - { - path = "/ui/MenuBar/MenuFile/"; - path.append(name); - action = uiManager->get_action(path); - } - if (!action) - { - path = "/ui/MenuBar/MenuEdit/"; - path.append(name); - action = uiManager->get_action(path); - } - if (!action) - { - path = "/ui/MenuBar/MenuRegister/"; - path.append(name); - action = uiManager->get_action(path); - } - if (!action) - { - path = "/ui/MenuBar/MenuTransfer/"; - path.append(name); - action = uiManager->get_action(path); - } - if (!action) - { - path = "/ui/MenuBar/MenuHelp/"; - path.append(name); - action = uiManager->get_action(path); - } - if (!action) - return; - action->set_sensitive(val); -} - - -bool PedroGui::configLoad() -{ - if (!config.readFile("pedro.ini")) - return false; - return true; -} - - -bool PedroGui::configSave() -{ - if (!config.writeFile("pedro.ini")) - return false; - return true; -} - - - - -bool PedroGui::doSetup() -{ - configLoad(); - - set_title("Pedro XMPP Client"); - set_size_request(500, 300); - add(mainBox); - - Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create(); - - //### FILE MENU - actionGroup->add( Gtk::Action::create("MenuFile", "_File") ); - - actionGroup->add( Gtk::Action::create("Connect", - Gtk::Stock::CONNECT, "Connect"), - sigc::mem_fun(*this, &PedroGui::connectCallback) ); - - actionGroup->add( Gtk::Action::create("Chat", - Gtk::Stock::CONNECT, "Chat"), - sigc::mem_fun(*this, &PedroGui::chatCallback) ); - - actionGroup->add( Gtk::Action::create("GroupChat", - Gtk::Stock::CONNECT, "Group Chat"), - sigc::mem_fun(*this, &PedroGui::groupChatCallback) ); - - actionGroup->add( Gtk::Action::create("Disconnect", - Gtk::Stock::DISCONNECT, "Disconnect"), - sigc::mem_fun(*this, &PedroGui::disconnectCallback) ); - - actionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT), - sigc::mem_fun(*this, &PedroGui::quitCallback) ); - - //### EDIT MENU - actionGroup->add( Gtk::Action::create("MenuEdit", "_Edit") ); - actionGroup->add( Gtk::Action::create("SelectFont", - Gtk::Stock::SELECT_FONT, "Select Font"), - sigc::mem_fun(*this, &PedroGui::fontCallback) ); - actionGroup->add( Gtk::Action::create("SelectColor", - Gtk::Stock::SELECT_COLOR, "Select Color"), - sigc::mem_fun(*this, &PedroGui::colorCallback) ); - - //### REGISTER MENU - actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") ); - actionGroup->add( Gtk::Action::create("RegPass", - Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"), - sigc::mem_fun(*this, &PedroGui::regPassCallback) ); - actionGroup->add( Gtk::Action::create("RegCancel", - Gtk::Stock::CANCEL, "Cancel Registration"), - sigc::mem_fun(*this, &PedroGui::regCancelCallback) ); - - //### TRANSFER MENU - actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") ); - actionGroup->add( Gtk::Action::create("SendFile", - Gtk::Stock::NETWORK, "Send File"), - sigc::mem_fun(*this, &PedroGui::sendFileCallback) ); - - //### HELP MENU - actionGroup->add( Gtk::Action::create("MenuHelp", "_Help") ); - actionGroup->add( Gtk::Action::create("About", - Gtk::Stock::ABOUT, "About Pedro"), - sigc::mem_fun(*this, &PedroGui::aboutCallback) ); - - uiManager = Gtk::UIManager::create(); - - uiManager->insert_action_group(actionGroup, 0); - add_accel_group(uiManager->get_accel_group()); - - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='MenuFile'>" - " <menuitem action='Connect'/>" - " <separator/>" - " <menuitem action='Chat'/>" - " <menuitem action='GroupChat'/>" - " <separator/>" - " <menuitem action='Disconnect'/>" - " <menuitem action='Quit'/>" - " </menu>" - " <menu action='MenuEdit'>" - " <menuitem action='SelectFont'/>" - " <menuitem action='SelectColor'/>" - " </menu>" - " <menu action='MenuRegister'>" - " <menuitem action='RegPass'/>" - " <menuitem action='RegCancel'/>" - " </menu>" - " <menu action='MenuTransfer'>" - " <menuitem action='SendFile'/>" - " </menu>" - " <menu action='MenuHelp'>" - " <menuitem action='About'/>" - " </menu>" - " </menubar>" - "</ui>"; - - uiManager->add_ui_from_string(ui_info); - Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar"); - menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK); - - padlockDisable(); - menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK); - - mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK); - - actionEnable("Connect", true); - actionEnable("Chat", false); - actionEnable("GroupChat", false); - actionEnable("Disconnect", false); - actionEnable("RegPass", false); - actionEnable("RegCancel", false); - - mainBox.pack_start(vPaned); - vPaned.add1(roster); - vPaned.add2(messageList); - roster.setParent(this); - - show_all_children(); - - //# Start a timer to check the queue every nn milliseconds - Glib::signal_timeout().connect( - sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 ); - - //client.addXmppEventListener(*this); - client.eventQueueEnable(true); - - return true; -} - - -} // namespace Pedro - - - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/pedrogui.h b/src/pedro/pedrogui.h deleted file mode 100644 index 2898da118..000000000 --- a/src/pedro/pedrogui.h +++ /dev/null @@ -1,907 +0,0 @@ -#ifndef __PEDROGUI_H__ -#define __PEDROGUI_H__ -/* - * Simple demo GUI for the Pedro mini-XMPP client. - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - - -#include <gtkmm.h> -#include "ui/widget/spinbutton.h" - -#include "pedroxmpp.h" -#include "pedroconfig.h" - - -namespace Pedro -{ - - -class PedroGui; -class GroupChatWindow; - -//######################################################################### -//# R O S T E R -//######################################################################### -class Roster : public Gtk::ScrolledWindow -{ -public: - - Roster() - { doSetup(); } - - virtual ~Roster() - {} - - /** - * Clear all roster items from the list - */ - virtual void clear(); - - /** - * Regenerate the roster - */ - virtual void refresh(); - - - void setParent(PedroGui *val) - { parent = val; } - -private: - - class CustomTreeView : public Gtk::TreeView - { - public: - CustomTreeView() - { parent = NULL; } - virtual ~CustomTreeView() - {} - - bool on_button_press_event(GdkEventButton* event) - { - Gtk::TreeView::on_button_press_event(event); - if (parent) - parent->buttonPressCallback(event); - return true; - } - void setParent(Roster *val) - { parent = val; } - - private: - Roster *parent; - }; - - void doubleClickCallback(const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col); - - void sendFileCallback(); - void chatCallback(); - bool buttonPressCallback(GdkEventButton* event); - - bool doSetup(); - - Glib::RefPtr<Gdk::Pixbuf> pixbuf_available; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_away; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_error; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa; - - class RosterColumns : public Gtk::TreeModel::ColumnRecord - { - public: - RosterColumns() - { - add(groupColumn); - add(statusColumn); add(userColumn); - add(nameColumn); add(subColumn); - } - - Gtk::TreeModelColumn<Glib::ustring> groupColumn; - Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn; - Gtk::TreeModelColumn<Glib::ustring> userColumn; - Gtk::TreeModelColumn<Glib::ustring> nameColumn; - Gtk::TreeModelColumn<Glib::ustring> subColumn; - }; - - RosterColumns rosterColumns; - - Glib::RefPtr<Gtk::UIManager> uiManager; - - Glib::RefPtr<Gtk::TreeStore> treeStore; - CustomTreeView rosterView; - - PedroGui *parent; -}; - -//######################################################################### -//# M E S S A G E L I S T -//######################################################################### -class MessageList : public Gtk::ScrolledWindow -{ -public: - - MessageList() - { doSetup(); } - - virtual ~MessageList() - {} - - /** - * Clear all messages from the list - */ - virtual void clear(); - - /** - * Post a message to the list - */ - virtual void postMessage(const DOMString &from, const DOMString &msg); - -private: - - bool doSetup(); - - Gtk::TextView messageList; - Glib::RefPtr<Gtk::TextBuffer> messageListBuffer; - -}; - -//######################################################################### -//# U S E R L I S T -//######################################################################### -class UserList : public Gtk::ScrolledWindow -{ -public: - - UserList() - { doSetup(); } - - virtual ~UserList() - {} - - /** - * Clear all messages from the list - */ - virtual void clear(); - - /** - * Post a message to the list - */ - virtual void addUser(const DOMString &user, const DOMString &show); - - - void setParent(GroupChatWindow *val) - { parent = val; } - -private: - - class CustomTreeView : public Gtk::TreeView - { - public: - CustomTreeView() - { parent = NULL; } - virtual ~CustomTreeView() - {} - - bool on_button_press_event(GdkEventButton* event) - { - Gtk::TreeView::on_button_press_event(event); - if (parent) - parent->buttonPressCallback(event); - return true; - } - void setParent(UserList *val) - { parent = val; } - - private: - UserList *parent; - }; - - void doubleClickCallback(const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col); - - void sendFileCallback(); - void chatCallback(); - bool buttonPressCallback(GdkEventButton* event); - - bool doSetup(); - - Glib::RefPtr<Gdk::Pixbuf> pixbuf_available; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_away; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_chat; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_dnd; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_error; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline; - Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa; - - class UserListColumns : public Gtk::TreeModel::ColumnRecord - { - public: - UserListColumns() - { add(statusColumn); add(userColumn); } - - Gtk::TreeModelColumn<Glib::ustring> userColumn; - Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > statusColumn; - }; - - UserListColumns userListColumns; - - Glib::RefPtr<Gtk::UIManager> uiManager; - - Glib::RefPtr<Gtk::ListStore> userListStore; - CustomTreeView userList; - - GroupChatWindow *parent; -}; - - -//######################################################################### -//# C H A T W I N D O W -//######################################################################### -class ChatWindow : public Gtk::Window -{ -public: - - ChatWindow(PedroGui &par, const DOMString jid); - - virtual ~ChatWindow(); - - virtual DOMString getJid() - { return jid; } - - virtual void setJid(const DOMString &val) - { jid = val; } - - virtual bool postMessage(const DOMString &data); - -private: - - DOMString jid; - - void leaveCallback(); - void hideCallback(); - void textEnterCallback(); - - bool doSetup(); - - Gtk::VBox vbox; - Gtk::VPaned vPaned; - - MessageList messageList; - - Gtk::Entry inputTxt; - - PedroGui &parent; -}; - - -//######################################################################### -//# G R O U P C H A T W I N D O W -//######################################################################### -class GroupChatWindow : public Gtk::Window -{ -public: - - GroupChatWindow(PedroGui &par, const DOMString &groupJid, - const DOMString &nick); - - virtual ~GroupChatWindow(); - - - virtual DOMString getGroupJid() - { return groupJid; } - - virtual void setGroupJid(const DOMString &val) - { groupJid = val; } - - virtual DOMString getNick() - { return nick; } - - virtual void setNick(const DOMString &val) - { nick = val; } - - virtual bool receiveMessage(const DOMString &from, - const DOMString &data); - - virtual bool receivePresence(const DOMString &nick, - bool presence, - const DOMString &show, - const DOMString &status); - - virtual void doSendFile(const DOMString &nick); - - virtual void doChat(const DOMString &nick); - - -private: - - void textEnterCallback(); - void leaveCallback(); - void hideCallback(); - - bool doSetup(); - - Gtk::VBox vbox; - Gtk::VPaned vPaned; - Gtk::HPaned hPaned; - - MessageList messageList; - - UserList userList; - - Gtk::Entry inputTxt; - - DOMString groupJid; - DOMString nick; - - PedroGui &parent; - }; - - - -//######################################################################### -//# C O N F I G D I A L O G -//######################################################################### - -class ConfigDialog : public Gtk::Dialog -{ -public: - - ConfigDialog (PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~ConfigDialog () - {} - - DOMString getPass() - { return passField.get_text(); } - DOMString getNewPass() - { return newField.get_text(); } - DOMString getConfirm() - { return confField.get_text(); } - -protected: - - //Overloaded from Gtk::Dialog - virtual void on_response(int response_id); - -private: - - void okCallback(); - void cancelCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label passLabel; - Gtk::Entry passField; - Gtk::Label newLabel; - Gtk::Entry newField; - Gtk::Label confLabel; - Gtk::Entry confField; - - PedroGui &parent; -}; - - -//######################################################################### -//# P A S S W O R D D I A L O G -//######################################################################### -class PasswordDialog : public Gtk::Dialog -{ -public: - - PasswordDialog (PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~PasswordDialog () - {} - - DOMString getPass() - { return passField.get_text(); } - DOMString getNewPass() - { return newField.get_text(); } - DOMString getConfirm() - { return confField.get_text(); } - -protected: - - //Overloaded from Gtk::Dialog - virtual void on_response(int response_id); - -private: - - void okCallback(); - void cancelCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label passLabel; - Gtk::Entry passField; - Gtk::Label newLabel; - Gtk::Entry newField; - Gtk::Label confLabel; - Gtk::Entry confField; - - PedroGui &parent; -}; - - - -//######################################################################### -//# C H A T D I A L O G -//######################################################################### -class ChatDialog : public Gtk::Dialog -{ -public: - - ChatDialog(PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~ChatDialog() - {} - - DOMString getUser() - { return userField.get_text(); } - - DOMString getText() - { return textField.get_text(); } - -private: - - void okCallback(); - void cancelCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label userLabel; - Gtk::Entry userField; - Gtk::Entry textField; - - PedroGui &parent; -}; - - - -//######################################################################### -//# G R O U P C H A T D I A L O G -//######################################################################### - -class GroupChatDialog : public Gtk::Dialog -{ -public: - - GroupChatDialog(PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~GroupChatDialog() - {} - - DOMString getGroup() - { return groupField.get_text(); } - DOMString getHost() - { return hostField.get_text(); } - DOMString getPass() - { return passField.get_text(); } - DOMString getNick() - { return nickField.get_text(); } - -private: - - void okCallback(); - void cancelCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label groupLabel; - Gtk::Entry groupField; - Gtk::Label hostLabel; - Gtk::Entry hostField; - Gtk::Label passLabel; - Gtk::Entry passField; - Gtk::Label nickLabel; - Gtk::Entry nickField; - - PedroGui &parent; -}; - - -//######################################################################### -//# C O N N E C T D I A L O G -//######################################################################### -class ConnectDialog : public Gtk::Dialog -{ -public: - - ConnectDialog (PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~ConnectDialog () - {} - - DOMString getHost() - { return hostField.get_text(); } - void setHost(const DOMString &val) - { hostField.set_text(val); } - int getPort() - { return (int)portSpinner.get_value(); } - void setPort(int val) - { portSpinner.set_value(val); } - DOMString getUser() - { return userField.get_text(); } - void setUser(const DOMString &val) - { userField.set_text(val); } - DOMString getPass() - { return passField.get_text(); } - void setPass(const DOMString &val) - { passField.set_text(val); } - DOMString getResource() - { return resourceField.get_text(); } - void setResource(const DOMString &val) - { resourceField.set_text(val); } - bool getRegister() - { return registerButton.get_active(); } - - /** - * Regenerate the account list - */ - virtual void refresh(); - -private: - - void okCallback(); - void saveCallback(); - void cancelCallback(); - void doubleClickCallback( - const Gtk::TreeModel::Path &path, - Gtk::TreeViewColumn *col); - void selectedCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label hostLabel; - Gtk::Entry hostField; - Gtk::Label portLabel; - Inkscape::UI::Widget::SpinButton portSpinner; - Gtk::Label userLabel; - Gtk::Entry userField; - Gtk::Label passLabel; - Gtk::Entry passField; - Gtk::Label resourceLabel; - Gtk::Entry resourceField; - Gtk::Label registerLabel; - Gtk::CheckButton registerButton; - - Glib::RefPtr<Gtk::UIManager> uiManager; - - - //## Account list - - void buttonPressCallback(GdkEventButton* event); - - Gtk::ScrolledWindow accountScroll; - - void connectCallback(); - - void modifyCallback(); - - void deleteCallback(); - - - class AccountColumns : public Gtk::TreeModel::ColumnRecord - { - public: - AccountColumns() - { - add(nameColumn); - add(hostColumn); - } - - Gtk::TreeModelColumn<Glib::ustring> nameColumn; - Gtk::TreeModelColumn<Glib::ustring> hostColumn; - }; - - AccountColumns accountColumns; - - Glib::RefPtr<Gtk::UIManager> accountUiManager; - - Glib::RefPtr<Gtk::ListStore> accountListStore; - Gtk::TreeView accountView; - - - PedroGui &parent; -}; - - - - -//######################################################################### -//# F I L E S E N D D I A L O G -//######################################################################### - -class FileSendDialog : public Gtk::Dialog -{ -public: - - FileSendDialog(PedroGui &par) : parent(par) - { doSetup(); } - - virtual ~FileSendDialog() - {} - - DOMString getFileName() - { return fileName; } - DOMString getJid() - { return jidField.get_text(); } - void setJid(const DOMString &val) - { return jidField.set_text(val); } - -private: - - void okCallback(); - void cancelCallback(); - void buttonCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label jidLabel; - Gtk::Entry jidField; - - DOMString fileName; - Gtk::Entry fileNameField; - - Gtk::Button selectFileButton; - - PedroGui &parent; -}; - -//######################################################################### -//# F I L E R E C E I V E D I A L O G -//######################################################################### - -class FileReceiveDialog : public Gtk::Dialog -{ -public: - - FileReceiveDialog(PedroGui &par, - const DOMString &jidArg, - const DOMString &iqIdArg, - const DOMString &streamIdArg, - const DOMString &offeredNameArg, - const DOMString &descArg, - long sizeArg, - const DOMString &hashArg - ) : parent(par) - { - jid = jidArg; - iqId = iqIdArg; - streamId = streamIdArg; - offeredName = offeredNameArg; - desc = descArg; - fileSize = sizeArg; - hash = hashArg; - doSetup(); - } - - virtual ~FileReceiveDialog() - {} - - DOMString getJid() - { return jid; } - DOMString getIq() - { return iqId; } - DOMString getStreamId() - { return streamId; } - DOMString getOfferedName() - { return offeredName; } - DOMString getFileName() - { return fileName; } - DOMString getDescription() - { return desc; } - long getSize() - { return fileSize; } - DOMString getHash() - { return hash; } - -private: - - void okCallback(); - void cancelCallback(); - void buttonCallback(); - - bool doSetup(); - - Gtk::Table table; - - Gtk::Label jidLabel; - Gtk::Entry jidField; - Gtk::Label offeredLabel; - Gtk::Entry offeredField; - Gtk::Label descLabel; - Gtk::Entry descField; - Gtk::Label sizeLabel; - Gtk::Entry sizeField; - Gtk::Label hashLabel; - Gtk::Entry hashField; - - Gtk::Entry fileNameField; - - Gtk::Button selectFileButton; - - DOMString jid; - DOMString iqId; - DOMString streamId; - DOMString offeredName; - DOMString desc; - long fileSize; - DOMString hash; - - DOMString fileName; - - PedroGui &parent; -}; - - - -//######################################################################### -//# M A I N W I N D O W -//######################################################################### - -class PedroGui : public Gtk::Window -{ -public: - - PedroGui(); - - virtual ~PedroGui(); - - //Let everyone share these - XmppClient client; - XmppConfig config; - - - virtual void error(const char *fmt, ...) G_GNUC_PRINTF(2,3); - - virtual void status(const char *fmt, ...) G_GNUC_PRINTF(2,3); - - - - void handleConnectEvent(); - - void handleDisconnectEvent(); - - /** - * - */ - virtual void doEvent(const XmppEvent &event); - - /** - * - */ - bool checkEventQueue(); - - - bool chatCreate(const DOMString &userJid); - bool chatDelete(const DOMString &userJid); - bool chatDeleteAll(); - bool chatMessage(const DOMString &jid, const DOMString &data); - - bool groupChatCreate(const DOMString &groupJid, - const DOMString &nick); - bool groupChatDelete(const DOMString &groupJid, - const DOMString &nick); - bool groupChatDeleteAll(); - bool groupChatMessage(const DOMString &groupJid, - const DOMString &from, const DOMString &data); - bool groupChatPresence(const DOMString &groupJid, - const DOMString &nick, - bool presence, - const DOMString &show, - const DOMString &status); - - void doChat(const DOMString &jid); - void doSendFile(const DOMString &jid); - void doReceiveFile(const DOMString &jid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &offeredName, - const DOMString &desc, - long size, - const DOMString &hash); - - - //# File menu - void connectCallback(); - void chatCallback(); - void groupChatCallback(); - void disconnectCallback(); - void quitCallback(); - - //# Edit menu - void fontCallback(); - void colorCallback(); - - //# Transfer menu - void sendFileCallback(); - - //# Registration menu - void regPassCallback(); - void regCancelCallback(); - - //# Help menu - void aboutCallback(); - - //# Configuration file - bool configLoad(); - bool configSave(); - - -private: - - bool doSetup(); - - Gtk::VBox mainBox; - - Gtk::HBox menuBarBox; - - Gtk::Image padlockIcon; - void padlockEnable(); - void padlockDisable(); - - - Pango::FontDescription fontDesc; - Gdk::Color foregroundColor; - Gdk::Color backgroundColor; - - Gtk::VPaned vPaned; - MessageList messageList; - Roster roster; - - Glib::RefPtr<Gtk::UIManager> uiManager; - void actionEnable(const DOMString &name, bool val); - - std::vector<ChatWindow *>chats; - - std::vector<GroupChatWindow *>groupChats; -}; - - -} //namespace Pedro - -#endif /* __PEDROGUI_H__ */ -//######################################################################### -//# E N D O F F I L E -//######################################################################### - - diff --git a/src/pedro/pedromain.cpp b/src/pedro/pedromain.cpp deleted file mode 100644 index 60322f718..000000000 --- a/src/pedro/pedromain.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> - - - - -//####################################################################### -//# G E C K O (xulrunner) -//####################################################################### - -#ifdef GECKO_EMBED - - -#include "geckoembed.h" - -int main(int argc, char *argv[]) -{ - GeckoEmbed embedder; - - embedder.run(); - - return 0; -} - - -//####################################################################### -//# G T K M M (pedrogui) -//####################################################################### -#else /* NOT GECKO_EMBED */ - - - -#include "pedrogui.h" - -int main(int argc, char *argv[]) -{ - Gtk::Main kit(argc, argv); - - Pedro::PedroGui window; - - kit.run(window); - - return 0; -} - - - -#endif /* GECKO_EMBED */ - - - - - -#ifdef __WIN32__ -#include <windows.h> - -extern "C" int __export WINAPI -WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, - char *lpszCmdLine, int nCmdShow) -{ - int ret = main (__argc, __argv); - return ret; -} - -#endif - - - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/pedroutil.cpp b/src/pedro/pedroutil.cpp deleted file mode 100644 index 09407ff08..000000000 --- a/src/pedro/pedroutil.cpp +++ /dev/null @@ -1,1516 +0,0 @@ -/* - * Support classes for the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <sys/stat.h> - -#include "pedroutil.h" - - - -#ifdef __WIN32__ - -#include <windows.h> - -#else /* UNIX */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#include <unistd.h> -#include <sys/ioctl.h> - -#include <pthread.h> - -#endif /* UNIX */ - -#ifdef HAVE_SSL -RELAYTOOL_SSL -#endif - - -namespace Pedro -{ - - - - - -//######################################################################## -//######################################################################## -//# B A S E 6 4 -//######################################################################## -//######################################################################## - - -//################# -//# ENCODER -//################# - - -static const char *base64encode = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - - -/** - * Writes the specified byte to the output buffer - */ -void Base64Encoder::append(int ch) -{ - outBuf <<= 8; - outBuf |= (ch & 0xff); - bitCount += 8; - if (bitCount >= 24) - { - int indx = (int)((outBuf & 0x00fc0000L) >> 18); - int obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x0003f000L) >> 12); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x00000fc0L) >> 6); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x0000003fL) ); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - bitCount = 0; - outBuf = 0L; - } -} - -/** - * Writes the specified string to the output buffer - */ -void Base64Encoder::append(char *str) -{ - while (*str) - append((int)*str++); -} - -/** - * Writes the specified string to the output buffer - */ -void Base64Encoder::append(unsigned char *str, int len) -{ - while (len>0) - { - append((int)*str++); - len--; - } -} - -/** - * Writes the specified string to the output buffer - */ -void Base64Encoder::append(const DOMString &str) -{ - append((char *)str.c_str()); -} - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -DOMString Base64Encoder::finish() -{ - //get any last bytes (1 or 2) out of the buffer - if (bitCount == 16) - { - outBuf <<= 2; //pad to make 18 bits - - int indx = (int)((outBuf & 0x0003f000L) >> 12); - int obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x00000fc0L) >> 6); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x0000003fL) ); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - buf.push_back('='); - } - else if (bitCount == 8) - { - outBuf <<= 4; //pad to make 12 bits - - int indx = (int)((outBuf & 0x00000fc0L) >> 6); - int obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - indx = (int)((outBuf & 0x0000003fL) ); - obyte = (int)base64encode[indx & 63]; - buf.push_back(obyte); - - buf.push_back('='); - buf.push_back('='); - } - - DOMString ret = buf; - reset(); - return ret; -} - - -DOMString Base64Encoder::encode(const DOMString &str) -{ - Base64Encoder encoder; - encoder.append(str); - DOMString ret = encoder.finish(); - return ret; -} - - - -//################# -//# DECODER -//################# - -static int base64decode[] = -{ -/*00*/ -1, -1, -1, -1, -1, -1, -1, -1, -/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, -/*10*/ -1, -1, -1, -1, -1, -1, -1, -1, -/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, -/*20*/ -1, -1, -1, -1, -1, -1, -1, -1, -/*28*/ -1, -1, -1, 62, -1, -1, -1, 63, -/*30*/ 52, 53, 54, 55, 56, 57, 58, 59, -/*38*/ 60, 61, -1, -1, -1, -1, -1, -1, -/*40*/ -1, 0, 1, 2, 3, 4, 5, 6, -/*48*/ 7, 8, 9, 10, 11, 12, 13, 14, -/*50*/ 15, 16, 17, 18, 19, 20, 21, 22, -/*58*/ 23, 24, 25, -1, -1, -1, -1, -1, -/*60*/ -1, 26, 27, 28, 29, 30, 31, 32, -/*68*/ 33, 34, 35, 36, 37, 38, 39, 40, -/*70*/ 41, 42, 43, 44, 45, 46, 47, 48, -/*78*/ 49, 50, 51, -1, -1, -1, -1, -1 -}; - - - -/** - * Appends one char to the decoder - */ -void Base64Decoder::append(int ch) -{ - if (isspace(ch)) - return; - else if (ch == '=') //padding - { - inBytes[inCount++] = 0; - } - else - { - int byteVal = base64decode[ch & 0x7f]; - //printf("char:%c %d\n", ch, byteVal); - if (byteVal < 0) - { - //Bad lookup value - } - inBytes[inCount++] = byteVal; - } - - if (inCount >=4 ) - { - unsigned char b0 = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03); - unsigned char b1 = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f); - unsigned char b2 = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f); - buf.push_back(b0); - buf.push_back(b1); - buf.push_back(b2); - inCount = 0; - } - -} - -void Base64Decoder::append(char *str) -{ - while (*str) - append((int)*str++); -} - -void Base64Decoder::append(const DOMString &str) -{ - append((char *)str.c_str()); -} - -std::vector<unsigned char> Base64Decoder::finish() -{ - std::vector<unsigned char> ret = buf; - reset(); - return ret; -} - -std::vector<unsigned char> Base64Decoder::decode(const DOMString &str) -{ - Base64Decoder decoder; - decoder.append(str); - std::vector<unsigned char> ret = decoder.finish(); - return ret; -} - -DOMString Base64Decoder::decodeToString(const DOMString &str) -{ - Base64Decoder decoder; - decoder.append(str); - std::vector<unsigned char> ret = decoder.finish(); - DOMString buf; - for (unsigned int i=0 ; i<ret.size() ; i++) - buf.push_back(ret[i]); - return buf; -} - - - - - - - -//######################################################################## -//######################################################################## -//### S H A 1 H A S H I N G -//######################################################################## -//######################################################################## - -void Sha1::hash(unsigned char *dataIn, int len, unsigned char *digest) -{ - Sha1 sha1; - sha1.append(dataIn, len); - sha1.finish(digest); -} - -static const char *sha1hex = "0123456789abcdef"; - -DOMString Sha1::hashHex(unsigned char *dataIn, int len) -{ - unsigned char hashout[20]; - hash(dataIn, len, hashout); - DOMString ret; - for (int i=0 ; i<20 ; i++) - { - unsigned char ch = hashout[i]; - ret.push_back(sha1hex[ (ch>>4) & 15 ]); - ret.push_back(sha1hex[ ch & 15 ]); - } - return ret; -} - - -DOMString Sha1::hashHex(const DOMString &str) -{ - return hashHex((unsigned char *)str.c_str(), str.size()); -} - - -void Sha1::init() -{ - - longNr = 0; - byteNr = 0; - nrBytesHi = 0; - nrBytesLo = 0; - - // Initialize H with the magic constants (see FIPS180 for constants) - hashBuf[0] = 0x67452301L; - hashBuf[1] = 0xefcdab89L; - hashBuf[2] = 0x98badcfeL; - hashBuf[3] = 0x10325476L; - hashBuf[4] = 0xc3d2e1f0L; - - for (int i = 0; i < 4; i++) - inb[i] = 0; - - for (int i = 0; i < 80; i++) - inBuf[i] = 0; -} - - -void Sha1::append(unsigned char ch) -{ - if (nrBytesLo == 0xffffffffL) - { - nrBytesHi++; - nrBytesLo = 0; - } - else - nrBytesLo++; - - inb[byteNr++] = (unsigned long)ch; - if (byteNr >= 4) - { - inBuf[longNr++] = inb[0] << 24 | inb[1] << 16 | - inb[2] << 8 | inb[3]; - byteNr = 0; - } - if (longNr >= 16) - { - transform(); - longNr = 0; - } -} - - -void Sha1::append(unsigned char *dataIn, int len) -{ - for (int i = 0; i < len; i++) - append(dataIn[i]); -} - - -void Sha1::append(const DOMString &str) -{ - append((unsigned char *)str.c_str(), str.size()); -} - - -void Sha1::finish(unsigned char digest[20]) -{ - //snapshot the bit count now before padding - unsigned long nrBitsLo = (nrBytesLo << 3) & 0xffffffff; - unsigned long nrBitsHi = (nrBytesHi << 3) | ((nrBytesLo >> 29) & 7); - - //Append terminal char - append(0x80); - - //pad until we have a 56 of 64 bytes, allowing for 8 bytes at the end - while (longNr != 14) - append(0); - - - //##### Append length in bits - append((unsigned char)((nrBitsHi>>24) & 0xff)); - append((unsigned char)((nrBitsHi>>16) & 0xff)); - append((unsigned char)((nrBitsHi>> 8) & 0xff)); - append((unsigned char)((nrBitsHi ) & 0xff)); - append((unsigned char)((nrBitsLo>>24) & 0xff)); - append((unsigned char)((nrBitsLo>>16) & 0xff)); - append((unsigned char)((nrBitsLo>> 8) & 0xff)); - append((unsigned char)((nrBitsLo ) & 0xff)); - - - //copy out answer - int indx = 0; - for (int i=0 ; i<5 ; i++) - { - digest[indx++] = (unsigned char)((hashBuf[i] >> 24) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] >> 16) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] >> 8) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] ) & 0xff); - } - - // Re-initialize the context (also zeroizes contents) - init(); -} - - - -#define SHA_ROTL(X,n) ((((X) << (n)) & 0xffffffff) | (((X) >> (32-(n))) & 0xffffffff)) - -void Sha1::transform() -{ - unsigned long *W = inBuf; - unsigned long *H = hashBuf; - - for (int t = 16; t <= 79; t++) - W[t] = SHA_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); - - unsigned long A = H[0]; - unsigned long B = H[1]; - unsigned long C = H[2]; - unsigned long D = H[3]; - unsigned long E = H[4]; - - unsigned long TEMP; - - for (int t = 0; t <= 19; t++) - { - TEMP = (SHA_ROTL(A,5) + ((B&C)|((~B)&D)) + - E + W[t] + 0x5a827999L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (int t = 20; t <= 39; t++) - { - TEMP = (SHA_ROTL(A,5) + (B^C^D) + - E + W[t] + 0x6ed9eba1L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (int t = 40; t <= 59; t++) - { - TEMP = (SHA_ROTL(A,5) + ((B&C)|(B&D)|(C&D)) + - E + W[t] + 0x8f1bbcdcL) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (int t = 60; t <= 79; t++) - { - TEMP = (SHA_ROTL(A,5) + (B^C^D) + - E + W[t] + 0xca62c1d6L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - - H[0] = (H[0] + A) & 0xffffffffL; - H[1] = (H[1] + B) & 0xffffffffL; - H[2] = (H[2] + C) & 0xffffffffL; - H[3] = (H[3] + D) & 0xffffffffL; - H[4] = (H[4] + E) & 0xffffffffL; -} - - - -//######################################################################## -//######################################################################## -//### M D 5 H A S H I N G -//######################################################################## -//######################################################################## - - - - -void Md5::hash(unsigned char *dataIn, unsigned long len, unsigned char *digest) -{ - Md5 md5; - md5.append(dataIn, len); - md5.finish(digest); -} - -DOMString Md5::hashHex(unsigned char *dataIn, unsigned long len) -{ - Md5 md5; - md5.append(dataIn, len); - DOMString ret = md5.finishHex(); - return ret; -} - -DOMString Md5::hashHex(const DOMString &str) -{ - Md5 md5; - md5.append(str); - DOMString ret = md5.finishHex(); - return ret; -} - - -/** - * Initialize MD5 polynomials and storage - */ -void Md5::init() -{ - hashBuf[0] = 0x67452301; - hashBuf[1] = 0xefcdab89; - hashBuf[2] = 0x98badcfe; - hashBuf[3] = 0x10325476; - - nrBytesHi = 0; - nrBytesLo = 0; - byteNr = 0; - longNr = 0; -} - - - - -/** - * Update with one character - */ -void Md5::append(unsigned char ch) -{ - if (nrBytesLo == 0xffffffff) - { - nrBytesLo = 0; - nrBytesHi++; - } - else - nrBytesLo++; - - //pack 64 bytes into 16 longs - inb[byteNr++] = (unsigned long)ch; - if (byteNr >= 4) - { - unsigned long val = - inb[3] << 24 | inb[2] << 16 | inb[1] << 8 | inb[0]; - inBuf[longNr++] = val; - byteNr = 0; - } - if (longNr >= 16) - { - transform(); - longNr = 0; - } -} - - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void Md5::append(unsigned char *source, unsigned long len) -{ - while (len--) - append(*source++); -} - - -/* - * Update context to reflect the concatenation of another string - */ -void Md5::append(const DOMString &str) -{ - append((unsigned char *)str.c_str(), str.size()); -} - - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void Md5::finish(unsigned char *digest) -{ - //snapshot the bit count now before padding - unsigned long nrBitsLo = (nrBytesLo << 3) & 0xffffffff; - unsigned long nrBitsHi = (nrBytesHi << 3) | ((nrBytesLo >> 29) & 7); - - //Append terminal char - append(0x80); - - //pad until we have a 56 of 64 bytes, allowing for 8 bytes at the end - while (longNr != 14) - append(0); - - //##### Append length in bits - append((unsigned char)((nrBitsLo ) & 0xff)); - append((unsigned char)((nrBitsLo>> 8) & 0xff)); - append((unsigned char)((nrBitsLo>>16) & 0xff)); - append((unsigned char)((nrBitsLo>>24) & 0xff)); - append((unsigned char)((nrBitsHi ) & 0xff)); - append((unsigned char)((nrBitsHi>> 8) & 0xff)); - append((unsigned char)((nrBitsHi>>16) & 0xff)); - append((unsigned char)((nrBitsHi>>24) & 0xff)); - - //copy out answer - int indx = 0; - for (int i=0 ; i<4 ; i++) - { - digest[indx++] = (unsigned char)((hashBuf[i] ) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] >> 8) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] >> 16) & 0xff); - digest[indx++] = (unsigned char)((hashBuf[i] >> 24) & 0xff); - } - - init(); // Security! ;-) -} - - - -static const char *md5hex = "0123456789abcdef"; - -DOMString Md5::finishHex() -{ - unsigned char hashout[16]; - finish(hashout); - DOMString ret; - for (int i=0 ; i<16 ; i++) - { - unsigned char ch = hashout[i]; - ret.push_back(md5hex[ (ch>>4) & 15 ]); - ret.push_back(md5hex[ ch & 15 ]); - } - return ret; -} - - - -//# The four core functions - F1 is optimized somewhat - -// #define F1(x, y, z) (x & y | ~x & z) -#define M(x) ((x) &= 0xffffffff) -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -// ## This is the central step in the MD5 algorithm. -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += (f(x, y, z) + data), M(w), w = w<<s | w>>(32-s), w += x, M(w) ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - * @parm buf points to an array of 4 unsigned 32bit (at least) integers - * @parm in points to an array of 16 unsigned 32bit (at least) integers - */ -void Md5::transform() -{ - unsigned long *i = inBuf; - unsigned long a = hashBuf[0]; - unsigned long b = hashBuf[1]; - unsigned long c = hashBuf[2]; - unsigned long d = hashBuf[3]; - - MD5STEP(F1, a, b, c, d, i[ 0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, i[ 1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, i[ 2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, i[ 3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, i[ 4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, i[ 5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, i[ 6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, i[ 7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, i[ 8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, i[ 9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, i[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, i[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, i[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, i[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, i[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, i[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, i[ 1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, i[ 6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, i[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, i[ 0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, i[ 5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, i[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, i[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, i[ 4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, i[ 9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, i[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, i[ 3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, i[ 8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, i[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, i[ 2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, i[ 7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, i[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, i[ 5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, i[ 8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, i[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, i[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, i[ 1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, i[ 4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, i[ 7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, i[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, i[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, i[ 0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, i[ 3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, i[ 6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, i[ 9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, i[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, i[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, i[ 2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, i[ 0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, i[ 7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, i[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, i[ 5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, i[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, i[ 3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, i[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, i[ 1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, i[ 8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, i[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, i[ 6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, i[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, i[ 4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, i[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, i[ 2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, i[ 9] + 0xeb86d391, 21); - - hashBuf[0] += a; - hashBuf[1] += b; - hashBuf[2] += c; - hashBuf[3] += d; -} - - - - - -//######################################################################## -//######################################################################## -//### T H R E A D -//######################################################################## -//######################################################################## - - - - - -#ifdef __WIN32__ - - -static DWORD WINAPI WinThreadFunction(LPVOID context) -{ - Thread *thread = (Thread *)context; - thread->execute(); - return 0; -} - - -void Thread::start() -{ - DWORD dwThreadId; - HANDLE hThread = CreateThread(NULL, 0, WinThreadFunction, - (LPVOID)this, 0, &dwThreadId); - //Make sure the thread is started before 'this' is deallocated - while (!started) - sleep(10); - CloseHandle(hThread); -} - -void Thread::sleep(unsigned long millis) -{ - Sleep(millis); -} - -#else /* UNIX */ - - -void *PthreadThreadFunction(void *context) -{ - Thread *thread = (Thread *)context; - thread->execute(); - return NULL; -} - - -void Thread::start() -{ - pthread_t thread; - - int ret = pthread_create(&thread, NULL, - PthreadThreadFunction, (void *)this); - if (ret != 0) - printf("Thread::start: thread creation failed: %s\n", strerror(ret)); - - //Make sure the thread is started before 'this' is deallocated - while (!started) - sleep(10); - -} - -void Thread::sleep(unsigned long millis) -{ - timespec requested; - requested.tv_sec = millis / 1000; - requested.tv_nsec = (millis % 1000 ) * 1000000L; - nanosleep(&requested, NULL); -} - -#endif - - - - - - - - -//######################################################################## -//######################################################################## -//### S O C K E T -//######################################################################## -//######################################################################## - - - - - -//######################################################################### -//# U T I L I T Y -//######################################################################### - -static void mybzero(void *s, size_t n) -{ - unsigned char *p = (unsigned char *)s; - while (n > 0) - { - *p++ = (unsigned char)0; - n--; - } -} - -static void mybcopy(void *src, void *dest, size_t n) -{ - unsigned char *p = (unsigned char *)dest; - unsigned char *q = (unsigned char *)src; - while (n > 0) - { - *p++ = *q++; - n--; - } -} - - - -//######################################################################### -//# T C P C O N N E C T I O N -//######################################################################### - -TcpSocket::TcpSocket() -{ - init(); -} - - -TcpSocket::TcpSocket(const std::string &hostnameArg, int port) -{ - init(); - hostname = hostnameArg; - portno = port; -} - - - - -#ifdef HAVE_SSL - -static void cryptoLockCallback(int mode, int type, const char */*file*/, int /*line*/) -{ - //printf("########### LOCK\n"); - static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ - const char *errstr = NULL; - - int rw = mode & (CRYPTO_READ|CRYPTO_WRITE); - if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) - { - errstr = "invalid mode"; - goto err; - } - - if (type < 0 || type >= CRYPTO_NUM_LOCKS) - { - errstr = "type out of bounds"; - goto err; - } - - if (mode & CRYPTO_LOCK) - { - if (modes[type]) - { - errstr = "already locked"; - /* must not happen in a single-threaded program - * (would deadlock) - */ - goto err; - } - - modes[type] = rw; - } - else if (mode & CRYPTO_UNLOCK) - { - if (!modes[type]) - { - errstr = "not locked"; - goto err; - } - - if (modes[type] != rw) - { - errstr = (rw == CRYPTO_READ) ? - "CRYPTO_r_unlock on write lock" : - "CRYPTO_w_unlock on read lock"; - } - - modes[type] = 0; - } - else - { - errstr = "invalid mode"; - goto err; - } - - err: - if (errstr) - { - //how do we pass a context pointer here? - //error("openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d", - // errstr, mode, type, file, line); - } -} - -static unsigned long cryptoIdCallback() -{ -#ifdef __WIN32__ - unsigned long ret = (unsigned long) GetCurrentThreadId(); -#else - unsigned long ret = (unsigned long) pthread_self(); -#endif - return ret; -} - -#endif - - -TcpSocket::TcpSocket(const TcpSocket &other) -{ - init(); - sock = other.sock; - hostname = other.hostname; - portno = other.portno; -} - - -void TcpSocket::error(const char *fmt, ...) -{ - static char buf[256]; - lastError = "TcpSocket err: "; - va_list args; - va_start(args, fmt); - vsnprintf(buf, 255, fmt, args); - va_end(args); - lastError.append(buf); - fprintf(stderr, "%s\n", lastError.c_str()); -} - - -DOMString &TcpSocket::getLastError() -{ - return lastError; -} - - - -static bool tcp_socket_inited = false; - -void TcpSocket::init() -{ - if (!tcp_socket_inited) - { -#ifdef __WIN32__ - WORD wVersionRequested = MAKEWORD( 2, 2 ); - WSADATA wsaData; - WSAStartup( wVersionRequested, &wsaData ); -#endif -#ifdef HAVE_SSL - if (libssl_is_present) - { - sslStream = NULL; - sslContext = NULL; - CRYPTO_set_locking_callback(cryptoLockCallback); - CRYPTO_set_id_callback(cryptoIdCallback); - SSL_library_init(); - SSL_load_error_strings(); - } -#endif - tcp_socket_inited = true; - } - sock = -1; - connected = false; - hostname = ""; - portno = -1; - sslEnabled = false; - receiveTimeout = 0; -} - -TcpSocket::~TcpSocket() -{ - disconnect(); -} - -bool TcpSocket::isConnected() -{ - if (!connected || sock < 0) - return false; - return true; -} - -bool TcpSocket::getHaveSSL() -{ -#ifdef HAVE_SSL - if (libssl_is_present) - { - return true; - } else { - return false; - } -#else - return false; -#endif -} - -void TcpSocket::enableSSL(bool val) -{ - sslEnabled = val; -} - -bool TcpSocket::getEnableSSL() -{ - return sslEnabled; -} - - - -bool TcpSocket::connect(const std::string &hostnameArg, int portnoArg) -{ - hostname = hostnameArg; - portno = portnoArg; - return connect(); -} - - - -#ifdef HAVE_SSL -/* -static int password_cb(char *buf, int bufLen, int rwflag, void *userdata) -{ - char *password = "password"; - if (bufLen < (int)(strlen(password)+1)) - return 0; - - strcpy(buf,password); - int ret = strlen(password); - return ret; -} - -static void infoCallback(const SSL *ssl, int where, int ret) -{ - switch (where) - { - case SSL_CB_ALERT: - { - printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret)); - break; - } - default: - { - printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl)); - break; - } - } -} -*/ -#endif - - -bool TcpSocket::startTls() -{ -#ifndef HAVE_SSL - error("SSL starttls() error: client not compiled with SSL enabled"); - return false; -#else /*HAVE_SSL*/ - if (!libssl_is_present) - { - error("SSL starttls() error: the correct version of libssl was not found"); - return false; - } - - sslStream = NULL; - sslContext = NULL; - - //SSL_METHOD *meth = SSLv23_method(); - //SSL_METHOD *meth = SSLv3_client_method(); - SSL_METHOD *meth = TLSv1_client_method(); - sslContext = SSL_CTX_new(meth); - //SSL_CTX_set_info_callback(sslContext, infoCallback); - - /** - * For now, let's accept all connections. Ignore this - * block of code - * - char *keyFile = "client.pem"; - char *caList = "root.pem"; - //# Load our keys and certificates - if (!(SSL_CTX_use_certificate_chain_file(sslContext, keyFile))) - { - fprintf(stderr, "Can't read certificate file\n"); - disconnect(); - return false; - } - - SSL_CTX_set_default_passwd_cb(sslContext, password_cb); - - if (!(SSL_CTX_use_PrivateKey_file(sslContext, keyFile, SSL_FILETYPE_PEM))) - { - fprintf(stderr, "Can't read key file\n"); - disconnect(); - return false; - } - - //## Load the CAs we trust - if (!(SSL_CTX_load_verify_locations(sslContext, caList, 0))) - { - fprintf(stderr, "Can't read CA list\n"); - disconnect(); - return false; - } - */ - - /* Connect the SSL socket */ - sslStream = SSL_new(sslContext); - SSL_set_fd(sslStream, sock); - - int ret = SSL_connect(sslStream); - if (ret == 0) - { - error("SSL connection not successful"); - disconnect(); - return false; - } - else if (ret < 0) - { - int err = SSL_get_error(sslStream, ret); - error("SSL connect error %d", err); - disconnect(); - return false; - } - - sslEnabled = true; - return true; -#endif /* HAVE_SSL */ -} - - -bool TcpSocket::connect() -{ - if (hostname.size()<1) - { - error("open: null hostname"); - return false; - } - - if (portno<1) - { - error("open: bad port number"); - return false; - } - - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) - { - error("open: error creating socket"); - return false; - } - - char *c_hostname = (char *)hostname.c_str(); - struct hostent *server = gethostbyname(c_hostname); - if (!server) - { - error("open: could not locate host '%s'", c_hostname); - return false; - } - - struct sockaddr_in serv_addr; - mybzero((char *) &serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - mybcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, - server->h_length); - serv_addr.sin_port = htons(portno); - - int ret = ::connect(sock, (const sockaddr *)&serv_addr, sizeof(serv_addr)); - if (ret < 0) - { - error("open: could not connect to host '%s'", c_hostname); - return false; - } - - if (sslEnabled) - { - if (!startTls()) - return false; - } - connected = true; - return true; -} - -bool TcpSocket::disconnect() -{ - bool ret = true; - connected = false; -#ifdef HAVE_SSL - if (libssl_is_present) - { - if (sslEnabled) - { - if (sslStream) - { - int r = SSL_shutdown(sslStream); - switch(r) - { - case 1: - break; /* Success */ - case 0: - case -1: - default: - error("Shutdown failed"); - ret = false; - } - SSL_free(sslStream); - } - if (sslContext) - SSL_CTX_free(sslContext); - } - sslStream = NULL; - sslContext = NULL; - } -#endif /*HAVE_SSL*/ - -#ifdef __WIN32__ - closesocket(sock); -#else - ::close(sock); -#endif - sock = -1; - sslEnabled = false; - - return ret; -} - - - -bool TcpSocket::setReceiveTimeout(unsigned long millis) -{ - receiveTimeout = millis; - return true; -} - -/** - * For normal sockets, return the number of bytes waiting to be received. - * For SSL, just return >0 when something is ready to be read. - */ -long TcpSocket::available() -{ - if (!isConnected()) - return -1; - - long count = 0; -#ifdef __WIN32__ - if (ioctlsocket(sock, FIONREAD, (unsigned long *)&count) != 0) - return -1; -#else - if (ioctl(sock, FIONREAD, &count) != 0) - return -1; -#endif - if (count<=0 && sslEnabled) - { -#ifdef HAVE_SSL - if (libssl_is_present) - { - return SSL_pending(sslStream); - } -#endif - } - return count; -} - - - -bool TcpSocket::write(int ch) -{ - if (!isConnected()) - { - error("write: socket closed"); - return false; - } - unsigned char c = (unsigned char)ch; - - if (sslEnabled) - { -#ifdef HAVE_SSL - if (libssl_is_present) - { - int r = SSL_write(sslStream, &c, 1); - if (r<=0) - { - switch(SSL_get_error(sslStream, r)) - { - default: - error("SSL write problem"); - return -1; - } - } - } -#endif - } - else - { - if (send(sock, (const char *)&c, 1, 0) < 0) - //if (send(sock, &c, 1, 0) < 0) - { - error("write: could not send data"); - return false; - } - } - return true; -} - -bool TcpSocket::write(char *str) -{ - if (!isConnected()) - { - error("write(str): socket closed"); - return false; - } - int len = strlen(str); - - if (sslEnabled) - { -#ifdef HAVE_SSL - if (libssl_is_present) - { - int r = SSL_write(sslStream, (unsigned char *)str, len); - if (r<=0) - { - switch(SSL_get_error(sslStream, r)) - { - default: - error("SSL write problem"); - return -1; - } - } - } -#endif - } - else - { - if (send(sock, str, len, 0) < 0) - //if (send(sock, &c, 1, 0) < 0) - { - error("write: could not send data"); - return false; - } - } - return true; -} - -bool TcpSocket::write(const std::string &str) -{ - return write((char *)str.c_str()); -} - -int TcpSocket::read() -{ - if (!isConnected()) - return -1; - - //We'll use this loop for timeouts, so that SSL and plain sockets - //will behave the same way - if (receiveTimeout > 0) - { - unsigned long tim = 0; - while (true) - { - int avail = available(); - if (avail > 0) - break; - if (tim >= receiveTimeout) - return -2; - Thread::sleep(20); - tim += 20; - } - } - - //check again - if (!isConnected()) - return -1; - - unsigned char ch; - if (sslEnabled) - { -#ifdef HAVE_SSL - if (libssl_is_present) - { - if (!sslStream) - return -1; - int r = SSL_read(sslStream, &ch, 1); - unsigned long err = SSL_get_error(sslStream, r); - switch (err) - { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_ZERO_RETURN: - return -1; - case SSL_ERROR_SYSCALL: - error("SSL read problem(syscall) %s", - ERR_error_string(ERR_get_error(), NULL)); - return -1; - default: - error("SSL read problem %s", - ERR_error_string(ERR_get_error(), NULL)); - return -1; - } - } -#endif - } - else - { - if (recv(sock, (char *)&ch, 1, 0) <= 0) - { - error("read: could not receive data"); - disconnect(); - return -1; - } - } - return (int)ch; -} - -std::string TcpSocket::readLine() -{ - std::string ret; - - while (isConnected()) - { - int ch = read(); - if (ch<0) - return ret; - if (ch=='\r' || ch=='\n') - return ret; - ret.push_back((char)ch); - } - - return ret; -} - - - - - - - - - -} //namespace Pedro -//######################################################################## -//# E N D O F F I L E -//######################################################################## - - - - - - - - - - - diff --git a/src/pedro/pedroutil.h b/src/pedro/pedroutil.h deleted file mode 100644 index fde2b16f8..000000000 --- a/src/pedro/pedroutil.h +++ /dev/null @@ -1,545 +0,0 @@ -#ifndef __PEDROUTIL_H__ -#define __PEDROUTIL_H__ -/* - * Support classes for the Pedro mini-XMPP client. - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <stdarg.h> -#include <vector> - -#include <string> - -#include "pedrodom.h" - - -#ifdef HAVE_SSL -#include <openssl/ssl.h> -#include <openssl/err.h> -#endif - - - -namespace Pedro -{ - - - - -//######################################################################## -//######################################################################## -//# B A S E 6 4 -//######################################################################## -//######################################################################## - - -//################# -//# ENCODER -//################# - - -/** - * This class is for Base-64 encoding - */ -class Base64Encoder -{ - -public: - - Base64Encoder() - { - reset(); - } - - virtual ~Base64Encoder() - {} - - virtual void reset() - { - outBuf = 0L; - bitCount = 0; - buf = ""; - } - - virtual void append(int ch); - - virtual void append(char *str); - - virtual void append(unsigned char *str, int len); - - virtual void append(const DOMString &str); - - virtual DOMString finish(); - - static DOMString encode(const DOMString &str); - - -private: - - - unsigned long outBuf; - - int bitCount; - - DOMString buf; - -}; - - - - -//################# -//# DECODER -//################# - -class Base64Decoder -{ -public: - Base64Decoder() - { - reset(); - } - - virtual ~Base64Decoder() - {} - - virtual void reset() - { - inCount = 0; - buf.clear(); - } - - - virtual void append(int ch); - - virtual void append(char *str); - - virtual void append(const DOMString &str); - - std::vector<unsigned char> finish(); - - static std::vector<unsigned char> decode(const DOMString &str); - - static DOMString decodeToString(const DOMString &str); - -private: - - int inBytes[4]; - int inCount; - std::vector<unsigned char> buf; -}; - - - - -//######################################################################## -//######################################################################## -//### S H A 1 H A S H I N G -//######################################################################## -//######################################################################## - -/** - * This class performs a slow SHA1 hash on a stream of input data. - */ -class Sha1 -{ -public: - - /** - * Constructor - */ - Sha1() - { init(); } - - /** - * - */ - virtual ~Sha1() - { init(); } - - - /** - * Static convenience method. This would be the most commonly used - * version; - * @parm digest points to a bufer of 20 unsigned chars - */ - static void hash(unsigned char *dataIn, int len, unsigned char *digest); - - /** - * Static convenience method. This will fill a string with the hex - * coded string. - */ - static DOMString hashHex(unsigned char *dataIn, int len); - - /** - * Static convenience method. - */ - static DOMString hashHex(const DOMString &str); - - /** - * Initialize the context (also zeroizes contents) - */ - virtual void init(); - - /** - * Append a single character - */ - virtual void append(unsigned char ch); - - /** - * Append a data buffer - */ - virtual void append(unsigned char *dataIn, int len); - - /** - * Append a String - */ - virtual void append(const DOMString &str); - - /** - * - * @parm digest points to a bufer of 20 unsigned chars - */ - virtual void finish(unsigned char *digest); - - -private: - - void transform(); - - unsigned long hashBuf[5]; - unsigned long inBuf[80]; - unsigned long nrBytesHi; - unsigned long nrBytesLo; - int longNr; - int byteNr; - unsigned long inb[4]; - -}; - - - - - -//######################################################################## -//######################################################################## -//### M D 5 H A S H I N G -//######################################################################## -//######################################################################## - - -/** - * This is a utility version of a simple MD5 hash algorithm. This is - * neither efficient nor fast. It is intended to be a small simple utility - * for hashing small amounts of data in a non-time-critical place. - * - * Note that this is a rewrite whose purpose is to remove any - * machine dependencies. - */ -class Md5 -{ -public: - - /** - * Constructor - */ - Md5() - { init(); } - - /** - * Destructor - */ - virtual ~Md5() - {} - - /** - * Static convenience method. - * @parm digest points to an buffer of 16 unsigned chars - */ - static void hash(unsigned char *dataIn, - unsigned long len, unsigned char *digest); - - /** - * Static convenience method. - * Hash a byte array of a given length - */ - static DOMString hashHex(unsigned char *dataIn, unsigned long len); - - /** - * Static convenience method. - * Hash a String - */ - static DOMString hashHex(const DOMString &str); - - /** - * Initialize the context (also zeroizes contents) - */ - virtual void init(); - - /* - * Update with one character - */ - virtual void append(unsigned char ch); - - /** - * Update with a byte buffer of a given length - */ - virtual void append(unsigned char *dataIn, unsigned long len); - - /** - * Update with a string - */ - virtual void append(const DOMString &str); - - /** - * Finalize and output the hash. - * @parm digest points to an buffer of 16 unsigned chars - */ - virtual void finish(unsigned char *digest); - - - /** - * Same as above , but hex to an output String - */ - virtual DOMString finishHex(); - -private: - - void transform(); - - unsigned long hashBuf[4]; - unsigned long inBuf[16]; - unsigned long nrBytesHi; - unsigned long nrBytesLo; - - unsigned long inb[4]; // Buffer for input bytes as longs - int byteNr; // which byte in long - int longNr; // which long in 8 long segment - -}; - - - - - -//######################################################################## -//######################################################################## -//### T H R E A D -//######################################################################## -//######################################################################## - - - -/** - * This is the interface for a delegate class which can - * be run by a Thread. - * Thread thread(runnable); - * thread.start(); - */ -class Runnable -{ -public: - - Runnable() - {} - virtual ~Runnable() - {} - - /** - * The method of a delegate class which can - * be run by a Thread. Thread is completed when this - * method is done. - */ - virtual void run() = 0; - -}; - - - -/** - * A simple wrapper of native threads in a portable class. - * It can be used either to execute its own run() method, or - * delegate to a Runnable class's run() method. - */ -class Thread -{ -public: - - /** - * Create a thread which will execute its own run() method. - */ - Thread() - { runnable = NULL ; started = false; } - - /** - * Create a thread which will run a Runnable class's run() method. - */ - Thread(const Runnable &runner) - { runnable = (Runnable *)&runner; started = false; } - - /** - * This does not kill a spawned thread. - */ - virtual ~Thread() - {} - - /** - * Static method to pause the current thread for a given - * number of milliseconds. - */ - static void sleep(unsigned long millis); - - /** - * This method will be executed if the Thread was created with - * no delegated Runnable class. The thread is completed when - * the method is done. - */ - virtual void run() - {} - - /** - * Starts the thread. - */ - virtual void start(); - - /** - * Calls either this class's run() method, or that of a Runnable. - * A user would normally not call this directly. - */ - virtual void execute() - { - started = true; - if (runnable) - runnable->run(); - else - run(); - } - -private: - - Runnable *runnable; - - bool started; - -}; - - - - - - -//######################################################################## -//######################################################################## -//### S O C K E T -//######################################################################## -//######################################################################## - - - -/** - * A socket wrapper that provides cross-platform capability, plus SSL - */ -class TcpSocket -{ -public: - - TcpSocket(); - - TcpSocket(const std::string &hostname, int port); - - TcpSocket(const char *hostname, int port); - - TcpSocket(const TcpSocket &other); - - virtual ~TcpSocket(); - - void error(const char *fmt, ...); - - DOMString &getLastError(); - - bool isConnected(); - - void enableSSL(bool val); - - bool getEnableSSL(); - - bool getHaveSSL(); - - bool connect(const std::string &hostname, int portno); - - bool connect(const char *hostname, int portno); - - bool startTls(); - - bool connect(); - - bool disconnect(); - - bool setReceiveTimeout(unsigned long millis); - - long available(); - - bool write(int ch); - - bool write(char *str); - - bool write(const std::string &str); - - int read(); - - std::string readLine(); - -private: - void init(); - - DOMString lastError; - - std::string hostname; - int portno; - int sock; - bool connected; - - bool sslEnabled; - - unsigned long receiveTimeout; - - -#ifdef HAVE_SSL - SSL_CTX *sslContext; - SSL *sslStream; -#endif - -}; - - - - - - -} //namespace Pedro - -#endif /* __PEDROUTIL_H__ */ - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/pedroxmpp.cpp b/src/pedro/pedroxmpp.cpp deleted file mode 100644 index 3baeeee06..000000000 --- a/src/pedro/pedroxmpp.cpp +++ /dev/null @@ -1,3649 +0,0 @@ -/* - * Implementation the Pedro mini-XMPP client - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <algorithm> -#include <cstdio> -#include <stdarg.h> -#include <stdlib.h> - -#include <sys/stat.h> - -#include <time.h> - -#include "pedroxmpp.h" -#include "pedrodom.h" -#include "pedroutil.h" - -#include <map> - - - -namespace Pedro -{ - - -//######################################################################## -//######################################################################## -//# X M P P E V E N T -//######################################################################## -//######################################################################## - - -XmppEvent::XmppEvent(int type) -{ - eventType = type; - presence = false; - dom = NULL; -} - -XmppEvent::XmppEvent(const XmppEvent &other) -{ - assign(other); -} - -XmppEvent &XmppEvent::operator=(const XmppEvent &other) -{ - assign(other); - return (*this); -} - -XmppEvent::~XmppEvent() -{ - if (dom) - delete dom; -} - -void XmppEvent::assign(const XmppEvent &other) -{ - eventType = other.eventType; - presence = other.presence; - status = other.status; - show = other.show; - to = other.to; - from = other.from; - group = other.group; - data = other.data; - fileName = other.fileName; - fileDesc = other.fileDesc; - fileSize = other.fileSize; - fileHash = other.fileHash; - setDOM(other.dom); -} - -int XmppEvent::getType() const -{ - return eventType; -} - -DOMString XmppEvent::getIqId() const -{ - return iqId; -} - -void XmppEvent::setIqId(const DOMString &val) -{ - iqId = val; -} - -DOMString XmppEvent::getStreamId() const -{ - return streamId; -} - -void XmppEvent::setStreamId(const DOMString &val) -{ - streamId = val; -} - -bool XmppEvent::getPresence() const -{ - return presence; -} - -void XmppEvent::setPresence(bool val) -{ - presence = val; -} - -DOMString XmppEvent::getShow() const -{ - return show; -} - -void XmppEvent::setShow(const DOMString &val) -{ - show = val; -} - -DOMString XmppEvent::getStatus() const -{ - return status; -} - -void XmppEvent::setStatus(const DOMString &val) -{ - status = val; -} - -DOMString XmppEvent::getTo() const -{ - return to; -} - -void XmppEvent::setTo(const DOMString &val) -{ - to = val; -} - -DOMString XmppEvent::getFrom() const -{ - return from; -} - -void XmppEvent::setFrom(const DOMString &val) -{ - from = val; -} - -DOMString XmppEvent::getGroup() const -{ - return group; -} - -void XmppEvent::setGroup(const DOMString &val) -{ - group = val; -} - -DOMString XmppEvent::getData() const -{ - return data; -} - -void XmppEvent::setData(const DOMString &val) -{ - data = val; -} - -DOMString XmppEvent::getFileName() const -{ - return fileName; -} - -void XmppEvent::setFileName(const DOMString &val) -{ - fileName = val; -} - -DOMString XmppEvent::getFileDesc() const -{ - return fileDesc; -} - -void XmppEvent::setFileDesc(const DOMString &val) -{ - fileDesc = val; -} - -long XmppEvent::getFileSize() const -{ - return fileSize; -} - -void XmppEvent::setFileSize(long val) -{ - fileSize = val; -} - -DOMString XmppEvent::getFileHash() const -{ - return fileHash; -} - -void XmppEvent::setFileHash(const DOMString &val) -{ - fileHash = val; -} - -Element *XmppEvent::getDOM() const -{ - return dom; -} - -void XmppEvent::setDOM(const Element *val) -{ - if (!val) - dom = NULL; - else - dom = ((Element *)val)->clone(); -} - - -std::vector<XmppUser> XmppEvent::getUserList() const -{ - return userList; -} - -void XmppEvent::setUserList(const std::vector<XmppUser> &val) -{ - userList = val; -} - - - - - - - - - -//######################################################################## -//######################################################################## -//# X M P P E V E N T T A R G E T -//######################################################################## -//######################################################################## - - -//########################### -//# CONSTRUCTORS -//########################### - -XmppEventTarget::XmppEventTarget() -{ - eventQueueEnabled = false; -} - - -XmppEventTarget::XmppEventTarget(const XmppEventTarget &other) -{ - listeners = other.listeners; - eventQueueEnabled = other.eventQueueEnabled; -} - -XmppEventTarget::~XmppEventTarget() -{ -} - - -//########################### -//# M E S S A G E S -//########################### - -/** - * Print a printf()-like formatted error message - */ -void XmppEventTarget::error(const char *fmt, ...) -{ - va_list args; - va_start(args,fmt); - gchar * buffer = g_strdup_vprintf(fmt, args); - va_end(args) ; - fprintf(stderr, "Error:%s\n", buffer); - XmppEvent evt(XmppEvent::EVENT_ERROR); - evt.setData(buffer); - dispatchXmppEvent(evt); - g_free(buffer); -} - - - -/** - * Print a printf()-like formatted trace message - */ -void XmppEventTarget::status(const char *fmt, ...) -{ - va_list args; - va_start(args,fmt); - gchar * buffer = g_strdup_vprintf(fmt, args); - va_end(args) ; - //printf("Status:%s\n", buffer); - XmppEvent evt(XmppEvent::EVENT_STATUS); - evt.setData(buffer); - dispatchXmppEvent(evt); - g_free(buffer); -} - - - -//########################### -//# L I S T E N E R S -//########################### - -void XmppEventTarget::dispatchXmppEvent(const XmppEvent &event) -{ - std::vector<XmppEventListener *>::iterator iter; - for (iter = listeners.begin(); iter != listeners.end() ; iter++) - (*iter)->processXmppEvent(event); - if (eventQueueEnabled) - eventQueue.push_back(event); -} - -void XmppEventTarget::addXmppEventListener(const XmppEventListener &listener) -{ - XmppEventListener *lsnr = (XmppEventListener *)&listener; - std::vector<XmppEventListener *>::iterator iter; - for (iter = listeners.begin(); iter != listeners.end() ; iter++) - if (*iter == lsnr) - return; - listeners.push_back(lsnr); -} - -void XmppEventTarget::removeXmppEventListener(const XmppEventListener &listener) -{ - XmppEventListener *lsnr = (XmppEventListener *)&listener; - std::vector<XmppEventListener *>::iterator iter; - for (iter = listeners.begin(); iter != listeners.end() ; iter++) - if (*iter == lsnr) - listeners.erase(iter); -} - -void XmppEventTarget::clearXmppEventListeners() -{ - listeners.clear(); -} - - -//########################### -//# E V E N T Q U E U E -//########################### - -void XmppEventTarget::eventQueueEnable(bool val) -{ - eventQueueEnabled = val; - if (!eventQueueEnabled) - eventQueue.clear(); -} - -int XmppEventTarget::eventQueueAvailable() -{ - return eventQueue.size(); -} - -XmppEvent XmppEventTarget::eventQueuePop() -{ - if (!eventQueueEnabled || eventQueue.size()<1) - { - XmppEvent dummy(XmppEvent::EVENT_NONE); - return dummy; - } - XmppEvent event = *(eventQueue.begin()); - eventQueue.erase(eventQueue.begin()); - return event; -} - - - - - -//######################################################################## -//######################################################################## -//# X M P P S T R E A M -//######################################################################## -//######################################################################## - - -/** - * - */ -class XmppStream -{ -public: - - /** - * - */ - XmppStream() - { reset(); } - - /** - * - */ - XmppStream(const XmppStream &other) - { assign(other); } - - /** - * - */ - XmppStream &operator=(const XmppStream &other) - { assign(other); return *this; } - - /** - * - */ - virtual ~XmppStream() - {} - - /** - * - */ - virtual void reset() - { - state = XmppClient::STREAM_AVAILABLE; - seqNr = 0; - messageId = ""; - sourceId = ""; - data.clear(); - } - - /** - * - */ - virtual int getState() - { return state; } - - /** - * - */ - virtual void setState(int val) - { state = val; } - - /** - * - */ - virtual DOMString getStreamId() - { return streamId; } - - /** - * - */ - void setStreamId(const DOMString &val) - { streamId = val; } - - /** - * - */ - virtual DOMString getMessageId() - { return messageId; } - - /** - * - */ - void setMessageId(const DOMString &val) - { messageId = val; } - - /** - * - */ - virtual int getSeqNr() - { - seqNr++; - if (seqNr >= 65535) - seqNr = 0; - return seqNr; - } - - /** - * - */ - virtual DOMString getPeerId() - { return sourceId; } - - /** - * - */ - virtual void setPeerId(const DOMString &val) - { sourceId = val; } - - /** - * - */ - int available() - { return data.size(); } - - /** - * - */ - void receiveData(std::vector<unsigned char> &newData) - { - std::vector<unsigned char>::iterator iter; - for (iter=newData.begin() ; iter!=newData.end() ; iter++) - data.push_back(*iter); - } - - /** - * - */ - std::vector<unsigned char> read() - { - if (state != XmppClient::STREAM_OPEN) - { - std::vector<unsigned char>dummy; - return dummy; - } - std::vector<unsigned char> ret = data; - data.clear(); - return ret; - } - -private: - - void assign(const XmppStream &other) - { - streamId = other.streamId; - messageId = other.messageId; - sourceId = other.sourceId; - state = other.state; - seqNr = other.seqNr; - data = other.data; - } - - - DOMString streamId; - - DOMString messageId; - - DOMString sourceId; - - int state; - - long seqNr; - - std::vector<unsigned char> data; -}; - - - - - - - - - - -//######################################################################## -//######################################################################## -//# X M P P C L I E N T -//######################################################################## -//######################################################################## - -class ReceiverThread : public Runnable -{ -public: - - ReceiverThread(XmppClient &par) : client(par) {} - - virtual ~ReceiverThread() {} - - void run() - { client.receiveAndProcessLoop(); } - -private: - - XmppClient &client; -}; - - - - - -//######################################################################## -//# CONSTRUCTORS -//######################################################################## - -XmppClient::XmppClient() -{ - init(); -} - - -XmppClient::XmppClient(const XmppClient &other) : XmppEventTarget(other) -{ - init(); - assign(other); -} - -void XmppClient::assign(const XmppClient &other) -{ - msgId = other.msgId; - host = other.host; - realm = other.realm; - port = other.port; - username = other.username; - password = other.password; - resource = other.resource; - connected = other.connected; - doRegister = other.doRegister; - groupChats = other.groupChats; - streamPacket = other.streamPacket; -} - - -void XmppClient::init() -{ - sock = new TcpSocket(); - msgId = 0; - connected = false; - doRegister = false; - streamPacket = "message"; - -} - -XmppClient::~XmppClient() -{ - disconnect(); - delete sock; - std::map<DOMString, XmppStream *>::iterator iter; - for (iter = outputStreams.begin(); iter!=outputStreams.end() ; iter++) - delete iter->second; - for (iter = inputStreams.begin(); iter!=inputStreams.end() ; iter++) - delete iter->second; - for (iter = fileSends.begin(); iter!=fileSends.end() ; iter++) - delete iter->second; - groupChatsClear(); -} - - - - - - -//######################################################################## -//# UTILILY -//######################################################################## - -/** - * - */ -bool XmppClient::pause(unsigned long millis) -{ - Thread::sleep(millis); - return true; -} - - -static int strIndex(const DOMString &str, const char *key) -{ - unsigned int p = str.find(key); - if (p == str.npos) - return -1; - return p; -} - - -DOMString XmppClient::toXml(const DOMString &str) -{ - return Parser::encode(str); -} - - - -static DOMString trim(const DOMString &str) -{ - unsigned int i; - for (i=0 ; i<str.size() ; i++) - if (!isspace(str[i])) - break; - int start = i; - for (i=str.size() ; i>0 ; i--) - if (!isspace(str[i-1])) - break; - int end = i; - if (start>=end) - return ""; - return str.substr(start, end); -} - - - - - -//######################################################################## -//# VARIABLES (ones that need special handling) -//######################################################################## - -/** - * - */ -DOMString XmppClient::getUsername() -{ - return username; -} - -/** - * - */ -void XmppClient::setUsername(const DOMString &val) -{ - int p = strIndex(val, "@"); - if (p > 0) - { - username = val.substr(0, p); - realm = val.substr(p+1, jid.size()-p-1); - } - else - { - realm = host; - username = val; - } -} - - - - - - - - -//######################################################################## -//# RECEIVING -//######################################################################## - - -DOMString XmppClient::readStanza() -{ - - int openCount = 0; - bool inTag = false; - bool slashSeen = false; - bool trivialTag = false; - bool querySeen = false; - bool inQuote = false; - bool textSeen = false; - DOMString buf; - - - time_t timeout = time((time_t *)0) + 180; - - while (true) - { - int ch = sock->read(); - //printf("%c", ch); fflush(stdout); - if (ch<0) - { - if (ch == -2) //a simple timeout, not an error - { - //Since we are timed out, let's assume that we - //are between chunks of text. Let's reset all states. - //printf("-----#### Timeout\n"); - time_t currentTime = time((time_t *)0); - if (currentTime > timeout) - { - timeout = currentTime + 180; - if (!write("\n")) - { - error("ping send error"); - disconnect(); - return ""; - } - } - continue; - } - else - { - keepGoing = false; - if (!sock->isConnected()) - { - disconnect(); - return ""; - } - else - { - error("socket read error: %s", sock->getLastError().c_str()); - disconnect(); - return ""; - } - } - } - buf.push_back(ch); - if (ch == '<') - { - inTag = true; - slashSeen = false; - querySeen = false; - inQuote = false; - textSeen = false; - trivialTag = false; - } - else if (ch == '>') - { - if (!inTag) //unescaped '>' in pcdata? horror - continue; - inTag = false; - if (!trivialTag && !querySeen) - { - if (slashSeen) - openCount--; - else - openCount++; - } - //printf("# openCount:%d t:%d q:%d\n", - // openCount, trivialTag, querySeen); - //check if we are 'balanced', but not a <?version?> tag - if (openCount <= 0 && !querySeen) - { - break; - } - //we know that this one will be open-ended - if (strIndex(buf, "<stream:stream") >= 0) - { - buf.append("</stream:stream>"); - break; - } - } - else if (ch == '/') - { - if (inTag && !inQuote) - { - slashSeen = true; - if (textSeen) // <tagName/> <--looks like this - trivialTag = true; - } - } - else if (ch == '?') - { - if (inTag && !inQuote) - querySeen = true; - } - else if (ch == '"' || ch == '\'') - { - if (inTag) - inQuote = !inQuote; - } - else - { - if (inTag && !inQuote && !isspace(ch)) - textSeen = true; - } - } - return buf; -} - - - -static bool isGroupChat(Element *root) -{ - if (!root) - return false; - ElementList elems = root->findElements("x"); - for (unsigned int i=0 ; i<elems.size() ; i++) - { - DOMString xmlns = elems[i]->getAttribute("xmlns"); - //printf("### XMLNS ### %s\n", xmlns.c_str()); - if (strIndex(xmlns, "http://jabber.org/protocol/muc") >=0 ) - return true; - } - return false; -} - - - - -static bool parseJid(const DOMString &fullJid, - DOMString &jid, DOMString &resource) -{ - DOMString str = fullJid; - jid.clear(); - resource.clear(); - unsigned int p = str.size(); - unsigned int p2 = str.rfind('/', p); - if (p2 != str.npos) - { - resource = str.substr(p2+1, p-(p2+1)); - str = str.substr(0, p); - p = p2; - } - jid = str.substr(0, p); - printf("fullJid:%s jid:%s rsrc:%s\n", - fullJid.c_str(), jid.c_str(), resource.c_str()); - return true; -} - - - - -bool XmppClient::processMessage(Element *root) -{ - DOMString from = root->getTagAttribute("message", "from"); - DOMString to = root->getTagAttribute("message", "to"); - DOMString type = root->getTagAttribute("message", "type"); - - //####Check for embedded namespaces here - //### FILE TRANSFERS - if (processFileMessage(root)) - return true; - - //### STREAMS - if (processInBandByteStreamMessage(root)) - return true; - - - //#### NORMAL MESSAGES - DOMString subject = root->getTagValue("subject"); - DOMString body = root->getTagValue("body"); - DOMString thread = root->getTagValue("thread"); - //##rfc 3921, para 2.4. ignore if no recognizable info - //if (subject.size() < 1 && thread.size()<1) - // return true; - - if (type == "groupchat") - { - DOMString fromGid; - DOMString fromNick; - parseJid(from, fromGid, fromNick); - //printf("fromGid:%s fromNick:%s\n", - // fromGid.c_str(), fromNick.c_str()); - DOMString toGid; - DOMString toNick; - parseJid(to, toGid, toNick); - //printf("toGid:%s toNick:%s\n", - // toGid.c_str(), toNick.c_str()); - - if (fromNick.size() > 0)//normal group message - { - XmppEvent event(XmppEvent::EVENT_MUC_MESSAGE); - event.setGroup(fromGid); - event.setFrom(fromNick); - event.setData(body); - event.setDOM(root); - dispatchXmppEvent(event); - } - else // from the server itself - { - //note the space before, so it doesnt match 'unlocked' - if (strIndex(body, " locked") >= 0) - { - printf("LOCKED!! ;)\n"); - const char *fmt = - "<iq id='create%d' to='%s' type='set'>" - "<query xmlns='http://jabber.org/protocol/muc#owner'>" - "<x xmlns='jabber:x:data' type='submit'/>" - "</query></iq>\n"; - if (!write(fmt, msgId++, fromGid.c_str())) - return false; - } - } - } - else - { - XmppEvent event(XmppEvent::EVENT_MESSAGE); - event.setFrom(from); - event.setData(body); - event.setDOM(root); - dispatchXmppEvent(event); - } - - return true; -} - - - - -bool XmppClient::processPresence(Element *root) -{ - - DOMString fullJid = root->getTagAttribute("presence", "from"); - DOMString to = root->getTagAttribute("presence", "to"); - DOMString presenceStr = root->getTagAttribute("presence", "type"); - bool presence = true; - if (presenceStr == "unavailable") - presence = false; - DOMString status = root->getTagValue("status"); - DOMString show = root->getTagValue("show"); - - if (isGroupChat(root)) - { - DOMString fromGid; - DOMString fromNick; - parseJid(fullJid, fromGid, fromNick); - //printf("fromGid:%s fromNick:%s\n", - // fromGid.c_str(), fromNick.c_str()); - DOMString item_jid = root->getTagAttribute("item", "jid"); - if (item_jid == jid || item_jid == to) //Me - { - if (presence) - { - groupChatCreate(fromGid); - groupChatUserAdd(fromGid, fromNick, ""); - groupChatUserShow(fromGid, fromNick, "available"); - - XmppEvent event(XmppEvent::EVENT_MUC_JOIN); - event.setGroup(fromGid); - event.setFrom(fromNick); - event.setPresence(presence); - event.setShow(show); - event.setStatus(status); - dispatchXmppEvent(event); - } - else - { - groupChatDelete(fromGid); - groupChatUserDelete(fromGid, fromNick); - - XmppEvent event(XmppEvent::EVENT_MUC_LEAVE); - event.setGroup(fromGid); - event.setFrom(fromNick); - event.setPresence(presence); - event.setShow(show); - event.setStatus(status); - dispatchXmppEvent(event); - } - } - else // someone else - { - if (presence) - { - groupChatUserAdd(fromGid, fromNick, ""); - } - else - groupChatUserDelete(fromGid, fromNick); - groupChatUserShow(fromGid, fromNick, show); - XmppEvent event(XmppEvent::EVENT_MUC_PRESENCE); - event.setGroup(fromGid); - event.setFrom(fromNick); - event.setPresence(presence); - event.setShow(show); - event.setStatus(status); - dispatchXmppEvent(event); - } - } - else - { - DOMString shortJid; - DOMString dummy; - parseJid(fullJid, shortJid, dummy); - rosterShow(shortJid, show); //users in roster do not have resource - - XmppEvent event(XmppEvent::EVENT_PRESENCE); - event.setFrom(fullJid); - event.setPresence(presence); - event.setShow(show); - event.setStatus(status); - dispatchXmppEvent(event); - } - - return true; -} - - - -bool XmppClient::processIq(Element *root) -{ - DOMString from = root->getTagAttribute("iq", "from"); - DOMString id = root->getTagAttribute("iq", "id"); - DOMString type = root->getTagAttribute("iq", "type"); - DOMString xmlns = root->getTagAttribute("query", "xmlns"); - - if (id.size()<1) - return true; - - //Group chat - if (strIndex(xmlns, "http://jabber.org/protocol/muc") >=0 ) - { - printf("results of MUC query\n"); - } - //printf("###IQ xmlns:%s\n", xmlns.c_str()); - - //### FILE TRANSFERS - if (processFileMessage(root)) - return true; - - //### STREAMS - if (processInBandByteStreamMessage(root)) - return true; - - - //###Normal Roster stuff - if (root->getTagAttribute("query", "xmlns") == "jabber:iq:roster") - { - roster.clear(); - ElementList elems = root->findElements("item"); - for (unsigned int i=0 ; i<elems.size() ; i++) - { - Element *item = elems[i]; - DOMString userJid = item->getAttribute("jid"); - DOMString name = item->getAttribute("name"); - DOMString subscription = item->getAttribute("subscription"); - DOMString group = item->getTagValue("group"); - //printf("jid:%s name:%s sub:%s group:%s\n", userJid.c_str(), name.c_str(), - // subscription.c_str(), group.c_str()); - XmppUser user(userJid, name, subscription, group); - roster.push_back(user); - } - XmppEvent event(XmppEvent::XmppEvent::EVENT_ROSTER); - dispatchXmppEvent(event); - } - - else if (id.find("regnew") != id.npos) - { - - } - - else if (id.find("regpass") != id.npos) - { - ElementList list = root->findElements("error"); - if (list.size()==0) - { - XmppEvent evt(XmppEvent::EVENT_REGISTRATION_CHANGE_PASS); - evt.setTo(username); - evt.setFrom(host); - dispatchXmppEvent(evt); - return true; - } - - Element *errElem = list[0]; - DOMString errMsg = "Password change error: "; - if (errElem->findElements("bad-request").size()>0) - { - errMsg.append("password change does not contain complete information"); - } - else if (errElem->findElements("not-authorized").size()>0) - { - errMsg.append("server does not consider the channel safe " - "enough to enable a password change"); - } - else if (errElem->findElements("not-allowed").size()>0) - { - errMsg.append("server does not allow password changes"); - } - else if (errElem->findElements("unexpected-request").size()>0) - { - errMsg.append( - "IQ set does not contain a 'from' address because " - "the entity is not registered with the server"); - } - error("%s", errMsg.c_str()); - } - - else if (id.find("regcancel") != id.npos) - { - ElementList list = root->findElements("error"); - if (list.size()==0) - { - XmppEvent evt(XmppEvent::EVENT_REGISTRATION_CANCEL); - evt.setTo(username); - evt.setFrom(host); - dispatchXmppEvent(evt); - return true; - } - - Element *errElem = list[0]; - DOMString errMsg = "Registration cancel error: "; - if (errElem->findElements("bad-request").size()>0) - { - errMsg.append("The <remove/> element was not the only child element of the <query/> element."); - } - else if (errElem->findElements("forbidden").size()>0) - { - errMsg.append("sender does not have sufficient permissions to cancel the registration"); - } - else if (errElem->findElements("not-allowed").size()>0) - { - errMsg.append("not allowed to cancel registrations in-band"); - } - else if (errElem->findElements("registration-required").size()>0) - { - errMsg.append("not previously registered"); - } - else if (errElem->findElements("unexpected-request").size()>0) - { - errMsg.append( - "IQ set does not contain a 'from' address because " - "the entity is not registered with the server"); - } - error("%s", errMsg.c_str()); - } - - return true; -} - - - - - -bool XmppClient::receiveAndProcess() -{ - if (!keepGoing) - return false; - - Parser parser; - - DOMString recvBuf = readStanza(); - recvBuf = trim(recvBuf); - if (recvBuf.size() < 1) - return true; - - //Ugly hack. Apparently the first char can be dropped on timeouts - //if (recvBuf[0] != '<') - // recvBuf.insert(0, "<"); - - status("RECV: %s", recvBuf.c_str()); - Element *root = parser.parse(recvBuf); - if (!root) - { - printf("Bad elem\n"); - return true; - } - - //#### MESSAGE - ElementList elems = root->findElements("message"); - if (elems.size()>0) - { - if (!processMessage(root)) - return false; - } - - //#### PRESENCE - elems = root->findElements("presence"); - if (elems.size()>0) - { - if (!processPresence(root)) - return false; - } - - //#### INFO - elems = root->findElements("iq"); - if (elems.size()>0) - { - if (!processIq(root)) - return false; - } - - delete root; - - return true; -} - - -bool XmppClient::receiveAndProcessLoop() -{ - keepGoing = true; - while (true) - { - if (!keepGoing) - { - status("Abort requested"); - break; - } - if (!receiveAndProcess()) - return false; - } - return true; -} - - - - -//######################################################################## -//# SENDING -//######################################################################## - - -bool XmppClient::write(const char *fmt, ...) -{ - bool rc = true; - va_list args; - va_start(args,fmt); - gchar * buffer = g_strdup_vprintf(fmt,args); - va_end(args) ; - status("SEND: %s", buffer); - if (!sock->write(buffer)) - { - error("Cannot write to socket: %s", sock->getLastError().c_str()); - rc = false; - } - g_free(buffer); - return rc; -} - - - - - - -//######################################################################## -//# R E G I S T R A T I O N -//######################################################################## - -/** - * Perform JEP-077 In-Band Registration. Performed synchronously after SSL, - * before authentication - */ -bool XmppClient::inBandRegistrationNew() -{ - Parser parser; - - const char *fmt = - "<iq type='get' id='regnew%d'>" - "<query xmlns='jabber:iq:register'/>" - "</iq>\n\n"; - if (!write(fmt, msgId++)) - return false; - - DOMString recbuf = readStanza(); - status("RECV reg: %s", recbuf.c_str()); - Element *elem = parser.parse(recbuf); - //elem->print(); - - //# does the entity send the newer "instructions" tag? - ElementList fields = elem->findElements("field"); - std::vector<DOMString> fnames; - for (unsigned int i=0; i<fields.size() ; i++) - { - DOMString fname = fields[i]->getAttribute("var"); - if (fname == "FORM_TYPE") - continue; - fnames.push_back(fname); - status("field name:%s", fname.c_str()); - } - - //Do we have any fields? - if (fnames.size() == 0) - { - //If no fields, maybe the older method was offered - if (elem->findElements("username").size() == 0 || - elem->findElements("password").size() == 0) - { - error("server did not offer registration"); - delete elem; - return false; - } - } - - delete elem; - - fmt = - "<iq type='set' id='regnew%d'>" - "<query xmlns='jabber:iq:register'>" - "<username>%s</username>" - "<password>%s</password>" - "<email/><name/>" - "</query>" - "</iq>\n\n"; - if (!write(fmt, msgId++, toXml(username).c_str(), - toXml(password).c_str() )) - return false; - - - recbuf = readStanza(); - status("RECV reg: %s", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - - ElementList list = elem->findElements("error"); - if (list.size()>0) - { - Element *errElem = list[0]; - DOMString code = errElem->getAttribute("code"); - DOMString errMsg = "Registration error: "; - if (code == "409") - { - errMsg.append("conflict with existing user name"); - } - else if (code == "406") - { - errMsg.append("some registration information was not provided"); - } - error("%s", errMsg.c_str()); - delete elem; - return false; - } - - delete elem; - - XmppEvent evt(XmppEvent::EVENT_REGISTRATION_NEW); - evt.setTo(username); - evt.setFrom(host); - dispatchXmppEvent(evt); - - return true; -} - - -/** - * Perform JEP-077 In-Band Registration. Performed asynchronously, after login. - * See processIq() for response handling. - */ -bool XmppClient::inBandRegistrationChangePassword(const DOMString &newpassword) -{ - Parser parser; - - //# Let's try it form-style to allow the common old/new password thing - const char *fmt = - "<iq type='set' id='regpass%d' to='%s'>" - " <query xmlns='jabber:iq:register'>" - " <x xmlns='jabber:x:data' type='form'>" - " <field type='hidden' var='FORM_TYPE'>" - " <value>jabber:iq:register:changepassword</value>" - " </field>" - " <field type='text-single' var='username'>" - " <value>%s</value>" - " </field>" - " <field type='text-private' var='old_password'>" - " <value>%s</value>" - " </field>" - " <field type='text-private' var='password'>" - " <value>%s</value>" - " </field>" - " </x>" - " </query>" - "</iq>\n\n"; - - if (!write(fmt, msgId++, host.c_str(), - username.c_str(), password.c_str(), newpassword.c_str())) - return false; - - return true; - -} - - -/** - * Perform JEP-077 In-Band Registration. Performed asynchronously, after login. - * See processIq() for response handling. - */ -bool XmppClient::inBandRegistrationCancel() -{ - Parser parser; - - const char *fmt = - "<iq type='set' id='regcancel%d'>" - "<query xmlns='jabber:iq:register'><remove/></query>" - "</iq>\n\n"; - if (!write(fmt, msgId++)) - return false; - - return true; -} - - - - - -//######################################################################## -//# A U T H E N T I C A T E -//######################################################################## - - - -bool XmppClient::iqAuthenticate(const DOMString &streamId) -{ - Parser parser; - - const char *fmt = - "<iq type='get' to='%s' id='auth%d'>" - "<query xmlns='jabber:iq:auth'><username>%s</username></query>" - "</iq>\n"; - if (!write(fmt, realm.c_str(), msgId++, username.c_str())) - return false; - - DOMString recbuf = readStanza(); - status("iq auth recv: '%s'\n", recbuf.c_str()); - Element *elem = parser.parse(recbuf); - //elem->print(); - DOMString iqType = elem->getTagAttribute("iq", "type"); - //printf("##iqType:%s\n", iqType.c_str()); - delete elem; - - if (iqType != "result") - { - error("error:server does not allow login"); - return false; - } - - bool digest = true; - if (digest) - { - //## Digest authentication - DOMString digest = streamId; - digest.append(password); - digest = Sha1::hashHex(digest); - //printf("digest:%s\n", digest.c_str()); - fmt = - "<iq type='set' id='auth%d'>" - "<query xmlns='jabber:iq:auth'>" - "<username>%s</username>" - "<digest>%s</digest>" - "<resource>%s</resource>" - "</query>" - "</iq>\n"; - if (!write(fmt, msgId++, username.c_str(), - digest.c_str(), resource.c_str())) - return false; - } - else - { - - //## Plaintext authentication - fmt = - "<iq type='set' id='auth%d'>" - "<query xmlns='jabber:iq:auth'>" - "<username>%s</username>" - "<password>%s</password>" - "<resource>%s</resource>" - "</query>" - "</iq>\n"; - if (!write(fmt, msgId++, username.c_str(), - password.c_str(), resource.c_str())) - return false; - } - - recbuf = readStanza(); - status("iq auth recv: '%s'\n", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - iqType = elem->getTagAttribute("iq", "type"); - //printf("##iqType:%s\n", iqType.c_str()); - delete elem; - - if (iqType != "result") - { - error("server does not allow login"); - return false; - } - - return true; -} - - -/** - * Parse a sasl challenge to retrieve all of its key=value pairs - */ -static bool saslParse(const DOMString &s, - std::map<DOMString, DOMString> &vals) -{ - - vals.clear(); - - int p = 0; - int siz = s.size(); - - while (p < siz) - { - DOMString key; - DOMString value; - char ch = '\0'; - - //# Parse key - while (p<siz) - { - ch = s[p++]; - if (ch == '=') - break; - key.push_back(ch); - } - - //No value? - if (ch != '=') - break; - - //# Parse value - bool quoted = false; - while (p<siz) - { - ch = s[p++]; - if (ch == '"') - quoted = !quoted; - else if (ch == ',' && !quoted) - break; - else - value.push_back(ch); - } - - //printf("# Key: '%s' Value: '%s'\n", key.c_str(), value.c_str()); - vals[key] = value; - if (ch != ',') - break; - } - - return true; -} - - - -/** - * Attempt suthentication using the MD5 SASL mechanism - */ -bool XmppClient::saslMd5Authenticate() -{ - Parser parser; - const char *fmt = - "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' " - "mechanism='DIGEST-MD5'/>\n"; - if (!write("%s",fmt)) - return false; - - DOMString recbuf = readStanza(); - status("challenge received: '%s'", recbuf.c_str()); - Element *elem = parser.parse(recbuf); - //elem->print(); - DOMString b64challenge = elem->getTagValue("challenge"); - delete elem; - - if (b64challenge.size() < 1) - { - error("login: no SASL challenge offered by server"); - return false; - } - DOMString challenge = Base64Decoder::decodeToString(b64challenge); - status("md5 challenge:'%s'", challenge.c_str()); - - std::map<DOMString, DOMString> attrs; - if (!saslParse(challenge, attrs)) - { - error("login: error parsing SASL challenge"); - return false; - } - - DOMString nonce = attrs["nonce"]; - if (nonce.size()==0) - { - error("login: no SASL nonce sent by server"); - return false; - } - - DOMString realm = attrs["realm"]; - if (realm.size()==0) - { - //Apparently this is not a problem - //error("login: no SASL realm sent by server"); - //return false; - } - - status("SASL recv nonce: '%s' realm:'%s'\n", nonce.c_str(), realm.c_str()); - - char idBuf[14]; - snprintf(idBuf, 13, "%dsasl", msgId++); - DOMString cnonceStr = idBuf; - DOMString cnonce = Sha1::hashHex(cnonceStr); - DOMString authzid = username; authzid.append("@"); authzid.append(host); - DOMString digest_uri = "xmpp/"; digest_uri.append(host); - - //## Make A1 - Md5 md5; - md5.append(username); - md5.append(":"); - md5.append(realm); - md5.append(":"); - md5.append(password); - unsigned char a1tmp[16]; - md5.finish(a1tmp); - md5.init(); - md5.append(a1tmp, 16); - md5.append(":"); - md5.append(nonce); - md5.append(":"); - md5.append(cnonce); - //RFC2831 says authzid is optional. Wildfire has trouble with authzid's - //md5.append(":"); - //md5.append(authzid); - md5.append(""); - DOMString a1 = md5.finishHex(); - status("##a1:'%s'", a1.c_str()); - - //# Make A2 - md5.init(); - md5.append("AUTHENTICATE:"); - md5.append(digest_uri); - DOMString a2 = md5.finishHex(); - status("##a2:'%s'", a2.c_str()); - - //# Now make the response - md5.init(); - md5.append(a1); - md5.append(":"); - md5.append(nonce); - md5.append(":"); - md5.append("00000001");//nc - md5.append(":"); - md5.append(cnonce); - md5.append(":"); - md5.append("auth");//qop - md5.append(":"); - md5.append(a2); - DOMString response = md5.finishHex(); - - DOMString resp; - resp.append("username=\""); resp.append(username); resp.append("\","); - resp.append("realm=\""); resp.append(realm); resp.append("\","); - resp.append("nonce=\""); resp.append(nonce); resp.append("\","); - resp.append("cnonce=\""); resp.append(cnonce); resp.append("\","); - resp.append("nc=00000001,qop=auth,"); - resp.append("digest-uri=\""); resp.append(digest_uri); resp.append("\"," ); - //resp.append("authzid=\""); resp.append(authzid); resp.append("\","); - resp.append("response="); resp.append(response); resp.append(","); - resp.append("charset=utf-8"); - status("sending response:'%s'", resp.c_str()); - resp = Base64Encoder::encode(resp); - status("base64 response:'%s'", resp.c_str()); - fmt = - "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>\n"; - if (!write(fmt, resp.c_str())) - return false; - - recbuf = readStanza(); - status("server says: '%s'", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - //# Success or failure already? - if (elem->findElements("success").size() > 0) - { - delete elem; - return true; - } - else - { - ElementList list = elem->findElements("failure"); - if (list.size() > 0) - { - DOMString errmsg = ""; - Element *errmsgElem = list[0]->getFirstChild(); - if (errmsgElem) - errmsg = errmsgElem->getName(); - error("login: initial md5 authentication failed: %s", errmsg.c_str()); - delete elem; - return false; - } - } - //# Continue for one more SASL cycle - b64challenge = elem->getTagValue("challenge"); - delete elem; - - if (b64challenge.size() < 1) - { - error("login: no second SASL challenge offered by server"); - return false; - } - - challenge = Base64Decoder::decodeToString(b64challenge); - status("md5 challenge: '%s'", challenge.c_str()); - - if (!saslParse(challenge, attrs)) - { - error("login: error parsing SASL challenge"); - return false; - } - - DOMString rspauth = attrs["rspauth"]; - if (rspauth.size()==0) - { - error("login: no SASL respauth sent by server\n"); - return false; - } - - fmt = - "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>\n"; - if (!write("%s",fmt)) - return false; - - recbuf = readStanza(); - status("SASL recv: '%s", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - b64challenge = elem->getTagValue("challenge"); - bool success = (elem->findElements("success").size() > 0); - delete elem; - - return success; -} - - - -/** - * Attempt to authentication using the SASL PLAIN mechanism. This - * is used most commonly my Google Talk. - */ -bool XmppClient::saslPlainAuthenticate() -{ - Parser parser; - - DOMString id = username; - //id.append("@"); - //id.append(host); - Base64Encoder encoder; - encoder.append('\0'); - encoder.append(id); - encoder.append('\0'); - encoder.append(password); - DOMString base64Auth = encoder.finish(); - //printf("authbuf:%s\n", base64Auth.c_str()); - - const char *fmt = - "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' " - "mechanism='PLAIN'>%s</auth>\n"; - if (!write(fmt, base64Auth.c_str())) - return false; - DOMString recbuf = readStanza(); - status("challenge received: '%s'", recbuf.c_str()); - Element *elem = parser.parse(recbuf); - - bool success = (elem->findElements("success").size() > 0); - delete elem; - - return success; -} - - - -/** - * Handshake with SASL, and use one of its offered mechanisms to - * authenticate. - * @param streamId used for iq auth fallback is SASL not supported - */ -bool XmppClient::saslAuthenticate(const DOMString &streamId) -{ - Parser parser; - - DOMString recbuf = readStanza(); - status("RECV: '%s'\n", recbuf.c_str()); - Element *elem = parser.parse(recbuf); - //elem->print(); - - //Check for starttls - bool wantStartTls = false; - if (elem->findElements("starttls").size() > 0) - { - wantStartTls = true; - if (elem->findElements("required").size() > 0) - status("login: STARTTLS required"); - else - status("login: STARTTLS available"); - } - - //# do we want TLS, are we not already running SSL, and can - //# the client actually do an ssl connection? - if (wantStartTls && !sock->getEnableSSL() && sock->getHaveSSL()) - { - delete elem; - const char *fmt = - "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n"; - if (!write("%s",fmt)) - return false; - recbuf = readStanza(); - status("RECV: '%s'\n", recbuf.c_str()); - elem = parser.parse(recbuf); - if (elem->getTagAttribute("proceed", "xmlns").size()<1) - { - error("Server rejected TLS negotiation"); - disconnect(); - return false; - } - delete elem; - if (!sock->startTls()) - { - DOMString tcperr = sock->getLastError(); - error("Could not start TLS: %s", tcperr.c_str()); - disconnect(); - return false; - } - - fmt = - "<stream:stream xmlns='jabber:client' " - "xmlns:stream='http://etherx.jabber.org/streams' " - "to='%s' version='1.0'>\n\n"; - if (!write(fmt, realm.c_str())) - return false; - - recbuf = readStanza(); - status("RECVx: '%s'", recbuf.c_str()); - recbuf.append("</stream:stream>"); - elem = parser.parse(recbuf); - bool success = - (elem->getTagAttribute("stream:stream", "id").size()>0); - if (!success) - { - error("STARTTLS negotiation failed"); - disconnect(); - return false; - } - delete elem; - recbuf = readStanza(); - status("RECV: '%s'\n", recbuf.c_str()); - elem = parser.parse(recbuf); - - XmppEvent event(XmppEvent::EVENT_SSL_STARTED); - dispatchXmppEvent(event); - } - - //register, if user requests - if (doRegister) - { - if (!inBandRegistrationNew()) - return false; - } - - //check for sasl authentication mechanisms - ElementList elems = elem->findElements("mechanism"); - if (elems.size() < 1) - { - status("login: no SASL mechanism offered by server"); - //fall back to iq - if (iqAuthenticate(streamId)) - return true; - return false; - } - bool md5Found = false; - bool plainFound = false; - for (unsigned int i=0 ; i<elems.size() ; i++) - { - DOMString mech = elems[i]->getValue(); - if (mech == "DIGEST-MD5") - { - status("MD5 authentication offered"); - md5Found = true; - } - else if (mech == "PLAIN") - { - status("PLAIN authentication offered"); - plainFound = true; - } - } - delete elem; - - bool success = false; - if (md5Found) - { - success = saslMd5Authenticate(); - } - else if (plainFound) - { - success = saslPlainAuthenticate(); - } - else - { - error("not able to handle sasl authentication mechanisms"); - return false; - } - - if (success) - status("###### SASL authentication success\n"); - else - error("###### SASL authentication failure\n"); - - return success; -} - - - - - - -//######################################################################## -//# CONNECT -//######################################################################## - - -/** - * Check if we are connected, and fail with an error if we are not - */ -bool XmppClient::checkConnect() -{ - if (!connected) - { - XmppEvent evt(XmppEvent::EVENT_ERROR); - evt.setData("Attempted operation while disconnected"); - dispatchXmppEvent(evt); - return false; - } - return true; -} - - - -/** - * Create an XMPP session with a server. This - * is basically the transport layer of XMPP. - */ -bool XmppClient::createSession() -{ - - Parser parser; - if (port==443 || port==5223) - sock->enableSSL(true); - if (!sock->connect(host, port)) - { - error("Cannot connect:%s", sock->getLastError().c_str()); - return false; - } - - if (sock->getEnableSSL()) - { - XmppEvent event(XmppEvent::EVENT_SSL_STARTED); - dispatchXmppEvent(event); - } - - const char *fmt = - "<stream:stream " - "to='%s' " - "xmlns='jabber:client' " - "xmlns:stream='http://etherx.jabber.org/streams' " - "version='1.0'>\n\n"; - if (!write(fmt, realm.c_str())) - return false; - - DOMString recbuf = readStanza(); - status("RECV: '%s'\n", recbuf.c_str()); - recbuf.append("</stream:stream>"); - Element *elem = parser.parse(recbuf); - //elem->print(); - bool useSasl = false; - DOMString streamId = elem->getTagAttribute("stream:stream", "id"); - //printf("### StreamID: %s\n", streamId.c_str()); - DOMString streamVersion = elem->getTagAttribute("stream:stream", "version"); - if (streamVersion == "1.0") - useSasl = true; - - if (useSasl) - { - if (!saslAuthenticate(streamId)) - return false; - - fmt = - "<stream:stream " - "to='%s' " - "xmlns='jabber:client' " - "xmlns:stream='http://etherx.jabber.org/streams' " - "version='1.0'>\n\n"; - - if (!write(fmt, realm.c_str())) - return false; - recbuf = readStanza(); - recbuf.append("</stream:stream>\n"); - //printf("now server says:: '%s'\n", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - delete elem; - - recbuf = readStanza(); - //printf("now server says:: '%s'\n", recbuf.c_str()); - elem = parser.parse(recbuf); - bool hasBind = (elem->findElements("bind").size() > 0); - //elem->print(); - delete elem; - - if (!hasBind) - { - error("no binding provided by server"); - return false; - } - - - } - else // not SASL - { - if (!iqAuthenticate(streamId)) - return false; - } - - - //### Resource binding - fmt = - "<iq type='set' id='bind%d'>" - "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>" - "<resource>%s</resource>" - "</bind></iq>\n"; - if (!write(fmt, msgId++, resource.c_str())) - return false; - - recbuf = readStanza(); - status("bind result: '%s'", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - DOMString bindType = elem->getTagAttribute("iq", "type"); - //printf("##bindType:%s\n", bindType.c_str()); - DOMString givenFullJid = elem->getTagValue("jid"); - delete elem; - - if (bindType != "result") - { - error("no binding with server failed"); - return false; - } - - //The server sent us a JID. We need to listen. - if (givenFullJid.size()>0) - { - DOMString givenJid, givenResource; - parseJid(givenFullJid, givenJid, givenResource); - status("given user: %s realm: %s, rsrc: %s", - givenJid.c_str(), realm.c_str(), givenResource.c_str()); - setResource(givenResource); - } - - - fmt = - "<iq type='set' id='sess%d'>" - "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>" - "</iq>\n"; - if (!write(fmt, msgId++)) - return false; - - recbuf = readStanza(); - status("session received: '%s'", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - DOMString sessionType = elem->getTagAttribute("iq", "type"); - //printf("##sessionType:%s\n", sessionType.c_str()); - delete elem; - - if (sessionType != "result") - { - error("no session provided by server"); - return false; - } - - //printf("########## COOL #########\n"); - //Now that we are bound, we have a valid JID - jid = username; - jid.append("@"); - jid.append(realm); - jid.append("/"); - jid.append(resource); - - //We are now done with the synchronous handshaking. Let's go into - //async mode - - fmt = - "<iq type='get' id='roster%d'><query xmlns='jabber:iq:roster'/></iq>\n"; - if (!write(fmt, msgId++)) - return false; - - fmt = - "<iq type='get' id='discoItems%d' to='%s'>" - "<query xmlns='http://jabber.org/protocol/disco#items'/></iq>\n"; - if (!write(fmt, msgId++, realm.c_str())) - return false; - - fmt = - "<iq type='get' id='discoInfo%d' to='conference.%s'>" - "<query xmlns='http://jabber.org/protocol/disco#info'/></iq>\n"; - if (!write(fmt, msgId++, realm.c_str())) - return false; - - fmt = - "<presence/>\n"; - if (!write("%s",fmt)) - return false; - - /* - recbuf = readStanza(); - status("stream received: '%s'", recbuf.c_str()); - elem = parser.parse(recbuf); - //elem->print(); - delete elem; - */ - - //We are now logged in - status("Connected"); - connected = true; - XmppEvent evt(XmppEvent::EVENT_CONNECTED); - evt.setData(host); - dispatchXmppEvent(evt); - //Thread::sleep(1000000); - - sock->setReceiveTimeout(1000); - ReceiverThread runner(*this); - Thread thread(runner); - thread.start(); - - return true; -} - - - -/** - * Public call to connect - */ -bool XmppClient::connect() -{ - if (!createSession()) - { - disconnect(); - return false; - } - return true; -} - - -/** - * Public call to connect - */ -bool XmppClient::connect(DOMString hostArg, int portArg, - DOMString usernameArg, - DOMString passwordArg, - DOMString resourceArg) -{ - host = hostArg; - port = portArg; - password = passwordArg; - resource = resourceArg; - - //parse this one - setUsername(usernameArg); - - bool ret = connect(); - return ret; -} - - - -/** - * Public call to disconnect - */ -bool XmppClient::disconnect() -{ - if (connected) - { - const char *fmt = - "<presence type='unavailable'/>\n"; - write("%s",fmt); - } - keepGoing = false; - connected = false; - Thread::sleep(2000); //allow receiving thread to quit - sock->disconnect(); - roster.clear(); - groupChatsClear(); - XmppEvent event(XmppEvent::EVENT_DISCONNECTED); - event.setData(host); - dispatchXmppEvent(event); - return true; -} - - - - - -//######################################################################## -//# ROSTER -//######################################################################## - -/** - * Add an XMPP id to your roster - */ -bool XmppClient::rosterAdd(const DOMString &rosterGroup, - const DOMString &otherJid, - const DOMString &name) -{ - if (!checkConnect()) - return false; - const char *fmt = - "<iq type='set' id='roster_%d'>" - "<query xmlns='jabber:iq:roster'>" - "<item jid='%s' name='%s'><group>%s</group></item>" - "</query></iq>\n"; - if (!write(fmt, msgId++, otherJid.c_str(), - name.c_str(), rosterGroup.c_str())) - { - return false; - } - return true; -} - - - -/** - * Delete an XMPP id from your roster. - */ -bool XmppClient::rosterDelete(const DOMString &otherJid) -{ - if (!checkConnect()) - return false; - const char *fmt = - "<iq type='set' id='roster_%d'>" - "<query xmlns='jabber:iq:roster'>" - "<item jid='%s' subscription='remove'><group>%s</group></item>" - "</query></iq>\n"; - if (!write(fmt, msgId++, otherJid.c_str())) - { - return false; - } - return true; -} - - -/** - * Comparison method for sort() call below - */ -static bool xmppRosterCompare(const XmppUser& p1, const XmppUser& p2) -{ - DOMString s1 = p1.group; - DOMString s2 = p2.group; - for (unsigned int len=0 ; len<s1.size() && len<s2.size() ; len++) - { - int comp = tolower(s1[len]) - tolower(s2[len]); - if (comp) - return (comp<0); - } - - s1 = p1.jid; - s2 = p2.jid; - for (unsigned int len=0 ; len<s1.size() && len<s2.size() ; len++) - { - int comp = tolower(s1[len]) - tolower(s2[len]); - if (comp) - return (comp<0); - } - return false; -} - - - -/** - * Sort and return the roster that has just been reported by - * an XmppEvent::EVENT_ROSTER event. - */ -std::vector<XmppUser> XmppClient::getRoster() -{ - std::vector<XmppUser> ros = roster; - std::sort(ros.begin(), ros.end(), xmppRosterCompare); - return ros; -} - - -/** - * - */ -void XmppClient::rosterShow(const DOMString &jid, const DOMString &show) -{ - DOMString theShow = show; - if (theShow == "") - theShow = "available"; - - std::vector<XmppUser>::iterator iter; - for (iter=roster.begin() ; iter != roster.end() ; iter++) - { - if (iter->jid == jid) - iter->show = theShow; - } -} - - - - - - -//######################################################################## -//# CHAT (individual) -//######################################################################## - -/** - * Send a message to an xmpp jid - */ -bool XmppClient::message(const DOMString &user, const DOMString &subj, - const DOMString &msg) -{ - if (!checkConnect()) - return false; - - DOMString xmlSubj = toXml(subj); - DOMString xmlMsg = toXml(msg); - - if (xmlSubj.size() > 0) - { - const char *fmt = - "<message to='%s' from='%s' type='chat'>" - "<subject>%s</subject><body>%s</body></message>\n"; - if (!write(fmt, user.c_str(), jid.c_str(), - xmlSubj.c_str(), xmlMsg.c_str())) - return false; - } - else - { - const char *fmt = - "<message to='%s' from='%s'>" - "<body>%s</body></message>\n"; - if (!write(fmt, user.c_str(), jid.c_str(), xmlMsg.c_str())) - return false; - } - return true; -} - - - -/** - * - */ -bool XmppClient::message(const DOMString &user, const DOMString &msg) -{ - return message(user, "", msg); -} - - - -/** - * - */ -bool XmppClient::presence(const DOMString &presence) -{ - if (!checkConnect()) - return false; - - DOMString xmlPres = toXml(presence); - - const char *fmt = - "<presence><show>%s</show></presence>\n"; - if (!write(fmt, xmlPres.c_str())) - return false; - return true; -} - - - - - - -//######################################################################## -//# GROUP CHAT -//######################################################################## - -/** - * - */ -bool XmppClient::groupChatCreate(const DOMString &groupJid) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - { - if ((*iter)->getGroupJid() == groupJid) - { - //error("Group chat '%s' already exists", groupJid.c_str()); - return false; - } - } - XmppGroupChat *chat = new XmppGroupChat(groupJid); - groupChats.push_back(chat); - return true; -} - - - -/** - * - */ -void XmppClient::groupChatDelete(const DOMString &groupJid) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; ) - { - XmppGroupChat *chat = *iter; - if (chat->getGroupJid() == groupJid) - { - iter = groupChats.erase(iter); - delete chat; - } - else - iter++; - } -} - - - -/** - * - */ -bool XmppClient::groupChatExists(const DOMString &groupJid) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - if ((*iter)->getGroupJid() == groupJid) - return true; - return false; -} - - - -/** - * - */ -void XmppClient::groupChatsClear() -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - delete (*iter); - groupChats.clear(); -} - - - - -/** - * - */ -void XmppClient::groupChatUserAdd(const DOMString &groupJid, - const DOMString &nick, - const DOMString &jid) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - { - if ((*iter)->getGroupJid() == groupJid) - { - (*iter)->userAdd(nick, jid); - } - } -} - - - -/** - * - */ -void XmppClient::groupChatUserShow(const DOMString &groupJid, - const DOMString &nick, - const DOMString &show) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - { - if ((*iter)->getGroupJid() == groupJid) - { - (*iter)->userShow(nick, show); - } - } -} - - - - -/** - * - */ -void XmppClient::groupChatUserDelete(const DOMString &groupJid, - const DOMString &nick) -{ - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - { - if ((*iter)->getGroupJid() == groupJid) - { - (*iter)->userDelete(nick); - } - } -} - - - -/** - * Comparison method for the sort() below - */ -static bool xmppUserCompare(const XmppUser& p1, const XmppUser& p2) -{ - DOMString s1 = p1.nick; - DOMString s2 = p2.nick; - int comp = 0; - for (unsigned int len=0 ; len<s1.size() && len<s2.size() ; len++) - { - comp = tolower(s1[len]) - tolower(s2[len]); - if (comp) - break; - } - return (comp<0); -} - - - -/** - * Return the user list for the named group - */ -std::vector<XmppUser> XmppClient::groupChatGetUserList( - const DOMString &groupJid) -{ - if (!checkConnect()) - { - std::vector<XmppUser> dummy; - return dummy; - } - - std::vector<XmppGroupChat *>::iterator iter; - for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) - { - if ((*iter)->getGroupJid() == groupJid ) - { - std::vector<XmppUser> uList = (*iter)->getUserList(); - std::sort(uList.begin(), uList.end(), xmppUserCompare); - return uList; - } - } - std::vector<XmppUser> dummy; - return dummy; -} - - - - -/** - * Try to join a group - */ -bool XmppClient::groupChatJoin(const DOMString &groupJid, - const DOMString &nick, - const DOMString &/*pass*/) -{ - if (!checkConnect()) - return false; - - DOMString user = nick; - if (user.size()<1) - user = username; - - const char *fmt = - "<presence to='%s/%s'>" - "<x xmlns='http://jabber.org/protocol/muc'/></presence>\n"; - if (!write(fmt, groupJid.c_str(), user.c_str())) - return false; - return true; -} - - - - -/** - * Leave a group - */ -bool XmppClient::groupChatLeave(const DOMString &groupJid, - const DOMString &nick) -{ - if (!checkConnect()) - return false; - - DOMString user = nick; - if (user.size()<1) - user = username; - - const char *fmt = - "<presence to='%s/%s' type='unavailable'>" - "<x xmlns='http://jabber.org/protocol/muc'/></presence>\n"; - if (!write(fmt, groupJid.c_str(), user.c_str())) - return false; - return true; -} - - - - -/** - * Send a message to a group - */ -bool XmppClient::groupChatMessage(const DOMString &groupJid, - const DOMString &msg) -{ - if (!checkConnect()) - { - return false; - } - - DOMString xmlMsg = toXml(msg); - - const char *fmt = - "<message from='%s' to='%s' type='groupchat'>" - "<body>%s</body></message>\n"; - if (!write(fmt, jid.c_str(), groupJid.c_str(), xmlMsg.c_str())) - return false; - /* - const char *fmt = - "<message to='%s' type='groupchat'>" - "<body>%s</body></message>\n"; - if (!write(fmt, groupJid.c_str(), xmlMsg.c_str())) - return false; - */ - return true; -} - - - - -/** - * Send a message to an individual in a group - */ -bool XmppClient::groupChatPrivateMessage(const DOMString &groupJid, - const DOMString &toNick, - const DOMString &msg) -{ - if (!checkConnect()) - return false; - - DOMString xmlMsg = toXml(msg); - - /* - const char *fmt = - "<message from='%s' to='%s/%s' type='chat'>" - "<body>%s</body></message>\n"; - if (!write(fmt, jid.c_str(), groupJid.c_str(), - toNick.c_str(), xmlMsg.c_str())) - return false; - */ - const char *fmt = - "<message to='%s/%s' type='chat'>" - "<body>%s</body></message>\n"; - if (!write(fmt, groupJid.c_str(), - toNick.c_str(), xmlMsg.c_str())) - return false; - return true; -} - - - - -/** - * Change your presence within a group - */ -bool XmppClient::groupChatPresence(const DOMString &groupJid, - const DOMString &myNick, - const DOMString &presence) -{ - if (!checkConnect()) - return false; - - DOMString user = myNick; - if (user.size()<1) - user = username; - - DOMString xmlPresence = toXml(presence); - - const char *fmt = - "<presence to='%s/%s' type='%s'>" - "<x xmlns='http://jabber.org/protocol/muc'/></presence>\n"; - if (!write(fmt, groupJid.c_str(), - user.c_str(), xmlPresence.c_str())) - return true; - return true; -} - - - - - -//######################################################################## -//# S T R E A M S -//######################################################################## - - -bool XmppClient::processInBandByteStreamMessage(Element *root) -{ - DOMString from = root->getAttribute("from"); - DOMString id = root->getAttribute("id"); - DOMString type = root->getAttribute("type"); - - //### Incoming stream requests - //Input streams are id's by stream id - DOMString ibbNamespace = "http://jabber.org/protocol/ibb"; - - if (root->getTagAttribute("open", "xmlns") == ibbNamespace) - { - DOMString streamId = root->getTagAttribute("open", "sid"); - XmppEvent event(XmppEvent::XmppEvent::EVENT_STREAM_RECEIVE_INIT); - dispatchXmppEvent(event); - std::map<DOMString, XmppStream *>::iterator iter = - inputStreams.find(streamId); - if (iter != inputStreams.end()) - { - XmppStream *ins = iter->second; - ins->setState(STREAM_OPENING); - ins->setMessageId(id); - return true; - } - return true; - } - - else if (root->getTagAttribute("close", "xmlns") == ibbNamespace) - { - XmppEvent event(XmppEvent::XmppEvent::EVENT_STREAM_RECEIVE_CLOSE); - dispatchXmppEvent(event); - DOMString streamId = root->getTagAttribute("close", "sid"); - std::map<DOMString, XmppStream *>::iterator iter = - inputStreams.find(streamId); - if (iter != inputStreams.end()) - { - XmppStream *ins = iter->second; - if (from == ins->getPeerId()) - { - ins->setState(STREAM_CLOSING); - ins->setMessageId(id); - return true; - } - } - return true; - } - - else if (root->getTagAttribute("data", "xmlns") == ibbNamespace) - { - DOMString streamId = root->getTagAttribute("data", "sid"); - std::map<DOMString, XmppStream *>::iterator iter = - inputStreams.find(streamId); - if (iter != inputStreams.end()) - { - XmppStream *ins = iter->second; - if (ins->getState() != STREAM_OPEN) - { - XmppEvent event(XmppEvent::EVENT_ERROR); - event.setFrom(from); - event.setData("received unrequested stream data"); - dispatchXmppEvent(event); - return true; - } - DOMString data = root->getTagValue("data"); - std::vector<unsigned char>binData = - Base64Decoder::decode(data); - ins->receiveData(binData); - } - } - - //### Responses to outgoing requests - //Output streams are id's by message id - std::map<DOMString, XmppStream *>::iterator iter = - outputStreams.find(id); - if (iter != outputStreams.end()) - { - XmppStream *outs = iter->second; - if (type == "error") - { - outs->setState(STREAM_ERROR); - return true; - } - else if (type == "result") - { - if (outs->getState() == STREAM_OPENING) - { - outs->setState(STREAM_OPEN); - } - else if (outs->getState() == STREAM_CLOSING) - { - outs->setState(STREAM_CLOSED); - } - return true; - } - } - - return false; -} - - -/** - * - */ -bool XmppClient::outputStreamOpen(const DOMString &destId, - const DOMString &streamIdArg) -{ - char buf[32]; - snprintf(buf, 31, "inband%d", getMsgId()); - DOMString messageId = buf; - - //Output streams are id's by message id - XmppStream *outs = new XmppStream(); - outputStreams[messageId] = outs; - - outs->setState(STREAM_OPENING); - - DOMString streamId = streamIdArg; - if (streamId.size()<1) - { - snprintf(buf, 31, "stream%d", getMsgId()); - DOMString streamId = buf; - } - outs->setMessageId(messageId); - outs->setStreamId(streamId); - outs->setPeerId(destId); - - - const char *fmt = - "<%s type='set' to='%s' id='%s'>" - "<open sid='%s' block-size='4096'" - " xmlns='http://jabber.org/protocol/ibb'/></%s>\n"; - if (!write(fmt, - streamPacket.c_str(), - destId.c_str(), messageId.c_str(), - streamId.c_str(), - streamPacket.c_str())) - { - outs->reset(); - return -1; - } - - int state = outs->getState(); - for (int tim=0 ; tim<20 ; tim++) - { - if (state == STREAM_OPEN) - break; - else if (state == STREAM_ERROR) - { - printf("ERROR\n"); - outs->reset(); - return false; - } - Thread::sleep(1000); - state = outs->getState(); - } - if (state != STREAM_OPEN) - { - printf("TIMEOUT ERROR\n"); - outs->reset(); - return -1; - } - - return true; -} - -/** - * - */ -bool XmppClient::outputStreamWrite(const DOMString &streamId, - const std::vector<unsigned char> &buf) -{ - std::map<DOMString, XmppStream *>::iterator iter = - outputStreams.find(streamId); - if (iter == outputStreams.end()) - return false; - XmppStream *outs = iter->second; - - unsigned int len = buf.size(); - unsigned int pos = 0; - - while (pos < len) - { - unsigned int pos2 = pos + 1024; - if (pos2>len) - pos2 = len; - - Base64Encoder encoder; - for (unsigned int i=pos ; i<pos2 ; i++) - encoder.append(buf[i]); - DOMString b64data = encoder.finish(); - - - const char *fmt = - "<message to='%s' id='msg%d'>" - "<data xmlns='http://jabber.org/protocol/ibb' sid='%s' seq='%d'>" - "%s" - "</data>" - "<amp xmlns='http://jabber.org/protocol/amp'>" - "<rule condition='deliver-at' value='stored' action='error'/>" - "<rule condition='match-resource' value='exact' action='error'/>" - "</amp>" - "</message>\n"; - if (!write(fmt, - outs->getPeerId().c_str(), - getMsgId(), - outs->getStreamId().c_str(), - outs->getSeqNr(), - b64data.c_str())) - { - outs->reset(); - return false; - } - pause(5000); - - pos = pos2; - } - - return true; -} - -/** - * - */ -bool XmppClient::outputStreamClose(const DOMString &streamId) -{ - std::map<DOMString, XmppStream *>::iterator iter = - outputStreams.find(streamId); - if (iter == outputStreams.end()) - return false; - XmppStream *outs = iter->second; - - char buf[32]; - snprintf(buf, 31, "inband%d", getMsgId()); - DOMString messageId = buf; - outs->setMessageId(messageId); - - outs->setState(STREAM_CLOSING); - const char *fmt = - "<%s type='set' to='%s' id='%s'>" - "<close sid='%s' xmlns='http://jabber.org/protocol/ibb'/></%s>\n"; - if (!write(fmt, - streamPacket.c_str(), - outs->getPeerId().c_str(), - messageId.c_str(), - outs->getStreamId().c_str(), - streamPacket.c_str() - )) - return false; - - int state = outs->getState(); - for (int tim=0 ; tim<20 ; tim++) - { - if (state == STREAM_CLOSED) - break; - else if (state == STREAM_ERROR) - { - printf("ERROR\n"); - outs->reset(); - return false; - } - Thread::sleep(1000); - state = outs->getState(); - } - if (state != STREAM_CLOSED) - { - printf("TIMEOUT ERROR\n"); - outs->reset(); - return false; - } - - delete outs; - outputStreams.erase(streamId); - - return true; -} - - -/** - * - */ -bool XmppClient::inputStreamOpen(const DOMString &fromJid, - const DOMString &streamId, - const DOMString &/*iqId*/) -{ - XmppStream *ins = new XmppStream(); - - inputStreams[streamId] = ins; - ins->reset(); - ins->setPeerId(fromJid); - ins->setState(STREAM_CLOSED); - ins->setStreamId(streamId); - - int state = ins->getState(); - for (int tim=0 ; tim<20 ; tim++) - { - if (state == STREAM_OPENING) - break; - else if (state == STREAM_ERROR) - { - printf("ERROR\n"); - ins->reset(); - return false; - } - Thread::sleep(1000); - state = ins->getState(); - } - if (state != STREAM_OPENING) - { - printf("TIMEOUT ERROR\n"); - ins->reset(); - return false; - } - const char *fmt = - "<%s type='result' to='%s' id='%s'/>\n"; - if (!write(fmt, streamPacket.c_str(), - fromJid.c_str(), ins->getMessageId().c_str())) - { - return false; - } - - ins->setState(STREAM_OPEN); - return true; -} - - - -/** - * - */ -bool XmppClient::inputStreamClose(const DOMString &streamId) -{ - std::map<DOMString, XmppStream *>::iterator iter = - inputStreams.find(streamId); - if (iter == inputStreams.end()) - return false; - XmppStream *ins = iter->second; - - if (ins->getState() == STREAM_CLOSING) - { - const char *fmt = - "<iq type='result' to='%s' id='%s'/>\n"; - if (!write(fmt, ins->getPeerId().c_str(), - ins->getMessageId().c_str())) - { - return false; - } - } - inputStreams.erase(streamId); - delete ins; - - return true; -} - - - - - - -//######################################################################## -//# FILE TRANSFERS -//######################################################################## - - -bool XmppClient::processFileMessage(Element *root) -{ - DOMString siNamespace = "http://jabber.org/protocol/si"; - if (root->getTagAttribute("si", "xmlns") != siNamespace) - return false; - - - Element *mainElement = root->getFirstChild(); - if (!mainElement) - return false; - - DOMString from = mainElement->getAttribute("from"); - DOMString id = mainElement->getAttribute("id"); - DOMString type = mainElement->getAttribute("type"); - - status("received file message from %s", from.c_str()); - - if (type == "set") - { - DOMString streamId = root->getTagAttribute("si", "id"); - DOMString fname = root->getTagAttribute("file", "name"); - DOMString sizeStr = root->getTagAttribute("file", "size"); - DOMString hash = root->getTagAttribute("file", "hash"); - XmppEvent event(XmppEvent::XmppEvent::EVENT_FILE_RECEIVE); - event.setFrom(from); - event.setIqId(id); - event.setStreamId(streamId); - event.setFileName(fname); - event.setFileHash(hash); - event.setFileSize(atol(sizeStr.c_str())); - dispatchXmppEvent(event); - return true; - } - - //##expecting result or error - //file sends id'd by message id's - std::map<DOMString, XmppStream *>::iterator iter = - fileSends.find(id); - if (iter != fileSends.end()) - { - XmppStream *outf = iter->second; - if (from != outf->getPeerId()) - return true; - if (type == "error") - { - outf->setState(STREAM_ERROR); - error("user '%s' rejected file", from.c_str()); - return true; - } - else if (type == "result") - { - if (outf->getState() == STREAM_OPENING) - { - XmppEvent event(XmppEvent::XmppEvent::EVENT_FILE_ACCEPTED); - event.setFrom(from); - dispatchXmppEvent(event); - outf->setState(STREAM_OPEN); - } - else if (outf->getState() == STREAM_CLOSING) - { - outf->setState(STREAM_CLOSED); - } - return true; - } - } - - return true; -} - - - - - - -/** - * - */ -bool XmppClient::fileSend(const DOMString &destJidArg, - const DOMString &offeredNameArg, - const DOMString &fileNameArg, - const DOMString &descriptionArg) -{ - DOMString destJid = destJidArg; - DOMString offeredName = offeredNameArg; - DOMString fileName = fileNameArg; - DOMString description = descriptionArg; - - struct stat finfo; - if (stat(fileName.c_str(), &finfo)<0) - { - error("Cannot stat file '%s' for sending", fileName.c_str()); - return false; - } - long fileLen = finfo.st_size; - if (!fileLen > 1000000) - { - error("'%s' too large", fileName.c_str()); - return false; - } - if (!S_ISREG(finfo.st_mode)) - { - error("'%s' is not a regular file", fileName.c_str()); - return false; - } - FILE *f = fopen(fileName.c_str(), "rb"); - if (!f) - { - error("cannot open '%s' for sending", fileName.c_str()); - return false; - } - std::vector<unsigned char> sendBuf; - Md5 md5hash; - for (long i=0 ; i<fileLen && !feof(f); i++) - { - int ch = fgetc(f); - if (ch<0) - break; - md5hash.append((unsigned char)ch); - sendBuf.push_back((unsigned char)ch); - } - fclose(f); - DOMString hash = md5hash.finishHex(); - printf("Hash:%s\n", hash.c_str()); - - - //## get the last path segment from the whole path - if (offeredName.size()<1) - { - int slashPos = -1; - for (unsigned int i=0 ; i<fileName.size() ; i++) - { - int ch = fileName[i]; - if (ch == '/' || ch == '\\') - slashPos = i; - } - if (slashPos>=0 && slashPos<=(int)(fileName.size()-1)) - { - offeredName = fileName.substr(slashPos+1, - fileName.size()-slashPos-1); - printf("offeredName:%s\n", offeredName.c_str()); - } - } - - char buf[32]; - snprintf(buf, 31, "file%d", getMsgId()); - DOMString messageId = buf; - - XmppStream *outf = new XmppStream(); - - outf->setState(STREAM_OPENING); - outf->setMessageId(messageId); - fileSends[messageId] = outf; - - snprintf(buf, 31, "stream%d", getMsgId()); - DOMString streamId = buf; - //outf->setStreamId(streamId); - - outf->setPeerId(destJid); - - char dtgBuf[81]; - struct tm *timeVal = gmtime(&(finfo.st_mtime)); - strftime(dtgBuf, 80, "%Y-%m-%dT%H:%M:%Sz", timeVal); - - const char *fmt = - "<%s type='set' id='%s' to='%s'>" - "<si xmlns='http://jabber.org/protocol/si' id='%s'" - " mime-type='text/plain'" - " profile='http://jabber.org/protocol/si/profile/file-transfer'>" - "<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'" - " name='%s' size='%d' hash='%s' date='%s'><desc>%s</desc></file>" - "<feature xmlns='http://jabber.org/protocol/feature-neg'>" - "<x xmlns='jabber:x:data' type='form'>" - "<field var='stream-method' type='list-single'>" - //"<option><value>http://jabber.org/protocol/bytestreams</value></option>" - "<option><value>http://jabber.org/protocol/ibb</value></option>" - "</field></x></feature></si></%s>\n"; - if (!write(fmt, streamPacket.c_str(), - messageId.c_str(), destJid.c_str(), - streamId.c_str(), offeredName.c_str(), fileLen, - hash.c_str(), dtgBuf, description.c_str(), - streamPacket.c_str())) - { - return false; - } - - int ret = true; - int state = outf->getState(); - for (int tim=0 ; tim<20 ; tim++) - { - printf("##### waiting for open\n"); - if (state == STREAM_OPEN) - { - outf->reset(); - break; - } - else if (state == STREAM_ERROR) - { - printf("ERROR\n"); - outf->reset(); - ret = false; - } - Thread::sleep(1000); - state = outf->getState(); - } - if (state != STREAM_OPEN) - { - printf("TIMEOUT ERROR\n"); - ret = false; - } - - //free up this resource - fileSends.erase(messageId); - delete outf; - - if (!outputStreamOpen(destJid, streamId)) - { - error("cannot open output stream %s", streamId.c_str()); - return false; - } - - if (!outputStreamWrite(streamId, sendBuf)) - { - } - - if (!outputStreamClose(streamId)) - { - } - - return true; -} - - -class FileSendThread : public Thread -{ -public: - - FileSendThread(XmppClient &par, - const DOMString &destJidArg, - const DOMString &offeredNameArg, - const DOMString &fileNameArg, - const DOMString &descriptionArg) : client(par) - { - destJid = destJidArg; - offeredName = offeredNameArg; - fileName = fileNameArg; - description = descriptionArg; - } - - virtual ~FileSendThread() {} - - void run() - { - client.fileSend(destJid, offeredName, - fileName, description); - } - -private: - - XmppClient &client; - DOMString destJid; - DOMString offeredName; - DOMString fileName; - DOMString description; -}; - -/** - * - */ -bool XmppClient::fileSendBackground(const DOMString &destJid, - const DOMString &offeredName, - const DOMString &fileName, - const DOMString &description) -{ - FileSendThread thread(*this, destJid, offeredName, - fileName, description); - thread.start(); - return true; -} - - -/** - * - */ -bool XmppClient::fileReceive(const DOMString &fromJid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &fileName, - long /*fileSize*/, - const DOMString &/*fileHash*/) -{ - const char *fmt = - "<%s type='result' to='%s' id='%s'>" - "<si xmlns='http://jabber.org/protocol/si'>" - "<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'/>" - "<feature xmlns='http://jabber.org/protocol/feature-neg'>" - "<x xmlns='jabber:x:data' type='submit'>" - "<field var='stream-method'>" - "<value>http://jabber.org/protocol/ibb</value>" - "</field></x></feature></si></%s>\n"; - if (!write(fmt, streamPacket.c_str(), - fromJid.c_str(), iqId.c_str(), - streamPacket.c_str())) - { - return false; - } - - if (!inputStreamOpen(fromJid, streamId, iqId)) - { - return false; - } - - XmppStream *ins = inputStreams[streamId]; - - Md5 md5; - FILE *f = fopen(fileName.c_str(), "wb"); - if (!f) - { - return false; - } - - while (true) - { - if (ins->available()<1) - { - if (ins->getState() == STREAM_CLOSING) - break; - pause(100); - continue; - } - std::vector<unsigned char> ret = ins->read(); - std::vector<unsigned char>::iterator iter; - for (iter=ret.begin() ; iter!=ret.end() ; iter++) - { - unsigned char ch = *iter; - md5.append(&ch, 1); - fwrite(&ch, 1, 1, f); - } - } - - inputStreamClose(streamId); - fclose(f); - - DOMString hash = md5.finishHex(); - printf("received file hash:%s\n", hash.c_str()); - - return true; -} - - - -class FileReceiveThread : public Thread -{ -public: - - FileReceiveThread(XmppClient &par, - const DOMString &fromJidArg, - const DOMString &iqIdArg, - const DOMString &streamIdArg, - const DOMString &fileNameArg, - long fileSizeArg, - const DOMString &fileHashArg) : client(par) - { - fromJid = fromJidArg; - iqId = iqIdArg; - streamId = streamIdArg; - fileName = fileNameArg; - fileSize = fileSizeArg; - fileHash = fileHashArg; - } - - virtual ~FileReceiveThread() {} - - void run() - { - client.fileReceive(fromJid, iqId, streamId, - fileName, fileSize, fileHash); - } - -private: - - XmppClient &client; - DOMString fromJid; - DOMString iqId; - DOMString streamId; - DOMString fileName; - long fileSize; - DOMString fileHash; -}; - -/** - * - */ -bool XmppClient::fileReceiveBackground(const DOMString &fromJid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &fileName, - long fileSize, - const DOMString &fileHash) -{ - FileReceiveThread thread(*this, fromJid, iqId, streamId, - fileName, fileSize, fileHash); - thread.start(); - return true; -} - - - -//######################################################################## -//# X M P P G R O U P C H A T -//######################################################################## - -/** - * - */ -XmppGroupChat::XmppGroupChat(const DOMString &groupJidArg) -{ - groupJid = groupJidArg; -} - -/** - * - */ -XmppGroupChat::XmppGroupChat(const XmppGroupChat &other) -{ - groupJid = other.groupJid; - userList = other.userList; -} - -/** - * - */ -XmppGroupChat::~XmppGroupChat() -{ -} - - -/** - * - */ -DOMString XmppGroupChat::getGroupJid() -{ - return groupJid; -} - - -void XmppGroupChat::userAdd(const DOMString &nick, - const DOMString &jid) -{ - std::vector<XmppUser>::iterator iter; - for (iter= userList.begin() ; iter!=userList.end() ; iter++) - { - if (iter->nick == nick) - return; - } - XmppUser user(jid, nick); - userList.push_back(user); -} - -void XmppGroupChat::userShow(const DOMString &nick, - const DOMString &show) -{ - DOMString theShow = show; - if (theShow == "") - theShow = "available"; // a join message will now have a show - std::vector<XmppUser>::iterator iter; - for (iter= userList.begin() ; iter!=userList.end() ; iter++) - { - if (iter->nick == nick) - iter->show = theShow; - } -} - -void XmppGroupChat::userDelete(const DOMString &nick) -{ - std::vector<XmppUser>::iterator iter; - for (iter= userList.begin() ; iter!=userList.end() ; ) - { - if (iter->nick == nick) - iter = userList.erase(iter); - else - iter++; - } -} - -std::vector<XmppUser> XmppGroupChat::getUserList() const -{ - return userList; -} - - - - - - - - - -} //namespace Pedro -//######################################################################## -//# E N D O F F I L E -//######################################################################## - - - - - - - - - - - - - - - diff --git a/src/pedro/pedroxmpp.h b/src/pedro/pedroxmpp.h deleted file mode 100644 index ee3234fd4..000000000 --- a/src/pedro/pedroxmpp.h +++ /dev/null @@ -1,1251 +0,0 @@ -#ifndef __XMPP_H__ -#define __XMPP_H__ -/* - * API for the Pedro mini-XMPP client. - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005-2007 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <glib.h> -#include <vector> -#include <map> - -#include <string> - -#include "pedrodom.h" - -namespace Pedro -{ - -typedef std::string DOMString; - - -//######################################################################## -//# X M P P E V E N T -//######################################################################## -class XmppUser -{ -public: - XmppUser() - { - } - XmppUser(const DOMString &jidArg, const DOMString &nickArg) - { - jid = jidArg; - nick = nickArg; - } - XmppUser(const DOMString &jidArg, const DOMString &nickArg, - const DOMString &subscriptionArg, const DOMString &groupArg) - { - jid = jidArg; - nick = nickArg; - subscription = subscriptionArg; - group = groupArg; - } - XmppUser(const XmppUser &other) - { - jid = other.jid; - nick = other.nick; - subscription = other.subscription; - group = other.group; - show = other.show; - } - XmppUser &operator=(const XmppUser &other) - { - jid = other.jid; - nick = other.nick; - subscription = other.subscription; - group = other.group; - show = other.show; - return *this; - } - virtual ~XmppUser() - {} - DOMString jid; - DOMString nick; - DOMString subscription; - DOMString group; - DOMString show; -}; - - - - - -/** - * Class that emits information from a client - */ -class XmppEvent -{ - -public: - - /** - * People might want to refer to these docs to understand - * the XMPP terminology used here. - * http://www.ietf.org/rfc/rfc3920.txt -- Xmpp Core - * http://www.ietf.org/rfc/rfc3921.txt -- Messaging and presence - * http://www.jabber.org/jeps/jep-0077.html -- In-Band registration - * http://www.jabber.org/jeps/jep-0045.html -- Multiuser Chat - * http://www.jabber.org/jeps/jep-0047.html -- In-Band byte streams - * http://www.jabber.org/jeps/jep-0096.html -- File transfer - */ - - /** - * No event type. Default - */ - static const int EVENT_NONE = 0; - - /** - * Client emits a status message. Message is in getData(). - */ - static const int EVENT_STATUS = 1; - - /** - * Client emits an error message. Message is in getData(). - */ - static const int EVENT_ERROR = 2; - - /** - * Client has connected to a host. Host name is in getData(). - */ - static const int EVENT_CONNECTED = 10; - - /** - * Client has disconnected from a host. Host name is in getData(). - */ - static const int EVENT_DISCONNECTED = 11; - - /** - * Client has begun speaking to the server in SSL. This is usually - * emitted just before EVENT_CONNECTED, since authorization has not - * yet taken place. - */ - static const int EVENT_SSL_STARTED = 12; - - /** - * Client has successfully registered a new account on a server. - * The server is in getFrom(), the user in getTo() - */ - static const int EVENT_REGISTRATION_NEW = 20; - - /** - * Client has successfully changed the password of an existing account on a server. - * The server is in getFrom(), the user in getTo() - */ - static const int EVENT_REGISTRATION_CHANGE_PASS = 21; - - /** - * Client has successfully cancelled an existing account on a server. - * The server is in getFrom(), the user in getTo() - */ - static const int EVENT_REGISTRATION_CANCEL = 22; - - /** - * A <presence> packet has been received. - * getFrom() returns the full jabber id - * getPresence() returns the available/unavailable boolean - * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc - * getStatus() returns a status message, sent from a client - * Note: if a presence packet is determined to be MUC, it is - * rather sent as an EVENT_MUC_JOIN, LEAVE, or PRESENCE - */ - static const int EVENT_PRESENCE = 30; - - /** - * Client has just received a complete roster. The collected information - * can be found at client.getRoster(), and is a std::vector of XmppUser - * records. - */ - static const int EVENT_ROSTER = 31; - - /** - * Client has just received a message packet. - * getFrom() returns the full jabber id of the sender - * getData() returns the text of the message - * getDom() returns the DOM treelet for this stanza. This is provided - * to make message extension easier. - * Note: if a message packet is determined to be MUC, it is - * rather sent as an EVENT_MUC_MESSAGE - */ - static const int EVENT_MESSAGE = 32; - - /** - * THIS user has just joined a multi-user chat group. - * getGroup() returns the group name - * getFrom() returns the nick of the user in the group - * getPresence() returns the available/unavailable boolean - * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc - * getStatus() returns a status message, sent from a client - */ - static const int EVENT_MUC_JOIN = 40; - - /** - * THIS user has just left a multi-user chat group. - * getGroup() returns the group name - * getFrom() returns the nick of the user in the group - * getPresence() returns the available/unavailable boolean - * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc - * getStatus() returns a status message, sent from a client - */ - static const int EVENT_MUC_LEAVE = 41; - - /** - * Presence for another user in a multi-user chat room. - * getGroup() returns the group name - * getFrom() returns the nick of the user in the group - * getPresence() returns the available/unavailable boolean - * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc - * getStatus() returns a status message, sent from a client - */ - static const int EVENT_MUC_PRESENCE = 42; - - /** - * Client has just received a message packet from a multi-user chat room - * getGroup() returns the group name - * getFrom() returns the full jabber id of the sender - * getData() returns the text of the message - * getDom() returns the DOM treelet for this stanza. This is provided - * to make message extension easier. - */ - static const int EVENT_MUC_MESSAGE = 43; - - /** - * Client has begun receiving a stream - */ - static const int EVENT_STREAM_RECEIVE_INIT = 50; - - /** - * Client receives another stream packet. - */ - static const int EVENT_STREAM_RECEIVE = 51; - - /** - * Client has received the end of a stream - */ - static const int EVENT_STREAM_RECEIVE_CLOSE = 52; - - /** - * Other client has accepted a file. - */ - static const int EVENT_FILE_ACCEPTED = 60; - - /** - * This client has just received a file. - */ - static const int EVENT_FILE_RECEIVE = 61; - - /** - * Constructs an event with one of the types above. - */ - XmppEvent(int type); - - /** - * Copy constructor - */ - XmppEvent(const XmppEvent &other); - - /** - * Assignment - */ - virtual XmppEvent &operator=(const XmppEvent &other); - - /** - * Destructor - */ - virtual ~XmppEvent(); - - /** - * Assignment - */ - virtual void assign(const XmppEvent &other); - - /** - * Return the event type. - */ - virtual int getType() const; - - - /** - * - */ - virtual DOMString getIqId() const; - - - /** - * - */ - virtual void setIqId(const DOMString &val); - - /** - * - */ - virtual DOMString getStreamId() const; - - - /** - * - */ - virtual void setStreamId(const DOMString &val); - - /** - * - */ - virtual bool getPresence() const; - - - /** - * - */ - virtual void setPresence(bool val); - - /** - * - */ - virtual DOMString getShow() const; - - - /** - * - */ - virtual void setShow(const DOMString &val); - - /** - * - */ - virtual DOMString getStatus() const; - - /** - * - */ - virtual void setStatus(const DOMString &val); - - /** - * - */ - virtual DOMString getTo() const; - - /** - * - */ - virtual void setTo(const DOMString &val); - - /** - * - */ - virtual DOMString getFrom() const; - - /** - * - */ - virtual void setFrom(const DOMString &val); - - /** - * - */ - virtual DOMString getGroup() const; - - /** - * - */ - virtual void setGroup(const DOMString &val); - - /** - * - */ - virtual Element *getDOM() const; - - - /** - * - */ - virtual void setDOM(const Element *val); - - /** - * - */ - virtual std::vector<XmppUser> getUserList() const; - - /** - * - */ - virtual void setUserList(const std::vector<XmppUser> &userList); - - /** - * - */ - virtual DOMString getFileName() const; - - - /** - * - */ - virtual void setFileName(const DOMString &val); - - - /** - * - */ - virtual DOMString getFileDesc() const; - - - /** - * - */ - virtual void setFileDesc(const DOMString &val); - - - /** - * - */ - virtual long getFileSize() const; - - - /** - * - */ - virtual void setFileSize(long val); - - /** - * - */ - virtual DOMString getFileHash() const; - - /** - * - */ - virtual void setFileHash(const DOMString &val); - - /** - * - */ - virtual DOMString getData() const; - - - /** - * - */ - virtual void setData(const DOMString &val); - -private: - - int eventType; - - DOMString iqId; - - DOMString streamId; - - bool presence; - - DOMString show; - - DOMString status; - - DOMString to; - - DOMString from; - - DOMString group; - - DOMString data; - - DOMString fileName; - DOMString fileDesc; - long fileSize; - DOMString fileHash; - - Element *dom; - - std::vector<XmppUser>userList; - -}; - - - - - - -//######################################################################## -//# X M P P E V E N T L I S T E N E R -//######################################################################## - -/** - * Class that receives and processes an XmppEvent. Users should inherit - * from this class, and overload processXmppEvent() to perform their event - * handling - */ -class XmppEventListener -{ -public: - - /** - * Constructor - */ - XmppEventListener() - {} - - /** - * Assignment - */ - XmppEventListener(const XmppEventListener &/*other*/) - {} - - - /** - * Destructor - */ - virtual ~XmppEventListener() - {} - - /** - * Overload this method to provide your application-specific - * event handling. Use event.getType() to decide what to do - * with the event. - */ - virtual void processXmppEvent(const XmppEvent &/*event*/) - {} - -}; - - - -//######################################################################## -//# X M P P E V E N T T A R G E T -//######################################################################## - -/** - * A base class for classes that emit XmppEvents. - * - * Note: terminology: 'target' is the common term for this, although it - * seems odd that a 'target' is the source of the events. It is clearer - * if you consider that the greater system targets this class with events, - * and this class delegates the handling to its listeners. - */ -class XmppEventTarget -{ -public: - - /** - * Constructor - */ - XmppEventTarget(); - - /** - * Copy constructor - */ - XmppEventTarget(const XmppEventTarget &other); - - /** - * Destructor - */ - virtual ~XmppEventTarget(); - - - //########################### - //# M E S S A G E S - //########################### - - - /** - * Send an error message to all subscribers - */ - void error(const char *fmt, ...) G_GNUC_PRINTF(2,3); - - - /** - * Send a status message to all subscribers - */ - void status(const char *fmt, ...) G_GNUC_PRINTF(2,3); - - //########################### - //# LISTENERS - //########################### - - /** - * Subscribe a subclass of XmppEventListener to this target's events. - */ - virtual void addXmppEventListener(const XmppEventListener &listener); - - /** - * Unsubscribe a subclass of XmppEventListener from this target's events. - */ - virtual void removeXmppEventListener(const XmppEventListener &listener); - - /** - * Remove all event subscribers - */ - virtual void clearXmppEventListeners(); - - /** - * This sends an event to all registered listeners. - */ - virtual void dispatchXmppEvent(const XmppEvent &event); - - /** - * By enabling this, you provide an alternate way to get XmppEvents. - * Any event sent to dispatchXmppEvent() is also sent to this queue, - * so that it can be later be picked up by eventQueuePop(); - * This can sometimes be good for GUI's which can't always respond - * repidly or asynchronously. - */ - void eventQueueEnable(bool val); - - /** - * Return true if there is one or more XmppEvents waiting in the event - * queue. This is used to avoid calling eventQueuePop() when there is - * nothing in the queue. - */ - int eventQueueAvailable(); - - /** - * Return the next XmppEvent in the queue. Users should check that - * eventQueueAvailable() is greater than 0 before calling this. If - * people forget to do this, an event of type XmppEvent::EVENT_NONE - * is generated and returned. - */ - XmppEvent eventQueuePop(); - - -private: - - std::vector<XmppEventListener *> listeners; - - std::vector<XmppEvent> eventQueue; - bool eventQueueEnabled; -}; - - - - - -//######################################################################## -//# X M P P C L I E N T -//######################################################################## - -//forward declarations -class TcpSocket; -class XmppChat; -class XmppGroupChat; -class XmppStream; - - -/** - * This is the actual XMPP (Jabber) client. - */ -class XmppClient : public XmppEventTarget -{ - -public: - - //########################### - //# CONSTRUCTORS - //########################### - - /** - * Constructor - */ - XmppClient(); - - /** - * Copy constructor - */ - XmppClient(const XmppClient &other); - - /** - * Assignment - */ - void assign(const XmppClient &other); - - /** - * Destructor - */ - virtual ~XmppClient(); - - - //########################### - //# UTILITY - //########################### - - /** - * Pause execution of the app for a given number of - * milliseconds. Use this rarely, only when really needed. - */ - virtual bool pause(unsigned long millis); - - /** - * Process a string so that it can safely be - * placed in XML as PCDATA - */ - DOMString toXml(const DOMString &str); - - //########################### - //# CONNECTION - //########################### - - /** - * - */ - virtual bool connect(); - - /** - * - */ - virtual bool connect(DOMString host, int port, - DOMString userName, - DOMString password, - DOMString resource); - - /** - * - */ - virtual bool disconnect(); - - - /** - * - */ - virtual bool write(const char *fmt, ...) G_GNUC_PRINTF(2,3); - - //####################### - //# V A R I A B L E S - //####################### - - /** - * - */ - virtual bool isConnected() - { return connected; } - - /** - * - */ - virtual DOMString getHost() - { return host; } - - /** - * - */ - virtual void setHost(const DOMString &val) - { host = val; } - - /** - * - */ - virtual DOMString getRealm() - { return realm; } - - /** - * - */ - virtual void setRealm(const DOMString &val) - { realm = val; } - - /** - * - */ - virtual int getPort() - { return port; } - - /** - * - */ - virtual void setPort(int val) - { port = val; } - - /** - * - */ - virtual DOMString getUsername(); - - /** - * - */ - virtual void setUsername(const DOMString &val); - - /** - * - */ - virtual DOMString getPassword() - { return password; } - - /** - * - */ - virtual void setPassword(const DOMString &val) - { password = val; } - - /** - * - */ - virtual DOMString getResource() - { return resource; } - - /** - * - */ - virtual void setResource(const DOMString &val) - { resource = val; } - - /** - * - */ - virtual void setJid(const DOMString &val) - { jid = val; } - - /** - * - */ - virtual DOMString getJid() - { return jid; } - - - - /** - * - */ - virtual int getMsgId() - { return msgId++; } - - - - //####################### - //# P R O C E S S I N G - //####################### - - - /** - * - */ - bool processMessage(Element *root); - - /** - * - */ - bool processPresence(Element *root); - - /** - * - */ - bool processIq(Element *root); - - /** - * - */ - virtual bool receiveAndProcess(); - - /** - * - */ - virtual bool receiveAndProcessLoop(); - - //####################### - //# ROSTER - //####################### - - /** - * - */ - bool rosterAdd(const DOMString &rosterGroup, - const DOMString &otherJid, - const DOMString &name); - - /** - * - */ - bool rosterDelete(const DOMString &otherJid); - - /** - * - */ - std::vector<XmppUser> getRoster(); - - /** - * - */ - virtual void rosterShow(const DOMString &jid, const DOMString &show); - - //####################### - //# REGISTRATION - //####################### - - /** - * Set whether the client should to in-band registration - * before authentication. Causes inBandRegistrationNew() to be called - * synchronously, before async is started. - */ - virtual void setDoRegister(bool val) - { doRegister = val; } - - /** - * Change the password of an existing account with a server - */ - bool inBandRegistrationChangePassword(const DOMString &newPassword); - - /** - * Cancel an existing account with a server - */ - bool inBandRegistrationCancel(); - - - //####################### - //# CHAT (individual) - //####################### - - /** - * - */ - virtual bool message(const DOMString &user, const DOMString &subj, - const DOMString &text); - - /** - * - */ - virtual bool message(const DOMString &user, const DOMString &text); - - /** - * - */ - virtual bool presence(const DOMString &presence); - - //####################### - //# GROUP CHAT - //####################### - - /** - * - */ - virtual bool groupChatCreate(const DOMString &groupJid); - - /** - * - */ - virtual void groupChatDelete(const DOMString &groupJid); - - /** - * - */ - bool groupChatExists(const DOMString &groupJid); - - /** - * - */ - virtual void groupChatsClear(); - - /** - * - */ - virtual void groupChatUserAdd(const DOMString &groupJid, - const DOMString &nick, - const DOMString &jid); - /** - * - */ - virtual void groupChatUserShow(const DOMString &groupJid, - const DOMString &nick, - const DOMString &show); - - /** - * - */ - virtual void groupChatUserDelete(const DOMString &groupJid, - const DOMString &nick); - - /** - * - */ - virtual std::vector<XmppUser> - groupChatGetUserList(const DOMString &groupJid); - - /** - * - */ - virtual bool groupChatJoin(const DOMString &groupJid, - const DOMString &nick, - const DOMString &pass); - - /** - * - */ - virtual bool groupChatLeave(const DOMString &groupJid, - const DOMString &nick); - - /** - * - */ - virtual bool groupChatMessage(const DOMString &groupJid, - const DOMString &msg); - - /** - * - */ - virtual bool groupChatPrivateMessage(const DOMString &groupJid, - const DOMString &toNick, - const DOMString &msg); - - /** - * - */ - virtual bool groupChatPresence(const DOMString &groupJid, - const DOMString &nick, - const DOMString &presence); - - - //####################### - //# STREAMS - //####################### - - typedef enum - { - STREAM_AVAILABLE, - STREAM_OPENING, - STREAM_OPEN, - STREAM_CLOSING, - STREAM_CLOSED, - STREAM_ERROR - } StreamStates; - - /** - * - */ - virtual bool outputStreamOpen(const DOMString &jid, - const DOMString &streamId); - - /** - * - */ - virtual bool outputStreamWrite(const DOMString &streamId, - const std::vector<unsigned char> &buf); - - /** - * - */ - virtual bool outputStreamClose(const DOMString &streamId); - - /** - * - */ - virtual bool inputStreamOpen(const DOMString &jid, - const DOMString &streamId, - const DOMString &iqId); - - /** - * - */ - virtual bool inputStreamClose(const DOMString &streamId); - - - //####################### - //# FILE TRANSFERS - //####################### - - /** - * - */ - virtual bool fileSend(const DOMString &destJid, - const DOMString &offeredName, - const DOMString &fileName, - const DOMString &description); - - /** - * - */ - virtual bool fileSendBackground(const DOMString &destJid, - const DOMString &offeredName, - const DOMString &fileName, - const DOMString &description); - - /** - * - */ - virtual bool fileReceive(const DOMString &fromJid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &fileName, - long fileSize, - const DOMString &fileHash); - /** - * - */ - virtual bool fileReceiveBackground(const DOMString &fromJid, - const DOMString &iqId, - const DOMString &streamId, - const DOMString &fileName, - long fileSize, - const DOMString &fileHash); - - -private: - - void init(); - - DOMString host; - - /** - * will be same as host, unless username is - * user@realm - */ - DOMString realm; - - int port; - - DOMString username; - - DOMString password; - - DOMString resource; - - DOMString jid; - - int msgId; - - TcpSocket *sock; - - bool connected; - - bool createSession(); - - bool checkConnect(); - - DOMString readStanza(); - - bool saslMd5Authenticate(); - - bool saslPlainAuthenticate(); - - bool saslAuthenticate(const DOMString &streamId); - - bool iqAuthenticate(const DOMString &streamId); - - /** - * Register a new account with a server. Not done by user - */ - bool inBandRegistrationNew(); - - bool keepGoing; - - bool doRegister; - - std::vector<XmppGroupChat *>groupChats; - - //#### Roster - std::vector<XmppUser>roster; - - - //#### Streams - - bool processInBandByteStreamMessage(Element *root); - - DOMString streamPacket; - - std::map<DOMString, XmppStream *> outputStreams; - - std::map<DOMString, XmppStream *> inputStreams; - - - //#### File send - - bool processFileMessage(Element *root); - - std::map<DOMString, XmppStream *> fileSends; - -}; - - - - -//######################################################################## -//# X M P P G R O U P C H A T -//######################################################################## - -/** - * - */ -class XmppGroupChat -{ -public: - - /** - * - */ - XmppGroupChat(const DOMString &groupJid); - - /** - * - */ - XmppGroupChat(const XmppGroupChat &other); - - /** - * - */ - virtual ~XmppGroupChat(); - - /** - * - */ - virtual DOMString getGroupJid(); - - /** - * - */ - virtual void userAdd(const DOMString &nick, - const DOMString &jid); - /** - * - */ - virtual void userShow(const DOMString &nick, - const DOMString &show); - - /** - * - */ - virtual void userDelete(const DOMString &nick); - - /** - * - */ - virtual std::vector<XmppUser> getUserList() const; - - -private: - - DOMString groupJid; - - std::vector<XmppUser>userList; - -}; - - - - - - - - - - -} //namespace Pedro - -#endif /* __XMPP_H__ */ - -//######################################################################## -//# E N D O F F I L E -//######################################################################## - diff --git a/src/pedro/work/filerec.cpp b/src/pedro/work/filerec.cpp deleted file mode 100644 index 01d9b6bd8..000000000 --- a/src/pedro/work/filerec.cpp +++ /dev/null @@ -1,130 +0,0 @@ - - -#include <stdio.h> - -#include "pedroxmpp.h" - -//######################################################################## -//# T E S T -//######################################################################## - - -class TestListener : public Pedro::XmppEventListener -{ -public: - TestListener() - { - incoming = false; - } - - virtual ~TestListener(){} - - virtual void processXmppEvent(const Pedro::XmppEvent &evt) - { - int typ = evt.getType(); - switch (typ) - { - case Pedro::XmppEvent::EVENT_STATUS: - { - printf("STATUS: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_ERROR: - { - printf("ERROR: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_CONNECTED: - { - printf("CONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_DISCONNECTED: - { - printf("DISCONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_MUC_PRESENCE: - { - printf("MUC PRESENCE\n"); - printf("group : %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence: %d\n", evt.getPresence()); - break; - } - case Pedro::XmppEvent::EVENT_FILE_RECEIVE: - { - printf("FILE RECEIVE\n"); - from = evt.getFrom(); - streamId = evt.getStreamId(); - iqId = evt.getIqId(); - fileName = evt.getFileName(); - fileHash = evt.getFileHash(); - fileSize = evt.getFileSize(); - incoming = true; - break; - } - - } - } - - Pedro::DOMString from; - Pedro::DOMString streamId; - Pedro::DOMString iqId; - Pedro::DOMString fileName; - Pedro::DOMString fileHash; - long fileSize; - bool incoming; -}; - - -bool doTest() -{ - printf("############ RECEIVING FILE\n"); - - Pedro::XmppClient client; - TestListener listener; - client.addXmppEventListener(listener); - - //Host, port, user, pass, resource - if (!client.connect("jabber.org.uk", 443, "ishmal", "PASSWORD", "filerec")) - { - printf("Connect failed\n"); - return false; - } - - while (true) - { - printf("####Waiting for file\n"); - if (listener.incoming) - break; - client.pause(2000); - } - - printf("#####GOT A FILE\n"); -/* -TODO: Just Commented out to compile - if (!client.fileReceive(listener.from, - listener.iqId, - listener.streamId, - listener.fileName, - "text.sav", - listener.fileHash)) - { - return false; - } -*/ - client.pause(1000000); - - client.disconnect(); - - return true; -} - -int main(int argc, char **argv) -{ - if (!doTest()) - return 1; - return 0; -} - diff --git a/src/pedro/work/filesend.cpp b/src/pedro/work/filesend.cpp deleted file mode 100644 index 7a114abe2..000000000 --- a/src/pedro/work/filesend.cpp +++ /dev/null @@ -1,95 +0,0 @@ - - -#include <stdio.h> - -#include "pedroxmpp.h" - -//######################################################################## -//# T E S T -//######################################################################## - - -class TestListener : public Pedro::XmppEventListener -{ -public: - TestListener(){} - - virtual ~TestListener(){} - - virtual void processXmppEvent(const Pedro::XmppEvent &evt) - { - int typ = evt.getType(); - switch (typ) - { - case Pedro::XmppEvent::EVENT_STATUS: - { - printf("STATUS: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_ERROR: - { - printf("ERROR: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_CONNECTED: - { - printf("CONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_DISCONNECTED: - { - printf("DISCONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_MUC_PRESENCE: - { - printf("MUC PRESENCE\n"); - printf("group : %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence: %d\n", evt.getPresence()); - break; - } - - } - } -}; - - -bool doTest() -{ - printf("############ SENDING FILE\n"); - - Pedro::XmppClient client; - TestListener listener; - client.addXmppEventListener(listener); - - //Host, port, user, pass, resource - if (!client.connect("jabber.org.uk", 443, "ishmal", "PASSWORD", "filesend")) - { - printf("Connect failed\n"); - return false; - } - - - if (!client.fileSend("ishmal@jabber.org.uk/filerec", - "server.pem" , "server.pem", - "a short story by edgar allen poe")) - { - return false; - } - - printf("OK\n"); - client.pause(1000000); - - client.disconnect(); - - return true; -} - -int main(int argc, char **argv) -{ - if (!doTest()) - return 1; - return 0; -} - diff --git a/src/pedro/work/groupchat.cpp b/src/pedro/work/groupchat.cpp deleted file mode 100644 index 6c2e186d9..000000000 --- a/src/pedro/work/groupchat.cpp +++ /dev/null @@ -1,225 +0,0 @@ - - -#include <stdio.h> -#include <string.h> - -#include "pedroxmpp.h" - -//######################################################################## -//# T E S T -//######################################################################## - -using namespace Pedro; - - -class Listener : public Pedro::XmppEventListener -{ -public: - Listener(){} - - virtual ~Listener(){} - - virtual void processXmppEvent(const Pedro::XmppEvent &evt) - { - int typ = evt.getType(); - switch (typ) - { - case Pedro::XmppEvent::EVENT_STATUS: - { - printf("STATUS: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_ERROR: - { - printf("ERROR: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_CONNECTED: - { - printf("CONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_DISCONNECTED: - { - printf("DISCONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_MESSAGE: - { - printf("<%s> %s\n", evt.getFrom().c_str(), evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_PRESENCE: - { - printf("PRESENCE\n"); - printf("from : %s\n", evt.getFrom().c_str()); - //printf("presence : %s\n", evt.getPresence().c_str()); - // TODO: Just Commented out to compile - break; - } - case Pedro::XmppEvent::EVENT_MUC_MESSAGE: - { - printf("<%s> %s\n", evt.getFrom().c_str(), evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_MUC_JOIN: - { - printf("MUC JOIN\n"); - printf("group: %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - //printf("presence: %s\n", evt.getPresence().c_str()); - // TODO: Just Commented out to compile - break; - } - case Pedro::XmppEvent::EVENT_MUC_LEAVE: - { - printf("MUC LEAVE\n"); - printf("group: %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - //printf("presence: %s\n", evt.getPresence().c_str()); - // TODO: Just Commented out to compile - break; - } - case Pedro::XmppEvent::EVENT_MUC_PRESENCE: - { - printf("MUC PRESENCE\n"); - printf("group : %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - //printf("presence: %s\n", evt.getPresence().c_str()); - // TODO: Just Commented out to compile - break; - } - - } - } -}; - - -class CommandLineGroupChat -{ -public: - CommandLineGroupChat(const DOMString &hostArg, - int portArg, - const DOMString &userArg, - const DOMString &passArg, - const DOMString &resourceArg, - const DOMString &groupJidArg, - const DOMString &nickArg) - { - host = hostArg; - port = portArg; - user = userArg; - pass = passArg; - resource = resourceArg; - groupJid = groupJidArg; - nick = nickArg; - } - ~CommandLineGroupChat() - { - client.disconnect(); - } - - virtual bool run(); - virtual bool processCommandLine(); - -private: - - DOMString host; - int port; - DOMString user; - DOMString pass; - DOMString resource; - DOMString groupJid; - DOMString nick; - - XmppClient client; - -}; - - -bool CommandLineGroupChat::run() -{ - Listener listener; - client.addXmppEventListener(listener); - - //Host, port, user, pass, resource - if (!client.connect(host, port, user, pass, resource)) - { - return false; - } - - //Group jabber id, nick, pass - if (!client.groupChatJoin(groupJid, nick, "")) - { - printf("failed join\n"); - return false; - } - - //Allow receive buffer to clear out - client.pause(10000); - - while (true) - { - if (!processCommandLine()) - break; - } - - //Group jabber id, nick - client.groupChatLeave(groupJid, nick); - - - client.disconnect(); - - return true; -} - - -bool CommandLineGroupChat::processCommandLine() -{ - char buf[512]; - printf("send>:"); - fgets(buf, 511, stdin); - - if (buf[0]=='/') - { - if (strncmp(buf, "/q", 2)==0) - return false; - else - { - printf("Unknown command\n"); - return true; - } - } - - else - { - DOMString msg = buf; - if (msg.size() > 0 ) - { - if (!client.groupChatMessage(groupJid, buf)) - { - printf("failed message send\n"); - return false; - } - } - } - - return true; -} - - -int main(int argc, char **argv) -{ - if (argc!=8) - { - printf("usage: %s host port user pass resource groupid nick\n", argv[0]); - return 1; - } - int port = atoi(argv[2]); - CommandLineGroupChat groupChat(argv[1], port, argv[3], argv[4], - argv[5], argv[6], argv[7]); - if (!groupChat.run()) - return 1; - return 0; -} - diff --git a/src/pedro/work/inklayout.svg b/src/pedro/work/inklayout.svg deleted file mode 100644 index 5f28a129b..000000000 --- a/src/pedro/work/inklayout.svg +++ /dev/null @@ -1,378 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="841.88977pt"
- height="595.27557pt"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.42+devel"
- version="1.0"
- sodipodi:docbase="/home/rjamison/pedro"
- sodipodi:docname="inklayout.svg">
- <defs
- id="defs4">
- <marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Mend"
- style="overflow:visible;">
- <path
- id="path4241"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
- transform="scale(0.4) rotate(180)" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Mstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Mstart"
- style="overflow:visible">
- <path
- id="path4244"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
- transform="scale(0.4)" />
- </marker>
- <marker
- inkscape:stockid="TriangleInL"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="TriangleInL"
- style="overflow:visible">
- <path
- id="path4158"
- d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
- transform="scale(-0.8)" />
- </marker>
- <marker
- inkscape:stockid="Arrow2Lstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow2Lstart"
- style="overflow:visible">
- <path
- id="path4232"
- style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
- d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
- transform="scale(1.1) translate(-5,0)" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Lstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Lstart"
- style="overflow:visible">
- <path
- id="path4250"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
- transform="scale(0.8)" />
- </marker>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.98994949"
- inkscape:cx="544.45061"
- inkscape:cy="385.08312"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- fill="#000000"
- inkscape:window-width="899"
- inkscape:window-height="951"
- inkscape:window-x="284"
- inkscape:window-y="59" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <rect
- y="20.094482"
- x="424.57144"
- height="37.142857"
- width="240"
- id="rect3148"
- style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect2273"
- width="240"
- height="37.142857"
- x="418.57144"
- y="14.094482" />
- <rect
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect1358"
- width="83.244057"
- height="35.076485"
- x="191.22281"
- y="182.43959" />
- <text
- xml:space="preserve"
- style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="199.27339"
- y="203.54922"
- id="text2233"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan2235"
- x="199.27339"
- y="203.54922">Private chat</tspan></text>
- <rect
- y="278.15387"
- x="282.6514"
- height="35.076485"
- width="83.244057"
- id="rect2237"
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <text
- id="text2239"
- y="331.4064"
- x="252.13055"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="331.4064"
- x="252.13055"
- id="tspan2241"
- sodipodi:role="line">Gui Client Main Window</tspan></text>
- <rect
- y="182.43959"
- x="289.22281"
- height="35.076485"
- width="83.244057"
- id="rect2243"
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <text
- id="text2245"
- y="204.97781"
- x="302.9877"
- style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"
- sodipodi:linespacing="125%"><tspan
- y="204.97781"
- x="302.9877"
- id="tspan2247"
- sodipodi:role="line">Group chat</tspan></text>
- <rect
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.62177706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect2249"
- width="96.722092"
- height="35.076485"
- x="391.2695"
- y="182.43959" />
- <text
- xml:space="preserve"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="419.9877"
- y="173.54926"
- id="text2251"><tspan
- sodipodi:role="line"
- id="tspan2253"
- x="419.9877"
- y="173.54926">Dialog</tspan></text>
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 249.87329,217.80449 L 307.24497,277.86545"
- id="path2255"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect1358"
- inkscape:connection-end="#rect2237" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 329.62092,217.80449 L 325.49734,277.86545"
- id="path2257"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect2243"
- inkscape:connection-end="#rect2237" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 418.11835,217.82696 L 345.75854,277.86545"
- id="path2259"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect2249"
- inkscape:connection-end="#rect2237" />
- <text
- xml:space="preserve"
- style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="428.57141"
- y="39.808769"
- id="text2261"
- sodipodi:linespacing="100%"><tspan
- sodipodi:role="line"
- id="tspan2263"
- x="428.57141"
- y="39.808769">Inkboard Layout</tspan></text>
- <rect
- y="182.02116"
- x="582.86676"
- height="35.076485"
- width="83.244057"
- id="rect3150"
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <text
- id="text3152"
- y="173.84511"
- x="603.06018"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="173.84511"
- x="603.06018"
- id="tspan3154"
- sodipodi:role="line">Session</tspan></text>
- <rect
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect3156"
- width="83.244057"
- height="35.076485"
- x="674.29535"
- y="277.73547" />
- <text
- xml:space="preserve"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="664.48877"
- y="330.98801"
- id="text3158"><tspan
- sodipodi:role="line"
- id="tspan3160"
- x="664.48877"
- y="330.98801">Session Manager</tspan></text>
- <rect
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect3162"
- width="83.244057"
- height="35.076485"
- x="680.86676"
- y="182.02116" />
- <text
- xml:space="preserve"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="701.06018"
- y="173.84511"
- id="text3164"><tspan
- sodipodi:role="line"
- id="tspan3166"
- x="701.06018"
- y="173.84511">Session</tspan></text>
- <rect
- y="182.02116"
- x="782.86676"
- height="35.076485"
- width="83.244057"
- id="rect3168"
- style="fill:none;fill-opacity:0.75;stroke:#000000;stroke-width:0.57683086;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <text
- id="text3170"
- y="173.84511"
- x="803.06018"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="173.84511"
- x="803.06018"
- id="tspan3172"
- sodipodi:role="line">Session</tspan></text>
- <path
- inkscape:connection-end="#rect2237"
- inkscape:connection-start="#rect1358"
- inkscape:connector-type="polyline"
- id="path3174"
- d="M 249.87329,217.80449 L 307.24497,277.86545"
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <text
- id="text3180"
- y="195.69208"
- x="407.84482"
- style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"
- sodipodi:linespacing="125%"><tspan
- y="195.69208"
- x="407.84482"
- id="tspan3182"
- sodipodi:role="line">Private chat</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="393.70197"
- y="208.54922"
- id="text3184"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3186"
- x="393.70197"
- y="208.54922">w/ group member</tspan></text>
- <text
- id="text3188"
- y="174.26353"
- x="311.41626"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- y="174.26353"
- x="311.41626"
- id="tspan3190"
- sodipodi:role="line">Dialog</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="213.41626"
- y="174.26353"
- id="text3192"><tspan
- sodipodi:role="line"
- id="tspan3194"
- x="213.41626"
- y="174.26353">Dialog</tspan></text>
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 804.26751,217.38606 L 736.13865,277.44706"
- id="path3196"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect3168"
- inkscape:connection-end="#rect3156" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 721.26487,217.38606 L 717.14129,277.44706"
- id="path3198"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect3162"
- inkscape:connection-end="#rect3156" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 641.51724,217.38606 L 698.88893,277.44706"
- id="path3200"
- inkscape:connector-type="polyline"
- inkscape:connection-start="#rect3150"
- inkscape:connection-end="#rect3156" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:6.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
- d="M 452.54834,260.23141 C 615.1829,260.23141 616.19305,260.23141 616.19305,260.23141"
- id="path3202" />
- </g>
-</svg>
diff --git a/src/pedro/work/test.cpp b/src/pedro/work/test.cpp deleted file mode 100644 index f822ceca9..000000000 --- a/src/pedro/work/test.cpp +++ /dev/null @@ -1,183 +0,0 @@ - - -#include <stdio.h> - -#include "pedroxmpp.h" -#include "pedroconfig.h" - -//######################################################################## -//# T E S T -//######################################################################## - - -class TestListener : public Pedro::XmppEventListener -{ -public: - TestListener(){} - - virtual ~TestListener(){} - - virtual void processXmppEvent(const Pedro::XmppEvent &evt) - { - int typ = evt.getType(); - switch (typ) - { - case Pedro::XmppEvent::EVENT_STATUS: - { - printf("STATUS: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_ERROR: - { - printf("ERROR: %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_CONNECTED: - { - printf("CONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_DISCONNECTED: - { - printf("DISCONNECTED\n"); - break; - } - case Pedro::XmppEvent::EVENT_MESSAGE: - { - printf("MESSAGE\n"); - printf("from : %s\n", evt.getFrom().c_str()); - printf("msg : %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_PRESENCE: - { - printf("PRESENCE\n"); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence : %d\n", evt.getPresence()); - break; - } - case Pedro::XmppEvent::EVENT_MUC_MESSAGE: - { - printf("MUC GROUP MESSAGE\n"); - printf("group: %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("msg : %s\n", evt.getData().c_str()); - break; - } - case Pedro::XmppEvent::EVENT_MUC_JOIN: - { - printf("MUC JOIN\n"); - printf("group: %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence: %d\n", evt.getPresence()); - break; - } - case Pedro::XmppEvent::EVENT_MUC_LEAVE: - { - printf("MUC LEAVE\n"); - printf("group: %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence: %d\n", evt.getPresence()); - break; - } - case Pedro::XmppEvent::EVENT_MUC_PRESENCE: - { - printf("MUC PRESENCE\n"); - printf("group : %s\n", evt.getGroup().c_str()); - printf("from : %s\n", evt.getFrom().c_str()); - printf("presence: %d\n", evt.getPresence()); - break; - } - - } - } -}; - - -bool doTest() -{ - printf("############ TESTING\n"); - - char *groupJid = "inkscape@conference.gristle.org"; - - Pedro::XmppClient client; - TestListener listener; - client.addXmppEventListener(listener); - - //Host, port, user, pass, resource - if (!client.connect("jabber.org.uk", 443, "ishmal", "PASSWORD", "myclient")) - { - printf("Connect failed\n"); - return false; - } - - //Group jabber id, nick, pass - client.groupChatJoin(groupJid, "mynick", ""); - - client.pause(8000); - - //Group jabber id, nick, msg - //client.groupChatMessage(groupJid, "hello, world"); - - client.pause(3000); - - //client.groupChatGetUserList(groupJid); - - client.pause(3000); - - //client.groupChatPrivateMessage("inkscape2@conference.gristle.org", - // "ishmal", "hello, world"); - client.message("ishmal@jabber.org.uk/https", "hey, bob"); - - client.pause(60000); - - //Group jabber id, nick - client.groupChatLeave(groupJid, "mynick"); - - client.pause(1000000); - - client.disconnect(); - - return true; -} - - -bool configTest() -{ - printf("#################################\n"); - printf("## C o n f i g t e s t\n"); - printf("#################################\n"); - - Pedro::XmppConfig config; - - if (!config.readFile("pedro.ini")) - { - printf("could not read config file\n"); - return false; - } - - Pedro::DOMString str = config.toXmlBuffer(); - - printf("#################################\n"); - printf("%s\n", str.c_str()); - - if (!config.writeFile("pedro2.ini")) - { - printf("could not write config file\n"); - return false; - } - - - return true; - -}; - - - -int main(int argc, char **argv) -{ - if (!configTest()) - return 1; - return 0; -} - |
