commit 9d20827c4609baa8b135212ed58c59ce92c2d549 Author: synzr Date: Thu Dec 25 01:37:49 2025 +0500 initial commit diff --git a/.darcs_binaries b/.darcs_binaries new file mode 100644 index 0000000..8c39a32 --- /dev/null +++ b/.darcs_binaries @@ -0,0 +1,41 @@ +# Binary file regexps: +\.png$ +\.PNG$ +\.gz$ +\.GZ$ +\.pdf$ +\.PDF$ +\.jpg$ +\.JPG$ +\.gif$ +\.GIF$ +\.tar$ +\.TAR$ +\.bz2$ +\.BZ2$ +\.z$ +\.Z$ +\.zip$ +\.ZIP$ +\.jar$ +\.JAR$ +\.so$ +\.SO$ +\.a$ +\.A$ +\.tgz$ +\.TGZ$ +\.jpeg$ +\.JPEG$ +\.mpg$ +\.MPG$ +\.mpeg$ +\.MPEG$ +\.iso$ +\.ISO$ +\.exe$ +\.EXE$ +\.doc$ +\.DOC$ +\.jisp$ +\.JISP$ diff --git a/.darcs_boring b/.darcs_boring new file mode 100644 index 0000000..e4ff429 --- /dev/null +++ b/.darcs_boring @@ -0,0 +1,140 @@ +# Boring file regexps: +\.hi$ +#\.o$ +\.o\.cmd$ +\.ko$ +\.ko\.cmd$ +\.mod\.c$ +(^|/)\.tmp_versions($|/) +#(^|/)CVS($|/) +(^|/)RCS($|/) +~$ +#(^|/)\.[^/] +(^|/)_darcs($|/) +\.bak$ +\.BAK$ +\.orig$ +(^|/)vssver\.scc$ +\.swp$ +(^|/)MT($|/) +(^|/)\{arch\}($|/) +(^|/).arch-ids($|/) +(^|/), +\.class$ +\.prof$ +(^|/)\.DS_Store$ +(^|/)BitKeeper($|/) +(^|/)ChangeSet($|/) +(^|/)\.svn($|/) +\.py[co]$ +\# +#\.cvsignore$ +(^|/)Thumbs\.db$ +(^|/)\.gdb_history$ + +# Mac OS X metadata +\/\._(.*) +^\._(.*) + +# Iris +^iris/example/xmpptest/xmpptest.app$ +^iris/example/xmpptest/Makefile$ + +# Irisnet +^iris/irisnet/Makefile$ +^iris/irisnet/(.*)\.o$ +^iris/irisnet/(.*)\.moc$ +^iris/irisnet/moc_(.*)\.cpp$ +^iris/irisnet/irisnet$ +^iris/irisnet/jdns/(.*)\.o$ +^iris/irisnet/jdns/Makefile$ +^iris/irisnet/jdns/jdns$ +^iris/irisnet/jdns/(.*)\.o$ + +# libjingle +^third-party/libjingle/Makefile +^third-party/libjingle/liblibjingle.a +^third-party/qca/Makefile +^third-party/qca/libqca.a + +# Binaries +^src/psi$ +^src/psi.app$ +^src/yachat$ +^src/yachat.app$ +^third-party/qca/libqca_psi.a$ + +# Mac binaries +^mac/disk +^mac/Psi-.* +^mac/(template|wc)\.dmg($|\.bz2$) + +# Windows +^psiwin/.*$ + +# QMake makefiles +^Makefile +^src/Makefile +^src/widgets/Makefile + +# QConf +^conf.log +^conf.pri +^src/config.h + +# Qt dirs +(^|/).ui($|/) +(^|/).obj($|/) +(^|/).moc($|/) +(^|/).rcc($|/) + +# YaStuff +^src/tools/yastuff/uitest/Makefile$ +^src/tools/yastuff/uitest/uitest$ +^src/tools/yastuff/yawidgets/Makefile$ +^src/tools/yastuff/yawidgets/libyawidgets.(so|dylib)$ +^src/tools/yastuff/yapsi_revision\.h$ +^src/tools/yastuff/yawidgets/chatviewtest/Makefile$ +^src/tools/yastuff/yawidgets/chatviewtest/chatviewtest$ +^src/tools/yastuff/yawidgets/customwindowtest/Makefile$ +^src/tools/yastuff/yawidgets/customwindowtest/customwindowtest$ +^src/tools/yastuff/yawidgets/expandingoverlaylineedittest/Makefile$ +^src/tools/yastuff/yawidgets/expandingoverlaylineedittest/expandingoverlaylineedittest$ +^src/tools/yastuff/yawidgets/newselfavatar/Makefile$ +^src/tools/yastuff/yawidgets/newselfavatar/newselfavatar$ +^src/tools/yastuff/yawidgets/rostertabstest/Makefile$ +^src/tools/yastuff/yawidgets/rostertabstest/rostertabtest$ +^src/tools/yastuff/yawidgets/rostertest/Makefile$ +^src/tools/yastuff/yawidgets/statusbartest/Makefile$ +^src/tools/yastuff/yawidgets/statusbartest/statusbartest$ +^src/tools/yastuff/yawidgets/chatviewbench/Makefile$ +^src/tools/yastuff/yawidgets/chatviewbench/chatviewbench$ +^src/tools/yastuff/yawidgets/tabbartest/Makefile$ +^src/tools/yastuff/yawidgets/tabbartest/tabbartest$ +^src/tools/yastuff/yawidgets/expandingoverlaylineedittest/expandingoverlaylineedittest.app$ +^src/tools/yastuff/yawidgets/rostertabstest/rostertabtest.app$ +^src/tools/yastuff/yawidgets/animatedstackedwidgettest/Makefile$ +^src/tools/yastuff/yawidgets/animatedstackedwidgettest/animatedstackedwidgettest.app$ +^src/tools/yastuff/yawidgets/trimmablemultilinelabeltest/test/test.app$ +^src/tools/yastuff/yawidgets/accountinformertest/Makefile$ +^src/tools/yastuff/yawidgets/accountinformertest/accountinformertest$ +^src/tools/yastuff/yawidgets/busywidgettest/(Makefile|busywidgettest(\.app)?)$ +^src/tools/yastuff/yawidgets/settingsbuttontest/(Makefile|settingsbuttontest(\.app)?)$ + +# Stuff +^tmtags$ + +# Compiled translations +^lang/(.*)\.qm$ + +# Tools +^src/tools/optionstree/(.*)\.o +^src/tools/optionstree/(.*)\.app +^src/tools/optionstree/moc_(.*)\.cpp +^src/tools/optionstree/options(.*)\.xml +^src/tools/optionstree/Makefile +^src/tools/optionstree/optionstreeviewtest/Makefile +^src/tools/optionstree/optionstreeviewtest/moc_(.*)\.cpp +^src/tools/contactlist/example/(.*)\.o +^src/tools/contactlist/example/(moc_)?(.*)\.(cpp|o|moc) +^src/tools/contactlist/example/(Makefile|contactlist) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5a8be2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +*.hi +*.o +*.o.cmd +*.ko +*.ko.cmd +*.mod.c +*.bak +*.BAK +*.orig +*.swp +.svn +*.dylib +*.user +*.xcodeproj + +# Mac OS X metadata +._* +.DS_Store +.AppleDouble +:2e_* + +*.app +*.moc +*.obj +*.rcc +moc_*.cpp +ui_*.h +Makefile +*.supp + +/tmtags +/conf.log +/conf.pri +/yachat +/yapsi_revision + +/mac/YaChat.dmg +/mac/template.dmg +/mac/template.dmg.bz2 +/mac/wc.dmg + +/src/*.plist diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e2aa4a0 --- /dev/null +++ b/COPYING @@ -0,0 +1,55 @@ +Перед использованием программы, пожалуйста, ознакомьтесь с условиями нижеследующего лицензионного соглашения. Любое использование вами программы означает полное и безоговорочное принятие вами его условий. +Если вы не принимаете условия лицензионного соглашения в полном объеме, вы не имеете права использовать программу в каких-либо целях. + +Лицензионное соглашение +на использование программы «Я.Онлайн» + +1. Общие положения +1.1. Настоящее Лицензионное соглашение («Лицензия») устанавливает условия использования программы для ЭВМ «Я.Онлайн», включая все дополнительные модули или расширения к ней («Программа»), и заключено между любым лицом, использующим Программу («Пользователь»), и ООО «ЯНДЕКС», Россия, 119021, г.Москва, ул. Льва Толстого, д. 16, являющимся правообладателем исключительного права на Программу («Правообладатель»). +1.2. Копируя Программу, устанавливая её на свой персональный компьютер или используя Программу любым образом, Пользователь выражает свое полное и безоговорочное согласие со всеми условиями Лицензии. +1.3. За исключением условий, изложенных в разделе 5 настоящей Лицензии, использование Программы разрешается только на условиях настоящей Лицензии. Если Пользователь не принимает условия Лицензии в полном объеме, Пользователь не имеет права использовать Программу в каких-либо целях. Использование Программы с нарушением (невыполнением) какого-либо из условий Лицензии запрещено. +1.4. Использование Программы на условиях настоящей Лицензии в личных некоммерческих целях осуществляется безвозмездно. Использование Программы на условиях и способами, не предусмотренными настоящей Лицензией, возможно только на основании отдельного соглашения с Правообладателем. +1.5. К настоящей Лицензии и всем отношениям, связанным с использованием Программы, подлежит применению право Российской Федерации и любые претензии или иски, вытекающие из настоящей Лицензии или использования Программы, должны быть поданы и рассмотрены в суде по месту нахождения Правообладателя. +1.6. Правообладатель может предоставить Пользователю перевод настоящей Лицензии с русского на другие языки, однако в случае противоречия между условиями Лицензии на русском языке и ее переводом, юридическую силу имеет исключительно русскоязычная версия Лицензии. + +2. Права на Программу +2.1. Исключительное право на Программу принадлежит Правообладателю. + +3. Лицензия +3.1. Правообладатель безвозмездно, на условиях простой (неисключительной) лицензии, предоставляет Пользователю непередаваемое право использования Программы на территории стран всего мира следующими способами: +3.1.1. Применять Программу по прямому функциональному назначению, в целях чего произвести её копирование и установку (воспроизведение) на персональном(-ых) компьютере(-ах) Пользователя. Пользователь вправе произвести установку Программы на неограниченное число персональных компьютеров. При установке на персональный компьютер каждой копии Программы присваивается индивидуальный номер, который автоматически сообщается Правообладателю. +3.1.2. Воспроизводить и распространять Программу в некоммерческих целях (безвозмездно). + +4. Ограничения +4.1. За исключением использования в объемах и способами, прямо предусмотренными настоящей Лицензией или законодательством РФ, Пользователь не имеет права изменять, декомпилировать, дизассемблировать, дешифровать и производить иные действия с объектным кодом Программы или отдельных её компонентов, имеющие целью получение информации о реализации алгоритмов, используемых в Программе, создавать производные произведения с использованием Программы или её компонентов, а также осуществлять (разрешать осуществлять) иное использование Программы, без письменного согласия Правообладателя. +4.2. Пользователь не имеет права воспроизводить и распространять Программу в коммерческих целях (в том числе за плату), в том числе в составе сборников программных продуктов, без письменного согласия Правообладателя. +4.3. Программа должна использоваться под наименованием: «Я.Онлайн». Пользователь не вправе изменять наименование Программы или отдельных её компонентов, изменять и/или удалять знак охраны авторского права (copyright notice) или иное указание на Правообладателя. + +5. Условия использования отдельных функций Программы +5.1. Пользователь настоящим уведомлен и соглашается, что при включении в Программе функции «История общения» (по умолчанию – включена) все сообщения, направленные Пользователем и/или в адрес Пользователя с использованием Программы, сохраняются на аппаратных средствах Правообладателя, до момента отключения указанной функции. +При включении функции «Хранить настройки на сервере» (по умолчанию – включена) все настройки Пользователя, в том числе введенные Пользователем логины и пароли для доступа к его учетным записям, сохраняются на аппаратных средствах Правообладателя, до момента отключения данной функции. +История общения, сохраненные настройки, а также управление параметрами ее сохранения доступны для Пользователя в настройках Программы при вводе логина и пароля учетной записи Пользователя. +5.2. Пользователь настоящим уведомлен и соглашается, что при включении в Программе функции «Сбор почты», для подключения к данной функции почтового ящика Пользователя, расположенного как в почтовом сервисе Правообладателя, так и в почтовых сервисах, принадлежащих третьим лицам, Пользователь должен ввести логин и пароль для доступа к соответствующей учетной записи почтового сервиса, и они будут сохранены на аппаратных средствах Правообладателя. Пользователь самостоятельно отвечает за правомерность подобного использования логинов и паролей учетных записей и несет все риски такого использования, включая риски нарушения правил использования соответствующего почтового сервиса и/или прав третьих лиц. +5.3. Пользователь может в любой момент отказаться от передачи данных, указанных в п. 5.1, отключив соответствующие функции. +5.4. Все данные об использовании Программы, передаваемые в соответствии с настоящей Лицензией, сохраняются и обрабатываются в соответствии с Политикой конфиденциальности (http://legal.yandex.ru/confidential/). +5.5. При создании программы «Я.Чат», распространяемой совместно с Программой, использован модифицированный исходный код программы «Psi» (Copyright © The Psi Team, 2001-2008), распространяемой на условиях лицензии GNU GPL версии 2. В связи с этим данная программа также распространяется на условиях лицензии GNU GPL версии 2, с которыми можно ознакомиться по адресу http://download.yandex.ru/online/GPL.txt. К использованию программы «Я.Чат» применяются также все требования настоящей Лицензии в части, не противоречащей условиям лицензии GNU GPL версии 2. Исходный код программы «Я.Чат» доступен по адресу: http://download.yandex.ru/online/yachat-source.zip. +5.6. При создании версии Программы для Microsoft Windows использована библиотека isxdl.dll, входящая в состав программы «ISTools» (www.istool.org, Copyright © 2009, Bjørnar Henden. All rights reserved.). Указанное программное обеспечение может использоваться на условиях, доступных для ознакомления по адресу: http://download.yandex.ru/online/addons/ISToolLicense.rtf. +5.7. При создании Программы использовано программное обеспечение, разработанное The OpenSSL Project для использования в «OpenSSL Toolkit» (www.openssl.org, Copyright © 1998-2008, The OpenSSL Project. All rights reserved.). Указанное программное обеспечение может использоваться на условиях, доступных для ознакомления по адресу: http://www.openssl.org/source/license.html. +5.8. При создании Программы использовано программное обеспечение разработанное Tim Hudson (tjh@cryptsoft.com). +5.9. При создании версии Программы для Microsoft Windows использована библиотека «Loudmouth», разработанная Imendio AB (http://projects.imendio.com/loudmouth, Copyright © 2003 Imendio AB), распространяемая на условиях лицензии GNU LGPL версии 3. Указанное программное обеспечение может использоваться на условиях, доступных для ознакомления по адресу: http://www.gnu.org/copyleft/lesser.html. + +6. Ограничение ответственности по Лицензии +6.1. Программа предоставляется на условиях «как есть» (as is). Правообладатель не предоставляет никаких гарантий в отношении безошибочной и бесперебойной работы Программы или отдельных её компонентов, соответствия Программы конкретным целям и ожиданиям Пользователя, а также не предоставляет никаких иных гарантий, прямо не указанных в настоящей Лицензии. +6.2. В максимальной степени, допустимой действующим законодательством, Правообладатель не несет никакой ответственности за какие-либо прямые или косвенные последствия какого-либо использования или невозможности использования Программы и/или ущерб, причиненный Пользователю и/или третьим сторонам в результате какого-либо использования, неиспользования или невозможности использования Программы или отдельных её компонентов и/или функций, в том числе из-за возможных ошибок или сбоев в работе Программе. +6.3. Пользователь настоящим уведомлен и соглашается, что при использовании Программы Правообладателю в автоматическом режиме анонимно (без привязки к Пользователю) передается следующая информация: тип операционной системы компьютера Пользователя, версия и идентификатор Программы, статистика использования функций Программы, а также иная техническая информация. + +7.Обновления/новые версии Программы +7.1. Действие настоящей Лицензии распространяется на все последующие обновления/новые версии Программы. Соглашаясь с установкой обновления/новой версии Программы, Пользователь принимает условия настоящей Лицензии для соответствующих обновлений/новых версий Программы, если обновление/установка новой версии Программы не сопровождается иным лицензионным соглашением. + +8. Изменения условий настоящей Лицензии +8.1. Настоящее лицензионное соглашение может изменяться Правообладателем в одностороннем порядке. Уведомление Пользователя о внесенных изменениях в условия настоящей Лицензии публикуется на странице: http://legal.yandex.ru/online_agreement/. Указанные изменения в условиях лицензионного соглашения вступают в силу с даты их публикации, если иное не оговорено в соответствующей публикации. + +Версия для Microsoft Windows © 2007-2011 ООО «ЯНДЕКС» +Версия для Mac OS X © 2008-2011 ООО «ЯНДЕКС» +Версия для Linux © 2008-2011 ООО «ЯНДЕКС» + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e8e6e6b --- /dev/null +++ b/INSTALL @@ -0,0 +1,35 @@ +Installation +------------ + +-=[ Important ]=- + + For best experience, use of patched Qt is adviced: all required patches + are provided in qt-patches directory. + +-=[ Linux / Unix ]=- + + For instructions on how to build and install Psi on Unix systems, see + the 'Compiling' section below. + +-=[ Windows ]=- + + No installation required for Windows. You can simply just + run the Psi executable. You might want to move everything into + C:\Program Files\Psi + +-=[ MacOS X ]=- + + Drag the Psi application file from the disk image into the Applications dir. + + +Compiling +--------- + +Requirements: + - Qt 4.5.x with patches + +You can obtain Qt at http://www.trolltech.com/ + +For information about building Psi on Unix, see doc/build-unix.txt. +For information about building Psi on Mac OS X, see doc/build-mac.txt. +For information about building Psi on Windows, see doc/build-win.txt. diff --git a/README b/README new file mode 100644 index 0000000..db4c25a --- /dev/null +++ b/README @@ -0,0 +1,21 @@ +Chat module of Ya.Online 3.0.3 +------------------------------ +Date: December 16, 2009 + +Project Manager: + Dmitry Matveev + http://matv.ru/ + +Lead Develoeper: + Michail Pishchagin + http://mblsha.psi-im.org/ + +Chat module of Ya.Online is project aimed to deliver a +Yandex-branded jabber client for the general public. + +Chat module of Ya.Online is based on Psi (http://psi-im.org). + +For installation or compiling instructions, see the INSTALL file. + +This program is licensed under the GNU General Public License. See +the COPYING file for more information. diff --git a/admin/bundle_qca.sh b/admin/bundle_qca.sh new file mode 100644 index 0000000..4570c5c --- /dev/null +++ b/admin/bundle_qca.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +TARGET=third-party + +################################################################################ +# QCA +################################################################################ + +QCA_SOURCE=../qca +QCA_TARGET=third-party/qca + +rm -rf $QCA_TARGET +cp -r $QCA_SOURCE/src $QCA_TARGET +cp -r $QCA_SOURCE/certs $QCA_TARGET +cp -r $QCA_SOURCE/include $QCA_TARGET +rm $QCA_TARGET/qt.tag $QCA_TARGET/src.pro +echo 'include(../qca.pri)' > $QCA_TARGET/qca.pro + +################################################################################ +# QCA-OpenSSL +################################################################################ + +QCAOPENSSL_SOURCE=../qca-openssl +QCAOPENSSL_TARGET=third-party/qca-openssl +rm -rf $QCAOPENSSL_TARGET +cp -r $QCAOPENSSL_SOURCE $QCA_OPENSSL_TARGET diff --git a/admin/legoptx.txt b/admin/legoptx.txt new file mode 100644 index 0000000..00a452b --- /dev/null +++ b/admin/legoptx.txt @@ -0,0 +1,154 @@ +==========bool: +useleft psi/options/ui/contactlist/use-left-click +singleclick psi/options/ui/contactlist/use-single-click +!hideMenubar psi/options/ui/contactlist/show-menubar +useTransportIconsForContacts psi/options/ui/contactlist/use-transport-icons +alwaysOnTop psi/options/ui/contactlist/always-on-top +keepSizes psi/options/ui/remember-window-sizes +ignoreHeadline psi/options/message/ignore-headlines +ignoreNonRoster psi/options/message/ignore-non-roster-contacts +excludeGroupChatsFromIgnore psi/options/messages/exclude-muc-from-ignore +scrollTo psi/options/ui/contactlist/ensure-contact-visible-on-event +useEmoticons psi/options/ui/emoticons/use-emoticons +alertOpenChats psi/options/ui/chat/alert-for-already-open-chats +raiseChatWindow psi/options/ui/chat/raise-chat-windows-on-new-messages +showSubjects psi/options/ui/message/show-subjects +showGroupCounts psi/options/ui/contactlist/show-group-counts +showCounter psi/options/ui/message/show-character-count +chatSays psi/options/ui/chat/use-chat-says-style +jidComplete psi/options/ui/message/use-jid-auto-completion +grabUrls psi/options/ui/message/auto-grab-urls-from-clipboard +smallChats psi/options/ui/chat/use-small-chats +brushedMetal psi/options/ui/mac/use-brushed-metal-windows +chatLineEdit psi/options/ui/chat/use-expanding-line-edit +useTabs psi/options/ui/tabs/use-tabs +usePerTabCloseButton UNUSED +putTabsAtBottom psi/options/ui/tabs/put-tabs-at-bottom +autoRosterSize psi/options/ui/contactlist/automatically-resize-roster +autoRosterSizeGrowTop psi/options/ui/contactlist/grow-roster-upwards +autoResolveNicksOnAdd psi/options/contactlist/resolve-nicks-on-contact-add +messageEvents psi/options/message/send-composing-events +inactiveEvents psi/options/message/send-inactivity-events +autoCopy psi/options/ui/automatically-copy-selected-text +useCaps DIE? +useRC psi/options/external-control/adhoc-remote-control/enable +useDock psi/options/systemtray/enable +dockDCstyle psi/options/systemtray/use-double-click +dockHideMW psi/options/contactlist/hide-on-start +dockToolMW psi/options/contactlist/use-toolwindow +autoAuth psi/options/subscriptions/automatically-allow-authorisation +notifyAuth psi/options/ui/notifications/successful-subscription +popupMsgs psi/options/ui/message/auto-popup +popupChats psi/options/ui/chat/auto-popup +popupHeadlines psi/options/ui/message/auto-popup-headlines +popupFiles psi/options/ui/file-transfer/auto-popup +noAwayPopup psi/options/ui/notifications/popup-dialogs/suppress-while-away +noUnlistedPopup psi/options/ui/notifications/popup-dialogs/suppress-when-not-on-roster +raise psi/options/ui/contactlist/raise-on-new-event +askOnline psi/options/status/ask-for-message-on-online +askOffline psi/options/status/ask-for-message-on-offline +rosterAnim psi/options/ui/contactlist/use-status-change-animation +autoVCardOnLogin psi/options/vcard/prompt-on-login-for-empty-vcard +xmlConsoleOnLogin psi/options/vcard/xml-console/enable-at-login +use_asAway psi/options/status/auto-away/use-away +use_asXa psi/options/status/auto-away/use-not-availible +use_asOffline psi/options/status/auto-away/use-offline +clNewHeadings psi/options/look/use-slim-group-headings +outlineHeadings psi/options/look/use-outlined-group-headings +noAwaySound psi/options/ui/notifications/sounds/silent-while-away +!noGCSound psi/options/ui/notifications/sounds/notify-every-muc-message +gcNickColoring psi/options/ui/muc/use-nick-coloring +gcHighlighting psi/options/ui/muc/use-highlighting +ppIsOn psi/options/ui/notifications/passive-popups/enabled +ppOnline psi/options/ui/notifications/passive-popups/status/online +ppOffline psi/options/ui/notifications/passive-popups/status/offline +ppStatus psi/options/ui/notifications/passive-popups/status/other-changes +ppMessage psi/options/ui/notifications/passive-popups/incoming-message +ppChat psi/options/ui/notifications/passive-popups/incoming-chat +ppHeadline psi/options/ui/notifications/passive-popups/incoming-headline +ppFile psi/options/ui/notifications/passive-popups/incoming-file-transfer +lockdown.roster psi/options/ui/contactlist/lockdown-roster +lockdown.services psi/options/ui/contactlist/disable-service-discovery +discoItems psi/options/ui/service-discovery/automatically-get-items +discoInfo psi/options/ui/service-discovery/automatically-browse-into +useSound psi/options/ui/notifications/sounds/enable + +==========int: +ppJidClip psi/options/ui/notifications/passive-popups/maximum-jid-length +ppStatusClip psi/options/ui/notifications/passive-popups/maximum-status-length +ppTextClip psi/options/ui/notifications/passive-popups/maximum-text-length +ppHideTime psi/options/ui/notifications/passive-popups/duration +eventPriorityMessage +eventPriorityChat +eventPriorityHeadline +eventPriorityAuth +eventPriorityFile +eventPriorityRosterExchange +dtPort psi/options/p2p/bytestreams/listen-port +asOffline psi/options/status/auto-away/offline-after +asXa psi/options/status/auto-away/not-availible-after +asAway psi/options/status/auto-away/away-after +alertStyle psi/options/ui/notifications/??? +delChats psi/options/ui/chat/contents-after +defaultAction psi/options/message/default-outgoing-message-type +incomingAs psi/options/message/force-incoming-message-type + +=========QSize: +sizeEventDlg psi/options/ui/message/size +sizeTabDlg psi/options/ui/tabs/size + +=========QColor +ppBorderColor psi/options/ui/look/colors/passive-popup/border +color.Online psi/options/ui/look/colors/contactlist/status/online +color.ListBack psi/options/ui/look/colors/contactlist/background +color.Away psi/options/ui/look/colors/contactlist/status/away +color.DND psi/options/ui/look/colors/contactlist/status/do-no-disturb +color.Offline psi/options/ui/look/colors/contactlist/status/offline +color.Status psi/options/ui/look/colors/contactlist/status-messages +color.GroupFore psi/options/ui/look/colors/contactlist/grouping/header-foreground +color.GroupBack psi/options/ui/look/colors/contactlist/grouping/header-background +color.ProfileFore psi/options/ui/look/colors/contactlist/profile/header-foreground +color.ProfileBack psi/options/ui/look/colors/contactlist/profile/header-background +color.AnimFront psi/options/ui/look/contactlist/status-change-animation/color1 +color.AnimBack psi/options/ui/look/contactlist/status-change-animation/color2 + +=========QStringList +emoticons psi/options/iconsets/emoticons +gcHighlights psi/options/ui/muc/highlight-words +gcNickColors psi/options/ui/look/colors/muc/nick-colors +recentGCList psi/options/muc/recent-joins/jids +recentBrowseList psi/options/ui/service-discovery/recent-jids + +=========QString: +systemIconset psi/options/iconsets/system +defaultRosterIconset psi/options/iconsets/status +asMessage psi/options/status/auto-away/message +player psi/options/ui/notifications/sounds/unix-sound-player +dtExternal psi/options/p2p/bytestreams/external-address +lastPath psi/options/ui/last-used-open-path +lastSavePath psi/options/ui/last-used-save-path +lastStatusString psi/options/status/last-message +onevent.Message psi/options/ui/notifications/sounds/incoming-message +onevent.Chat1 psi/options/ui/notifications/sounds/new-chat +onevent.Chat2 psi/options/ui/notifications/sounds/chat-message +onevent.System psi/options/ui/notifications/sounds/system-message +onevent.Headline psi/options/ui/notifications/sounds/incoming-headline +onevent.Online psi/options/ui/notifications/sounds/contact-online +onevent.Offline psi/options/ui/notifications/sounds/contact-offline +onevent.Send psi/options/ui/notifications/sounds/outgoing-chat +onevent.IncomingFT psi/options/ui/notifications/sounds/incoming-file-transfer +onevent.FTComplete psi/options/ui/notifications/sounds/completed-file-transfer +font.Roster psi/options/ui/look/font/contactlist +font.Message psi/options/ui/look/font/message +font.Chat psi/options/ui/look/font/chat +font.Popup psi/options/ui/look/font/passive-popup +bounceDock psi/options/ui/notifications/bounce-dock +rosterContactSortStyle psi/options/ui/contactlist/contact-sort-style +rosterGroupSortStyle psi/options/ui/contactlist/group-sort-style +rosterAccountSortStyle psi/options/ui/contactlist/account-sort-style + +=========== QMaps: +sp psi/options/status/presets +serviceRosterIconset psi/options/iconsets/service-status +customRosterIconset psi/options/iconsets/custom-status +mainwintoolbars psi/options/ui/contactlist/toolbars diff --git a/admin/prune.sh b/admin/prune.sh new file mode 100644 index 0000000..50badbb --- /dev/null +++ b/admin/prune.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +rm -rf _darcs .darcs_boring .darcs_binaries +rm -rf TODO +rm -rf configure-jingle psi-jingle.qc +rm -rf third-party/qca/qca third-party/qca/qca-openssl third-party/qca/qca-sasl third-party/qca/qca-gnupg +rm -rf third-party/customjinglefiles.txt third-party/libjingle third-party/libjingle.new +rm -rf admin diff --git a/admin/update_iconsets.sh b/admin/update_iconsets.sh new file mode 100644 index 0000000..10b53b0 --- /dev/null +++ b/admin/update_iconsets.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +SOURCE_DIR=../../iconsets +TARGET_DIR=../iconsets + +ROSTER_DEFAULT='crystal-roster' +ROSTER_EXTRAS=' + crystal-aim crystal-icq crystal-msn crystal-service crystal-yahoo + crystal-gadu crystal-sms crystal-roster + ' + +SYSTEM_DEFAULT='crystal-system' +SYSTEM_EXTRAS='' + +################################################################################ + +if test ! -d $SOURCE_DIR; then + echo "Cannot find source dir $SOURCE_DIR" + exit +fi + +if test ! -d $TARGET_DIR; then + echo "Cannot find target dir $TARGET_DIR" + exit +fi + +################################################################################ + +# Roster iconsets +echo '*** Updating Roster iconsets ***' +#cp -R $SOURCE_DIR/roster/$ROSTER_DEFAULT/* $TARGET_DIR/roster/default +rm -f $TARGET_DIR/roster/default/Makefile +for i in $ROSTER_EXTRAS; do + make -C $SOURCE_DIR/roster $i.jisp + cp $SOURCE_DIR/roster/$i.jisp $TARGET_DIR/roster +done + +################################################################################ + +# System iconsets +echo '*** Updating System iconsets ***' +#cp -R $SOURCE_DIR/system/$SYSTEM_DEFAULT/* $TARGET_DIR/system/default +rm -f $TARGET_DIR/system/default/Makefile +for i in $SYSTEM_EXTRAS; do + make -C $SOURCE_DIR/system $i.jisp + cp $SOURCE_DIR/system/$i.jisp $TARGET_DIR/system +done diff --git a/admin/update_options_ts.py b/admin/update_options_ts.py new file mode 100644 index 0000000..faf3260 --- /dev/null +++ b/admin/update_options_ts.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +from xml.dom.minidom import parse, parseString +import xml.dom +import sys + +def rec_parse(node, context): # node : xml.dom.Node + for i in node.childNodes: + if i.nodeType == xml.dom.Node.ELEMENT_NODE: + if i.hasAttribute("comment"): + print 'QT_TRANSLATE_NOOP("' + context + '","' + i.getAttribute("comment") + '");'; + rec_parse(i,context) + + +if len(sys.argv) != 2: + print "usage: %s options.xml > output.cpp" % sys.argv[0] + sys.exit(1) + +print "#define QT_TRANSLATE_NOOP(a,b)" + +dom = parse(sys.argv[1]) # parse an XML file by name + +toplevel = dom.getElementsByTagName("psi")[0] +options = toplevel.getElementsByTagName("options")[0] + +shortcuts = options.getElementsByTagName("shortcuts")[0] +rec_parse(shortcuts,"Shortcuts") diff --git a/certs/README b/certs/README new file mode 100644 index 0000000..bb498c5 --- /dev/null +++ b/certs/README @@ -0,0 +1,11 @@ +This directory contains the SSL certificates shipped with psi. The files should be in PEM format, and should have the extension '.crt' or '.pem'. + +Please use PSIDATADIR/certs for local additions. + +Default value of PSIDATADIR: + Linux, MacOS X and other Unices + ~/.psi/ + Windows NT, 2000, XP and Server 2003 + %UserProfile%\PsiData\ (usually C:\Documents and Settings\username\PsiData ) + Windows 95, 98 and Me + %ProgramFiles%\Psi\PsiData\ (usually C:\Program Files\Psi\PsiData ) diff --git a/certs/rootcerts.pem b/certs/rootcerts.pem new file mode 100644 index 0000000..ead8f9a --- /dev/null +++ b/certs/rootcerts.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIBrDCCAVYCCQCJJPs4An5zrTANBgkqhkiG9w0BAQQFADBdMQswCQYDVQQGEwJS +VTETMBEGA1UECBMKU29tZS1TdGF0ZTEPMA0GA1UEBxMGTW9zY293MQ8wDQYDVQQK +EwZZYW5kZXgxFzAVBgNVBAMTDm90cnMueWFuZGV4LnJ1MB4XDTA1MDMwNDExNTAy +MFoXDTA1MDUwMzExNTAyMFowXTELMAkGA1UEBhMCUlUxEzARBgNVBAgTClNvbWUt +U3RhdGUxDzANBgNVBAcTBk1vc2NvdzEPMA0GA1UEChMGWWFuZGV4MRcwFQYDVQQD +Ew5vdHJzLnlhbmRleC5ydTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDpsqoHlz06 +dkWHqBYvaw0xHHmXlLQ11HE8/LvKGmPIfkUEw27H9qjCCoRAqyGdsPr5jUVsRf46 +GeVZiFfN1YxNAgMBAAEwDQYJKoZIhvcNAQEEBQADQQDcCmIjo5OvcH1d8dXy9GCC +bNsa9RDPsR2XWfMd44vq1JmRnqTvbV44UdG+S5yKlOm5b9a4MbBJytSJr20/fUTE +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC7zCCAligAwIBAgIJAP1+T3fKl1p3MA0GCSqGSIb3DQEBBAUAMFkxEzARBgNV +BAoTCnlhbmRleC5uZXQxDDAKBgNVBAsTA2JvYTEQMA4GA1UEAxMHeWFiYmVyZDEi +MCAGCSqGSIb3DQEJARYTcm9vdEBib2EueWFuZGV4Lm5ldDAeFw0wNjA5MTkwOTM0 +NTdaFw0wNzA5MTkwOTM0NTdaMFkxEzARBgNVBAoTCnlhbmRleC5uZXQxDDAKBgNV +BAsTA2JvYTEQMA4GA1UEAxMHeWFiYmVyZDEiMCAGCSqGSIb3DQEJARYTcm9vdEBi +b2EueWFuZGV4Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAz6nPMiYp +tTq3K1mB9r0w+yCb3xyj8xJ5fimq06K1mnC8sj9O5h8z+BC9Eq98CyOOJ1jnorP4 +YGT7KPPWxl1Cq1MUX7HAjaf/Q3ubSOUS+2kJHFcpxbjGO8ZW7KXRK+5mbCe8PEKB +jtnOaNtS68VMXY2bjW4TTxMf5KuxH1k8d4cCAwEAAaOBvjCBuzAdBgNVHQ4EFgQU +VZjHsJGTojkcBDqdtloLeNeLg84wgYsGA1UdIwSBgzCBgIAUVZjHsJGTojkcBDqd +tloLeNeLg86hXaRbMFkxEzARBgNVBAoTCnlhbmRleC5uZXQxDDAKBgNVBAsTA2Jv +YTEQMA4GA1UEAxMHeWFiYmVyZDEiMCAGCSqGSIb3DQEJARYTcm9vdEBib2EueWFu +ZGV4Lm5ldIIJAP1+T3fKl1p3MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD +gYEAMgOrhadTWkboYsYI4kAWvm+XuNrAIrjM2YGAfO4cSU8oWk24ZXGep3S+kbAC +2Yhm76I2ZS0tmQH9P3zjoIMGXbhoy3PGX7DNx8BOeI5bTzE6dMoonUSCXW4yFyRq +PnJ74wrRZK6UXHbwcJzZdqv1oXvltHKeiKe2+ilSv+XT838= +-----END CERTIFICATE----- diff --git a/certs/startcom_ca.crt b/certs/startcom_ca.crt new file mode 100644 index 0000000..957842c --- /dev/null +++ b/certs/startcom_ca.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx +DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0 +Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS +YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0 +OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp +bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp +dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x +18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5 +yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI +LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G +A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW +zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT +BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x +GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh +cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV +HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G +CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy +BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j +cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ +YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/ +YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1 +ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p +00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb +cCOxgN8aIDjnfg== +-----END CERTIFICATE----- diff --git a/conf_windows.pri b/conf_windows.pri new file mode 100644 index 0000000..8c35a77 --- /dev/null +++ b/conf_windows.pri @@ -0,0 +1,31 @@ +# Windows build settings +CONFIG += release +CONFIG += qca-static + +# tell iris to use our internal libz +CONFIG += psi-zip + +# OpenSSL +qca-static { + DEFINES += HAVE_OPENSSL + DEFINES += OSSL_097 + OPENSSL_PREFIX = $$PWD/../vendor/openssl + INCLUDEPATH += $$OPENSSL_PREFIX/include + LIBS += -L$$OPENSSL_PREFIX/lib +} + +# SASL +#qca-static { +# CYRUSSASL_PREFIX = /local +# INCLUDEPATH += $$CYRUSSASL_PREFIX/include +# LIBS += $$CYRUSSASL_PREFIX/lib/libsasl.lib +#} + +# ASpell +#DEFINES += HAVE_ASPELL +contains(DEFINES, HAVE_ASPELL) { + ASPELL_PREFIX = ../../../aspell + INCLUDEPATH += "$$ASPELL_PREFIX/include" + LIBS += -L"$$ASPELL_PREFIX/lib" + LIBS += -laspell-15 +} diff --git a/configure b/configure new file mode 100644 index 0000000..60c2877 --- /dev/null +++ b/configure @@ -0,0 +1,2303 @@ +#!/bin/sh +# +# Generated by qconf 1.4 ( http://delta.affinix.com/qconf/ ) +# + +show_usage() { +cat </dev/null` + if echo $WHICH | grep 'shell built-in command' >/dev/null 2>&1; then + WHICH=which + elif [ -z "$WHICH" ]; then + if which which >/dev/null 2>&1; then + WHICH=which + else + for a in /usr/ucb /usr/bin /bin /usr/local/bin; do + if [ -x $a/which ]; then + WHICH=$a/which + break; + fi + done + fi + fi + + if [ -z "$WHICH" ]; then + OLD_IFS=$IFS + IFS=: + for a in $PATH; do + if [ -x $a/$1 ]; then + echo "$a/$1" + IFS=$OLD_IFS + export IFS + HOME=$OLD_HOME + export HOME + return 0 + fi + done + IFS=$OLD_IFS + export IFS + else + a=`"$WHICH" "$1" 2>/dev/null` + if [ ! -z "$a" -a -x "$a" ]; then + echo "$a" + HOME=$OLD_HOME + export HOME + return 0 + fi + fi + HOME=$OLD_HOME + export HOME + return 1 +} +WHICH=which_command + +# find a make command +if [ -z "$MAKE" ]; then + MAKE= + for mk in gmake make; do + if $WHICH $mk >/dev/null 2>&1; then + MAKE=`$WHICH $mk` + break + fi + done + if [ -z "$MAKE" ]; then + echo "You don't seem to have 'make' or 'gmake' in your PATH." + echo "Cannot proceed." + exit 1 + fi +fi + +show_qt_info() { + printf "Be sure you have a proper Qt 4.0 build environment set up. This means not\n" + printf "just Qt, but also a C++ compiler, a make tool, and any other packages\n" + printf "necessary for compiling C++ programs.\n" + printf "\n" + printf "If you are certain everything is installed, then it could be that Qt 4 is not\n" + printf "being recognized or that a different version of Qt is being detected by\n" + printf "mistake (for example, this could happen if \$QTDIR is pointing to a Qt 3\n" + printf "installation). At least one of the following conditions must be satisfied:\n" + printf "\n" + printf " 1) --qtdir is set to the location of Qt\n" + printf " 2) \$QTDIR is set to the location of Qt\n" + printf " 3) QtCore is in the pkg-config database\n" + printf " 4) qmake is in the \$PATH\n" + printf "\n" + printf "This script will use the first one it finds to be true, checked in the above\n" + printf "order. #3 and #4 are the recommended options. #1 and #2 are mainly for\n" + printf "overriding the system configuration.\n" + printf "\n" +} + +while [ $# -gt 0 ]; do + optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + case "$1" in + --prefix=*) + PREFIX=$optarg + shift + ;; + + --bindir=*) + BINDIR=$optarg + shift + ;; + + --datadir=*) + DATADIR=$optarg + shift + ;; + + --qtdir=*) + EX_QTDIR=$optarg + shift + ;; + + --certstore-path=*) + QC_CERTSTORE_PATH=$optarg + shift + ;; + + --disable-bundled-qca) + QC_DISABLE_bundled_qca="Y" + shift + ;; + + --disable-openssl) + QC_DISABLE_openssl="Y" + shift + ;; + + --with-openssl-inc=*) + QC_WITH_OPENSSL_INC=$optarg + shift + ;; + + --with-openssl-lib=*) + QC_WITH_OPENSSL_LIB=$optarg + shift + ;; + + --with-zlib-inc=*) + QC_WITH_ZLIB_INC=$optarg + shift + ;; + + --with-zlib-lib=*) + QC_WITH_ZLIB_LIB=$optarg + shift + ;; + + --enable-universal) + QC_ENABLE_universal="Y" + shift + ;; + + --disable-qdbus) + QC_DISABLE_qdbus="Y" + shift + ;; + + --disable-growl) + QC_DISABLE_growl="Y" + shift + ;; + + --with-growl=*) + QC_WITH_GROWL=$optarg + shift + ;; + + --disable-xss) + QC_DISABLE_xss="Y" + shift + ;; + + --disable-dnotify) + QC_DISABLE_dnotify="Y" + shift + ;; + + --disable-ghbnr) + QC_DISABLE_ghbnr="Y" + shift + ;; + + --disable-aspell) + QC_DISABLE_aspell="Y" + shift + ;; + + --with-aspell-inc=*) + QC_WITH_ASPELL_INC=$optarg + shift + ;; + + --with-aspell-lib=*) + QC_WITH_ASPELL_LIB=$optarg + shift + ;; + + --enable-tests) + QC_ENABLE_tests="Y" + shift + ;; + + --with-cppunit-inc=*) + QC_WITH_CPPUNIT_INC=$optarg + shift + ;; + + --with-cppunit-lib=*) + QC_WITH_CPPUNIT_LIB=$optarg + shift + ;; + + --enable-debug) + QC_ENABLE_DEBUG="Y" + shift + ;; + + --verbose) + QC_VERBOSE="Y" + shift + ;; + --help) show_usage; exit ;; + *) show_usage; exit ;; + esac +done + +PREFIX=${PREFIX:-/usr/local} +BINDIR=${BINDIR:-$PREFIX/bin} +DATADIR=${DATADIR:-$PREFIX/share} + +echo "Configuring Psi ..." + +if [ "$QC_VERBOSE" = "Y" ]; then +echo +echo PREFIX=$PREFIX +echo BINDIR=$BINDIR +echo DATADIR=$DATADIR +echo EX_QTDIR=$EX_QTDIR +echo QC_CERTSTORE_PATH=$QC_CERTSTORE_PATH +echo QC_DISABLE_bundled_qca=$QC_DISABLE_bundled_qca +echo QC_DISABLE_openssl=$QC_DISABLE_openssl +echo QC_WITH_OPENSSL_INC=$QC_WITH_OPENSSL_INC +echo QC_WITH_OPENSSL_LIB=$QC_WITH_OPENSSL_LIB +echo QC_WITH_ZLIB_INC=$QC_WITH_ZLIB_INC +echo QC_WITH_ZLIB_LIB=$QC_WITH_ZLIB_LIB +echo QC_ENABLE_universal=$QC_ENABLE_universal +echo QC_DISABLE_qdbus=$QC_DISABLE_qdbus +echo QC_DISABLE_growl=$QC_DISABLE_growl +echo QC_WITH_GROWL=$QC_WITH_GROWL +echo QC_DISABLE_xss=$QC_DISABLE_xss +echo QC_DISABLE_dnotify=$QC_DISABLE_dnotify +echo QC_DISABLE_ghbnr=$QC_DISABLE_ghbnr +echo QC_DISABLE_aspell=$QC_DISABLE_aspell +echo QC_WITH_ASPELL_INC=$QC_WITH_ASPELL_INC +echo QC_WITH_ASPELL_LIB=$QC_WITH_ASPELL_LIB +echo QC_ENABLE_tests=$QC_ENABLE_tests +echo QC_WITH_CPPUNIT_INC=$QC_WITH_CPPUNIT_INC +echo QC_WITH_CPPUNIT_LIB=$QC_WITH_CPPUNIT_LIB +echo QC_ENABLE_DEBUG=$QC_ENABLE_DEBUG +echo +fi + +printf "Verifying Qt 4 build environment ... " + +# run qmake -v and check version +qmake_check_v4() { + if [ -x "$1" ]; then + if echo `$1 -v 2>&1` | grep "Qt version 4\." >/dev/null 2>&1; then + return 0 + elif [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: $1 not for Qt 4" + fi + fi + return 1 +} + +if [ "$QC_VERBOSE" = "Y" ]; then + echo +fi + +qm="" +names="qmake-qt4 qmake4 qmake" + +# qt4 check: --qtdir +if [ -z "$qm" ] && [ ! -z "$EX_QTDIR" ]; then + for n in $names; do + qstr=$EX_QTDIR/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via --qtdir" +fi + +# qt4 check: QTDIR +if [ -z "$qm" ] && [ ! -z "$QTDIR" ]; then + for n in $names; do + qstr=$QTDIR/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via \$QTDIR" +fi + +# qt4 check: pkg-config +if [ -z "$qm" ]; then + str=`pkg-config QtCore --variable=exec_prefix 2>/dev/null` + if [ ! -z "$str" ]; then + for n in $names; do + qstr=$str/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done + fi +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via pkg-config" +fi + +# qt4 check: PATH +if [ -z "$qm" ]; then + for n in $names; do + qstr=`$WHICH $n 2>/dev/null` + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via \$PATH" +fi + +if [ -z "$qm" ]; then + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + printf "\n" + printf "Reason: Unable to find the 'qmake' tool for Qt 4.\n" + printf "\n" + show_qt_info + exit 1; +fi +if [ "$QC_VERBOSE" = "Y" ]; then + echo qmake found in $qm +fi + +gen_files() { +cat >$1/modules.cpp <= 4.1 +-----END QCMOD----- +*/ +class qc_qt4 : public ConfObj +{ +public: + qc_qt4(Conf *c) : ConfObj(c) {} + QString name() const { return "Qt >= 4.2.3"; } + QString shortname() const { return "qt4"; } + bool exec() + { + return(QT_VERSION >= 0x040203); + } +}; +#line 1 "bundled-qca.qcm" +/* +-----BEGIN QCMOD----- +name: Use bundled QCA +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_bundled_qca +//---------------------------------------------------------------------------- +class qc_bundled_qca : public ConfObj +{ +public: + qc_bundled_qca(Conf *c) : ConfObj(c) {} + QString name() const { return "bundled QCA 2.0"; } + QString shortname() const { return "bundled_qca"; } + + bool exec() + { + // FIXME: Check QCA version number + if (QFile::exists("third-party/qca/qca")) { + conf->addExtra("CONFIG += qca-static"); + conf->addDefine("QCA_NO_PLUGINS"); + return true; + } + else { + return false; + } + } +}; +#line 1 "qca.qcm" +/* +-----BEGIN QCMOD----- +name: external QCA 2.0 +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_qca +//---------------------------------------------------------------------------- +class qc_qca : public ConfObj +{ +public: + qc_qca(Conf *c) : ConfObj(c) {} + QString name() const { return "QCA 2.0"; } + QString shortname() const { return "qca"; } + + QString checkString() const { + if (QFile::exists("third-party/qca/qca") && conf->getenv("QC_DISABLE_bundled_qca").isEmpty()) + return ""; + else + return ConfObj::checkString(); + } + + bool exec() + { + // Check if we have a bundnled version + if (QFile::exists("third-party/qca/qca") && conf->getenv("QC_DISABLE_bundled_qca").isEmpty()) + return true; + + // test for "crypto" feature and check qca version number + + QString proextra = + "CONFIG += qt crypto\n" + "QT -= gui\n"; + + QString str = + "#include \n" + "\n" + "int main()\n" + "{\n" + " unsigned long x = QCA_VERSION;\n" + " if(x >= 0x016363) return 0; else return 1;\n" + "}\n"; + + int ret; + if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra, &ret)) + return false; + if(ret != 0) + return false; + + return true; + } +}; +#line 1 "openssl.qcm" +/* +-----BEGIN QCMOD----- +name: OpenSSL (bundled QCA only) +arg: with-openssl-inc=[path],Path to OpenSSL include files (bundled QCA only) +arg: with-openssl-lib=[path],Path to OpenSSL library files (bundled QCA only) +-----END QCMOD----- +*/ +class qc_openssl : public ConfObj +{ +public: + qc_openssl(Conf *c) : ConfObj(c) {} + QString name() const { return "OpenSSL"; } + QString shortname() const { return "openssl"; } + + QString checkString() const { + if (!QFile::exists("third-party/qca/qca") || !conf->getenv("QC_DISABLE_bundled_qca").isEmpty()) + return ""; + else + return ConfObj::checkString(); + } + + bool exec() + { + if (!QFile::exists("third-party/qca/qca") || !conf->getenv("QC_DISABLE_bundled_qca").isEmpty() || !QFile::exists("third-party/qca/qca-ossl")) + return false; + + QString inc, lib; + QString s; + bool kb = false; + QString kbdir = "/usr/kerberos/include"; + + // Redhat 9? + if(QFileInfo(kbdir).exists()) + kb = true; + + s = conf->getenv("QC_WITH_OPENSSL_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "openssl/ssl.h")) + return false; + inc = s; + } + else { + if(!conf->findHeader("openssl/ssl.h", QStringList(), &s)) + return false; + inc = s; + } + + s = conf->getenv("QC_WITH_OPENSSL_LIB"); + if(!s.isEmpty()) { + if(!conf->checkLibrary(s, "ssl")) + return false; + lib = s; + } + else { + if(!conf->findLibrary("ssl", &s)) + return false; + lib = s; + } + + // is it at least openssl 0.9.7? + QString str = + "#include\n" + "int main()\n" + "{\n" + " unsigned long x = OPENSSL_VERSION_NUMBER;\n" + " if(x >= 0x00907000) return 0; else return 1;\n" + "}\n"; + QString ext; + QStringList incs; + if(!inc.isEmpty()) + incs += inc; + if(kb) + incs += kbdir; + if(!lib.isEmpty()) + ext += QString("-L") + lib + " -lssl -lcrypto "; + int ret; + if(!conf->doCompileAndLink(str, incs, ext, QString(), &ret)) + return false; + if(ret == 0) + conf->addDefine("OSSL_097"); + + if(!inc.isEmpty()) + conf->addIncludePath(inc); + if(kb) + conf->addIncludePath(kbdir); + if(!lib.isEmpty()) + conf->addLib(QString("-L") + s); + conf->addLib("-lssl -lcrypto"); + + conf->addDefine("HAVE_OPENSSL"); + + return true; + } +}; +#line 1 "zlib.qcm" +/* +-----BEGIN QCMOD----- +name: zlib +arg: with-zlib-inc=[path],Path to zlib include files +arg: with-zlib-lib=[path],Path to zlib library files +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_zlib +//---------------------------------------------------------------------------- +class qc_zlib : public ConfObj +{ +public: + qc_zlib(Conf *c) : ConfObj(c) {} + QString name() const { return "zlib"; } + QString shortname() const { return "zlib"; } + bool exec() + { + QString inc, lib; + QString s; + + s = conf->getenv("QC_WITH_ZLIB_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "zlib.h")) + return false; + inc = s; + } + else { + if(!conf->findHeader("zlib.h", QStringList(), &s)) + return false; + inc = s; + } + + s = conf->getenv("QC_WITH_ZLIB_LIB"); + if(!s.isEmpty()) { + if(!conf->checkLibrary(s, "z")) + return false; + lib = s; + } + else { + if(!conf->findLibrary("z", &s)) + return false; + lib = s; + } + + if(!inc.isEmpty()) + conf->addIncludePath(inc); + if(!lib.isEmpty()) + conf->addLib(QString("-L") + s); + conf->addLib("-lz"); + + return true; + } +}; +#line 1 "universal.qcm" +/* +-----BEGIN QCMOD----- +name: Mac OS X universal binary support +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_universal +//---------------------------------------------------------------------------- +class qc_universal : public ConfObj +{ +public: + qc_universal(Conf *c) : ConfObj(c) {} + QString name() const { return "universal binary support"; } + QString shortname() const { return "universal"; } + QString checkString() const { return QString(); } + + bool exec() + { +#ifdef Q_WS_MAC + conf->addExtra("CONFIG += qc_universal"); +#endif + return true; + } +}; +#line 1 "certstore.qcm" +/* +-----BEGIN QCMOD----- +name: certstore +section: project +arg: certstore-path=[path],Path to the SSL/X509 Certificate store file (bundled QCA only) +-----END QCMOD----- +*/ + +class qc_certstore : public ConfObj +{ +public: + qc_certstore(Conf *c) : ConfObj(c) {} + QString name() const { return "certstore"; } + QString shortname() const { return "certstore"; } + + QString checkString() const { + if (!QFile::exists("third-party/qca/qca") || !conf->getenv("QC_DISABLE_bundled_qca").isEmpty()) + return ""; + else + return ConfObj::checkString(); + } + + bool exec() + { + if (!QFile::exists("third-party/qca/qca") || !conf->getenv("QC_DISABLE_bundled_qca").isEmpty() || !QFile::exists("third-party/qca/qca-ossl")) { + return true; + } + + bundled = false; + +#if defined(Q_OS_WIN) || defined(Q_OS_MAC) + // use built-in + return true; +#else + QStringList pathsToTry; + + path = conf->getenv("QC_CERTSTORE_PATH"); + if(!path.isEmpty()) + { + if(QFile::exists(path)) + { + QString certPathString = + "QCA_SYSTEMSTORE_PATH=\\\\\\\\\\\\\"" + path + "\\\\\\\\\\\\\""; + conf->addDefine(certPathString); + return true; + } + return false; + } + + // This is from Debian + pathsToTry.append( QString("/etc/ssl/certs/ca-certificates.crt") ); + + // Fedora Core 2 uses these + pathsToTry.append( QString("/usr/share/ssl/cert.pem") ); + pathsToTry.append( QString("/usr/share/ssl/certs/ca-bundle.crt") ); + + // Fedora Core 5 changes to this + pathsToTry.append( QString("/etc/pki/tls/cert.pem") ); + + for(int n = 0; n < pathsToTry.count(); ++n) + { + if(QFile::exists(pathsToTry[n])) + { + path = pathsToTry[n]; + break; + } + } + + // fall back to bundled + if(path.isEmpty()) + { + // --prefix=\$pwd ? + if(QFile::exists(conf->getenv("PREFIX") + "/certs/rootcerts.pem")) + path = "\$\$PREFIX/certs/rootcerts.pem"; + else + path = "\$\$DATADIR/yachat/certs/rootcerts.pem"; + + QString extra = + "qcasharedfiles.path = \$\$DATADIR/yachat\n" + "qcasharedfiles.files = third-party/qca/qca/certs\n" + "INSTALLS += qcasharedfiles\n"; + conf->addExtra(extra); + bundled = true; + } + + // Qt<4.2 workaround + QString certPathString = + "QCA_SYSTEMSTORE_PATH=\\\\\\\\\\\\\"" + path + "\\\\\\\\\\\\\""; + conf->addDefine(certPathString); + + return true; +#endif + } + + QString resultString() const + { +#if defined(Q_OS_WIN) + return "using Windows built-in"; +#elif defined(Q_OS_MAC) + return "using Mac built-in"; +#else + if(success) + { + if(bundled) + return "using bundled"; + else + return path; + } + else + return ConfObj::resultString(); +#endif + } + +private: + QString path; + bool bundled; +}; +#line 1 "qdbus.qcm" +/* +-----BEGIN QCMOD----- +name: QDBUS +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_qdbus +//---------------------------------------------------------------------------- +class qc_qdbus : public ConfObj +{ +public: + qc_qdbus(Conf *c) : ConfObj(c) {} + QString name() const { return "QDBUS"; } + QString shortname() const { return "qdbus"; } + bool exec() + { + if (!conf->getenv("QC_DISABLE_qdbus").isEmpty()) + return false; + + // test for "qdbus" feature + + QString proextra = + "CONFIG += qt qdbus\n" + "QT -= gui\n"; + + QString str = + "\n" + "int main()\n" + "{\n" + " return 0;\n" + "}\n"; + + int ret; + if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra, &ret)) + return false; + if(ret != 0) + return false; + + conf->addExtra("CONFIG += dbus"); + return true; + } +}; +#line 1 "growl.qcm" +/* +-----BEGIN QCMOD----- +name: Growl +arg: with-growl=[path],Path to the Growl framework +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_growl +//---------------------------------------------------------------------------- +class qc_growl : public ConfObj +{ +public: + qc_growl(Conf *c) : ConfObj(c) {} + QString name() const { return "Growl"; } + QString shortname() const { return "growl"; } +#ifndef Q_WS_MAC + QString checkString() const { return QString(); } +#endif + + // TODO: This should go into ConfObj + bool checkFramework(const QString &path, const QString &name) + { + QString str = + "int main()\n" + "{\n" + " return 0;\n" + "}\n"; + + QString extra; + if(!path.isEmpty()) + extra += QString("-F") + path + ' '; + extra += QString("-framework ") + name; + if(!conf->doCompileAndLink(str, QStringList(), extra, "", NULL)) + return false; + return true; + } + + // TODO: This should go into ConfObj + void addFrameworkPath(const QString& str) + { + conf->addExtra("QMAKE_CXXFLAGS += -F" + str); + conf->addLib("-F" + str); + } + + bool exec() + { +#ifdef Q_WS_MAC + QString growl_path = conf->getenv("QC_WITH_GROWL"); + if(!checkFramework(growl_path, "Growl")) + return false; + + if(!growl_path.isEmpty()) + addFrameworkPath(growl_path); + conf->addLib("-framework Growl"); + conf->addDefine("HAVE_GROWL"); + + return true; +#else + return false; +#endif + } +}; +#line 1 "xss.qcm" +/* +-----BEGIN QCMOD----- +name: the XScreenSaver extension +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_xss +//---------------------------------------------------------------------------- +class qc_xss : public ConfObj +{ +public: + qc_xss(Conf *c) : ConfObj(c) {} + + QString name() const { return "the XScreenSaver extension"; } + QString shortname() const { return "xss"; } + + bool exec() + { + QString str = + "#include\n" + "#include\n" + "#include\n" + "\n" + "int main()\n" + "{\n" + " XScreenSaverQueryExtension(NULL, NULL, NULL);\n" + " return 0;\n" + "}\n"; + QString proextra = "CONFIG += x11\n"; + + if (!conf->doCompileAndLink(str, QStringList(), "-lXss", proextra, NULL)) { + if (!conf->doCompileAndLink(str, QStringList(), QString(), proextra, NULL)) { + return false; + } + } + else { + conf->addLib("-lXss"); + } + + conf->addDefine("HAVE_XSS"); + return true; + } +}; +#line 1 "dnotify.qcm" +/* +-----BEGIN QCMOD----- +name: Linux Directory Notification +-----END QCMOD----- +*/ + +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +// qc_dnotify +//---------------------------------------------------------------------------- +class qc_dnotify : public ConfObj +{ +public: + qc_dnotify(Conf *c) : ConfObj(c) { } + + QString name() const { return "Linux Directory Notification"; } + QString shortname() const { return "dnotify"; } + + bool exec() + { + QString str = + "#define _GNU_SOURCE\n" + "#include\n" + "#include\n" + "#include\n" + "#include\n" + "\n" + "int main()\n" + "{\n" + " DN_DELETE|DN_CREATE|DN_RENAME|DN_MULTISHOT|DN_MODIFY|DN_ATTRIB;\n" + " return 0;\n" + "}\n"; + int ret; + if (!conf->doCompileAndLink(str, QStringList(), QString(), QString(), &ret) || ret != 0) + return false; + + conf->addDefine("HAVE_DNOTIFY"); + return true; + } +}; +#line 1 "ghbnr.qcm" +/* +-----BEGIN QCMOD----- +name: gethostbyname_r() +-----END QCMOD----- +*/ +class qc_ghbnr : public ConfObj +{ +public: + qc_ghbnr(Conf *c) : ConfObj(c) { } + + QString name() const { return "gethostbyname_r()"; } + QString shortname() const { return "ghbnr"; } + + bool exec() + { + QString str = + "#include\n" + "\n" + "int main()\n" + "{\n" + " gethostbyname_r(\"\", 0, 0, 0, 0, 0);\n" + " return 0;\n" + "}\n"; + if (!conf->doCompileAndLink(str, QStringList(), QString(), QString(), NULL)) + return false; + + conf->addDefine("HAVE_GETHOSTBYNAME_R"); + return true; + } +}; +#line 1 "aspell.qcm" +/* +-----BEGIN QCMOD----- +name: ASPELL +arg: with-aspell-inc=[path],Path to Aspell include files +arg: with-aspell-lib=[path],Path to Aspell library files +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_spell +//---------------------------------------------------------------------------- +class qc_aspell : public ConfObj +{ +public: + qc_aspell(Conf *c) : ConfObj(c) {} + QString name() const { return "Aspell support"; } + QString shortname() const { return "aspell"; } + bool exec() + { + QString s; + + s = conf->getenv("QC_WITH_ASPELL_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "aspell.h")) { + conf->debug("Aspell includes not found!"); + return false; + } + conf->addIncludePath(s); + } + else { + QStringList sl; + sl += "/usr/include"; + sl += "/usr/local/include"; + sl += "/sw/include"; + if(!conf->findHeader("aspell.h", sl, &s)) { + conf->debug("Aspell includes not found!"); + return false; + } + conf->addIncludePath(s); + } + + s = conf->getenv("QC_WITH_ASPELL_LIB"); + if(!s.isEmpty()) { + if(!conf->checkLibrary(s, "aspell")) { + conf->debug("Aspell libraries not found!"); + return false; + } + conf->addLib(QString("-L") + s); + } + else { + if(!conf->findLibrary("aspell", &s)) { + conf->debug("Aspell libraries not found!"); + return false; + } + if (!s.isEmpty()) + conf->addLib(QString("-L") + s); + } + + // conf->addLib("-laspell"); + // conf->addDefine("HAVE_ASPELL"); + + return true; + } +}; +#line 1 "tests.qcm" +/* +-----BEGIN QCMOD----- +name: Tests +arg: with-cppunit-inc=[path],Path to CppUnit include files +arg: with-cppunit-lib=[path],Path to CppUnit library files +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_tests +//---------------------------------------------------------------------------- +class qc_tests : public ConfObj +{ +public: + qc_tests(Conf *c) : ConfObj(c) {} + QString name() const { return "tests"; } + QString shortname() const { return "tests"; } + bool exec() + { + QString s = conf->getenv("QC_WITH_CPPUNIT_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "cppunit/Test.h")) { + conf->debug("CppUnit includes not found!"); + return false; + } + conf->addIncludePath(s); + } + else { + QStringList sl; + sl += "/usr/include"; + sl += "/usr/local/include"; + sl += "/sw/include"; + sl += "/opt/local/include"; + if(!conf->findHeader("cppunit/Test.h", sl, &s)) { + conf->debug("CppUnit includes not found!"); + return false; + } + conf->addIncludePath(s); + } + + s = conf->getenv("QC_WITH_CPPUNIT_LIB"); + if(!s.isEmpty()) { + if(!conf->checkLibrary(s, "cppunit")) { + conf->debug("CppUnit libraries not found!"); + return false; + } + conf->addLib(QString("-L") + s); + } + else { + if(!conf->findLibrary("cppunit", &s)) { + conf->debug("CppUnit libraries not found!"); + return false; + } + if (!s.isEmpty()) + conf->addLib(QString("-L") + s); + } + + conf->addLib("-lcppunit"); + conf->addExtra("CONFIG += tests"); + + return true; + } +}; +#line 1 "debug.qcm" +/* +-----BEGIN QCMOD----- +name: Debugging support +arg: enable-debug,Enable debugging support +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_debug +//---------------------------------------------------------------------------- +class qc_debug : public ConfObj +{ +public: + qc_debug(Conf *c) : ConfObj(c) {} + QString name() const { return "debugging support"; } + QString shortname() const { return "debug"; } + QString checkString() const { return QString(); } + + bool exec() + { + if (conf->getenv("QC_ENABLE_DEBUG").isEmpty()) + conf->addExtra("CONFIG += release"); + else + conf->addExtra("CONFIG += debug"); + return true; + } +}; +#line 1 "conf.qcm" +/* +-----BEGIN QCMOD----- +name: Psi Configuration +-----END QCMOD----- +*/ + +//---------------------------------------------------------------------------- +// qc_conf +//---------------------------------------------------------------------------- +class qc_conf : public ConfObj +{ +public: + qc_conf(Conf *c) : ConfObj(c) {} + QString name() const { return "Psi Configuration"; } + QString shortname() const { return "conf"; } + QString checkString() const { return QString(); } + bool exec() + { + conf->addExtra(QString("PSI_DATADIR=%1/yachat").arg(conf->getenv("DATADIR"))); + + QFile file("src/config.h"); + if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { + QTextStream stream( &file ); + stream << "#define PSI_DATADIR \"" << conf->getenv("DATADIR") << "/yachat\"" << endl; + } + + conf->addDefine("HAVE_CONFIG"); + + return true; + } +}; + +EOT +cat >$1/modules_new.cpp <required = true; + o->disabled = false; + o = new qc_bundled_qca(conf); + o->required = false; + o->disabled = false; + o = new qc_qca(conf); + o->required = true; + o->disabled = false; + o = new qc_openssl(conf); + o->required = false; + o->disabled = false; + o = new qc_zlib(conf); + o->required = true; + o->disabled = false; + o = new qc_universal(conf); + o->required = false; + o->disabled = true; + o = new qc_certstore(conf); + o->required = true; + o->disabled = false; + o = new qc_qdbus(conf); + o->required = false; + o->disabled = false; + o = new qc_growl(conf); + o->required = false; + o->disabled = false; + o = new qc_xss(conf); + o->required = false; + o->disabled = false; + o = new qc_dnotify(conf); + o->required = false; + o->disabled = false; + o = new qc_ghbnr(conf); + o->required = false; + o->disabled = false; + o = new qc_aspell(conf); + o->required = false; + o->disabled = false; + o = new qc_tests(conf); + o->required = false; + o->disabled = true; + o = new qc_debug(conf); + o->required = true; + o->disabled = false; + o = new qc_conf(conf); + o->required = true; + o->disabled = false; + +EOT +cat >$1/conf4.h < + +class Conf; + +enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; + +// ConfObj +// +// Subclass ConfObj to create a new configuration module. +class ConfObj +{ +public: + Conf *conf; + bool required; + bool disabled; + bool success; + + ConfObj(Conf *c); + virtual ~ConfObj(); + + // long or descriptive name of what is being checked/performed + // example: "KDE >= 3.3" + virtual QString name() const = 0; + + // short name + // example: "kde" + virtual QString shortname() const = 0; + + // string to display during check + // default: "Checking for [name] ..." + virtual QString checkString() const; + + // string to display after check + // default: "yes" or "no", based on result of exec() + virtual QString resultString() const; + + // this is where the checking code goes + virtual bool exec() = 0; +}; + +// Conf +// +// Interact with this class from your ConfObj to perform detection +// operations and to output configuration parameters. +class Conf +{ +public: + bool debug_enabled; + QString qmake_path; + QString maketool; + + QString DEFINES; + QString INCLUDEPATH; + QString LIBS; + QString extra; + + QList list; + QMap vars; + + Conf(); + ~Conf(); + + QString getenv(const QString &var); + QString qvar(const QString &s); + + bool exec(); + + void debug(const QString &s); + + QString expandIncludes(const QString &inc); + QString expandLibs(const QString &lib); + + int doCommand(const QString &s, QByteArray *out = 0); + int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0); + + bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0); + bool checkHeader(const QString &path, const QString &h); + bool findHeader(const QString &h, const QStringList &ext, QString *inc); + bool checkLibrary(const QString &path, const QString &name); + bool findLibrary(const QString &name, QString *lib); + QString findProgram(const QString &prog); + bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs); + bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags); + bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags); + + void addDefine(const QString &str); + void addLib(const QString &str); + void addIncludePath(const QString &str); + void addExtra(const QString &str); + +private: + bool first_debug; + + friend class ConfObj; + void added(ConfObj *o); +}; + +#endif + +EOT +cat >$1/conf4.cpp < +#include + +class MocTestObject : public QObject +{ + Q_OBJECT +public: + MocTestObject() {} +}; + +QString qc_getenv(const QString &var) +{ + char *p = ::getenv(var.toLatin1().data()); + if(!p) + return QString(); + return QString(p); +} + +QStringList qc_pathlist() +{ + QStringList list; + QString path = qc_getenv("PATH"); + if(!path.isEmpty()) + list = path.split(':', QString::SkipEmptyParts); + return list; +} + +QString qc_findprogram(const QString &prog) +{ + QString out; + QStringList list = qc_pathlist(); + for(int n = 0; n < list.count(); ++n) + { + QFileInfo fi(list[n] + '/' + prog); + if(fi.exists() && fi.isExecutable()) + { + out = fi.filePath(); + break; + } + } + return out; +} + +QString qc_findself(const QString &argv0) +{ + if(argv0.contains('/')) + return argv0; + else + return qc_findprogram(argv0); +} + +int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) +{ + QString fullcmd = command; + if(!showOutput) + fullcmd += " 2>/dev/null"; + FILE *f = popen(fullcmd.toLatin1().data(), "r"); + if(!f) + return -1; + if(out) + out->clear(); + while(1) + { + char c = (char)fgetc(f); + if(feof(f)) + break; + if(out) + out->append(c); + if(showOutput) + fputc(c, stdout); + } + int ret = pclose(f); + if(ret == -1) + return -1; + return ret; +} + +int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) +{ + QString fullcmd = prog; + QString argstr = args.join(" "); + if(!argstr.isEmpty()) + fullcmd += QString(" ") + argstr; + return qc_runcommand(fullcmd, out, showOutput); + + // TODO: use QProcess once it is fixed + /* + QProcess process; + if(showOutput) + process.setReadChannelMode(ForwardedChannels); + process.start(prog, args); + process.waitForFinished(-1); + return process.exitCode(); + */ +} + +bool qc_removedir(const QString &dirPath) +{ + QDir dir(dirPath); + if(!dir.exists()) + return false; + QStringList list = dir.entryList(); + foreach(QString s, list) + { + if(s == "." || s == "..") + continue; + QFileInfo fi(dir.filePath(s)); + if(fi.isDir()) + { + if(!qc_removedir(fi.filePath())) + return false; + } + else + { + if(!dir.remove(s)) + return false; + } + } + QString dirName = dir.dirName(); + if(!dir.cdUp()) + return false; + if(!dir.rmdir(dirName)) + return false; + return true; +} + +void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags) +{ + incs->clear(); + otherflags->clear(); + + QStringList cflagsList = cflags.split(" "); + for(int n = 0; n < cflagsList.count(); ++n) + { + QString str = cflagsList[n]; + if(str.startsWith("-I")) + { + // we want everything except the leading "-I" + incs->append(str.remove(0, 2)); + } + else + { + // we want whatever is left + otherflags->append(str); + } + } +} + +QString qc_escapeArg(const QString &str) +{ + QString out; + for(int n = 0; n < (int)str.length(); ++n) { + if(str[n] == '-') + out += '_'; + else + out += str[n]; + } + return out; +} + +//---------------------------------------------------------------------------- +// ConfObj +//---------------------------------------------------------------------------- +ConfObj::ConfObj(Conf *c) +{ + conf = c; + conf->added(this); + required = false; + disabled = false; + success = false; +} + +ConfObj::~ConfObj() +{ +} + +QString ConfObj::checkString() const +{ + return QString("Checking for %1 ...").arg(name()); +} + +QString ConfObj::resultString() const +{ + if(success) + return "yes"; + else + return "no"; +} + +//---------------------------------------------------------------------------- +// qc_internal_pkgconfig +//---------------------------------------------------------------------------- +class qc_internal_pkgconfig : public ConfObj +{ +public: + QString pkgname, desc; + VersionMode mode; + QString req_ver; + + qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c) + { + pkgname = _name; + desc = _desc; + mode = _mode; + req_ver = _req_ver; + } + + QString name() const { return desc; } + QString shortname() const { return pkgname; } + + bool exec() + { + QStringList incs; + QString version, libs, other; + if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other)) + return false; + + for(int n = 0; n < incs.count(); ++n) + conf->addIncludePath(incs[n]); + if(!libs.isEmpty()) + conf->addLib(libs); + //if(!other.isEmpty()) + // conf->addExtra(QString("QMAKE_CFLAGS += %1\n").arg(other)); + return true; + } +}; + +//---------------------------------------------------------------------------- +// Conf +//---------------------------------------------------------------------------- +Conf::Conf() +{ + // TODO: no more vars? + //vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); + //vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); + //vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); + //vars.insert("QMAKE_CC", CC); + + debug_enabled = false; +} + +Conf::~Conf() +{ + qDeleteAll(list); +} + +void Conf::added(ConfObj *o) +{ + list.append(o); +} + +QString Conf::getenv(const QString &var) +{ + return qc_getenv(var); +} + +void Conf::debug(const QString &s) +{ + if(debug_enabled) + { + if(first_debug) + printf("\n"); + first_debug = false; + printf(" * %s\n", qPrintable(s)); + } +} + +bool Conf::exec() +{ + for(int n = 0; n < list.count(); ++n) + { + ConfObj *o = list[n]; + + // if this was a disabled-by-default option, check if it was enabled + if(o->disabled) + { + QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname()); + if(getenv(v) != "Y") + continue; + } + // and the opposite? + else + { + QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname()); + if(getenv(v) == "Y") + continue; + } + + bool output = true; + QString check = o->checkString(); + if(check.isEmpty()) + output = false; + + if(output) + { + printf("%s", check.toLatin1().data()); + fflush(stdout); + } + + first_debug = true; + bool ok = o->exec(); + o->success = ok; + + if(output) + { + QString result = o->resultString(); + if(!first_debug) + printf(" -> %s\n", result.toLatin1().data()); + else + printf(" %s\n", result.toLatin1().data()); + } + + if(!ok && o->required) + { + printf("\nError: need %s!\n", o->name().toLatin1().data()); + return false; + } + } + return true; +} + +QString Conf::qvar(const QString &s) +{ + return vars.value(s); +} + +QString Conf::expandIncludes(const QString &inc) +{ + return QString("-I") + inc; +} + +QString Conf::expandLibs(const QString &lib) +{ + return QString("-L") + lib; +} + +int Conf::doCommand(const QString &s, QByteArray *out) +{ + debug(QString("[%1]").arg(s)); + int r = qc_runcommand(s, out, debug_enabled); + debug(QString("returned: %1").arg(r)); + return r; +} + +int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out) +{ + QString fullcmd = prog; + QString argstr = args.join(" "); + if(!argstr.isEmpty()) + fullcmd += QString(" ") + argstr; + debug(QString("[%1]").arg(fullcmd)); + int r = qc_runprogram(prog, args, out, debug_enabled); + debug(QString("returned: %1").arg(r)); + return r; +} + +bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode) +{ + QDir tmp(".qconftemp"); + if(!tmp.mkdir("atest")) + { + debug("unable to create atest dir"); + return false; + } + QDir dir(tmp.filePath("atest")); + if(!dir.exists()) + { + debug("atest dir does not exist"); + return false; + } + + QString fname = dir.filePath("atest.cpp"); + QString out = "atest"; + QFile f(fname); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + debug("unable to open atest.cpp for writing"); + return false; + } + if(f.write(filedata.toLatin1()) == -1) + { + debug("error writing to atest.cpp"); + return false; + } + f.close(); + + debug(QString("Wrote atest.cpp:\n%1").arg(filedata)); + + QString pro = QString( + "CONFIG += console\n" + "CONFIG -= qt app_bundle\n" + "SOURCES += atest.cpp\n"); + QString inc = incs.join(" "); + if(!inc.isEmpty()) + pro += "INCLUDEPATH += " + inc + '\n'; + if(!libs.isEmpty()) + pro += "LIBS += " + libs + '\n'; + pro += proextra; + + fname = dir.filePath("atest.pro"); + f.setFileName(fname); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + debug("unable to open atest.pro for writing"); + return false; + } + if(f.write(pro.toLatin1()) == -1) + { + debug("error writing to atest.pro"); + return false; + } + f.close(); + + debug(QString("Wrote atest.pro:\n%1").arg(pro)); + + QString oldpath = QDir::currentPath(); + QDir::setCurrent(dir.path()); + + bool ok = false; + int r = doCommand(qmake_path, QStringList() << "atest.pro"); + if(r == 0) + { + r = doCommand(maketool, QStringList()); + if(r == 0) + { + ok = true; + if(retcode) + *retcode = doCommand(QString("./") + out, QStringList()); + } + r = doCommand(maketool, QStringList() << "distclean"); + if(r != 0) + debug("error during atest distclean"); + } + + QDir::setCurrent(oldpath); + + // cleanup + //dir.remove("atest.pro"); + //dir.remove("atest.cpp"); + //tmp.rmdir("atest"); + + // remove whole dir since distclean doesn't always work + qc_removedir(tmp.filePath("atest")); + + if(!ok) + return false; + return true; +} + +bool Conf::checkHeader(const QString &path, const QString &h) +{ + QFileInfo fi(path + '/' + h); + if(fi.exists()) + return true; + return false; +} + +bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc) +{ + if(checkHeader("/usr/include", h)) + { + *inc = ""; + return true; + } + QStringList dirs; + dirs += "/usr/local/include"; + dirs += ext; + for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) + { + if(checkHeader(*it, h)) + { + *inc = *it; + return true; + } + } + return false; +} + +bool Conf::checkLibrary(const QString &path, const QString &name) +{ + QString str = + //"#include \n" + "int main()\n" + "{\n" + //" printf(\"library checker running\\\\n\");\n" + " return 0;\n" + "}\n"; + + QString libs; + if(!path.isEmpty()) + libs += QString("-L") + path + ' '; + libs += QString("-l") + name; + if(!doCompileAndLink(str, QStringList(), libs, QString())) + return false; + return true; +} + +bool Conf::findLibrary(const QString &name, QString *lib) +{ + if(checkLibrary("", name)) + { + *lib = ""; + return true; + } + if(checkLibrary("/usr/local/lib", name)) + { + *lib = "/usr/local/lib"; + return true; + } + return false; +} + +QString Conf::findProgram(const QString &prog) +{ + return qc_findprogram(prog); +} + +bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs) +{ + QString inc, lib; + QString s; + + s = getenv(incvar); + if(!s.isEmpty()) { + if(!checkHeader(s, incname)) + return false; + inc = s; + } + else { + if(!findHeader(incname, QStringList(), &s)) + return false; + inc = s; + } + + s = getenv(libvar); + if(!s.isEmpty()) { + if(!checkLibrary(s, libname)) + return false; + lib = s; + } + else { + if(!findLibrary(libname, &s)) + return false; + lib = s; + } + + QString lib_out; + if(!lib.isEmpty()) + lib_out += QString("-L") + s; + lib_out += QString("-l") + libname; + + *incpath = inc; + *libs = lib_out; + return true; +} + +bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags) +{ + QStringList args; + QByteArray out; + int ret; + + args += "--version"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString version_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += "--libs"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString libs_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += "--cflags"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString cflags = QString::fromLatin1(out).trimmed(); + + QStringList incs_out, otherflags_out; + qc_splitcflags(cflags, &incs_out, &otherflags_out); + + *version = version_out; + *incs = incs_out; + *libs = libs_out; + *otherflags = otherflags_out.join(" "); + return true; +} + +bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags) +{ + QStringList args; + QByteArray out; + int ret; + + args += name; + args += "--exists"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + if(mode != VersionAny) + { + args.clear(); + args += name; + if(mode == VersionMin) + args += QString("--atleast-version=%1").arg(req_version); + else if(mode == VersionMax) + args += QString("--max-version=%1").arg(req_version); + else + args += QString("--exact-version=%1").arg(req_version); + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + } + + args.clear(); + args += name; + args += "--modversion"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString version_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += name; + args += "--libs"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString libs_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += name; + args += "--cflags"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString cflags = QString::fromLatin1(out).trimmed(); + + QStringList incs_out, otherflags_out; + qc_splitcflags(cflags, &incs_out, &otherflags_out); + + *version = version_out; + *incs = incs_out; + *libs = libs_out; + *otherflags = otherflags_out.join(" "); + return true; +} + +void Conf::addDefine(const QString &str) +{ + if(DEFINES.isEmpty()) + DEFINES = str; + else + DEFINES += QString(" ") + str; + debug(QString("DEFINES += %1").arg(str)); +} + +void Conf::addLib(const QString &str) +{ + if(LIBS.isEmpty()) + LIBS = str; + else + LIBS += QString(" ") + str; + debug(QString("LIBS += %1").arg(str)); +} + +void Conf::addIncludePath(const QString &str) +{ + if(INCLUDEPATH.isEmpty()) + INCLUDEPATH = str; + else + INCLUDEPATH += QString(" ") + str; + debug(QString("INCLUDEPATH += %1").arg(str)); +} + +void Conf::addExtra(const QString &str) +{ + extra += str + '\n'; + debug(QString("extra += %1").arg(str)); +} + +//---------------------------------------------------------------------------- +// main +//---------------------------------------------------------------------------- +#include "conf4.moc" + +#ifdef HAVE_MODULES +# include"modules.cpp" +#endif + +int main() +{ + Conf *conf = new Conf; + ConfObj *o; + o = 0; +#ifdef HAVE_MODULES +# include"modules_new.cpp" +#endif + + conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false; + if(conf->debug_enabled) + printf(" -> ok\n"); + else + printf("ok\n"); + + QString confCommand = qc_getenv("QC_COMMAND"); + QString proName = qc_getenv("QC_PROFILE"); + conf->qmake_path = qc_getenv("QC_QMAKE"); + conf->maketool = qc_getenv("QC_MAKETOOL"); + + if(conf->debug_enabled) + printf("conf command: [%s]\n", qPrintable(confCommand)); + + QString confPath = qc_findself(confCommand); + if(confPath.isEmpty()) + { + printf("Error: cannot find myself; rerun with an absolute path\n"); + return 1; + } + + QString srcdir = QFileInfo(confPath).absolutePath(); + QString builddir = QDir::current().absolutePath(); + QString proPath = QDir(srcdir).filePath(proName); + + if(conf->debug_enabled) + { + printf("conf path: [%s]\n", qPrintable(confPath)); + printf("srcdir: [%s]\n", qPrintable(srcdir)); + printf("builddir: [%s]\n", qPrintable(builddir)); + printf("profile: [%s]\n", qPrintable(proPath)); + printf("qmake path: [%s]\n", qPrintable(conf->qmake_path)); + printf("make tool: [%s]\n", qPrintable(conf->maketool)); + printf("\n"); + } + + bool success = false; + if(conf->exec()) + { + QFile f("conf.pri"); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + printf("Error writing %s\n", qPrintable(f.fileName())); + return 1; + } + + QString str; + str += "# qconf\n\n"; + + QString var; + var = qc_getenv("PREFIX"); + if(!var.isEmpty()) + str += QString("PREFIX = %1\n").arg(var); + var = qc_getenv("BINDIR"); + if(!var.isEmpty()) + str += QString("BINDIR = %1\n").arg(var); + var = qc_getenv("INCDIR"); + if(!var.isEmpty()) + str += QString("INCDIR = %1\n").arg(var); + var = qc_getenv("LIBDIR"); + if(!var.isEmpty()) + str += QString("LIBDIR = %1\n").arg(var); + var = qc_getenv("DATADIR"); + if(!var.isEmpty()) + str += QString("DATADIR = %1\n").arg(var); + str += '\n'; + + if(qc_getenv("QC_STATIC") == "Y") + str += "CONFIG += staticlib\n"; + + // TODO: don't need this? + //str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; + + if(!conf->DEFINES.isEmpty()) + str += "DEFINES += " + conf->DEFINES + '\n'; + if(!conf->INCLUDEPATH.isEmpty()) + str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; + if(!conf->LIBS.isEmpty()) + str += "LIBS += " + conf->LIBS + '\n'; + if(!conf->extra.isEmpty()) + str += conf->extra; + str += '\n'; + + QByteArray cs = str.toLatin1(); + f.write(cs); + f.close(); + success = true; + } + QString qmake_path = conf->qmake_path; + delete conf; + + if(!success) + return 1; + + // run qmake on the project file + int ret = qc_runprogram(qmake_path, QStringList() << proPath, 0, true); + if(ret != 0) + return 1; + + return 0; +} + +EOT +cat >$1/conf4.pro </dev/null + $MAKE clean >/dev/null 2>&1 + $MAKE >../conf.log 2>&1 +) + +if [ "$?" != "0" ]; then + rm -rf .qconftemp + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + printf "\n" + printf "Reason: There was an error compiling 'conf'. See conf.log for details.\n" + printf "\n" + show_qt_info + if [ "$QC_VERBOSE" = "Y" ]; then + echo "conf.log:" + cat conf.log + fi + exit 1; +fi + +QC_COMMAND=$0 +export QC_COMMAND +QC_PROFILE=psi.pro +export QC_PROFILE +QC_QMAKE=$qm +export QC_QMAKE +QC_MAKETOOL=$MAKE +export QC_MAKETOOL +.qconftemp/conf +ret="$?" +if [ "$ret" = "1" ]; then + rm -rf .qconftemp + echo + exit 1; +else + if [ "$ret" != "0" ]; then + rm -rf .qconftemp + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + echo + echo "Reason: Unexpected error launching 'conf'" + echo + exit 1; + fi +fi +rm -rf .qconftemp + +echo +echo "Good, your configure finished. Now run $MAKE." +echo diff --git a/crashreporter/.gitignore b/crashreporter/.gitignore new file mode 100644 index 0000000..af365b1 --- /dev/null +++ b/crashreporter/.gitignore @@ -0,0 +1,12 @@ +/Makefile +/Makefile.Debug +/Makefile.Release +/_moc +/_obj +/_ui +/debug +/release +/.moc +/.obj +/.ui +/crashreporter \ No newline at end of file diff --git a/crashreporter/crashreporter.cpp b/crashreporter/crashreporter.cpp new file mode 100644 index 0000000..e40fc3d --- /dev/null +++ b/crashreporter/crashreporter.cpp @@ -0,0 +1,294 @@ +/* + * crashreporter.cpp - simple crash reporter + * Copyright (C) 2008 Michail Pishchagin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui_crashreporter.h" + +#if defined(Q_WS_WIN) +#include "mailmsg_windows.h" +#endif + +class CrashReporter : public QWidget +{ + Q_OBJECT +public: + CrashReporter() + : QWidget() + , http_(0) + , restartButton_(0) + , quitButton_(0) + { + ui_.setupUi(this); + + appName_ = "Application"; + + http_ = new QHttp(this); + connect(http_, SIGNAL(done(bool)), SLOT(httpDone(bool))); + + ui_.textEdit->setFocus(); + } + + void doShow() + { + ui_.label->setText(ui_.label->text().arg(appName_)); + + if (!appPath_.isEmpty()) { + restartButton_ = ui_.buttonBox->addButton(tr("Restart %1").arg(appName_), QDialogButtonBox::AcceptRole); + connect(restartButton_, SIGNAL(clicked()), SLOT(restartApp())); + } + + quitButton_ = ui_.buttonBox->addButton(tr("Quit %1").arg(appName_), QDialogButtonBox::RejectRole); + connect(quitButton_, SIGNAL(clicked()), SLOT(quitApp())); + + show(); + } + + void setAppName(const QString& appName) + { + appName_ = appName; + } + + void setAppVersion(const QString& appVersion) + { + appVersion_ = appVersion; + } + + void setAppPath(const QString& appPath) + { + appPath_ = appPath; + } + + void setMinidump(const QString& minidump) + { + minidump_ = minidump; + } + + void setReportURL(const QString& reportURL) + { + reportURL_ = reportURL; + } + + void setReportEmail(const QString& reportEmail) + { + reportEmail_ = reportEmail; + } + +private slots: + void restartApp() + { + if (!appPath_.isEmpty()) { + QProcess::startDetached(appPath_); + } + close(); + } + + void quitApp() + { + close(); + } + + QByteArray makeFormField(const QString& name, const QByteArray& data) + { + QByteArray result; + result.append("------FormBoundary5WRMUdn8jqMNiFOP\r\n"); + result.append("Content-Disposition: form-data; name=\"" + name + "\"\r\n"); + result.append("\r\n"); + result.append(data); + result.append("\r\n"); + return result; + } + + bool reportCrash() + { + if (reportURL_.isEmpty()) { + qWarning("report url is empty"); + return false; + } + + QFileInfo fi(minidump_); + if (!fi.exists()) { + qWarning("minidump not found"); + return false; + } + + QFile minidump(minidump_); + if (!minidump.open(QIODevice::ReadOnly)) { + qWarning("unable to open minidump"); + return false; + } + + if (!ui_.groupBox->isChecked() || !http_) + return false; + + if (restartButton_) + restartButton_->setEnabled(false); + if (quitButton_) + quitButton_->setEnabled(false); + + QUrl url(reportURL_, QUrl::TolerantMode); + QHttpRequestHeader header("POST", url.path()); + header.setValue("User-Agent", "crashreporter"); + header.setValue("Host", url.port() == -1 ? url.host() : QString("%1:%2").arg(url.host(), url.port())); + header.setValue("Accept-Language", "en-us"); + header.setValue("Content-Type", "multipart/form-data; boundary=----FormBoundary5WRMUdn8jqMNiFOP"); + header.setValue("Accept", "*/*"); + + QByteArray bytes; + bytes.append(makeFormField("app-name", appName_.toUtf8())); + bytes.append(makeFormField("app-version", appVersion_.toUtf8())); + bytes.append(makeFormField("comments", ui_.textEdit->toPlainText().toUtf8())); + bytes.append(makeFormField("upload_file_minidump", minidump.readAll())); + + bytes.append("------FormBoundary5WRMUdn8jqMNiFOP--"); + bytes.append("\r\n"); + + int contentLength = bytes.length(); + header.setContentLength(contentLength); + + http_->setHost(url.host(), url.port() == -1 ? 80 : url.port()); + http_->request(header, bytes); + + return true; + } + + void httpDone(bool error) + { + if (error) { + qWarning("CrashReporter: ERROR: %s", qPrintable(http_->errorString())); + sendEmail(); + http_->abort(); + } + else { + QString result(http_->readAll()); + QRegExp rx("CrashID\\=([\\d\\w-]+)"); + if (rx.indexIn(result) != -1) { + qWarning("CrashReporter: CrashID=%s", qPrintable(rx.capturedTexts().at(1))); + } + } + + delete http_; + http_ = 0; + close(); + } + + void sendEmail() + { + if (reportEmail_.isEmpty()) { + qWarning("report email is empty"); + return; + } + +#if defined(Q_WS_WIN) + QStringList attachments; + QFileInfo fi(minidump_); + if (fi.exists()) { + attachments << fi.absoluteFilePath(); + } + + MailMsg::sendEmail(reportEmail_, + "Crash report", + ui_.textEdit->toPlainText(), + attachments); +#endif + } + +protected: + // reimplemented + void closeEvent(QCloseEvent* e) + { + if (reportCrash()) { + e->ignore(); + return; + } + QWidget::closeEvent(e); + } + +private: + Ui::CrashReporter ui_; + QHttp* http_; + QPushButton* restartButton_; + QPushButton* quitButton_; + QString appName_; + QString appVersion_; + QString appPath_; + QString minidump_; + QString reportURL_; + QString reportEmail_; +}; + +static QString optionValue(const QString& optionName, const QString string) +{ + if (string.startsWith(QString("-%1=").arg(optionName))) { + QStringList list = string.split("="); + list.removeFirst(); + if (!list.isEmpty()) { + return list.join("="); + } + } + + return QString(); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + CrashReporter crashReporter; + + for (int n = 1; n < argc; ++n) { + QString str = argv[n]; + if (!optionValue("appName", str).isEmpty()) { + crashReporter.setAppName(optionValue("appName", str)); + } + + if (!optionValue("appVersion", str).isEmpty()) { + crashReporter.setAppVersion(optionValue("appVersion", str)); + } + + if (!optionValue("appPath", str).isEmpty()) { + crashReporter.setAppPath(optionValue("appPath", str)); + } + + if (!optionValue("minidump", str).isEmpty()) { + crashReporter.setMinidump(optionValue("minidump", str)); + } + + if (!optionValue("reportURL", str).isEmpty()) { + crashReporter.setReportURL(optionValue("reportURL", str)); + } + + if (!optionValue("reportEmail", str).isEmpty()) { + crashReporter.setReportEmail(optionValue("reportEmail", str)); + } + } + + crashReporter.doShow(); + return app.exec(); +} + +#include "crashreporter.moc" diff --git a/crashreporter/crashreporter.pro b/crashreporter/crashreporter.pro new file mode 100644 index 0000000..466a585 --- /dev/null +++ b/crashreporter/crashreporter.pro @@ -0,0 +1,33 @@ +TEMPLATE = app +CONFIG += qt debug +CONFIG -= app_bundle +QT += gui network +SOURCES += crashreporter.cpp +INTERFACES += crashreporter.ui +include($$PWD/mailmsg/mailmsg.pri) + +include(/users/mblsha/src/psi-git/qa/oldtest/unittest.pri) + +mac { + QMAKE_POST_LINK = rm -f ../test/test.app/Contents/Resources/crashreporter; mkdir -p ../test/test.app/Contents/Resources; cp crashreporter ../test/test.app/Contents/Resources +} + +win32 { + QMAKE_POST_LINK = del /Q ..\test\release\crashreporter.exe && copy release\crashreporter.exe ..\test\release\crashreporter.exe +} + +windows { + # otherwise we would get 'unresolved external _WinMainCRTStartup' + # when compiling with MSVC + MOC_DIR = _moc + OBJECTS_DIR = _obj + UI_DIR = _ui + RCC_DIR = _rcc +} +!windows { + MOC_DIR = .moc + OBJECTS_DIR = .obj + UI_DIR = .ui + RCC_DIR = .rcc +} + diff --git a/crashreporter/crashreporter.ui b/crashreporter/crashreporter.ui new file mode 100644 index 0000000..914f47e --- /dev/null +++ b/crashreporter/crashreporter.ui @@ -0,0 +1,59 @@ + + CrashReporter + + + + 0 + 0 + 422 + 313 + + + + Crash Reporter + + + + + + %1 had a problem and crashed. We'll try to restore all your data when it restarts. To help us diagnose and fix the problem, you can send us a crash report. + + + true + + + + + + + Send crash report + + + true + + + + + + Add a comment: + + + + + + + + + + + + + QDialogButtonBox::NoButton + + + + + + + + diff --git a/crashreporter/mailmsg/mailmsg.pri b/crashreporter/mailmsg/mailmsg.pri new file mode 100644 index 0000000..1751ddf --- /dev/null +++ b/crashreporter/mailmsg/mailmsg.pri @@ -0,0 +1,7 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +win32 { + SOURCES += $$PWD/mailmsg_windows.cpp + HEADERS += $$PWD/mailmsg_windows.h +} diff --git a/crashreporter/mailmsg/mailmsg_windows.cpp b/crashreporter/mailmsg/mailmsg_windows.cpp new file mode 100644 index 0000000..31029aa --- /dev/null +++ b/crashreporter/mailmsg/mailmsg_windows.cpp @@ -0,0 +1,124 @@ +/* + * mailmsg_windows.cpp - send e-mails programmaticaly. On Windows. + * Copyright (C) 2008 Michail Pishchagin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +// based on code taken from MailMsg.cpp by Michael Carruth +// http://code.google.com/p/crashrpt/ + +#include +#include + +#include "mailmsg_windows.h" + +#include +#include +#include + +LPSTR qStringToLPSTR(const QString& qString) +{ + // return qString.toLocal8Bit().data(); + return qString.toLatin1().data(); +} + +QString mapi32path() +{ + // // try to determine default Simple MAPI handler + // // first, look for current user's default client + // registry::tstring default_client = registry::const_key(HKEY_CURRENT_USER, "Software\\Clients\\Mail")[""].reg_sz(""); + // + // if (default_client.empty()) { + // // then look for machine-wide settings + // default_client = registry::const_key(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail")[""].reg_sz(""); + // } + // + // if (!default_client.empty()) { + // registry::const_key regClient(HKEY_LOCAL_MACHINE, registry::tstring("Software\\Clients\\Mail\\" + default_client).c_str()); + // registry::tstring s = regClient["DLLPath"].reg_sz(""); + // + // if (s.empty()) + // s = regClient["DLLPathEx"].reg_sz(""); + // + // if (!s.empty()) + // dllpath = s; + // } + + return "mapi32"; +} + +void MailMsg::sendEmail(const QString& to, const QString& subject, const QString& message, const QStringList& attachments) +{ + qWarning("sending off email..."); + QLibrary mapi32(mapi32path()); + if (!mapi32.load()) { + qWarning("MailMsg: failed to load mapi32.dll"); + return; + } + + LPMAPISENDMAIL mapiSendMail = 0; + mapiSendMail = (LPMAPISENDMAIL)mapi32.resolve("MAPISendMail"); + if (!mapiSendMail) { + qWarning("MailMsg: failed to resolve MAPISendMail"); + return; + } + + MapiRecipDesc* pRecipients = NULL; + MapiFileDesc* pAttachments = NULL; + MapiMessage msg; + + pRecipients = new MapiRecipDesc[1]; + pRecipients[0].ulReserved = 0; + pRecipients[0].ulRecipClass = MAPI_TO; + pRecipients[0].lpszAddress = qStringToLPSTR(to); + pRecipients[0].lpszName = qStringToLPSTR(to); + pRecipients[0].ulEIDSize = 0; + pRecipients[0].lpEntryID = NULL; + + if (attachments.size()) + pAttachments = new MapiFileDesc[attachments.size()]; + for (int i = 0; i < attachments.size(); ++i) { + pAttachments[i].ulReserved = 0; + pAttachments[i].flFlags = 0; + pAttachments[i].nPosition = 0xFFFFFFFF; + pAttachments[i].lpszPathName = qStringToLPSTR(attachments[i]); + pAttachments[i].lpszFileName = qStringToLPSTR(attachments[i]); + pAttachments[i].lpFileType = NULL; + } + + msg.ulReserved = 0; + msg.lpszSubject = qStringToLPSTR(subject); + msg.lpszNoteText = qStringToLPSTR(message); + msg.lpszMessageType = NULL; + msg.lpszDateReceived = NULL; + msg.lpszConversationID = NULL; + msg.flFlags = 0; + msg.lpOriginator = NULL; + msg.nRecipCount = 1; + msg.lpRecips = pRecipients; + msg.nFileCount = attachments.size(); + msg.lpFiles = pAttachments; + + int status = mapiSendMail(0, 0, &msg, MAPI_DIALOG | MAPI_LOGON_UI | MAPI_NEW_SESSION, 0); + Q_UNUSED(status); + + if (pRecipients) + delete[] pRecipients; + + if (pAttachments) + delete[] pAttachments; +} diff --git a/crashreporter/mailmsg/mailmsg_windows.h b/crashreporter/mailmsg/mailmsg_windows.h new file mode 100644 index 0000000..266d421 --- /dev/null +++ b/crashreporter/mailmsg/mailmsg_windows.h @@ -0,0 +1,31 @@ +/* + * mailmsg_windows.h - send e-mails programmaticaly. On Windows. + * Copyright (C) 2008 Michail Pishchagin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef MAILMSG_WINDOWS_H +#define MAILMSG_WINDOWS_H + +class QString; +class QStringList; + +namespace MailMsg { + void sendEmail(const QString& to, const QString& subject, const QString& message, const QStringList& attachments); +}; + +#endif diff --git a/doc/Doxyfile.private b/doc/Doxyfile.private new file mode 100644 index 0000000..9eb2ca3 --- /dev/null +++ b/doc/Doxyfile.private @@ -0,0 +1,288 @@ +# Doxyfile 1.4.5 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Psi +PROJECT_NUMBER = +OUTPUT_DIRECTORY = doc/api/private +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 5 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY +RECURSIVE = YES +EXCLUDE = _darcs/ \ + third-party/ \ + iris/libidn/ \ + iris/irisnet/ \ + iris/irisnet/jdns \ + iris/example \ + src/tools/tunecontroller/plugins/winamp/third-party \ + src/tools/iconset/unittest \ + src/tools/optionstree/optionstreeviewtest \ + src/tools/zip/minizip \ + src/unittest \ + src/widgets/private/ \ + src/widgets/unittest/ \ + doc/ +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */.ui/* \ + */.moc/* \ + moc_* +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = NO +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = YES diff --git a/doc/Doxyfile.public b/doc/Doxyfile.public new file mode 100644 index 0000000..5c47082 --- /dev/null +++ b/doc/Doxyfile.public @@ -0,0 +1,288 @@ +# Doxyfile 1.4.5 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Psi +PROJECT_NUMBER = +OUTPUT_DIRECTORY = doc/api/public +CREATE_SUBDIRS = no +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 5 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY +RECURSIVE = YES +EXCLUDE = _darcs/ \ + third-party/ \ + iris/libidn/ \ + iris/irisnet/ \ + iris/irisnet/jdns \ + iris/example \ + src/tools/tunecontroller/plugins/winamp/third-party \ + src/tools/iconset/unittest \ + src/tools/optionstree/optionstreeviewtest \ + src/tools/zip/minizip \ + src/unittest \ + src/widgets/private/ \ + src/widgets/unittest/ \ + doc/ +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */.ui/* \ + */.moc/* \ + moc_* +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = YES diff --git a/doc/build-mac.txt b/doc/build-mac.txt new file mode 100644 index 0000000..f2e28fa --- /dev/null +++ b/doc/build-mac.txt @@ -0,0 +1,22 @@ +Building Psi on Mac OS X +------------------------ + +To simply compile Psi, the same instructions apply as for other *nix +platforms: +1. First, configure the build using the 'configure' script, optionally + adding parameters to specify where to find certain dependencies: + ./configure +2. Build the binary: + make +After this, the built binary 'psi.app' will be available in src/. +For more details, check 'doc/build-unix.txt'. + +To make a distributable copy of your binary, do the following: +1. As above, use configure to configure the build +2. Alter the first lines of 'mac/Makefile' to reflect your setting +3. Run 'make -C mac/'. + This will create a distributable binary 'Psi.app' in 'mac/disk/'. +4. (OPTIONAL) Create a DMG image by running 'make -C mac/ dmg'. + This will create a 'Psi-.dmg' file in 'mac/'. + You can create your own DMG template to make the resulting DMG + look different. For more instructions on this, see 'mac/Makefile'. diff --git a/doc/build-unix.txt b/doc/build-unix.txt new file mode 100644 index 0000000..d05566f --- /dev/null +++ b/doc/build-unix.txt @@ -0,0 +1,75 @@ +Requirements +------------ + +* You need Qt 4.2 or higher to build Psi. If a packaged version of Qt is not +available for your OS (or if you want debug symbols in your Qt libraries), you +will need to build and install Qt 4.1 yourself. See the Qt instructions to find +out how to do this. + +* You need QCA 2.0 and the QCA OpenSSL plugin, which you can get at + http://delta.affinix.com/qca/2.0/beta2 +Instructions on how to build these packages can be found below. + +The 'Building QCA' and 'Building QCA the OpenSSL plugin' sections can be +skipped by downloading the sources of these packages, and unpackaging them +in third-party/qca (see the INSTALL file for the exact location of each +package). + + +Building QCA +------------ + +After unpacking the QCA sources, run the following command: + + ./configure --prefix=/usr/local/qca2 + +If configure cannot find your Qt4 library, use the --qtdir option to specify +the path to Qt (e.g. /usr/share/qt4), or make sure that the qmake binary for +Qt4 occurs first in your PATH. If something else goes wrong, use the --debug +option to get more information on the configuration process. + +After QCA configured, run + + make + make install + +To be able to run applications using QCA2, you will need to add +/usr/local/qca2/lib to /etc/ld.so.conf and run ldconfig, or add +/usr/local/qca2/lib to your LD_LIBRARY_PATH. + + + +Building the QCA OpenSSL plugin +------------------------------- +After unpacking the QCA OpenSSL plugin's sources, run the following commands + + ./configure + make + make install + +See above on how to troubleshoot configure problems. + + + +Building the QCA GnuPG plugin +------------------------------- +After unpacking the QCA GnuPG plugin's sources, run the following commands + + ./configure + make + make install + +See above on how to troubleshoot configure problems. + + +Building Psi +------------ + +From the toplevel Psi source dir, run the following commands: + + ./configure --prefix=/usr/local/psi + make + make install + +This should configure, build, and install Psi. See above on how to troubleshoot +configure problems. diff --git a/doc/build-win.txt b/doc/build-win.txt new file mode 100644 index 0000000..63f2ef9 --- /dev/null +++ b/doc/build-win.txt @@ -0,0 +1,79 @@ +Requirements +------------ + +* You need Qt 4.2 or higher to build Psi. Just download and install the MingW32 +self-installer. All the instructions below are performed from within the Qt command +prompt (found in the Start menu) + +* You need QCA 2.0 and the QCA OpenSSL plugin, which you can get at + http://delta.affinix.com/qca/2.0/beta2 +Instructions on how to build these packages can be found below. + +* If you want to use the QCA OpenSSL plugin on Windows, you will need to +download and install the OpenSSL package from + http://www.openssl.org/related/binaries.html + +The 'Building QCA' and 'Building QCA the OpenSSL plugin' sections can be +skipped by downloading the sources of these packages, and unpackaging them +in third-party/qca (see the INSTALL file for the exact location of each +package). Then, uncomment the 'CONFIG += qca-static' in conf_windows.pri. + + +Building QCA +------------ + +* Edit crypto_win.prf and change the QCA_PATH to the dir where you unpacked QCA. Then, +change -lqca to -lqca2. + +* Copy crypto_win.prf to the mkspecs/features subdir of your Qt dir, and rename it to +crypto.prf. + +* In the src/ dir, run the following commands: + + qmake + mingw32-make + +* Copy lib/qca2.dll to your system dir (e.g. \Windows\System32) + + + +Building the QCA OpenSSL plugin +------------------------------- + +* Go to the dir where you unpacked OpenSSL. In the lib\MingW subdir of that dir, copy the +files ssleay32.a and libeay32.a to ssleay32.lib and libeay32.lib respectively. + +* Edit qca-openssl.pro, and change the OPENSSL_PREFIX in +the windows section to point to the dir where you installed OpenSSL (e.g. C:/OpenSSL). +Change -L$$OPENSSL_PREFIX/lib into -L$$OPENSSL_PREFIX/lib/MingW. + +* Run the following commands: + + qmake + mingw32-make + + + +Building Psi +------------ + +* Edit src/src.pro in the Psi tree, and remove the line CONFIG += DEBUG. + +* From the toplevel dir in your tree, run the following commands: + + qmake + mingw32-make + +* There should now be a binary psi.exe in src/release. + + + +Packaging Psi +------------- + +To package everything up into a self-containing dir, edit win32/Makefile to reflect your +local setup, and run + + mingw32-make -C win32 + +This should make a dir win32/psi with all the necessary files. diff --git a/dsa_pub.pem b/dsa_pub.pem new file mode 100644 index 0000000..e428e97 --- /dev/null +++ b/dsa_pub.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDOzCCAi4GByqGSM44BAEwggIhAoIBAQD9PC101SLooiS7UiAYZWszXSsLlXVx +oY2sMy7Loy37K0Dj7TfxtoA6X7wUzxPSGxo7SfeETjqwO1Xd0kFx+njQWUv04TlE +Ut8jzVCM28h1Sj6vygq57I4/xNvStWWAuhpt+s4jPDryE0ixihRzRZFZYdiOWI7j +PnkQAPeONjIrygva+EN0kJgw7x4OEp2B7rRlMM9N6VpaVxRIkFrdBXyVyTivWHt3 +ndsN7yNYWkEa0kmEM1f3pDNwwOiToIW8vt7Jfxmq+EUi+wAoSR+7NbhmEHQwqrv1 +/BPrHJuTnlzPPBxGgGNhw5Chj3zyKVM3iy4NWP+fMUIMdew9d3z1BSitAhUAp6SZ +1/fwORUQ4HJ2QN86QI8ypaMCggEBAIx1tFPhnxOGcIv8pl63yJt+U49PPGFRbsYs +L6w30faZa8HJ/z44U99dq4egt983ZWJlsThkjl7CeL2UE3UO12Z76aONfaigIOik +ij/D7/A+U9m0e1WqPc4/HmMLIVSYsVMtbcZkrvZcBA0A5c0JCBc0ZsUT6ImBsaSt +NWE7o0CZGzUKJ7OUuxWL4/a5hvyi52DXrJmK5T5v15VbcEf17MQtpNSsLsNugPsw +OAO8eljmDtOWW5aDtLe75UFZuDgHKch8xxMpnuKW+mGc9HC/U7I0GBhhq1LA17Xf +pEv+UfyDFyYWzKuZQ61cCdC+tCvDqeF7iyMgIQjmh6f0I23Kz+cDggEFAAKCAQBu +GFIbwJHL6w/d3Jgw03b7YQQQYX7G4S1rOW/nCs9upklwNo1OI58qvrBvBl3SwubM +uTQfdgjg8IUI24rhwAvtMvvvHkXEPypW9XrmxcABKloGNk0LVdYpzSl3tUH6I95w +YBu7WdWrutFKhLEouWUXHH930fIlm/tnTJlh2J1oE7u1SiH+hHNzjO4ip40qwSjS +CHFm+TBASkg1RJGK5JHTp+9g6kllRGIqKYZ5gf0GT3Xr1kbdahlwQzR4AI+Sgjz9 +z5uCWe/zc2mPhJgkCV/s7KV2oSu7qETkmEyQg8pjiJP0tzRCiQ6FK1GDFmOdQIpl +btKfiD4qC+U4HKBH4xcn +-----END PUBLIC KEY----- diff --git a/iconsets.qrc b/iconsets.qrc new file mode 100644 index 0000000..e1c5a09 --- /dev/null +++ b/iconsets.qrc @@ -0,0 +1,160 @@ + + + + iconsets/system/default/icondef.xml + iconsets/system/default/ssl_no.png + iconsets/system/default/ssl_yes.png + iconsets/system/default/logo_16.png + iconsets/system/default/logo_32.png + iconsets/system/default/logo_48.png + iconsets/system/default/logo_96.png + iconsets/system/default/logo_128.png + + + diff --git a/iconsets/emoticons/default/angry.png b/iconsets/emoticons/default/angry.png new file mode 100644 index 0000000..22e285d Binary files /dev/null and b/iconsets/emoticons/default/angry.png differ diff --git a/iconsets/emoticons/default/bat.png b/iconsets/emoticons/default/bat.png new file mode 100644 index 0000000..2767603 Binary files /dev/null and b/iconsets/emoticons/default/bat.png differ diff --git a/iconsets/emoticons/default/beer.png b/iconsets/emoticons/default/beer.png new file mode 100644 index 0000000..b28d7e3 Binary files /dev/null and b/iconsets/emoticons/default/beer.png differ diff --git a/iconsets/emoticons/default/biggrin.png b/iconsets/emoticons/default/biggrin.png new file mode 100644 index 0000000..dc3d8df Binary files /dev/null and b/iconsets/emoticons/default/biggrin.png differ diff --git a/iconsets/emoticons/default/blush.png b/iconsets/emoticons/default/blush.png new file mode 100644 index 0000000..c434321 Binary files /dev/null and b/iconsets/emoticons/default/blush.png differ diff --git a/iconsets/emoticons/default/boy.png b/iconsets/emoticons/default/boy.png new file mode 100644 index 0000000..9502e87 Binary files /dev/null and b/iconsets/emoticons/default/boy.png differ diff --git a/iconsets/emoticons/default/brflower.png b/iconsets/emoticons/default/brflower.png new file mode 100644 index 0000000..d8be5ea Binary files /dev/null and b/iconsets/emoticons/default/brflower.png differ diff --git a/iconsets/emoticons/default/brheart.png b/iconsets/emoticons/default/brheart.png new file mode 100644 index 0000000..598d894 Binary files /dev/null and b/iconsets/emoticons/default/brheart.png differ diff --git a/iconsets/emoticons/default/coffee.png b/iconsets/emoticons/default/coffee.png new file mode 100644 index 0000000..2890fe5 Binary files /dev/null and b/iconsets/emoticons/default/coffee.png differ diff --git a/iconsets/emoticons/default/coolglasses.png b/iconsets/emoticons/default/coolglasses.png new file mode 100644 index 0000000..cbb49ed Binary files /dev/null and b/iconsets/emoticons/default/coolglasses.png differ diff --git a/iconsets/emoticons/default/cry.png b/iconsets/emoticons/default/cry.png new file mode 100644 index 0000000..4136f7f Binary files /dev/null and b/iconsets/emoticons/default/cry.png differ diff --git a/iconsets/emoticons/default/cuffs.png b/iconsets/emoticons/default/cuffs.png new file mode 100644 index 0000000..ed033ad Binary files /dev/null and b/iconsets/emoticons/default/cuffs.png differ diff --git a/iconsets/emoticons/default/devil.png b/iconsets/emoticons/default/devil.png new file mode 100644 index 0000000..f469a1d Binary files /dev/null and b/iconsets/emoticons/default/devil.png differ diff --git a/iconsets/emoticons/default/drink.png b/iconsets/emoticons/default/drink.png new file mode 100644 index 0000000..970a961 Binary files /dev/null and b/iconsets/emoticons/default/drink.png differ diff --git a/iconsets/emoticons/default/flower.png b/iconsets/emoticons/default/flower.png new file mode 100644 index 0000000..6151ff5 Binary files /dev/null and b/iconsets/emoticons/default/flower.png differ diff --git a/iconsets/emoticons/default/frowning.png b/iconsets/emoticons/default/frowning.png new file mode 100644 index 0000000..ab04d33 Binary files /dev/null and b/iconsets/emoticons/default/frowning.png differ diff --git a/iconsets/emoticons/default/girl.png b/iconsets/emoticons/default/girl.png new file mode 100644 index 0000000..e86a011 Binary files /dev/null and b/iconsets/emoticons/default/girl.png differ diff --git a/iconsets/emoticons/default/heart.png b/iconsets/emoticons/default/heart.png new file mode 100644 index 0000000..3088575 Binary files /dev/null and b/iconsets/emoticons/default/heart.png differ diff --git a/iconsets/emoticons/default/hugleft.png b/iconsets/emoticons/default/hugleft.png new file mode 100644 index 0000000..fcc4c79 Binary files /dev/null and b/iconsets/emoticons/default/hugleft.png differ diff --git a/iconsets/emoticons/default/hugright.png b/iconsets/emoticons/default/hugright.png new file mode 100644 index 0000000..5865d5a Binary files /dev/null and b/iconsets/emoticons/default/hugright.png differ diff --git a/iconsets/emoticons/default/icondef.xml b/iconsets/emoticons/default/icondef.xml new file mode 100644 index 0000000..aabeb19 --- /dev/null +++ b/iconsets/emoticons/default/icondef.xml @@ -0,0 +1,280 @@ + + + + Stellar (default) + 1.0 + Default Psi 0.9.3 iconset + 2003-07-08 + http://psi.affinix.com + Jason Kim + Michail Pishchagin (icondef.xml) + + + + + :-) + :) + + smile.png + + + + ;-) + ;) + + wink.png + + + + :-P + :-p + :P + :p + + tongue.png + + + + :-D + :-d + :D + :d + :-> + :> + + biggrin.png + + + + :-( + :( + + unhappy.png + + + + :'-( + :'( + ;-( + ;( + + cry.png + + + + :-O + :-o + :O + :o + + oh.png + + + + :-@ + :@ + + angry.png + + + + :-$ + :$ + + blush.png + + + + :-| + :| + + stare.png + + + + :-S + :-s + :S + :s + + frowning.png + + + + B-) + B) + (H) + (h) + + coolglasses.png + + + + :-[ + :[ + + bat.png + + + + + (L) + (l) + + heart.png + + + + (U) + (u) + + brheart.png + + + + (Y) + (y) + + yes.png + + + + (N) + (n) + + no.png + + + + (Z) + (z) + + boy.png + + + + (X) + (x) + + girl.png + + + + (@) + + pussy.png + + + + (}) + + hugleft.png + + + + ({) + + hugright.png + + + + (6) + + devil.png + + + + (R) + (r) + + rainbow.png + + + + (W) + (w) + + brflower.png + + + + (F) + (f) + + flower.png + + + + (P) + (p) + + photo.png + + + + (T) + (t) + + phone.png + + + + (*) + + star.png + + + + (8) + + music.png + + + + (I) + (i) + + lamp.png + + + + (B) + (b) + + beer.png + + + + (D) + (d) + + drink.png + + + + (C) + (c) + + coffee.png + + + + (%) + + cuffs.png + + + + (E) + (e) + + mail.png + + + + (K) + (k) + + kiss.png + + diff --git a/iconsets/emoticons/default/kiss.png b/iconsets/emoticons/default/kiss.png new file mode 100644 index 0000000..b951063 Binary files /dev/null and b/iconsets/emoticons/default/kiss.png differ diff --git a/iconsets/emoticons/default/lamp.png b/iconsets/emoticons/default/lamp.png new file mode 100644 index 0000000..f1b6336 Binary files /dev/null and b/iconsets/emoticons/default/lamp.png differ diff --git a/iconsets/emoticons/default/mail.png b/iconsets/emoticons/default/mail.png new file mode 100644 index 0000000..776b380 Binary files /dev/null and b/iconsets/emoticons/default/mail.png differ diff --git a/iconsets/emoticons/default/music.png b/iconsets/emoticons/default/music.png new file mode 100644 index 0000000..56fa9c3 Binary files /dev/null and b/iconsets/emoticons/default/music.png differ diff --git a/iconsets/emoticons/default/no.png b/iconsets/emoticons/default/no.png new file mode 100644 index 0000000..c63797b Binary files /dev/null and b/iconsets/emoticons/default/no.png differ diff --git a/iconsets/emoticons/default/oh.png b/iconsets/emoticons/default/oh.png new file mode 100644 index 0000000..41907a2 Binary files /dev/null and b/iconsets/emoticons/default/oh.png differ diff --git a/iconsets/emoticons/default/phone.png b/iconsets/emoticons/default/phone.png new file mode 100644 index 0000000..b5600c9 Binary files /dev/null and b/iconsets/emoticons/default/phone.png differ diff --git a/iconsets/emoticons/default/photo.png b/iconsets/emoticons/default/photo.png new file mode 100644 index 0000000..d23027c Binary files /dev/null and b/iconsets/emoticons/default/photo.png differ diff --git a/iconsets/emoticons/default/pussy.png b/iconsets/emoticons/default/pussy.png new file mode 100644 index 0000000..3b1473e Binary files /dev/null and b/iconsets/emoticons/default/pussy.png differ diff --git a/iconsets/emoticons/default/rainbow.png b/iconsets/emoticons/default/rainbow.png new file mode 100644 index 0000000..0114614 Binary files /dev/null and b/iconsets/emoticons/default/rainbow.png differ diff --git a/iconsets/emoticons/default/smile.png b/iconsets/emoticons/default/smile.png new file mode 100644 index 0000000..981b7d9 Binary files /dev/null and b/iconsets/emoticons/default/smile.png differ diff --git a/iconsets/emoticons/default/star.png b/iconsets/emoticons/default/star.png new file mode 100644 index 0000000..8d947d8 Binary files /dev/null and b/iconsets/emoticons/default/star.png differ diff --git a/iconsets/emoticons/default/stare.png b/iconsets/emoticons/default/stare.png new file mode 100644 index 0000000..69b393e Binary files /dev/null and b/iconsets/emoticons/default/stare.png differ diff --git a/iconsets/emoticons/default/tongue.png b/iconsets/emoticons/default/tongue.png new file mode 100644 index 0000000..33cfb22 Binary files /dev/null and b/iconsets/emoticons/default/tongue.png differ diff --git a/iconsets/emoticons/default/unhappy.png b/iconsets/emoticons/default/unhappy.png new file mode 100644 index 0000000..464b3de Binary files /dev/null and b/iconsets/emoticons/default/unhappy.png differ diff --git a/iconsets/emoticons/default/wink.png b/iconsets/emoticons/default/wink.png new file mode 100644 index 0000000..d003925 Binary files /dev/null and b/iconsets/emoticons/default/wink.png differ diff --git a/iconsets/emoticons/default/yes.png b/iconsets/emoticons/default/yes.png new file mode 100644 index 0000000..91ea768 Binary files /dev/null and b/iconsets/emoticons/default/yes.png differ diff --git a/iconsets/roster/README b/iconsets/roster/README new file mode 100644 index 0000000..b3c33a3 --- /dev/null +++ b/iconsets/roster/README @@ -0,0 +1,36 @@ +Roster iconset README +~~~~~~~~~~~~~~~~~~~~~ + +For general information about creation of iconsets, see psi/libpsi/iconset/ICONSET-HOWTO. +This file contains only required icon names and some details about them. + +Read a little note about animations in the README for the system iconsets. + +Note: how to add service iconsets: modify src/psiiconset.cpp and add new service RegExp, +add the default iconset name to profiles.cpp, and add your iconset to common.cpp's +category2icon() (and don't forget to add entry to lv_isServices in ui_options.ui). + +status/online - Online +status/offline - Offline +status/away - Away +status/xa - eXtended Away +status/dnd - Do Not Disturb +status/invisible - Invisible +status/chat - Free For Chat + +// special statuses +status/ask - We are asking for authorization +status/noauth - No authorization +status/error - Error status (contact is unavailable due to some reason) + +// special roster icons +psi/chat - Received a chat message +psi/message - Received a message +psi/headline - Received a headline message +psi/system - Received a system event +psi/connect - Connection to server in progress... + +// these icons make sense, only when used in default roster iconset +psi/groupClosed - Closed group in roster +psi/groupEmpty - Empty group in roster +psi/groupOpen - Open group in roster diff --git a/iconsets/roster/crystal-aim.jisp b/iconsets/roster/crystal-aim.jisp new file mode 100644 index 0000000..e8aa51e Binary files /dev/null and b/iconsets/roster/crystal-aim.jisp differ diff --git a/iconsets/roster/crystal-gadu.jisp b/iconsets/roster/crystal-gadu.jisp new file mode 100644 index 0000000..d801a44 Binary files /dev/null and b/iconsets/roster/crystal-gadu.jisp differ diff --git a/iconsets/roster/crystal-icq.jisp b/iconsets/roster/crystal-icq.jisp new file mode 100644 index 0000000..e93626f Binary files /dev/null and b/iconsets/roster/crystal-icq.jisp differ diff --git a/iconsets/roster/crystal-msn.jisp b/iconsets/roster/crystal-msn.jisp new file mode 100644 index 0000000..60d3f30 Binary files /dev/null and b/iconsets/roster/crystal-msn.jisp differ diff --git a/iconsets/roster/crystal-roster.jisp b/iconsets/roster/crystal-roster.jisp new file mode 100644 index 0000000..bf26c83 Binary files /dev/null and b/iconsets/roster/crystal-roster.jisp differ diff --git a/iconsets/roster/crystal-service.jisp b/iconsets/roster/crystal-service.jisp new file mode 100644 index 0000000..37b5dfc Binary files /dev/null and b/iconsets/roster/crystal-service.jisp differ diff --git a/iconsets/roster/crystal-sms.jisp b/iconsets/roster/crystal-sms.jisp new file mode 100644 index 0000000..87e4fcd Binary files /dev/null and b/iconsets/roster/crystal-sms.jisp differ diff --git a/iconsets/roster/crystal-yahoo.jisp b/iconsets/roster/crystal-yahoo.jisp new file mode 100644 index 0000000..e5a0243 Binary files /dev/null and b/iconsets/roster/crystal-yahoo.jisp differ diff --git a/iconsets/roster/default/ask.png b/iconsets/roster/default/ask.png new file mode 100644 index 0000000..6089e52 Binary files /dev/null and b/iconsets/roster/default/ask.png differ diff --git a/iconsets/roster/default/away.png b/iconsets/roster/default/away.png new file mode 100644 index 0000000..c30f344 Binary files /dev/null and b/iconsets/roster/default/away.png differ diff --git a/iconsets/roster/default/chat.fading.png b/iconsets/roster/default/chat.fading.png new file mode 100644 index 0000000..6943b13 Binary files /dev/null and b/iconsets/roster/default/chat.fading.png differ diff --git a/iconsets/roster/default/chatty.png b/iconsets/roster/default/chatty.png new file mode 100644 index 0000000..bae2907 Binary files /dev/null and b/iconsets/roster/default/chatty.png differ diff --git a/iconsets/roster/default/dnd.png b/iconsets/roster/default/dnd.png new file mode 100644 index 0000000..20d71a8 Binary files /dev/null and b/iconsets/roster/default/dnd.png differ diff --git a/iconsets/roster/default/file.fading.png b/iconsets/roster/default/file.fading.png new file mode 100644 index 0000000..00a5c76 Binary files /dev/null and b/iconsets/roster/default/file.fading.png differ diff --git a/iconsets/roster/default/groupclose.png b/iconsets/roster/default/groupclose.png new file mode 100644 index 0000000..49fbee7 Binary files /dev/null and b/iconsets/roster/default/groupclose.png differ diff --git a/iconsets/roster/default/groupopen.png b/iconsets/roster/default/groupopen.png new file mode 100644 index 0000000..0ba4c05 Binary files /dev/null and b/iconsets/roster/default/groupopen.png differ diff --git a/iconsets/roster/default/headline.png b/iconsets/roster/default/headline.png new file mode 100644 index 0000000..b3c2974 Binary files /dev/null and b/iconsets/roster/default/headline.png differ diff --git a/iconsets/roster/default/icondef.xml b/iconsets/roster/default/icondef.xml new file mode 100644 index 0000000..9175423 --- /dev/null +++ b/iconsets/roster/default/icondef.xml @@ -0,0 +1,117 @@ + + + + Stellar3 + Stellar3 Iconset + 0.1 + 2006-08-30 + Jason Kim (Base icon) + Everaldo Coelho (Overlay icons) + Remko Troncon (Packaging) + + + + + status/online + online.png + + + + status/offline + offline.png + + + + status/away + away.png + + + + status/xa + xa.png + + + + status/dnd + dnd.png + + + + status/invisible + invisible.png + + + + status/chat + chatty.png + + + + + status/ask + ask.png + + + + status/noauth + noauth.png + + + + status/error + perr.png + + + + + psi/chat + animation + chat.fading.png + + + + psi/message + animation + message.fading.png + + + + psi/headline + headline.png + + + + psi/file + animation + file.fading.png + + + + psi/system + + system.png + + + + psi/connect + animation + online.dimming.png + + + + psi/groupClosed + groupclose.png + + + + + psi/groupEmpty + groupopen.png + + + + psi/groupOpen + groupopen.png + + diff --git a/iconsets/roster/default/invisible.png b/iconsets/roster/default/invisible.png new file mode 100644 index 0000000..5af7e41 Binary files /dev/null and b/iconsets/roster/default/invisible.png differ diff --git a/iconsets/roster/default/message.fading.png b/iconsets/roster/default/message.fading.png new file mode 100644 index 0000000..22050e6 Binary files /dev/null and b/iconsets/roster/default/message.fading.png differ diff --git a/iconsets/roster/default/noauth.png b/iconsets/roster/default/noauth.png new file mode 100644 index 0000000..ed1fe30 Binary files /dev/null and b/iconsets/roster/default/noauth.png differ diff --git a/iconsets/roster/default/offline.png b/iconsets/roster/default/offline.png new file mode 100644 index 0000000..c46e452 Binary files /dev/null and b/iconsets/roster/default/offline.png differ diff --git a/iconsets/roster/default/online.dimming.png b/iconsets/roster/default/online.dimming.png new file mode 100644 index 0000000..6a05778 Binary files /dev/null and b/iconsets/roster/default/online.dimming.png differ diff --git a/iconsets/roster/default/online.png b/iconsets/roster/default/online.png new file mode 100644 index 0000000..54292d5 Binary files /dev/null and b/iconsets/roster/default/online.png differ diff --git a/iconsets/roster/default/perr.png b/iconsets/roster/default/perr.png new file mode 100644 index 0000000..9152973 Binary files /dev/null and b/iconsets/roster/default/perr.png differ diff --git a/iconsets/roster/default/system.png b/iconsets/roster/default/system.png new file mode 100644 index 0000000..fd49f31 Binary files /dev/null and b/iconsets/roster/default/system.png differ diff --git a/iconsets/roster/default/xa.png b/iconsets/roster/default/xa.png new file mode 100644 index 0000000..e859acb Binary files /dev/null and b/iconsets/roster/default/xa.png differ diff --git a/iconsets/system/README b/iconsets/system/README new file mode 100644 index 0000000..68076ff --- /dev/null +++ b/iconsets/system/README @@ -0,0 +1,79 @@ +System iconset README +~~~~~~~~~~~~~~~~~~~~~ + +For general information about creation of iconsets, see psi/libpsi/iconset/ICONSET-HOWTO. +This file contains only required icon names and some details about them. + +System iconset, is a special iconset, that contains icons that are used in labels, +buttons and other widgets in Psi. + +And a little note about animations: Icons could contain animations, and system Psi +animations are a bit special. Their first frame is used only for creation of static +images (such as in popup menus, or if Psi's alert style is set to 'blink'). This first +frame is not used in animation (since it's stripped out of them). + +PS: If you would use Psi's .png-style animation don't forget to add animation +tag to the icon. + +psi/account - Used in Modify accounts dialog +psi/addContact - Add contact +psi/arrowUp - Arrow up +psi/arrowDown - Arrow down +psi/arrowLeft - Arrow left +psi/arrowRight - Arrow right +psi/profile - Change account +psi/clearChat - Clear chat +psi/groupChat - GroupChat +psi/help - Help menu +psi/history - Chat history +psi/vCard - vCard/User info +psi/info - Info icon +psi/jabber - Jabber icon +psi/options - Options +psi/toolbars - Configure Toolbars +psi/pgp - PGP +psi/keySingle - Single (public) PGP key +psi/keyBad - Bad PGP key +psi/keyDouble - Double (public + private) PGP key +psi/keyUnknown - Unknown PGP key +psi/playSounds - Play sounds +psi/psiMain - Psi logo, used in roster and tray context menu +psi/quit - Quit +psi/register - Register service +psi/reload - Reload button +psi/stop - Stop button +psi/remove - Remove/Delete item +psi/search - Search service +psi/sendMessage - New plain message/Send message +psi/cryptoYes - Encryption enabled +psi/cryptoNo - Encryption disabled +psi/time - Time +psi/www - URL icon +psi/email - Email icon +psi/xml - XML icon +psi/psi16 - 16x16 Psi icon +psi/psi32 - 32x32 Psi icon +psi/psi48 - 48x48 Psi icon +psi/psiMac - 128x128 Psi MacOS X icon +psi/psiLogo - Psi logo. Used in the first dialog. NOTE: the leftmost and the + rightmost vertical lines of that icon are used for stretching +psi/smile - Used in the profile creation dialog +psi/ok - Check icon +psi/cancel - Cross icon +psi/done - Done icon -- TODO +psi/close - Close icon -- TODO: add to default iconset +psi/apply - Apply icon -- TODO: add +psi/edit/clear - Clear icon +psi/edit/copy - Copy icon +psi/edit/cut - Cut icon +psi/edit/delete - Delete icon +psi/edit/paste - Paste icon +psi/edit - Edit icon +psi/edit/trash - Trash icon +psi/tip - Tip of the Day +psi/browse - Browse file +psi/play - Play sound +psi/eye - Used to determine Hidden group visibility +psi/upload - Upload icon +psi/download - Download icon +psi/filemanager - Transfer Manager diff --git a/iconsets/system/default/account.png b/iconsets/system/default/account.png new file mode 100644 index 0000000..0240ab6 Binary files /dev/null and b/iconsets/system/default/account.png differ diff --git a/iconsets/system/default/add.png b/iconsets/system/default/add.png new file mode 100644 index 0000000..cec9f51 Binary files /dev/null and b/iconsets/system/default/add.png differ diff --git a/iconsets/system/default/advanced.png b/iconsets/system/default/advanced.png new file mode 100644 index 0000000..85c9de0 Binary files /dev/null and b/iconsets/system/default/advanced.png differ diff --git a/iconsets/system/default/appearance.png b/iconsets/system/default/appearance.png new file mode 100644 index 0000000..33c3767 Binary files /dev/null and b/iconsets/system/default/appearance.png differ diff --git a/iconsets/system/default/arrow_down.png b/iconsets/system/default/arrow_down.png new file mode 100644 index 0000000..19ad376 Binary files /dev/null and b/iconsets/system/default/arrow_down.png differ diff --git a/iconsets/system/default/arrow_left.png b/iconsets/system/default/arrow_left.png new file mode 100644 index 0000000..e6f5722 Binary files /dev/null and b/iconsets/system/default/arrow_left.png differ diff --git a/iconsets/system/default/arrow_right.png b/iconsets/system/default/arrow_right.png new file mode 100644 index 0000000..b7746b3 Binary files /dev/null and b/iconsets/system/default/arrow_right.png differ diff --git a/iconsets/system/default/arrow_up.png b/iconsets/system/default/arrow_up.png new file mode 100644 index 0000000..36547c1 Binary files /dev/null and b/iconsets/system/default/arrow_up.png differ diff --git a/iconsets/system/default/browse.png b/iconsets/system/default/browse.png new file mode 100644 index 0000000..037c2da Binary files /dev/null and b/iconsets/system/default/browse.png differ diff --git a/iconsets/system/default/cancel.png b/iconsets/system/default/cancel.png new file mode 100644 index 0000000..8975c68 Binary files /dev/null and b/iconsets/system/default/cancel.png differ diff --git a/iconsets/system/default/changeacc.png b/iconsets/system/default/changeacc.png new file mode 100644 index 0000000..66a9fe8 Binary files /dev/null and b/iconsets/system/default/changeacc.png differ diff --git a/iconsets/system/default/chatclear.png b/iconsets/system/default/chatclear.png new file mode 100644 index 0000000..79e15ac Binary files /dev/null and b/iconsets/system/default/chatclear.png differ diff --git a/iconsets/system/default/close.png b/iconsets/system/default/close.png new file mode 100644 index 0000000..688cb5c Binary files /dev/null and b/iconsets/system/default/close.png differ diff --git a/iconsets/system/default/closetab.png b/iconsets/system/default/closetab.png new file mode 100644 index 0000000..597a070 Binary files /dev/null and b/iconsets/system/default/closetab.png differ diff --git a/iconsets/system/default/command.png b/iconsets/system/default/command.png new file mode 100644 index 0000000..efc3a71 Binary files /dev/null and b/iconsets/system/default/command.png differ diff --git a/iconsets/system/default/configure-room.png b/iconsets/system/default/configure-room.png new file mode 100644 index 0000000..95bd319 Binary files /dev/null and b/iconsets/system/default/configure-room.png differ diff --git a/iconsets/system/default/configure_toolbars.png b/iconsets/system/default/configure_toolbars.png new file mode 100644 index 0000000..ae1d04f Binary files /dev/null and b/iconsets/system/default/configure_toolbars.png differ diff --git a/iconsets/system/default/disco.png b/iconsets/system/default/disco.png new file mode 100644 index 0000000..378afc5 Binary files /dev/null and b/iconsets/system/default/disco.png differ diff --git a/iconsets/system/default/download.png b/iconsets/system/default/download.png new file mode 100644 index 0000000..cafac61 Binary files /dev/null and b/iconsets/system/default/download.png differ diff --git a/iconsets/system/default/events.png b/iconsets/system/default/events.png new file mode 100644 index 0000000..fd49f31 Binary files /dev/null and b/iconsets/system/default/events.png differ diff --git a/iconsets/system/default/eye_blue.png b/iconsets/system/default/eye_blue.png new file mode 100644 index 0000000..f671311 Binary files /dev/null and b/iconsets/system/default/eye_blue.png differ diff --git a/iconsets/system/default/filemanager.png b/iconsets/system/default/filemanager.png new file mode 100644 index 0000000..41b3f43 Binary files /dev/null and b/iconsets/system/default/filemanager.png differ diff --git a/iconsets/system/default/groupchat.png b/iconsets/system/default/groupchat.png new file mode 100644 index 0000000..31b6f33 Binary files /dev/null and b/iconsets/system/default/groupchat.png differ diff --git a/iconsets/system/default/help.png b/iconsets/system/default/help.png new file mode 100644 index 0000000..cd32162 Binary files /dev/null and b/iconsets/system/default/help.png differ diff --git a/iconsets/system/default/history.png b/iconsets/system/default/history.png new file mode 100644 index 0000000..e2a44ec Binary files /dev/null and b/iconsets/system/default/history.png differ diff --git a/iconsets/system/default/icondef.xml b/iconsets/system/default/icondef.xml new file mode 100644 index 0000000..4d8b4cd --- /dev/null +++ b/iconsets/system/default/icondef.xml @@ -0,0 +1,486 @@ + + + + Crystal - System (default) + 1.0 + Crystal System Iconset + 2005-11-23 + http://psi.affinix.com + Jason Kim (Logo and misc. icons) + Everaldo Coelho (Crystal icons) + + + + psi/appearance + appearance.png + + + + psi/account + account.png + + + + psi/statusmsg + info.png + + + + psi/addContact + add.png + + + + psi/arrowUp + arrow_up.png + + + + psi/arrowDown + arrow_down.png + + + + psi/arrowLeft + arrow_left.png + + + + psi/arrowRight + arrow_right.png + + + + psi/profile + changeacc.png + + + + psi/clearChat + chatclear.png + + + + psi/compact + ok.png + + + + psi/disco + disco.png + + + + psi/events + events.png + + + + psi/groupChat + groupchat.png + + + + psi/help + help.png + + + + psi/history + history.png + + + + psi/shortcuts + shortcuts.png + + + + psi/vCard + vcard.png + + + + psi/jabber + jabber.png + + + + psi/options + options.png + + + + psi/toolbars + configure_toolbars.png + + + + psi/configure-room + configure-room.png + + + + psi/pgp + pgp.png + + + + psi/gpg-yes + key.png + + + + psi/gpg-no + key.png + + + + psi/keyBad + key_bad.png + + + + psi/keyUnknown + key_unknown.png + + + + psi/playSounds + play_sounds.png + + + + psi/voice + play_sounds.png + + + + psi/main + psimain.png + + + + psi/quit + quit.png + + + + psi/register + register.png + + + + psi/reload + reload.png + + + + psi/stop + stop.png + + + + psi/remove + remove.png + + + + psi/search + search.png + + + + psi/status + status.png + + + + psi/sendMessage + send.png + + + + psi/start-chat + start-chat.png + + + + psi/cryptoYes + ssl_yes.png + + + + psi/cryptoNo + ssl_no.png + + + + psi/time + time.png + + + + psi/www + url.png + + + + psi/xml + xml.png + + + + psi/logo_16 + logo_16.png + + + + psi/logo_32 + logo_32.png + + + + psi/logo_48 + logo_48.png + + + + psi/logo_64 + logo_64.png + + + + psi/logo_128 + logo_128.png + + + + psi/psiLogo + psilogo.png + + + + psi/smile + smile.png + + + + psi/email + send.png + + + + psi/ok + ok.png + + + + psi/done + close.png + + + + psi/closetab + closetab.png + + + + psi/cancel + cancel.png + + + + psi/close + close.png + + + + psi/apply + ok.png + + + + psi/info + info.png + + + + psi/tip + tip.png + + + + psi/browse + browse.png + + + + psi/play + play.png + + + + psi/eye + eye_blue.png + + + + psi/upload + upload.png + + + + psi/download + download.png + + + + psi/filemanager + filemanager.png + + + + psi/command + command.png + + + + + + psi/roster + url.png + + + + psi/advanced + advanced.png + + + + psi/show_self + self.png + + + + psi/show_offline + show_offline.png + + + + psi/show_away + show_away.png + + + + psi/show_hidden + show_hidden.png + + + + psi/publishTune + publish_tune.png + + + + + psi/whiteboard + whiteboarding/whiteboard.png + + + + psi/select + whiteboarding/select.png + + + + psi/translate + whiteboarding/translate.png + + + + psi/rotate + whiteboarding/rotate.png + + + + psi/scale + whiteboarding/scale.png + + + + psi/scroll + whiteboarding/scroll.png + + + + psi/erase + whiteboarding/erase.png + + + + psi/drawPaths + whiteboarding/draw_paths.png + + + + psi/drawLines + whiteboarding/draw_lines.png + + + + psi/drawEllipses + whiteboarding/draw_ellipses.png + + + + psi/drawCircles + whiteboarding/draw_circles.png + + + + psi/drawRectangles + whiteboarding/draw_rectangles.png + + + + psi/addText + whiteboarding/add_text.png + + + + psi/addImage + whiteboarding/add_image.png + + + + psi/bringForwards + whiteboarding/bring_forwards.png + + + + psi/bringToFront + whiteboarding/bring_to_front.png + + + + psi/sendBackwards + whiteboarding/send_backwards.png + + + + psi/sendToBack + whiteboarding/send_to_back.png + + + + psi/group + whiteboarding/group.png + + + + psi/ungroup + whiteboarding/ungroup.png + + + diff --git a/iconsets/system/default/info.png b/iconsets/system/default/info.png new file mode 100644 index 0000000..1903fab Binary files /dev/null and b/iconsets/system/default/info.png differ diff --git a/iconsets/system/default/jabber.png b/iconsets/system/default/jabber.png new file mode 100644 index 0000000..e96d826 Binary files /dev/null and b/iconsets/system/default/jabber.png differ diff --git a/iconsets/system/default/key.png b/iconsets/system/default/key.png new file mode 100644 index 0000000..ca93f0d Binary files /dev/null and b/iconsets/system/default/key.png differ diff --git a/iconsets/system/default/key_bad.png b/iconsets/system/default/key_bad.png new file mode 100644 index 0000000..04a93f2 Binary files /dev/null and b/iconsets/system/default/key_bad.png differ diff --git a/iconsets/system/default/key_unknown.png b/iconsets/system/default/key_unknown.png new file mode 100644 index 0000000..a21c0a1 Binary files /dev/null and b/iconsets/system/default/key_unknown.png differ diff --git a/iconsets/system/default/logo_128.png b/iconsets/system/default/logo_128.png new file mode 100644 index 0000000..3a569b6 Binary files /dev/null and b/iconsets/system/default/logo_128.png differ diff --git a/iconsets/system/default/logo_16.png b/iconsets/system/default/logo_16.png new file mode 100644 index 0000000..058ef7b Binary files /dev/null and b/iconsets/system/default/logo_16.png differ diff --git a/iconsets/system/default/logo_24.png b/iconsets/system/default/logo_24.png new file mode 100644 index 0000000..10bdcfa Binary files /dev/null and b/iconsets/system/default/logo_24.png differ diff --git a/iconsets/system/default/logo_256.png b/iconsets/system/default/logo_256.png new file mode 100644 index 0000000..65bc58f Binary files /dev/null and b/iconsets/system/default/logo_256.png differ diff --git a/iconsets/system/default/logo_32.png b/iconsets/system/default/logo_32.png new file mode 100644 index 0000000..b1e89f1 Binary files /dev/null and b/iconsets/system/default/logo_32.png differ diff --git a/iconsets/system/default/logo_48.png b/iconsets/system/default/logo_48.png new file mode 100644 index 0000000..3a9dbec Binary files /dev/null and b/iconsets/system/default/logo_48.png differ diff --git a/iconsets/system/default/logo_64.png b/iconsets/system/default/logo_64.png new file mode 100644 index 0000000..25d3771 Binary files /dev/null and b/iconsets/system/default/logo_64.png differ diff --git a/iconsets/system/default/logo_96.png b/iconsets/system/default/logo_96.png new file mode 100644 index 0000000..562b6b8 Binary files /dev/null and b/iconsets/system/default/logo_96.png differ diff --git a/iconsets/system/default/ok.png b/iconsets/system/default/ok.png new file mode 100644 index 0000000..d88b146 Binary files /dev/null and b/iconsets/system/default/ok.png differ diff --git a/iconsets/system/default/options.png b/iconsets/system/default/options.png new file mode 100644 index 0000000..5d92de3 Binary files /dev/null and b/iconsets/system/default/options.png differ diff --git a/iconsets/system/default/pgp.png b/iconsets/system/default/pgp.png new file mode 100644 index 0000000..10e8afd Binary files /dev/null and b/iconsets/system/default/pgp.png differ diff --git a/iconsets/system/default/play.png b/iconsets/system/default/play.png new file mode 100644 index 0000000..26d6fe3 Binary files /dev/null and b/iconsets/system/default/play.png differ diff --git a/iconsets/system/default/play_sounds.png b/iconsets/system/default/play_sounds.png new file mode 100644 index 0000000..9a7b6ae Binary files /dev/null and b/iconsets/system/default/play_sounds.png differ diff --git a/iconsets/system/default/psilogo.png b/iconsets/system/default/psilogo.png new file mode 100644 index 0000000..5a005f6 Binary files /dev/null and b/iconsets/system/default/psilogo.png differ diff --git a/iconsets/system/default/psimain.png b/iconsets/system/default/psimain.png new file mode 100644 index 0000000..f74bd12 Binary files /dev/null and b/iconsets/system/default/psimain.png differ diff --git a/iconsets/system/default/publish_tune.png b/iconsets/system/default/publish_tune.png new file mode 100644 index 0000000..dbf51d2 Binary files /dev/null and b/iconsets/system/default/publish_tune.png differ diff --git a/iconsets/system/default/quit.png b/iconsets/system/default/quit.png new file mode 100644 index 0000000..9e78eb1 Binary files /dev/null and b/iconsets/system/default/quit.png differ diff --git a/iconsets/system/default/register.png b/iconsets/system/default/register.png new file mode 100644 index 0000000..325daef Binary files /dev/null and b/iconsets/system/default/register.png differ diff --git a/iconsets/system/default/reload.png b/iconsets/system/default/reload.png new file mode 100644 index 0000000..667219f Binary files /dev/null and b/iconsets/system/default/reload.png differ diff --git a/iconsets/system/default/remove.png b/iconsets/system/default/remove.png new file mode 100644 index 0000000..7eff52d Binary files /dev/null and b/iconsets/system/default/remove.png differ diff --git a/iconsets/system/default/search.png b/iconsets/system/default/search.png new file mode 100644 index 0000000..d99f70b Binary files /dev/null and b/iconsets/system/default/search.png differ diff --git a/iconsets/system/default/self.png b/iconsets/system/default/self.png new file mode 100644 index 0000000..65f5d9a Binary files /dev/null and b/iconsets/system/default/self.png differ diff --git a/iconsets/system/default/send.png b/iconsets/system/default/send.png new file mode 100644 index 0000000..d42bb0a Binary files /dev/null and b/iconsets/system/default/send.png differ diff --git a/iconsets/system/default/shortcuts.png b/iconsets/system/default/shortcuts.png new file mode 100644 index 0000000..198d202 Binary files /dev/null and b/iconsets/system/default/shortcuts.png differ diff --git a/iconsets/system/default/show_away.png b/iconsets/system/default/show_away.png new file mode 100644 index 0000000..c30f344 Binary files /dev/null and b/iconsets/system/default/show_away.png differ diff --git a/iconsets/system/default/show_hidden.png b/iconsets/system/default/show_hidden.png new file mode 100644 index 0000000..9e276f5 Binary files /dev/null and b/iconsets/system/default/show_hidden.png differ diff --git a/iconsets/system/default/show_offline.png b/iconsets/system/default/show_offline.png new file mode 100644 index 0000000..c46e452 Binary files /dev/null and b/iconsets/system/default/show_offline.png differ diff --git a/iconsets/system/default/smile.png b/iconsets/system/default/smile.png new file mode 100644 index 0000000..3567cd0 Binary files /dev/null and b/iconsets/system/default/smile.png differ diff --git a/iconsets/system/default/ssl_no.png b/iconsets/system/default/ssl_no.png new file mode 100644 index 0000000..e3532f2 Binary files /dev/null and b/iconsets/system/default/ssl_no.png differ diff --git a/iconsets/system/default/ssl_yes.png b/iconsets/system/default/ssl_yes.png new file mode 100644 index 0000000..2986704 Binary files /dev/null and b/iconsets/system/default/ssl_yes.png differ diff --git a/iconsets/system/default/start-chat.png b/iconsets/system/default/start-chat.png new file mode 100644 index 0000000..e6b17b1 Binary files /dev/null and b/iconsets/system/default/start-chat.png differ diff --git a/iconsets/system/default/status.png b/iconsets/system/default/status.png new file mode 100644 index 0000000..38b6388 Binary files /dev/null and b/iconsets/system/default/status.png differ diff --git a/iconsets/system/default/stop.png b/iconsets/system/default/stop.png new file mode 100644 index 0000000..19ef9bd Binary files /dev/null and b/iconsets/system/default/stop.png differ diff --git a/iconsets/system/default/time.png b/iconsets/system/default/time.png new file mode 100644 index 0000000..280a010 Binary files /dev/null and b/iconsets/system/default/time.png differ diff --git a/iconsets/system/default/tip.png b/iconsets/system/default/tip.png new file mode 100644 index 0000000..ab210ab Binary files /dev/null and b/iconsets/system/default/tip.png differ diff --git a/iconsets/system/default/upload.png b/iconsets/system/default/upload.png new file mode 100644 index 0000000..91e3b24 Binary files /dev/null and b/iconsets/system/default/upload.png differ diff --git a/iconsets/system/default/url.png b/iconsets/system/default/url.png new file mode 100644 index 0000000..610cd76 Binary files /dev/null and b/iconsets/system/default/url.png differ diff --git a/iconsets/system/default/vcard.png b/iconsets/system/default/vcard.png new file mode 100644 index 0000000..631d4e3 Binary files /dev/null and b/iconsets/system/default/vcard.png differ diff --git a/iconsets/system/default/whiteboarding/add_image.png b/iconsets/system/default/whiteboarding/add_image.png new file mode 100644 index 0000000..b0ce7bb Binary files /dev/null and b/iconsets/system/default/whiteboarding/add_image.png differ diff --git a/iconsets/system/default/whiteboarding/add_text.png b/iconsets/system/default/whiteboarding/add_text.png new file mode 100644 index 0000000..b7960db Binary files /dev/null and b/iconsets/system/default/whiteboarding/add_text.png differ diff --git a/iconsets/system/default/whiteboarding/bring_forwards.png b/iconsets/system/default/whiteboarding/bring_forwards.png new file mode 100644 index 0000000..00818f6 Binary files /dev/null and b/iconsets/system/default/whiteboarding/bring_forwards.png differ diff --git a/iconsets/system/default/whiteboarding/bring_to_front.png b/iconsets/system/default/whiteboarding/bring_to_front.png new file mode 100644 index 0000000..00818f6 Binary files /dev/null and b/iconsets/system/default/whiteboarding/bring_to_front.png differ diff --git a/iconsets/system/default/whiteboarding/draw_circles.png b/iconsets/system/default/whiteboarding/draw_circles.png new file mode 100644 index 0000000..6535b0c Binary files /dev/null and b/iconsets/system/default/whiteboarding/draw_circles.png differ diff --git a/iconsets/system/default/whiteboarding/draw_ellipses.png b/iconsets/system/default/whiteboarding/draw_ellipses.png new file mode 100644 index 0000000..6535b0c Binary files /dev/null and b/iconsets/system/default/whiteboarding/draw_ellipses.png differ diff --git a/iconsets/system/default/whiteboarding/draw_lines.png b/iconsets/system/default/whiteboarding/draw_lines.png new file mode 100644 index 0000000..0bfecd5 Binary files /dev/null and b/iconsets/system/default/whiteboarding/draw_lines.png differ diff --git a/iconsets/system/default/whiteboarding/draw_paths.png b/iconsets/system/default/whiteboarding/draw_paths.png new file mode 100644 index 0000000..0bfecd5 Binary files /dev/null and b/iconsets/system/default/whiteboarding/draw_paths.png differ diff --git a/iconsets/system/default/whiteboarding/draw_rectangles.png b/iconsets/system/default/whiteboarding/draw_rectangles.png new file mode 100644 index 0000000..b485a39 Binary files /dev/null and b/iconsets/system/default/whiteboarding/draw_rectangles.png differ diff --git a/iconsets/system/default/whiteboarding/erase.png b/iconsets/system/default/whiteboarding/erase.png new file mode 100644 index 0000000..79e15ac Binary files /dev/null and b/iconsets/system/default/whiteboarding/erase.png differ diff --git a/iconsets/system/default/whiteboarding/group.png b/iconsets/system/default/whiteboarding/group.png new file mode 100644 index 0000000..25eacb7 Binary files /dev/null and b/iconsets/system/default/whiteboarding/group.png differ diff --git a/iconsets/system/default/whiteboarding/rotate.png b/iconsets/system/default/whiteboarding/rotate.png new file mode 100644 index 0000000..2434948 Binary files /dev/null and b/iconsets/system/default/whiteboarding/rotate.png differ diff --git a/iconsets/system/default/whiteboarding/scale.png b/iconsets/system/default/whiteboarding/scale.png new file mode 100644 index 0000000..5b0377c Binary files /dev/null and b/iconsets/system/default/whiteboarding/scale.png differ diff --git a/iconsets/system/default/whiteboarding/scroll.png b/iconsets/system/default/whiteboarding/scroll.png new file mode 100644 index 0000000..564a1a9 Binary files /dev/null and b/iconsets/system/default/whiteboarding/scroll.png differ diff --git a/iconsets/system/default/whiteboarding/select.png b/iconsets/system/default/whiteboarding/select.png new file mode 100644 index 0000000..532f532 Binary files /dev/null and b/iconsets/system/default/whiteboarding/select.png differ diff --git a/iconsets/system/default/whiteboarding/send_backwards.png b/iconsets/system/default/whiteboarding/send_backwards.png new file mode 100644 index 0000000..00818f6 Binary files /dev/null and b/iconsets/system/default/whiteboarding/send_backwards.png differ diff --git a/iconsets/system/default/whiteboarding/send_to_back.png b/iconsets/system/default/whiteboarding/send_to_back.png new file mode 100644 index 0000000..00818f6 Binary files /dev/null and b/iconsets/system/default/whiteboarding/send_to_back.png differ diff --git a/iconsets/system/default/whiteboarding/translate.png b/iconsets/system/default/whiteboarding/translate.png new file mode 100644 index 0000000..bb90fb2 Binary files /dev/null and b/iconsets/system/default/whiteboarding/translate.png differ diff --git a/iconsets/system/default/whiteboarding/ungroup.png b/iconsets/system/default/whiteboarding/ungroup.png new file mode 100644 index 0000000..f66e297 Binary files /dev/null and b/iconsets/system/default/whiteboarding/ungroup.png differ diff --git a/iconsets/system/default/whiteboarding/whiteboard.png b/iconsets/system/default/whiteboarding/whiteboard.png new file mode 100644 index 0000000..fb2efb8 Binary files /dev/null and b/iconsets/system/default/whiteboarding/whiteboard.png differ diff --git a/iconsets/system/default/xml.png b/iconsets/system/default/xml.png new file mode 100644 index 0000000..efc3a71 Binary files /dev/null and b/iconsets/system/default/xml.png differ diff --git a/iris-legacy/cutestuff/cutestuff.pri b/iris-legacy/cutestuff/cutestuff.pri new file mode 100644 index 0000000..d2afbdd --- /dev/null +++ b/iris-legacy/cutestuff/cutestuff.pri @@ -0,0 +1,32 @@ +INCLUDEPATH += $$PWD/util $$PWD/network +DEPENDPATH += $$PWD/util $$PWD/network + +HEADERS += \ + $$PWD/util/bytestream.h \ + $$PWD/network/bsocket.h \ + $$PWD/network/httpconnect.h \ + $$PWD/network/httppoll.h \ + $$PWD/network/socks.h + +SOURCES += \ + $$PWD/util/bytestream.cpp \ + $$PWD/network/bsocket.cpp \ + $$PWD/network/httpconnect.cpp \ + $$PWD/network/httppoll.cpp \ + $$PWD/network/socks.cpp + +!irisnet { + INCLUDEPATH += $$PWD/legacy + HEADERS += \ + $$PWD/legacy/safedelete.h \ + $$PWD/legacy/ndns.h \ + $$PWD/legacy/srvresolver.h \ + $$PWD/legacy/servsock.h + + SOURCES += \ + $$PWD/legacy/safedelete.cpp \ + $$PWD/legacy/ndns.cpp \ + $$PWD/legacy/srvresolver.cpp \ + $$PWD/legacy/servsock.cpp +} + diff --git a/iris-legacy/cutestuff/legacy/ndns.cpp b/iris-legacy/cutestuff/legacy/ndns.cpp new file mode 100644 index 0000000..15d95f9 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/ndns.cpp @@ -0,0 +1,393 @@ +/* + * ndns.cpp - native DNS resolution + * Copyright (C) 2001, 2002 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +//! \class NDns ndns.h +//! \brief Simple DNS resolution using native system calls +//! +//! This class is to be used when Qt's QDns is not good enough. Because QDns +//! does not use threads, it cannot make a system call asyncronously. Thus, +//! QDns tries to imitate the behavior of each platform's native behavior, and +//! generally falls short. +//! +//! NDns uses a thread to make the system call happen in the background. This +//! gives your program native DNS behavior, at the cost of requiring threads +//! to build. +//! +//! \code +//! #include "ndns.h" +//! +//! ... +//! +//! NDns dns; +//! dns.resolve("psi.affinix.com"); +//! +//! // The class will emit the resultsReady() signal when the resolution +//! // is finished. You may then retrieve the results: +//! +//! QHostAddress ip_address = dns.result(); +//! +//! // or if you want to get the IP address as a string: +//! +//! QString ip_address = dns.resultString(); +//! \endcode + +#include "ndns.h" + +#include +#include +#include +#include +//Added by qt3to4: +#include +#include +#include +#include + +#ifdef Q_OS_UNIX +#include +#include +#include +#include +#include +#endif + +#ifdef Q_OS_WIN32 +#include +#endif + +#include "psilogger.h" + +// CS_NAMESPACE_BEGIN + +//! \if _hide_doc_ +class NDnsWorker : public QThread +{ +public: + NDnsWorker(QObject *, const Q3CString &); + ~NDnsWorker(); + + bool success; + bool cancelled; + QHostAddress addr; + +protected: + void run(); + +private: + Q3CString host; +}; +//! \endif + +//---------------------------------------------------------------------------- +// NDnsManager +//---------------------------------------------------------------------------- +#ifndef HAVE_GETHOSTBYNAME_R +#ifndef Q_WS_WIN +static QMutex *workerMutex = 0; +static QMutex *workerCancelled = 0; +#endif +#endif +static NDnsManager *manager_instance = 0; +bool winsock_init = false; + +class NDnsManager::Item +{ +public: + NDns *ndns; + NDnsWorker *worker; +}; + +class NDnsManager::Private +{ +public: + Item *find(const NDns *n) + { + Q3PtrListIterator it(list); + for(Item *i; (i = it.current()); ++it) { + if(i->ndns == n) + return i; + } + return 0; + } + + Item *find(const NDnsWorker *w) + { + Q3PtrListIterator it(list); + for(Item *i; (i = it.current()); ++it) { + if(i->worker == w) + return i; + } + return 0; + } + + Q3PtrList list; +}; + +NDnsManager::NDnsManager() +: QObject(QCoreApplication::instance()) +{ +#ifndef HAVE_GETHOSTBYNAME_R +#ifndef Q_WS_WIN + workerMutex = new QMutex; + workerCancelled = new QMutex; +#endif +#endif + +#ifdef Q_OS_WIN32 + if(!winsock_init) { + winsock_init = true; + Q3SocketDevice *sd = new Q3SocketDevice; + delete sd; + } +#endif + + d = new Private; + d->list.setAutoDelete(true); + + connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(app_aboutToQuit())); +} + +NDnsManager::~NDnsManager() +{ + delete d; + +#ifndef HAVE_GETHOSTBYNAME_R +#ifndef Q_WS_WIN + delete workerMutex; + workerMutex = 0; + delete workerCancelled; + workerCancelled = 0; +#endif +#endif +} + +void NDnsManager::resolve(NDns *self, const QString &name) +{ + Item *i = new Item; + i->ndns = self; + i->worker = new NDnsWorker(this, name.utf8()); + connect(i->worker, SIGNAL(finished()), SLOT(workerFinished())); + d->list.append(i); + + i->worker->start(); +} + +void NDnsManager::stop(NDns *self) +{ + Item *i = d->find(self); + if(!i) + return; + // disassociate + i->ndns = 0; + +#ifndef HAVE_GETHOSTBYNAME_R +#ifndef Q_WS_WIN + // cancel + workerCancelled->lock(); + i->worker->cancelled = true; + workerCancelled->unlock(); +#endif +#endif + + d->list.removeRef(i); +} + +bool NDnsManager::isBusy(const NDns *self) const +{ + Item *i = d->find(self); + return (i ? true: false); +} + +void NDnsManager::workerFinished() +{ + NDnsWorker* worker = dynamic_cast(sender()); + Q_ASSERT(worker); + if (!worker) + return; + worker->wait(); // ensure that the thread is terminated + + Item *i = d->find(worker); + if(i) { + QHostAddress addr = i->worker->addr; + QPointer ndns = i->ndns; + d->list.removeRef(i); + + // nuke manager if no longer needed (code that follows MUST BE SAFE!) + tryDestroy(); + + // requestor still around? + if(ndns) { + ndns->finished(addr); + } + } + + worker->deleteLater(); +} + +void NDnsManager::tryDestroy() +{ +// mblsha: NDnsManager is now singleton +#if 0 + if(d->list.isEmpty()) { + manager_instance = 0; + deleteLater(); + } +#endif +} + +void NDnsManager::app_aboutToQuit() +{ +// mblsha: NDnsManager is now singleton +#if 0 + while(man) { + QCoreApplication::instance()->processEvents(QEventLoop::WaitForMoreEvents); + } +#endif +} + + +//---------------------------------------------------------------------------- +// NDns +//---------------------------------------------------------------------------- + +//! \fn void NDns::resultsReady() +//! This signal is emitted when the DNS resolution succeeds or fails. + +//! +//! Constructs an NDns object with parent \a parent. +NDns::NDns(QObject *parent) +:QObject(parent) +{ +} + +//! +//! Destroys the object and frees allocated resources. +NDns::~NDns() +{ + stop(); + PsiLogger::instance()->log(QString("%1 NDns::~NDns()").arg(LOG_THIS)); +} + +//! +//! Resolves hostname \a host (eg. psi.affinix.com) +void NDns::resolve(const QString &host) +{ + PsiLogger::instance()->log(QString("%1 NDns::resolve(%2)").arg(LOG_THIS).arg(host)); + stop(); + if(!manager_instance) + manager_instance = new NDnsManager; + manager_instance->resolve(this, host); +} + +//! +//! Cancels the lookup action. +//! \note This will not stop the underlying system call, which must finish before the next lookup will proceed. +void NDns::stop() +{ + PsiLogger::instance()->log(QString("%1 NDns::stop()").arg(LOG_THIS)); + if(manager_instance) + manager_instance->stop(this); +} + +//! +//! Returns the IP address as QHostAddress. This will be a Null QHostAddress if the lookup failed. +//! \sa resultsReady() +QHostAddress NDns::result() const +{ + return addr; +} + +//! +//! Returns the IP address as a string. This will be an empty string if the lookup failed. +//! \sa resultsReady() +QString NDns::resultString() const +{ + if (addr.isNull()) + return QString(); + else + return addr.toString(); +} + +//! +//! Returns TRUE if busy resolving a hostname. +bool NDns::isBusy() const +{ + if(!manager_instance) + return false; + return manager_instance->isBusy(this); +} + +void NDns::finished(const QHostAddress &a) +{ + PsiLogger::instance()->log(QString("%1 NDns::finished(%2)").arg(LOG_THIS).arg(a.toString())); + addr = a; + resultsReady(); +} + +//---------------------------------------------------------------------------- +// NDnsWorker +//---------------------------------------------------------------------------- +NDnsWorker::NDnsWorker(QObject *_par, const Q3CString &_host) +: QThread(_par) +{ + success = cancelled = false; + host = _host.copy(); // do we need this to avoid sharing across threads? +} + +NDnsWorker::~NDnsWorker() +{ +} + +void NDnsWorker::run() +{ + hostent *h = 0; + +#ifdef HAVE_GETHOSTBYNAME_R + hostent buf; + char char_buf[1024]; + int err; + gethostbyname_r(host.data(), &buf, char_buf, sizeof(char_buf), &h, &err); +#else +#ifndef Q_WS_WIN + // lock for gethostbyname + QMutexLocker locker(workerMutex); + + // check for cancel + workerCancelled->lock(); + bool cancel = cancelled; + workerCancelled->unlock(); + + if(!cancel) +#endif + h = gethostbyname(host.data()); +#endif + + // FIXME: not ipv6 clean, currently. + if(!h || h->h_addrtype != AF_INET) { + success = false; + return; + } + + in_addr a = *((struct in_addr *)h->h_addr_list[0]); + addr.setAddress(ntohl(a.s_addr)); + success = true; +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/legacy/ndns.h b/iris-legacy/cutestuff/legacy/ndns.h new file mode 100644 index 0000000..3167e89 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/ndns.h @@ -0,0 +1,90 @@ +/* + * ndns.h - native DNS resolution + * Copyright (C) 2001, 2002 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_NDNS_H +#define CS_NDNS_H + +#include +#include +#include +#include +#include +//Added by qt3to4: +#include + +// CS_NAMESPACE_BEGIN + +class NDnsWorker; +class NDnsManager; + +class NDns : public QObject +{ + Q_OBJECT +public: + NDns(QObject *parent=0); + ~NDns(); + + void resolve(const QString &); + void stop(); + bool isBusy() const; + + QHostAddress result() const; + QString resultString() const; + +signals: + void resultsReady(); + +private: + QHostAddress addr; + + friend class NDnsManager; + void finished(const QHostAddress &); +}; + +class NDnsManager : public QObject +{ + Q_OBJECT +public: + ~NDnsManager(); + class Item; + +//! \if _hide_doc_ +protected slots: + void workerFinished(); +//! \endif + +private slots: + void app_aboutToQuit(); + +private: + class Private; + Private *d; + + friend class NDns; + NDnsManager(); + void resolve(NDns *self, const QString &name); + void stop(NDns *self); + bool isBusy(const NDns *self) const; + void tryDestroy(); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/legacy/safedelete.cpp b/iris-legacy/cutestuff/legacy/safedelete.cpp new file mode 100644 index 0000000..51dd388 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/safedelete.cpp @@ -0,0 +1,111 @@ +#include "safedelete.h" + +#include + +//---------------------------------------------------------------------------- +// SafeDelete +//---------------------------------------------------------------------------- +SafeDelete::SafeDelete() +{ + lock = 0; +} + +SafeDelete::~SafeDelete() +{ + if(lock) + lock->dying(); +} + +void SafeDelete::deleteLater(QObject *o) +{ + if(!lock) + deleteSingle(o); + else + list.append(o); +} + +void SafeDelete::unlock() +{ + lock = 0; + deleteAll(); +} + +void SafeDelete::deleteAll() +{ + if(list.isEmpty()) + return; + + QObjectList::Iterator it = list.begin(); + for(QObjectList::Iterator it = list.begin(); it != list.end(); ++it) + deleteSingle(*it); + list.clear(); +} + +void SafeDelete::deleteSingle(QObject *o) +{ + o->deleteLater(); +} + +//---------------------------------------------------------------------------- +// SafeDeleteLock +//---------------------------------------------------------------------------- +SafeDeleteLock::SafeDeleteLock(SafeDelete *sd) +{ + own = false; + if(!sd->lock) { + _sd = sd; + _sd->lock = this; + } + else + _sd = 0; +} + +SafeDeleteLock::~SafeDeleteLock() +{ + if(_sd) { + _sd->unlock(); + if(own) + delete _sd; + } +} + +void SafeDeleteLock::dying() +{ + _sd = new SafeDelete(*_sd); + own = true; +} + +//---------------------------------------------------------------------------- +// SafeDeleteLater +//---------------------------------------------------------------------------- +SafeDeleteLater *SafeDeleteLater::self = 0; + +SafeDeleteLater *SafeDeleteLater::ensureExists() +{ + if(!self) + new SafeDeleteLater(); + return self; +} + +SafeDeleteLater::SafeDeleteLater() +{ + self = this; + QTimer::singleShot(0, this, SLOT(explode())); +} + +SafeDeleteLater::~SafeDeleteLater() +{ + while (!list.isEmpty()) + delete list.takeFirst(); + self = 0; +} + +void SafeDeleteLater::deleteItLater(QObject *o) +{ + list.append(o); +} + +void SafeDeleteLater::explode() +{ + delete this; +} diff --git a/iris-legacy/cutestuff/legacy/safedelete.h b/iris-legacy/cutestuff/legacy/safedelete.h new file mode 100644 index 0000000..b33174f --- /dev/null +++ b/iris-legacy/cutestuff/legacy/safedelete.h @@ -0,0 +1,60 @@ +#ifndef SAFEDELETE_H +#define SAFEDELETE_H + +#include +#include + +class SafeDelete; +class SafeDeleteLock +{ +public: + SafeDeleteLock(SafeDelete *sd); + ~SafeDeleteLock(); + +private: + SafeDelete *_sd; + bool own; + friend class SafeDelete; + void dying(); +}; + +class SafeDelete +{ +public: + SafeDelete(); + ~SafeDelete(); + + void deleteLater(QObject *o); + + // same as QObject::deleteLater() + static void deleteSingle(QObject *o); + +private: + QObjectList list; + void deleteAll(); + + friend class SafeDeleteLock; + SafeDeleteLock *lock; + void unlock(); +}; + +class SafeDeleteLater : public QObject +{ + Q_OBJECT +public: + static SafeDeleteLater *ensureExists(); + void deleteItLater(QObject *o); + +private slots: + void explode(); + +private: + SafeDeleteLater(); + ~SafeDeleteLater(); + + QObjectList list; + friend class SafeDelete; + static SafeDeleteLater *self; +}; + +#endif diff --git a/iris-legacy/cutestuff/legacy/servsock.cpp b/iris-legacy/cutestuff/legacy/servsock.cpp new file mode 100644 index 0000000..47ca927 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/servsock.cpp @@ -0,0 +1,111 @@ +/* + * servsock.cpp - simple wrapper to QServerSocket + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "servsock.h" + +// CS_NAMESPACE_BEGIN + +//---------------------------------------------------------------------------- +// ServSock +//---------------------------------------------------------------------------- +class ServSock::Private +{ +public: + Private() {} + + ServSockSignal *serv; +}; + +ServSock::ServSock(QObject *parent) +:QObject(parent) +{ + d = new Private; + d->serv = 0; +} + +ServSock::~ServSock() +{ + stop(); + delete d; +} + +bool ServSock::isActive() const +{ + return (d->serv ? true: false); +} + +bool ServSock::listen(quint16 port) +{ + stop(); + + d->serv = new ServSockSignal(this); + if(!d->serv->listen(QHostAddress::Any, port)) { + delete d->serv; + d->serv = 0; + return false; + } + connect(d->serv, SIGNAL(connectionReady(int)), SLOT(sss_connectionReady(int))); + + return true; +} + +void ServSock::stop() +{ + delete d->serv; + d->serv = 0; +} + +int ServSock::port() const +{ + if(d->serv) + return d->serv->serverPort(); + else + return -1; +} + +QHostAddress ServSock::address() const +{ + if(d->serv) + return d->serv->serverAddress(); + else + return QHostAddress(); +} + +void ServSock::sss_connectionReady(int s) +{ + connectionReady(s); +} + + +//---------------------------------------------------------------------------- +// ServSockSignal +//---------------------------------------------------------------------------- +ServSockSignal::ServSockSignal(QObject *parent) +:QTcpServer(parent) +{ + setMaxPendingConnections(16); +} + +void ServSockSignal::incomingConnection(int socketDescriptor) +{ + connectionReady(socketDescriptor); +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/legacy/servsock.h b/iris-legacy/cutestuff/legacy/servsock.h new file mode 100644 index 0000000..382697b --- /dev/null +++ b/iris-legacy/cutestuff/legacy/servsock.h @@ -0,0 +1,68 @@ +/* + * servsock.h - simple wrapper to QServerSocket + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_SERVSOCK_H +#define CS_SERVSOCK_H + +#include + +// CS_NAMESPACE_BEGIN + +class ServSock : public QObject +{ + Q_OBJECT +public: + ServSock(QObject *parent=0); + ~ServSock(); + + bool isActive() const; + bool listen(quint16 port); + void stop(); + int port() const; + QHostAddress address() const; + +signals: + void connectionReady(int); + +private slots: + void sss_connectionReady(int); + +private: + class Private; + Private *d; +}; + +class ServSockSignal : public QTcpServer +{ + Q_OBJECT +public: + ServSockSignal(QObject *parent = 0); + +signals: + void connectionReady(int); + +protected: + // reimplemented + void incomingConnection(int socketDescriptor); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/legacy/srvresolver.cpp b/iris-legacy/cutestuff/legacy/srvresolver.cpp new file mode 100644 index 0000000..c8de2d5 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/srvresolver.cpp @@ -0,0 +1,313 @@ +/* + * srvresolver.cpp - class to simplify SRV lookups + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "srvresolver.h" + +#include +#include +#include +//Added by qt3to4: +#include +#include +#include "safedelete.h" +#include "psilogger.h" + +#ifndef NO_NDNS +#include "ndns.h" +#endif + +// CS_NAMESPACE_BEGIN + +bool serverLessThan(const Q3Dns::Server &s1, const Q3Dns::Server &s2) +{ + int a = s1.priority; + int b = s2.priority; + int j = s1.weight; + int k = s2.weight; + return a < b || (a == b && j < k); +} + +static void sortSRVList(QList &list) +{ + qStableSort(list.begin(), list.end(), serverLessThan); +} + +class SrvResolver::Private +{ +public: + Private() {} + + Q3Dns *qdns; +#ifndef NO_NDNS + NDns ndns; +#endif + + bool failed; + QHostAddress resultAddress; + Q_UINT16 resultPort; + + bool srvonly; + QString srv; + QList servers; + bool aaaa; + + QTimer t; + SafeDelete sd; +}; + +SrvResolver::SrvResolver(QObject *parent) +:QObject(parent) +{ + d = new Private; + d->qdns = 0; + +#ifndef NO_NDNS + connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done())); +#endif + connect(&d->t, SIGNAL(timeout()), SLOT(t_timeout())); + stop(); +} + +SrvResolver::~SrvResolver() +{ + stop(); + delete d; +} + +void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly) +{ + PsiLogger::instance()->log(QString("SrvResolver::resolve(%1, %2, %3, %4)").arg(server).arg(type).arg(proto).arg(srvOnly)); + stop(); + + d->failed = false; + d->srvonly = srvOnly; + d->srv = QString("_") + type + "._" + proto + '.' + server; + d->t.start(15000, true); + d->qdns = new Q3Dns; + connect(d->qdns, SIGNAL(resultsReady()), SLOT(qdns_done())); + d->qdns->setRecordType(Q3Dns::Srv); + d->qdns->setLabel(d->srv); +} + +void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto) +{ + resolve(server, type, proto, false); +} + +void SrvResolver::resolveSrvOnly(const QString &server, const QString &type, const QString &proto) +{ + resolve(server, type, proto, true); +} + +void SrvResolver::next() +{ + if(d->servers.isEmpty()) + return; + + tryNext(); +} + +void SrvResolver::stop() +{ + if(d->t.isActive()) + d->t.stop(); + if(d->qdns) { + d->qdns->disconnect(this); + d->sd.deleteLater(d->qdns); + d->qdns = 0; + } +#ifndef NO_NDNS + if(d->ndns.isBusy()) + d->ndns.stop(); +#endif + d->resultAddress = QHostAddress(); + d->resultPort = 0; + d->servers.clear(); + d->srv = ""; + d->failed = true; +} + +bool SrvResolver::isBusy() const +{ +#ifndef NO_NDNS + if(d->qdns || d->ndns.isBusy()) +#else + if(d->qdns) +#endif + return true; + else + return false; +} + +QList SrvResolver::servers() const +{ + return d->servers; +} + +bool SrvResolver::failed() const +{ + return d->failed; +} + +QHostAddress SrvResolver::resultAddress() const +{ + return d->resultAddress; +} + +Q_UINT16 SrvResolver::resultPort() const +{ + return d->resultPort; +} + +void SrvResolver::tryNext() +{ +#ifndef NO_NDNS + PsiLogger::instance()->log(QString("SrvResolver(%1)::tryNext() d->ndns.resolve(%2)").arg(d->srv).arg(d->servers.first().name)); + d->ndns.resolve(d->servers.first().name); +#else + d->qdns = new Q3Dns; + connect(d->qdns, SIGNAL(resultsReady()), SLOT(ndns_done())); + if(d->aaaa) + d->qdns->setRecordType(Q3Dns::Aaaa); // IPv6 + else + d->qdns->setRecordType(Q3Dns::A); // IPv4 + d->qdns->setLabel(d->servers.first().name); +#endif +} + +void SrvResolver::qdns_done() +{ + PsiLogger::instance()->log(QString("SrvResolver(%1)::qdns_done() d->qdns = %2; d->qdns->isWorking() = %3; d->qdns->servers().count() = %4").arg(d->srv).arg((long)d->qdns).arg(d->qdns ? d->qdns->isWorking() : 0).arg(d->qdns ? d->qdns->servers().count() : 0)); + if(!d->qdns) + return; + + // apparently we sometimes get this signal even though the results aren't ready + if(d->qdns->isWorking()) + return; + d->t.stop(); + + SafeDeleteLock s(&d->sd); + + // grab the server list and destroy the qdns object + QList list; + if(d->qdns->recordType() == Q3Dns::Srv) + list = d->qdns->servers(); + d->qdns->disconnect(this); + d->sd.deleteLater(d->qdns); + d->qdns = 0; + + if(list.isEmpty()) { + stop(); + resultsReady(); + return; + } + sortSRVList(list); + d->servers = list; + + if(d->srvonly) + resultsReady(); + else { + // kick it off + d->aaaa = true; + tryNext(); + } +} + +void SrvResolver::ndns_done() +{ +#ifndef NO_NDNS + SafeDeleteLock s(&d->sd); + + QHostAddress r = d->ndns.result(); + int port = d->servers.first().port; + d->servers.remove(d->servers.begin()); + + PsiLogger::instance()->log(QString("SrvResolver(%1)::ndns_done() r.isNull = %2, r = %3, port = %4").arg(d->srv).arg(r.isNull()).arg(r.toString()).arg(port)); + + if(!r.isNull()) { + d->resultAddress = r; + d->resultPort = port; + resultsReady(); + } + else { + // failed? bail if last one + if(d->servers.isEmpty()) { + stop(); + resultsReady(); + return; + } + + // otherwise try the next + tryNext(); + } +#else + if(!d->qdns) + return; + + // apparently we sometimes get this signal even though the results aren't ready + if(d->qdns->isWorking()) + return; + + SafeDeleteLock s(&d->sd); + + // grab the address list and destroy the qdns object + QList list; + if(d->qdns->recordType() == Q3Dns::A || d->qdns->recordType() == Q3Dns::Aaaa) + list = d->qdns->addresses(); + d->qdns->disconnect(this); + d->sd.deleteLater(d->qdns); + d->qdns = 0; + + if(!list.isEmpty()) { + int port = d->servers.first().port; + d->servers.remove(d->servers.begin()); + d->aaaa = true; + + d->resultAddress = list.first(); + d->resultPort = port; + resultsReady(); + } + else { + if(!d->aaaa) + d->servers.remove(d->servers.begin()); + d->aaaa = !d->aaaa; + + // failed? bail if last one + if(d->servers.isEmpty()) { + stop(); + resultsReady(); + return; + } + + // otherwise try the next + tryNext(); + } +#endif +} + +void SrvResolver::t_timeout() +{ + SafeDeleteLock s(&d->sd); + + stop(); + resultsReady(); +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/legacy/srvresolver.h b/iris-legacy/cutestuff/legacy/srvresolver.h new file mode 100644 index 0000000..0b456a4 --- /dev/null +++ b/iris-legacy/cutestuff/legacy/srvresolver.h @@ -0,0 +1,66 @@ +/* + * srvresolver.h - class to simplify SRV lookups + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_SRVRESOLVER_H +#define CS_SRVRESOLVER_H + +#include +#include + +// CS_NAMESPACE_BEGIN + +class SrvResolver : public QObject +{ + Q_OBJECT +public: + SrvResolver(QObject *parent=0); + ~SrvResolver(); + + void resolve(const QString &server, const QString &type, const QString &proto); + void resolveSrvOnly(const QString &server, const QString &type, const QString &proto); + void next(); + void stop(); + bool isBusy() const; + + QList servers() const; + + bool failed() const; + QHostAddress resultAddress() const; + Q_UINT16 resultPort() const; + +signals: + void resultsReady(); + +private slots: + void qdns_done(); + void ndns_done(); + void t_timeout(); + +private: + class Private; + Private *d; + + void tryNext(); + void resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/network/bsocket.cpp b/iris-legacy/cutestuff/network/bsocket.cpp new file mode 100644 index 0000000..ca7ce7b --- /dev/null +++ b/iris-legacy/cutestuff/network/bsocket.cpp @@ -0,0 +1,474 @@ +/* + * bsocket.cpp - QSocket wrapper based on Bytestream with SRV DNS support + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include + +#include "bsocket.h" + +//#include "safedelete.h" +#ifndef NO_NDNS +#include "ndns.h" +#endif +#include "srvresolver.h" + +//#define BS_DEBUG + +#ifdef BS_DEBUG +#include +#endif + +#define READBUFSIZE 65536 + +// CS_NAMESPACE_BEGIN + +#include "psilogger.h" + +class QTcpSocketSignalRelay : public QObject +{ + Q_OBJECT +public: + QTcpSocketSignalRelay(QTcpSocket *sock, QObject *parent = 0) + :QObject(parent) + { + qRegisterMetaType("QAbstractSocket::SocketError"); + connect(sock, SIGNAL(hostFound()), SLOT(sock_hostFound()), Qt::QueuedConnection); + connect(sock, SIGNAL(connected()), SLOT(sock_connected()), Qt::QueuedConnection); + connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected()), Qt::QueuedConnection); + connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()), Qt::QueuedConnection); + connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)), Qt::QueuedConnection); + connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)), Qt::QueuedConnection); + } + +signals: + void hostFound(); + void connected(); + void disconnected(); + void readyRead(); + void bytesWritten(qint64); + void error(QAbstractSocket::SocketError); + +public slots: + void sock_hostFound() + { + emit hostFound(); + } + + void sock_connected() + { + emit connected(); + } + + void sock_disconnected() + { + emit disconnected(); + } + + void sock_readyRead() + { + emit readyRead(); + } + + void sock_bytesWritten(qint64 x) + { + emit bytesWritten(x); + } + + void sock_error(QAbstractSocket::SocketError x) + { + emit error(x); + } +}; + +class BSocket::Private +{ +public: + Private() + { + qsock = 0; + qsock_relay = 0; + } + + QTcpSocket *qsock; + QTcpSocketSignalRelay *qsock_relay; + int state; + +#ifndef NO_NDNS + NDns ndns; +#endif + SrvResolver srv; + QString host; + int port; + //SafeDelete sd; +}; + +BSocket::BSocket(QObject *parent) +:ByteStream(parent) +{ + d = new Private; +#ifndef NO_NDNS + connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done())); +#endif + connect(&d->srv, SIGNAL(resultsReady()), SLOT(srv_done())); + + reset(); +} + +BSocket::~BSocket() +{ + reset(true); + delete d; + PsiLogger::instance()->log(QString("%1 BSocket::~BSocket()").arg(LOG_THIS)); +} + +void BSocket::reset(bool clear) +{ + PsiLogger::instance()->log(QString("%1 BSocket::reset()").arg(LOG_THIS)); + + if(d->qsock) { + delete d->qsock_relay; + d->qsock_relay = 0; + + /*d->qsock->disconnect(this); + + if(!clear && d->qsock->isOpen() && d->qsock->isValid()) {*/ + // move remaining into the local queue + QByteArray block(d->qsock->bytesAvailable(), 0); + d->qsock->read(block.data(), block.size()); + appendRead(block); + //} + + //d->sd.deleteLater(d->qsock); + // delete d->qsock; + d->qsock->deleteLater(); + d->qsock = 0; + } + else { + if(clear) + clearReadBuffer(); + } + + if(d->srv.isBusy()) + d->srv.stop(); +#ifndef NO_NDNS + if(d->ndns.isBusy()) + d->ndns.stop(); +#endif + d->state = Idle; +} + +void BSocket::ensureSocket() +{ + PsiLogger::instance()->log(QString("%1 BSocket::ensureSocket()").arg(LOG_THIS)); + if(!d->qsock) { + d->qsock = new QTcpSocket; +#if QT_VERSION >= 0x030200 + d->qsock->setReadBufferSize(READBUFSIZE); +#endif + d->qsock_relay = new QTcpSocketSignalRelay(d->qsock); + connect(d->qsock_relay, SIGNAL(hostFound()), SLOT(qs_hostFound())); + connect(d->qsock_relay, SIGNAL(connected()), SLOT(qs_connected())); + connect(d->qsock_relay, SIGNAL(disconnected()), SLOT(qs_closed())); + connect(d->qsock_relay, SIGNAL(readyRead()), SLOT(qs_readyRead())); + connect(d->qsock_relay, SIGNAL(bytesWritten(qint64)), SLOT(qs_bytesWritten(qint64))); + connect(d->qsock_relay, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(qs_error(QAbstractSocket::SocketError))); + } +} + +void BSocket::connectToHost(const QString &host, quint16 port) +{ + PsiLogger::instance()->log(QString("%1 BSocket::connectToHost(%2, %3)").arg(LOG_THIS).arg(host).arg(port)); + reset(true); + d->host = host; + d->port = port; +#ifdef NO_NDNS + d->state = Connecting; + do_connect(); +#else + d->state = HostLookup; + d->ndns.resolve(d->host); +#endif +} + +void BSocket::connectToServer(const QString &srv, const QString &type) +{ + PsiLogger::instance()->log(QString("%1 BSocket::connectToServer(%2, %3)").arg(LOG_THIS).arg(srv).arg(type)); + reset(true); + d->state = HostLookup; + d->srv.resolve(srv, type, "tcp"); +} + +int BSocket::socket() const +{ + if(d->qsock) + return d->qsock->socketDescriptor(); + else + return -1; +} + +void BSocket::setSocket(int s) +{ + PsiLogger::instance()->log(QString("%1 BSocket::setSocket(%2)").arg(LOG_THIS).arg(s)); + reset(true); + ensureSocket(); + d->state = Connected; + d->qsock->setSocketDescriptor(s); +} + +int BSocket::state() const +{ + return d->state; +} + +bool BSocket::isOpen() const +{ + if(d->state == Connected) + return true; + else + return false; +} + +void BSocket::close() +{ + PsiLogger::instance()->log(QString("%1 BSocket::close()").arg(LOG_THIS)); + if(d->state == Idle) + return; + + if(d->qsock) { + d->qsock->close(); + d->state = Closing; + if(d->qsock->bytesToWrite() == 0) + reset(); + } + else { + reset(); + } +} + +void BSocket::write(const QByteArray &a) +{ + if(d->state != Connected) + return; +#ifdef BS_DEBUG + QString s = QString::fromUtf8(a); + fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), s.latin1()); +#endif + d->qsock->write(a.data(), a.size()); +} + +QByteArray BSocket::read(int bytes) +{ + QByteArray block; + if(d->qsock) { + int max = bytesAvailable(); + if(bytes <= 0 || bytes > max) + bytes = max; + block.resize(bytes); + d->qsock->read(block.data(), block.size()); + } + else + block = ByteStream::read(bytes); + +#ifdef BS_DEBUG + QString s = QString::fromUtf8(block); + fprintf(stderr, "BSocket: read [%d]: {%s}\n", block.size(), s.latin1()); +#endif + return block; +} + +int BSocket::bytesAvailable() const +{ + if(d->qsock) + return d->qsock->bytesAvailable(); + else + return ByteStream::bytesAvailable(); +} + +int BSocket::bytesToWrite() const +{ + if(!d->qsock) + return 0; + return d->qsock->bytesToWrite(); +} + +QHostAddress BSocket::address() const +{ + if(d->qsock) + return d->qsock->localAddress(); + else + return QHostAddress(); +} + +quint16 BSocket::port() const +{ + if(d->qsock) + return d->qsock->localPort(); + else + return 0; +} + +QHostAddress BSocket::peerAddress() const +{ + if(d->qsock) + return d->qsock->peerAddress(); + else + return QHostAddress(); +} + +quint16 BSocket::peerPort() const +{ + if(d->qsock) + return d->qsock->peerPort(); + else + return 0; +} + +void BSocket::srv_done() +{ + PsiLogger::instance()->log(QString("%1 BSocket::srv_done()").arg(LOG_THIS)); + if(d->srv.failed()) { +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Error resolving hostname.\n"); +#endif + error(ErrHostNotFound); + return; + } + + d->host = d->srv.resultAddress().toString(); + d->port = d->srv.resultPort(); + do_connect(); + //QTimer::singleShot(0, this, SLOT(do_connect())); + //hostFound(); +} + +void BSocket::ndns_done() +{ + PsiLogger::instance()->log(QString("%1 BSocket::ndns_done()").arg(LOG_THIS)); +#ifndef NO_NDNS + if(!d->ndns.result().isNull()) { + d->host = d->ndns.resultString(); + d->state = Connecting; + do_connect(); + //QTimer::singleShot(0, this, SLOT(do_connect())); + //hostFound(); + } + else { +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Error resolving hostname.\n"); +#endif + error(ErrHostNotFound); + } +#endif +} + +void BSocket::do_connect() +{ + PsiLogger::instance()->log(QString("%1 BSocket::do_connect()").arg(LOG_THIS)); +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Connecting to %s:%d\n", d->host.latin1(), d->port); +#endif + ensureSocket(); + d->qsock->connectToHost(d->host, d->port); +} + +void BSocket::qs_hostFound() +{ + PsiLogger::instance()->log(QString("%1 BSocket::qs_hostFound()").arg(LOG_THIS)); + //SafeDeleteLock s(&d->sd); +} + +void BSocket::qs_connected() +{ + PsiLogger::instance()->log(QString("%1 BSocket::qs_connected()").arg(LOG_THIS)); + d->state = Connected; +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Connected.\n"); +#endif + //SafeDeleteLock s(&d->sd); + connected(); +} + +void BSocket::qs_closed() +{ + PsiLogger::instance()->log(QString("%1 BSocket::qs_closed()").arg(LOG_THIS)); + if(d->state == Closing) + { +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Delayed Close Finished.\n"); +#endif + //SafeDeleteLock s(&d->sd); + reset(); + delayedCloseFinished(); + } +} + +void BSocket::qs_readyRead() +{ + //SafeDeleteLock s(&d->sd); + readyRead(); +} + +void BSocket::qs_bytesWritten(qint64 x64) +{ + int x = x64; +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: BytesWritten [%d].\n", x); +#endif + //SafeDeleteLock s(&d->sd); + bytesWritten(x); +} + +void BSocket::qs_error(QAbstractSocket::SocketError x) +{ + PsiLogger::instance()->log(QString("%1 BSocket::qs_error(%2)").arg(LOG_THIS).arg(x)); + if(x == QTcpSocket::RemoteHostClosedError) { +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Connection Closed.\n"); +#endif + //SafeDeleteLock s(&d->sd); + reset(); + connectionClosed(); + return; + } + +#ifdef BS_DEBUG + fprintf(stderr, "BSocket: Error.\n"); +#endif + //SafeDeleteLock s(&d->sd); + + // connection error during SRV host connect? try next + if(d->state == HostLookup && (x == QTcpSocket::ConnectionRefusedError || x == QTcpSocket::HostNotFoundError)) { + d->srv.next(); + return; + } + + reset(); + if(x == QTcpSocket::ConnectionRefusedError) + error(ErrConnectionRefused); + else if(x == QTcpSocket::HostNotFoundError) + error(ErrHostNotFound); + else + error(ErrRead); +} + +#include "bsocket.moc" + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/network/bsocket.h b/iris-legacy/cutestuff/network/bsocket.h new file mode 100644 index 0000000..1b3e6cc --- /dev/null +++ b/iris-legacy/cutestuff/network/bsocket.h @@ -0,0 +1,90 @@ +/* + * bsocket.h - QSocket wrapper based on Bytestream with SRV DNS support + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_BSOCKET_H +#define CS_BSOCKET_H + +#include + +#include "bytestream.h" + +class QString; +class QObject; +class QByteArray; + +// CS_NAMESPACE_BEGIN + +class BSocket : public ByteStream +{ + Q_OBJECT +public: + enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound }; + enum State { Idle, HostLookup, Connecting, Connected, Closing }; + BSocket(QObject *parent=0); + ~BSocket(); + + void connectToHost(const QString &host, quint16 port); + void connectToServer(const QString &srv, const QString &type); + int socket() const; + void setSocket(int); + int state() const; + + // from ByteStream + bool isOpen() const; + void close(); + void write(const QByteArray &); + QByteArray read(int bytes=0); + int bytesAvailable() const; + int bytesToWrite() const; + + // local + QHostAddress address() const; + quint16 port() const; + + // remote + QHostAddress peerAddress() const; + quint16 peerPort() const; + +signals: + void hostFound(); + void connected(); + +private slots: + void qs_hostFound(); + void qs_connected(); + void qs_closed(); + void qs_readyRead(); + void qs_bytesWritten(qint64); + void qs_error(QAbstractSocket::SocketError); + void srv_done(); + void ndns_done(); + void do_connect(); + +private: + class Private; + Private *d; + + void reset(bool clear=false); + void ensureSocket(); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/network/httpconnect.cpp b/iris-legacy/cutestuff/network/httpconnect.cpp new file mode 100644 index 0000000..b7e5b01 --- /dev/null +++ b/iris-legacy/cutestuff/network/httpconnect.cpp @@ -0,0 +1,363 @@ +/* + * httpconnect.cpp - HTTP "CONNECT" proxy + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "httpconnect.h" + +#include +//Added by qt3to4: +#include +#include "bsocket.h" +#include + +#ifdef PROX_DEBUG +#include +#endif + +// CS_NAMESPACE_BEGIN + +static QString extractLine(QByteArray *buf, bool *found) +{ + // Scan for newline + int index = buf->indexOf ("\r\n"); + if (index == -1) { + // Newline not found + if (found) + *found = false; + return ""; + } + else { + // Found newline + QString s = QString::fromAscii(buf->left(index)); + buf->remove(0, index + 2); + + if (found) + *found = true; + return s; + } +} + +static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg) +{ + int n = line.find(' '); + if(n == -1) + return false; + if(proto) + *proto = line.mid(0, n); + ++n; + int n2 = line.find(' ', n); + if(n2 == -1) + return false; + if(code) + *code = line.mid(n, n2-n).toInt(); + n = n2+1; + if(msg) + *msg = line.mid(n); + return true; +} + +class HttpConnect::Private +{ +public: + Private() {} + + BSocket sock; + QString host; + int port; + QString user, pass; + QString real_host; + int real_port; + + QByteArray recvBuf; + + bool inHeader; + QStringList headerLines; + + int toWrite; + bool active; +}; + +HttpConnect::HttpConnect(QObject *parent) +:ByteStream(parent) +{ + d = new Private; + connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected())); + connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed())); + connect(&d->sock, SIGNAL(delayedCloseFinished()), SLOT(sock_delayedCloseFinished())); + connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); + connect(&d->sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int))); + connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int))); + + reset(true); +} + +HttpConnect::~HttpConnect() +{ + reset(true); + delete d; +} + +void HttpConnect::reset(bool clear) +{ + if(d->sock.state() != BSocket::Idle) + d->sock.close(); + if(clear) { + clearReadBuffer(); + d->recvBuf.resize(0); + } + d->active = false; +} + +void HttpConnect::setAuth(const QString &user, const QString &pass) +{ + d->user = user; + d->pass = pass; +} + +void HttpConnect::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port) +{ + reset(true); + + d->host = proxyHost; + d->port = proxyPort; + d->real_host = host; + d->real_port = port; + +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: Connecting to %s:%d", proxyHost.latin1(), proxyPort); + if(d->user.isEmpty()) + fprintf(stderr, "\n"); + else + fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1()); +#endif + d->sock.connectToHost(d->host, d->port); +} + +bool HttpConnect::isOpen() const +{ + return d->active; +} + +void HttpConnect::close() +{ + d->sock.close(); + if(d->sock.bytesToWrite() == 0) + reset(); +} + +void HttpConnect::write(const QByteArray &buf) +{ + if(d->active) + d->sock.write(buf); +} + +QByteArray HttpConnect::read(int bytes) +{ + return ByteStream::read(bytes); +} + +int HttpConnect::bytesAvailable() const +{ + return ByteStream::bytesAvailable(); +} + +int HttpConnect::bytesToWrite() const +{ + if(d->active) + return d->sock.bytesToWrite(); + else + return 0; +} + +void HttpConnect::sock_connected() +{ +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: Connected\n"); +#endif + d->inHeader = true; + d->headerLines.clear(); + + // connected, now send the request + QString s; + s += QString("CONNECT ") + d->real_host + ':' + QString::number(d->real_port) + " HTTP/1.0\r\n"; + if(!d->user.isEmpty()) { + QString str = d->user + ':' + d->pass; + s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n"; + } + s += "Pragma: no-cache\r\n"; + s += "\r\n"; + + Q3CString cs = s.utf8(); + QByteArray block(cs.length()); + memcpy(block.data(), cs.data(), block.size()); + d->toWrite = block.size(); + d->sock.write(block); +} + +void HttpConnect::sock_connectionClosed() +{ + if(d->active) { + reset(); + connectionClosed(); + } + else { + error(ErrProxyNeg); + } +} + +void HttpConnect::sock_delayedCloseFinished() +{ + if(d->active) { + reset(); + delayedCloseFinished(); + } +} + +void HttpConnect::sock_readyRead() +{ + QByteArray block = d->sock.read(); + + if(!d->active) { + ByteStream::appendArray(&d->recvBuf, block); + + if(d->inHeader) { + // grab available lines + while(1) { + bool found; + QString line = extractLine(&d->recvBuf, &found); + if(!found) + break; + if(line.isEmpty()) { + d->inHeader = false; + break; + } + d->headerLines += line; + } + + // done with grabbing the header? + if(!d->inHeader) { + QString str = d->headerLines.first(); + d->headerLines.remove(d->headerLines.begin()); + + QString proto; + int code; + QString msg; + if(!extractMainHeader(str, &proto, &code, &msg)) { +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: invalid header!\n"); +#endif + reset(true); + error(ErrProxyNeg); + return; + } + else { +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1()); + for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it) + fprintf(stderr, "HttpConnect: * [%s]\n", (*it).latin1()); +#endif + } + + if(code == 200) { // OK +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: << Success >>\n"); +#endif + d->active = true; + connected(); + + if(!d->recvBuf.isEmpty()) { + appendRead(d->recvBuf); + d->recvBuf.resize(0); + readyRead(); + return; + } + } + else { + int err; + QString errStr; + if(code == 407) { // Authentication failed + err = ErrProxyAuth; + errStr = tr("Authentication failed"); + } + else if(code == 404) { // Host not found + err = ErrHostNotFound; + errStr = tr("Host not found"); + } + else if(code == 403) { // Access denied + err = ErrProxyNeg; + errStr = tr("Access denied"); + } + else if(code == 503) { // Connection refused + err = ErrConnectionRefused; + errStr = tr("Connection refused"); + } + else { // invalid reply + err = ErrProxyNeg; + errStr = tr("Invalid reply"); + } + +#ifdef PROX_DEBUG + fprintf(stderr, "HttpConnect: << Error >> [%s]\n", errStr.latin1()); +#endif + reset(true); + error(err); + return; + } + } + } + } + else { + appendRead(block); + readyRead(); + return; + } +} + +void HttpConnect::sock_bytesWritten(int x) +{ + if(d->toWrite > 0) { + int size = x; + if(d->toWrite < x) + size = d->toWrite; + d->toWrite -= size; + x -= size; + } + + if(d->active && x > 0) + bytesWritten(x); +} + +void HttpConnect::sock_error(int x) +{ + if(d->active) { + reset(); + error(ErrRead); + } + else { + reset(true); + if(x == BSocket::ErrHostNotFound) + error(ErrProxyConnect); + else if(x == BSocket::ErrConnectionRefused) + error(ErrProxyConnect); + else if(x == BSocket::ErrRead) + error(ErrProxyNeg); + } +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/network/httpconnect.h b/iris-legacy/cutestuff/network/httpconnect.h new file mode 100644 index 0000000..4ab84b2 --- /dev/null +++ b/iris-legacy/cutestuff/network/httpconnect.h @@ -0,0 +1,67 @@ +/* + * httpconnect.h - HTTP "CONNECT" proxy + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_HTTPCONNECT_H +#define CS_HTTPCONNECT_H + +#include "bytestream.h" + +// CS_NAMESPACE_BEGIN + +class HttpConnect : public ByteStream +{ + Q_OBJECT +public: + enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth }; + HttpConnect(QObject *parent=0); + ~HttpConnect(); + + void setAuth(const QString &user, const QString &pass=""); + void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port); + + // from ByteStream + bool isOpen() const; + void close(); + void write(const QByteArray &); + QByteArray read(int bytes=0); + int bytesAvailable() const; + int bytesToWrite() const; + +signals: + void connected(); + +private slots: + void sock_connected(); + void sock_connectionClosed(); + void sock_delayedCloseFinished(); + void sock_readyRead(); + void sock_bytesWritten(int); + void sock_error(int); + +private: + class Private; + Private *d; + + void reset(bool clear=false); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/network/httppoll.cpp b/iris-legacy/cutestuff/network/httppoll.cpp new file mode 100644 index 0000000..da7113c --- /dev/null +++ b/iris-legacy/cutestuff/network/httppoll.cpp @@ -0,0 +1,666 @@ +/* + * httppoll.cpp - HTTP polling proxy + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "httppoll.h" + +#include +#include +#include +#include +#include +//Added by qt3to4: +#include +#include +#include "bsocket.h" + +#ifdef PROX_DEBUG +#include +#endif + +#define POLL_KEYS 64 + +// CS_NAMESPACE_BEGIN + +static QByteArray randomArray(int size) +{ + QByteArray a(size); + for(int n = 0; n < size; ++n) + a[n] = (char)(256.0*rand()/(RAND_MAX+1.0)); + return a; +} + +//---------------------------------------------------------------------------- +// HttpPoll +//---------------------------------------------------------------------------- +static QString hpk(int n, const QString &s) +{ + if(n == 0) + return s; + else + return QCA::Base64().arrayToString( QCA::Hash("sha1").hash( Q3CString(hpk(n - 1, s).latin1()) ).toByteArray() ); +} + +class HttpPoll::Private +{ +public: + Private() {} + + HttpProxyPost http; + QString host; + int port; + QString user, pass; + QString url; + bool use_proxy; + + QByteArray out; + + int state; + bool closing; + QString ident; + + QTimer *t; + + QString key[POLL_KEYS]; + int key_n; + + int polltime; +}; + +HttpPoll::HttpPoll(QObject *parent) +:ByteStream(parent) +{ + d = new Private; + + d->polltime = 30; + d->t = new QTimer; + connect(d->t, SIGNAL(timeout()), SLOT(do_sync())); + + connect(&d->http, SIGNAL(result()), SLOT(http_result())); + connect(&d->http, SIGNAL(error(int)), SLOT(http_error(int))); + + reset(true); +} + +HttpPoll::~HttpPoll() +{ + reset(true); + delete d->t; + delete d; +} + +void HttpPoll::reset(bool clear) +{ + if(d->http.isActive()) + d->http.stop(); + if(clear) + clearReadBuffer(); + clearWriteBuffer(); + d->out.resize(0); + d->state = 0; + d->closing = false; + d->t->stop(); +} + +void HttpPoll::setAuth(const QString &user, const QString &pass) +{ + d->user = user; + d->pass = pass; +} + +void HttpPoll::connectToUrl(const QString &url) +{ + connectToHost("", 0, url); +} + +void HttpPoll::connectToHost(const QString &proxyHost, int proxyPort, const QString &url) +{ + reset(true); + + // using proxy? + if(!proxyHost.isEmpty()) { + d->host = proxyHost; + d->port = proxyPort; + d->url = url; + d->use_proxy = true; + } + else { + Q3Url u = url; + d->host = u.host(); + if(u.hasPort()) + d->port = u.port(); + else + d->port = 80; + d->url = u.encodedPathAndQuery(); + d->use_proxy = false; + } + + resetKey(); + bool last; + QString key = getKey(&last); + +#ifdef PROX_DEBUG + fprintf(stderr, "HttpPoll: Connecting to %s:%d [%s]", d->host.latin1(), d->port, d->url.latin1()); + if(d->user.isEmpty()) + fprintf(stderr, "\n"); + else + fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1()); +#endif + QPointer self = this; + syncStarted(); + if(!self) + return; + + d->state = 1; + d->http.setAuth(d->user, d->pass); + d->http.post(d->host, d->port, d->url, makePacket("0", key, "", QByteArray()), d->use_proxy); +} + +QByteArray HttpPoll::makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block) +{ + QString str = ident; + if(!key.isEmpty()) { + str += ';'; + str += key; + } + if(!newkey.isEmpty()) { + str += ';'; + str += newkey; + } + str += ','; + Q3CString cs = str.latin1(); + int len = cs.length(); + + QByteArray a(len + block.size()); + memcpy(a.data(), cs.data(), len); + memcpy(a.data() + len, block.data(), block.size()); + return a; +} + +int HttpPoll::pollInterval() const +{ + return d->polltime; +} + +void HttpPoll::setPollInterval(int seconds) +{ + d->polltime = seconds; +} + +bool HttpPoll::isOpen() const +{ + return (d->state == 2 ? true: false); +} + +void HttpPoll::close() +{ + if(d->state == 0 || d->closing) + return; + + if(bytesToWrite() == 0) + reset(); + else + d->closing = true; +} + +void HttpPoll::http_result() +{ + // check for death :) + QPointer self = this; + syncFinished(); + if(!self) + return; + + // get id and packet + QString id; + QString cookie = d->http.getHeader("Set-Cookie"); + int n = cookie.find("ID="); + if(n == -1) { + reset(); + error(ErrRead); + return; + } + n += 3; + int n2 = cookie.find(';', n); + if(n2 != -1) + id = cookie.mid(n, n2-n); + else + id = cookie.mid(n); + QByteArray block = d->http.body(); + + // session error? + if(id.right(2) == ":0") { + if(id == "0:0" && d->state == 2) { + reset(); + connectionClosed(); + return; + } + else { + reset(); + error(ErrRead); + return; + } + } + + d->ident = id; + bool justNowConnected = false; + if(d->state == 1) { + d->state = 2; + justNowConnected = true; + } + + // sync up again soon + if(bytesToWrite() > 0 || !d->closing) + d->t->start(d->polltime * 1000, true); + + // connecting + if(justNowConnected) { + connected(); + } + else { + if(!d->out.isEmpty()) { + int x = d->out.size(); + d->out.resize(0); + takeWrite(x); + bytesWritten(x); + } + } + + if(!self) + return; + + if(!block.isEmpty()) { + appendRead(block); + readyRead(); + } + + if(!self) + return; + + if(bytesToWrite() > 0) { + do_sync(); + } + else { + if(d->closing) { + reset(); + delayedCloseFinished(); + return; + } + } +} + +void HttpPoll::http_error(int x) +{ + reset(); + if(x == HttpProxyPost::ErrConnectionRefused) + error(ErrConnectionRefused); + else if(x == HttpProxyPost::ErrHostNotFound) + error(ErrHostNotFound); + else if(x == HttpProxyPost::ErrSocket) + error(ErrRead); + else if(x == HttpProxyPost::ErrProxyConnect) + error(ErrProxyConnect); + else if(x == HttpProxyPost::ErrProxyNeg) + error(ErrProxyNeg); + else if(x == HttpProxyPost::ErrProxyAuth) + error(ErrProxyAuth); +} + +int HttpPoll::tryWrite() +{ + if(!d->http.isActive()) + do_sync(); + return 0; +} + +void HttpPoll::do_sync() +{ + if(d->http.isActive()) + return; + + d->t->stop(); + d->out = takeWrite(0, false); + + bool last; + QString key = getKey(&last); + QString newkey; + if(last) { + resetKey(); + newkey = getKey(&last); + } + + QPointer self = this; + syncStarted(); + if(!self) + return; + + d->http.post(d->host, d->port, d->url, makePacket(d->ident, key, newkey, d->out), d->use_proxy); +} + +void HttpPoll::resetKey() +{ +#ifdef PROX_DEBUG + fprintf(stderr, "HttpPoll: reset key!\n"); +#endif + QByteArray a = randomArray(64); + QString str = QString::fromLatin1(a.data(), a.size()); + + d->key_n = POLL_KEYS; + for(int n = 0; n < POLL_KEYS; ++n) + d->key[n] = hpk(n+1, str); +} + +const QString & HttpPoll::getKey(bool *last) +{ + *last = false; + --(d->key_n); + if(d->key_n == 0) + *last = true; + return d->key[d->key_n]; +} + + +//---------------------------------------------------------------------------- +// HttpProxyPost +//---------------------------------------------------------------------------- +static QString extractLine(QByteArray *buf, bool *found) +{ + // scan for newline + int n; + for(n = 0; n < (int)buf->size()-1; ++n) { + if(buf->at(n) == '\r' && buf->at(n+1) == '\n') { + //Q3CString cstr; + //cstr.resize(n+1); + QByteArray cstr; + cstr.resize(n); + memcpy(cstr.data(), buf->data(), n); + n += 2; // hack off CR/LF + + memmove(buf->data(), buf->data() + n, buf->size() - n); + buf->resize(buf->size() - n); + QString s = QString::fromUtf8(cstr); + + if(found) + *found = true; + return s; + } + } + + if(found) + *found = false; + return ""; +} + +static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg) +{ + int n = line.find(' '); + if(n == -1) + return false; + if(proto) + *proto = line.mid(0, n); + ++n; + int n2 = line.find(' ', n); + if(n2 == -1) + return false; + if(code) + *code = line.mid(n, n2-n).toInt(); + n = n2+1; + if(msg) + *msg = line.mid(n); + return true; +} + +class HttpProxyPost::Private +{ +public: + Private() {} + + BSocket sock; + QByteArray postdata, recvBuf, body; + QString url; + QString user, pass; + bool inHeader; + QStringList headerLines; + bool asProxy; + QString host; +}; + +HttpProxyPost::HttpProxyPost(QObject *parent) +:QObject(parent) +{ + d = new Private; + connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected())); + connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed())); + connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); + connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int))); + reset(true); +} + +HttpProxyPost::~HttpProxyPost() +{ + reset(true); + delete d; +} + +void HttpProxyPost::reset(bool clear) +{ + if(d->sock.state() != BSocket::Idle) + d->sock.close(); + d->recvBuf.resize(0); + if(clear) + d->body.resize(0); +} + +void HttpProxyPost::setAuth(const QString &user, const QString &pass) +{ + d->user = user; + d->pass = pass; +} + +bool HttpProxyPost::isActive() const +{ + return (d->sock.state() == BSocket::Idle ? false: true); +} + +void HttpProxyPost::post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy) +{ + reset(true); + + d->host = proxyHost; + d->url = url; + d->postdata = data; + d->asProxy = asProxy; + +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: Connecting to %s:%d", proxyHost.latin1(), proxyPort); + if(d->user.isEmpty()) + fprintf(stderr, "\n"); + else + fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1()); +#endif + d->sock.connectToHost(proxyHost, proxyPort); +} + +void HttpProxyPost::stop() +{ + reset(); +} + +QByteArray HttpProxyPost::body() const +{ + return d->body; +} + +QString HttpProxyPost::getHeader(const QString &var) const +{ + for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it) { + const QString &s = *it; + int n = s.find(": "); + if(n == -1) + continue; + QString v = s.mid(0, n); + if(v == var) + return s.mid(n+2); + } + return ""; +} + +void HttpProxyPost::sock_connected() +{ +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: Connected\n"); +#endif + d->inHeader = true; + d->headerLines.clear(); + + Q3Url u = d->url; + + // connected, now send the request + QString s; + s += QString("POST ") + d->url + " HTTP/1.0\r\n"; + if(d->asProxy) { + if(!d->user.isEmpty()) { + QString str = d->user + ':' + d->pass; + s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n"; + } + s += "Pragma: no-cache\r\n"; + s += QString("Host: ") + u.host() + "\r\n"; + } + else { + s += QString("Host: ") + d->host + "\r\n"; + } + s += "Content-Type: application/x-www-form-urlencoded\r\n"; + s += QString("Content-Length: ") + QString::number(d->postdata.size()) + "\r\n"; + s += "\r\n"; + + // write request + Q3CString cs = s.utf8(); + QByteArray block(cs.length()); + memcpy(block.data(), cs.data(), block.size()); + d->sock.write(block); + + // write postdata + d->sock.write(d->postdata); +} + +void HttpProxyPost::sock_connectionClosed() +{ + d->body = d->recvBuf; + reset(); + result(); +} + +void HttpProxyPost::sock_readyRead() +{ + QByteArray block = d->sock.read(); + ByteStream::appendArray(&d->recvBuf, block); + + if(d->inHeader) { + // grab available lines + while(1) { + bool found; + QString line = extractLine(&d->recvBuf, &found); + if(!found) + break; + if(line.isEmpty()) { + d->inHeader = false; + break; + } + d->headerLines += line; + } + + // done with grabbing the header? + if(!d->inHeader) { + QString str = d->headerLines.first(); + d->headerLines.remove(d->headerLines.begin()); + + QString proto; + int code; + QString msg; + if(!extractMainHeader(str, &proto, &code, &msg)) { +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: invalid header!\n"); +#endif + reset(true); + error(ErrProxyNeg); + return; + } + else { +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1()); + for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it) + fprintf(stderr, "HttpProxyPost: * [%s]\n", (*it).latin1()); +#endif + } + + if(code == 200) { // OK +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: << Success >>\n"); +#endif + } + else { + int err; + QString errStr; + if(code == 407) { // Authentication failed + err = ErrProxyAuth; + errStr = tr("Authentication failed"); + } + else if(code == 404) { // Host not found + err = ErrHostNotFound; + errStr = tr("Host not found"); + } + else if(code == 403) { // Access denied + err = ErrProxyNeg; + errStr = tr("Access denied"); + } + else if(code == 503) { // Connection refused + err = ErrConnectionRefused; + errStr = tr("Connection refused"); + } + else { // invalid reply + err = ErrProxyNeg; + errStr = tr("Invalid reply"); + } + +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: << Error >> [%s]\n", errStr.latin1()); +#endif + reset(true); + error(err); + return; + } + } + } +} + +void HttpProxyPost::sock_error(int x) +{ +#ifdef PROX_DEBUG + fprintf(stderr, "HttpProxyPost: socket error: %d\n", x); +#endif + reset(true); + if(x == BSocket::ErrHostNotFound) + error(ErrProxyConnect); + else if(x == BSocket::ErrConnectionRefused) + error(ErrProxyConnect); + else if(x == BSocket::ErrRead) + error(ErrProxyNeg); +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/network/httppoll.h b/iris-legacy/cutestuff/network/httppoll.h new file mode 100644 index 0000000..0b79802 --- /dev/null +++ b/iris-legacy/cutestuff/network/httppoll.h @@ -0,0 +1,104 @@ +/* + * httppoll.h - HTTP polling proxy + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_HTTPPOLL_H +#define CS_HTTPPOLL_H + +#include "bytestream.h" + +// CS_NAMESPACE_BEGIN + +class HttpPoll : public ByteStream +{ + Q_OBJECT +public: + enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth }; + HttpPoll(QObject *parent=0); + ~HttpPoll(); + + void setAuth(const QString &user, const QString &pass=""); + void connectToUrl(const QString &url); + void connectToHost(const QString &proxyHost, int proxyPort, const QString &url); + + int pollInterval() const; + void setPollInterval(int seconds); + + // from ByteStream + bool isOpen() const; + void close(); + +signals: + void connected(); + void syncStarted(); + void syncFinished(); + +protected: + int tryWrite(); + +private slots: + void http_result(); + void http_error(int); + void do_sync(); + +private: + class Private; + Private *d; + + void reset(bool clear=false); + QByteArray makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block); + void resetKey(); + const QString & getKey(bool *); +}; + +class HttpProxyPost : public QObject +{ + Q_OBJECT +public: + enum Error { ErrConnectionRefused, ErrHostNotFound, ErrSocket, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth }; + HttpProxyPost(QObject *parent=0); + ~HttpProxyPost(); + + void setAuth(const QString &user, const QString &pass=""); + bool isActive() const; + void post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy=true); + void stop(); + QByteArray body() const; + QString getHeader(const QString &) const; + +signals: + void result(); + void error(int); + +private slots: + void sock_connected(); + void sock_connectionClosed(); + void sock_readyRead(); + void sock_error(int); + +private: + class Private; + Private *d; + + void reset(bool clear=false); +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/network/socks.cpp b/iris-legacy/cutestuff/network/socks.cpp new file mode 100644 index 0000000..31d728d --- /dev/null +++ b/iris-legacy/cutestuff/network/socks.cpp @@ -0,0 +1,1231 @@ +/* + * socks.cpp - SOCKS5 TCP proxy client/server + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "socks.h" + +#include +#include +#include +#include +#include +#include +#include +//Added by qt3to4: +#include + +#ifdef Q_OS_UNIX +#include +#include +#endif + +#ifdef Q_OS_WIN32 +#include +#endif + +#ifdef Q_OS_UNIX +#include +#include +#endif + +#include "servsock.h" +#include "bsocket.h" + +#ifdef PROX_DEBUG +#include +#endif + +// CS_NAMESPACE_BEGIN + +//---------------------------------------------------------------------------- +// SocksUDP +//---------------------------------------------------------------------------- +static QByteArray sp_create_udp(const QString &host, Q_UINT16 port, const QByteArray &buf) +{ + // detect for IP addresses + //QHostAddress addr; + //if(addr.setAddress(host)) + // return sp_set_request(addr, port, cmd1); + + Q3CString h = host.utf8(); + h.truncate(255); + h = QString::fromUtf8(h).utf8(); // delete any partial characters? + int hlen = h.length(); + + int at = 0; + QByteArray a(4); + a[at++] = 0x00; // reserved + a[at++] = 0x00; // reserved + a[at++] = 0x00; // frag + a[at++] = 0x03; // address type = domain + + // host + a.resize(at+hlen+1); + a[at++] = hlen; + memcpy(a.data() + at, h.data(), hlen); + at += hlen; + + // port + a.resize(at+2); + unsigned short p = htons(port); + memcpy(a.data() + at, &p, 2); + at += 2; + + a.resize(at+buf.size()); + memcpy(a.data() + at, buf.data(), buf.size()); + + return a; +} + +struct SPS_UDP +{ + QString host; + Q_UINT16 port; + QByteArray data; +}; + +static int sp_read_udp(QByteArray *from, SPS_UDP *s) +{ + int full_len = 4; + if((int)from->size() < full_len) + return 0; + + QString host; + QHostAddress addr; + unsigned char atype = from->at(3); + + if(atype == 0x01) { + full_len += 4; + if((int)from->size() < full_len) + return 0; + Q_UINT32 ip4; + memcpy(&ip4, from->data() + 4, 4); + addr.setAddress(ntohl(ip4)); + host = addr.toString(); + } + else if(atype == 0x03) { + ++full_len; + if((int)from->size() < full_len) + return 0; + unsigned char host_len = from->at(4); + full_len += host_len; + if((int)from->size() < full_len) + return 0; + Q3CString cs(host_len+1); + memcpy(cs.data(), from->data() + 5, host_len); + host = QString::fromLatin1(cs); + } + else if(atype == 0x04) { + full_len += 16; + if((int)from->size() < full_len) + return 0; + Q_UINT8 a6[16]; + memcpy(a6, from->data() + 4, 16); + addr.setAddress(a6); + host = addr.toString(); + } + + full_len += 2; + if((int)from->size() < full_len) + return 0; + + Q_UINT16 p; + memcpy(&p, from->data() + full_len - 2, 2); + + s->host = host; + s->port = ntohs(p); + s->data.resize(from->size() - full_len); + memcpy(s->data.data(), from->data() + full_len, s->data.size()); + + return 1; +} + +class SocksUDP::Private +{ +public: + Q3SocketDevice *sd; + QSocketNotifier *sn; + SocksClient *sc; + QHostAddress routeAddr; + int routePort; + QString host; + int port; +}; + +SocksUDP::SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort) +:QObject(sc) +{ + d = new Private; + d->sc = sc; + d->sd = new Q3SocketDevice(Q3SocketDevice::Datagram); + d->sd->setBlocking(false); + d->sn = new QSocketNotifier(d->sd->socket(), QSocketNotifier::Read); + connect(d->sn, SIGNAL(activated(int)), SLOT(sn_activated(int))); + d->host = host; + d->port = port; + d->routeAddr = routeAddr; + d->routePort = routePort; +} + +SocksUDP::~SocksUDP() +{ + delete d->sn; + delete d->sd; + delete d; +} + +void SocksUDP::change(const QString &host, int port) +{ + d->host = host; + d->port = port; +} + +void SocksUDP::write(const QByteArray &data) +{ + QByteArray buf = sp_create_udp(d->host, d->port, data); + d->sd->setBlocking(true); + d->sd->writeBlock(buf.data(), buf.size(), d->routeAddr, d->routePort); + d->sd->setBlocking(false); +} + +void SocksUDP::sn_activated(int) +{ + QByteArray buf(8192); + int actual = d->sd->readBlock(buf.data(), buf.size()); + buf.resize(actual); + packetReady(buf); +} + +//---------------------------------------------------------------------------- +// SocksClient +//---------------------------------------------------------------------------- +#define REQ_CONNECT 0x01 +#define REQ_BIND 0x02 +#define REQ_UDPASSOCIATE 0x03 + +#define RET_SUCCESS 0x00 +#define RET_UNREACHABLE 0x04 +#define RET_CONNREFUSED 0x05 + +// spc = socks packet client +// sps = socks packet server +// SPCS = socks packet client struct +// SPSS = socks packet server struct + +// Version +static QByteArray spc_set_version() +{ + QByteArray ver(4); + ver[0] = 0x05; // socks version 5 + ver[1] = 0x02; // number of methods + ver[2] = 0x00; // no-auth + ver[3] = 0x02; // username + return ver; +} + +static QByteArray sps_set_version(int method) +{ + QByteArray ver(2); + ver[0] = 0x05; + ver[1] = method; + return ver; +} + +struct SPCS_VERSION +{ + unsigned char version; + QByteArray methodList; +}; + +static int spc_get_version(QByteArray *from, SPCS_VERSION *s) +{ + if(from->size() < 1) + return 0; + if(from->at(0) != 0x05) // only SOCKS5 supported + return -1; + if(from->size() < 2) + return 0; + int num = from->at(1); + if(num > 16) // who the heck has over 16 auth methods?? + return -1; + if(from->size() < 2 + num) + return 0; + QByteArray a = ByteStream::takeArray(from, 2+num); + s->version = a[0]; + s->methodList.resize(num); + memcpy(s->methodList.data(), a.data() + 2, num); + return 1; +} + +struct SPSS_VERSION +{ + unsigned char version; + unsigned char method; +}; + +static int sps_get_version(QByteArray *from, SPSS_VERSION *s) +{ + if(from->size() < 2) + return 0; + QByteArray a = ByteStream::takeArray(from, 2); + s->version = a[0]; + s->method = a[1]; + return 1; +} + +// authUsername +static QByteArray spc_set_authUsername(const Q3CString &user, const Q3CString &pass) +{ + int len1 = user.length(); + int len2 = pass.length(); + if(len1 > 255) + len1 = 255; + if(len2 > 255) + len2 = 255; + QByteArray a(1+1+len1+1+len2); + a[0] = 0x01; // username auth version 1 + a[1] = len1; + memcpy(a.data() + 2, user.data(), len1); + a[2+len1] = len2; + memcpy(a.data() + 3 + len1, pass.data(), len2); + return a; +} + +static QByteArray sps_set_authUsername(bool success) +{ + QByteArray a(2); + a[0] = 0x01; + a[1] = success ? 0x00 : 0xff; + return a; +} + +struct SPCS_AUTHUSERNAME +{ + QString user, pass; +}; + +static int spc_get_authUsername(QByteArray *from, SPCS_AUTHUSERNAME *s) +{ + if(from->size() < 1) + return 0; + unsigned char ver = from->at(0); + if(ver != 0x01) + return -1; + if(from->size() < 2) + return 0; + unsigned char ulen = from->at(1); + if((int)from->size() < ulen + 3) + return 0; + unsigned char plen = from->at(ulen+2); + if((int)from->size() < ulen + plen + 3) + return 0; + QByteArray a = ByteStream::takeArray(from, ulen + plen + 3); + + Q3CString user, pass; + user.resize(ulen+1); + pass.resize(plen+1); + memcpy(user.data(), a.data()+2, ulen); + memcpy(pass.data(), a.data()+ulen+3, plen); + s->user = QString::fromUtf8(user); + s->pass = QString::fromUtf8(pass); + return 1; +} + +struct SPSS_AUTHUSERNAME +{ + unsigned char version; + bool success; +}; + +static int sps_get_authUsername(QByteArray *from, SPSS_AUTHUSERNAME *s) +{ + if(from->size() < 2) + return 0; + QByteArray a = ByteStream::takeArray(from, 2); + s->version = a[0]; + s->success = ((char) a[1] == 0 ? true: false); + return 1; +} + +// connectRequest +static QByteArray sp_set_request(const QHostAddress &addr, unsigned short port, unsigned char cmd1) +{ + int at = 0; + QByteArray a(4); + a[at++] = 0x05; // socks version 5 + a[at++] = cmd1; + a[at++] = 0x00; // reserved + if(addr.isIp4Addr()) { + a[at++] = 0x01; // address type = ipv4 + Q_UINT32 ip4 = htonl(addr.ip4Addr()); + a.resize(at+4); + memcpy(a.data() + at, &ip4, 4); + at += 4; + } + else { + a[at++] = 0x04; + Q_UINT8 a6[16]; + QStringList s6 = QStringList::split(':', addr.toString(), true); + int at = 0; + Q_UINT16 c; + bool ok; + for(QStringList::ConstIterator it = s6.begin(); it != s6.end(); ++it) { + c = (*it).toInt(&ok, 16); + a6[at++] = (c >> 8); + a6[at++] = c & 0xff; + } + a.resize(at+16); + memcpy(a.data() + at, a6, 16); + at += 16; + } + + // port + a.resize(at+2); + unsigned short p = htons(port); + memcpy(a.data() + at, &p, 2); + + return a; +} + +static QByteArray sp_set_request(const QString &host, Q_UINT16 port, unsigned char cmd1) +{ + // detect for IP addresses + QHostAddress addr; + if(addr.setAddress(host)) + return sp_set_request(addr, port, cmd1); + + Q3CString h = host.utf8(); + h.truncate(255); + h = QString::fromUtf8(h).utf8(); // delete any partial characters? + int hlen = h.length(); + + int at = 0; + QByteArray a(4); + a[at++] = 0x05; // socks version 5 + a[at++] = cmd1; + a[at++] = 0x00; // reserved + a[at++] = 0x03; // address type = domain + + // host + a.resize(at+hlen+1); + a[at++] = hlen; + memcpy(a.data() + at, h.data(), hlen); + at += hlen; + + // port + a.resize(at+2); + unsigned short p = htons(port); + memcpy(a.data() + at, &p, 2); + + return a; +} + +struct SPS_CONNREQ +{ + unsigned char version; + unsigned char cmd; + int address_type; + QString host; + QHostAddress addr; + Q_UINT16 port; +}; + +static int sp_get_request(QByteArray *from, SPS_CONNREQ *s) +{ + int full_len = 4; + if((int)from->size() < full_len) + return 0; + + QString host; + QHostAddress addr; + unsigned char atype = from->at(3); + + if(atype == 0x01) { + full_len += 4; + if((int)from->size() < full_len) + return 0; + Q_UINT32 ip4; + memcpy(&ip4, from->data() + 4, 4); + addr.setAddress(ntohl(ip4)); + } + else if(atype == 0x03) { + ++full_len; + if((int)from->size() < full_len) + return 0; + unsigned char host_len = from->at(4); + full_len += host_len; + if((int)from->size() < full_len) + return 0; + Q3CString cs(host_len+1); + memcpy(cs.data(), from->data() + 5, host_len); + host = QString::fromLatin1(cs); + } + else if(atype == 0x04) { + full_len += 16; + if((int)from->size() < full_len) + return 0; + Q_UINT8 a6[16]; + memcpy(a6, from->data() + 4, 16); + addr.setAddress(a6); + } + + full_len += 2; + if((int)from->size() < full_len) + return 0; + + QByteArray a = ByteStream::takeArray(from, full_len); + + Q_UINT16 p; + memcpy(&p, a.data() + full_len - 2, 2); + + s->version = a[0]; + s->cmd = a[1]; + s->address_type = atype; + s->host = host; + s->addr = addr; + s->port = ntohs(p); + + return 1; +} + +enum { StepVersion, StepAuth, StepRequest }; + +class SocksClient::Private +{ +public: + Private() {} + + BSocket sock; + QString host; + int port; + QString user, pass; + QString real_host; + int real_port; + + QByteArray recvBuf; + bool active; + int step; + int authMethod; + bool incoming, waiting; + + QString rhost; + int rport; + + int pending; + + bool udp; + QString udpAddr; + int udpPort; +}; + +SocksClient::SocksClient(QObject *parent) +:ByteStream(parent) +{ + init(); + + d->incoming = false; +} + +SocksClient::SocksClient(int s, QObject *parent) +:ByteStream(parent) +{ + init(); + + d->incoming = true; + d->waiting = true; + d->sock.setSocket(s); +} + +void SocksClient::init() +{ + d = new Private; + connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected())); + connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed())); + connect(&d->sock, SIGNAL(delayedCloseFinished()), SLOT(sock_delayedCloseFinished())); + connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); + connect(&d->sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int))); + connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int))); + + reset(true); +} + +SocksClient::~SocksClient() +{ + reset(true); + delete d; +} + +void SocksClient::reset(bool clear) +{ + if(d->sock.state() != BSocket::Idle) + d->sock.close(); + if(clear) + clearReadBuffer(); + d->recvBuf.resize(0); + d->active = false; + d->waiting = false; + d->udp = false; + d->pending = 0; +} + +bool SocksClient::isIncoming() const +{ + return d->incoming; +} + +void SocksClient::setAuth(const QString &user, const QString &pass) +{ + d->user = user; + d->pass = pass; +} + +void SocksClient::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode) +{ + reset(true); + + d->host = proxyHost; + d->port = proxyPort; + d->real_host = host; + d->real_port = port; + d->udp = udpMode; + +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Connecting to %s:%d", proxyHost.latin1(), proxyPort); + if(d->user.isEmpty()) + fprintf(stderr, "\n"); + else + fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1()); +#endif + d->sock.connectToHost(d->host, d->port); +} + +bool SocksClient::isOpen() const +{ + return d->active; +} + +void SocksClient::close() +{ + d->sock.close(); + if(d->sock.bytesToWrite() == 0) + reset(); +} + +void SocksClient::writeData(const QByteArray &buf) +{ + d->pending += buf.size(); + d->sock.write(buf); +} + +void SocksClient::write(const QByteArray &buf) +{ + if(d->active && !d->udp) + d->sock.write(buf); +} + +QByteArray SocksClient::read(int bytes) +{ + return ByteStream::read(bytes); +} + +int SocksClient::bytesAvailable() const +{ + return ByteStream::bytesAvailable(); +} + +int SocksClient::bytesToWrite() const +{ + if(d->active) + return d->sock.bytesToWrite(); + else + return 0; +} + +void SocksClient::sock_connected() +{ +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Connected\n"); +#endif + + d->step = StepVersion; + writeData(spc_set_version()); +} + +void SocksClient::sock_connectionClosed() +{ + if(d->active) { + reset(); + connectionClosed(); + } + else { + error(ErrProxyNeg); + } +} + +void SocksClient::sock_delayedCloseFinished() +{ + if(d->active) { + reset(); + delayedCloseFinished(); + } +} + +void SocksClient::sock_readyRead() +{ + QByteArray block = d->sock.read(); + + if(!d->active) { + if(d->incoming) + processIncoming(block); + else + processOutgoing(block); + } + else { + if(!d->udp) { + appendRead(block); + readyRead(); + } + } +} + +void SocksClient::processOutgoing(const QByteArray &block) +{ +#ifdef PROX_DEBUG + // show hex + fprintf(stderr, "SocksClient: client recv { "); + for(int n = 0; n < (int)block.size(); ++n) + fprintf(stderr, "%02X ", (unsigned char)block[n]); + fprintf(stderr, " } \n"); +#endif + ByteStream::appendArray(&d->recvBuf, block); + + if(d->step == StepVersion) { + SPSS_VERSION s; + int r = sps_get_version(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + if(s.version != 0x05 || s.method == 0xff) { +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Method selection failed\n"); +#endif + reset(true); + error(ErrProxyNeg); + return; + } + + QString str; + if(s.method == 0x00) { + str = "None"; + d->authMethod = AuthNone; + } + else if(s.method == 0x02) { + str = "Username/Password"; + d->authMethod = AuthUsername; + } + else { +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Server wants to use unknown method '%02x'\n", s.method); +#endif + reset(true); + error(ErrProxyNeg); + return; + } + + if(d->authMethod == AuthNone) { + // no auth, go straight to the request + do_request(); + } + else if(d->authMethod == AuthUsername) { + d->step = StepAuth; +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Authenticating [Username] ...\n"); +#endif + writeData(spc_set_authUsername(d->user.latin1(), d->pass.latin1())); + } + } + } + if(d->step == StepAuth) { + if(d->authMethod == AuthUsername) { + SPSS_AUTHUSERNAME s; + int r = sps_get_authUsername(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + if(s.version != 0x01) { + reset(true); + error(ErrProxyNeg); + return; + } + if(!s.success) { + reset(true); + error(ErrProxyAuth); + return; + } + + do_request(); + } + } + } + else if(d->step == StepRequest) { + SPS_CONNREQ s; + int r = sp_get_request(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + if(s.cmd != RET_SUCCESS) { +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: client << Error >> [%02x]\n", s.cmd); +#endif + reset(true); + if(s.cmd == RET_UNREACHABLE) + error(ErrHostNotFound); + else if(s.cmd == RET_CONNREFUSED) + error(ErrConnectionRefused); + else + error(ErrProxyNeg); + return; + } + +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: client << Success >>\n"); +#endif + if(d->udp) { + if(s.address_type == 0x03) + d->udpAddr = s.host; + else + d->udpAddr = s.addr.toString(); + d->udpPort = s.port; + } + + d->active = true; + + QPointer self = this; + connected(); + if(!self) + return; + + if(!d->recvBuf.isEmpty()) { + appendRead(d->recvBuf); + d->recvBuf.resize(0); + readyRead(); + } + } + } +} + +void SocksClient::do_request() +{ +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: Requesting ...\n"); +#endif + d->step = StepRequest; + int cmd = d->udp ? REQ_UDPASSOCIATE : REQ_CONNECT; + QByteArray buf; + if(!d->real_host.isEmpty()) + buf = sp_set_request(d->real_host, d->real_port, cmd); + else + buf = sp_set_request(QHostAddress(), 0, cmd); + writeData(buf); +} + +void SocksClient::sock_bytesWritten(int x) +{ + int bytes = x; + if(d->pending >= bytes) { + d->pending -= bytes; + bytes = 0; + } + else { + bytes -= d->pending; + d->pending = 0; + } + if(bytes > 0) + bytesWritten(bytes); +} + +void SocksClient::sock_error(int x) +{ + if(d->active) { + reset(); + error(ErrRead); + } + else { + reset(true); + if(x == BSocket::ErrHostNotFound) + error(ErrProxyConnect); + else if(x == BSocket::ErrConnectionRefused) + error(ErrProxyConnect); + else if(x == BSocket::ErrRead) + error(ErrProxyNeg); + } +} + +void SocksClient::serve() +{ + d->waiting = false; + d->step = StepVersion; + continueIncoming(); +} + +void SocksClient::processIncoming(const QByteArray &block) +{ +#ifdef PROX_DEBUG + // show hex + fprintf(stderr, "SocksClient: server recv { "); + for(int n = 0; n < (int)block.size(); ++n) + fprintf(stderr, "%02X ", (unsigned char)block[n]); + fprintf(stderr, " } \n"); +#endif + ByteStream::appendArray(&d->recvBuf, block); + + if(!d->waiting) + continueIncoming(); +} + +void SocksClient::continueIncoming() +{ + if(d->recvBuf.isEmpty()) + return; + + if(d->step == StepVersion) { + SPCS_VERSION s; + int r = spc_get_version(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + if(s.version != 0x05) { + reset(true); + error(ErrProxyNeg); + return; + } + + int methods = 0; + for(int n = 0; n < (int)s.methodList.size(); ++n) { + unsigned char c = s.methodList[n]; + if(c == 0x00) + methods |= AuthNone; + else if(c == 0x02) + methods |= AuthUsername; + } + d->waiting = true; + incomingMethods(methods); + } + } + else if(d->step == StepAuth) { + SPCS_AUTHUSERNAME s; + int r = spc_get_authUsername(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + d->waiting = true; + incomingAuth(s.user, s.pass); + } + } + else if(d->step == StepRequest) { + SPS_CONNREQ s; + int r = sp_get_request(&d->recvBuf, &s); + if(r == -1) { + reset(true); + error(ErrProxyNeg); + return; + } + else if(r == 1) { + d->waiting = true; + if(s.cmd == REQ_CONNECT) { + if(!s.host.isEmpty()) + d->rhost = s.host; + else + d->rhost = s.addr.toString(); + d->rport = s.port; + incomingConnectRequest(d->rhost, d->rport); + } + else if(s.cmd == REQ_UDPASSOCIATE) { + incomingUDPAssociateRequest(); + } + else { + requestDeny(); + return; + } + } + } +} + +void SocksClient::chooseMethod(int method) +{ + if(d->step != StepVersion || !d->waiting) + return; + + unsigned char c; + if(method == AuthNone) { + d->step = StepRequest; + c = 0x00; + } + else { + d->step = StepAuth; + c = 0x02; + } + + // version response + d->waiting = false; + writeData(sps_set_version(c)); + continueIncoming(); +} + +void SocksClient::authGrant(bool b) +{ + if(d->step != StepAuth || !d->waiting) + return; + + if(b) + d->step = StepRequest; + + // auth response + d->waiting = false; + writeData(sps_set_authUsername(b)); + if(!b) { + reset(true); + return; + } + continueIncoming(); +} + +void SocksClient::requestDeny() +{ + if(d->step != StepRequest || !d->waiting) + return; + + // response + d->waiting = false; + writeData(sp_set_request(d->rhost, d->rport, RET_UNREACHABLE)); + reset(true); +} + +void SocksClient::grantConnect() +{ + if(d->step != StepRequest || !d->waiting) + return; + + // response + d->waiting = false; + writeData(sp_set_request(d->rhost, d->rport, RET_SUCCESS)); + d->active = true; +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: server << Success >>\n"); +#endif + + if(!d->recvBuf.isEmpty()) { + appendRead(d->recvBuf); + d->recvBuf.resize(0); + readyRead(); + } +} + +void SocksClient::grantUDPAssociate(const QString &relayHost, int relayPort) +{ + if(d->step != StepRequest || !d->waiting) + return; + + // response + d->waiting = false; + writeData(sp_set_request(relayHost, relayPort, RET_SUCCESS)); + d->udp = true; + d->active = true; +#ifdef PROX_DEBUG + fprintf(stderr, "SocksClient: server << Success >>\n"); +#endif + + if(!d->recvBuf.isEmpty()) + d->recvBuf.resize(0); +} + +QHostAddress SocksClient::peerAddress() const +{ + return d->sock.peerAddress(); +} + +Q_UINT16 SocksClient::peerPort() const +{ + return d->sock.peerPort(); +} + +QString SocksClient::udpAddress() const +{ + return d->udpAddr; +} + +Q_UINT16 SocksClient::udpPort() const +{ + return d->udpPort; +} + +SocksUDP *SocksClient::createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort) +{ + return new SocksUDP(this, host, port, routeAddr, routePort); +} + +//---------------------------------------------------------------------------- +// SocksServer +//---------------------------------------------------------------------------- +class SocksServer::Private +{ +public: + Private() {} + + ServSock serv; + Q3PtrList incomingConns; + Q3SocketDevice *sd; + QSocketNotifier *sn; +}; + +SocksServer::SocksServer(QObject *parent) +:QObject(parent) +{ + d = new Private; + d->sd = 0; + d->sn = 0; + connect(&d->serv, SIGNAL(connectionReady(int)), SLOT(connectionReady(int))); +} + +SocksServer::~SocksServer() +{ + stop(); + d->incomingConns.setAutoDelete(true); + d->incomingConns.clear(); + delete d; +} + +bool SocksServer::isActive() const +{ + return d->serv.isActive(); +} + +bool SocksServer::listen(Q_UINT16 port, bool udp) +{ + stop(); + if(!d->serv.listen(port)) + return false; + if(udp) { + d->sd = new Q3SocketDevice(Q3SocketDevice::Datagram); +#ifdef Q_OS_UNIX + ::fcntl(d->sd->socket(), F_SETFD, FD_CLOEXEC); +#endif + d->sd->setBlocking(false); + if(!d->sd->bind(QHostAddress(), port)) { + delete d->sd; + d->sd = 0; + d->serv.stop(); + return false; + } + d->sn = new QSocketNotifier(d->sd->socket(), QSocketNotifier::Read); + connect(d->sn, SIGNAL(activated(int)), SLOT(sn_activated(int))); + } + return true; +} + +void SocksServer::stop() +{ + delete d->sn; + d->sn = 0; + delete d->sd; + d->sd = 0; + d->serv.stop(); +} + +int SocksServer::port() const +{ + return d->serv.port(); +} + +QHostAddress SocksServer::address() const +{ + return d->serv.address(); +} + +SocksClient *SocksServer::takeIncoming() +{ + if(d->incomingConns.isEmpty()) + return 0; + + SocksClient *c = d->incomingConns.getFirst(); + d->incomingConns.removeRef(c); + + // we don't care about errors anymore + disconnect(c, SIGNAL(error(int)), this, SLOT(connectionError())); + + // don't serve the connection until the event loop, to give the caller a chance to map signals + QTimer::singleShot(0, c, SLOT(serve())); + + return c; +} + +void SocksServer::writeUDP(const QHostAddress &addr, int port, const QByteArray &data) +{ + if(d->sd) { + d->sd->setBlocking(true); + d->sd->writeBlock(data.data(), data.size(), addr, port); + d->sd->setBlocking(false); + } +} + +void SocksServer::connectionReady(int s) +{ + SocksClient *c = new SocksClient(s, this); + connect(c, SIGNAL(error(int)), this, SLOT(connectionError())); + d->incomingConns.append(c); + incomingReady(); +} + +void SocksServer::connectionError() +{ + SocksClient *c = (SocksClient *)sender(); + d->incomingConns.removeRef(c); + c->deleteLater(); +} + +void SocksServer::sn_activated(int) +{ + QByteArray buf(8192); + int actual = d->sd->readBlock(buf.data(), buf.size()); + buf.resize(actual); + QHostAddress pa = d->sd->peerAddress(); + int pp = d->sd->peerPort(); + SPS_UDP s; + int r = sp_read_udp(&buf, &s); + if(r != 1) + return; + incomingUDP(s.host, s.port, pa, pp, s.data); +} + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/network/socks.h b/iris-legacy/cutestuff/network/socks.h new file mode 100644 index 0000000..0721ee7 --- /dev/null +++ b/iris-legacy/cutestuff/network/socks.h @@ -0,0 +1,160 @@ +/* + * socks.h - SOCKS5 TCP proxy client/server + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_SOCKS_H +#define CS_SOCKS_H + +#include "bytestream.h" + +// CS_NAMESPACE_BEGIN + +class QHostAddress; +class SocksClient; +class SocksServer; + +class SocksUDP : public QObject +{ + Q_OBJECT +public: + ~SocksUDP(); + + void change(const QString &host, int port); + void write(const QByteArray &data); + +signals: + void packetReady(const QByteArray &data); + +private slots: + void sn_activated(int); + +private: + class Private; + Private *d; + + friend class SocksClient; + SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort); +}; + +class SocksClient : public ByteStream +{ + Q_OBJECT +public: + enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth }; + enum Method { AuthNone=0x0001, AuthUsername=0x0002 }; + enum Request { ReqConnect, ReqUDPAssociate }; + SocksClient(QObject *parent=0); + SocksClient(int, QObject *parent=0); + ~SocksClient(); + + bool isIncoming() const; + + // outgoing + void setAuth(const QString &user, const QString &pass=""); + void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode=false); + + // incoming + void chooseMethod(int); + void authGrant(bool); + void requestDeny(); + void grantConnect(); + void grantUDPAssociate(const QString &relayHost, int relayPort); + + // from ByteStream + bool isOpen() const; + void close(); + void write(const QByteArray &); + QByteArray read(int bytes=0); + int bytesAvailable() const; + int bytesToWrite() const; + + // remote address + QHostAddress peerAddress() const; + Q_UINT16 peerPort() const; + + // udp + QString udpAddress() const; + Q_UINT16 udpPort() const; + SocksUDP *createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort); + +signals: + // outgoing + void connected(); + + // incoming + void incomingMethods(int); + void incomingAuth(const QString &user, const QString &pass); + void incomingConnectRequest(const QString &host, int port); + void incomingUDPAssociateRequest(); + +private slots: + void sock_connected(); + void sock_connectionClosed(); + void sock_delayedCloseFinished(); + void sock_readyRead(); + void sock_bytesWritten(int); + void sock_error(int); + void serve(); + +private: + class Private; + Private *d; + + void init(); + void reset(bool clear=false); + void do_request(); + void processOutgoing(const QByteArray &); + void processIncoming(const QByteArray &); + void continueIncoming(); + void writeData(const QByteArray &a); +}; + +class SocksServer : public QObject +{ + Q_OBJECT +public: + SocksServer(QObject *parent=0); + ~SocksServer(); + + bool isActive() const; + bool listen(Q_UINT16 port, bool udp=false); + void stop(); + int port() const; + QHostAddress address() const; + SocksClient *takeIncoming(); + + void writeUDP(const QHostAddress &addr, int port, const QByteArray &data); + +signals: + void incomingReady(); + void incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data); + +private slots: + void connectionReady(int); + void connectionError(); + void sn_activated(int); + +private: + class Private; + Private *d; +}; + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/cutestuff/util/bytestream.cpp b/iris-legacy/cutestuff/util/bytestream.cpp new file mode 100644 index 0000000..e85defe --- /dev/null +++ b/iris-legacy/cutestuff/util/bytestream.cpp @@ -0,0 +1,269 @@ +/* + * bytestream.cpp - base class for bytestreams + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "bytestream.h" +//Added by qt3to4: +#include + +// CS_NAMESPACE_BEGIN + +//! \class ByteStream bytestream.h +//! \brief Base class for "bytestreams" +//! +//! This class provides a basic framework for a "bytestream", here defined +//! as a bi-directional, asynchronous pipe of data. It can be used to create +//! several different kinds of bytestream-applications, such as a console or +//! TCP connection, or something more abstract like a security layer or tunnel, +//! all with the same interface. The provided functions make creating such +//! classes simpler. ByteStream is a pure-virtual class, so you do not use it +//! on its own, but instead through a subclass such as \a BSocket. +//! +//! The signals connectionClosed(), delayedCloseFinished(), readyRead(), +//! bytesWritten(), and error() serve the exact same function as those from +//! QSocket. +//! +//! The simplest way to create a ByteStream is to reimplement isOpen(), close(), +//! and tryWrite(). Call appendRead() whenever you want to make data available for +//! reading. ByteStream will take care of the buffers with regards to the caller, +//! and will call tryWrite() when the write buffer gains data. It will be your +//! job to call tryWrite() whenever it is acceptable to write more data to +//! the underlying system. +//! +//! If you need more advanced control, reimplement read(), write(), bytesAvailable(), +//! and/or bytesToWrite() as necessary. +//! +//! Use appendRead(), appendWrite(), takeRead(), and takeWrite() to modify the +//! buffers. If you have more advanced requirements, the buffers can be accessed +//! directly with readBuf() and writeBuf(). +//! +//! Also available are the static convenience functions ByteStream::appendArray() +//! and ByteStream::takeArray(), which make dealing with byte queues very easy. + +class ByteStream::Private +{ +public: + Private() {} + + QByteArray readBuf, writeBuf; +}; + +//! +//! Constructs a ByteStream object with parent \a parent. +ByteStream::ByteStream(QObject *parent) +:QObject(parent) +{ + d = new Private; +} + +//! +//! Destroys the object and frees allocated resources. +ByteStream::~ByteStream() +{ + delete d; +} + +//! +//! Returns TRUE if the stream is open, meaning that you can write to it. +bool ByteStream::isOpen() const +{ + return false; +} + +//! +//! Closes the stream. If there is data in the write buffer then it will be +//! written before actually closing the stream. Once all data has been written, +//! the delayedCloseFinished() signal will be emitted. +//! \sa delayedCloseFinished() +void ByteStream::close() +{ +} + +//! +//! Writes array \a a to the stream. +void ByteStream::write(const QByteArray &a) +{ + if(!isOpen()) + return; + + bool doWrite = bytesToWrite() == 0 ? true: false; + appendWrite(a); + if(doWrite) + tryWrite(); +} + +//! +//! Reads bytes \a bytes of data from the stream and returns them as an array. If \a bytes is 0, then +//! \a read will return all available data. +QByteArray ByteStream::read(int bytes) +{ + return takeRead(bytes); +} + +//! +//! Returns the number of bytes available for reading. +int ByteStream::bytesAvailable() const +{ + return d->readBuf.size(); +} + +//! +//! Returns the number of bytes that are waiting to be written. +int ByteStream::bytesToWrite() const +{ + return d->writeBuf.size(); +} + +//! +//! Writes string \a cs to the stream. +void ByteStream::write(const Q3CString &cs) +{ + QByteArray block(cs.length()); + memcpy(block.data(), cs.data(), block.size()); + write(block); +} + +//! +//! Clears the read buffer. +void ByteStream::clearReadBuffer() +{ + d->readBuf.resize(0); +} + +//! +//! Clears the write buffer. +void ByteStream::clearWriteBuffer() +{ + d->writeBuf.resize(0); +} + +//! +//! Appends \a block to the end of the read buffer. +void ByteStream::appendRead(const QByteArray &block) +{ + appendArray(&d->readBuf, block); +} + +//! +//! Appends \a block to the end of the write buffer. +void ByteStream::appendWrite(const QByteArray &block) +{ + appendArray(&d->writeBuf, block); +} + +//! +//! Returns \a size bytes from the start of the read buffer. +//! If \a size is 0, then all available data will be returned. +//! If \a del is TRUE, then the bytes are also removed. +QByteArray ByteStream::takeRead(int size, bool del) +{ + return takeArray(&d->readBuf, size, del); +} + +//! +//! Returns \a size bytes from the start of the write buffer. +//! If \a size is 0, then all available data will be returned. +//! If \a del is TRUE, then the bytes are also removed. +QByteArray ByteStream::takeWrite(int size, bool del) +{ + return takeArray(&d->writeBuf, size, del); +} + +//! +//! Returns a reference to the read buffer. +QByteArray & ByteStream::readBuf() +{ + return d->readBuf; +} + +//! +//! Returns a reference to the write buffer. +QByteArray & ByteStream::writeBuf() +{ + return d->writeBuf; +} + +//! +//! Attempts to try and write some bytes from the write buffer, and returns the number +//! successfully written or -1 on error. The default implementation returns -1. +int ByteStream::tryWrite() +{ + return -1; +} + +//! +//! Append array \a b to the end of the array pointed to by \a a. +void ByteStream::appendArray(QByteArray *a, const QByteArray &b) +{ + int oldsize = a->size(); + a->resize(oldsize + b.size()); + memcpy(a->data() + oldsize, b.data(), b.size()); +} + +//! +//! Returns \a size bytes from the start of the array pointed to by \a from. +//! If \a size is 0, then all available data will be returned. +//! If \a del is TRUE, then the bytes are also removed. +QByteArray ByteStream::takeArray(QByteArray *from, int size, bool del) +{ + QByteArray a; + if(size == 0) { + a = *from; + if(del) + from->resize(0); + } + else { + if(size > (int)from->size()) + size = from->size(); + a.resize(size); + char *r = from->data(); + memcpy(a.data(), r, size); + if(del) { + int newsize = from->size()-size; + memmove(r, r+size, newsize); + from->resize(newsize); + } + } + return a; +} + void connectionClosed(); + void delayedCloseFinished(); + void readyRead(); + void bytesWritten(int); + void error(int); + +//! \fn void ByteStream::connectionClosed() +//! This signal is emitted when the remote end of the stream closes. + +//! \fn void ByteStream::delayedCloseFinished() +//! This signal is emitted when all pending data has been written to the stream +//! after an attempt to close. + +//! \fn void ByteStream::readyRead() +//! This signal is emitted when data is available to be read. + +//! \fn void ByteStream::bytesWritten(int x); +//! This signal is emitted when data has been successfully written to the stream. +//! \a x is the number of bytes written. + +//! \fn void ByteStream::error(int code) +//! This signal is emitted when an error occurs in the stream. The reason for +//! error is indicated by \a code. + +// CS_NAMESPACE_END diff --git a/iris-legacy/cutestuff/util/bytestream.h b/iris-legacy/cutestuff/util/bytestream.h new file mode 100644 index 0000000..85c676f --- /dev/null +++ b/iris-legacy/cutestuff/util/bytestream.h @@ -0,0 +1,78 @@ +/* + * bytestream.h - base class for bytestreams + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CS_BYTESTREAM_H +#define CS_BYTESTREAM_H + +#include +#include + +// CS_NAMESPACE_BEGIN + +// CS_EXPORT_BEGIN +class ByteStream : public QObject +{ + Q_OBJECT +public: + enum Error { ErrRead, ErrWrite, ErrCustom = 10 }; + ByteStream(QObject *parent=0); + virtual ~ByteStream()=0; + + virtual bool isOpen() const; + virtual void close(); + virtual void write(const QByteArray &); + virtual QByteArray read(int bytes=0); + virtual int bytesAvailable() const; + virtual int bytesToWrite() const; + + void write(const Q3CString &); + + static void appendArray(QByteArray *a, const QByteArray &b); + static QByteArray takeArray(QByteArray *from, int size=0, bool del=true); + +signals: + void connectionClosed(); + void delayedCloseFinished(); + void readyRead(); + void bytesWritten(int); + void error(int); + +protected: + void clearReadBuffer(); + void clearWriteBuffer(); + void appendRead(const QByteArray &); + void appendWrite(const QByteArray &); + QByteArray takeRead(int size=0, bool del=true); + QByteArray takeWrite(int size=0, bool del=true); + QByteArray & readBuf(); + QByteArray & writeBuf(); + virtual int tryWrite(); + +private: +//! \if _hide_doc_ + class Private; + Private *d; +//! \endif +}; +// CS_EXPORT_END + +// CS_NAMESPACE_END + +#endif diff --git a/iris-legacy/iris/COPYING b/iris-legacy/iris/COPYING new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/iris-legacy/iris/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/iris-legacy/iris/TODO b/iris-legacy/iris/TODO new file mode 100644 index 0000000..001df66 --- /dev/null +++ b/iris-legacy/iris/TODO @@ -0,0 +1,18 @@ +- Stream::id(), Stream::lang() +- whitespace pings (but disable when using http poll) +- make stanza error conditions work for both 1.0 and old + +- xmpp-im (messages, roster, subscriptions, presence, privacy) +- document xmpp-core +- provide complete support for xmpp-core. this means all functionality from + the draft, and noting behavior issues (like IQ semantics) in the + library documentation. + +- SASL "EXTERNAL" w/ client certificate +- SASL "ANONYMOUS" ? + +credits: + MD5 algorithm by Peter Deutsch (Aladdin Enterprises) + +- s5b: support multiple streamhosts in proxy reply + diff --git a/iris-legacy/iris/example/conntest/configure b/iris-legacy/iris/example/conntest/configure new file mode 100644 index 0000000..f78cf2e --- /dev/null +++ b/iris-legacy/iris/example/conntest/configure @@ -0,0 +1,609 @@ +#!/bin/sh + +show_usage() { +cat </dev/null` + if [ ! -x "$m" ]; then + echo fail + echo + echo "We found Qt in $QTDIR, but we were unable to locate" + echo "the moc utility. It was not found in $QTDIR/bin" + echo "nor in PATH. This seems to be a very unusual setup." + echo "You might try using the --qtdir option." + echo + exit 1; + fi + qtpre=`echo $m | awk '{ n = index($0, "/bin/moc"); if (!n) { exit 1; } print substr($0, 0, n-1); exit 0; }' 2>/dev/null` + ret="$?" + if [ "$ret" != "0" ]; then + echo fail + echo + echo "We found Qt in $QTDIR, but the location of moc" + echo "($m) is not suitable for use with this build system." + echo "This is a VERY unusual and likely-broken setup. You" + echo "should contact the maintainer of your Qt package." + echo + exit 1; + fi + QTDIR=$qtpre + fi +fi + +if [ ! -x "$QTDIR/bin/qmake" ]; then + if [ "$QC_DEBUG" = "Y" ]; then + echo Warning: qmake not in \$QTDIR/bin/qmake + echo trying to find it in \$PATH + fi + qm=`which qmake 2>/dev/null` + if [ -x "$qm" ]; then + if [ "$QC_DEBUG" = "Y" ]; then + echo qmake found in $qm + fi + else + echo fail + echo + echo Sorry, you seem to have a very unusual setup, + echo or I missdetected \$QTDIR=$QTDIR + echo + echo Please set \$QTDIR manually and make sure that + echo \$QTDIR/bin/qmake exists. + echo + exit 1; + fi +else + qm=$QTDIR/bin/qmake +fi + +gen_files() { +cat >$1/modules.cpp <$1/modules_new.cpp <$1/conf.cpp < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MocTestObject : public QObject +{ + Q_OBJECT +public: + MocTestObject() {} +}; + +class Conf; + +class ConfObj +{ +public: + ConfObj(Conf *c); + virtual ~ConfObj(); + + virtual QString name() const=0; + virtual QString shortname() const=0; + virtual QString checkString() const; + virtual QString resultString() const; + virtual bool exec()=0; + + Conf *conf; + bool required; + bool disabled; +}; + +typedef QPtrList ConfObjList; +typedef QPtrListIterator ConfObjListIt; + +class Conf +{ +public: + Conf() : vars(17) + { + list.setAutoDelete(true); + vars.setAutoDelete(true); + + vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); + vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); + vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); + vars.insert("QMAKE_CC", new QString(CC)); + + do_debug = false; + done_debug = false; + } + + ~Conf() + { + } + + void added(ConfObj *o) + { + list.append(o); + } + + QString getenv(const QString &var) + { + char *p = ::getenv(var.latin1()); + if(!p) + return QString::null; + return QString(p); + } + + void debug(const QString &s) + { + if(do_debug) { + if(!done_debug) + printf("\n"); + done_debug = true; + printf(" * %s\n", s.latin1()); + } + } + + bool exec() + { + if(getenv("QC_DEBUG") == "Y") + do_debug = true; + + ConfObjListIt it(list); + for(ConfObj *o; (o = it.current()); ++it) { + // if this was a disabled-by-default option, check if it was enabled + if(o->disabled) { + QString v = QString("QC_ENABLE_") + o->shortname(); + if(getenv(v) != "Y") + continue; + } + // and the opposite? + else { + QString v = QString("QC_DISABLE_") + o->shortname(); + if(getenv(v) == "Y") + continue; + } + + QString check = o->checkString(); + if(check.isEmpty()) + check = QString("Checking for %1 ...").arg(o->name()); + printf("%s", check.latin1()); + fflush(stdout); + + done_debug = false; + bool ok = o->exec(); + + QString result = o->resultString(); + if(result.isEmpty()) { + if(ok) + result = "yes"; + else + result = "no"; + } + if(done_debug) + printf(" -> %s\n", result.latin1()); + else + printf(" %s\n", result.latin1()); + + if(!ok && o->required) { + printf("\nError: need %s!\n", o->name().latin1()); + return false; + } + } + return true; + } + + const QString & qvar(const QString &s) + { + QString *p = vars.find(s); + if(p) + return *p; + else + return blank; + } + + QString expandIncludes(const QString &inc) + { + return QString("-I") + inc; + } + + QString expandLibs(const QString &lib) + { + return QString("-L") + lib; + } + + int doCommand(const QString &s) + { + debug(QString("[%1]").arg(s)); + QString fullcmd; + if(do_debug) + fullcmd = s; + else + fullcmd = s + " 1>/dev/null 2>/dev/null"; + int r = system(fullcmd.latin1()); + debug(QString("returned: %1").arg(r)); + return r; + } + + bool doCompileAndLink(const QString &filedata, const QString &flags, int *retcode=0) + { + QDir dir("."); + QString fname = "atest.c"; + QString out = "atest"; + QFile f(fname); + QCString cs = filedata.latin1(); + if(!f.open(IO_WriteOnly | IO_Truncate)) { + debug("unable to open atest.c for writing"); + return false; + } + if(f.writeBlock(cs.data(), cs.length()) == -1) { + debug("error writing to atest.c"); + return false; + } + f.close(); + + debug(QString("Wrote atest.c:\n%1").arg(filedata)); + + QString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out; + if(!flags.isEmpty()) { + str += ' '; + str += flags; + } + + int r = doCommand(str); + if(r == 0 && retcode) + *retcode = doCommand(QString("./") + out); + dir.remove(fname); + dir.remove(out); + if(r != 0) + return false; + return true; + } + + bool checkHeader(const QString &path, const QString &h) + { + QFileInfo fi(path + '/' + h); + if(fi.exists()) + return true; + return false; + } + + bool findHeader(const QString &h, const QStringList &ext, QString *inc) + { + if(checkHeader("/usr/include", h)) { + *inc = ""; + return true; + } + QStringList dirs; + dirs += "/usr/local/include"; + dirs += ext; + for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { + if(checkHeader(*it, h)) { + *inc = *it; + return true; + } + } + return false; + } + + bool checkLibrary(const QString &path, const QString &name) + { + QString str = + "int main()\n" + "{\n" + " return 0;\n" + "}\n"; + + QString extra; + if(!path.isEmpty()) + extra += QString("-L") + path + ' '; + extra += QString("-l") + name; + if(!doCompileAndLink(str, extra)) + return false; + return true; + } + + bool findLibrary(const QString &name, QString *lib) + { + if(checkLibrary("", name)) { + *lib = ""; + return true; + } + if(checkLibrary("/usr/local/lib", name)) { + *lib = "/usr/local/lib"; + return true; + } + return false; + } + + void addDefine(const QString &str) + { + if(DEFINES.isEmpty()) + DEFINES = str; + else + DEFINES += QString(" ") + str; + debug(QString("DEFINES += %1").arg(str)); + } + + void addLib(const QString &str) + { + if(LIBS.isEmpty()) + LIBS = str; + else + LIBS += QString(" ") + str; + debug(QString("LIBS += %1").arg(str)); + } + + void addIncludePath(const QString &str) + { + if(INCLUDEPATH.isEmpty()) + INCLUDEPATH = str; + else + INCLUDEPATH += QString(" ") + str; + debug(QString("INCLUDEPATH += %1").arg(str)); + } + + void addExtra(const QString &str) + { + extra += str + '\n'; + debug(QString("extra += %1").arg(str)); + } + + QString DEFINES; + QString INCLUDEPATH; + QString LIBS; + QString extra; + +private: + ConfObjList list; + QDict vars; + QString blank; + bool do_debug, done_debug; +}; + +ConfObj::ConfObj(Conf *c) +{ + conf = c; + conf->added(this); + required = false; + disabled = false; +} + +ConfObj::~ConfObj() +{ +} + +QString ConfObj::checkString() const +{ + return QString(); +} + +QString ConfObj::resultString() const +{ + return QString(); +} + +#include"modules.cpp" + +//---------------------------------------------------------------------------- +// main +//---------------------------------------------------------------------------- +int main() +{ + Conf *conf = new Conf; + ConfObj *o; + o = 0; +#include"modules_new.cpp" + + printf("ok\n"); + bool success = false; + if(conf->exec()) { + QFile f("conf.pri"); + if(!f.open(IO_WriteOnly | IO_Truncate)) { + printf("Error writing %s\n", f.name().latin1()); + return 1; + } + + QString str; + str += "# qconf\n"; + str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; + if(!conf->DEFINES.isEmpty()) + str += "DEFINES += " + conf->DEFINES + '\n'; + if(!conf->INCLUDEPATH.isEmpty()) + str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; + if(!conf->LIBS.isEmpty()) + str += "LIBS += " + conf->LIBS + '\n'; + if(!conf->extra.isEmpty()) + str += conf->extra; + str += '\n'; + + char *p = getenv("BINDIR"); + if(p) { + str += QString("target.path = ") + p + '\n'; + str += "INSTALLS += target\n"; + } + + QCString cs = str.latin1(); + f.writeBlock(cs.data(), cs.length()); + f.close(); + success = true; + } + delete conf; + + if(success) + return 0; + else + return 1; +} + +#include"conf.moc" + + +EOT +cat >$1/conf.pro </dev/null + QTDIR=$QTDIR make clean >/dev/null 2>&1 + QTDIR=$QTDIR make >../conf.log 2>&1 +) + +if [ "$?" != "0" ]; then + rm -rf .qconftemp + echo fail + echo + echo "There was an error compiling 'conf'. Be sure you have a proper" + echo "Qt 3.x Multithreaded (MT) build environment set up. This" + echo "means not just Qt, but also a C++ compiler, the 'make' command," + echo "and any other packages necessary to compile C++ programs." + echo "See conf.log for details." + if [ ! -f "$QTDIR/lib/libqt-mt.so.3" ]; then + echo + echo "One possible reason is that you don't have" + echo "libqt-mt.so.3 installed in $QTDIR/lib/." + fi + echo + exit 1; +fi + +.qconftemp/conf +ret="$?" +if [ "$ret" = "1" ]; then + rm -rf .qconftemp + echo + exit 1; +else + if [ "$ret" != "0" ]; then + rm -rf .qconftemp + echo fail + echo + echo Unexpected error launching 'conf' + echo + exit 1; + fi +fi +rm -rf .qconftemp + +if [ -x "./qcextra" ]; then + ./qcextra +fi +# run qmake +$qm conntest.pro +if [ "$?" != "0" ]; then + echo + exit 1; +fi +cat >Makefile.tmp <> Makefile.tmp +rm -f Makefile +cp -f Makefile.tmp Makefile +rm -f Makefile.tmp + +echo +echo Good, your configure finished. Now run \'make\'. +echo diff --git a/iris-legacy/iris/example/conntest/conntest.cpp b/iris-legacy/iris/example/conntest/conntest.cpp new file mode 100644 index 0000000..6e6f1d9 --- /dev/null +++ b/iris-legacy/iris/example/conntest/conntest.cpp @@ -0,0 +1,578 @@ +#include +#include "bconsole.h" +#include +#include "xmpp.h" + +#include + +#define ROOTCERT_PATH "/usr/local/share/psi/certs/rootcert.xml" + +QCA::Cert readCertXml(const QDomElement &e) +{ + QCA::Cert cert; + // there should be one child data tag + QDomElement data = e.elementsByTagName("data").item(0).toElement(); + if(!data.isNull()) + cert.fromDER(Base64::stringToArray(data.text())); + return cert; +} + +QPtrList getRootCerts(const QString &store) +{ + QPtrList list; + + // open the Psi rootcerts file + QFile f(store); + if(!f.open(IO_ReadOnly)) { + printf("unable to open %s\n", f.name().latin1()); + return list; + } + QDomDocument doc; + doc.setContent(&f); + f.close(); + + QDomElement base = doc.documentElement(); + if(base.tagName() != "store") { + printf("wrong format of %s\n", f.name().latin1()); + return list; + } + QDomNodeList cl = base.elementsByTagName("certificate"); + if(cl.count() == 0) { + printf("no certs found in %s\n", f.name().latin1()); + return list; + } + + int num = 0; + for(int n = 0; n < (int)cl.count(); ++n) { + QCA::Cert *cert = new QCA::Cert(readCertXml(cl.item(n).toElement())); + if(cert->isNull()) { + printf("error reading cert\n"); + delete cert; + continue; + } + + ++num; + list.append(cert); + } + printf("imported %d root certs\n", num); + + return list; +} + +static QString prompt(const QString &s) +{ + printf("* %s ", s.latin1()); + fflush(stdout); + char line[256]; + fgets(line, 255, stdin); + QString result = line; + if(result[result.length()-1] == '\n') + result.truncate(result.length()-1); + return result; +} + +static void showCertInfo(const QCA::Cert &cert) +{ + fprintf(stderr, "-- Cert --\n"); + fprintf(stderr, " CN: %s\n", cert.subject()["CN"].latin1()); + fprintf(stderr, " Valid from: %s, until %s\n", + cert.notBefore().toString().latin1(), + cert.notAfter().toString().latin1()); + fprintf(stderr, " PEM:\n%s\n", cert.toPEM().latin1()); +} + +static QString resultToString(int result) +{ + QString s; + switch(result) { + case QCA::TLS::NoCert: + s = QObject::tr("No certificate presented."); + break; + case QCA::TLS::Valid: + break; + case QCA::TLS::HostMismatch: + s = QObject::tr("Hostname mismatch."); + break; + case QCA::TLS::Rejected: + s = QObject::tr("Root CA rejects the specified purpose."); + break; + case QCA::TLS::Untrusted: + s = QObject::tr("Not trusted for the specified purpose."); + break; + case QCA::TLS::SignatureFailed: + s = QObject::tr("Invalid signature."); + break; + case QCA::TLS::InvalidCA: + s = QObject::tr("Invalid CA certificate."); + break; + case QCA::TLS::InvalidPurpose: + s = QObject::tr("Invalid certificate purpose."); + break; + case QCA::TLS::SelfSigned: + s = QObject::tr("Certificate is self-signed."); + break; + case QCA::TLS::Revoked: + s = QObject::tr("Certificate has been revoked."); + break; + case QCA::TLS::PathLengthExceeded: + s = QObject::tr("Maximum cert chain length exceeded."); + break; + case QCA::TLS::Expired: + s = QObject::tr("Certificate has expired."); + break; + case QCA::TLS::Unknown: + default: + s = QObject::tr("General validation error."); + break; + } + return s; +} + +class App : public QObject +{ + Q_OBJECT +public: + XMPP::AdvancedConnector *conn; + QCA::TLS *tls; + XMPP::QCATLSHandler *tlsHandler; + XMPP::ClientStream *stream; + BConsole *c; + XMPP::Jid jid; + QPtrList rootCerts; + + App(const XMPP::Jid &_jid, const XMPP::AdvancedConnector::Proxy &proxy, const QString &host, int port, bool opt_ssl, bool opt_probe) + :QObject(0) + { + c = 0; + jid = _jid; + + // Connector + conn = new XMPP::AdvancedConnector; + conn->setProxy(proxy); + if(!host.isEmpty()) + conn->setOptHostPort(host, port); + conn->setOptProbe(opt_probe); + conn->setOptSSL(opt_ssl); + + // TLSHandler + tls = 0; + tlsHandler = 0; + rootCerts.setAutoDelete(true); + if(QCA::isSupported(QCA::CAP_TLS)) { + rootCerts = getRootCerts(ROOTCERT_PATH); + tls = new QCA::TLS; + tls->setCertificateStore(rootCerts); + tlsHandler = new XMPP::QCATLSHandler(tls); + connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken())); + } + + // Stream + stream = new XMPP::ClientStream(conn, tlsHandler); + connect(stream, SIGNAL(connected()), SLOT(cs_connected())); + connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated())); + connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool))); + connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated())); + connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed())); + connect(stream, SIGNAL(readyRead()), SLOT(cs_readyRead())); + connect(stream, SIGNAL(stanzaWritten()), SLOT(cs_stanzaWritten())); + connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int))); + connect(stream, SIGNAL(error(int)), SLOT(cs_error(int))); + + fprintf(stderr, "conntest: Connecting ...\n"); + stream->setSSFRange(0, 256); + stream->connectToServer(jid); + } + + ~App() + { + delete stream; + delete tls; // this destroys the TLSHandler also + delete conn; + delete c; + } + +signals: + void quit(); + +private slots: + void tls_handshaken() + { + QCA::Cert cert = tls->peerCertificate(); + int vr = tls->certificateValidityResult(); + + fprintf(stderr, "conntest: Successful TLS handshake.\n"); + if(!cert.isNull()) + showCertInfo(cert); + if(vr == QCA::TLS::Valid) + fprintf(stderr, "conntest: Valid certificate.\n"); + else + fprintf(stderr, "conntest: Invalid certificate: %s\n", resultToString(vr).latin1()); + + tlsHandler->continueAfterHandshake(); + } + + void cs_connected() + { + fprintf(stderr, "conntest: Connected\n"); + } + + void cs_securityLayerActivated() + { + fprintf(stderr, "conntest: Security layer activated (%s)\n", tls->isHandshaken() ? "TLS": "SASL"); + } + + void cs_needAuthParams(bool user, bool pass, bool realm) + { + fprintf(stderr, "conntest: need auth params -"); + if(user) + fprintf(stderr, " (user)"); + if(pass) + fprintf(stderr, " (pass)"); + if(realm) + fprintf(stderr, " (realm)"); + fprintf(stderr, "\n"); + + if(user) + stream->setUsername(jid.node()); + if(pass) + stream->setPassword(prompt("Password (not hidden!) :")); + stream->continueAfterParams(); + } + + void cs_authenticated() + { + fprintf(stderr, "conntest: <<< Authenticated >>>\n"); + + // console + c = new BConsole; + connect(c, SIGNAL(connectionClosed()), SLOT(con_connectionClosed())); + connect(c, SIGNAL(readyRead()), SLOT(con_readyRead())); + } + + void cs_connectionClosed() + { + fprintf(stderr, "conntest: Disconnected by peer\n"); + quit(); + } + + void cs_readyRead() + { + for(XMPP::Stanza s; !(s = stream->read()).isNull();) { + QString str = s.toString(); + printf("%s\n", str.local8Bit().data()); + } + } + + void cs_stanzaWritten() + { + fprintf(stderr, "conntest: Stanza written\n"); + } + + void cs_warning(int warn) + { + if(warn == XMPP::ClientStream::WarnOldVersion) { + fprintf(stderr, "conntest: Warning: pre-1.0 protocol server\n"); + } + else if(warn == XMPP::ClientStream::WarnNoTLS) { + fprintf(stderr, "conntest: Warning: TLS not available!\n"); + } + stream->continueAfterWarning(); + } + + void cs_error(int err) + { + if(err == XMPP::ClientStream::ErrParse) { + fprintf(stderr, "conntest: XML parsing error\n"); + } + else if(err == XMPP::ClientStream::ErrProtocol) { + fprintf(stderr, "conntest: XMPP protocol error\n"); + } + else if(err == XMPP::ClientStream::ErrStream) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::Stream::GenericStreamError) + s = "generic stream error"; + else if(x == XMPP::ClientStream::Conflict) + s = "conflict (remote login replacing this one)"; + else if(x == XMPP::ClientStream::ConnectionTimeout) + s = "timed out from inactivity"; + else if(x == XMPP::ClientStream::InternalServerError) + s = "internal server error"; + else if(x == XMPP::ClientStream::InvalidXml) + s = "invalid XML"; + else if(x == XMPP::ClientStream::PolicyViolation) + s = "policy violation. go to jail!"; + else if(x == XMPP::ClientStream::ResourceConstraint) + s = "server out of resources"; + else if(x == XMPP::ClientStream::SystemShutdown) + s = "system is shutting down NOW"; + fprintf(stderr, "conntest: XMPP stream error: %s\n", s.latin1()); + } + else if(err == XMPP::ClientStream::ErrConnection) { + int x = conn->errorCode(); + QString s; + if(x == XMPP::AdvancedConnector::ErrConnectionRefused) + s = "unable to connect to server"; + else if(x == XMPP::AdvancedConnector::ErrHostNotFound) + s = "host not found"; + else if(x == XMPP::AdvancedConnector::ErrProxyConnect) + s = "proxy connect"; + else if(x == XMPP::AdvancedConnector::ErrProxyNeg) + s = "proxy negotiating"; + else if(x == XMPP::AdvancedConnector::ErrProxyAuth) + s = "proxy authorization"; + else if(x == XMPP::AdvancedConnector::ErrStream) + s = "stream error"; + fprintf(stderr, "conntest: connection error: %s\n", s.latin1()); + } + else if(err == XMPP::ClientStream::ErrNeg) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::HostGone) + s = "host no longer hosted"; + else if(x == XMPP::ClientStream::HostUnknown) + s = "host unknown"; + else if(x == XMPP::ClientStream::RemoteConnectionFailed) + s = "a required remote connection failed"; + else if(x == XMPP::ClientStream::SeeOtherHost) + s = QString("see other host: [%1]").arg(stream->errorText()); + else if(x == XMPP::ClientStream::UnsupportedVersion) + s = "server does not support proper xmpp version"; + fprintf(stderr, "conntest: stream negotiation error: %s\n", s.latin1()); + } + else if(err == XMPP::ClientStream::ErrTLS) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::TLSStart) + s = "server rejected STARTTLS"; + else if(x == XMPP::ClientStream::TLSFail) { + int t = tlsHandler->tlsError(); + if(t == QCA::TLS::ErrHandshake) + s = "TLS handshake error"; + else + s = "broken security layer (TLS)"; + } + fprintf(stderr, "conntest: %s\n", s.latin1()); + } + else if(err == XMPP::ClientStream::ErrAuth) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::GenericAuthError) + s = "unable to login"; + else if(x == XMPP::ClientStream::NoMech) + s = "no appropriate auth mechanism available for given security settings"; + else if(x == XMPP::ClientStream::BadProto) + s = "bad server response"; + else if(x == XMPP::ClientStream::BadServ) + s = "server failed mutual authentication"; + else if(x == XMPP::ClientStream::EncryptionRequired) + s = "encryption required for chosen SASL mechanism"; + else if(x == XMPP::ClientStream::InvalidAuthzid) + s = "invalid authzid"; + else if(x == XMPP::ClientStream::InvalidMech) + s = "invalid SASL mechanism"; + else if(x == XMPP::ClientStream::InvalidRealm) + s = "invalid realm"; + else if(x == XMPP::ClientStream::MechTooWeak) + s = "SASL mechanism too weak for authzid"; + else if(x == XMPP::ClientStream::NotAuthorized) + s = "not authorized"; + else if(x == XMPP::ClientStream::TemporaryAuthFailure) + s = "temporary auth failure"; + fprintf(stderr, "conntest: auth error: %s\n", s.latin1()); + } + else if(err == XMPP::ClientStream::ErrSecurityLayer) + fprintf(stderr, "conntest: broken security layer (SASL)\n"); + quit(); + } + + void con_connectionClosed() + { + fprintf(stderr, "conntest: Closing.\n"); + stream->close(); + quit(); + } + + void con_readyRead() + { + QByteArray a = c->read(); + QCString cs; + cs.resize(a.size()+1); + memcpy(cs.data(), a.data(), a.size()); + QString s = QString::fromLocal8Bit(cs); + stream->writeDirect(s); + } +}; + +#include "conntest.moc" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv, false); + + if(argc < 2) { + printf("usage: conntest [options] [jid]\n"); + printf(" Options:\n"); + printf(" --host=host:port\n"); + printf(" --sslhost=host:port\n"); + printf(" --probe\n"); + printf(" --proxy=[https|poll|socks],host:port,url\n"); + printf(" --proxy-auth=user,pass\n"); + printf("\n"); + return 0; + } + + bool have_tls = QCA::isSupported(QCA::CAP_TLS); + + XMPP::Jid jid; + XMPP::AdvancedConnector::Proxy proxy; + QString host; + int port = 0; + bool opt_ssl = false; + bool opt_probe = false; + + for(int at = 1; at < argc; ++at) { + QString s = argv[at]; + + // is it an option? + if(s.left(2) == "--") { + QString name; + QStringList args; + int n = s.find('=', 2); + if(n != -1) { + name = s.mid(2, n-2); + ++n; + args = QStringList::split(',', s.mid(n), true); + } + else { + name = s.mid(2); + args.clear(); + } + + // eat the arg + --argc; + for(int x = at; x < argc; ++x) + argv[x] = argv[x+1]; + --at; // don't advance + + // process option + if(name == "proxy") { + QString proxy_host; + int proxy_port = 0; + QString type = args[0]; + QString s = args[1]; + int n = s.find(':'); + if(n == -1) { + if(type != "poll") { + printf("Invalid host:port for proxy\n"); + return 0; + } + } + else { + proxy_host = s.mid(0, n); + ++n; + proxy_port = s.mid(n).toInt(); + } + + if(type == "https") { + proxy.setHttpConnect(proxy_host, proxy_port); + } + else if(type == "poll") { + if(args.count() < 3) { + printf("poll needs more args\n"); + return 0; + } + QString proxy_url = args[2]; + proxy.setHttpPoll(proxy_host, proxy_port, proxy_url); + } + else if(type == "socks") { + proxy.setSocks(proxy_host, proxy_port); + } + else { + printf("No such proxy type '%s'\n", type.latin1()); + return 0; + } + } + else if(name == "proxy-auth") { + proxy.setUserPass(args[0], args[1]); + } + else if(name == "host") { + QString s = args[0]; + int n = s.find(':'); + if(n == -1) { + printf("Invalid host:port for host\n"); + return 0; + } + host = s.mid(0, n); + ++n; + port = s.mid(n).toInt(); + } + else if(name == "sslhost") { + QString s = args[0]; + int n = s.find(':'); + if(n == -1) { + printf("Invalid host:port for host\n"); + return 0; + } + host = s.mid(0, n); + ++n; + port = s.mid(n).toInt(); + opt_ssl = true; + } + else if(name == "probe") { + opt_probe = true; + } + else { + printf("Unknown option '%s'\n", name.latin1()); + return 0; + } + } + } + + if(argc < 2) { + printf("No host specified!\n"); + return 0; + } + jid = argv[1]; + + if((opt_ssl || opt_probe) && !have_tls) { + printf("TLS not supported, so the sslhost and probe options are not allowed.\n"); + return 0; + } + + printf("JID: %s\n", jid.full().latin1()); + if(proxy.type() != XMPP::AdvancedConnector::Proxy::None) { + printf("Proxy: "); + if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpConnect) + printf("HttpConnect (%s:%d)", proxy.host().latin1(), proxy.port()); + else if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpPoll) { + printf("HttpPoll {%s}", proxy.url().latin1()); + if(!proxy.host().isEmpty()) { + printf(" (%s:%d)", proxy.host().latin1(), proxy.port()); + } + } + else if(proxy.type() == XMPP::AdvancedConnector::Proxy::Socks) + printf("Socks (%s:%d)", proxy.host().latin1(), proxy.port()); + printf("\n"); + } + if(proxy.type() != XMPP::AdvancedConnector::Proxy::HttpPoll) { + if(!host.isEmpty()) { + printf("Host: %s:%d", host.latin1(), port); + if(opt_ssl) + printf(" (ssl)"); + printf("\n"); + } + else { + if(opt_probe) + printf("Probe active\n"); + } + } + printf("----------\n"); + + App *a = new App(jid, proxy, host, port, opt_ssl, opt_probe); + QObject::connect(a, SIGNAL(quit()), &app, SLOT(quit())); + app.exec(); + delete a; + + return 0; +} diff --git a/iris-legacy/iris/example/conntest/conntest.pro b/iris-legacy/iris/example/conntest/conntest.pro new file mode 100644 index 0000000..44f4721 --- /dev/null +++ b/iris-legacy/iris/example/conntest/conntest.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +CONFIG += qt thread console +TARGET = conntest +QT += qt3support network xml + +# Dependencies +CONFIG += crypto +include(../../../cutestuff/cutestuff.pri) +include(../../iris.pri) +irisnet { + include(../../irisnet/irisnet.pri) +} + +SOURCES += conntest.cpp + diff --git a/iris-legacy/iris/example/conntest/conntest.qc b/iris-legacy/iris/example/conntest/conntest.qc new file mode 100644 index 0000000..afcdb84 --- /dev/null +++ b/iris-legacy/iris/example/conntest/conntest.qc @@ -0,0 +1,4 @@ + + Iris Conntest + conntest.pro + diff --git a/iris-legacy/iris/example/conntest/prepare b/iris-legacy/iris/example/conntest/prepare new file mode 100644 index 0000000..d3e8d32 --- /dev/null +++ b/iris-legacy/iris/example/conntest/prepare @@ -0,0 +1,30 @@ +#!/bin/sh + +CS_BASE=../../../cutestuff +QCA_BASE=../../../qca +IRIS_BASE=../.. + +# import cutestuff +mkdir cutestuff +cp -a $CS_BASE/util cutestuff +cp -a $CS_BASE/network cutestuff + +# import qca +mkdir qca +cp -a $QCA_BASE/src/* qca + +# import iris +mkdir iris +cp -a $IRIS_BASE/libidn iris +cp -a $IRIS_BASE/libidn.pri iris +cp -a $IRIS_BASE/include iris +cp -a $IRIS_BASE/xmpp-core iris +cp -a $IRIS_BASE/xmpp-im iris +cp -a $IRIS_BASE/jabber iris +cp -a $IRIS_BASE/iris.pri iris + +# other stuff +cp -a $IRIS_BASE/cs.pri . +cp -a $IRIS_BASE/example/example.pri . +cp -a $IRIS_BASE/COPYING . + diff --git a/iris-legacy/iris/example/server/server.cpp b/iris-legacy/iris/example/server/server.cpp new file mode 100644 index 0000000..4f4fdd3 --- /dev/null +++ b/iris-legacy/iris/example/server/server.cpp @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "bsocket.h" +#include "xmpp.h" + +#include + +char pemdata_cert[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIDbjCCAtegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhzELMAkGA1UEBhMCVVMx\n" + "EzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNVBAcTBklydmluZTEYMBYGA1UEChMP\n" + "RXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqGSIb3\n" + "DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTAeFw0wMzA3MjQwNzMwMDBaFw0wMzA4\n" + "MjMwNzMwMDBaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEP\n" + "MA0GA1UEBxMGSXJ2aW5lMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNV\n" + "BAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\n" + "Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobzCF268K2sRp473gvBTT\n" + "4AgSL1kjeF8N57vxS1P8zWrWMXNs4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwW\n" + "WZToesxebu3m9VeA8dqWyOaUMjoxAcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8m\n" + "a+AAPByfTORbzpSTmXAQAwIDAQABo4HnMIHkMB0GA1UdDgQWBBTvFierzLmmYMq0\n" + "cB/+5rK1bNR56zCBtAYDVR0jBIGsMIGpgBTvFierzLmmYMq0cB/+5rK1bNR566GB\n" + "jaSBijCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNV\n" + "BAcTBklydmluZTEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtl\n" + "eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbYIB\n" + "ADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGqGhXf7xNOnYNtFO7gz\n" + "K6RdZGHFI5q1DAEz4hhNBC9uElh32XGX4wN7giz3zLC8v9icL/W4ff/K5NDfv3Gf\n" + "gQe/+Wo9Be3H3ul6uwPPFnx4+PIOF2a5TW99H9smyxWdNjnFtcUte4al3RszcMWG\n" + "x3iqsWosGtj6F+ridmKoqKLu\n" + "-----END CERTIFICATE-----\n"; + +char pemdata_privkey[] = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXAIBAAKBgQCobzCF268K2sRp473gvBTT4AgSL1kjeF8N57vxS1P8zWrWMXNs\n" + "4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwWWZToesxebu3m9VeA8dqWyOaUMjox\n" + "AcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8ma+AAPByfTORbzpSTmXAQAwIDAQAB\n" + "AoGAP83u+aYghuIcaWhmM03MLf69z/WztKYSi/fu0BcS977w67bL3MC9CVPoPRB/\n" + "0nLSt/jZIuRzHKUCYfXLerSU7v0oXDTy6GPzWMh/oXIrpF0tYNbwWF7LSq2O2gGZ\n" + "XtA9MSmUNNJaKzQQeXjqdVFOY8A0Pho+k2KByBiCi+ChkcECQQDRUuyX0+PKJtA2\n" + "M36BOTFpy61BAv+JRlXUnHuevOfQWl6NR6YGygqCyH1sWtP1sa9S4wWys3DFH+5A\n" + "DkuAqk7zAkEAzf4eUH2hp5CIMsXH+WpIzKj09oY1it2CAKjVq4rUELf8iXvmGoFl\n" + "000spua4MjHNUYm7LR0QaKesKrMyGZUesQJAL8aLdYPJI+SD9Tr/jqLtIkZ4frQe\n" + "eshw4pvsoyheiHF3zyshO791crAr4EVCx3sMlxB1xnmqLXPCPyCEHxO//QJBAIBY\n" + "IYkjDZJ6ofGIe1UyXJNvfdkPu9J+ut4wU5jjEcgs6mK62J6RGuFxhy2iOQfFMdjo\n" + "yL+OCUg7mDCun7uCxrECQAtSvnLOFMjO5qExRjFtwi+b1rcSekd3Osk/izyRFSzg\n" + "Or+AL56/EKfiogNnFipgaXIbb/xj785Cob6v96XoW1I=\n" + "-----END RSA PRIVATE KEY-----\n"; + +QCA::Cert *cert; +QCA::RSAKey *privkey; + +using namespace XMPP; + +int id_num = 0; + +class Session : public QObject +{ + Q_OBJECT +public: + Session(const QString &host, const QString &defRealm, ByteStream *bs) : QObject(0) + { + id = id_num++; + + tls = new QCA::TLS; + tls->setCertificate(*cert, *privkey); + + cs = new ClientStream(host, defRealm, bs, tls); + connect(cs, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed())); + connect(cs, SIGNAL(error(int)), SLOT(cs_error(int))); + } + + ~Session() + { + delete cs; + delete tls; + printf("[%d]: deleted\n", id); + } + + void start() + { + printf("[%d]: New session!\n", id); + cs->accept(); + } + +signals: + void done(); + +private slots: + void cs_connectionClosed() + { + printf("[%d]: Connection closed by peer\n", id); + done(); + } + + void cs_error(int) + { + printf("[%d]: Error\n", id); + done(); + } + +private: + int id; + ClientStream *cs; + QCA::TLS *tls; +}; + +class ServerTest : public QServerSocket +{ + Q_OBJECT +public: + enum { Idle, Handshaking, Active, Closing }; + + ServerTest(const QString &_host, int _port) : QServerSocket(_port), host(_host), port(_port) + { + cert = new QCA::Cert; + privkey = new QCA::RSAKey; + + cert->fromPEM(pemdata_cert); + privkey->fromPEM(pemdata_privkey); + + list.setAutoDelete(true); + } + + ~ServerTest() + { + } + + void start() + { + char buf[256]; + int r = gethostname(buf, sizeof(buf)-1); + if(r == -1) { + printf("Error getting hostname!\n"); + QTimer::singleShot(0, this, SIGNAL(quit())); + return; + } + QString myhostname = buf; + + realm = myhostname; + if(host.isEmpty()) + host = myhostname; + + if(cert->isNull() || privkey->isNull()) { + printf("Error loading cert and/or private key!\n"); + QTimer::singleShot(0, this, SIGNAL(quit())); + return; + } + if(!ok()) { + printf("Error binding to port %d!\n", port); + QTimer::singleShot(0, this, SIGNAL(quit())); + return; + } + printf("Listening on %s:%d ...\n", host.latin1(), port); + } + + void newConnection(int s) + { + BSocket *bs = new BSocket; + bs->setSocket(s); + Session *sess = new Session(host, realm, bs); + list.append(sess); + connect(sess, SIGNAL(done()), SLOT(sess_done())); + sess->start(); + } + +signals: + void quit(); + +private slots: + void sess_done() + { + Session *sess = (Session *)sender(); + list.removeRef(sess); + } + +private: + QString host, realm; + int port; + QPtrList list; +}; + +#include "server.moc" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv, false); + QString host = argc > 1 ? QString(argv[1]) : QString(); + int port = argc > 2 ? QString(argv[2]).toInt() : 5222; + + if(!QCA::isSupported(QCA::CAP_TLS)) { + printf("TLS not supported!\n"); + return 1; + } + + if(!QCA::isSupported(QCA::CAP_SASL)) { + printf("SASL not supported!\n"); + return 1; + } + + srand(time(NULL)); + + ServerTest *s = new ServerTest(host, port); + QObject::connect(s, SIGNAL(quit()), &app, SLOT(quit())); + s->start(); + app.exec(); + delete s; + + // clean up + QCA::unloadAllPlugins(); + + return 0; +} diff --git a/iris-legacy/iris/example/server/server.pro b/iris-legacy/iris/example/server/server.pro new file mode 100644 index 0000000..4f2dc6f --- /dev/null +++ b/iris-legacy/iris/example/server/server.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +CONFIG += qt thread console +TARGET = server + +MOC_DIR = .moc +OBJECTS_DIR = .obj +UI_DIR = .ui + +include(../xmpptest/iris.pri) + +SOURCES += server.cpp + +# gentoo hack? +LIBS += -lcrypto + diff --git a/iris-legacy/iris/example/xmpptest/ui_test.ui b/iris-legacy/iris/example/xmpptest/ui_test.ui new file mode 100644 index 0000000..f199ee1 --- /dev/null +++ b/iris-legacy/iris/example/xmpptest/ui_test.ui @@ -0,0 +1,470 @@ + + + + + TestUI + + + + 0 + 0 + 652 + 591 + + + + Form1 + + + + + + + Core + + + + 0 + + + + + Server + + + + + + 0 + + + + + Full JID: + + + + + + + + + + + + 0 + + + + + User (if needed): + + + + + + + + + + + + + + Pass: + + + + + + + QLineEdit::Password + + + + + + + + + 0 + + + + + SSL + + + + + + + + None + + + + + HTTP(S) + + + + + SOCKS5 + + + + + HTTP Polling + + + + + + + + Host:Port: + + + + + + + Legacy SSL probe + + + + + + + Proxy: + + + + + + + + + + + + Proxy Settings + + + + + + Host:Port: + + + + + + + + + + User/Pass: + + + + + + + + + + / + + + + + + + QLineEdit::Password + + + + + + + Polling URL: + + + + + + + + + + + + + Security Settings + + + + + + Allow plaintext login + + + + + + + Require mutual authentication + + + + + + + 0 + + + + + SASL SSF min/max: + + + + + + + + + + / + + + + + + + + + + + + + + + + + + 0 + + + + + &Connect + + + Alt+C + + + + + + + + 130 + 20 + + + + Expanding + + + Horizontal + + + + + + + &About + + + + + + + + + + 20 + 16 + + + + Expanding + + + Vertical + + + + + + + Quick XML >> + + + + + + 0 + + + + + To: + + + + + + + + + + + + 0 + + + + + &IM Session + + + + + + + &Message + + + + + + + IQ &Version + + + + + + + + + + + + + IM + + + + + + + + 0 + + + + + + 300 + 0 + + + + AtWordOrDocumentBoundary + + + true + + + + + + + + 32767 + 200 + + + + + + + + 0 + + + + + + 40 + 20 + + + + Expanding + + + Horizontal + + + + + + + &Send + + + Alt+S + + + + + + + + + + + qPixmapFromMimeSource + + le_jid + le_user + le_pass + ck_probe + le_host + ck_ssl + cb_proxy + le_proxyhost + le_proxyuser + le_proxypass + le_proxyurl + ck_plain + ck_mutual + sb_ssfmin + sb_ssfmax + pb_go + pb_about + le_to + pb_im + pb_msg + pb_iqv + te_input + pb_send + te_log + + diff --git a/iris-legacy/iris/example/xmpptest/xmpptest.cpp b/iris-legacy/iris/example/xmpptest/xmpptest.cpp new file mode 100644 index 0000000..d3cd22f --- /dev/null +++ b/iris-legacy/iris/example/xmpptest/xmpptest.cpp @@ -0,0 +1,916 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//Added by qt3to4: +#include +#include +//#include +#include "xmpp.h" +#include "im.h" + +#include +#include + +#include "ui_ui_test.h" + +#include + +#define AppName "xmpptest" + +static QString plain2rich(const QString &plain) +{ + QString rich; + int col = 0; + + for(int i = 0; i < (int)plain.length(); ++i) { + if(plain[i] == '\n') { + rich += "
"; + col = 0; + } + else if(plain[i] == '\t') { + rich += QChar::nbsp; + while(col % 4) { + rich += QChar::nbsp; + ++col; + } + } + else if(plain[i].isSpace()) { + if(i > 0 && plain[i-1] == ' ') + rich += QChar::nbsp; + else + rich += ' '; + } + else if(plain[i] == '<') + rich += "<"; + else if(plain[i] == '>') + rich += ">"; + else if(plain[i] == '\"') + rich += """; + else if(plain[i] == '\'') + rich += "'"; + else if(plain[i] == '&') + rich += "&"; + else + rich += plain[i]; + ++col; + } + + return rich; +} + +/*static void showCertInfo(const QCA::Cert &cert) +{ + fprintf(stderr, "-- Cert --\n"); + fprintf(stderr, " CN: %s\n", cert.subject()["CN"].latin1()); + fprintf(stderr, " Valid from: %s, until %s\n", + cert.notBefore().toString().latin1(), + cert.notAfter().toString().latin1()); + fprintf(stderr, " PEM:\n%s\n", cert.toPEM().latin1()); +}*/ + +static QString resultToString(int result) +{ + QString s; + switch(result) { + case QCA::TLS::NoCertificate: + s = QObject::tr("No certificate presented."); + break; + case QCA::TLS::Valid: + break; + case QCA::TLS::HostMismatch: + s = QObject::tr("Hostname mismatch."); + break; + case QCA::TLS::InvalidCertificate: + s = QObject::tr("Invalid Certificate."); + break; + // TODO: Inspect why +// case QCA::TLS::Untrusted: +// s = QObject::tr("Not trusted for the specified purpose."); +// break; +// case QCA::TLS::SignatureFailed: +// s = QObject::tr("Invalid signature."); +// break; +// case QCA::TLS::InvalidCA: +// s = QObject::tr("Invalid CA certificate."); +// break; +// case QCA::TLS::InvalidPurpose: +// s = QObject::tr("Invalid certificate purpose."); +// break; +// case QCA::TLS::SelfSigned: +// s = QObject::tr("Certificate is self-signed."); +// break; +// case QCA::TLS::Revoked: +// s = QObject::tr("Certificate has been revoked."); +// break; +// case QCA::TLS::PathLengthExceeded: +// s = QObject::tr("Maximum cert chain length exceeded."); +// break; +// case QCA::TLS::Expired: +// s = QObject::tr("Certificate has expired."); +// break; +// case QCA::TLS::Unknown: + default: + s = QObject::tr("General validation error."); + break; + } + return s; +} + +class TestDebug : public XMPP::Debug +{ +public: + void msg(const QString &); + void outgoingTag(const QString &); + void incomingTag(const QString &); + void outgoingXml(const QDomElement &); + void incomingXml(const QDomElement &); +}; + +class TestDlg : public QDialog, public Ui::TestUI +{ + Q_OBJECT +public: + bool active, connected; + XMPP::AdvancedConnector *conn; + QCA::TLS *tls; + XMPP::QCATLSHandler *tlsHandler; + XMPP::ClientStream *stream; + XMPP::Jid jid; + + TestDlg(QWidget *parent=0) : QDialog(parent) + { + setupUi(this); + setWindowTitle(tr("XMPP Test")); + + connect(ck_probe, SIGNAL(toggled(bool)), SLOT(probe_toggled(bool))); + connect(cb_proxy, SIGNAL(activated(int)), SLOT(proxy_activated(int))); + connect(pb_go, SIGNAL(clicked()), SLOT(go())); + connect(pb_send, SIGNAL(clicked()), SLOT(send())); + connect(pb_im, SIGNAL(clicked()), SLOT(sc_im())); + connect(pb_msg, SIGNAL(clicked()), SLOT(sc_msg())); + connect(pb_iqv, SIGNAL(clicked()), SLOT(sc_iqv())); + connect(pb_about, SIGNAL(clicked()), SLOT(about())); + + sb_ssfmin->setMinValue(0); + sb_ssfmin->setMaxValue(256); + sb_ssfmax->setMinValue(0); + sb_ssfmax->setMaxValue(256); + + pb_send->setEnabled(false); + proxy_activated(0); + ck_probe->setChecked(true); + ck_mutual->setChecked(false); + pb_go->setText(tr("&Connect")); + + //le_jid->setText("psitest@jabberd.jabberstudio.org/Test"); + //ck_probe->setChecked(false); + //le_host->setText("jabberd.jabberstudio.org:15222"); + //ck_mutual->setChecked(false); + //le_jid->setText("sasltest@e.jabber.ru/Test"); + //le_jid->setText("psitest@jabber.cz/Test"); + //le_pass->setText("psitest"); + //cb_proxy->setCurrentItem(3); + //le_proxyurl->setText("http://connect.jabber.cz/"); + + // setup xmpp + conn = new XMPP::AdvancedConnector; + connect(conn, SIGNAL(srvLookup(const QString &)), SLOT(conn_srvLookup(const QString &))); + connect(conn, SIGNAL(srvResult(bool)), SLOT(conn_srvResult(bool))); + connect(conn, SIGNAL(httpSyncStarted()), SLOT(conn_httpSyncStarted())); + connect(conn, SIGNAL(httpSyncFinished()), SLOT(conn_httpSyncFinished())); + + if(QCA::isSupported("tls")) { + tls = new QCA::TLS; + tlsHandler = new XMPP::QCATLSHandler(tls); + tlsHandler->setXMPPCertCheck(true); + connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken())); + } + else { + tls = 0; + tlsHandler = 0; + } + + stream = new XMPP::ClientStream(conn, tlsHandler); + //stream->setOldOnly(true); + connect(stream, SIGNAL(connected()), SLOT(cs_connected())); + connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated(int))); + connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool))); + connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated())); + connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed())); + connect(stream, SIGNAL(delayedCloseFinished()), SLOT(cs_delayedCloseFinished())); + connect(stream, SIGNAL(readyRead()), SLOT(cs_readyRead())); + connect(stream, SIGNAL(stanzaWritten()), SLOT(cs_stanzaWritten())); + connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int))); + connect(stream, SIGNAL(error(int)), SLOT(cs_error(int))); + + QTimer::singleShot(0, this, SLOT(adjustLayout())); + + le_jid->setFocus(); + active = false; + connected = false; + } + + ~TestDlg() + { + delete stream; + delete tls; // this destroys the TLSHandler also + delete conn; + } + +private slots: + void adjustLayout() + { + tb_main->setFixedWidth(tb_main->minimumSizeHint().width()); + resize(minimumSizeHint()); + show(); + } + + void about() + { + QMessageBox::about(this, tr("About %1").arg(AppName), tr( + "%1 v1.0\n" + "\n" + "Utility to demonstrate the Iris XMPP library.\n" + "\n" + "Currently supports:\n" + " draft-ietf-xmpp-core-21\n" + " JEP-0025\n" + "\n" + "Copyright (C) 2003 Justin Karneges").arg(AppName)); + } + + void probe_toggled(bool) + { + setHostState(); + } + + void proxy_activated(int x) + { + bool ok = (x != 0); + bool okpoll = (x == 3); + gb_proxy->setEnabled(ok); + lb_proxyurl->setEnabled(okpoll); + le_proxyurl->setEnabled(okpoll); + ck_probe->setEnabled(!okpoll); + setHostState(); + } + + void cleanup() + { + pb_send->setEnabled(false); + pb_go->setEnabled(true); + pb_go->setText(tr("&Connect")); + pb_go->setFocus(); + gb_server->setEnabled(true); + active = false; + connected = false; + } + + void start() + { + if(active) + return; + + jid = XMPP::Jid(le_jid->text()); + if(jid.domain().isEmpty() || jid.node().isEmpty() || jid.resource().isEmpty()) { + QMessageBox::information(this, tr("Error"), tr("Please enter the Full JID to connect with.")); + return; + } + + int p = cb_proxy->currentItem(); + XMPP::AdvancedConnector::Proxy proxy; + if(p > 0) { + QString s = le_proxyhost->text(); + QString url = le_proxyurl->text(); + if(p != 3 && s.isEmpty()) { + QMessageBox::information(this, tr("Error"), tr("You must specify a host:port for the proxy.")); + return; + } + if(p == 3 && s.isEmpty() && url.isEmpty()) { + QMessageBox::information(this, tr("Error"), tr("You must at least enter a URL to use http poll.")); + return; + } + QString host; + int port = 0; + if(!s.isEmpty()) { + int n = s.find(':'); + if(n == -1) { + QMessageBox::information(this, tr("Error"), tr("Please enter the proxy host in the form 'host:port'.")); + return; + } + host = s.mid(0, n); + port = s.mid(n+1).toInt(); + } + if(p == 1) + proxy.setHttpConnect(host, port); + else if(p == 2) + proxy.setSocks(host, port); + else if(p == 3) { + proxy.setHttpPoll(host, port, url); + proxy.setPollInterval(2); // fast during login + } + proxy.setUserPass(le_proxyuser->text(), le_proxypass->text()); + } + bool probe = (p != 3 && ck_probe->isChecked()); + bool useHost = (!probe && !le_host->text().isEmpty()); + QString host; + int port = 0; + bool ssl = false; + if(useHost) { + QString s = le_host->text(); + int n = s.find(':'); + if(n == -1) { + QMessageBox::information(this, tr("Error"), tr("Please enter the host in the form 'host:port'.")); + return; + } + host = s.mid(0, n); + port = s.mid(n+1).toInt(); + + if(ck_ssl->isChecked()) + ssl = true; + } + if(sb_ssfmin->value() > sb_ssfmax->value()) { + QMessageBox::information(this, tr("Error"), tr("Error: SSF Min is greater than SSF Max.")); + return; + } + + if((probe || ssl) && !tls) { + QMessageBox::information(this, tr("Error"), tr("Error: TLS not available. Disable any TLS options.")); + return; + } + + // prepare + conn->setProxy(proxy); + if(useHost) + conn->setOptHostPort(host, port); + else + conn->setOptHostPort("", 0); + conn->setOptProbe(probe); + conn->setOptSSL(ssl); + + if(tls) { + tls->setTrustedCertificates(QCA::systemStore()); + } + + stream->setNoopTime(55000); // every 55 seconds + stream->setAllowPlain(ck_plain->isChecked() ? XMPP::ClientStream::AllowPlain : XMPP::ClientStream::NoAllowPlain); + stream->setRequireMutualAuth(ck_mutual->isChecked()); + stream->setSSFRange(sb_ssfmin->value(), sb_ssfmax->value()); + //stream->setOldOnly(true); + stream->setCompress(true); + + gb_server->setEnabled(false); + pb_go->setText(tr("&Disconnect")); + pb_go->setFocus(); + active = true; + + appendSysMsg("Connecting..."); + stream->connectToServer(jid); + } + + void stop() + { + if(!active) + return; + + if(connected) { + pb_go->setEnabled(false); + appendSysMsg("Disconnecting..."); + stream->close(); + } + else { + stream->close(); + appendSysMsg("Disconnected"); + cleanup(); + } + } + + void go() + { + if(active) + stop(); + else + start(); + } + + void send() + { + if(te_input->text().isEmpty()) + return; + + // construct a "temporary" document to parse the input + QString str = "\n"; + str += te_input->text() + '\n'; + str += ""; + + QDomDocument doc; + QString errMsg; + int errLine, errCol; + if(!doc.setContent(str, true, &errMsg, &errLine, &errCol)) { + int lines = QStringList::split('\n', str, true).count(); + --errLine; // skip the first line + if(errLine == lines-1) { + errLine = lines-2; + errCol = te_input->paragraphLength(errLine-1)+1; + errMsg = "incomplete input"; + } + te_input->setCursorPosition(errLine-1, errCol-1); + QMessageBox::information(this, tr("Error"), tr("Bad XML input (%1,%2): %3\nPlease correct and try again.").arg(errCol).arg(errLine).arg(errMsg)); + return; + } + QDomElement e = doc.firstChild().toElement(); + + int num = 0; + QDomNodeList nl = e.childNodes(); + QList stanzaList; + for(uint x = 0; x < nl.count(); ++x) { + QDomNode n = nl.item(x); + if(n.isElement()) { + QDomElement e = n.toElement(); + XMPP::Stanza s = stream->createStanza(e); + if(s.isNull()) { + QMessageBox::information(this, tr("Error"), tr("Bad Stanza '%1'. Must be 'message', 'presence', or 'iq'").arg(e.tagName())); + return; + } + stanzaList += s; + ++num; + } + } + if(num == 0) { + QMessageBox::information(this, tr("Error"), tr("You must enter at least one stanza!")); + return; + } + + // out the door + for(QList::ConstIterator it = stanzaList.begin(); it != stanzaList.end(); ++it) { + appendXmlOut(XMPP::Stream::xmlToString((*it).element(), true)); + stream->write(*it); + } + + te_input->setText(""); + } + + void sc_im() + { + /*XMPP::Message m("justin@andbit.net/Psi"); + m.setSubject("Hi"); + m.setBody("I send you this in order to have your advice."); + m.setBody("Escucha lechuga!", "es"); + XMPP::Stanza stanza = m.toStanza(stream); + QString str = stanza.toString(); + printf("[%s]\n", str.latin1()); + + XMPP::Message n; + n.fromStanza(stanza); + printf("subject: [%s]\n", n.subject().latin1()); + printf("body: [%s]\n", n.body().latin1()); + printf("body-es: [%s]\n", n.body("es").latin1());*/ + + QString s; + s += "\n"; + s += " \n"; + s += ""; + te_input->setText(s); + te_input->setFocus(); + } + + void sc_msg() + { + QString to = le_to->text(); + QString s; + if(!to.isEmpty()) + s += QString("\n").arg(to); + else + s += QString("\n"); + s += " hello world\n"; + s += ""; + te_input->setText(s); + if(!to.isEmpty()) { + te_input->setCursorPosition(1, 7); + te_input->setSelection(1, 7, 1, 18); + } + else + te_input->setCursorPosition(0, 13); + te_input->setFocus(); + } + + void sc_iqv() + { + QString to = le_to->text(); + QString s; + if(!to.isEmpty()) + s += QString("\n").arg(to); + else + s += QString("\n"); + s += " \n"; + s += ""; + te_input->setText(s); + if(!to.isEmpty()) { + te_input->setCursorPosition(0, 8); + te_input->setSelection(0, 8, 0, 8 + to.length()); + } + else + te_input->setCursorPosition(0, 8); + te_input->setFocus(); + } + + void conn_srvLookup(const QString &server) + { + appendLibMsg(QString("SRV lookup on [%1]").arg(server)); + } + + void conn_srvResult(bool b) + { + if(b) + appendLibMsg("SRV lookup success!"); + else + appendLibMsg("SRV lookup failed"); + } + + void conn_httpSyncStarted() + { + appendLibMsg("HttpPoll: syncing"); + } + + void conn_httpSyncFinished() + { + appendLibMsg("HttpPoll: done"); + } + + void tls_handshaken() + { + //QCA::Certificate cert = tls->peerCertificate(); + int vr = tls->peerIdentityResult(); + if (vr == QCA::TLS::Valid && !tlsHandler->certMatchesHostname()) vr = QCA::TLS::HostMismatch; + + appendSysMsg("Successful TLS handshake."); + if(vr == QCA::TLS::Valid) + appendSysMsg("Valid certificate."); + else { + appendSysMsg(QString("Invalid certificate: %1").arg(resultToString(vr)), Qt::red); + appendSysMsg("Continuing anyway"); + } + + tlsHandler->continueAfterHandshake(); + } + + void cs_connected() + { + QString s = "Connected"; + if(conn->havePeerAddress()) + s += QString(" (%1:%2)").arg(conn->peerAddress().toString()).arg(conn->peerPort()); + if(conn->useSSL()) + s += " [ssl]"; + appendSysMsg(s); + } + + void cs_securityLayerActivated(int type) + { + appendSysMsg(QString("Security layer activated (%1)").arg((type == XMPP::ClientStream::LayerTLS) ? "TLS": "SASL")); + } + + void cs_needAuthParams(bool user, bool pass, bool realm) + { + QString s = "Need auth parameters -"; + if(user) + s += " (Username)"; + if(pass) + s += " (Password)"; + if(realm) + s += " (Realm)"; + appendSysMsg(s); + + if(user) { + if(!le_user->text().isEmpty()) + stream->setUsername(le_user->text()); + else + stream->setUsername(jid.node()); + } + if(pass) { + if(!le_pass->text().isEmpty()) + stream->setPassword(le_pass->text()); + else { + conn->changePollInterval(10); // slow down during prompt + bool ok; + QString s = QInputDialog::getText(tr("Password"), tr("Enter the password for %1").arg(jid.full()), QLineEdit::Password, QString::null, &ok, this); + if(!ok) { + stop(); + return; + } + stream->setPassword(s); + + conn->changePollInterval(2); // resume speed + } + } + if(realm) + stream->setRealm(jid.domain()); + + stream->continueAfterParams(); + } + + void cs_authenticated() + { + connected = true; + pb_send->setEnabled(true); + conn->changePollInterval(10); // slow down after login + appendSysMsg("Authenticated"); + } + + void cs_connectionClosed() + { + appendSysMsg("Disconnected by peer"); + cleanup(); + } + + void cs_delayedCloseFinished() + { + appendSysMsg("Disconnected"); + cleanup(); + } + + void cs_readyRead() + { + while(stream->stanzaAvailable()) { + XMPP::Stanza s = stream->read(); + appendXmlIn(XMPP::Stream::xmlToString(s.element(), true)); + } + } + + void cs_stanzaWritten() + { + appendSysMsg("Stanza sent"); + } + + void cs_warning(int warn) + { + if(warn == XMPP::ClientStream::WarnOldVersion) { + appendSysMsg("Warning: pre-1.0 protocol server", Qt::red); + } + else if(warn == XMPP::ClientStream::WarnNoTLS) { + appendSysMsg("Warning: TLS not available!", Qt::red); + } + stream->continueAfterWarning(); + } + + void cs_error(int err) + { + if(err == XMPP::ClientStream::ErrParse) { + appendErrMsg("XML parsing error"); + } + else if(err == XMPP::ClientStream::ErrProtocol) { + appendErrMsg("XMPP protocol error"); + } + else if(err == XMPP::ClientStream::ErrStream) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::Stream::GenericStreamError) + s = "generic stream error"; + else if(x == XMPP::ClientStream::Conflict) + s = "conflict (remote login replacing this one)"; + else if(x == XMPP::ClientStream::ConnectionTimeout) + s = "timed out from inactivity"; + else if(x == XMPP::ClientStream::InternalServerError) + s = "internal server error"; + else if(x == XMPP::ClientStream::InvalidFrom) + s = "invalid from address"; + else if(x == XMPP::ClientStream::InvalidXml) + s = "invalid XML"; + else if(x == XMPP::ClientStream::PolicyViolation) + s = "policy violation. go to jail!"; + else if(x == XMPP::ClientStream::ResourceConstraint) + s = "server out of resources"; + else if(x == XMPP::ClientStream::SystemShutdown) + s = "system is shutting down NOW"; + appendErrMsg(QString("XMPP stream error: %1").arg(s)); + } + else if(err == XMPP::ClientStream::ErrConnection) { + int x = conn->errorCode(); + QString s; + if(x == XMPP::AdvancedConnector::ErrConnectionRefused) + s = "unable to connect to server"; + else if(x == XMPP::AdvancedConnector::ErrHostNotFound) + s = "host not found"; + else if(x == XMPP::AdvancedConnector::ErrProxyConnect) + s = "proxy connect"; + else if(x == XMPP::AdvancedConnector::ErrProxyNeg) + s = "proxy negotiating"; + else if(x == XMPP::AdvancedConnector::ErrProxyAuth) + s = "proxy authorization"; + else if(x == XMPP::AdvancedConnector::ErrStream) + s = "stream error"; + appendErrMsg(QString("Connection error: %1").arg(s)); + } + else if(err == XMPP::ClientStream::ErrNeg) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::HostGone) + s = "host no longer hosted"; + else if(x == XMPP::ClientStream::HostUnknown) + s = "host unknown"; + else if(x == XMPP::ClientStream::RemoteConnectionFailed) + s = "a required remote connection failed"; + else if(x == XMPP::ClientStream::SeeOtherHost) + s = QString("see other host: [%1]").arg(stream->errorText()); + else if(x == XMPP::ClientStream::UnsupportedVersion) + s = "server does not support proper xmpp version"; + appendErrMsg(QString("Stream negotiation error: %1").arg(s)); + } + else if(err == XMPP::ClientStream::ErrTLS) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::TLSStart) + s = "server rejected STARTTLS"; + else if(x == XMPP::ClientStream::TLSFail) { + int t = tlsHandler->tlsError(); + if(t == QCA::TLS::ErrorHandshake) + s = "TLS handshake error"; + else + s = "broken security layer (TLS)"; + } + appendErrMsg(s); + } + else if(err == XMPP::ClientStream::ErrAuth) { + int x = stream->errorCondition(); + QString s; + if(x == XMPP::ClientStream::GenericAuthError) + s = "unable to login"; + else if(x == XMPP::ClientStream::NoMech) + s = "no appropriate auth mechanism available for given security settings"; + else if(x == XMPP::ClientStream::BadProto) + s = "bad server response"; + else if(x == XMPP::ClientStream::BadServ) + s = "server failed mutual authentication"; + else if(x == XMPP::ClientStream::EncryptionRequired) + s = "encryption required for chosen SASL mechanism"; + else if(x == XMPP::ClientStream::InvalidAuthzid) + s = "invalid authzid"; + else if(x == XMPP::ClientStream::InvalidMech) + s = "invalid SASL mechanism"; + else if(x == XMPP::ClientStream::InvalidRealm) + s = "invalid realm"; + else if(x == XMPP::ClientStream::MechTooWeak) + s = "SASL mechanism too weak for authzid"; + else if(x == XMPP::ClientStream::NotAuthorized) + s = "not authorized"; + else if(x == XMPP::ClientStream::TemporaryAuthFailure) + s = "temporary auth failure"; + appendErrMsg(QString("Auth error: %1").arg(s)); + } + else if(err == XMPP::ClientStream::ErrSecurityLayer) + appendErrMsg("Broken security layer (SASL)"); + cleanup(); + } + +private: + void setHostState() + { + bool ok = false; + if(!ck_probe->isChecked() && cb_proxy->currentItem() != 3) + ok = true; + lb_host->setEnabled(ok); + le_host->setEnabled(ok); + ck_ssl->setEnabled(ok); + } + + void appendSysMsg(const QString &s, const QColor &_c=QColor()) + { + QString str; + QColor c; + if(_c.isValid()) + c = _c; + else + c = Qt::blue; + + if(c.isValid()) + str += QString("").arg(c.name()); + str += QString("*** %1").arg(s); + if(c.isValid()) + str += QString(""); + te_log->append(str); + } + +public: + void appendLibMsg(const QString &s) + { + appendSysMsg(s, Qt::magenta); + } + + void appendErrMsg(const QString &s) + { + appendSysMsg(s, Qt::red); + } + + void appendXmlOut(const QString &s) + { + QStringList lines = QStringList::split('\n', s, true); + QString str; + bool first = true; + for(QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it) { + if(!first) + str += "
"; + str += QString("%2").arg(QColor(Qt::darkGreen).name()).arg(plain2rich(*it)); + first = false; + } + te_log->append(str); + } + + void appendXmlIn(const QString &s) + { + QStringList lines = QStringList::split('\n', s, true); + QString str; + bool first = true; + for(QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it) { + if(!first) + str += "
"; + str += QString("%2").arg(QColor(Qt::darkBlue).name()).arg(plain2rich(*it)); + first = false; + } + te_log->append(str); + } +}; + +TestDlg *td_glob = 0; + +void TestDebug::msg(const QString &s) +{ + if(td_glob) + td_glob->appendLibMsg(s); +} + +void TestDebug::outgoingTag(const QString &s) +{ + if(td_glob) + td_glob->appendXmlOut(s); +} + +void TestDebug::incomingTag(const QString &s) +{ + if(td_glob) + td_glob->appendXmlIn(s); +} + +void TestDebug::outgoingXml(const QDomElement &e) +{ + QString out = XMPP::Stream::xmlToString(e, true); + if(td_glob) + td_glob->appendXmlOut(out); +} + +void TestDebug::incomingXml(const QDomElement &e) +{ + QString out = XMPP::Stream::xmlToString(e, true); + if(td_glob) + td_glob->appendXmlIn(out); +} + +#include "xmpptest.moc" + +int main(int argc, char **argv) +{ + QCA::Initializer init; + +#ifdef Q_OS_WIN32 + QApplication::addLibraryPath("."); + putenv("SASL_PATH=.\\sasl"); +#endif + QApplication app(argc, argv); + + // seed the random number generator (needed at least for HttpPoll) + srand(time(NULL)); + + TestDlg *w = new TestDlg(0); + td_glob = w; + TestDebug *td = new TestDebug; + XMPP::setDebug(td); + QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); + app.exec(); + XMPP::setDebug(0); + delete td; + delete w; + + // we need this for a clean exit + QCA::unloadAllPlugins(); + + return 0; +} + +#ifdef QCA_STATIC +#include +#ifdef HAVE_OPENSSL +Q_IMPORT_PLUGIN(qca_openssl) +#endif +#endif diff --git a/iris-legacy/iris/example/xmpptest/xmpptest.pro b/iris-legacy/iris/example/xmpptest/xmpptest.pro new file mode 100644 index 0000000..f9cd363 --- /dev/null +++ b/iris-legacy/iris/example/xmpptest/xmpptest.pro @@ -0,0 +1,41 @@ +TEMPLATE = app +CONFIG += thread +CONFIG -= app_bundle +TARGET = xmpptest +QT += xml network qt3support +DEFINES += QT_STATICPLUGIN + +MOC_DIR = .moc +OBJECTS_DIR = .obj +UI_DIR = .ui + +#DEFINES += CS_XMPP +DEFINES += XMPP_DEBUG + +# Dependencies +include(../../../conf.pri) +windows:include(../../../conf_windows.pri) + +!qca-static { + CONFIG += crypto +} +qca-static { + # QCA + DEFINES += QCA_STATIC + include(../../../third-party/qca/qca.pri) + + # QCA-OpenSSL + contains(DEFINES, HAVE_OPENSSL) { + include(../../../third-party/qca/qca-openssl.pri) + } +} + +include(../../../cutestuff/cutestuff.pri) +include(../../iris.pri) +irisnet { + include(../../irisnet/irisnet.pri) +} + +SOURCES += xmpptest.cpp +INTERFACES += ui_test.ui + diff --git a/iris-legacy/iris/include/im.h b/iris-legacy/iris/include/im.h new file mode 100644 index 0000000..a570fb0 --- /dev/null +++ b/iris-legacy/iris/include/im.h @@ -0,0 +1,133 @@ +/* + * im.h - XMPP "IM" library API + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_IM_H +#define XMPP_IM_H + +#include +//Added by qt3to4: +#include + +#include "xmpp.h" +#include "xmpp_jid.h" +#include "xmpp_muc.h" +#include "xmpp_message.h" +#include "xmpp_chatstate.h" +#include "xmpp_status.h" +#include "xmpp_htmlelement.h" +#include "xmpp_features.h" +#include "xmpp_httpauthrequest.h" +#include "xmpp_url.h" +#include "xmpp_task.h" +#include "xmpp_resource.h" +#include "xmpp_resourcelist.h" +#include "xmpp_roster.h" +#include "xmpp_rosteritem.h" +#include "xmpp_liverosteritem.h" +#include "xmpp_liveroster.h" +#include "xmpp_rosterx.h" +#include "xmpp_xdata.h" +#include "xmpp_discoitem.h" +#include "xmpp_agentitem.h" +#include "xmpp_client.h" +#include "xmpp_address.h" +#include "xmpp_pubsubitem.h" +#include "xmpp_pubsubretraction.h" + +namespace XMPP +{ + typedef QMap StringMap; + + typedef QList AgentList; + typedef QList DiscoList; + + class FormField + { + public: + enum { username, nick, password, name, first, last, email, address, city, state, zip, phone, url, date, misc }; + FormField(const QString &type="", const QString &value=""); + ~FormField(); + + int type() const; + QString fieldName() const; + QString realName() const; + bool isSecret() const; + const QString & value() const; + void setType(int); + bool setType(const QString &); + void setValue(const QString &); + + private: + int tagNameToType(const QString &) const; + QString typeToTagName(int) const; + + int v_type; + QString v_value; + + class Private; + Private *d; + }; + + class Form : public QList + { + public: + Form(const Jid &j=""); + ~Form(); + + Jid jid() const; + QString instructions() const; + QString key() const; + void setJid(const Jid &); + void setInstructions(const QString &); + void setKey(const QString &); + + private: + Jid v_jid; + QString v_instructions, v_key; + + class Private; + Private *d; + }; + + class SearchResult + { + public: + SearchResult(const Jid &jid=""); + ~SearchResult(); + + const Jid & jid() const; + const QString & nick() const; + const QString & first() const; + const QString & last() const; + const QString & email() const; + + void setJid(const Jid &); + void setNick(const QString &); + void setFirst(const QString &); + void setLast(const QString &); + void setEmail(const QString &); + + private: + Jid v_jid; + QString v_nick, v_first, v_last, v_email; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp.h b/iris-legacy/iris/include/xmpp.h new file mode 100644 index 0000000..b9fb959 --- /dev/null +++ b/iris-legacy/iris/include/xmpp.h @@ -0,0 +1,235 @@ +/* + * xmpp.h - XMPP "core" library API + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_H +#define XMPP_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xmpp_jid.h" +#include "xmpp_stanza.h" +#include "xmpp_stream.h" +#include "xmpp_clientstream.h" + +namespace QCA +{ + class TLS; +}; + +#ifndef CS_XMPP +class ByteStream; +#endif + +#include // For QCA::SASL::Params + +namespace XMPP +{ + // CS_IMPORT_BEGIN cutestuff/bytestream.h +#ifdef CS_XMPP + class ByteStream; +#endif + // CS_IMPORT_END + + class Debug + { + public: + virtual ~Debug(); + + virtual void msg(const QString &)=0; + virtual void outgoingTag(const QString &)=0; + virtual void incomingTag(const QString &)=0; + virtual void outgoingXml(const QDomElement &)=0; + virtual void incomingXml(const QDomElement &)=0; + }; + + void setDebug(Debug *); + + class Connector : public QObject + { + Q_OBJECT + public: + Connector(QObject *parent=0); + virtual ~Connector(); + + virtual void connectToServer(const QString &server)=0; + virtual ByteStream *stream() const=0; + virtual void done()=0; + + bool useSSL() const; + bool havePeerAddress() const; + QHostAddress peerAddress() const; + Q_UINT16 peerPort() const; + + signals: + void connected(); + void error(); + + protected: + void setUseSSL(bool b); + void setPeerAddressNone(); + void setPeerAddress(const QHostAddress &addr, Q_UINT16 port); + + private: + bool ssl; + bool haveaddr; + QHostAddress addr; + Q_UINT16 port; + }; + + class AdvancedConnector : public Connector + { + Q_OBJECT + public: + enum Error { ErrConnectionRefused, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth, ErrStream }; + AdvancedConnector(QObject *parent=0); + virtual ~AdvancedConnector(); + + class Proxy + { + public: + enum { None, HttpConnect, HttpPoll, Socks }; + Proxy(); + ~Proxy(); + + int type() const; + QString host() const; + Q_UINT16 port() const; + QString url() const; + QString user() const; + QString pass() const; + int pollInterval() const; + + void setHttpConnect(const QString &host, Q_UINT16 port); + void setHttpPoll(const QString &host, Q_UINT16 port, const QString &url); + void setSocks(const QString &host, Q_UINT16 port); + void setUserPass(const QString &user, const QString &pass); + void setPollInterval(int secs); + + private: + int t; + QString v_host, v_url; + Q_UINT16 v_port; + QString v_user, v_pass; + int v_poll; + }; + + void setProxy(const Proxy &proxy); + void setOptHostPort(const QString &host, Q_UINT16 port); + void setOptProbe(bool); + void setOptSSL(bool); + + void changePollInterval(int secs); + + void connectToServer(const QString &server); + ByteStream *stream() const; + void done(); + + int errorCode() const; + + signals: + void srvLookup(const QString &server); + void srvResult(bool success); + void httpSyncStarted(); + void httpSyncFinished(); + + private slots: + void dns_done(); + void srv_done(); + void bs_connected(); + void bs_error(int); + void http_syncStarted(); + void http_syncFinished(); + + private: + class Private; + Private *d; + + void cleanup(); + void do_resolve(); + void do_connect(); + void tryNextSrv(); + }; + + class TLSHandler : public QObject + { + Q_OBJECT + public: + TLSHandler(QObject *parent=0); + virtual ~TLSHandler(); + + virtual void reset()=0; + virtual void startClient(const QString &host)=0; + virtual void write(const QByteArray &a)=0; + virtual void writeIncoming(const QByteArray &a)=0; + + signals: + void success(); + void fail(); + void closed(); + void readyRead(const QByteArray &a); + void readyReadOutgoing(const QByteArray &a, int plainBytes); + }; + + class QCATLSHandler : public TLSHandler + { + Q_OBJECT + public: + QCATLSHandler(QCA::TLS *parent); + ~QCATLSHandler(); + + QCA::TLS *tls() const; + int tlsError() const; + + void setXMPPCertCheck(bool enable); + bool XMPPCertCheck(); + bool certMatchesHostname(); + + void reset(); + void startClient(const QString &host); + void write(const QByteArray &a); + void writeIncoming(const QByteArray &a); + + signals: + void tlsHandshaken(); + + public slots: + void continueAfterHandshake(); + + private slots: + void tls_handshaken(); + void tls_readyRead(); + void tls_readyReadOutgoing(); + void tls_closed(); + void tls_error(); + + private: + class Private; + Private *d; + }; +}; + +#endif diff --git a/iris-legacy/iris/include/xmpp_address.h b/iris-legacy/iris/include/xmpp_address.h new file mode 100644 index 0000000..e532069 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_address.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_ADDRESS_H +#define XMPP_ADDRESS_H + +#include + +#include "xmpp_jid.h" + +class QDomElement; + +namespace XMPP +{ + class Address + { + public: + typedef enum { Unknown, To, Cc, Bcc, ReplyTo, ReplyRoom, NoReply, OriginalFrom, OriginalTo } Type; + + Address(Type type = Unknown, const Jid& jid = Jid()); + Address(const QDomElement&); + + const Jid& jid() const; + const QString& uri() const; + const QString& node() const; + const QString& desc() const; + bool delivered() const; + Type type() const; + + QDomElement toXml(Stanza&) const; + void fromXml(const QDomElement& t); + + void setJid(const Jid &); + void setUri(const QString &); + void setNode(const QString &); + void setDesc(const QString &); + void setDelivered(bool); + void setType(Type); + + private: + Jid v_jid; + QString v_uri, v_node, v_desc; + bool v_delivered; + Type v_type; + }; + + typedef QList
AddressList; +}; + +#endif diff --git a/iris-legacy/iris/include/xmpp_agentitem.h b/iris-legacy/iris/include/xmpp_agentitem.h new file mode 100644 index 0000000..dcd9151 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_agentitem.h @@ -0,0 +1,55 @@ +/* + * xmpp_agentitem.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_AGENTITEM +#define XMPP_AGENTITEM + +#include + +#include "xmpp_jid.h" +#include "xmpp_features.h" + +namespace XMPP { + class AgentItem + { + public: + AgentItem() { } + + const Jid & jid() const { return v_jid; } + const QString & name() const { return v_name; } + const QString & category() const { return v_category; } + const QString & type() const { return v_type; } + const Features & features() const { return v_features; } + + void setJid(const Jid &j) { v_jid = j; } + void setName(const QString &n) { v_name = n; } + void setCategory(const QString &c) { v_category = c; } + void setType(const QString &t) { v_type = t; } + void setFeatures(const Features &f) { v_features = f; } + + private: + Jid v_jid; + QString v_name, v_category, v_type; + Features v_features; + }; +} + +#endif + diff --git a/iris-legacy/iris/include/xmpp_chatstate.h b/iris-legacy/iris/include/xmpp_chatstate.h new file mode 100644 index 0000000..f9f4f5e --- /dev/null +++ b/iris-legacy/iris/include/xmpp_chatstate.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_CHATSTATE +#define XMPP_CHATSTATE + +namespace XMPP { + typedef enum { + StateNone, + StateActive, + StateComposing, + StatePaused, + StateInactive, + StateGone + } ChatState; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_client.h b/iris-legacy/iris/include/xmpp_client.h new file mode 100644 index 0000000..cd385ac --- /dev/null +++ b/iris-legacy/iris/include/xmpp_client.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_CLIENT_H +#define XMPP_CLIENT_H + +#include +#include + +#include "xmpp_jid.h" +#include "xmpp_status.h" +#include "xmpp_discoitem.h" + +class QString; +class QDomElement; +class QDomDocument; +namespace XMPP { + class ClientStream; + class Features; + class FileTransferManager; + class IBBManager; + class JidLinkManager; + class LiveRoster; + class LiveRosterItem; + class Message; + class Resource; + class ResourceList; + class Roster; + class RosterItem; + class S5BManager; + class Stream; + class Task; +} + +namespace XMPP +{ + class Client : public QObject + { + Q_OBJECT + + public: + Client(QObject *parent=0); + ~Client(); + + bool isActive() const; + void connectToServer(ClientStream *s, const Jid &j, bool auth=true); + void start(const QString &host, const QString &user, const QString &pass, const QString &resource); + void close(bool fast=false); + + Stream & stream(); + QString streamBaseNS() const; + const LiveRoster & roster() const; + const ResourceList & resourceList() const; + + void send(const QDomElement &); + void send(const QString &); + + QString host() const; + QString user() const; + QString pass() const; + QString resource() const; + Jid jid() const; + + void rosterRequest(); + void sendMessage(const Message &); + void sendSubscription(const Jid &, const QString &, const QString& nick = QString()); + void setPresence(const Status &); + + void debug(const QString &); + QString genUniqueId(); + Task *rootTask(); + QDomDocument *doc() const; + + QString OSName() const; + QString timeZone() const; + int timeZoneOffset() const; + QString clientName() const; + QString clientVersion() const; + QString capsNode() const; + QString capsVersion() const; + QString capsExt() const; + + void setOSName(const QString &); + void setTimeZone(const QString &, int); + void setClientName(const QString &); + void setClientVersion(const QString &); + void setCapsNode(const QString &); + void setCapsVersion(const QString &); + + void setIdentity(DiscoItem::Identity); + DiscoItem::Identity identity(); + + void setFeatures(const Features& f); + const Features& features() const; + + void addExtension(const QString& ext, const Features& f); + void removeExtension(const QString& ext); + const Features& extension(const QString& ext) const; + QStringList extensions() const; + + S5BManager *s5bManager() const; + IBBManager *ibbManager() const; + JidLinkManager *jidLinkManager() const; + + void setFileTransferEnabled(bool b); + FileTransferManager *fileTransferManager() const; + + QString groupChatPassword(const QString& host, const QString& room) const; + bool groupChatJoin(const QString &host, const QString &room, const QString &nick, const QString& password = QString(), int maxchars = -1, int maxstanzas = -1, int seconds = -1, const Status& = Status()); + void groupChatSetStatus(const QString &host, const QString &room, const Status &); + void groupChatChangeNick(const QString &host, const QString &room, const QString &nick, const Status &); + void groupChatLeave(const QString &host, const QString &room); + + signals: + void activated(); + void disconnected(); + //void authFinished(bool, int, const QString &); + void rosterRequestFinished(bool, int, const QString &); + void rosterItemAdded(const RosterItem &); + void rosterItemUpdated(const RosterItem &); + void rosterItemRemoved(const RosterItem &); + void resourceAvailable(const Jid &, const Resource &); + void resourceUnavailable(const Jid &, const Resource &); + void presenceError(const Jid &, int, const QString &); + void subscription(const Jid &, const QString &, const QString &); + void messageReceived(const Message &); + void debugText(const QString &); + void xmlIncoming(const QString &); + void xmlOutgoing(const QString &); + void groupChatJoined(const Jid &); + void groupChatLeft(const Jid &); + void groupChatPresence(const Jid &, const Status &); + void groupChatError(const Jid &, int, const QString &); + + void incomingJidLink(); + + void beginImportRoster(); + void endImportRoster(); + + private slots: + //void streamConnected(); + //void streamHandshaken(); + //void streamError(const StreamError &); + //void streamSSLCertificateReady(const QSSLCert &); + //void streamCloseFinished(); + void streamError(int); + void streamReadyRead(); + void streamIncomingXml(const QString &); + void streamOutgoingXml(const QString &); + + void slotRosterRequestFinished(); + + // basic daemons + void ppSubscription(const Jid &, const QString &, const QString&); + void ppPresence(const Jid &, const Status &); + void pmMessage(const Message &); + void prRoster(const Roster &); + + void s5b_incomingReady(); + void ibb_incomingReady(); + + public: + class GroupChat; + private: + void cleanup(); + void distribute(const QDomElement &); + void importRoster(const Roster &); + void importRosterItem(const RosterItem &); + void updateSelfPresence(const Jid &, const Status &); + void updatePresence(LiveRosterItem *, const Jid &, const Status &); + + class ClientPrivate; + ClientPrivate *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_clientstream.h b/iris-legacy/iris/include/xmpp_clientstream.h new file mode 100644 index 0000000..8975dea --- /dev/null +++ b/iris-legacy/iris/include/xmpp_clientstream.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_CLIENTSTREAM_H +#define XMPP_CLIENTSTREAM_H + +#include + +#include "xmpp_stream.h" + +class QByteArray; +class QString; +class QDomDocument; +class QDomElement; +class QObject; +class ByteStream; +class QHostAddress; + +namespace XMPP +{ + class TLSHandler; + class Connector; + + class ClientStream : public Stream + { + Q_OBJECT + public: + enum Error { + ErrConnection = ErrCustom, // Connection error, ask Connector-subclass what's up + ErrNeg, // Negotiation error, see condition + ErrTLS, // TLS error, see condition + ErrAuth, // Auth error, see condition + ErrSecurityLayer, // broken SASL security layer + ErrBind // Resource binding error + }; + enum Warning { + WarnOldVersion, // server uses older XMPP/Jabber "0.9" protocol + WarnNoTLS // there is no chance for TLS at this point + }; + enum NegCond { + HostGone, // host no longer hosted + HostUnknown, // unknown host + RemoteConnectionFailed, // unable to connect to a required remote resource + SeeOtherHost, // a 'redirect', see errorText() for other host + UnsupportedVersion // unsupported XMPP version + }; + enum TLSCond { + TLSStart, // server rejected STARTTLS + TLSFail // TLS failed, ask TLSHandler-subclass what's up + }; + enum SecurityLayer { + LayerTLS, + LayerSASL + }; + enum AuthCond { + GenericAuthError, // all-purpose "can't login" error + NoMech, // No appropriate auth mech available + BadProto, // Bad SASL auth protocol + BadServ, // Server failed mutual auth + EncryptionRequired, // can't use mech without TLS + InvalidAuthzid, // bad input JID + InvalidMech, // bad mechanism + InvalidRealm, // bad realm + MechTooWeak, // can't use mech with this authzid + NotAuthorized, // bad user, bad password, bad creditials + TemporaryAuthFailure // please try again later! + }; + enum BindCond { + BindNotAllowed, // not allowed to bind a resource + BindConflict // resource in-use + }; + enum AllowPlainType { + NoAllowPlain, + AllowPlain, + AllowPlainOverTLS + }; + + ClientStream(Connector *conn, TLSHandler *tlsHandler=0, QObject *parent=0); + ClientStream(const QString &host, const QString &defRealm, ByteStream *bs, QCA::TLS *tls=0, QObject *parent=0); // server + ~ClientStream(); + + Jid jid() const; + void connectToServer(const Jid &jid, bool auth=true); + void accept(); // server + bool isActive() const; + bool isAuthenticated() const; + + // login params + void setUsername(const QString &s); + void setPassword(const QString &s); + void setRealm(const QString &s); + void setAuthzid(const QString &s); + void continueAfterParams(); + + // SASL information + QString saslMechanism() const; + int saslSSF() const; + + // binding + void setResourceBinding(bool); + + // Language + void setLang(const QString&); + + // security options (old protocol only uses the first !) + void setAllowPlain(AllowPlainType); +#ifdef YAPSI + void setAllowXFacebookPlatform(bool); +#endif + void setRequireMutualAuth(bool); + void setSSFRange(int low, int high); + void setOldOnly(bool); + void setSASLMechanism(const QString &s); + void setLocalAddr(const QHostAddress &addr, Q_UINT16 port); + + // Compression + void setCompress(bool); + + // reimplemented + QDomDocument & doc() const; + QString baseNS() const; + bool old() const; + + void close(); + bool stanzaAvailable() const; + Stanza read(); + void write(const Stanza &s); + + int errorCondition() const; + QString errorText() const; + QDomElement errorAppSpec() const; + + // extra + void writeDirect(const QString &s); + void setNoopTime(int mills); + + signals: + void connected(); + void securityLayerActivated(int); + void needAuthParams(bool user, bool pass, bool realm); + void authenticated(); + void warning(int); + void incomingXml(const QString &s); + void outgoingXml(const QString &s); + + public slots: + void continueAfterWarning(); + + private slots: + void cr_connected(); + void cr_error(); + + void bs_connectionClosed(); + void bs_delayedCloseFinished(); + void bs_error(int); // server only + + void ss_readyRead(); + void ss_bytesWritten(int); + void ss_tlsHandshaken(); + void ss_tlsClosed(); + void ss_error(int); + + void sasl_clientFirstStep(bool, const QByteArray&); + void sasl_nextStep(const QByteArray &stepData); + void sasl_needParams(const QCA::SASL::Params&); + void sasl_authCheck(const QString &user, const QString &authzid); + void sasl_authenticated(); + void sasl_error(); + + void doNoop(); + void doReadyRead(); + + private: + class Private; + Private *d; + + void reset(bool all=false); + void processNext(); + int convertedSASLCond() const; + bool handleNeed(); + void handleError(); + void srvProcessNext(); + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_discoitem.h b/iris-legacy/iris/include/xmpp_discoitem.h new file mode 100644 index 0000000..b587679 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_discoitem.h @@ -0,0 +1,86 @@ +/* + * xmpp_discoitem.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_DISCOITEM +#define XMPP_DISCOITEM + +#include + +#include "xmpp_jid.h" +#include "xmpp_features.h" +#include "xmpp_agentitem.h" + +namespace XMPP { + class DiscoItem + { + public: + DiscoItem(); + ~DiscoItem(); + + const Jid &jid() const; + const QString &node() const; + const QString &name() const; + + void setJid(const Jid &); + void setName(const QString &); + void setNode(const QString &); + + enum Action { + None = 0, + Remove, + Update + }; + + Action action() const; + void setAction(Action); + + const Features &features() const; + void setFeatures(const Features &); + + struct Identity + { + QString category; + QString name; + QString type; + }; + + typedef QList Identities; + + const Identities &identities() const; + void setIdentities(const Identities &); + + // some useful helper functions + static Action string2action(QString s); + static QString action2string(Action a); + + DiscoItem & operator= (const DiscoItem &); + DiscoItem(const DiscoItem &); + + operator AgentItem() const { return toAgentItem(); } + AgentItem toAgentItem() const; + void fromAgentItem(const AgentItem &); + + private: + class Private; + Private *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_features.h b/iris-legacy/iris/include/xmpp_features.h new file mode 100644 index 0000000..be4079a --- /dev/null +++ b/iris-legacy/iris/include/xmpp_features.h @@ -0,0 +1,88 @@ +/* + * xmpp_features.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_FEATURES_H +#define XMPP_FEATURES_H + +#include + +class QString; + +namespace XMPP +{ + class Features + { + public: + Features(); + Features(const QStringList &); + Features(const QString &); + ~Features(); + + QStringList list() const; // actual featurelist + void setList(const QStringList &); + void addFeature(const QString&); + + // features + bool canRegister() const; + bool canSearch() const; + bool canMulticast() const; + bool canGroupchat() const; + bool canVoice() const; + bool canDisco() const; + bool canChatState() const; + bool canCommand() const; + bool isGateway() const; + bool haveVCard() const; + bool canMessageReceipts() const; + + enum FeatureID { + FID_Invalid = -1, + FID_None, + FID_Register, + FID_Search, + FID_Groupchat, + FID_Disco, + FID_Gateway, + FID_VCard, + FID_AHCommand, + + // private Psi actions + FID_Add + }; + + // useful functions + bool test(const QString &) const; + bool test(const QStringList &) const; + + QString name() const; + static QString name(long id); + static QString name(const QString &feature); + + long id() const; + static long id(const QString &feature); + static QString feature(long id); + + class FeatureName; + private: + QStringList _list; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_htmlelement.h b/iris-legacy/iris/include/xmpp_htmlelement.h new file mode 100644 index 0000000..68d34a9 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_htmlelement.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_HTMLELEMENT_H +#define XMPP_HTMLELEMENT_H + +#include + +class QString; + +namespace XMPP +{ + class HTMLElement + { + public: + HTMLElement(); + HTMLElement(const QDomElement &body); + + void setBody(const QDomElement &body); + const QDomElement& body() const; + QString toString(const QString &rootTagName = "body") const; + QString text() const; + + private: + QDomDocument doc_; + QDomElement body_; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_httpauthrequest.h b/iris-legacy/iris/include/xmpp_httpauthrequest.h new file mode 100644 index 0000000..32fe9b3 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_httpauthrequest.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006 Maciek Niedzielski + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_AUTHREQUEST_H +#define XMPP_AUTHREQUEST_H + +#include + +class QDomElement; +class QDomDocument; + +namespace XMPP +{ + class HttpAuthRequest + { + public: + HttpAuthRequest(const QString &m, const QString &u, const QString &i); + HttpAuthRequest(const QString &m = "", const QString &u = ""); + HttpAuthRequest(const QDomElement &); + + bool isEmpty() const; + + void setMethod(const QString&); + void setUrl(const QString&); + void setId(const QString&); + QString method() const; + QString url() const; + QString id() const; + bool hasId() const; + + QDomElement toXml(QDomDocument &) const; + bool fromXml(const QDomElement &); + + static Stanza::Error denyError; + private: + QString method_, url_, id_; + bool hasId_; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_jid.h b/iris-legacy/iris/include/xmpp_jid.h new file mode 100644 index 0000000..dc3b2be --- /dev/null +++ b/iris-legacy/iris/include/xmpp_jid.h @@ -0,0 +1,83 @@ +/* + * xmpp_jid.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_JID_H +#define XMPP_JID_H + +#include + +namespace XMPP +{ + class Jid + { + public: + Jid(); + ~Jid(); + + Jid(const QString &s); + Jid(const char *s); + Jid & operator=(const QString &s); + Jid & operator=(const char *s); + + bool operator==(const Jid& other) const; + + void set(const QString &s); + void set(const QString &domain, const QString &node, const QString &resource=""); + + void setDomain(const QString &s); + void setNode(const QString &s); + void setResource(const QString &s); + + bool isNull() const { return null; } + const QString & domain() const { return d; } + const QString & node() const { return n; } + const QString & resource() const { return r; } + const QString & bare() const { return b; } + const QString & full() const { return f; } + + Jid withNode(const QString &s) const; + Jid withResource(const QString &s) const; + + bool isValid() const; + bool isEmpty() const; + bool compare(const Jid &a, bool compareRes=true) const; + + static bool validDomain(const QString &s, QString *norm=0); + static bool validNode(const QString &s, QString *norm=0); + static bool validResource(const QString &s, QString *norm=0); + + // TODO: kill these later + const QString & host() const { return d; } + const QString & user() const { return n; } + const QString & userHost() const { return b; } + + private: + void reset(); + void update(); + + QString f, b, d, n, r; + bool valid, null; + }; +} + +// TODO: doesn't seem to have any effect at all on gcc 4.2.3 / linux +uint qHash(const XMPP::Jid& jid); + +#endif diff --git a/iris-legacy/iris/include/xmpp_liveroster.h b/iris-legacy/iris/include/xmpp_liveroster.h new file mode 100644 index 0000000..6e1625b --- /dev/null +++ b/iris-legacy/iris/include/xmpp_liveroster.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_LIVEROSTER_H +#define XMPP_LIVEROSTER_H + +#include + +#include "xmpp_liverosteritem.h" + +namespace XMPP +{ + class Jid; + + class LiveRoster : public QList + { + public: + LiveRoster(); + ~LiveRoster(); + + void flagAllForDelete(); + LiveRoster::Iterator find(const Jid &, bool compareRes=true); + LiveRoster::ConstIterator find(const Jid &, bool compareRes=true) const; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_liverosteritem.h b/iris-legacy/iris/include/xmpp_liverosteritem.h new file mode 100644 index 0000000..9d5ee7e --- /dev/null +++ b/iris-legacy/iris/include/xmpp_liverosteritem.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_LIVEROSTERITEM_H +#define XMPP_LIVEROSTERITEM_H + +#include "xmpp_status.h" +#include "xmpp_resourcelist.h" +#include "xmpp_rosteritem.h" + +namespace XMPP +{ + class LiveRosterItem : public RosterItem + { + public: + LiveRosterItem(const Jid &j=""); + LiveRosterItem(const RosterItem &); + ~LiveRosterItem(); + + void setRosterItem(const RosterItem &); + + ResourceList & resourceList(); + ResourceList::Iterator priority(); + + const ResourceList & resourceList() const; + ResourceList::ConstIterator priority() const; + + bool isAvailable() const; + const Status & lastUnavailableStatus() const; + bool flagForDelete() const; + + void setLastUnavailableStatus(const Status &); + void setFlagForDelete(bool); + + private: + ResourceList v_resourceList; + Status v_lastUnavailableStatus; + bool v_flagForDelete; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_message.h b/iris-legacy/iris/include/xmpp_message.h new file mode 100644 index 0000000..61507c4 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_message.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_MESSAGE_H +#define XMPP_MESSAGE_H + +#include "xmpp_stanza.h" +#include "xmpp_url.h" +#include "xmpp_chatstate.h" +#include "xmpp_receipts.h" +#include "xmpp_address.h" +#include "xmpp_rosterx.h" +#include "xmpp_muc.h" + +class QString; +class QDateTime; +#ifdef YAPSI +class YaLastMail; +#endif + +namespace XMPP { + class Jid; + class PubSubItem; + class PubSubRetraction; + class HTMLElement; + class HttpAuthRequest; + class XData; + + typedef enum { OfflineEvent, DeliveredEvent, DisplayedEvent, + ComposingEvent, CancelEvent } MsgEvent; + + class Message + { + public: + Message(const Jid &to=""); + Message(const Message &from); + Message & operator=(const Message &from); + ~Message(); + + Jid to() const; + Jid from() const; + QString id() const; + QString type() const; + QString lang() const; + QString subject(const QString &lang="") const; + QString body(const QString &lang="") const; + QString thread() const; + Stanza::Error error() const; + + void setTo(const Jid &j); + void setFrom(const Jid &j); + void setId(const QString &s); + void setType(const QString &s); + void setLang(const QString &s); + void setSubject(const QString &s, const QString &lang=""); + void setBody(const QString &s, const QString &lang=""); + void setThread(const QString &s, bool send = false); + void setError(const Stanza::Error &err); + + // JEP-0060 + const QString& pubsubNode() const; + const QList& pubsubItems() const; + const QList& pubsubRetractions() const; + + // JEP-0091 + QDateTime timeStamp() const; + void setTimeStamp(const QDateTime &ts, bool send = false); + + // JEP-0071 + HTMLElement html(const QString &lang="") const; + void setHTML(const HTMLElement &s, const QString &lang=""); + bool containsHTML() const; + + // JEP-0066 + UrlList urlList() const; + void urlAdd(const Url &u); + void urlsClear(); + void setUrlList(const UrlList &list); + + // JEP-0022 + QString eventId() const; + void setEventId(const QString& id); + bool containsEvents() const; + bool containsEvent(MsgEvent e) const; + void addEvent(MsgEvent e); + + // JEP-0085 + ChatState chatState() const; + void setChatState(ChatState); + + // XEP-0184 + MessageReceipt messageReceipt() const; + void setMessageReceipt(MessageReceipt); + + // JEP-0027 + QString xencrypted() const; + void setXEncrypted(const QString &s); + + // JEP-0033 + AddressList addresses() const; + AddressList findAddresses(Address::Type t) const; + void addAddress(const Address &a); + void clearAddresses(); + void setAddresses(const AddressList &list); + + // JEP-144 + const RosterExchangeItems& rosterExchangeItems() const; + void setRosterExchangeItems(const RosterExchangeItems&); + + // JEP-172 + void setNick(const QString&); + const QString& nick() const; + + // JEP-0070 + void setHttpAuthRequest(const HttpAuthRequest&); + HttpAuthRequest httpAuthRequest() const; + + // JEP-0004 + void setForm(const XData&); + const XData& getForm() const; + + // JEP-xxxx Whiteboarding + void setWhiteboard(const QDomElement&); + const QDomElement& whiteboard() const; + + // MUC + void setMUCStatus(int); + bool hasMUCStatus() const; + int mucStatus() const; + void addMUCInvite(const MUCInvite&); + const QList& mucInvites() const; + void setMUCDecline(const MUCDecline&); + const MUCDecline& mucDecline() const; + const QString& mucPassword() const; + void setMUCPassword(const QString&); + + // Obsolete invitation + QString invite() const; + void setInvite(const QString &s); + + // for compatibility. delete me later + bool spooled() const; + void setSpooled(bool); + bool wasEncrypted() const; + void setWasEncrypted(bool); + + Stanza toStanza(Stream *stream) const; + bool fromStanza(const Stanza &s, int tzoffset); + +#ifdef YAPSI + const YaLastMail& lastMailNotify() const; + void setLastMailNotify(const YaLastMail& lastMailNotify); + int spamFlag() const; + + QString twin() const; + void setTwin(const QString& twin); + + QString yaMessageId() const; + void setYaMessageId(const QString& yaMessageId); + + int yaFlags() const; + void setYaFlags(int flags); +#endif + + const QDomElement& getExtension(const QString& ns) const; + + private: + class Private; + Private *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_muc.h b/iris-legacy/iris/include/xmpp_muc.h new file mode 100644 index 0000000..4057679 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_muc.h @@ -0,0 +1,137 @@ +/* + * xmpp_muc.h + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_MUC_H +#define XMPP_MUC_H + +#include +#include + +#include "xmpp_jid.h" + +namespace XMPP +{ + class MUCItem + { + public: + enum Affiliation { UnknownAffiliation, Outcast, NoAffiliation, Member, Admin, Owner }; + enum Role { UnknownRole, NoRole, Visitor, Participant, Moderator }; + + MUCItem(Role = UnknownRole, Affiliation = UnknownAffiliation); + MUCItem(const QDomElement&); + + void setNick(const QString&); + void setJid(const Jid&); + void setAffiliation(Affiliation); + void setRole(Role); + void setActor(const Jid&); + void setReason(const QString&); + + const QString& nick() const; + const Jid& jid() const; + Affiliation affiliation() const; + Role role() const; + const Jid& actor() const; + const QString& reason() const; + + void fromXml(const QDomElement&); + QDomElement toXml(QDomDocument&); + + bool operator==(const MUCItem& o); + + private: + QString nick_; + Jid jid_, actor_; + Affiliation affiliation_; + Role role_; + QString reason_; + }; + + class MUCInvite + { + public: + MUCInvite(); + MUCInvite(const QDomElement&); + MUCInvite(const Jid& to, const QString& reason = QString()); + + const Jid& to() const; + void setTo(const Jid&); + const Jid& from() const; + void setFrom(const Jid&); + const QString& reason() const; + void setReason(const QString&); + bool cont() const; + void setCont(bool); + + + void fromXml(const QDomElement&); + QDomElement toXml(QDomDocument&) const; + bool isNull() const; + + private: + Jid to_, from_; + QString reason_, password_; + bool cont_; + }; + + class MUCDecline + { + public: + MUCDecline(); + MUCDecline(const Jid& to, const QString& reason); + MUCDecline(const QDomElement&); + + const Jid& to() const; + void setTo(const Jid&); + const Jid& from() const; + void setFrom(const Jid&); + const QString& reason() const; + void setReason(const QString&); + + void fromXml(const QDomElement&); + QDomElement toXml(QDomDocument&) const; + bool isNull() const; + + private: + Jid to_, from_; + QString reason_; + }; + + class MUCDestroy + { + public: + MUCDestroy(); + MUCDestroy(const QDomElement&); + + const Jid& jid() const; + void setJid(const Jid&); + const QString& reason() const; + void setReason(const QString&); + + void fromXml(const QDomElement&); + QDomElement toXml(QDomDocument&) const; + + private: + Jid jid_; + QString reason_; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_pubsubitem.h b/iris-legacy/iris/include/xmpp_pubsubitem.h new file mode 100644 index 0000000..0d48884 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_pubsubitem.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_PUBSUBITEM_H +#define XMPP_PUBSUBITEM_H + +#include +#include + +namespace XMPP +{ + class PubSubItem + { + public: + PubSubItem(); + PubSubItem(const QString& id, const QDomElement& payload); + const QString& id() const; + const QDomElement& payload() const; + + private: + QString id_; + QDomElement payload_; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_pubsubretraction.h b/iris-legacy/iris/include/xmpp_pubsubretraction.h new file mode 100644 index 0000000..d41781a --- /dev/null +++ b/iris-legacy/iris/include/xmpp_pubsubretraction.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_PUBSUBRETRACTION_H +#define XMPP_PUBSUBRETRACTION_H + +#include +#include + +namespace XMPP +{ + + class PubSubRetraction + { + public: + PubSubRetraction(); + PubSubRetraction(const QString& id); + const QString& id() const; + + private: + QString id_; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_receipts.h b/iris-legacy/iris/include/xmpp_receipts.h new file mode 100644 index 0000000..151c106 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_receipts.h @@ -0,0 +1,32 @@ +/* + * xmpp_receipts.h - XEP-0184 support helper file + * Copyright (C) 2007 Michail Pishchagin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_RECEIPTS_H +#define XMPP_RECEIPTS_H + +namespace XMPP { + typedef enum { + ReceiptNone, + ReceiptRequest, + ReceiptReceived + } MessageReceipt; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_resource.h b/iris-legacy/iris/include/xmpp_resource.h new file mode 100644 index 0000000..7e0b93e --- /dev/null +++ b/iris-legacy/iris/include/xmpp_resource.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_RESOURCE_H +#define XMPP_RESOURCE_H + +#include + +#include "xmpp_status.h" + +namespace XMPP +{ + class Resource + { + public: + Resource(const QString &name="", const Status &s=Status()); + ~Resource(); + + const QString & name() const; + int priority() const; + const Status & status() const; + + void setName(const QString &); + void setStatus(const Status &); + + private: + QString v_name; + Status v_status; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_resourcelist.h b/iris-legacy/iris/include/xmpp_resourcelist.h new file mode 100644 index 0000000..0aa58cc --- /dev/null +++ b/iris-legacy/iris/include/xmpp_resourcelist.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_RESOURCELIST_H +#define XMPP_RESOURCELIST_H + +#include + +#include "xmpp_resource.h" + +class QString; + +namespace XMPP +{ + class ResourceList : public QList + { + public: + ResourceList(); + ~ResourceList(); + + ResourceList::Iterator find(const QString &); + ResourceList::Iterator priority(); + + ResourceList::ConstIterator find(const QString &) const; + ResourceList::ConstIterator priority() const; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_roster.h b/iris-legacy/iris/include/xmpp_roster.h new file mode 100644 index 0000000..b151793 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_roster.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_ROSTER_H +#define XMPP_ROSTER_H + +#include + +#include "xmpp_rosteritem.h" + +class QDomDocument; +class QDomElement; + +namespace XMPP +{ + class Jid; + class Roster : public QList + { + public: + Roster(); + ~Roster(); + + Roster::Iterator find(const Jid &); + Roster::ConstIterator find(const Jid &) const; + + private: + class RosterPrivate *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_rosteritem.h b/iris-legacy/iris/include/xmpp_rosteritem.h new file mode 100644 index 0000000..0a9f955 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_rosteritem.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_ROSTERITEM_H +#define XMPP_ROSTERITEM_H + +#include +#include + +#include "xmpp_jid.h" + +namespace XMPP +{ + class Subscription + { + public: + enum SubType { None, To, From, Both, Remove }; + + Subscription(SubType type=None); + + int type() const; + + QString toString() const; + bool fromString(const QString &); + + private: + SubType value; + }; + + class RosterItem + { + public: + RosterItem(const Jid &jid=""); + virtual ~RosterItem(); + + const Jid & jid() const; + const QString & name() const; + const QStringList & groups() const; + const Subscription & subscription() const; + const QString & ask() const; + bool isPush() const; + bool inGroup(const QString &) const; + + virtual void setJid(const Jid &); + void setName(const QString &); + void setGroups(const QStringList &); + void setSubscription(const Subscription &); + void setAsk(const QString &); + void setIsPush(bool); + bool addGroup(const QString &); + bool removeGroup(const QString &); + + QDomElement toXml(QDomDocument *) const; + bool fromXml(const QDomElement &); + + private: + Jid v_jid; + QString v_name; + QStringList v_groups; + Subscription v_subscription; + QString v_ask; + bool v_push; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_rosterx.h b/iris-legacy/iris/include/xmpp_rosterx.h new file mode 100644 index 0000000..b833008 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_rosterx.h @@ -0,0 +1,66 @@ +/* + * rosterexchangeitem.h + * Copyright (C) 2003 Remko Troncon + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_ROSTERX_H +#define XMPP_ROSTERX_H + +#include +#include + +#include "xmpp_jid.h" + +class QDomElement; + +namespace XMPP +{ + class Stanza; + + class RosterExchangeItem + { + public: + enum Action { Add, Delete, Modify }; + + RosterExchangeItem(const Jid& jid, const QString& name = "", const QStringList& groups = QStringList(), Action = Add); + RosterExchangeItem(const QDomElement&); + + const Jid& jid() const; + Action action() const; + const QString& name() const; + const QStringList& groups() const; + bool isNull() const; + + void setJid(const Jid&); + void setAction(Action); + void setName(const QString&); + void setGroups(const QStringList&); + + QDomElement toXml(Stanza&) const; + void fromXml(const QDomElement&); + + private: + Jid jid_; + QString name_; + QStringList groups_; + Action action_; + }; + typedef QList RosterExchangeItems; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_stanza.h b/iris-legacy/iris/include/xmpp_stanza.h new file mode 100644 index 0000000..e165b8b --- /dev/null +++ b/iris-legacy/iris/include/xmpp_stanza.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_STANZA_H +#define XMPP_STANZA_H + +#include +#include +#include + +class QDomDocument; + +namespace XMPP +{ + class Jid; + class Stream; + + class Stanza + { + public: + enum Kind { Message, Presence, IQ }; + + Stanza(); + Stanza(const Stanza &from); + Stanza & operator=(const Stanza &from); + virtual ~Stanza(); + + class Error + { + public: + enum ErrorType { Cancel = 1, Continue, Modify, Auth, Wait }; + enum ErrorCond + { + BadRequest = 1, + Conflict, + FeatureNotImplemented, + Forbidden, + Gone, + InternalServerError, + ItemNotFound, + JidMalformed, + NotAcceptable, + NotAllowed, + NotAuthorized, + PaymentRequired, + RecipientUnavailable, + Redirect, + RegistrationRequired, + RemoteServerNotFound, + RemoteServerTimeout, + ResourceConstraint, + ServiceUnavailable, + SubscriptionRequired, + UndefinedCondition, + UnexpectedRequest + }; + + Error(int type=Cancel, int condition=UndefinedCondition, const QString &text="", const QDomElement &appSpec=QDomElement()); + + int type; + int condition; + QString text; + QDomElement appSpec; + + int code() const; + bool fromCode(int code); + + QPair description() const; + + QDomElement toXml(QDomDocument &doc, const QString &baseNS) const; + bool fromXml(const QDomElement &e, const QString &baseNS); + private: + class Private; + int originalCode; + + }; + + bool isNull() const; + + QDomElement element() const; + QString toString() const; + + QDomDocument & doc() const; + QString baseNS() const; + QDomElement createElement(const QString &ns, const QString &tagName); + QDomElement createTextElement(const QString &ns, const QString &tagName, const QString &text); + void appendChild(const QDomElement &e); + + Kind kind() const; + void setKind(Kind k); + + Jid to() const; + Jid from() const; + QString id() const; + QString type() const; + QString lang() const; + + void setTo(const Jid &j); + void setFrom(const Jid &j); + void setId(const QString &id); + void setType(const QString &type); + void setLang(const QString &lang); + +#ifdef YAPSI + void setAttribute(const QString& name, const QString& value); +#endif + + Error error() const; + void setError(const Error &err); + void clearError(); + + private: + friend class Stream; + Stanza(Stream *s, Kind k, const Jid &to, const QString &type, const QString &id); + Stanza(Stream *s, const QDomElement &e); + + class Private; + Private *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_status.h b/iris-legacy/iris/include/xmpp_status.h new file mode 100644 index 0000000..c04f9bd --- /dev/null +++ b/iris-legacy/iris/include/xmpp_status.h @@ -0,0 +1,151 @@ +/* + * xmpp_status.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_STATUS_H +#define XMPP_STATUS_H + +#include +#include + +#include "xmpp_muc.h" + +namespace XMPP +{ + class Status + { + public: + enum Type { + Offline, Online, Away, XA, DND, Invisible, FFC +#ifdef YAPSI + , Blocked, Reconnecting, NotAuthorizedToSeeStatus + , GC_Active, GC_Inactive, GC_Favorited +#endif + }; + + Status(const QString &show="", const QString &status="", int priority=0, bool available=true); + Status(Type type, const QString& status="", int priority=0); + ~Status(); + + int priority() const; + Type type() const; + QString typeString() const; + const QString & show() const; + const QString & status() const; + QDateTime timeStamp() const; + const QString & keyID() const; + bool isAvailable() const; + bool isAway() const; + bool isInvisible() const; + bool hasError() const; + int errorCode() const; + const QString & errorString() const; + + const QString & xsigned() const; + const QString & songTitle() const; + const QString & capsNode() const; + const QString & capsVersion() const; + const QString & capsExt() const; +#ifdef YAPSI + const QString & notifyValue() const; +#endif + + bool isMUC() const; + bool hasMUCItem() const; + const MUCItem & mucItem() const; + bool hasMUCDestroy() const; + const MUCDestroy & mucDestroy() const; + bool hasMUCStatus() const; + QList getMUCStatuses() const; + int mucStatus() const; + const QString& mucPassword() const; + bool hasMUCHistory() const; + int mucHistoryMaxChars() const; + int mucHistoryMaxStanzas() const; + int mucHistorySeconds() const; + + void setPriority(int); + void setType(Type); + void setType(QString); + void setShow(const QString &); + void setStatus(const QString &); + void setTimeStamp(const QDateTime &); + void setKeyID(const QString &); + void setIsAvailable(bool); + void setIsInvisible(bool); + void setError(int, const QString &); + void setCapsNode(const QString&); + void setCapsVersion(const QString&); + void setCapsExt(const QString&); + + void setMUC(); + void setMUCItem(const MUCItem&); + void setMUCDestroy(const MUCDestroy&); + void setMUCStatus(int); + void setMUCPassword(const QString&); + void setMUCHistory(int maxchars, int maxstanzas, int seconds); + + void setXSigned(const QString &); + void setSongTitle(const QString &); +#ifdef YAPSI + void setNotifyValue(const QString &); +#endif + + // JEP-153: VCard-based Avatars + const QString& photoHash() const; + void setPhotoHash(const QString&); + bool hasPhotoHash() const; + + private: + int v_priority; + QString v_show, v_status, v_key; + QDateTime v_timeStamp; + bool v_isAvailable; + bool v_isInvisible; + QString v_photoHash; + bool v_hasPhotoHash; + + QString v_xsigned; + // gabber song extension + QString v_songTitle; + QString v_capsNode, v_capsVersion, v_capsExt; + + // MUC + bool v_isMUC, v_hasMUCItem, v_hasMUCDestroy; + MUCItem v_mucItem; + MUCDestroy v_mucDestroy; + int v_mucStatus; + QString v_mucPassword; + int v_mucHistoryMaxChars, v_mucHistoryMaxStanzas, v_mucHistorySeconds; + +#ifdef YAPSI + QString v_notifyValue; +#endif + + int ecode; + QString estr; + }; + +} + +#include + +Q_DECLARE_METATYPE(XMPP::Status) + +#endif diff --git a/iris-legacy/iris/include/xmpp_stream.h b/iris-legacy/iris/include/xmpp_stream.h new file mode 100644 index 0000000..46e0d4b --- /dev/null +++ b/iris-legacy/iris/include/xmpp_stream.h @@ -0,0 +1,81 @@ +/* + * xmpp.h - XMPP "core" library API + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_STREAM_H +#define XMPP_STREAM_H + +#include +#include + +#include "xmpp_stanza.h" +#include "xmpp_jid.h" + +class QDomDocument; + +namespace XMPP +{ + class Stream : public QObject + { + Q_OBJECT + public: + enum Error { ErrParse, ErrProtocol, ErrStream, ErrCustom = 10 }; + enum StreamCond { + GenericStreamError, + Conflict, + ConnectionTimeout, + InternalServerError, + InvalidFrom, + InvalidXml, + PolicyViolation, + ResourceConstraint, + SystemShutdown + }; + + Stream(QObject *parent=0); + virtual ~Stream(); + + virtual QDomDocument & doc() const=0; + virtual QString baseNS() const=0; + virtual bool old() const=0; + + virtual void close()=0; + virtual bool stanzaAvailable() const=0; + virtual Stanza read()=0; + virtual void write(const Stanza &s)=0; + + virtual int errorCondition() const=0; + virtual QString errorText() const=0; + virtual QDomElement errorAppSpec() const=0; + + Stanza createStanza(Stanza::Kind k, const Jid &to="", const QString &type="", const QString &id=""); + Stanza createStanza(const QDomElement &e); + + static QString xmlToString(const QDomElement &e, bool clip=false); + + signals: + void connectionClosed(); + void delayedCloseFinished(); + void readyRead(); + void stanzaWritten(); + void error(int); + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_task.h b/iris-legacy/iris/include/xmpp_task.h new file mode 100644 index 0000000..270c86b --- /dev/null +++ b/iris-legacy/iris/include/xmpp_task.h @@ -0,0 +1,82 @@ +/* + * xmpp_task.h + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_TASK_H +#define XMPP_TASK_H + +#include +#include + +class QDomDocument; +class QDomElement; + +namespace XMPP { + class Client; + class Jid; + + class Task : public QObject + { + Q_OBJECT + public: + enum { ErrDisc }; + Task(Task *parent); + Task(Client *, bool isRoot); + virtual ~Task(); + + Task *parent() const; + Client *client() const; + QDomDocument *doc() const; + QString id() const; + + bool success() const; + int statusCode() const; + const QString & statusString() const; + + void go(bool autoDelete=false); + virtual bool take(const QDomElement &); + void safeDelete(); + + signals: + void finished(); + + protected: + virtual void onGo(); + virtual void onDisconnect(); + void send(const QDomElement &); + void setSuccess(int code=0, const QString &str=""); + void setError(const QDomElement &); + void setError(int code=0, const QString &str=""); + void debug(const char *, ...); + void debug(const QString &); + bool iqVerify(const QDomElement &x, const Jid &to, const QString &id, const QString &xmlns=""); + + private slots: + void clientDisconnected(); + void done(); + + private: + void init(); + + class TaskPrivate; + TaskPrivate *d; + }; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_url.h b/iris-legacy/iris/include/xmpp_url.h new file mode 100644 index 0000000..e9a80c2 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_url.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003 Justin Karneges + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPP_URL +#define XMPP_URL + +class QString; + +namespace XMPP +{ + class Url + { + public: + Url(const QString &url="", const QString &desc=""); + Url(const Url &); + Url & operator=(const Url &); + ~Url(); + + QString url() const; + QString desc() const; + + void setUrl(const QString &); + void setDesc(const QString &); + + private: + class Private; + Private *d; + }; + + typedef QList UrlList; +} + +#endif diff --git a/iris-legacy/iris/include/xmpp_xdata.h b/iris-legacy/iris/include/xmpp_xdata.h new file mode 100644 index 0000000..6169f91 --- /dev/null +++ b/iris-legacy/iris/include/xmpp_xdata.h @@ -0,0 +1,158 @@ +/* + * xmpp_xdata.h - a class for jabber:x:data forms + * Copyright (C) 2003-2004 Michail Pishchagin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef XMPPXDATA_H +#define XMPPXDATA_H + +#include +#include +#include +#include +#include + +class QDomElement; +class QDomDocument; + +namespace XMPP { + + class XData + { + public: + XData(); + + QString title() const; + void setTitle(const QString &); + + QString instructions() const; + void setInstructions(const QString &); + + enum Type { + Data_Form, + Data_Result, + Data_Submit, + Data_Cancel + }; + + Type type() const; + void setType(Type); + + struct ReportField { + ReportField() { } + ReportField( QString _label, QString _name ) { label = _label; name = _name; } + QString label; + QString name; + }; + const QList &report() const; + + typedef QMap ReportItem; + const QList &reportItems() const; + + void fromXml(const QDomElement &); + QDomElement toXml(QDomDocument *, bool submitForm = true) const; + bool isValid() const; + + public: + class Field { + public: + Field(); + ~Field(); + + QString desc() const; + void setDesc(const QString &); + + struct Option { + QString label; + QString value; + }; + + typedef QList