diff options
-rw-r--r-- | .gitignore | 91 | ||||
-rw-r--r-- | .travis.yml | 13 | ||||
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | Makefile.am | 110 | ||||
-rwxr-xr-x | configure-debug | 2 | ||||
-rw-r--r-- | configure.ac | 43 | ||||
-rwxr-xr-x | install-all.sh | 2 | ||||
-rw-r--r-- | src/command/command.c | 313 | ||||
-rw-r--r-- | src/command/command.h | 9 | ||||
-rw-r--r-- | src/command/commands.c | 994 | ||||
-rw-r--r-- | src/command/commands.h | 167 | ||||
-rw-r--r-- | src/common.c | 21 | ||||
-rw-r--r-- | src/common.h | 8 | ||||
-rw-r--r-- | src/config/account.c | 9 | ||||
-rw-r--r-- | src/config/account.h | 3 | ||||
-rw-r--r-- | src/config/accounts.c | 28 | ||||
-rw-r--r-- | src/config/accounts.h | 2 | ||||
-rw-r--r-- | src/config/preferences.c | 50 | ||||
-rw-r--r-- | src/config/preferences.h | 11 | ||||
-rw-r--r-- | src/config/theme.c | 8 | ||||
-rw-r--r-- | src/config/theme.h | 5 | ||||
-rw-r--r-- | src/event/client_events.c | 84 | ||||
-rw-r--r-- | src/event/server_events.c | 156 | ||||
-rw-r--r-- | src/event/server_events.h | 14 | ||||
-rw-r--r-- | src/event/ui_events.c | 4 | ||||
-rw-r--r-- | src/jid.c | 3 | ||||
-rw-r--r-- | src/log.c | 157 | ||||
-rw-r--r-- | src/log.h | 8 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/muc.c | 13 | ||||
-rw-r--r-- | src/muc.h | 3 | ||||
-rw-r--r-- | src/otr/otr.c | 65 | ||||
-rw-r--r-- | src/otr/otr.h | 6 | ||||
-rw-r--r-- | src/pgp/gpg.c | 531 | ||||
-rw-r--r-- | src/pgp/gpg.h | 59 | ||||
-rw-r--r-- | src/profanity.c | 34 | ||||
-rw-r--r-- | src/ui/buffer.c | 4 | ||||
-rw-r--r-- | src/ui/console.c | 58 | ||||
-rw-r--r-- | src/ui/core.c | 112 | ||||
-rw-r--r-- | src/ui/inputwin.c | 26 | ||||
-rw-r--r-- | src/ui/notifier.c | 2 | ||||
-rw-r--r-- | src/ui/occupantswin.c | 4 | ||||
-rw-r--r-- | src/ui/rosterwin.c | 4 | ||||
-rw-r--r-- | src/ui/statusbar.c | 3 | ||||
-rw-r--r-- | src/ui/statusbar.h | 6 | ||||
-rw-r--r-- | src/ui/titlebar.c | 100 | ||||
-rw-r--r-- | src/ui/ui.h | 70 | ||||
-rw-r--r-- | src/ui/win_types.h | 146 | ||||
-rw-r--r-- | src/ui/window.c | 115 | ||||
-rw-r--r-- | src/ui/window.h | 135 | ||||
-rw-r--r-- | src/window_list.c (renamed from src/ui/windows.c) | 142 | ||||
-rw-r--r-- | src/window_list.h (renamed from src/ui/windows.h) | 13 | ||||
-rw-r--r-- | src/xmpp/connection.c | 10 | ||||
-rw-r--r-- | src/xmpp/message.c | 152 | ||||
-rw-r--r-- | src/xmpp/presence.c | 28 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 21 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 4 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 8 | ||||
-rw-r--r-- | tests/functionaltests/functionaltests.c | 119 | ||||
-rw-r--r-- | tests/functionaltests/proftest.c | 238 | ||||
-rw-r--r-- | tests/functionaltests/proftest.h | 17 | ||||
-rwxr-xr-x | tests/functionaltests/start_profanity.sh | 2 | ||||
-rw-r--r-- | tests/functionaltests/test_chat_session.c | 207 | ||||
-rw-r--r-- | tests/functionaltests/test_chat_session.h | 7 | ||||
-rw-r--r-- | tests/functionaltests/test_connect.c | 95 | ||||
-rw-r--r-- | tests/functionaltests/test_connect.h | 6 | ||||
-rw-r--r-- | tests/functionaltests/test_message.c | 42 | ||||
-rw-r--r-- | tests/functionaltests/test_message.h | 2 | ||||
-rw-r--r-- | tests/functionaltests/test_ping.c | 57 | ||||
-rw-r--r-- | tests/functionaltests/test_ping.h | 2 | ||||
-rw-r--r-- | tests/functionaltests/test_presence.c | 243 | ||||
-rw-r--r-- | tests/functionaltests/test_presence.h | 13 | ||||
-rw-r--r-- | tests/functionaltests/test_rooms.c | 38 | ||||
-rw-r--r-- | tests/functionaltests/test_rooms.h | 2 | ||||
-rw-r--r-- | tests/unittests/config/stub_accounts.c (renamed from tests/config/stub_accounts.c) | 2 | ||||
-rw-r--r-- | tests/unittests/helpers.c (renamed from tests/helpers.c) | 0 | ||||
-rw-r--r-- | tests/unittests/helpers.h (renamed from tests/helpers.h) | 0 | ||||
-rw-r--r-- | tests/unittests/log/stub_log.c (renamed from tests/log/stub_log.c) | 8 | ||||
-rw-r--r-- | tests/unittests/otr/stub_otr.c (renamed from tests/otr/stub_otr.c) | 10 | ||||
-rw-r--r-- | tests/unittests/pgp/stub_gpg.c | 49 | ||||
-rw-r--r-- | tests/unittests/test_autocomplete.c (renamed from tests/test_autocomplete.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_autocomplete.h (renamed from tests/test_autocomplete.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_chat_session.c (renamed from tests/test_chat_session.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_chat_session.h (renamed from tests/test_chat_session.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_account.c (renamed from tests/test_cmd_account.c) | 160 | ||||
-rw-r--r-- | tests/unittests/test_cmd_account.h (renamed from tests/test_cmd_account.h) | 1 | ||||
-rw-r--r-- | tests/unittests/test_cmd_alias.c (renamed from tests/test_cmd_alias.c) | 18 | ||||
-rw-r--r-- | tests/unittests/test_cmd_alias.h (renamed from tests/test_cmd_alias.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_bookmark.c (renamed from tests/test_cmd_bookmark.c) | 47 | ||||
-rw-r--r-- | tests/unittests/test_cmd_bookmark.h (renamed from tests/test_cmd_bookmark.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_connect.c (renamed from tests/test_cmd_connect.c) | 50 | ||||
-rw-r--r-- | tests/unittests/test_cmd_connect.h (renamed from tests/test_cmd_connect.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_disconnect.c (renamed from tests/test_cmd_disconnect.c) | 4 | ||||
-rw-r--r-- | tests/unittests/test_cmd_disconnect.h (renamed from tests/test_cmd_disconnect.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_join.c (renamed from tests/test_cmd_join.c) | 20 | ||||
-rw-r--r-- | tests/unittests/test_cmd_join.h (renamed from tests/test_cmd_join.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_otr.c (renamed from tests/test_cmd_otr.c) | 185 | ||||
-rw-r--r-- | tests/unittests/test_cmd_otr.h (renamed from tests/test_cmd_otr.h) | 4 | ||||
-rw-r--r-- | tests/unittests/test_cmd_pgp.c | 129 | ||||
-rw-r--r-- | tests/unittests/test_cmd_pgp.h | 17 | ||||
-rw-r--r-- | tests/unittests/test_cmd_rooms.c (renamed from tests/test_cmd_rooms.c) | 6 | ||||
-rw-r--r-- | tests/unittests/test_cmd_rooms.h (renamed from tests/test_cmd_rooms.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_roster.c (renamed from tests/test_cmd_roster.c) | 27 | ||||
-rw-r--r-- | tests/unittests/test_cmd_roster.h (renamed from tests/test_cmd_roster.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_statuses.c (renamed from tests/test_cmd_statuses.c) | 26 | ||||
-rw-r--r-- | tests/unittests/test_cmd_statuses.h (renamed from tests/test_cmd_statuses.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_cmd_sub.c (renamed from tests/test_cmd_sub.c) | 4 | ||||
-rw-r--r-- | tests/unittests/test_cmd_sub.h (renamed from tests/test_cmd_sub.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_common.c (renamed from tests/test_common.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_common.h (renamed from tests/test_common.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_contact.c (renamed from tests/test_contact.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_contact.h (renamed from tests/test_contact.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_form.c (renamed from tests/test_form.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_form.h (renamed from tests/test_form.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_jid.c (renamed from tests/test_jid.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_jid.h (renamed from tests/test_jid.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_keyhandlers.c (renamed from tests/test_keyhandlers.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_keyhandlers.h (renamed from tests/test_keyhandlers.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_muc.c (renamed from tests/test_muc.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_muc.h (renamed from tests/test_muc.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_parser.c (renamed from tests/test_parser.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_parser.h (renamed from tests/test_parser.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_preferences.c (renamed from tests/test_preferences.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_preferences.h (renamed from tests/test_preferences.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_roster_list.c (renamed from tests/test_roster_list.c) | 0 | ||||
-rw-r--r-- | tests/unittests/test_roster_list.h (renamed from tests/test_roster_list.h) | 0 | ||||
-rw-r--r-- | tests/unittests/test_server_events.c (renamed from tests/test_server_events.c) | 6 | ||||
-rw-r--r-- | tests/unittests/test_server_events.h (renamed from tests/test_server_events.h) | 0 | ||||
-rw-r--r-- | tests/unittests/ui/stub_ui.c (renamed from tests/ui/stub_ui.c) | 87 | ||||
-rw-r--r-- | tests/unittests/ui/stub_ui.h (renamed from tests/ui/stub_ui.h) | 0 | ||||
-rw-r--r-- | tests/unittests/unittests.c (renamed from tests/testsuite.c) | 26 | ||||
-rw-r--r-- | tests/unittests/xmpp/stub_xmpp.c (renamed from tests/xmpp/stub_xmpp.c) | 12 | ||||
-rw-r--r-- | theme_template | 3 | ||||
-rw-r--r-- | themes/boothj5 | 5 | ||||
-rw-r--r-- | themes/complex | 2 | ||||
-rw-r--r-- | themes/simple | 3 |
136 files changed, 4556 insertions, 1641 deletions
diff --git a/.gitignore b/.gitignore index ba909849..fbf0a3fb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,68 +4,55 @@ # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ -profanity -profanity.sh -*.o -*.log -*.swp -testsuite -tags -cscope.out -.deps/ -build-aux/ + +# IDE +.codelite/ +profanity.mk +profanity.project +profanity.workspace +compile_commands.json + +# autotools +.libs/ Makefile Makefile.in +_configs.sed aclocal.m4 autom4te.cache/ -src/config.h -src/config.h.in +build-aux/ +config.log config.status configure -configure.scan -stamp-h1 -*~ -*dirstamp -valgrind*.out* -core -bugs/ -TODO -plugins/ -*_key.txt -*_fingerprints.txt -src/gitversion.h -src/gitversion.h.in -*_key.txt -*_fingerprints.txt -TAGS -.libs/ -_configs.sed libprofanity.la libtool -runvalgrind.sh -src/prof_config.h -clean.sh -valgrind.out.old -tests/testsuite.trs -push-all.sh -.DS_Store -.codelite/ -Profanity.project -Profanity.workspace -profanity.project -profanity.workspace -pageing.txt -cppcheck.out -gitpushall.sh -Debug/ -compile_commands.json -profanity.mk -profanity.project -profanity.workspace m4/ -test.sh +**/.deps/ +**.dirstamp +src/config.h +src/config.h.in +src/config.h.in~ +src/gitversion.h +src/gitversion.h.in +src/stamp-h1 + +# binaries +profanity +**/*.o + +# test output +tests/functionaltests/functionaltests +tests/functionaltests/functionaltests.log +tests/functionaltests/functionaltests.trs +tests/unittests/unittests +tests/unittests/unittests.log +tests/unittests/unittests.trs +test-suite.log + +# local scripts clean-test.sh -callgrind.out.* gen_docs.sh +gitpushall.sh + +# website files main_fragment.html toc_fragment.html diff --git a/.travis.yml b/.travis.yml index e546d8b3..ccc67e6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ language: c install: + - lsb_release -a + - uname -a - sudo apt-get update - - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev uuid-dev + - sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev libgpgme11-dev uuid-dev expect-dev tcl-dev - git clone git://github.com/strophe/libstrophe.git - cd libstrophe - mkdir m4 @@ -21,5 +23,14 @@ install: - sudo make install - cd ../.. - rm -rf cmocka-1.0.0 + - sudo apt-get install libmicrohttpd-dev + - git clone git://github.com/boothj5/stabber.git + - cd stabber + - ./bootstrap.sh + - ./configure --prefix=/usr + - make + - sudo make install + - cd .. + - rm -rf stabber - ./bootstrap.sh script: ./configure && make && make check diff --git a/CHANGELOG b/CHANGELOG index 519660db..0548c172 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ ===== - GNU Readline +- OpenPGP support - Message Carbons (xep-0280) - Message Delivery Receipts (xep-0184) - MUC Mediated Invitation support diff --git a/Makefile.am b/Makefile.am index 372b60f3..0486982d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,8 @@ core_sources = \ src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \ src/ui/titlebar.h src/ui/statusbar.h src/ui/inputwin.h \ src/ui/console.c src/ui/notifier.c \ - src/ui/windows.c src/ui/windows.h \ + src/ui/win_types.h \ + src/window_list.c src/window_list.h \ src/ui/rosterwin.c src/ui/occupantswin.c \ src/ui/buffer.c src/ui/buffer.h \ src/command/command.h src/command/command.c \ @@ -35,7 +36,7 @@ core_sources = \ src/config/preferences.c src/config/preferences.h \ src/config/theme.c src/config/theme.h -tests_sources = \ +unittest_sources = \ src/contact.c src/contact.h src/common.c \ src/log.h src/profanity.c src/common.h \ src/profanity.h src/chat_session.c \ @@ -46,6 +47,7 @@ tests_sources = \ src/xmpp/xmpp.h src/xmpp/form.c \ src/ui/ui.h \ src/otr/otr.h \ + src/pgp/gpg.h \ src/command/command.h src/command/command.c \ src/command/commands.h src/command/commands.c \ src/tools/parser.c \ @@ -57,55 +59,68 @@ tests_sources = \ src/config/account.c src/config/account.h \ src/config/preferences.c src/config/preferences.h \ src/config/theme.c src/config/theme.h \ - src/ui/windows.c src/ui/windows.h \ - src/ui/window.c src/ui/window.h \ - src/ui/buffer.c \ - src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \ - src/ui/titlebar.h src/ui/statusbar.h src/ui/inputwin.h \ + src/window_list.c src/window_list.h \ src/event/server_events.c src/event/server_events.h \ src/event/client_events.c src/event/client_events.h \ src/event/ui_events.c src/event/ui_events.h \ - tests/xmpp/stub_xmpp.c \ - tests/ui/stub_ui.c \ - tests/log/stub_log.c \ - tests/config/stub_accounts.c \ - tests/helpers.c tests/helpers.h \ - tests/test_cmd_account.c tests/test_cmd_account.h \ - tests/test_cmd_alias.c tests/test_cmd_alias.h \ - tests/test_cmd_bookmark.c tests/test_cmd_bookmark.h \ - tests/test_cmd_connect.c tests/test_cmd_connect.h \ - tests/test_cmd_join.c tests/test_cmd_join.h \ - tests/test_cmd_otr.c tests/test_cmd_otr.h \ - tests/test_cmd_rooms.c tests/test_cmd_rooms.h \ - tests/test_cmd_roster.c tests/test_cmd_roster.h \ - tests/test_cmd_statuses.c tests/test_cmd_statuses.h \ - tests/test_cmd_sub.c tests/test_cmd_sub.h \ - tests/test_cmd_disconnect.c tests/test_cmd_disconnect.h \ - tests/test_common.c tests/test_common.h \ - tests/test_contact.c tests/test_contact.h \ - tests/test_form.c tests/test_form.h \ - tests/test_jid.c tests/test_jid.h \ - tests/test_muc.c tests/test_muc.h \ - tests/test_parser.c tests/test_parser.h \ - tests/test_preferences.c tests/test_preferences.h \ - tests/test_roster_list.c tests/test_roster_list.h \ - tests/test_server_events.c tests/test_server_events.h \ - tests/test_autocomplete.c tests/test_autocomplete.h \ - tests/test_chat_session.c tests/test_chat_session.h \ - tests/testsuite.c + tests/unittests/xmpp/stub_xmpp.c \ + tests/unittests/ui/stub_ui.c \ + tests/unittests/log/stub_log.c \ + tests/unittests/config/stub_accounts.c \ + tests/unittests/helpers.c tests/unittests/helpers.h \ + tests/unittests/test_cmd_account.c tests/unittests/test_cmd_account.h \ + tests/unittests/test_cmd_alias.c tests/unittests/test_cmd_alias.h \ + tests/unittests/test_cmd_bookmark.c tests/unittests/test_cmd_bookmark.h \ + tests/unittests/test_cmd_connect.c tests/unittests/test_cmd_connect.h \ + tests/unittests/test_cmd_join.c tests/unittests/test_cmd_join.h \ + tests/unittests/test_cmd_otr.c tests/unittests/test_cmd_otr.h \ + tests/unittests/test_cmd_pgp.c tests/unittests/test_cmd_pgp.h \ + tests/unittests/test_cmd_rooms.c tests/unittests/test_cmd_rooms.h \ + tests/unittests/test_cmd_roster.c tests/unittests/test_cmd_roster.h \ + tests/unittests/test_cmd_statuses.c tests/unittests/test_cmd_statuses.h \ + tests/unittests/test_cmd_sub.c tests/unittests/test_cmd_sub.h \ + tests/unittests/test_cmd_disconnect.c tests/unittests/test_cmd_disconnect.h \ + tests/unittests/test_common.c tests/unittests/test_common.h \ + tests/unittests/test_contact.c tests/unittests/test_contact.h \ + tests/unittests/test_form.c tests/unittests/test_form.h \ + tests/unittests/test_jid.c tests/unittests/test_jid.h \ + tests/unittests/test_muc.c tests/unittests/test_muc.h \ + tests/unittests/test_parser.c tests/unittests/test_parser.h \ + tests/unittests/test_preferences.c tests/unittests/test_preferences.h \ + tests/unittests/test_roster_list.c tests/unittests/test_roster_list.h \ + tests/unittests/test_server_events.c tests/unittests/test_server_events.h \ + tests/unittests/test_autocomplete.c tests/unittests/test_autocomplete.h \ + tests/unittests/test_chat_session.c tests/unittests/test_chat_session.h \ + tests/unittests/unittests.c + +functionaltest_sources = \ + tests/functionaltests/proftest.c tests/functionaltests/proftest.h \ + tests/functionaltests/test_connect.c tests/functionaltests/test_connect.h \ + tests/functionaltests/test_ping.c tests/functionaltests/test_ping.h \ + tests/functionaltests/test_rooms.c tests/functionaltests/test_rooms.h \ + tests/functionaltests/test_presence.c tests/functionaltests/test_presence.h \ + tests/functionaltests/test_message.c tests/functionaltests/test_message.h \ + tests/functionaltests/test_chat_session.c tests/functionaltests/test_chat_session.h \ + tests/functionaltests/functionaltests.c main_source = src/main.c git_include = src/gitversion.h +pgp_sources = \ + src/pgp/gpg.h src/pgp/gpg.c + +pgp_unittest_sources = \ + tests/unittests/pgp/stub_gpg.c + otr3_sources = \ src/otr/otrlib.h src/otr/otrlibv3.c src/otr/otr.h src/otr/otr.c otr4_sources = \ src/otr/otrlib.h src/otr/otrlibv4.c src/otr/otr.h src/otr/otr.c -otr_test_sources = \ - tests/otr/stub_otr.c +otr_unittest_sources = \ + tests/unittests/otr/stub_otr.c themes_sources = themes/* @@ -113,8 +128,13 @@ script_sources = bootstrap.sh configure-debug install-all.sh man_sources = docs/profanity.1 +if BUILD_PGP +core_sources += $(pgp_sources) +unittest_sources += $(pgp_unittest_sources) +endif + if BUILD_OTR -tests_sources += $(otr_test_sources) +unittest_sources += $(otr_unittest_sources) if BUILD_OTR3 core_sources += $(otr3_sources) endif @@ -133,10 +153,13 @@ if INCLUDE_GIT_VERSION BUILT_SOURCES = $(git_include) endif -TESTS = tests/testsuite -check_PROGRAMS = tests/testsuite -tests_testsuite_SOURCES = $(tests_sources) -tests_testsuite_LDADD = -lcmocka +TESTS = tests/unittests/unittests tests/functionaltests/functionaltests +check_PROGRAMS = tests/unittests/unittests tests/functionaltests/functionaltests +tests_unittests_unittests_SOURCES = $(unittest_sources) +tests_unittests_unittests_LDADD = -lcmocka +tests_functionaltests_functionaltests_SOURCES = $(functionaltest_sources) +tests_functionaltests_functionaltests_CFLAGS = -I/usr/include/tcl8.6 -I/usr/include/tcl8.5 +tests_functionaltests_functionaltests_LDADD = -lcmocka -lstabber -lexpect -ltcl man_MANS = $(man_sources) @@ -165,3 +188,6 @@ $(git_include): $(git_include).in clean-local: rm -f $(git_include) $(git_include).in endif + +check-unit: tests/unittests/unittests + tests/unittests/unittests diff --git a/configure-debug b/configure-debug index 85bfd817..c61a0f50 100755 --- a/configure-debug +++ b/configure-debug @@ -1,3 +1,3 @@ #!/bin/sh -./configure CFLAGS='-g3 -O0' CXXFLAGS='-g3 -O0' +./configure CFLAGS='-g3 -O0' CXXFLAGS='-g3 -O0' $@ diff --git a/configure.ac b/configure.ac index 1e2c6173..1bf05a92 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,9 @@ AM_INIT_AUTOMAKE([foreign subdir-objects]) ### Checks for programs. AC_PROG_CC +## Check for LFS +AC_SYS_LARGEFILE + ### Get canonical host AC_CANONICAL_HOST PLATFORM="unknown" @@ -42,6 +45,8 @@ AC_ARG_ENABLE([notifications], [AS_HELP_STRING([--enable-notifications], [enable desktop notifications])]) AC_ARG_ENABLE([otr], [AS_HELP_STRING([--enable-otr], [enable otr encryption])]) +AC_ARG_ENABLE([pgp], + [AS_HELP_STRING([--enable-pgp], [enable pgp])]) AC_ARG_WITH([libxml2], [AS_HELP_STRING([--with-libxml2], [link with libxml2 instead of expat])]) AC_ARG_WITH([xscreensaver], @@ -186,10 +191,24 @@ elif test "x$with_xscreensaver" = x; then [AC_MSG_NOTICE([libX11 not found, falling back to profanity auto-away])]) fi +AM_CONDITIONAL([BUILD_PGP], [false]) +if test "x$enable_pgp" != xno; then + AC_CHECK_LIB([gpgme], [main], + [AM_CONDITIONAL([BUILD_PGP], [true]) + AC_DEFINE([HAVE_LIBGPGME], [1], [Have libgpgme]) + AC_PATH_PROG([GPGME_CONFIG], [gpgme-config], ["failed"]) + AS_IF([test "x$GPGME_CONFIG" = xfailed], + [LIBS="-lgpgme $LIBS"], + [LIBS="`$GPGME_CONFIG --libs` $LIBS" AM_CPPFLAGS="`$GPGME_CONFIG --cflags` $AM_CPPFLAGS"])], + [AS_IF([test "x$enable_pgp" = xyes], + [AC_MSG_ERROR([libgpgme is required for pgp support])], + [AC_MSG_NOTICE([libgpgme not found, pgp support not enabled])])]) +fi + AM_CONDITIONAL([BUILD_OTR], [false]) AM_CONDITIONAL([BUILD_OTR3], [false]) AM_CONDITIONAL([BUILD_OTR4], [false]) -if test "x$enable_otr" = xyes; then +if test "x$enable_otr" != xno; then AC_SEARCH_LIBS([otrl_init], [otr], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ @@ -203,22 +222,9 @@ if test "x$enable_otr" = xyes; then ]])], [AM_CONDITIONAL([BUILD_OTR], [true]) AM_CONDITIONAL([BUILD_OTR4], [true]) AC_DEFINE([HAVE_LIBOTR], [1], [Have libotr])], [AM_CONDITIONAL([BUILD_OTR], [true]) AM_CONDITIONAL([BUILD_OTR3], [true]) AC_DEFINE([HAVE_LIBOTR], [1], [Have libotr])])], - [AC_MSG_ERROR([libotr is required for otr encryption support])]) -elif test "x$enable_otr" = x; then - AC_SEARCH_LIBS([otrl_init], [otr], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #include <libotr/version.h> - ]],[[ - #if OTRL_VERSION_MAJOR == 4 - // OK - #else - # assume version 3 - #endif - ]])], - [AM_CONDITIONAL([BUILD_OTR], [true]) AM_CONDITIONAL([BUILD_OTR4], [true]) AC_DEFINE([HAVE_LIBOTR], [1], [Have libotr])], - [AM_CONDITIONAL([BUILD_OTR], [true]) AM_CONDITIONAL([BUILD_OTR3], [true]) AC_DEFINE([HAVE_LIBOTR], [1], [Have libotr])])], - [AC_MSG_NOTICE([libotr not found, otr encryption support not enabled])]) + [AS_IF([test "x$enable_otr" = xyes], + [AC_MSG_ERROR([libotr is required for otr encryption support])], + [AC_MSG_NOTICE([libotr not found, otr encryption support not enabled])])]) fi AS_IF([test "x$with_themes" = xno], @@ -235,6 +241,9 @@ AM_CONDITIONAL([THEMES_INSTALL], "$THEMES_INSTALL") PKG_CHECK_MODULES([cmocka], [cmocka], [], [AC_MSG_NOTICE([cmocka is not found, will not be able to run tests])]) +AC_CHECK_LIB([stabber], [stbbr_start], [LIBS="$LIBS"], + [AC_MSG_NOTICE([stabber not found, will not be able to run functional tests])]) + ### Check for ncursesw/ncurses.h first, Arch linux uses ncurses.h for ncursesw AC_CHECK_HEADERS([ncursesw/ncurses.h], [], []) AC_CHECK_HEADERS([ncurses.h], [], []) diff --git a/install-all.sh b/install-all.sh index 4ffc5999..0b1719a4 100755 --- a/install-all.sh +++ b/install-all.sh @@ -24,7 +24,7 @@ debian_prepare() echo echo Profanity installer... installing dependencies echo - sudo apt-get -y install git automake autoconf libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr5-dev libreadline-dev libtool uuid-dev + sudo apt-get -y install git automake autoconf libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr5-dev libreadline-dev libtool libgpgme11-dev uuid-dev } diff --git a/src/command/command.c b/src/command/command.c index 4086278c..105e41e5 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -66,42 +66,41 @@ #include "xmpp/xmpp.h" #include "xmpp/bookmark.h" #include "ui/ui.h" -#include "ui/windows.h" - -typedef char*(*autocompleter)(char*, int*); - -static gboolean _cmd_execute(const char * const command, const char * const inp); - -static char * _cmd_complete_parameters(const char * const input); - -static char * _sub_autocomplete(const char * const input); -static char * _notify_autocomplete(const char * const input); -static char * _theme_autocomplete(const char * const input); -static char * _autoaway_autocomplete(const char * const input); -static char * _autoconnect_autocomplete(const char * const input); -static char * _account_autocomplete(const char * const input); -static char * _who_autocomplete(const char * const input); -static char * _roster_autocomplete(const char * const input); -static char * _group_autocomplete(const char * const input); -static char * _bookmark_autocomplete(const char * const input); -static char * _otr_autocomplete(const char * const input); -static char * _connect_autocomplete(const char * const input); -static char * _statuses_autocomplete(const char * const input); -static char * _alias_autocomplete(const char * const input); -static char * _join_autocomplete(const char * const input); -static char * _log_autocomplete(const char * const input); -static char * _form_autocomplete(const char * const input); -static char * _form_field_autocomplete(const char * const input); -static char * _occupants_autocomplete(const char * const input); -static char * _kick_autocomplete(const char * const input); -static char * _ban_autocomplete(const char * const input); -static char * _affiliation_autocomplete(const char * const input); -static char * _role_autocomplete(const char * const input); -static char * _resource_autocomplete(const char * const input); -static char * _titlebar_autocomplete(const char * const input); -static char * _inpblock_autocomplete(const char * const input); -static char * _time_autocomplete(const char * const input); -static char * _receipts_autocomplete(const char * const input); +#include "window_list.h" + +static gboolean _cmd_execute(ProfWin *window, const char * const command, const char * const inp); + +static char * _cmd_complete_parameters(ProfWin *window, const char * const input); + +static char * _sub_autocomplete(ProfWin *window, const char * const input); +static char * _notify_autocomplete(ProfWin *window, const char * const input); +static char * _theme_autocomplete(ProfWin *window, const char * const input); +static char * _autoaway_autocomplete(ProfWin *window, const char * const input); +static char * _autoconnect_autocomplete(ProfWin *window, const char * const input); +static char * _account_autocomplete(ProfWin *window, const char * const input); +static char * _who_autocomplete(ProfWin *window, const char * const input); +static char * _roster_autocomplete(ProfWin *window, const char * const input); +static char * _group_autocomplete(ProfWin *window, const char * const input); +static char * _bookmark_autocomplete(ProfWin *window, const char * const input); +static char * _otr_autocomplete(ProfWin *window, const char * const input); +static char * _pgp_autocomplete(ProfWin *window, const char * const input); +static char * _connect_autocomplete(ProfWin *window, const char * const input); +static char * _statuses_autocomplete(ProfWin *window, const char * const input); +static char * _alias_autocomplete(ProfWin *window, const char * const input); +static char * _join_autocomplete(ProfWin *window, const char * const input); +static char * _log_autocomplete(ProfWin *window, const char * const input); +static char * _form_autocomplete(ProfWin *window, const char * const input); +static char * _form_field_autocomplete(ProfWin *window, const char * const input); +static char * _occupants_autocomplete(ProfWin *window, const char * const input); +static char * _kick_autocomplete(ProfWin *window, const char * const input); +static char * _ban_autocomplete(ProfWin *window, const char * const input); +static char * _affiliation_autocomplete(ProfWin *window, const char * const input); +static char * _role_autocomplete(ProfWin *window, const char * const input); +static char * _resource_autocomplete(ProfWin *window, const char * const input); +static char * _titlebar_autocomplete(ProfWin *window, const char * const input); +static char * _inpblock_autocomplete(ProfWin *window, const char * const input); +static char * _time_autocomplete(ProfWin *window, const char * const input); +static char * _receipts_autocomplete(ProfWin *window, const char * const input); GHashTable *commands = NULL; @@ -206,6 +205,7 @@ static struct cmd_t command_defs[] = "size : Percentage of the screen taken up by the roster (1-99).", "add jid [nick] : Add a new item to the roster.", "remove jid : Removes an item from the roster.", + "empty : Remove all items from roster." "nick jid nick : Change a contacts nickname.", "clearnick jid : Removes the current nickname.", "", @@ -668,6 +668,14 @@ static struct cmd_t command_defs[] = "If the terminal does not support sounds, it may attempt to flash the screen instead.", NULL } } }, + { "/encwarn", + cmd_encwarn, parse_args, 1, 1, &cons_encwarn_setting, + { "/encwarn on|off", "Titlebar encryption warning.", + { "/encwarn on|off", + "---------------", + "Enabled or disable the unencrypted warning message in the titlebar.", + NULL } } }, + { "/presence", cmd_presence, parse_args, 1, 1, &cons_presence_setting, { "/presence on|off", "Show the contacts presence in the titlebar.", @@ -684,6 +692,14 @@ static struct cmd_t command_defs[] = "Enable or disable word wrapping in the main window.", NULL } } }, + { "/winstidy", + cmd_winstidy, parse_args, 1, 1, &cons_winstidy_setting, + { "/winstidy on|off", "Auto tidy windows.", + { "/winstidy on|off", + "----------------", + "Enable or disable auto window tidy.", + NULL } } }, + { "/time", cmd_time, parse_args, 1, 3, &cons_time_setting, { "/time main|statusbar set|off [format]", "Time display.", @@ -855,6 +871,22 @@ static struct cmd_t command_defs[] = "Send chat state notifications during chat sessions.", NULL } } }, + { "/pgp", + cmd_pgp, parse_args, 1, 3, NULL, + { "/pgp command [args..]", "Open PGP commands.", + { "/pgp command [args..]", + "---------------------", + "Open PGP commands.", + "", + "keys : List all keys.", + "libver : Show which version of the libgpgme library is being used.", + "fps : Show known fingerprints.", + "setkey contact keyid : Manually associate a key ID with a JID.", + "start [contact] : Start PGP encrypted chat, current contact will be used if not specified.", + "end : End PGP encrypted chat with the current recipient.", + "log on|off|redact : PGP message logging, default: redact.", + NULL } } }, + { "/otr", cmd_otr, parse_args, 1, 3, NULL, { "/otr command [args..]", "Off The Record encryption commands.", @@ -1210,6 +1242,8 @@ static Autocomplete time_format_ac; static Autocomplete resource_ac; static Autocomplete inpblock_ac; static Autocomplete receipts_ac; +static Autocomplete pgp_ac; +static Autocomplete pgp_log_ac; /* * Initialise command autocompleter and history @@ -1269,6 +1303,7 @@ cmd_init(void) autocomplete_add(prefs_ac, "conn"); autocomplete_add(prefs_ac, "presence"); autocomplete_add(prefs_ac, "otr"); + autocomplete_add(prefs_ac, "pgp"); notify_ac = autocomplete_new(); autocomplete_add(notify_ac, "message"); @@ -1366,6 +1401,7 @@ cmd_init(void) autocomplete_add(account_set_ac, "muc"); autocomplete_add(account_set_ac, "nick"); autocomplete_add(account_set_ac, "otr"); + autocomplete_add(account_set_ac, "pgpkeyid"); account_clear_ac = autocomplete_new(); autocomplete_add(account_clear_ac, "password"); @@ -1373,6 +1409,7 @@ cmd_init(void) autocomplete_add(account_clear_ac, "server"); autocomplete_add(account_clear_ac, "port"); autocomplete_add(account_clear_ac, "otr"); + autocomplete_add(account_clear_ac, "pgpkeyid"); account_default_ac = autocomplete_new(); autocomplete_add(account_default_ac, "set"); @@ -1393,6 +1430,7 @@ cmd_init(void) autocomplete_add(roster_ac, "nick"); autocomplete_add(roster_ac, "clearnick"); autocomplete_add(roster_ac, "remove"); + autocomplete_add(roster_ac, "empty"); autocomplete_add(roster_ac, "show"); autocomplete_add(roster_ac, "hide"); autocomplete_add(roster_ac, "by"); @@ -1462,7 +1500,6 @@ cmd_init(void) autocomplete_add(otr_ac, "untrust"); autocomplete_add(otr_ac, "secret"); autocomplete_add(otr_ac, "log"); - autocomplete_add(otr_ac, "warn"); autocomplete_add(otr_ac, "libver"); autocomplete_add(otr_ac, "policy"); autocomplete_add(otr_ac, "question"); @@ -1571,6 +1608,20 @@ cmd_init(void) receipts_ac = autocomplete_new(); autocomplete_add(receipts_ac, "send"); autocomplete_add(receipts_ac, "request"); + + pgp_ac = autocomplete_new(); + autocomplete_add(pgp_ac, "keys"); + autocomplete_add(pgp_ac, "fps"); + autocomplete_add(pgp_ac, "setkey"); + autocomplete_add(pgp_ac, "libver"); + autocomplete_add(pgp_ac, "start"); + autocomplete_add(pgp_ac, "end"); + autocomplete_add(pgp_ac, "log"); + + pgp_log_ac = autocomplete_new(); + autocomplete_add(pgp_log_ac, "on"); + autocomplete_add(pgp_log_ac, "off"); + autocomplete_add(pgp_log_ac, "redact"); } void @@ -1630,6 +1681,8 @@ cmd_uninit(void) autocomplete_free(resource_ac); autocomplete_free(inpblock_ac); autocomplete_free(receipts_ac); + autocomplete_free(pgp_ac); + autocomplete_free(pgp_log_ac); } gboolean @@ -1714,7 +1767,7 @@ cmd_alias_remove(char *value) // Command autocompletion functions char* -cmd_autocomplete(const char * const input) +cmd_autocomplete(ProfWin *window, const char * const input) { // autocomplete command if ((strncmp(input, "/", 1) == 0) && (!str_contains(input, strlen(input), ' '))) { @@ -1726,7 +1779,7 @@ cmd_autocomplete(const char * const input) // autocomplete parameters } else { - char *found = _cmd_complete_parameters(input); + char *found = _cmd_complete_parameters(window, input); if (found) { return found; } @@ -1736,7 +1789,7 @@ cmd_autocomplete(const char * const input) } void -cmd_reset_autocomplete() +cmd_reset_autocomplete(ProfWin *window) { roster_reset_search_attempts(); muc_invites_reset_ac(); @@ -1802,23 +1855,28 @@ cmd_reset_autocomplete() autocomplete_reset(resource_ac); autocomplete_reset(inpblock_ac); autocomplete_reset(receipts_ac); + autocomplete_reset(pgp_ac); + autocomplete_reset(pgp_log_ac); - if (ui_current_win_type() == WIN_CHAT) { - ProfChatWin *chatwin = wins_get_current_chat(); + if (window->type == WIN_CHAT) { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); PContact contact = roster_get_contact(chatwin->barejid); if (contact) { p_contact_resource_ac_reset(contact); } } - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); muc_autocomplete_reset(mucwin->roomjid); muc_jid_autocomplete_reset(mucwin->roomjid); } - if (ui_current_win_type() == WIN_MUC_CONFIG) { - ProfMucConfWin *confwin = wins_get_current_muc_conf(); + if (window->type == WIN_MUC_CONFIG) { + ProfMucConfWin *confwin = (ProfMucConfWin*)window; + assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); if (confwin->form) { form_reset_autocompleters(confwin->form); } @@ -1832,11 +1890,11 @@ cmd_reset_autocomplete() * continue, FALSE otherwise */ gboolean -cmd_process_input(char *inp) +cmd_process_input(ProfWin *window, char *inp) { log_debug("Input received: %s", inp); gboolean result = FALSE; - g_strstrip(inp); + g_strchomp(inp); // just carry on if no input if (strlen(inp) == 0) { @@ -1846,12 +1904,12 @@ cmd_process_input(char *inp) } else if (inp[0] == '/') { char *inp_cpy = strdup(inp); char *command = strtok(inp_cpy, " "); - result = _cmd_execute(command, inp); + result = _cmd_execute(window, command, inp); free(inp_cpy); // call a default handler if input didn't start with '/' } else { - result = cmd_execute_default(inp); + result = cmd_execute_default(window, inp); } return result; @@ -1860,18 +1918,18 @@ cmd_process_input(char *inp) // Command execution void -cmd_execute_connect(const char * const account) +cmd_execute_connect(ProfWin *window, const char * const account) { GString *command = g_string_new("/connect "); g_string_append(command, account); - cmd_process_input(command->str); + cmd_process_input(window, command->str); g_string_free(command, TRUE); } static gboolean -_cmd_execute(const char * const command, const char * const inp) +_cmd_execute(ProfWin *window, const char * const command, const char * const inp) { - if (g_str_has_prefix(command, "/field") && ui_current_win_type() == WIN_MUC_CONFIG) { + if (g_str_has_prefix(command, "/field") && window->type == WIN_MUC_CONFIG) { gboolean result = FALSE; gchar **args = parse_args_with_freetext(inp, 1, 2, &result); if (!result) { @@ -1880,7 +1938,7 @@ _cmd_execute(const char * const command, const char * const inp) } else { gchar **tokens = g_strsplit(inp, " ", 2); char *field = tokens[0] + 1; - result = cmd_form_field(field, args); + result = cmd_form_field(window, field, args); g_strfreev(tokens); } @@ -1897,15 +1955,15 @@ _cmd_execute(const char * const command, const char * const inp) ui_invalid_command_usage(cmd->help.usage, cmd->setting_func); return TRUE; } else { - gboolean result = cmd->func(args, cmd->help); + gboolean result = cmd->func(window, args, cmd->help); g_strfreev(args); return result; } } else { gboolean ran_alias = FALSE; - gboolean alias_result = cmd_execute_alias(inp, &ran_alias); + gboolean alias_result = cmd_execute_alias(window, inp, &ran_alias); if (!ran_alias) { - return cmd_execute_default(inp); + return cmd_execute_default(window, inp); } else { return alias_result; } @@ -1913,7 +1971,7 @@ _cmd_execute(const char * const command, const char * const inp) } static char * -_cmd_complete_parameters(const char * const input) +_cmd_complete_parameters(ProfWin *window, const char * const input) { int i; char *result = NULL; @@ -1921,7 +1979,7 @@ _cmd_complete_parameters(const char * const input) // autocomplete boolean settings gchar *boolean_choices[] = { "/beep", "/intype", "/states", "/outtype", "/flash", "/splash", "/chlog", "/grlog", "/mouse", "/history", - "/vercheck", "/privileges", "/presence", "/wrap", "/carbons" }; + "/vercheck", "/privileges", "/presence", "/wrap", "/winstidy", "/carbons", "/encwarn" }; for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); @@ -1931,8 +1989,9 @@ _cmd_complete_parameters(const char * const input) } // autocomplete nickname in chat rooms - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid); if (nick_ac) { gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ; @@ -2008,6 +2067,7 @@ _cmd_complete_parameters(const char * const input) g_hash_table_insert(ac_funcs, "/bookmark", _bookmark_autocomplete); g_hash_table_insert(ac_funcs, "/autoconnect", _autoconnect_autocomplete); g_hash_table_insert(ac_funcs, "/otr", _otr_autocomplete); + g_hash_table_insert(ac_funcs, "/pgp", _pgp_autocomplete); g_hash_table_insert(ac_funcs, "/connect", _connect_autocomplete); g_hash_table_insert(ac_funcs, "/statuses", _statuses_autocomplete); g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete); @@ -2037,9 +2097,9 @@ _cmd_complete_parameters(const char * const input) } parsed[i] = '\0'; - char * (*ac_func)(const char * const) = g_hash_table_lookup(ac_funcs, parsed); + char * (*ac_func)(ProfWin*, const char * const) = g_hash_table_lookup(ac_funcs, parsed); if (ac_func) { - result = ac_func(input); + result = ac_func(window, input); if (result) { g_hash_table_destroy(ac_funcs); return result; @@ -2048,7 +2108,7 @@ _cmd_complete_parameters(const char * const input) g_hash_table_destroy(ac_funcs); if (g_str_has_prefix(input, "/field")) { - result = _form_field_autocomplete(input); + result = _form_field_autocomplete(window, input); if (result) { return result; } @@ -2058,7 +2118,7 @@ _cmd_complete_parameters(const char * const input) } static char * -_sub_autocomplete(const char * const input) +_sub_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/sub allow", presence_sub_request_find); @@ -2078,12 +2138,11 @@ _sub_autocomplete(const char * const input) } static char * -_who_autocomplete(const char * const input) +_who_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; - win_type_t win_type = ui_current_win_type(); - if (win_type == WIN_MUC) { + if (window->type == WIN_MUC) { result = autocomplete_param_with_ac(input, "/who", who_room_ac, TRUE); if (result) { return result; @@ -2111,7 +2170,7 @@ _who_autocomplete(const char * const input) } static char * -_roster_autocomplete(const char * const input) +_roster_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/roster nick", roster_barejid_autocomplete); @@ -2147,7 +2206,7 @@ _roster_autocomplete(const char * const input) } static char * -_group_autocomplete(const char * const input) +_group_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/group show", roster_group_autocomplete); @@ -2180,7 +2239,7 @@ _group_autocomplete(const char * const input) } static char * -_bookmark_autocomplete(const char * const input) +_bookmark_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2259,7 +2318,7 @@ _bookmark_autocomplete(const char * const input) } static char * -_notify_autocomplete(const char * const input) +_notify_autocomplete(ProfWin *window, const char * const input) { int i = 0; char *result = NULL; @@ -2322,7 +2381,7 @@ _notify_autocomplete(const char * const input) } static char * -_autoaway_autocomplete(const char * const input) +_autoaway_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2344,7 +2403,7 @@ _autoaway_autocomplete(const char * const input) } static char * -_log_autocomplete(const char * const input) +_log_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2367,7 +2426,7 @@ _log_autocomplete(const char * const input) } static char * -_autoconnect_autocomplete(const char * const input) +_autoconnect_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2385,7 +2444,7 @@ _autoconnect_autocomplete(const char * const input) } static char * -_otr_autocomplete(const char * const input) +_otr_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2423,13 +2482,35 @@ _otr_autocomplete(const char * const input) return found; } - found = autocomplete_param_with_func(input, "/otr warn", - prefs_autocomplete_boolean_choice); + found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE); if (found) { return found; } - found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE); + return NULL; +} + +static char * +_pgp_autocomplete(ProfWin *window, const char * const input) +{ + char *found = NULL; + + found = autocomplete_param_with_func(input, "/pgp start", roster_contact_autocomplete); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/pgp log", pgp_log_ac, TRUE); + if (found) { + return found; + } + + found = autocomplete_param_with_func(input, "/pgp setkey", roster_barejid_autocomplete); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/pgp", pgp_ac, TRUE); if (found) { return found; } @@ -2438,7 +2519,7 @@ _otr_autocomplete(const char * const input) } static char * -_theme_autocomplete(const char * const input) +_theme_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; if ((strncmp(input, "/theme load ", 12) == 0) && (strlen(input) > 12)) { @@ -2467,13 +2548,13 @@ _theme_autocomplete(const char * const input) } static char * -_resource_autocomplete(const char * const input) +_resource_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; - ProfWin *current = wins_get_current(); - if (current && current->type == WIN_CHAT) { - ProfChatWin *chatwin = wins_get_current_chat(); + if (window->type == WIN_CHAT) { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); PContact contact = roster_get_contact(chatwin->barejid); if (contact) { Autocomplete ac = p_contact_resource_ac(contact); @@ -2503,7 +2584,7 @@ _resource_autocomplete(const char * const input) } static char * -_titlebar_autocomplete(const char * const input) +_titlebar_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2526,7 +2607,7 @@ _titlebar_autocomplete(const char * const input) } static char * -_inpblock_autocomplete(const char * const input) +_inpblock_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2544,16 +2625,15 @@ _inpblock_autocomplete(const char * const input) } static char * -_form_autocomplete(const char * const input) +_form_autocomplete(ProfWin *window, const char * const input) { - ProfWin *current = wins_get_current(); - if (current->type != WIN_MUC_CONFIG) { + if (window->type != WIN_MUC_CONFIG) { return NULL; } char *found = NULL; - ProfMucConfWin *confwin = (ProfMucConfWin*)current; + ProfMucConfWin *confwin = (ProfMucConfWin*)window; DataForm *form = confwin->form; if (form) { found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE); @@ -2571,16 +2651,15 @@ _form_autocomplete(const char * const input) } static char * -_form_field_autocomplete(const char * const input) +_form_field_autocomplete(ProfWin *window, const char * const input) { - ProfWin *current = wins_get_current(); - if (current->type != WIN_MUC_CONFIG) { + if (window->type != WIN_MUC_CONFIG) { return NULL; } char *found = NULL; - ProfMucConfWin *confwin = (ProfMucConfWin*)current; + ProfMucConfWin *confwin = (ProfMucConfWin*)window; DataForm *form = confwin->form; if (form == NULL) { return NULL; @@ -2642,7 +2721,7 @@ _form_field_autocomplete(const char * const input) } static char * -_occupants_autocomplete(const char * const input) +_occupants_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2680,7 +2759,7 @@ _occupants_autocomplete(const char * const input) } static char * -_time_autocomplete(const char * const input) +_time_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; @@ -2703,12 +2782,13 @@ _time_autocomplete(const char * const input) } static char * -_kick_autocomplete(const char * const input) +_kick_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid); if (nick_ac) { @@ -2723,12 +2803,13 @@ _kick_autocomplete(const char * const input) } static char * -_ban_autocomplete(const char * const input) +_ban_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid); if (jid_ac) { @@ -2743,12 +2824,13 @@ _ban_autocomplete(const char * const input) } static char * -_affiliation_autocomplete(const char * const input) +_affiliation_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); gboolean parse_result; Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid); @@ -2790,12 +2872,13 @@ _affiliation_autocomplete(const char * const input) } static char * -_role_autocomplete(const char * const input) +_role_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; - if (ui_current_win_type() == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); gboolean parse_result; Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid); @@ -2837,7 +2920,7 @@ _role_autocomplete(const char * const input) } static char * -_statuses_autocomplete(const char * const input) +_statuses_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2865,7 +2948,7 @@ _statuses_autocomplete(const char * const input) } static char * -_receipts_autocomplete(const char * const input) +_receipts_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2888,7 +2971,7 @@ _receipts_autocomplete(const char * const input) } static char * -_alias_autocomplete(const char * const input) +_alias_autocomplete(ProfWin *window, const char * const input) { char *result = NULL; @@ -2906,7 +2989,7 @@ _alias_autocomplete(const char * const input) } static char * -_connect_autocomplete(const char * const input) +_connect_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; gboolean result = FALSE; @@ -2941,7 +3024,7 @@ _connect_autocomplete(const char * const input) } static char * -_join_autocomplete(const char * const input) +_join_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; gboolean result = FALSE; @@ -2976,7 +3059,7 @@ _join_autocomplete(const char * const input) } static char * -_account_autocomplete(const char * const input) +_account_autocomplete(ProfWin *window, const char * const input) { char *found = NULL; gboolean result = FALSE; diff --git a/src/command/command.h b/src/command/command.h index b500404b..e6fc7ead 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -38,14 +38,15 @@ #include <glib.h> #include "xmpp/form.h" +#include "ui/ui.h" GHashTable *commands; void cmd_init(void); void cmd_uninit(void); -char* cmd_autocomplete(const char * const input); -void cmd_reset_autocomplete(void); +char* cmd_autocomplete(ProfWin *window, const char * const input); +void cmd_reset_autocomplete(ProfWin *window); void cmd_autocomplete_add(char *value); void cmd_autocomplete_remove(char *value); void cmd_autocomplete_add_form_fields(DataForm *form); @@ -53,8 +54,8 @@ void cmd_autocomplete_remove_form_fields(DataForm *form); void cmd_alias_add(char *value); void cmd_alias_remove(char *value); -gboolean cmd_process_input(char *inp); -void cmd_execute_connect(const char * const account); +gboolean cmd_process_input(ProfWin *window, char *inp); +void cmd_execute_connect(ProfWin *window, const char * const account); gboolean cmd_exists(char *cmd); diff --git a/src/command/commands.c b/src/command/commands.c index c5350519..7f13d5f5 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -57,6 +57,9 @@ #ifdef HAVE_LIBOTR #include "otr/otr.h" #endif +#ifdef HAVE_LIBGPGME +#include "pgp/gpg.h" +#endif #include "profanity.h" #include "tools/autocomplete.h" #include "tools/parser.h" @@ -64,7 +67,7 @@ #include "xmpp/xmpp.h" #include "xmpp/bookmark.h" #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" #include "event/client_events.h" #include "event/ui_events.h" @@ -74,13 +77,13 @@ static gboolean _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help, const char * const display, preference_t pref); static void _cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size); static gint _compare_commands(Command *a, Command *b); -static void _who_room(gchar **args, struct cmd_help_t help); -static void _who_roster(gchar **args, struct cmd_help_t help); +static void _who_room(ProfWin *window, gchar **args, struct cmd_help_t help); +static void _who_roster(ProfWin *window, gchar **args, struct cmd_help_t help); extern GHashTable *commands; gboolean -cmd_execute_default(const char * inp) +cmd_execute_default(ProfWin *window, const char * inp) { // handle escaped commands - treat as normal message if (g_str_has_prefix(inp, "//")) { @@ -94,8 +97,7 @@ cmd_execute_default(const char * inp) } // handle non commands in non chat windows - ProfWin *current = wins_get_current(); - if (current->type != WIN_CHAT && current->type != WIN_MUC && current->type != WIN_PRIVATE) { + if (window->type != WIN_CHAT && window->type != WIN_MUC && window->type != WIN_PRIVATE) { cons_show("Unknown command: %s", inp); return TRUE; } @@ -106,22 +108,25 @@ cmd_execute_default(const char * inp) return TRUE; } - switch (current->type) { + switch (window->type) { case WIN_CHAT: { - ProfChatWin *chatwin = wins_get_current_chat(); + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); cl_ev_send_msg(chatwin, inp); break; } case WIN_PRIVATE: { - ProfPrivateWin *privatewin = wins_get_current_private(); + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); cl_ev_send_priv_msg(privatewin, inp); break; } case WIN_MUC: { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); cl_ev_send_muc_msg(mucwin, inp); break; } @@ -133,7 +138,7 @@ cmd_execute_default(const char * inp) } gboolean -cmd_execute_alias(const char * const inp, gboolean *ran) +cmd_execute_alias(ProfWin *window, const char * const inp, gboolean *ran) { if (inp[0] != '/') { ran = FALSE; @@ -145,7 +150,7 @@ cmd_execute_alias(const char * const inp, gboolean *ran) free(alias); if (value) { *ran = TRUE; - return cmd_process_input(value); + return cmd_process_input(window, value); } *ran = FALSE; @@ -153,7 +158,7 @@ cmd_execute_alias(const char * const inp, gboolean *ran) } gboolean -cmd_connect(gchar **args, struct cmd_help_t help) +cmd_connect(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); if ((conn_status != JABBER_DISCONNECTED) && (conn_status != JABBER_STARTED)) { @@ -221,6 +226,7 @@ cmd_connect(gchar **args, struct cmd_help_t help) } else { cons_show("Error evaluating password, see logs for details."); g_free(lower); + account_free(account); return TRUE; } @@ -233,6 +239,7 @@ cmd_connect(gchar **args, struct cmd_help_t help) } jid = account_create_full_jid(account); + account_free(account); // connect with JID } else { @@ -255,7 +262,7 @@ cmd_connect(gchar **args, struct cmd_help_t help) } gboolean -cmd_account(gchar **args, struct cmd_help_t help) +cmd_account(ProfWin *window, gchar **args, struct cmd_help_t help) { char *command = args[0]; @@ -431,7 +438,11 @@ cmd_account(gchar **args, struct cmd_help_t help) } } else if (strcmp(property, "resource") == 0) { accounts_set_resource(account_name, value); - cons_show("Updated resource for account %s: %s", account_name, value); + if (jabber_get_connection_status() == JABBER_CONNECTED) { + cons_show("Updated resource for account %s: %s, you will need to reconnect to pick up the change.", account_name, value); + } else { + cons_show("Updated resource for account %s: %s", account_name, value); + } cons_show(""); } else if (strcmp(property, "password") == 0) { if(accounts_get_account(account_name)->eval_password) { @@ -475,6 +486,10 @@ cmd_account(gchar **args, struct cmd_help_t help) cons_show("Updated login status for account %s: %s", account_name, value); } cons_show(""); + } else if (strcmp(property, "pgpkeyid") == 0) { + accounts_set_pgp_keyid(account_name, value); + cons_show("Updated PGP key ID for account %s: %s", account_name, value); + cons_show(""); } else if (valid_resource_presence_string(property)) { int intval; char *err_msg = NULL; @@ -553,6 +568,10 @@ cmd_account(gchar **args, struct cmd_help_t help) accounts_clear_otr(account_name); cons_show("OTR policy removed for account %s", account_name); cons_show(""); + } else if (strcmp(property, "pgpkeyid") == 0) { + accounts_clear_pgp_keyid(account_name); + cons_show("Removed PGP key ID for account %s", account_name); + cons_show(""); } else { cons_show("Invalid property: %s", property); cons_show(""); @@ -567,7 +586,7 @@ cmd_account(gchar **args, struct cmd_help_t help) } gboolean -cmd_sub(gchar **args, struct cmd_help_t help) +cmd_sub(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -595,14 +614,14 @@ cmd_sub(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if ((win_type != WIN_CHAT) && (jid == NULL)) { + if ((window->type != WIN_CHAT) && (jid == NULL)) { cons_show("You must specify a contact."); return TRUE; } if (jid == NULL) { - ProfChatWin *chatwin = wins_get_current_chat(); + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); jid = chatwin->barejid; } @@ -623,13 +642,13 @@ cmd_sub(gchar **args, struct cmd_help_t help) } else if (strcmp(subcmd, "show") == 0) { PContact contact = roster_get_contact(jidp->barejid); if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) { - if (win_type == WIN_CHAT) { + if (window->type == WIN_CHAT) { ui_current_print_line("No subscription information for %s.", jidp->barejid); } else { cons_show("No subscription information for %s.", jidp->barejid); } } else { - if (win_type == WIN_CHAT) { + if (window->type == WIN_CHAT) { if (p_contact_pending_out(contact)) { ui_current_print_line("%s subscription status: %s, request pending.", jidp->barejid, p_contact_subscription(contact)); @@ -657,7 +676,7 @@ cmd_sub(gchar **args, struct cmd_help_t help) } gboolean -cmd_disconnect(gchar **args, struct cmd_help_t help) +cmd_disconnect(ProfWin *window, gchar **args, struct cmd_help_t help) { if (jabber_get_connection_status() == JABBER_CONNECTED) { char *jid = strdup(jabber_get_fulljid()); @@ -667,6 +686,9 @@ cmd_disconnect(gchar **args, struct cmd_help_t help) muc_invites_clear(); chat_sessions_clear(); ui_disconnected(); +#ifdef HAVE_LIBGPGME + p_gpg_on_disconnect(); +#endif free(jid); } else { cons_show("You are not currently connected."); @@ -676,7 +698,7 @@ cmd_disconnect(gchar **args, struct cmd_help_t help) } gboolean -cmd_quit(gchar **args, struct cmd_help_t help) +cmd_quit(ProfWin *window, gchar **args, struct cmd_help_t help) { log_info("Profanity is shutting down..."); exit(0); @@ -684,12 +706,16 @@ cmd_quit(gchar **args, struct cmd_help_t help) } gboolean -cmd_wins(gchar **args, struct cmd_help_t help) +cmd_wins(ProfWin *window, gchar **args, struct cmd_help_t help) { if (args[0] == NULL) { cons_show_wins(); } else if (strcmp(args[0], "tidy") == 0) { - ui_tidy_wins(); + if (ui_tidy_wins()) { + cons_show("Windows tidied."); + } else { + cons_show("No tidy needed."); + } } else if (strcmp(args[0], "prune") == 0) { ui_prune_wins(); } else if (strcmp(args[0], "swap") == 0) { @@ -719,22 +745,34 @@ cmd_wins(gchar **args, struct cmd_help_t help) } gboolean -cmd_win(gchar **args, struct cmd_help_t help) +cmd_winstidy(ProfWin *window, gchar **args, struct cmd_help_t help) +{ + gboolean result = _cmd_set_boolean_preference(args[0], help, "Wins Auto Tidy", PREF_WINS_AUTO_TIDY); + + if (result && g_strcmp0(args[0], "on") == 0) { + ui_tidy_wins(); + } + + return result; +} + +gboolean +cmd_win(ProfWin *window, gchar **args, struct cmd_help_t help) { int num = atoi(args[0]); - ProfWin *window = wins_get_by_num(num); - if (!window) { + ProfWin *focuswin = wins_get_by_num(num); + if (!focuswin) { cons_show("Window %d does not exist.", num); } else { - ui_ev_focus_win(window); + ui_ev_focus_win(focuswin); } return TRUE; } gboolean -cmd_help(gchar **args, struct cmd_help_t help) +cmd_help(ProfWin *window, gchar **args, struct cmd_help_t help) { int num_args = g_strv_length(args); if (num_args == 0) { @@ -804,7 +842,7 @@ cmd_help(gchar **args, struct cmd_help_t help) "/carbons", "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority", "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme", - "/titlebar", "/vercheck", "/privileges", "/occupants", "/presence", "/wrap" }; + "/titlebar", "/vercheck", "/privileges", "/occupants", "/presence", "/wrap", "/winstidy" }; _cmd_show_filtered_help("Settings commands", filter, ARRAY_SIZE(filter)); } else if (strcmp(args[0], "navigation") == 0) { @@ -836,14 +874,14 @@ cmd_help(gchar **args, struct cmd_help_t help) } gboolean -cmd_about(gchar **args, struct cmd_help_t help) +cmd_about(ProfWin *window, gchar **args, struct cmd_help_t help) { ui_about(); return TRUE; } gboolean -cmd_prefs(gchar **args, struct cmd_help_t help) +cmd_prefs(ProfWin *window, gchar **args, struct cmd_help_t help) { if (args[0] == NULL) { cons_prefs(); @@ -876,6 +914,10 @@ cmd_prefs(gchar **args, struct cmd_help_t help) cons_show(""); cons_show_otr_prefs(); cons_show(""); + } else if (strcmp(args[0], "pgp") == 0) { + cons_show(""); + cons_show_pgp_prefs(); + cons_show(""); } else { cons_show("Usage: %s", help.usage); } @@ -884,7 +926,7 @@ cmd_prefs(gchar **args, struct cmd_help_t help) } gboolean -cmd_theme(gchar **args, struct cmd_help_t help) +cmd_theme(ProfWin *window, gchar **args, struct cmd_help_t help) { // list themes if (g_strcmp0(args[0], "list") == 0) { @@ -926,7 +968,7 @@ cmd_theme(gchar **args, struct cmd_help_t help) } static void -_who_room(gchar **args, struct cmd_help_t help) +_who_room(ProfWin *window, gchar **args, struct cmd_help_t help) { if ((g_strv_length(args) == 2) && args[1]) { cons_show("Argument group is not applicable to chat rooms."); @@ -954,7 +996,8 @@ _who_room(gchar **args, struct cmd_help_t help) return; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); // presence filter if (args[0] == NULL || @@ -1055,7 +1098,7 @@ _who_room(gchar **args, struct cmd_help_t help) } static void -_who_roster(gchar **args, struct cmd_help_t help) +_who_roster(ProfWin *window, gchar **args, struct cmd_help_t help) { char *presence = args[0]; @@ -1268,20 +1311,19 @@ _who_roster(gchar **args, struct cmd_help_t help) } gboolean -cmd_who(gchar **args, struct cmd_help_t help) +cmd_who(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); - } else if (win_type == WIN_MUC) { - _who_room(args, help); + } else if (window->type == WIN_MUC) { + _who_room(window, args, help); } else { - _who_roster(args, help); + _who_roster(window, args, help); } - if (win_type != WIN_CONSOLE && win_type != WIN_MUC) { + if (window->type != WIN_CONSOLE && window->type != WIN_MUC) { ui_statusbar_new(1); } @@ -1289,13 +1331,12 @@ cmd_who(gchar **args, struct cmd_help_t help) } gboolean -cmd_msg(gchar **args, struct cmd_help_t help) +cmd_msg(ProfWin *window, gchar **args, struct cmd_help_t help) { char *usr = args[0]; char *msg = args[1]; jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); @@ -1303,8 +1344,9 @@ cmd_msg(gchar **args, struct cmd_help_t help) } // send private message when in MUC room - if (win_type == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); if (muc_roster_contains_nick(mucwin->roomjid, usr)) { GString *full_jid = g_string_new(mucwin->roomjid); g_string_append(full_jid, "/"); @@ -1356,7 +1398,7 @@ cmd_msg(gchar **args, struct cmd_help_t help) } gboolean -cmd_group(gchar **args, struct cmd_help_t help) +cmd_group(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -1463,17 +1505,17 @@ cmd_group(gchar **args, struct cmd_help_t help) } gboolean -cmd_roster(gchar **args, struct cmd_help_t help) +cmd_roster(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - if (conn_status != JABBER_CONNECTED) { - cons_show("You are not currently connected."); - return TRUE; - } - // show roster if (args[0] == NULL) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + GSList *list = roster_get_contacts(); cons_show_roster(list); g_slist_free(list); @@ -1481,6 +1523,11 @@ cmd_roster(gchar **args, struct cmd_help_t help) // show roster, only online contacts } else if(g_strcmp0(args[0], "online") == 0){ + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + GSList *list = roster_get_contacts_online(); cons_show_roster(list); g_slist_free(list); @@ -1498,7 +1545,7 @@ cmd_roster(gchar **args, struct cmd_help_t help) if (res) { prefs_set_roster_size(intval); cons_show("Roster screen size set to: %d%%", intval); - if (prefs_get_boolean(PREF_ROSTER)) { + if (conn_status == JABBER_CONNECTED && prefs_get_boolean(PREF_ROSTER)) { wins_resize_all(); } return TRUE; @@ -1513,17 +1560,23 @@ cmd_roster(gchar **args, struct cmd_help_t help) if (args[1] == NULL) { cons_show("Roster enabled."); prefs_set_boolean(PREF_ROSTER, TRUE); - ui_show_roster(); + if (conn_status == JABBER_CONNECTED) { + ui_show_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "offline") == 0) { cons_show("Roster offline enabled"); prefs_set_boolean(PREF_ROSTER_OFFLINE, TRUE); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "resource") == 0) { cons_show("Roster resource enabled"); prefs_set_boolean(PREF_ROSTER_RESOURCE, TRUE); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else { cons_show("Usage: %s", help.usage); @@ -1533,17 +1586,23 @@ cmd_roster(gchar **args, struct cmd_help_t help) if (args[1] == NULL) { cons_show("Roster disabled."); prefs_set_boolean(PREF_ROSTER, FALSE); - ui_hide_roster(); + if (conn_status == JABBER_CONNECTED) { + ui_hide_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "offline") == 0) { cons_show("Roster offline disabled"); prefs_set_boolean(PREF_ROSTER_OFFLINE, FALSE); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "resource") == 0) { cons_show("Roster resource disabled"); prefs_set_boolean(PREF_ROSTER_RESOURCE, FALSE); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else { cons_show("Usage: %s", help.usage); @@ -1554,17 +1613,23 @@ cmd_roster(gchar **args, struct cmd_help_t help) if (g_strcmp0(args[1], "group") == 0) { cons_show("Grouping roster by roster group"); prefs_set_string(PREF_ROSTER_BY, "group"); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "presence") == 0) { cons_show("Grouping roster by presence"); prefs_set_string(PREF_ROSTER_BY, "presence"); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else if (g_strcmp0(args[1], "none") == 0) { cons_show("Roster grouping disabled"); prefs_set_string(PREF_ROSTER_BY, "none"); - rosterwin_roster(); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } return TRUE; } else { cons_show("Usage: %s", help.usage); @@ -1572,6 +1637,10 @@ cmd_roster(gchar **args, struct cmd_help_t help) } // add contact } else if (strcmp(args[0], "add") == 0) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } char *jid = args[1]; if (jid == NULL) { cons_show("Usage: %s", help.usage); @@ -1583,6 +1652,10 @@ cmd_roster(gchar **args, struct cmd_help_t help) // remove contact } else if (strcmp(args[0], "remove") == 0) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } char *jid = args[1]; if (jid == NULL) { cons_show("Usage: %s", help.usage); @@ -1591,8 +1664,29 @@ cmd_roster(gchar **args, struct cmd_help_t help) } return TRUE; + } else if (strcmp(args[0], "empty") == 0) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + + GSList *all = roster_get_contacts(); + GSList *curr = all; + while (curr) { + PContact contact = curr->data; + roster_send_remove(p_contact_barejid(contact)); + curr = g_slist_next(curr); + } + + g_slist_free(all); + return TRUE; + // change nickname } else if (strcmp(args[0], "nick") == 0) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } char *jid = args[1]; if (jid == NULL) { cons_show("Usage: %s", help.usage); @@ -1623,6 +1717,10 @@ cmd_roster(gchar **args, struct cmd_help_t help) // remove nickname } else if (strcmp(args[0], "clearnick") == 0) { + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } char *jid = args[1]; if (jid == NULL) { cons_show("Usage: %s", help.usage); @@ -1651,7 +1749,7 @@ cmd_roster(gchar **args, struct cmd_help_t help) } gboolean -cmd_resource(gchar **args, struct cmd_help_t help) +cmd_resource(ProfWin *window, gchar **args, struct cmd_help_t help) { char *cmd = args[0]; char *setting = NULL; @@ -1673,12 +1771,11 @@ cmd_resource(gchar **args, struct cmd_help_t help) } } - ProfWin *current = wins_get_current(); - if (current->type != WIN_CHAT) { + if (window->type != WIN_CHAT) { cons_show("Resource can only be changed in chat windows."); return TRUE; } - ProfChatWin *chatwin = (ProfChatWin*)current; + ProfChatWin *chatwin = (ProfChatWin*)window; if (g_strcmp0(cmd, "set") == 0) { char *resource = args[1]; @@ -1724,24 +1821,23 @@ cmd_resource(gchar **args, struct cmd_help_t help) } gboolean -cmd_status(gchar **args, struct cmd_help_t help) +cmd_status(ProfWin *window, gchar **args, struct cmd_help_t help) { char *usr = args[0]; jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); return TRUE; } - switch (win_type) + switch (window->type) { case WIN_MUC: if (usr) { - ProfMucWin *mucwin = wins_get_current_muc(); - ProfWin *window = (ProfWin*) mucwin; + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); Occupant *occupant = muc_roster_item(mucwin->roomjid, usr); if (occupant) { win_show_occupant(window, occupant); @@ -1756,8 +1852,8 @@ cmd_status(gchar **args, struct cmd_help_t help) if (usr) { ui_current_print_line("No parameter required when in chat."); } else { - ProfChatWin *chatwin = wins_get_current_chat(); - ProfWin *window = (ProfWin*) chatwin; + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); PContact pcontact = roster_get_contact(chatwin->barejid); if (pcontact) { win_show_contact(window, pcontact); @@ -1770,8 +1866,8 @@ cmd_status(gchar **args, struct cmd_help_t help) if (usr) { ui_current_print_line("No parameter required when in chat."); } else { - ProfPrivateWin *privatewin = wins_get_current_private(); - ProfWin *window = (ProfWin*) privatewin; + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); Jid *jid = jid_create(privatewin->fulljid); Occupant *occupant = muc_roster_item(jid->barejid, jid->resourcepart); if (occupant) { @@ -1801,12 +1897,11 @@ cmd_status(gchar **args, struct cmd_help_t help) } gboolean -cmd_info(gchar **args, struct cmd_help_t help) +cmd_info(ProfWin *window, gchar **args, struct cmd_help_t help) { char *usr = args[0]; jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); PContact pcontact = NULL; if (conn_status != JABBER_CONNECTED) { @@ -1814,20 +1909,21 @@ cmd_info(gchar **args, struct cmd_help_t help) return TRUE; } - switch (win_type) + switch (window->type) { case WIN_MUC: if (usr) { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); Occupant *occupant = muc_roster_item(mucwin->roomjid, usr); if (occupant) { - ProfWin *current = wins_get_current(); - win_show_occupant_info(current, mucwin->roomjid, occupant); + win_show_occupant_info(window, mucwin->roomjid, occupant); } else { ui_current_print_line("No such occupant \"%s\" in room.", usr); } } else { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); iq_room_info_request(mucwin->roomjid, TRUE); ui_show_room_info(mucwin); return TRUE; @@ -1837,8 +1933,8 @@ cmd_info(gchar **args, struct cmd_help_t help) if (usr) { ui_current_print_line("No parameter required when in chat."); } else { - ProfChatWin *chatwin = wins_get_current_chat(); - ProfWin *window = (ProfWin*) chatwin; + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); PContact pcontact = roster_get_contact(chatwin->barejid); if (pcontact) { win_show_info(window, pcontact); @@ -1851,8 +1947,8 @@ cmd_info(gchar **args, struct cmd_help_t help) if (usr) { ui_current_print_line("No parameter required when in chat."); } else { - ProfPrivateWin *privatewin = wins_get_current_private(); - ProfWin *window = (ProfWin*) privatewin; + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); Jid *jid = jid_create(privatewin->fulljid); Occupant *occupant = muc_roster_item(jid->barejid, jid->resourcepart); if (occupant) { @@ -1887,10 +1983,9 @@ cmd_info(gchar **args, struct cmd_help_t help) } gboolean -cmd_caps(gchar **args, struct cmd_help_t help) +cmd_caps(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); PContact pcontact = NULL; Occupant *occupant = NULL; @@ -1899,11 +1994,12 @@ cmd_caps(gchar **args, struct cmd_help_t help) return TRUE; } - switch (win_type) + switch (window->type) { case WIN_MUC: if (args[0]) { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); occupant = muc_roster_item(mucwin->roomjid, args[0]); if (occupant) { Jid *jidp = jid_create_from_bare_and_resource(mucwin->roomjid, args[0]); @@ -1945,7 +2041,8 @@ cmd_caps(gchar **args, struct cmd_help_t help) if (args[0]) { cons_show("No parameter needed to /caps when in private chat."); } else { - ProfPrivateWin *privatewin = wins_get_current_private(); + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); Jid *jid = jid_create(privatewin->fulljid); if (jid) { occupant = muc_roster_item(jid->barejid, jid->resourcepart); @@ -1963,10 +2060,9 @@ cmd_caps(gchar **args, struct cmd_help_t help) gboolean -cmd_software(gchar **args, struct cmd_help_t help) +cmd_software(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); Occupant *occupant = NULL; if (conn_status != JABBER_CONNECTED) { @@ -1974,11 +2070,12 @@ cmd_software(gchar **args, struct cmd_help_t help) return TRUE; } - switch (win_type) + switch (window->type) { case WIN_MUC: if (args[0]) { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); occupant = muc_roster_item(mucwin->roomjid, args[0]); if (occupant) { Jid *jid = jid_create_from_bare_and_resource(mucwin->roomjid, args[0]); @@ -2010,7 +2107,8 @@ cmd_software(gchar **args, struct cmd_help_t help) if (args[0]) { cons_show("No parameter needed to /software when in private chat."); } else { - ProfPrivateWin *privatewin = wins_get_current_private(); + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); iq_send_software_version(privatewin->fulljid); } break; @@ -2022,7 +2120,7 @@ cmd_software(gchar **args, struct cmd_help_t help) } gboolean -cmd_join(gchar **args, struct cmd_help_t help) +cmd_join(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); if (conn_status != JABBER_CONNECTED) { @@ -2086,6 +2184,7 @@ cmd_join(gchar **args, struct cmd_help_t help) if (!parsed) { cons_show("Usage: %s", help.usage); cons_show(""); + jid_destroy(room_arg); return TRUE; } @@ -2119,7 +2218,7 @@ cmd_join(gchar **args, struct cmd_help_t help) } gboolean -cmd_invite(gchar **args, struct cmd_help_t help) +cmd_invite(ProfWin *window, gchar **args, struct cmd_help_t help) { char *contact = args[0]; char *reason = args[1]; @@ -2130,7 +2229,7 @@ cmd_invite(gchar **args, struct cmd_help_t help) return TRUE; } - if (ui_current_win_type() != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("You must be in a chat room to send an invite."); return TRUE; } @@ -2140,7 +2239,8 @@ cmd_invite(gchar **args, struct cmd_help_t help) usr_jid = contact; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); message_send_invite(mucwin->roomjid, usr_jid, reason); if (reason) { cons_show("Room invite sent, contact: %s, room: %s, reason: \"%s\".", @@ -2154,7 +2254,7 @@ cmd_invite(gchar **args, struct cmd_help_t help) } gboolean -cmd_invites(gchar **args, struct cmd_help_t help) +cmd_invites(ProfWin *window, gchar **args, struct cmd_help_t help) { GSList *invites = muc_invites(); cons_show_room_invites(invites); @@ -2163,7 +2263,7 @@ cmd_invites(gchar **args, struct cmd_help_t help) } gboolean -cmd_decline(gchar **args, struct cmd_help_t help) +cmd_decline(ProfWin *window, gchar **args, struct cmd_help_t help) { if (!muc_invites_contain(args[0])) { cons_show("No such invite exists."); @@ -2176,14 +2276,13 @@ cmd_decline(gchar **args, struct cmd_help_t help) } gboolean -cmd_form_field(char *tag, gchar **args) +cmd_form_field(ProfWin *window, char *tag, gchar **args) { - ProfWin *current = wins_get_current(); - if (current->type != WIN_MUC_CONFIG) { + if (window->type != WIN_MUC_CONFIG) { return TRUE; } - ProfMucConfWin *confwin = (ProfMucConfWin*)current; + ProfMucConfWin *confwin = (ProfMucConfWin*)window; DataForm *form = confwin->form; if (form) { if (!form_tag_exists(form, tag)) { @@ -2204,11 +2303,11 @@ cmd_form_field(char *tag, gchar **args) if (g_strcmp0(value, "on") == 0) { form_set_value(form, tag, "1"); ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else if (g_strcmp0(value, "off") == 0) { form_set_value(form, tag, "0"); ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("Invalid command, usage:"); ui_show_form_field_help(confwin, tag); @@ -2227,7 +2326,7 @@ cmd_form_field(char *tag, gchar **args) } else { form_set_value(form, tag, value); ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } break; case FIELD_LIST_SINGLE: @@ -2239,7 +2338,7 @@ cmd_form_field(char *tag, gchar **args) } else { form_set_value(form, tag, value); ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } break; @@ -2263,7 +2362,7 @@ cmd_form_field(char *tag, gchar **args) if (g_strcmp0(cmd, "add") == 0) { form_add_value(form, tag, value); ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); break; } if (g_strcmp0(args[0], "remove") == 0) { @@ -2291,7 +2390,7 @@ cmd_form_field(char *tag, gchar **args) removed = form_remove_text_multi_value(form, tag, index); if (removed) { ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("Could not remove %s from %s", value, tag); } @@ -2320,7 +2419,7 @@ cmd_form_field(char *tag, gchar **args) added = form_add_unique_value(form, tag, value); if (added) { ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("Value %s already selected for %s", value, tag); } @@ -2337,7 +2436,7 @@ cmd_form_field(char *tag, gchar **args) removed = form_remove_value(form, tag, value); if (removed) { ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("Value %s is not currently set for %s", value, tag); } @@ -2369,7 +2468,7 @@ cmd_form_field(char *tag, gchar **args) added = form_add_unique_value(form, tag, value); if (added) { ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("JID %s already exists in %s", value, tag); } @@ -2379,7 +2478,7 @@ cmd_form_field(char *tag, gchar **args) removed = form_remove_value(form, tag, value); if (removed) { ui_current_print_line("Field updated..."); - ui_show_form_field(current, form, tag); + ui_show_form_field(window, form, tag); } else { ui_current_print_line("Field %s does not contain %s", tag, value); } @@ -2395,7 +2494,7 @@ cmd_form_field(char *tag, gchar **args) } gboolean -cmd_form(gchar **args, struct cmd_help_t help) +cmd_form(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2404,8 +2503,7 @@ cmd_form(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC_CONFIG) { + if (window->type != WIN_MUC_CONFIG) { cons_show("Command '/form' does not apply to this window."); return TRUE; } @@ -2418,7 +2516,8 @@ cmd_form(gchar **args, struct cmd_help_t help) return TRUE; } - ProfMucConfWin *confwin = wins_get_current_muc_conf(); + ProfMucConfWin *confwin = (ProfMucConfWin*)window; + assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); if (g_strcmp0(args[0], "show") == 0) { ui_show_form(confwin); @@ -2447,7 +2546,6 @@ cmd_form(gchar **args, struct cmd_help_t help) if (g_strcmp0(args[0], "submit") == 0) { iq_submit_room_config(confwin->roomjid, confwin->form); - } if (g_strcmp0(args[0], "cancel") == 0) { @@ -2470,7 +2568,7 @@ cmd_form(gchar **args, struct cmd_help_t help) } gboolean -cmd_kick(gchar **args, struct cmd_help_t help) +cmd_kick(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2479,13 +2577,13 @@ cmd_kick(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/kick' only applies in chat rooms."); return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); char *nick = args[0]; if (nick) { @@ -2503,7 +2601,7 @@ cmd_kick(gchar **args, struct cmd_help_t help) } gboolean -cmd_ban(gchar **args, struct cmd_help_t help) +cmd_ban(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2512,13 +2610,13 @@ cmd_ban(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/ban' only applies in chat rooms."); return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); char *jid = args[0]; if (jid) { @@ -2531,7 +2629,7 @@ cmd_ban(gchar **args, struct cmd_help_t help) } gboolean -cmd_subject(gchar **args, struct cmd_help_t help) +cmd_subject(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2540,14 +2638,13 @@ cmd_subject(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/room' does not apply to this window."); return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); - ProfWin *window = (ProfWin*) mucwin; + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); if (args[0] == NULL) { char *subject = muc_subject(mucwin->roomjid); @@ -2579,7 +2676,7 @@ cmd_subject(gchar **args, struct cmd_help_t help) } gboolean -cmd_affiliation(gchar **args, struct cmd_help_t help) +cmd_affiliation(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2588,8 +2685,7 @@ cmd_affiliation(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/affiliation' does not apply to this window."); return TRUE; } @@ -2611,7 +2707,8 @@ cmd_affiliation(gchar **args, struct cmd_help_t help) return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); if (g_strcmp0(cmd, "list") == 0) { if (!affiliation) { @@ -2649,7 +2746,7 @@ cmd_affiliation(gchar **args, struct cmd_help_t help) } gboolean -cmd_role(gchar **args, struct cmd_help_t help) +cmd_role(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2658,8 +2755,7 @@ cmd_role(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/role' does not apply to this window."); return TRUE; } @@ -2680,7 +2776,8 @@ cmd_role(gchar **args, struct cmd_help_t help) return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); if (g_strcmp0(cmd, "list") == 0) { if (!role) { @@ -2717,7 +2814,7 @@ cmd_role(gchar **args, struct cmd_help_t help) } gboolean -cmd_room(gchar **args, struct cmd_help_t help) +cmd_room(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2726,8 +2823,7 @@ cmd_room(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Command '/room' does not apply to this window."); return TRUE; } @@ -2739,8 +2835,8 @@ cmd_room(gchar **args, struct cmd_help_t help) return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); - ProfWin *window = (ProfWin*) mucwin; + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); int num = wins_get_num(window); int ui_index = num; @@ -2781,7 +2877,7 @@ cmd_room(gchar **args, struct cmd_help_t help) } gboolean -cmd_occupants(gchar **args, struct cmd_help_t help) +cmd_occupants(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2836,13 +2932,13 @@ cmd_occupants(gchar **args, struct cmd_help_t help) } } - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("Cannot apply setting when not in chat room."); return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); if (g_strcmp0(args[0], "show") == 0) { if (g_strcmp0(args[1], "jid") == 0) { @@ -2866,7 +2962,7 @@ cmd_occupants(gchar **args, struct cmd_help_t help) } gboolean -cmd_rooms(gchar **args, struct cmd_help_t help) +cmd_rooms(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2887,7 +2983,7 @@ cmd_rooms(gchar **args, struct cmd_help_t help) } gboolean -cmd_bookmark(gchar **args, struct cmd_help_t help) +cmd_bookmark(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -2896,12 +2992,11 @@ cmd_bookmark(gchar **args, struct cmd_help_t help) return TRUE; } - win_type_t win_type = ui_current_win_type(); - gchar *cmd = args[0]; - if (win_type == WIN_MUC && cmd == NULL) { + if (window->type == WIN_MUC && cmd == NULL) { // default to current nickname, password, and autojoin "on" - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); char *nick = muc_nick(mucwin->roomjid); char *password = muc_password(mucwin->roomjid); gboolean added = bookmark_add(mucwin->roomjid, nick, password, "on"); @@ -2999,7 +3094,7 @@ cmd_bookmark(gchar **args, struct cmd_help_t help) } gboolean -cmd_disco(gchar **args, struct cmd_help_t help) +cmd_disco(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -3029,7 +3124,7 @@ cmd_disco(gchar **args, struct cmd_help_t help) } gboolean -cmd_nick(gchar **args, struct cmd_help_t help) +cmd_nick(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -3037,12 +3132,13 @@ cmd_nick(gchar **args, struct cmd_help_t help) cons_show("You are not currently connected."); return TRUE; } - if (ui_current_win_type() != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("You can only change your nickname in a chat room window."); return TRUE; } - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); char *nick = args[0]; presence_change_room_nick(mucwin->roomjid, nick); @@ -3050,7 +3146,7 @@ cmd_nick(gchar **args, struct cmd_help_t help) } gboolean -cmd_alias(gchar **args, struct cmd_help_t help) +cmd_alias(ProfWin *window, gchar **args, struct cmd_help_t help) { char *subcmd = args[0]; @@ -3122,43 +3218,45 @@ cmd_alias(gchar **args, struct cmd_help_t help) } gboolean -cmd_tiny(gchar **args, struct cmd_help_t help) +cmd_tiny(ProfWin *window, gchar **args, struct cmd_help_t help) { char *url = args[0]; - ProfWin *current = wins_get_current(); - if (current->type != WIN_CHAT && current->type != WIN_MUC && current->type != WIN_PRIVATE) { + if (window->type != WIN_CHAT && window->type != WIN_MUC && window->type != WIN_PRIVATE) { cons_show("/tiny can only be used in chat windows"); return TRUE; } if (!tinyurl_valid(url)) { - win_vprint(current, '-', NULL, 0, THEME_ERROR, "", "/tiny, badly formed URL: %s", url); + win_vprint(window, '-', NULL, 0, THEME_ERROR, "", "/tiny, badly formed URL: %s", url); return TRUE; } char *tiny = tinyurl_get(url); if (!tiny) { - win_print(current, '-', NULL, 0, THEME_ERROR, "", "Couldn't create tinyurl."); + win_print(window, '-', NULL, 0, THEME_ERROR, "", "Couldn't create tinyurl."); return TRUE; } - switch (current->type){ + switch (window->type){ case WIN_CHAT: { - ProfChatWin *chatwin = wins_get_current_chat(); + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); cl_ev_send_msg(chatwin, tiny); break; } case WIN_PRIVATE: { - ProfPrivateWin *privatewin = wins_get_current_private(); + ProfPrivateWin *privatewin = (ProfPrivateWin*)window; + assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); cl_ev_send_priv_msg(privatewin, tiny); break; } case WIN_MUC: { - ProfMucWin *mucwin = wins_get_current_muc(); + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); cl_ev_send_muc_msg(mucwin, tiny); break; } @@ -3172,14 +3270,14 @@ cmd_tiny(gchar **args, struct cmd_help_t help) } gboolean -cmd_clear(gchar **args, struct cmd_help_t help) +cmd_clear(ProfWin *window, gchar **args, struct cmd_help_t help) { - ui_clear_current(); + ui_clear_win(window); return TRUE; } gboolean -cmd_close(gchar **args, struct cmd_help_t help) +cmd_close(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); int index = 0; @@ -3221,8 +3319,8 @@ cmd_close(gchar **args, struct cmd_help_t help) return TRUE; } - ProfWin *window = wins_get_by_num(index); - if (!window) { + ProfWin *toclose = wins_get_by_num(index); + if (!toclose) { cons_show("Window is not open."); return TRUE; } @@ -3242,17 +3340,21 @@ cmd_close(gchar **args, struct cmd_help_t help) ui_close_win(index); cons_show("Closed window %d", index); + // Tidy up the window list. + if (prefs_get_boolean(PREF_WINS_AUTO_TIDY)) { + ui_tidy_wins(); + } + return TRUE; } gboolean -cmd_leave(gchar **args, struct cmd_help_t help) +cmd_leave(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - win_type_t win_type = ui_current_win_type(); int index = wins_get_current_num(); - if (win_type != WIN_MUC) { + if (window->type != WIN_MUC) { cons_show("You can only use the /leave command in a chat room."); cons_alert(); return TRUE; @@ -3270,7 +3372,7 @@ cmd_leave(gchar **args, struct cmd_help_t help) } gboolean -cmd_privileges(gchar **args, struct cmd_help_t help) +cmd_privileges(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "MUC privileges", PREF_MUC_PRIVILEGES); @@ -3280,19 +3382,19 @@ cmd_privileges(gchar **args, struct cmd_help_t help) } gboolean -cmd_beep(gchar **args, struct cmd_help_t help) +cmd_beep(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Sound", PREF_BEEP); } gboolean -cmd_presence(gchar **args, struct cmd_help_t help) +cmd_presence(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Contact presence", PREF_PRESENCE); } gboolean -cmd_wrap(gchar **args, struct cmd_help_t help) +cmd_wrap(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Word wrap", PREF_WRAP); @@ -3302,7 +3404,7 @@ cmd_wrap(gchar **args, struct cmd_help_t help) } gboolean -cmd_time(gchar **args, struct cmd_help_t help) +cmd_time(ProfWin *window, gchar **args, struct cmd_help_t help) { if (g_strcmp0(args[0], "statusbar") == 0) { if (args[1] == NULL) { @@ -3347,7 +3449,7 @@ cmd_time(gchar **args, struct cmd_help_t help) } gboolean -cmd_states(gchar **args, struct cmd_help_t help) +cmd_states(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Sending chat states", PREF_STATES); @@ -3362,7 +3464,7 @@ cmd_states(gchar **args, struct cmd_help_t help) } gboolean -cmd_titlebar(gchar **args, struct cmd_help_t help) +cmd_titlebar(ProfWin *window, gchar **args, struct cmd_help_t help) { if (g_strcmp0(args[0], "show") != 0 && g_strcmp0(args[0], "goodbye") != 0) { cons_show("Usage: %s", help.usage); @@ -3379,7 +3481,7 @@ cmd_titlebar(gchar **args, struct cmd_help_t help) } gboolean -cmd_outtype(gchar **args, struct cmd_help_t help) +cmd_outtype(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Sending typing notifications", PREF_OUTTYPE); @@ -3393,7 +3495,7 @@ cmd_outtype(gchar **args, struct cmd_help_t help) } gboolean -cmd_gone(gchar **args, struct cmd_help_t help) +cmd_gone(ProfWin *window, gchar **args, struct cmd_help_t help) { char *value = args[0]; @@ -3417,7 +3519,7 @@ cmd_gone(gchar **args, struct cmd_help_t help) gboolean -cmd_notify(gchar **args, struct cmd_help_t help) +cmd_notify(ProfWin *window, gchar **args, struct cmd_help_t help) { char *kind = args[0]; @@ -3560,7 +3662,7 @@ cmd_notify(gchar **args, struct cmd_help_t help) } gboolean -cmd_inpblock(gchar **args, struct cmd_help_t help) +cmd_inpblock(ProfWin *window, gchar **args, struct cmd_help_t help) { char *subcmd = args[0]; char *value = args[1]; @@ -3606,7 +3708,7 @@ cmd_inpblock(gchar **args, struct cmd_help_t help) } gboolean -cmd_log(gchar **args, struct cmd_help_t help) +cmd_log(ProfWin *window, gchar **args, struct cmd_help_t help) { char *subcmd = args[0]; char *value = args[1]; @@ -3662,7 +3764,7 @@ cmd_log(gchar **args, struct cmd_help_t help) } gboolean -cmd_reconnect(gchar **args, struct cmd_help_t help) +cmd_reconnect(ProfWin *window, gchar **args, struct cmd_help_t help) { char *value = args[0]; @@ -3686,7 +3788,7 @@ cmd_reconnect(gchar **args, struct cmd_help_t help) } gboolean -cmd_autoping(gchar **args, struct cmd_help_t help) +cmd_autoping(ProfWin *window, gchar **args, struct cmd_help_t help) { char *value = args[0]; @@ -3711,7 +3813,7 @@ cmd_autoping(gchar **args, struct cmd_help_t help) } gboolean -cmd_ping(gchar **args, struct cmd_help_t help) +cmd_ping(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -3731,7 +3833,7 @@ cmd_ping(gchar **args, struct cmd_help_t help) } gboolean -cmd_autoaway(gchar **args, struct cmd_help_t help) +cmd_autoaway(ProfWin *window, gchar **args, struct cmd_help_t help) { char *setting = args[0]; char *value = args[1]; @@ -3790,7 +3892,7 @@ cmd_autoaway(gchar **args, struct cmd_help_t help) } gboolean -cmd_priority(gchar **args, struct cmd_help_t help) +cmd_priority(ProfWin *window, gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); @@ -3818,7 +3920,7 @@ cmd_priority(gchar **args, struct cmd_help_t help) } gboolean -cmd_statuses(gchar **args, struct cmd_help_t help) +cmd_statuses(ProfWin *window, gchar **args, struct cmd_help_t help) { if (strcmp(args[0], "console") != 0 && strcmp(args[0], "chat") != 0 && @@ -3871,7 +3973,7 @@ cmd_statuses(gchar **args, struct cmd_help_t help) } gboolean -cmd_vercheck(gchar **args, struct cmd_help_t help) +cmd_vercheck(ProfWin *window, gchar **args, struct cmd_help_t help) { int num_args = g_strv_length(args); @@ -3885,7 +3987,7 @@ cmd_vercheck(gchar **args, struct cmd_help_t help) } gboolean -cmd_xmlconsole(gchar **args, struct cmd_help_t help) +cmd_xmlconsole(ProfWin *window, gchar **args, struct cmd_help_t help) { if (!ui_xmlconsole_exists()) { ui_create_xmlconsole_win(); @@ -3897,28 +3999,28 @@ cmd_xmlconsole(gchar **args, struct cmd_help_t help) } gboolean -cmd_flash(gchar **args, struct cmd_help_t help) +cmd_flash(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Screen flash", PREF_FLASH); } gboolean -cmd_intype(gchar **args, struct cmd_help_t help) +cmd_intype(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Show contact typing", PREF_INTYPE); } gboolean -cmd_splash(gchar **args, struct cmd_help_t help) +cmd_splash(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Splash screen", PREF_SPLASH); } gboolean -cmd_autoconnect(gchar **args, struct cmd_help_t help) +cmd_autoconnect(ProfWin *window, gchar **args, struct cmd_help_t help) { if (strcmp(args[0], "off") == 0) { prefs_set_string(PREF_CONNECT_ACCOUNT, NULL); @@ -3933,7 +4035,7 @@ cmd_autoconnect(gchar **args, struct cmd_help_t help) } gboolean -cmd_chlog(gchar **args, struct cmd_help_t help) +cmd_chlog(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Chat logging", PREF_CHLOG); @@ -3947,7 +4049,7 @@ cmd_chlog(gchar **args, struct cmd_help_t help) } gboolean -cmd_grlog(gchar **args, struct cmd_help_t help) +cmd_grlog(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Groupchat logging", PREF_GRLOG); @@ -3956,14 +4058,14 @@ cmd_grlog(gchar **args, struct cmd_help_t help) } gboolean -cmd_mouse(gchar **args, struct cmd_help_t help) +cmd_mouse(ProfWin *window, gchar **args, struct cmd_help_t help) { return _cmd_set_boolean_preference(args[0], help, "Mouse handling", PREF_MOUSE); } gboolean -cmd_history(gchar **args, struct cmd_help_t help) +cmd_history(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Chat history", PREF_HISTORY); @@ -3977,7 +4079,7 @@ cmd_history(gchar **args, struct cmd_help_t help) } gboolean -cmd_carbons(gchar **args, struct cmd_help_t help) +cmd_carbons(ProfWin *window, gchar **args, struct cmd_help_t help) { gboolean result = _cmd_set_boolean_preference(args[0], help, "Message carbons preference", PREF_CARBONS); @@ -3998,7 +4100,7 @@ cmd_carbons(gchar **args, struct cmd_help_t help) } gboolean -cmd_receipts(gchar **args, struct cmd_help_t help) +cmd_receipts(ProfWin *window, gchar **args, struct cmd_help_t help) { if (g_strcmp0(args[0], "send") == 0) { return _cmd_set_boolean_preference(args[1], help, @@ -4013,42 +4115,254 @@ cmd_receipts(gchar **args, struct cmd_help_t help) } gboolean -cmd_away(gchar **args, struct cmd_help_t help) +cmd_away(ProfWin *window, gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_AWAY, "away", args); return TRUE; } gboolean -cmd_online(gchar **args, struct cmd_help_t help) +cmd_online(ProfWin *window, gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_ONLINE, "online", args); return TRUE; } gboolean -cmd_dnd(gchar **args, struct cmd_help_t help) +cmd_dnd(ProfWin *window, gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_DND, "dnd", args); return TRUE; } gboolean -cmd_chat(gchar **args, struct cmd_help_t help) +cmd_chat(ProfWin *window, gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_CHAT, "chat", args); return TRUE; } gboolean -cmd_xa(gchar **args, struct cmd_help_t help) +cmd_xa(ProfWin *window, gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_XA, "xa", args); return TRUE; } gboolean -cmd_otr(gchar **args, struct cmd_help_t help) +cmd_pgp(ProfWin *window, gchar **args, struct cmd_help_t help) +{ +#ifdef HAVE_LIBGPGME + if (args[0] == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + if (g_strcmp0(args[0], "log") == 0) { + char *choice = args[1]; + if (g_strcmp0(choice, "on") == 0) { + prefs_set_string(PREF_PGP_LOG, "on"); + cons_show("PGP messages will be logged as plaintext."); + if (!prefs_get_boolean(PREF_CHLOG)) { + cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); + } + } else if (g_strcmp0(choice, "off") == 0) { + prefs_set_string(PREF_PGP_LOG, "off"); + cons_show("PGP message logging disabled."); + } else if (g_strcmp0(choice, "redact") == 0) { + prefs_set_string(PREF_PGP_LOG, "redact"); + cons_show("PGP messages will be logged as '[redacted]'."); + if (!prefs_get_boolean(PREF_CHLOG)) { + cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); + } + } else { + cons_show("Usage: %s", help.usage); + } + return TRUE; + } + + if (g_strcmp0(args[0], "keys") == 0) { + GSList *keys = p_gpg_list_keys(); + if (!keys) { + cons_show("No keys found"); + return TRUE; + } + + cons_show("PGP keys:"); + GSList *curr = keys; + while (curr) { + ProfPGPKey *key = curr->data; + cons_show(" %s", key->name); + cons_show(" ID : %s", key->id); + cons_show(" Fingerprint : %s", key->fp); + curr = g_slist_next(curr); + } + g_slist_free_full(keys, (GDestroyNotify)p_gpg_free_key); + return TRUE; + } + + if (g_strcmp0(args[0], "setkey") == 0) { + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + + char *jid = args[1]; + if (!args[1]) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + char *keyid = args[2]; + if (!args[2]) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + gboolean res = p_gpg_addkey(jid, keyid); + if (!res) { + cons_show("Key ID not found."); + } else { + cons_show("Key %s set for %s.", keyid, jid); + } + + return TRUE; + } + + if (g_strcmp0(args[0], "fps") == 0) { + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + GHashTable *fingerprints = p_gpg_fingerprints(); + GList *jids = g_hash_table_get_keys(fingerprints); + if (!jids) { + cons_show("No PGP fingerprints available."); + return TRUE; + } + + cons_show("Known PGP fingerprints:"); + GList *curr = jids; + while (curr) { + char *jid = curr->data; + char *fingerprint = g_hash_table_lookup(fingerprints, jid); + cons_show(" %s: %s", jid, fingerprint); + curr = g_list_next(curr); + } + g_list_free(jids); + return TRUE; + } + + if (g_strcmp0(args[0], "libver") == 0) { + const char *libver = p_gpg_libver(); + if (!libver) { + cons_show("Could not get libgpgme version"); + return TRUE; + } + + GString *fullstr = g_string_new("Using libgpgme version "); + g_string_append(fullstr, libver); + cons_show("%s", fullstr->str); + g_string_free(fullstr, TRUE); + + return TRUE; + } + + if (g_strcmp0(args[0], "start") == 0) { + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status != JABBER_CONNECTED) { + cons_show("You must be connected to start PGP encrpytion."); + return TRUE; + } + + if (window->type != WIN_CHAT && args[1] == NULL) { + cons_show("You must be in a regular chat window to start PGP encrpytion."); + return TRUE; + } + + ProfChatWin *chatwin = NULL; + + if (args[1]) { + char *contact = args[1]; + char *barejid = roster_barejid_from_name(contact); + if (barejid == NULL) { + barejid = contact; + } + + chatwin = wins_get_chat(barejid); + if (!chatwin) { + chatwin = ui_ev_new_chat_win(barejid); + } + ui_ev_focus_win((ProfWin*)chatwin); + } else { + chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + } + + if (chatwin->enc_mode == PROF_ENC_OTR) { + ui_current_print_formatted_line('!', 0, "You must end the OTR session to start PGP encryption."); + return TRUE; + } + + if (chatwin->enc_mode == PROF_ENC_PGP) { + ui_current_print_formatted_line('!', 0, "You have already started PGP encryption."); + return TRUE; + } + + ProfAccount *account = accounts_get_account(jabber_get_account_name()); + if (!account->pgp_keyid) { + ui_current_print_formatted_line('!', 0, "You must specify a PGP key ID for this account to start PGP encryption."); + account_free(account); + return TRUE; + } + account_free(account); + + if (!p_gpg_available(chatwin->barejid)) { + ui_current_print_formatted_line('!', 0, "No PGP key found for %s.", chatwin->barejid); + return TRUE; + } + + chatwin->enc_mode = PROF_ENC_PGP; + ui_current_print_formatted_line('!', 0, "PGP encyption enabled."); + return TRUE; + } + + if (g_strcmp0(args[0], "end") == 0) { + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status != JABBER_CONNECTED) { + cons_show("You are not currently connected."); + return TRUE; + } + + if (window->type != WIN_CHAT) { + cons_show("You must be in a regular chat window to end PGP encrpytion."); + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + if (chatwin->enc_mode != PROF_ENC_PGP) { + ui_current_print_formatted_line('!', 0, "PGP encryption is not currently enabled."); + return TRUE; + } + + chatwin->enc_mode = PROF_ENC_NONE; + ui_current_print_formatted_line('!', 0, "PGP encyption disabled."); + return TRUE; + } + + cons_show("Usage: %s", help.usage); + return TRUE; +#else + cons_show("This version of Profanity has not been built with PGP support enabled"); + return TRUE; +#endif + +} + +gboolean +cmd_otr(ProfWin *window, gchar **args, struct cmd_help_t help) { #ifdef HAVE_LIBOTR if (args[0] == NULL) { @@ -4078,11 +4392,6 @@ cmd_otr(gchar **args, struct cmd_help_t help) } return TRUE; - } else if (strcmp(args[0], "warn") == 0) { - gboolean result = _cmd_set_boolean_preference(args[1], help, - "OTR warning message", PREF_OTR_WARN); - return result; - } else if (strcmp(args[0], "libver") == 0) { char *version = otr_libotr_version(); cons_show("Using libotr version %s", version); @@ -4138,29 +4447,34 @@ cmd_otr(gchar **args, struct cmd_help_t help) } else if (strcmp(args[0], "myfp") == 0) { if (!otr_key_loaded()) { ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); - } else { - char *fingerprint = otr_get_my_fingerprint(); - ui_current_print_formatted_line('!', 0, "Your OTR fingerprint: %s", fingerprint); - free(fingerprint); + return TRUE; } + + char *fingerprint = otr_get_my_fingerprint(); + ui_current_print_formatted_line('!', 0, "Your OTR fingerprint: %s", fingerprint); + free(fingerprint); return TRUE; } else if (strcmp(args[0], "theirfp") == 0) { - win_type_t win_type = ui_current_win_type(); - - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in a regular chat window to view a recipient's fingerprint."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - ProfChatWin *chatwin = ui_get_current_chat(); - char *fingerprint = otr_get_their_fingerprint(chatwin->barejid); - ui_current_print_formatted_line('!', 0, "%s's OTR fingerprint: %s", chatwin->barejid, fingerprint); - free(fingerprint); + return TRUE; } + + char *fingerprint = otr_get_their_fingerprint(chatwin->barejid); + ui_current_print_formatted_line('!', 0, "%s's OTR fingerprint: %s", chatwin->barejid, fingerprint); + free(fingerprint); return TRUE; } else if (strcmp(args[0], "start") == 0) { + // recipient supplied if (args[1]) { char *contact = args[1]; char *barejid = roster_barejid_from_name(contact); @@ -4174,131 +4488,175 @@ cmd_otr(gchar **args, struct cmd_help_t help) } ui_ev_focus_win((ProfWin*)chatwin); - if (ui_current_win_is_otr()) { + if (chatwin->enc_mode == PROF_ENC_PGP) { + ui_current_print_formatted_line('!', 0, "You must disable PGP encryption before starting an OTR session."); + return TRUE; + } + + if (chatwin->enc_mode == PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are already in an OTR session."); - } else { - if (!otr_key_loaded()) { - ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); - } else if (!otr_is_secure(barejid)) { - char *otr_query_message = otr_start_query(); - message_send_chat_encrypted(barejid, otr_query_message); - } else { - ui_gone_secure(barejid, otr_is_trusted(barejid)); - } + return TRUE; } - } else { - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_CHAT) { + if (!otr_key_loaded()) { + ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); + return TRUE; + } + + if (!otr_is_secure(barejid)) { + char *otr_query_message = otr_start_query(); + message_send_chat_otr(barejid, otr_query_message); + return TRUE; + } + + ui_gone_secure(barejid, otr_is_trusted(barejid)); + return TRUE; + + // no recipient, use current chat + } else { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in a regular chat window to start an OTR session."); - } else if (ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode == PROF_ENC_PGP) { + ui_current_print_formatted_line('!', 0, "You must disable PGP encryption before starting an OTR session."); + return TRUE; + } + + if (chatwin->enc_mode == PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are already in an OTR session."); - } else { - if (!otr_key_loaded()) { - ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); - } else { - ProfChatWin *chatwin = ui_get_current_chat(); - char *otr_query_message = otr_start_query(); - message_send_chat_encrypted(chatwin->barejid, otr_query_message); - } + return TRUE; } + + if (!otr_key_loaded()) { + ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); + return TRUE; + } + + char *otr_query_message = otr_start_query(); + message_send_chat_otr(chatwin->barejid, otr_query_message); + return TRUE; } - return TRUE; } else if (strcmp(args[0], "end") == 0) { - win_type_t win_type = ui_current_win_type(); - - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in a regular chat window to use OTR."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - ui_gone_insecure(chatwin->barejid); - otr_end_session(chatwin->barejid); + return TRUE; } + + ui_gone_insecure(chatwin->barejid); + otr_end_session(chatwin->barejid); return TRUE; } else if (strcmp(args[0], "trust") == 0) { - win_type_t win_type = ui_current_win_type(); - - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in an OTR session to trust a recipient."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - ui_trust(chatwin->barejid); - otr_trust(chatwin->barejid); + return TRUE; } + + ui_trust(chatwin->barejid); + otr_trust(chatwin->barejid); return TRUE; } else if (strcmp(args[0], "untrust") == 0) { - win_type_t win_type = ui_current_win_type(); - - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in an OTR session to untrust a recipient."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - ui_untrust(chatwin->barejid); - otr_untrust(chatwin->barejid); + return TRUE; } + + ui_untrust(chatwin->barejid); + otr_untrust(chatwin->barejid); return TRUE; } else if (strcmp(args[0], "secret") == 0) { - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in an OTR session to trust a recipient."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - char *secret = args[1]; - if (secret == NULL) { - cons_show("Usage: %s", help.usage); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - otr_smp_secret(chatwin->barejid, secret); - } + return TRUE; + } + + char *secret = args[1]; + if (secret == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; } + + otr_smp_secret(chatwin->barejid, secret); return TRUE; } else if (strcmp(args[0], "question") == 0) { char *question = args[1]; char *answer = args[2]; - if (question == NULL || answer == NULL) { cons_show("Usage: %s", help.usage); return TRUE; - } else { - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_CHAT) { - ui_current_print_line("You must be in an OTR session to trust a recipient."); - } else if (!ui_current_win_is_otr()) { - ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - otr_smp_question(chatwin->barejid, question, answer); - } + } + + if (window->type != WIN_CHAT) { + ui_current_print_line("You must be in an OTR session to trust a recipient."); + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { + ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); return TRUE; } + otr_smp_question(chatwin->barejid, question, answer); + return TRUE; + } else if (strcmp(args[0], "answer") == 0) { - win_type_t win_type = ui_current_win_type(); - if (win_type != WIN_CHAT) { + if (window->type != WIN_CHAT) { ui_current_print_line("You must be in an OTR session to trust a recipient."); - } else if (!ui_current_win_is_otr()) { + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->enc_mode != PROF_ENC_OTR) { ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - } else { - char *answer = args[1]; - if (answer == NULL) { - cons_show("Usage: %s", help.usage); - } else { - ProfChatWin *chatwin = wins_get_current_chat(); - otr_smp_answer(chatwin->barejid, answer); - } + return TRUE; } + + char *answer = args[1]; + if (answer == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + otr_smp_answer(chatwin->barejid, answer); return TRUE; } else { @@ -4311,6 +4669,12 @@ cmd_otr(gchar **args, struct cmd_help_t help) #endif } +gboolean +cmd_encwarn(ProfWin *window, gchar **args, struct cmd_help_t help) +{ + return _cmd_set_boolean_preference(args[0], help, "Encryption warning message", PREF_ENC_WARN); +} + // helper function for status change commands static void _update_presence(const resource_presence_t resource_presence, diff --git a/src/command/commands.h b/src/command/commands.h index 7b7e7c93..6f2bada2 100644 --- a/src/command/commands.h +++ b/src/command/commands.h @@ -35,6 +35,8 @@ #ifndef COMMANDS_H #define COMMANDS_H +#include "ui/ui.h" + // Command help strings typedef struct cmd_help_t { const gchar *usage; @@ -54,7 +56,7 @@ typedef struct cmd_help_t { */ typedef struct cmd_t { gchar *cmd; - gboolean (*func)(gchar **args, struct cmd_help_t help); + gboolean (*func)(ProfWin *window, gchar **args, struct cmd_help_t help); gchar** (*parser)(const char * const inp, int min, int max, gboolean *result); int min_args; int max_args; @@ -62,87 +64,90 @@ typedef struct cmd_t { CommandHelp help; } Command; -gboolean cmd_execute_alias(const char * const inp, gboolean *ran); -gboolean cmd_execute_default(const char * inp); +gboolean cmd_execute_alias(ProfWin *window, const char * const inp, gboolean *ran); +gboolean cmd_execute_default(ProfWin *window, const char * inp); -gboolean cmd_about(gchar **args, struct cmd_help_t help); -gboolean cmd_account(gchar **args, struct cmd_help_t help); -gboolean cmd_autoaway(gchar **args, struct cmd_help_t help); -gboolean cmd_autoconnect(gchar **args, struct cmd_help_t help); -gboolean cmd_autoping(gchar **args, struct cmd_help_t help); -gboolean cmd_away(gchar **args, struct cmd_help_t help); -gboolean cmd_beep(gchar **args, struct cmd_help_t help); -gboolean cmd_caps(gchar **args, struct cmd_help_t help); -gboolean cmd_chat(gchar **args, struct cmd_help_t help); -gboolean cmd_chlog(gchar **args, struct cmd_help_t help); -gboolean cmd_clear(gchar **args, struct cmd_help_t help); -gboolean cmd_close(gchar **args, struct cmd_help_t help); -gboolean cmd_connect(gchar **args, struct cmd_help_t help); -gboolean cmd_decline(gchar **args, struct cmd_help_t help); -gboolean cmd_disco(gchar **args, struct cmd_help_t help); -gboolean cmd_disconnect(gchar **args, struct cmd_help_t help); -gboolean cmd_dnd(gchar **args, struct cmd_help_t help); -gboolean cmd_flash(gchar **args, struct cmd_help_t help); -gboolean cmd_gone(gchar **args, struct cmd_help_t help); -gboolean cmd_grlog(gchar **args, struct cmd_help_t help); -gboolean cmd_group(gchar **args, struct cmd_help_t help); -gboolean cmd_help(gchar **args, struct cmd_help_t help); -gboolean cmd_history(gchar **args, struct cmd_help_t help); -gboolean cmd_carbons(gchar **args, struct cmd_help_t help); -gboolean cmd_receipts(gchar **args, struct cmd_help_t help); -gboolean cmd_info(gchar **args, struct cmd_help_t help); -gboolean cmd_intype(gchar **args, struct cmd_help_t help); -gboolean cmd_invite(gchar **args, struct cmd_help_t help); -gboolean cmd_invites(gchar **args, struct cmd_help_t help); -gboolean cmd_join(gchar **args, struct cmd_help_t help); -gboolean cmd_leave(gchar **args, struct cmd_help_t help); -gboolean cmd_log(gchar **args, struct cmd_help_t help); -gboolean cmd_mouse(gchar **args, struct cmd_help_t help); -gboolean cmd_msg(gchar **args, struct cmd_help_t help); -gboolean cmd_nick(gchar **args, struct cmd_help_t help); -gboolean cmd_notify(gchar **args, struct cmd_help_t help); -gboolean cmd_online(gchar **args, struct cmd_help_t help); -gboolean cmd_otr(gchar **args, struct cmd_help_t help); -gboolean cmd_outtype(gchar **args, struct cmd_help_t help); -gboolean cmd_prefs(gchar **args, struct cmd_help_t help); -gboolean cmd_priority(gchar **args, struct cmd_help_t help); -gboolean cmd_quit(gchar **args, struct cmd_help_t help); -gboolean cmd_reconnect(gchar **args, struct cmd_help_t help); -gboolean cmd_room(gchar **args, struct cmd_help_t help); -gboolean cmd_rooms(gchar **args, struct cmd_help_t help); -gboolean cmd_bookmark(gchar **args, struct cmd_help_t help); -gboolean cmd_roster(gchar **args, struct cmd_help_t help); -gboolean cmd_software(gchar **args, struct cmd_help_t help); -gboolean cmd_splash(gchar **args, struct cmd_help_t help); -gboolean cmd_states(gchar **args, struct cmd_help_t help); -gboolean cmd_status(gchar **args, struct cmd_help_t help); -gboolean cmd_statuses(gchar **args, struct cmd_help_t help); -gboolean cmd_sub(gchar **args, struct cmd_help_t help); -gboolean cmd_theme(gchar **args, struct cmd_help_t help); -gboolean cmd_tiny(gchar **args, struct cmd_help_t help); -gboolean cmd_titlebar(gchar **args, struct cmd_help_t help); -gboolean cmd_vercheck(gchar **args, struct cmd_help_t help); -gboolean cmd_who(gchar **args, struct cmd_help_t help); -gboolean cmd_win(gchar **args, struct cmd_help_t help); -gboolean cmd_wins(gchar **args, struct cmd_help_t help); -gboolean cmd_xa(gchar **args, struct cmd_help_t help); -gboolean cmd_alias(gchar **args, struct cmd_help_t help); -gboolean cmd_xmlconsole(gchar **args, struct cmd_help_t help); -gboolean cmd_ping(gchar **args, struct cmd_help_t help); -gboolean cmd_form(gchar **args, struct cmd_help_t help); -gboolean cmd_occupants(gchar **args, struct cmd_help_t help); -gboolean cmd_kick(gchar **args, struct cmd_help_t help); -gboolean cmd_ban(gchar **args, struct cmd_help_t help); -gboolean cmd_subject(gchar **args, struct cmd_help_t help); -gboolean cmd_affiliation(gchar **args, struct cmd_help_t help); -gboolean cmd_role(gchar **args, struct cmd_help_t help); -gboolean cmd_privileges(gchar **args, struct cmd_help_t help); -gboolean cmd_presence(gchar **args, struct cmd_help_t help); -gboolean cmd_wrap(gchar **args, struct cmd_help_t help); -gboolean cmd_time(gchar **args, struct cmd_help_t help); -gboolean cmd_resource(gchar **args, struct cmd_help_t help); -gboolean cmd_inpblock(gchar **args, struct cmd_help_t help); +gboolean cmd_about(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_account(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_autoaway(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_autoconnect(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_autoping(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_away(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_beep(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_caps(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_chat(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_chlog(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_clear(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_close(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_connect(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_decline(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_disco(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_disconnect(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_dnd(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_flash(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_gone(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_grlog(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_group(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_help(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_history(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_carbons(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_receipts(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_info(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_intype(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_invite(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_invites(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_join(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_leave(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_log(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_mouse(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_msg(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_nick(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_notify(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_online(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_otr(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_pgp(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_outtype(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_prefs(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_priority(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_quit(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_reconnect(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_room(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_rooms(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_bookmark(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_roster(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_software(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_splash(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_states(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_status(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_statuses(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_sub(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_theme(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_tiny(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_titlebar(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_vercheck(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_who(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_win(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_wins(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_winstidy(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_xa(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_alias(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_xmlconsole(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_ping(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_form(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_occupants(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_kick(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_ban(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_subject(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_affiliation(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_role(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_privileges(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_presence(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_wrap(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_time(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_resource(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_inpblock(ProfWin *window, gchar **args, struct cmd_help_t help); +gboolean cmd_encwarn(ProfWin *window, gchar **args, struct cmd_help_t help); -gboolean cmd_form_field(char *tag, gchar **args); +gboolean cmd_form_field(ProfWin *window, char *tag, gchar **args); #endif diff --git a/src/common.c b/src/common.c index 772e24d3..832e85dd 100644 --- a/src/common.c +++ b/src/common.c @@ -57,6 +57,8 @@ struct curl_data_t size_t size; }; +static unsigned long unique_id = 0; + static size_t _data_callback(void *ptr, size_t size, size_t nmemb, void *data); // taken from glib 2.30.3 @@ -251,18 +253,6 @@ utf8_display_len(const char * const str) return len; } -gboolean -utf8_is_printable(const wint_t ch) -{ - char bytes[MB_CUR_MAX+1]; - size_t utf_len = wcrtomb(bytes, ch, NULL); - bytes[utf_len] = '\0'; - - gunichar unichar = g_utf8_get_char(bytes); - - return g_unichar_isprint(unichar) && (ch != KEY_MOUSE); -} - char * prof_getline(FILE *stream) { @@ -469,7 +459,6 @@ xdg_get_data_home(void) char * create_unique_id(char *prefix) { - static unsigned long unique_id; char *result = NULL; GString *result_str = g_string_new(""); @@ -485,6 +474,12 @@ create_unique_id(char *prefix) return result; } +void +reset_unique_id(void) +{ + unique_id = 0; +} + char * p_sha1_hash(char *str) { diff --git a/src/common.h b/src/common.h index 9521a701..9da0c974 100644 --- a/src/common.h +++ b/src/common.h @@ -38,12 +38,6 @@ #include <stdio.h> #include <wchar.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif - #include <glib.h> #if !GLIB_CHECK_VERSION(2,28,0) @@ -113,7 +107,6 @@ char * str_replace(const char *string, const char *substr, int str_contains(const char str[], int size, char ch); gboolean strtoi_range(char *str, int *saveptr, int min, int max, char **err_msg); int utf8_display_len(const char * const str); -gboolean utf8_is_printable(const wint_t ch); char * prof_getline(FILE *stream); char* release_get_latest(void); gboolean release_is_new(char *found_version); @@ -127,6 +120,7 @@ contact_presence_t contact_presence_from_resource_presence(resource_presence_t r char * p_sha1_hash(char *str); char * create_unique_id(char *prefix); +void reset_unique_id(void); int cmp_win_num(gconstpointer a, gconstpointer b); int get_next_available_win_num(GList *used); diff --git a/src/config/account.c b/src/config/account.c index 857d049b..de48ba02 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -51,7 +51,7 @@ account_new(const gchar * const name, const gchar * const jid, int priority_away, int priority_xa, int priority_dnd, const gchar * const muc_service, const gchar * const muc_nick, const gchar * const otr_policy, GList *otr_manual, GList *otr_opportunistic, - GList *otr_always) + GList *otr_always, const gchar * const pgp_keyid) { ProfAccount *new_account = malloc(sizeof(ProfAccount)); @@ -144,6 +144,12 @@ account_new(const gchar * const name, const gchar * const jid, new_account->otr_opportunistic = otr_opportunistic; new_account->otr_always = otr_always; + if (pgp_keyid != NULL) { + new_account->pgp_keyid = strdup(pgp_keyid); + } else { + new_account->pgp_keyid = NULL; + } + return new_account; } @@ -210,6 +216,7 @@ account_free(ProfAccount *account) free(account->muc_service); free(account->muc_nick); free(account->otr_policy); + free(account->pgp_keyid); g_list_free_full(account->otr_manual, g_free); g_list_free_full(account->otr_opportunistic, g_free); g_list_free_full(account->otr_always, g_free); diff --git a/src/config/account.h b/src/config/account.h index 218f8ce7..22c29161 100644 --- a/src/config/account.h +++ b/src/config/account.h @@ -59,6 +59,7 @@ typedef struct prof_account_t { GList *otr_manual; GList *otr_opportunistic; GList *otr_always; + gchar *pgp_keyid; } ProfAccount; ProfAccount* account_new(const gchar * const name, const gchar * const jid, @@ -68,7 +69,7 @@ ProfAccount* account_new(const gchar * const name, const gchar * const jid, int priority_away, int priority_xa, int priority_dnd, const gchar * const muc_service, const gchar * const muc_nick, const gchar * const otr_policy, GList *otr_manual, GList *otr_opportunistic, - GList *otr_always); + GList *otr_always, const gchar * const pgp_keyid); char* account_create_full_jid(ProfAccount *account); gboolean account_eval_password(ProfAccount *account); void account_free(ProfAccount *account); diff --git a/src/config/accounts.c b/src/config/accounts.c index d68f3a55..a827392b 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -280,11 +280,16 @@ accounts_get_account(const char * const name) g_strfreev(always); } + gchar *pgp_keyid = NULL; + if (g_key_file_has_key(accounts, name, "pgp.keyid", NULL)) { + pgp_keyid = g_key_file_get_string(accounts, name, "pgp.keyid", NULL); + } + ProfAccount *new_account = account_new(name, jid, password, eval_password, enabled, server, port, resource, last_presence, login_presence, priority_online, priority_chat, priority_away, priority_xa, priority_dnd, muc_service, muc_nick, otr_policy, otr_manual, - otr_opportunistic, otr_always); + otr_opportunistic, otr_always, pgp_keyid); g_free(jid); g_free(password); @@ -296,6 +301,7 @@ accounts_get_account(const char * const name) g_free(muc_service); g_free(muc_nick); g_free(otr_policy); + g_free(pgp_keyid); return new_account; } @@ -405,6 +411,8 @@ accounts_set_jid(const char * const account_name, const char * const value) _save_accounts(); } + + jid_destroy(jid); } } @@ -454,6 +462,15 @@ accounts_set_eval_password(const char * const account_name, const char * const v } void +accounts_set_pgp_keyid(const char * const account_name, const char * const value) +{ + if (accounts_account_exists(account_name)) { + g_key_file_set_string(accounts, account_name, "pgp.keyid", value); + _save_accounts(); + } +} + +void accounts_clear_password(const char * const account_name) { if (accounts_account_exists(account_name)) { @@ -490,6 +507,15 @@ accounts_clear_port(const char * const account_name) } void +accounts_clear_pgp_keyid(const char * const account_name) +{ + if (accounts_account_exists(account_name)) { + g_key_file_remove_key(accounts, account_name, "pgp.keyid", NULL); + _save_accounts(); + } +} + +void accounts_clear_otr(const char * const account_name) { if (accounts_account_exists(account_name)) { diff --git a/src/config/accounts.h b/src/config/accounts.h index 50307b5b..eb981cb8 100644 --- a/src/config/accounts.h +++ b/src/config/accounts.h @@ -77,11 +77,13 @@ void accounts_set_priority_dnd(const char * const account_name, const gint value void accounts_set_priority_all(const char * const account_name, const gint value); gint accounts_get_priority_for_presence_type(const char * const account_name, resource_presence_t presence_type); +void accounts_set_pgp_keyid(const char * const account_name, const char * const value); void accounts_clear_password(const char * const account_name); void accounts_clear_eval_password(const char * const account_name); void accounts_clear_server(const char * const account_name); void accounts_clear_port(const char * const account_name); void accounts_clear_otr(const char * const account_name); +void accounts_clear_pgp_keyid(const char * const account_name); void accounts_add_otr_policy(const char * const account_name, const char * const contact_jid, const char * const policy); #endif diff --git a/src/config/preferences.c b/src/config/preferences.c index c0d6f6e5..7153d62b 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -41,12 +41,6 @@ #include <glib.h> #include <glib/gstdio.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif - #include "common.h" #include "log.h" #include "preferences.h" @@ -61,6 +55,7 @@ #define PREF_GROUP_CONNECTION "connection" #define PREF_GROUP_ALIAS "alias" #define PREF_GROUP_OTR "otr" +#define PREF_GROUP_PGP "pgp" #define INPBLOCK_DEFAULT 1000 @@ -81,8 +76,6 @@ void prefs_load(void) { GError *err; - - log_info("Loading preferences"); prefs_loc = _get_preferences_file(); if (g_file_test(prefs_loc, G_FILE_TEST_EXISTS)) { @@ -100,22 +93,12 @@ prefs_load(void) g_error_free(err); } - // move pre 0.4.6 OTR warn preferences to [ui] group - err = NULL; - gboolean otr_warn = g_key_file_get_boolean(prefs, PREF_GROUP_OTR, "warn", &err); - if (err == NULL) { - g_key_file_set_boolean(prefs, PREF_GROUP_UI, _get_key(PREF_OTR_WARN), otr_warn); - g_key_file_remove_key(prefs, PREF_GROUP_OTR, "warn", NULL); - } else { - g_error_free(err); - } - - // move pre 0.4.6 titlebar preference + // move pre 0.4.7 otr.warn to enc.warn err = NULL; - gchar *old_titlebar = g_key_file_get_string(prefs, PREF_GROUP_UI, "titlebar", &err); + gboolean otr_warn = g_key_file_get_boolean(prefs, PREF_GROUP_UI, "otr.warn", &err); if (err == NULL) { - g_key_file_set_string(prefs, PREF_GROUP_UI, _get_key(PREF_TITLEBAR_SHOW), old_titlebar); - g_key_file_remove_key(prefs, PREF_GROUP_UI, "titlebar", NULL); + g_key_file_set_boolean(prefs, PREF_GROUP_UI, _get_key(PREF_ENC_WARN), otr_warn); + g_key_file_remove_key(prefs, PREF_GROUP_UI, "otr.warn", NULL); } else { g_error_free(err); } @@ -181,7 +164,7 @@ prefs_get_string(preference_t pref) if (result == NULL) { if (def) { - return strdup(def); + return g_strdup(def); } else { return NULL; } @@ -194,7 +177,7 @@ void prefs_free_string(char *pref) { if (pref) { - free(pref); + g_free(pref); } pref = NULL; } @@ -507,6 +490,7 @@ _get_group(preference_t pref) case PREF_MUC_PRIVILEGES: case PREF_PRESENCE: case PREF_WRAP: + case PREF_WINS_AUTO_TIDY: case PREF_TIME: case PREF_TIME_STATUSBAR: case PREF_ROSTER: @@ -515,7 +499,7 @@ _get_group(preference_t pref) case PREF_ROSTER_BY: case PREF_RESOURCE_TITLE: case PREF_RESOURCE_MESSAGE: - case PREF_OTR_WARN: + case PREF_ENC_WARN: case PREF_INPBLOCK_DYNAMIC: return PREF_GROUP_UI; case PREF_STATES: @@ -550,6 +534,8 @@ _get_group(preference_t pref) case PREF_OTR_LOG: case PREF_OTR_POLICY: return PREF_GROUP_OTR; + case PREF_PGP_LOG: + return PREF_GROUP_PGP; default: return NULL; } @@ -642,8 +628,6 @@ _get_key(preference_t pref) return "defaccount"; case PREF_OTR_LOG: return "log"; - case PREF_OTR_WARN: - return "otr.warn"; case PREF_OTR_POLICY: return "policy"; case PREF_LOG_ROTATE: @@ -654,6 +638,8 @@ _get_key(preference_t pref) return "presence"; case PREF_WRAP: return "wrap"; + case PREF_WINS_AUTO_TIDY: + return "wins.autotidy"; case PREF_TIME: return "time"; case PREF_TIME_STATUSBAR: @@ -672,6 +658,10 @@ _get_key(preference_t pref) return "resource.message"; case PREF_INPBLOCK_DYNAMIC: return "inpblock.dynamic"; + case PREF_ENC_WARN: + return "enc.warn"; + case PREF_PGP_LOG: + return "log"; default: return NULL; } @@ -684,7 +674,7 @@ _get_default_boolean(preference_t pref) { switch (pref) { - case PREF_OTR_WARN: + case PREF_ENC_WARN: case PREF_AUTOAWAY_CHECK: case PREF_LOG_ROTATE: case PREF_LOG_SHARED: @@ -700,6 +690,7 @@ _get_default_boolean(preference_t pref) case PREF_MUC_PRIVILEGES: case PREF_PRESENCE: case PREF_WRAP: + case PREF_WINS_AUTO_TIDY: case PREF_INPBLOCK_DYNAMIC: case PREF_RESOURCE_TITLE: case PREF_RESOURCE_MESSAGE: @@ -720,6 +711,7 @@ _get_default_string(preference_t pref) switch (pref) { case PREF_AUTOAWAY_MODE: + return "off"; case PREF_NOTIFY_ROOM: return "on"; case PREF_OTR_LOG: @@ -736,6 +728,8 @@ _get_default_string(preference_t pref) return "%H:%M:%S"; case PREF_TIME_STATUSBAR: return "%H:%M"; + case PREF_PGP_LOG: + return "redact"; default: return NULL; } diff --git a/src/config/preferences.h b/src/config/preferences.h index 4455eca1..9e8d2898 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -38,11 +38,6 @@ #include "config.h" #include <glib.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif #define PREFS_MIN_LOG_SIZE 64 #define PREFS_MAX_LOG_SIZE 1048580 @@ -74,6 +69,7 @@ typedef enum { PREF_MUC_PRIVILEGES, PREF_PRESENCE, PREF_WRAP, + PREF_WINS_AUTO_TIDY, PREF_TIME, PREF_TIME_STATUSBAR, PREF_STATUSES, @@ -102,11 +98,12 @@ typedef enum { PREF_LOG_ROTATE, PREF_LOG_SHARED, PREF_OTR_LOG, - PREF_OTR_WARN, PREF_OTR_POLICY, PREF_RESOURCE_TITLE, PREF_RESOURCE_MESSAGE, - PREF_INPBLOCK_DYNAMIC + PREF_INPBLOCK_DYNAMIC, + PREF_ENC_WARN, + PREF_PGP_LOG } preference_t; typedef struct prof_alias_t { diff --git a/src/config/theme.c b/src/config/theme.c index f73dee19..d870b371 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -207,12 +207,15 @@ theme_close(void) { if (theme) { g_key_file_free(theme); + theme = NULL; } if (theme_loc) { g_string_free(theme_loc, TRUE); + theme_loc = NULL; } if (bold_items) { g_hash_table_destroy(bold_items); + bold_items = NULL; } } @@ -428,6 +431,7 @@ _load_preferences(void) _set_boolean_preference("flash", PREF_FLASH); _set_boolean_preference("splash", PREF_SPLASH); _set_boolean_preference("wrap", PREF_WRAP); + _set_boolean_preference("wins.autotidy", PREF_WINS_AUTO_TIDY); _set_string_preference("time", PREF_TIME); _set_string_preference("time.statusbar", PREF_TIME_STATUSBAR); @@ -459,7 +463,7 @@ _load_preferences(void) _set_boolean_preference("presence", PREF_PRESENCE); _set_boolean_preference("intype", PREF_INTYPE); - _set_boolean_preference("otr.warn", PREF_OTR_WARN); + _set_boolean_preference("enc.warn", PREF_ENC_WARN); } static gchar * @@ -613,4 +617,4 @@ theme_attrs(theme_item_t attrs) return result; } -} \ No newline at end of file +} diff --git a/src/config/theme.h b/src/config/theme.h index 13099eb4..2ddbb17b 100644 --- a/src/config/theme.h +++ b/src/config/theme.h @@ -38,11 +38,6 @@ #include "config.h" #include <glib.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif typedef enum { THEME_TEXT, diff --git a/src/event/client_events.c b/src/event/client_events.c index f0f763a6..2bf48234 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -32,16 +32,20 @@ * */ +#include <stdlib.h> #include <glib.h> #include "config.h" #include "log.h" #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" #include "xmpp/xmpp.h" #ifdef HAVE_LIBOTR #include "otr/otr.h" #endif +#ifdef HAVE_LIBGPGME +#include "pgp/gpg.h" +#endif jabber_conn_status_t cl_ev_connect_jid(const char * const jid, const char * const passwd, const char * const altdomain, const int port) @@ -63,7 +67,20 @@ cl_ev_connect_account(ProfAccount *account) void cl_ev_presence_send(const resource_presence_t presence_type, const char * const msg, const int idle) { - presence_send(presence_type, msg, idle); + char *signed_status = NULL; + +#ifdef HAVE_LIBGPGME + char *account_name = jabber_get_account_name(); + ProfAccount *account = accounts_get_account(account_name); + if (account->pgp_keyid) { + signed_status = p_gpg_sign(msg, account->pgp_keyid); + } + account_free(account); +#endif + + presence_send(presence_type, msg, idle, signed_status); + + free(signed_status); } void @@ -71,13 +88,70 @@ cl_ev_send_msg(ProfChatWin *chatwin, const char * const msg) { chat_state_active(chatwin->state); +// OTR suported, PGP supported +#ifdef HAVE_LIBOTR +#ifdef HAVE_LIBGPGME + prof_enc_t enc_mode = chatwin->enc_mode; + if (enc_mode == PROF_ENC_NONE || enc_mode == PROF_ENC_OTR) { + gboolean handled = otr_on_message_send(chatwin, msg); + if (!handled) { + char *id = message_send_chat(chatwin->barejid, msg); + chat_log_msg_out(chatwin->barejid, msg); + ui_outgoing_chat_msg(chatwin, msg, id); + free(id); + } + } else { // enc_mode = PROF_ENC_PGP + char *id = message_send_chat_pgp(chatwin->barejid, msg); + chat_log_pgp_msg_out(chatwin->barejid, msg); + ui_outgoing_chat_msg(chatwin, msg, id); + free(id); + } + return; +#endif +#endif + +// OTR supported, PGP unsupported #ifdef HAVE_LIBOTR - otr_on_message_send(chatwin, msg); -#else +#ifndef HAVE_LIBGPGME + gboolean handled = otr_on_message_send(chatwin, msg); + if (!handled) { + char *id = message_send_chat(chatwin->barejid, msg); + chat_log_msg_out(chatwin->barejid, msg); + ui_outgoing_chat_msg(chatwin, msg, id); + free(id); + } + return; +#endif +#endif + +// OTR unsupported, PGP supported +#ifndef HAVE_LIBOTR +#ifdef HAVE_LIBGPGME + prof_enc_t enc_mode = chatwin->enc_mode; + if (enc_mode == PROF_ENC_NONE) { + char *id = message_send_chat(chatwin->barejid, msg); + chat_log_msg_out(chatwin->barejid, msg); + ui_outgoing_chat_msg(chatwin, msg, id); + free(id); + } else if (enc_mode == PROF_ENC_PGP) { + char *id = message_send_chat_pgp(chatwin->barejid, msg); + chat_log_pgp_msg_out(chatwin->barejid, msg); + ui_outgoing_chat_msg(chatwin, msg, id); + free(id); + } + return; +#endif +#endif + +// OTR unsupported, PGP unsupported +#ifndef HAVE_LIBOTR +#ifndef HAVE_LIBGPGME char *id = message_send_chat(chatwin->barejid, msg); chat_log_msg_out(chatwin->barejid, msg); ui_outgoing_chat_msg(chatwin, msg, id); free(id); + return; +#endif #endif } @@ -92,4 +166,4 @@ cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char * const msg) { message_send_private(privwin->fulljid, msg); ui_outgoing_private_msg(privwin, msg); -} \ No newline at end of file +} diff --git a/src/event/server_events.c b/src/event/server_events.c index e2e910a3..df7a4418 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -43,10 +43,14 @@ #include "config/preferences.h" #include "config/account.h" #include "roster_list.h" +#include "window_list.h" #ifdef HAVE_LIBOTR #include "otr/otr.h" #endif +#ifdef HAVE_LIBGPGME +#include "pgp/gpg.h" +#endif #include "ui/ui.h" @@ -59,6 +63,10 @@ sv_ev_login_account_success(char *account_name) otr_on_connect(account); #endif +#ifdef HAVE_LIBGPGME + p_gpg_on_connect(account->jid); +#endif + ui_handle_login_account_success(account); // attempt to rejoin rooms with passwords @@ -93,6 +101,9 @@ sv_ev_lost_connection(void) muc_invites_clear(); chat_sessions_clear(); ui_disconnected(); +#ifdef HAVE_LIBGPGME + p_gpg_on_disconnect(); +#endif } void @@ -135,9 +146,9 @@ sv_ev_room_subject(const char * const room, const char * const nick, const char void sv_ev_room_history(const char * const room_jid, const char * const nick, - GTimeVal tv_stamp, const char * const message) + GDateTime *timestamp, const char * const message) { - ui_room_history(room_jid, nick, tv_stamp, message); + ui_room_history(room_jid, nick, timestamp, message); } void @@ -160,33 +171,146 @@ sv_ev_incoming_private_message(const char * const fulljid, char *message) } void -sv_ev_carbon(char *barejid, char *message) +sv_ev_outgoing_carbon(char *barejid, char *message) { ui_outgoing_chat_msg_carbon(barejid, message); } void -sv_ev_incoming_message(char *barejid, char *resource, char *message) +sv_ev_incoming_carbon(char *barejid, char *resource, char *message) +{ + gboolean new_win = FALSE; + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + ProfWin *window = wins_new_chat(barejid); + chatwin = (ProfChatWin*)window; + new_win = TRUE; + } + + ui_incoming_msg(chatwin, resource, message, NULL, new_win); + chat_log_msg_in(barejid, message); +} + +void +sv_ev_incoming_message(char *barejid, char *resource, char *message, char *enc_message) { + gboolean new_win = FALSE; + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + ProfWin *window = wins_new_chat(barejid); + chatwin = (ProfChatWin*)window; + new_win = TRUE; + } + +// OTR suported, PGP supported #ifdef HAVE_LIBOTR - otr_on_message_recv(barejid, resource, message); -#else - ui_incoming_msg(barejid, resource, message, NULL); +#ifdef HAVE_LIBGPGME + prof_enc_t enc_mode = chatwin->enc_mode; + if (enc_message) { + if (enc_mode == PROF_ENC_OTR) { + win_println((ProfWin*)chatwin, "PGP encrypted message received whilst in OTR session."); + } else { // PROF_ENC_NONE, PROF_ENC_PGP + char *decrypted = p_gpg_decrypt(barejid, enc_message); + if (decrypted) { + if (enc_mode == PROF_ENC_NONE) { + win_println((ProfWin*)chatwin, "PGP encryption enabled."); + } + ui_incoming_msg(chatwin, resource, decrypted, NULL, new_win); + chat_log_pgp_msg_in(barejid, decrypted); + chatwin->enc_mode = PROF_ENC_PGP; + } else { + ui_incoming_msg(chatwin, resource, message, NULL, new_win); + chat_log_msg_in(barejid, message); + chatwin->enc_mode = PROF_ENC_NONE; + } + } + } else { + if (enc_mode == PROF_ENC_PGP) { + win_println((ProfWin*)chatwin, "PGP encryption disabled."); + ui_incoming_msg(chatwin, resource, message, NULL, new_win); + chat_log_msg_in(barejid, message); + chatwin->enc_mode = PROF_ENC_NONE; + } else { + gboolean decrypted = FALSE; + char *otr_res = otr_on_message_recv(barejid, resource, message, &decrypted); + if (otr_res) { + ui_incoming_msg(chatwin, resource, otr_res, NULL, new_win); + chat_log_otr_msg_in(barejid, otr_res, decrypted); + otr_free_message(otr_res); + } + } + } + return; +#endif +#endif + +// OTR supported, PGP unsupported +#ifdef HAVE_LIBOTR +#ifndef HAVE_LIBGPGME + gboolean decrypted = FALSE; + char *otr_res = otr_on_message_recv(barejid, resource, message, &decrypted); + if (otr_res) { + ui_incoming_msg(chatwin, resource, otr_res, NULL, new_win); + chat_log_otr_msg_in(barejid, otr_res, decrypted); + otr_free_message(otr_res); + } + return; +#endif +#endif + +// OTR unsupported, PGP supported +#ifndef HAVE_LIBOTR +#ifdef HAVE_LIBGPGME + if (enc_message) { + char *decrypted = p_gpg_decrypt(barejid, enc_message); + if (decrypted) { + ui_incoming_msg(chatwin, resource, decrypted, NULL, new_win); + chat_log_pgp_msg_in(barejid, decrypted); + chatwin->enc_mode = PROF_ENC_PGP; + } else { + ui_incoming_msg(chatwin, resource, message, NULL, new_win); + chat_log_msg_in(barejid, message); + chatwin->enc_mode = PROF_ENC_NONE; + } + } else { + ui_incoming_msg(chatwin, resource, message, NULL, new_win); + chat_log_msg_in(barejid, message); + chatwin->enc_mode = PROF_ENC_NONE; + } + return; +#endif +#endif + +// OTR unsupported, PGP unsupported +#ifndef HAVE_LIBOTR +#ifndef HAVE_LIBGPGME + ui_incoming_msg(chatwin, resource, message, NULL, new_win); chat_log_msg_in(barejid, message); + chatwin->enc_mode = PROF_ENC_NONE; + return; +#endif #endif } void -sv_ev_delayed_private_message(const char * const fulljid, char *message, GTimeVal tv_stamp) +sv_ev_delayed_private_message(const char * const fulljid, char *message, GDateTime *timestamp) { - ui_incoming_private_msg(fulljid, message, &tv_stamp); + ui_incoming_private_msg(fulljid, message, timestamp); } void -sv_ev_delayed_message(char *barejid, char *message, GTimeVal tv_stamp) +sv_ev_delayed_message(char *barejid, char *message, GDateTime *timestamp) { - ui_incoming_msg(barejid, NULL, message, &tv_stamp); - chat_log_msg_in_delayed(barejid, message, &tv_stamp); + gboolean new_win = FALSE; + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + ProfWin *window = wins_new_chat(barejid); + chatwin = (ProfChatWin*)window; + new_win = TRUE; + } + + ui_incoming_msg(chatwin, NULL, message, timestamp, new_win); + chat_log_msg_in_delayed(barejid, message, timestamp); } void @@ -280,7 +404,7 @@ sv_ev_contact_offline(char *barejid, char *resource, char *status) } void -sv_ev_contact_online(char *barejid, Resource *resource, GDateTime *last_activity) +sv_ev_contact_online(char *barejid, Resource *resource, GDateTime *last_activity, char *pgpsig) { gboolean updated = roster_update_presence(barejid, resource, last_activity); @@ -288,6 +412,12 @@ sv_ev_contact_online(char *barejid, Resource *resource, GDateTime *last_activity ui_contact_online(barejid, resource, last_activity); } +#ifdef HAVE_LIBGPGME + if (pgpsig) { + p_gpg_verify(barejid, pgpsig); + } +#endif + rosterwin_roster(); chat_session_remove(barejid); } diff --git a/src/event/server_events.h b/src/event/server_events.h index 46d485da..4a3f86c2 100644 --- a/src/event/server_events.h +++ b/src/event/server_events.h @@ -47,13 +47,13 @@ void sv_ev_room_broadcast(const char *const room_jid, const char * const message); void sv_ev_room_subject(const char * const room, const char * const nick, const char * const subject); void sv_ev_room_history(const char * const room_jid, const char * const nick, - GTimeVal tv_stamp, const char * const message); + GDateTime *timestamp, const char * const message); void sv_ev_room_message(const char * const room_jid, const char * const nick, const char * const message); -void sv_ev_incoming_message(char *barejid, char *resource, char *message); +void sv_ev_incoming_message(char *barejid, char *resource, char *message, char *enc_message); void sv_ev_incoming_private_message(const char * const fulljid, char *message); -void sv_ev_delayed_message(char *fulljid, char *message, GTimeVal tv_stamp); -void sv_ev_delayed_private_message(const char * const fulljid, char *message, GTimeVal tv_stamp); +void sv_ev_delayed_message(char *fulljid, char *message, GDateTime *timestamp); +void sv_ev_delayed_private_message(const char * const fulljid, char *message, GDateTime *timestamp); void sv_ev_typing(char *barejid, char *resource); void sv_ev_paused(char *barejid, char *resource); void sv_ev_inactive(char *barejid, char *resource); @@ -62,8 +62,7 @@ void sv_ev_gone(const char * const barejid, const char * const resource); void sv_ev_subscription(const char *from, jabber_subscr_t type); void sv_ev_message_receipt(char *barejid, char *id); void sv_ev_contact_offline(char *contact, char *resource, char *status); -void sv_ev_contact_online(char *contact, Resource *resource, - GDateTime *last_activity); +void sv_ev_contact_online(char *contact, Resource *resource, GDateTime *last_activity, char *pgpkey); void sv_ev_leave_room(const char * const room); void sv_ev_room_destroy(const char * const room); void sv_ev_room_occupant_offline(const char * const room, const char * const nick, @@ -76,7 +75,8 @@ void sv_ev_room_occupent_kicked(const char * const room, const char * const nick void sv_ev_room_banned(const char * const room, const char * const actor, const char * const reason); void sv_ev_room_occupent_banned(const char * const room, const char * const nick, const char * const actor, const char * const reason); -void sv_ev_carbon(char *barejid, char *message); +void sv_ev_outgoing_carbon(char *barejid, char *message); +void sv_ev_incoming_carbon(char *barejid, char *resource, char *message); void sv_ev_xmpp_stanza(const char * const msg); void sv_ev_muc_self_online(const char * const room, const char * const nick, gboolean config_required, const char * const role, const char * const affiliation, const char * const actor, const char * const reason, diff --git a/src/event/ui_events.c b/src/event/ui_events.c index ff1d7273..11296739 100644 --- a/src/event/ui_events.c +++ b/src/event/ui_events.c @@ -33,7 +33,7 @@ */ #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" void ui_ev_focus_win(ProfWin *win) @@ -53,4 +53,4 @@ ProfPrivateWin* ui_ev_new_private_win(const char * const fulljid) { return ui_new_private_win(fulljid); -} \ No newline at end of file +} diff --git a/src/jid.c b/src/jid.c index baeeb279..4eb05e87 100644 --- a/src/jid.c +++ b/src/jid.c @@ -91,6 +91,7 @@ jid_create(const gchar * const str) char *barejidraw = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, slashp)); result->barejid = g_utf8_strdown(barejidraw, -1); result->fulljid = g_strdup(trimmed); + g_free(barejidraw); } else { result->domainpart = g_strdup(domain_start); result->barejid = g_utf8_strdown(trimmed, -1); @@ -192,4 +193,4 @@ jid_fulljid_or_barejid(Jid *jid) } else { return jid->barejid; } -} \ No newline at end of file +} diff --git a/src/log.c b/src/log.c index a7727e8b..e4c7f305 100644 --- a/src/log.c +++ b/src/log.c @@ -34,6 +34,7 @@ #include <assert.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -61,6 +62,16 @@ static GHashTable *logs; static GHashTable *groupchat_logs; static GDateTime *session_started; +enum { + STDERR_BUFSIZE = 4000, + STDERR_RETRY_NR = 5, +}; +static int stderr_inited; +static log_level_t stderr_level; +static int stderr_pipe[2]; +static char *stderr_buf; +static GString *stderr_msg; + struct dated_chat_log { gchar *filename; GDateTime *date; @@ -80,7 +91,7 @@ static gchar * _get_main_log_file(void); static void _rotate_log_file(void); static char* _log_string_from_level(log_level_t level); static void _chat_log_chat(const char * const login, const char * const other, - const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp); + const gchar * const msg, chat_log_direction_t direction, GDateTime *timestamp); void log_debug(const char * const msg, ...) @@ -280,6 +291,23 @@ chat_log_otr_msg_out(const char * const barejid, const char * const msg) } void +chat_log_pgp_msg_out(const char * const barejid, const char * const msg) +{ + if (prefs_get_boolean(PREF_CHLOG)) { + const char *jid = jabber_get_fulljid(); + Jid *jidp = jid_create(jid); + char *pref_pgp_log = prefs_get_string(PREF_PGP_LOG); + if (strcmp(pref_pgp_log, "on") == 0) { + _chat_log_chat(jidp->barejid, barejid, msg, PROF_OUT_LOG, NULL); + } else if (strcmp(pref_pgp_log, "redact") == 0) { + _chat_log_chat(jidp->barejid, barejid, "[redacted]", PROF_OUT_LOG, NULL); + } + prefs_free_string(pref_pgp_log); + jid_destroy(jidp); + } +} + +void chat_log_otr_msg_in(const char * const barejid, const char * const msg, gboolean was_decrypted) { if (prefs_get_boolean(PREF_CHLOG)) { @@ -297,6 +325,23 @@ chat_log_otr_msg_in(const char * const barejid, const char * const msg, gboolean } void +chat_log_pgp_msg_in(const char * const barejid, const char * const msg) +{ + if (prefs_get_boolean(PREF_CHLOG)) { + const char *jid = jabber_get_fulljid(); + Jid *jidp = jid_create(jid); + char *pref_pgp_log = prefs_get_string(PREF_PGP_LOG); + if (strcmp(pref_pgp_log, "on") == 0) { + _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, NULL); + } else if (strcmp(pref_pgp_log, "redact") == 0) { + _chat_log_chat(jidp->barejid, barejid, "[redacted]", PROF_IN_LOG, NULL); + } + prefs_free_string(pref_pgp_log); + jid_destroy(jidp); + } +} + +void chat_log_msg_in(const char * const barejid, const char * const msg) { if (prefs_get_boolean(PREF_CHLOG)) { @@ -308,19 +353,19 @@ chat_log_msg_in(const char * const barejid, const char * const msg) } void -chat_log_msg_in_delayed(const char * const barejid, const char * msg, GTimeVal *tv_stamp) +chat_log_msg_in_delayed(const char * const barejid, const char * msg, GDateTime *timestamp) { if (prefs_get_boolean(PREF_CHLOG)) { const char *jid = jabber_get_fulljid(); Jid *jidp = jid_create(jid); - _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, tv_stamp); + _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, timestamp); jid_destroy(jidp); } } static void _chat_log_chat(const char * const login, const char * const other, - const char * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp) + const char * const msg, chat_log_direction_t direction, GDateTime *timestamp) { struct dated_chat_log *dated_log = g_hash_table_lookup(logs, other); @@ -335,16 +380,9 @@ _chat_log_chat(const char * const login, const char * const other, g_hash_table_replace(logs, strdup(other), dated_log); } - gchar *date_fmt = NULL; - GDateTime *dt = NULL; - if (tv_stamp == NULL) { - dt = g_date_time_new_now_local(); - } else { - dt = g_date_time_new_from_timeval_utc(tv_stamp); - } - - date_fmt = g_date_time_format(dt, "%H:%M:%S"); + if (timestamp == NULL) timestamp = g_date_time_new_now_local(); + gchar *date_fmt = g_date_time_format(timestamp, "%H:%M:%S"); FILE *logp = fopen(dated_log->filename, "a"); g_chmod(dated_log->filename, S_IRUSR | S_IWUSR); if (logp) { @@ -369,7 +407,6 @@ _chat_log_chat(const char * const login, const char * const other, } g_free(date_fmt); - g_date_time_unref(dt); } void @@ -656,3 +693,95 @@ _log_string_from_level(log_level_t level) return "LOG"; } } + +void +log_stderr_handler(void) +{ + GString * const s = stderr_msg; + char * const buf = stderr_buf; + ssize_t size; + int retry = 0; + int i; + + if (!stderr_inited) + return; + + do { + size = read(stderr_pipe[0], buf, STDERR_BUFSIZE); + if (size == -1 && errno == EINTR && retry++ < STDERR_RETRY_NR) + continue; + if (size <= 0 || retry++ >= STDERR_RETRY_NR) + break; + + for (i = 0; i < size; ++i) { + if (buf[i] == '\n') { + log_msg(stderr_level, "stderr", s->str); + g_string_assign(s, ""); + } else + g_string_append_c(s, buf[i]); + } + } while (1); + + if (s->len > 0 && s->str[0] != '\0') { + log_msg(stderr_level, "stderr", s->str); + g_string_assign(s, ""); + } +} + +void +log_stderr_init(log_level_t level) +{ + int rc; + int flags; + + rc = pipe(stderr_pipe); + if (rc != 0) + goto err; + + flags = fcntl(stderr_pipe[0], F_GETFL); + rc = fcntl(stderr_pipe[0], F_SETFL, flags | O_NONBLOCK); + if (rc != 0) + goto err_close; + + close(STDERR_FILENO); + rc = dup2(stderr_pipe[1], STDERR_FILENO); + if (rc < 0) + goto err_close; + + stderr_buf = malloc(STDERR_BUFSIZE); + stderr_msg = g_string_sized_new(STDERR_BUFSIZE); + stderr_level = level; + stderr_inited = 1; + + if (stderr_buf == NULL || stderr_msg == NULL) { + errno = ENOMEM; + goto err_free; + } + return; + +err_free: + if (stderr_msg != NULL) + g_string_free(stderr_msg, TRUE); + free(stderr_buf); +err_close: + close(stderr_pipe[0]); + close(stderr_pipe[1]); +err: + stderr_inited = 0; + log_error("Unable to init stderr log handler: %s", strerror(errno)); +} + +void +log_stderr_close(void) +{ + if (!stderr_inited) + return; + + /* handle remaining logs before close */ + log_stderr_handler(); + stderr_inited = 0; + free(stderr_buf); + g_string_free(stderr_msg, TRUE); + close(stderr_pipe[0]); + close(stderr_pipe[1]); +} diff --git a/src/log.h b/src/log.h index 0689e2e6..99975670 100644 --- a/src/log.h +++ b/src/log.h @@ -63,14 +63,20 @@ void log_msg(log_level_t level, const char * const area, const char * const msg); log_level_t log_level_from_string(char *log_level); +void log_stderr_init(log_level_t level); +void log_stderr_close(void); +void log_stderr_handler(void); + void chat_log_init(void); void chat_log_msg_out(const char * const barejid, const char * const msg); void chat_log_otr_msg_out(const char * const barejid, const char * const msg); +void chat_log_pgp_msg_out(const char * const barejid, const char * const msg); void chat_log_msg_in(const char * const barejid, const char * const msg); -void chat_log_msg_in_delayed(const char * const barejid, const char * msg, GTimeVal *tv_stamp); +void chat_log_msg_in_delayed(const char * const barejid, const char * msg, GDateTime *timestamp); void chat_log_otr_msg_in(const char * const barejid, const char * const msg, gboolean was_decrypted); +void chat_log_pgp_msg_in(const char * const barejid, const char * const msg); void chat_log_close(void); GSList * chat_log_get_previous(const gchar * const login, diff --git a/src/main.c b/src/main.c index 3bb7eeb6..ea8f0cea 100644 --- a/src/main.c +++ b/src/main.c @@ -121,6 +121,12 @@ main(int argc, char **argv) g_print("OTR support: Disabled\n"); #endif +#ifdef HAVE_LIBGPGME + g_print("PGP support: Enabled\n"); +#else + g_print("PGP support: Disabled\n"); +#endif + return 0; } diff --git a/src/muc.c b/src/muc.c index d283b55e..4474976d 100644 --- a/src/muc.c +++ b/src/muc.c @@ -34,6 +34,7 @@ #include <stdlib.h> #include <string.h> +#include <assert.h> #include <glib.h> @@ -42,7 +43,7 @@ #include "jid.h" #include "tools/autocomplete.h" #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" #include "muc.h" typedef struct _muc_room_t { @@ -663,11 +664,11 @@ muc_roster_nick_change_complete(const char * const room, } char * -muc_autocomplete(const char * const input) +muc_autocomplete(ProfWin *window, const char * const input) { - win_type_t wintype = ui_current_win_type(); - if (wintype == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); + if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); ChatRoom *chat_room = g_hash_table_lookup(rooms, mucwin->roomjid); if (chat_room && chat_room->nick_ac) { @@ -978,4 +979,4 @@ _occupant_free(Occupant *occupant) free(occupant); occupant = NULL; } -} \ No newline at end of file +} diff --git a/src/muc.h b/src/muc.h index ad96f3d9..eb636aff 100644 --- a/src/muc.h +++ b/src/muc.h @@ -40,6 +40,7 @@ #include "contact.h" #include "jid.h" #include "tools/autocomplete.h" +#include "ui/win_types.h" typedef enum { MUC_ROLE_NONE, @@ -133,7 +134,7 @@ char* muc_subject(const char * const room); void muc_pending_broadcasts_add(const char * const room, const char * const message); GList * muc_pending_broadcasts(const char * const room); -char* muc_autocomplete(const char * const input); +char* muc_autocomplete(ProfWin *window, const char * const input); void muc_autocomplete_reset(const char * const room); gboolean muc_requires_config(const char * const room); diff --git a/src/otr/otr.c b/src/otr/otr.c index e568af56..e61a0e47 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -110,7 +110,7 @@ static void cb_inject_message(void *opdata, const char *accountname, const char *protocol, const char *recipient, const char *message) { - message_send_chat_encrypted(recipient, message); + message_send_chat_otr(recipient, message); } static void @@ -163,6 +163,8 @@ otr_init(void) log_info("Initialising OTR"); OTRL_INIT; + jid = NULL; + ops.policy = cb_policy; ops.is_logged_in = cb_is_logged_in; ops.inject_message = cb_inject_message; @@ -181,6 +183,7 @@ otr_shutdown(void) { if (jid) { free(jid); + jid = NULL; } } @@ -269,12 +272,9 @@ otr_on_connect(ProfAccount *account) return; } -void -otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message) +char* +otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message, gboolean *was_decrypted) { - gboolean was_decrypted = FALSE; - char *decrypted; - prof_otrpolicy_t policy = otr_get_policy(barejid); char *whitespace_base = strstr(message, OTRL_MESSAGE_TAG_BASE); @@ -291,65 +291,65 @@ otr_on_message_recv(const char * const barejid, const char * const resource, con memmove(whitespace_base, whitespace_base+tag_length, tag_length); char *otr_query_message = otr_start_query(); cons_show("OTR Whitespace pattern detected. Attempting to start OTR session..."); - message_send_chat_encrypted(barejid, otr_query_message); + message_send_chat_otr(barejid, otr_query_message); } } } - decrypted = otr_decrypt_message(barejid, message, &was_decrypted); - // internal OTR message - if (decrypted == NULL) { - return; + char *decrypted = otr_decrypt_message(barejid, message, was_decrypted); + if (!decrypted) { // internal OTR message + return NULL; } - if (policy == PROF_OTRPOLICY_ALWAYS && !was_decrypted && !whitespace_base) { + if (policy == PROF_OTRPOLICY_ALWAYS && *was_decrypted == FALSE && !whitespace_base) { char *otr_query_message = otr_start_query(); cons_show("Attempting to start OTR session..."); - message_send_chat_encrypted(barejid, otr_query_message); + message_send_chat_otr(barejid, otr_query_message); } - ui_incoming_msg(barejid, resource, decrypted, NULL); - chat_log_otr_msg_in(barejid, decrypted, was_decrypted); - otr_free_message(decrypted); + return decrypted; } -void +gboolean otr_on_message_send(ProfChatWin *chatwin, const char * const message) { char *id = NULL; - prof_otrpolicy_t policy = otr_get_policy(chatwin->barejid); + // Send encrypted message if (otr_is_secure(chatwin->barejid)) { char *encrypted = otr_encrypt_message(chatwin->barejid, message); if (encrypted) { - id = message_send_chat_encrypted(chatwin->barejid, encrypted); + id = message_send_chat_otr(chatwin->barejid, encrypted); chat_log_otr_msg_out(chatwin->barejid, message); ui_outgoing_chat_msg(chatwin, message, id); otr_free_message(encrypted); + free(id); + return TRUE; } else { ui_win_error_line((ProfWin*)chatwin, "Failed to encrypt and send message."); - return; + return TRUE; } + } - } else if (policy == PROF_OTRPOLICY_ALWAYS) { + // show error if not secure and policy always + if (policy == PROF_OTRPOLICY_ALWAYS) { ui_win_error_line((ProfWin*)chatwin, "Failed to send message. OTR policy set to: always"); - return; + return TRUE; + } - } else if (policy == PROF_OTRPOLICY_OPPORTUNISTIC) { + // tag and send for policy opportunistic + if (policy == PROF_OTRPOLICY_OPPORTUNISTIC) { char *otr_tagged_msg = otr_tag_message(message); - id = message_send_chat_encrypted(chatwin->barejid, otr_tagged_msg); + id = message_send_chat_otr(chatwin->barejid, otr_tagged_msg); ui_outgoing_chat_msg(chatwin, message, id); chat_log_msg_out(chatwin->barejid, message); free(otr_tagged_msg); - - } else { - id = message_send_chat(chatwin->barejid, message); - ui_outgoing_chat_msg(chatwin, message, id); - chat_log_msg_out(chatwin->barejid, message); + free(id); + return TRUE; } - free(id); + return FALSE; } void @@ -642,7 +642,8 @@ otr_get_their_fingerprint(const char * const recipient) prof_otrpolicy_t otr_get_policy(const char * const recipient) { - ProfAccount *account = accounts_get_account(jabber_get_account_name()); + char *account_name = jabber_get_account_name(); + ProfAccount *account = accounts_get_account(account_name); // check contact specific setting if (g_list_find_custom(account->otr_manual, recipient, (GCompareFunc)g_strcmp0)) { account_free(account); @@ -747,4 +748,4 @@ void otr_free_message(char *message) { otrl_message_free(message); -} \ No newline at end of file +} diff --git a/src/otr/otr.h b/src/otr/otr.h index e020c0c8..45abdc20 100644 --- a/src/otr/otr.h +++ b/src/otr/otr.h @@ -39,7 +39,7 @@ #include <libotr/message.h> #include "config/accounts.h" -#include "ui/window.h" +#include "ui/ui.h" typedef enum { PROF_OTRPOLICY_MANUAL, @@ -58,8 +58,8 @@ char* otr_start_query(void); void otr_poll(void); void otr_on_connect(ProfAccount *account); -void otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message); -void otr_on_message_send(ProfChatWin *chatwin, const char * const message); +char* otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message, gboolean *was_decrypted); +gboolean otr_on_message_send(ProfChatWin *chatwin, const char * const message); void otr_keygen(ProfAccount *account); diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c new file mode 100644 index 00000000..724f1e9b --- /dev/null +++ b/src/pgp/gpg.c @@ -0,0 +1,531 @@ +/* + * gpg.c + * + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#include "config.h" + +#include <locale.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/stat.h> + +#include <glib.h> +#include <glib/gstdio.h> +#include <gpgme.h> + +#include "pgp/gpg.h" +#include "log.h" +#include "common.h" + +#define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----" +#define PGP_SIGNATURE_FOOTER "-----END PGP SIGNATURE-----" +#define PGP_MESSAGE_HEADER "-----BEGIN PGP MESSAGE-----" +#define PGP_MESSAGE_FOOTER "-----END PGP MESSAGE-----" + +static const char *libversion; +static GHashTable *fingerprints; + +static gchar *fpsloc; +static GKeyFile *fpskeyfile; + +static char* _remove_header_footer(char *str, const char * const footer); +static char* _add_header_footer(const char * const str, const char * const header, const char * const footer); +static void _save_fps(void); + +void +p_gpg_init(void) +{ + libversion = gpgme_check_version(NULL); + log_debug("GPG: Found gpgme version: %s", libversion); + gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); + + fingerprints = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); +} + +void +p_gpg_close(void) +{ + if (fingerprints) { + g_hash_table_destroy(fingerprints); + fingerprints = NULL; + } + + if (fpskeyfile) { + g_key_file_free(fpskeyfile); + fpskeyfile = NULL; + } + + free(fpsloc); + fpsloc = NULL; +} + +void +p_gpg_on_connect(const char * const barejid) +{ + gchar *data_home = xdg_get_data_home(); + GString *fpsfile = g_string_new(data_home); + free(data_home); + + gchar *account_dir = str_replace(barejid, "@", "_at_"); + g_string_append(fpsfile, "/profanity/pgp/"); + g_string_append(fpsfile, account_dir); + free(account_dir); + + // mkdir if doesn't exist for account + errno = 0; + int res = g_mkdir_with_parents(fpsfile->str, S_IRWXU); + if (res == -1) { + char *errmsg = strerror(errno); + if (errmsg) { + log_error("Error creating directory: %s, %s", fpsfile->str, errmsg); + } else { + log_error("Error creating directory: %s", fpsfile->str); + } + } + + // create or read fingerprints keyfile + g_string_append(fpsfile, "/fingerprints"); + fpsloc = fpsfile->str; + g_string_free(fpsfile, FALSE); + + if (g_file_test(fpsloc, G_FILE_TEST_EXISTS)) { + g_chmod(fpsloc, S_IRUSR | S_IWUSR); + } + + fpskeyfile = g_key_file_new(); + g_key_file_load_from_file(fpskeyfile, fpsloc, G_KEY_FILE_KEEP_COMMENTS, NULL); + + // load each keyid + gsize len = 0; + gchar **jids = g_key_file_get_groups(fpskeyfile, &len); + + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + g_strfreev(jids); + return; + } + + int i = 0; + for (i = 0; i < len; i++) { + GError *gerr = NULL; + gchar *jid = jids[i]; + gchar *keyid = g_key_file_get_string(fpskeyfile, jid, "keyid", &gerr); + if (gerr) { + log_error("Error loading PGP key id for %s", jid); + g_error_free(gerr); + } else { + gpgme_key_t key = NULL; + error = gpgme_get_key(ctx, keyid, &key, 1); + if (error || key == NULL) { + log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + continue; + } + + g_hash_table_replace(fingerprints, strdup(jid), strdup(key->subkeys->fpr)); + gpgme_key_release(key); + } + } + + gpgme_release(ctx); + g_strfreev(jids); + + _save_fps(); +} + +void +p_gpg_on_disconnect(void) +{ + if (fingerprints) { + g_hash_table_destroy(fingerprints); + fingerprints = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + } + + if (fpskeyfile) { + g_key_file_free(fpskeyfile); + fpskeyfile = NULL; + } + + free(fpsloc); + fpsloc = NULL; +} + +gboolean +p_gpg_addkey(const char * const jid, const char * const keyid) +{ + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return FALSE; + } + + gpgme_key_t key = NULL; + error = gpgme_get_key(ctx, keyid, &key, 1); + if (error || key == NULL) { + log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return FALSE; + } + + // save to ID keyfile + g_key_file_set_string(fpskeyfile, jid, "keyid", keyid); + _save_fps(); + + // update in memory fingerprint list + g_hash_table_replace(fingerprints, strdup(jid), strdup(key->subkeys->fpr)); + gpgme_key_release(key); + + return TRUE; +} + +GSList * +p_gpg_list_keys(void) +{ + gpgme_error_t error; + gpgme_ctx_t ctx; + gpgme_key_t key; + GSList *result = NULL; + + error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return NULL; + } + + error = gpgme_op_keylist_start(ctx, NULL, 1); + if (error == GPG_ERR_NO_ERROR) { + while (!error) { + error = gpgme_op_keylist_next(ctx, &key); + if (error) { + break; + } + + ProfPGPKey *p_pgpkey = malloc(sizeof(ProfPGPKey)); + p_pgpkey->id = strdup(key->subkeys->keyid); + p_pgpkey->name = strdup(key->uids->uid); + p_pgpkey->fp = strdup(key->subkeys->fpr); + + result = g_slist_append(result, p_pgpkey); + + gpgme_key_release(key); + } + } else { + log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + } + + gpgme_release(ctx); + + return result; +} + +GHashTable * +p_gpg_fingerprints(void) +{ + return fingerprints; +} + +const char* +p_gpg_libver(void) +{ + return libversion; +} + +void +p_gpg_free_key(ProfPGPKey *key) +{ + if (key) { + free(key->id); + free(key->name); + free(key->fp); + free(key); + } +} + +gboolean +p_gpg_available(const char * const barejid) +{ + char *fp = g_hash_table_lookup(fingerprints, barejid); + return (fp != NULL); +} + +void +p_gpg_verify(const char * const barejid, const char *const sign) +{ + if (!sign) { + return; + } + + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return; + } + + gpgme_data_t sign_data; + gpgme_data_t plain_data; + char *sign_with_header_footer = _add_header_footer(sign, PGP_SIGNATURE_HEADER, PGP_SIGNATURE_FOOTER); + gpgme_data_new_from_mem(&sign_data, sign_with_header_footer, strlen(sign_with_header_footer), 1); + gpgme_data_new(&plain_data); + + error = gpgme_op_verify(ctx, sign_data, NULL, plain_data); + if (error) { + log_error("GPG: Failed to verify. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return; + } + + gpgme_verify_result_t result = gpgme_op_verify_result(ctx); + if (result) { + if (result->signatures) { + log_debug("Fingerprint found for %s: %s ", barejid, result->signatures->fpr); + g_hash_table_replace(fingerprints, strdup(barejid), strdup(result->signatures->fpr)); + } + } + + gpgme_data_release(sign_data); + gpgme_data_release(plain_data); +} + +char* +p_gpg_sign(const char * const str, const char * const fp) +{ + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return NULL; + } + + gpgme_key_t key = NULL; + error = gpgme_get_key(ctx, fp, &key, 1); + if (error || key == NULL) { + log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release (ctx); + return NULL; + } + + gpgme_signers_clear(ctx); + error = gpgme_signers_add(ctx, key); + if (error) { + log_error("GPG: Failed to load signer. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return NULL; + } + + gpgme_data_t str_data; + gpgme_data_t signed_data; + char *str_or_empty = NULL; + if (str) { + str_or_empty = strdup(str); + } else { + str_or_empty = strdup(""); + } + gpgme_data_new_from_mem(&str_data, str_or_empty, strlen(str_or_empty), 1); + gpgme_data_new(&signed_data); + + gpgme_set_armor(ctx,1); + error = gpgme_op_sign(ctx,str_data,signed_data,GPGME_SIG_MODE_DETACH); + if (error) { + log_error("GPG: Failed to sign string. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return NULL; + } + + char *result = NULL; + gpgme_data_release(str_data); + + size_t len = 0; + char *signed_str = gpgme_data_release_and_get_mem(signed_data, &len); + if (signed_str) { + signed_str[len] = 0; + result = _remove_header_footer(signed_str, PGP_SIGNATURE_FOOTER); + } + gpgme_free(signed_str); + gpgme_release(ctx); + free(str_or_empty); + + return result; +} + +char * +p_gpg_encrypt(const char * const barejid, const char * const message) +{ + char *fp = g_hash_table_lookup(fingerprints, barejid); + + if (!fp) { + return NULL; + } + + gpgme_key_t keys[2]; + + keys[0] = NULL; + keys[1] = NULL; + + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return NULL; + } + + gpgme_key_t key; + error = gpgme_get_key(ctx, fp, &key, 0); + if (error || key == NULL) { + log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return NULL; + } + + keys[0] = key; + + gpgme_data_t plain; + gpgme_data_t cipher; + gpgme_data_new_from_mem(&plain, message, strlen(message), 1); + gpgme_data_new(&cipher); + + gpgme_set_armor(ctx, 1); + error = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); + if (error) { + log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return NULL; + } + gpgme_data_release(plain); + + char *cipher_str = NULL; + char *result = NULL; + size_t len; + cipher_str = gpgme_data_release_and_get_mem(cipher, &len); + if (cipher_str) { + result = _remove_header_footer(cipher_str, PGP_MESSAGE_FOOTER); + } + + gpgme_free(cipher_str); + gpgme_release(ctx); + + return result; +} + +char * +p_gpg_decrypt(const char * const barejid, const char * const cipher) +{ + char *cipher_with_headers = _add_header_footer(cipher, PGP_MESSAGE_HEADER, PGP_MESSAGE_FOOTER); + + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return NULL; + } + + gpgme_data_t plain_data; + gpgme_data_t cipher_data; + gpgme_data_new_from_mem (&cipher_data, cipher_with_headers, strlen(cipher_with_headers), 1); + gpgme_data_new(&plain_data); + + error = gpgme_op_decrypt(ctx, cipher_data, plain_data); + if (error) { + log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return NULL; + } + + gpgme_data_release(cipher_data); + + size_t len = 0; + char *plain_str = gpgme_data_release_and_get_mem(plain_data, &len); + char *result = NULL; + if (plain_str) { + plain_str[len] = 0; + result = g_strdup(plain_str); + } + gpgme_free(plain_str); + + gpgme_release(ctx); + + return result; +} + +static char* +_remove_header_footer(char *str, const char * const footer) +{ + int pos = 0; + int newlines = 0; + + while (newlines < 3) { + if (str[pos] == '\n') { + newlines++; + } + pos++; + + if (str[pos] == '\0') { + return NULL; + } + } + + char *stripped = strdup(&str[pos]); + char *footer_start = g_strrstr(stripped, footer); + footer_start[0] = '\0'; + + return stripped; +} + +static char* +_add_header_footer(const char * const str, const char * const header, const char * const footer) +{ + GString *result_str = g_string_new(""); + + g_string_append(result_str, header); + g_string_append(result_str, "\n\n"); + g_string_append(result_str, str); + g_string_append(result_str, "\n"); + g_string_append(result_str, footer); + + char *result = result_str->str; + g_string_free(result_str, FALSE); + + return result; +} + +static void +_save_fps(void) +{ + gsize g_data_size; + gchar *g_fps_data = g_key_file_to_data(fpskeyfile, &g_data_size, NULL); + g_file_set_contents(fpsloc, g_fps_data, g_data_size, NULL); + g_chmod(fpsloc, S_IRUSR | S_IWUSR); + g_free(g_fps_data); +} diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h new file mode 100644 index 00000000..07c99465 --- /dev/null +++ b/src/pgp/gpg.h @@ -0,0 +1,59 @@ +/* + * gpg.h + * + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#ifndef GPG_H +#define GPG_H + +typedef struct pgp_key_t { + char *id; + char *name; + char *fp; +} ProfPGPKey; + +void p_gpg_init(void); +void p_gpg_close(void); +void p_gpg_on_connect(const char * const barejid); +void p_gpg_on_disconnect(void); +GSList* p_gpg_list_keys(void); +gboolean p_gpg_addkey(const char * const jid, const char * const keyid); +GHashTable* p_gpg_fingerprints(void); +gboolean p_gpg_available(const char * const barejid); +const char* p_gpg_libver(void); +void p_gpg_free_key(ProfPGPKey *key); +char* p_gpg_sign(const char * const str, const char * const fp); +void p_gpg_verify(const char * const barejid, const char *const sign); +char* p_gpg_encrypt(const char * const barejid, const char * const message); +char* p_gpg_decrypt(const char * const barejid, const char * const cipher); + +#endif diff --git a/src/profanity.c b/src/profanity.c index 55a73430..a56eb5e9 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -41,6 +41,7 @@ #include <signal.h> #include <stdlib.h> #include <string.h> +#include <assert.h> #include <glib.h> @@ -59,10 +60,13 @@ #ifdef HAVE_LIBOTR #include "otr/otr.h" #endif +#ifdef HAVE_LIBGPGME +#include "pgp/gpg.h" +#endif #include "resource.h" #include "xmpp/xmpp.h" #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" #include "event/client_events.h" static void _check_autoaway(void); @@ -85,11 +89,13 @@ prof_run(const int disable_tls, char *log_level, char *account_name) char *line = NULL; while(cont) { + log_stderr_handler(); _check_autoaway(); line = ui_readline(); if (line) { - cont = cmd_process_input(line); + ProfWin *window = wins_get_current(); + cont = cmd_process_input(window, line); free(line); line = NULL; } else { @@ -100,7 +106,7 @@ prof_run(const int disable_tls, char *log_level, char *account_name) otr_poll(); #endif notify_remind(); - jabber_process_events(); + jabber_process_events(10); ui_update(); } } @@ -129,11 +135,12 @@ prof_handle_idle(void) void prof_handle_activity(void) { - win_type_t win_type = ui_current_win_type(); jabber_conn_status_t status = jabber_get_connection_status(); + ProfWin *current = wins_get_current(); - if ((status == JABBER_CONNECTED) && (win_type == WIN_CHAT)) { - ProfChatWin *chatwin = wins_get_current_chat(); + if ((status == JABBER_CONNECTED) && (current->type == WIN_CHAT)) { + ProfChatWin *chatwin = (ProfChatWin*)current; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); chat_state_handle_typing(chatwin->barejid, chatwin->state); } } @@ -141,12 +148,13 @@ prof_handle_activity(void) static void _connect_default(const char * const account) { + ProfWin *window = wins_get_current(); if (account) { - cmd_execute_connect(account); + cmd_execute_connect(window, account); } else { char *pref_connect_account = prefs_get_string(PREF_CONNECT_ACCOUNT); if (pref_connect_account) { - cmd_execute_connect(pref_connect_account); + cmd_execute_connect(window, pref_connect_account); prefs_free_string(pref_connect_account); } } @@ -218,6 +226,7 @@ _init(const int disable_tls, char *log_level) log_level_t prof_log_level = log_level_from_string(log_level); prefs_load(); log_init(prof_log_level); + log_stderr_init(PROF_LEVEL_ERROR); if (strcmp(PACKAGE_STATUS, "development") == 0) { #ifdef HAVE_GIT_VERSION log_info("Starting Profanity (%sdev.%s.%s)...", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION); @@ -242,6 +251,9 @@ _init(const int disable_tls, char *log_level) #ifdef HAVE_LIBOTR otr_init(); #endif +#ifdef HAVE_LIBGPGME + p_gpg_init(); +#endif atexit(_shutdown); ui_input_nonblocking(TRUE); } @@ -266,12 +278,16 @@ _shutdown(void) #ifdef HAVE_LIBOTR otr_shutdown(); #endif +#ifdef HAVE_LIBGPGME + p_gpg_close(); +#endif chat_log_close(); - prefs_close(); theme_close(); accounts_close(); cmd_uninit(); + log_stderr_close(); log_close(); + prefs_close(); } static void diff --git a/src/ui/buffer.c b/src/ui/buffer.c index 0848b60f..b4771f1a 100644 --- a/src/ui/buffer.c +++ b/src/ui/buffer.c @@ -87,7 +87,7 @@ buffer_push(ProfBuff buffer, const char show_char, GDateTime *time, e->show_char = show_char; e->flags = flags; e->theme_item = theme_item; - e->time = time; + e->time = g_date_time_ref(time); e->from = strdup(from); e->message = strdup(message); e->receipt = receipt; @@ -136,4 +136,4 @@ _free_entry(ProfBuffEntry *entry) free(entry->receipt); } free(entry); -} \ No newline at end of file +} diff --git a/src/ui/console.c b/src/ui/console.c index 895efda4..8bf873a5 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -50,7 +50,7 @@ #include "config/preferences.h" #include "config/theme.h" #include "ui/window.h" -#include "ui/windows.h" +#include "window_list.h" #include "ui/ui.h" #include "ui/statusbar.h" #include "xmpp/xmpp.h" @@ -710,6 +710,10 @@ cons_show_account(ProfAccount *account) g_string_free(always, TRUE); } + if (account->pgp_keyid) { + cons_show ("PGP Key ID : %s", account->pgp_keyid); + } + cons_show ("Priority : chat:%d, online:%d, away:%d, xa:%d, dnd:%d", account->priority_chat, account->priority_online, account->priority_away, account->priority_xa, account->priority_dnd); @@ -872,6 +876,25 @@ cons_wrap_setting(void) } void +cons_winstidy_setting(void) +{ + if (prefs_get_boolean(PREF_WINS_AUTO_TIDY)) + cons_show("Window Auto Tidy (/winstidy) : ON"); + else + cons_show("Window Auto Tidy (/winstidy) : OFF"); +} + +void +cons_encwarn_setting(void) +{ + if (prefs_get_boolean(PREF_ENC_WARN)) { + cons_show("Warn unencrypted (/encwarn) : ON"); + } else { + cons_show("Warn unencrypted (/encwarn) : OFF"); + } +} + +void cons_presence_setting(void) { if (prefs_get_boolean(PREF_PRESENCE)) @@ -1018,6 +1041,7 @@ cons_roster_setting(void) char *by = prefs_get_string(PREF_ROSTER_BY); cons_show("Roster by (/roster) : %s", by); + prefs_free_string(by); int size = prefs_get_roster_size(); cons_show("Roster size (/roster) : %d", size); @@ -1033,6 +1057,7 @@ cons_show_ui_prefs(void) cons_flash_setting(); cons_splash_setting(); cons_wrap_setting(); + cons_winstidy_setting(); cons_time_setting(); cons_resource_setting(); cons_vercheck_setting(); @@ -1042,6 +1067,7 @@ cons_show_ui_prefs(void) cons_roster_setting(); cons_privileges_setting(); cons_titlebar_setting(); + cons_encwarn_setting(); cons_presence_setting(); cons_inpblock_setting(); @@ -1382,12 +1408,6 @@ cons_show_otr_prefs(void) cons_show("OTR policy (/otr policy) : %s", policy_value); prefs_free_string(policy_value); - if (prefs_get_boolean(PREF_OTR_WARN)) { - cons_show("Warn non-OTR (/otr warn) : ON"); - } else { - cons_show("Warn non-OTR (/otr warn) : OFF"); - } - char *log_value = prefs_get_string(PREF_OTR_LOG); if (strcmp(log_value, "on") == 0) { cons_show("OTR logging (/otr log) : ON"); @@ -1402,6 +1422,25 @@ cons_show_otr_prefs(void) } void +cons_show_pgp_prefs(void) +{ + cons_show("PGP preferences:"); + cons_show(""); + + char *log_value = prefs_get_string(PREF_PGP_LOG); + if (strcmp(log_value, "on") == 0) { + cons_show("PGP logging (/pgp log) : ON"); + } else if (strcmp(log_value, "off") == 0) { + cons_show("PGP logging (/pgp log) : OFF"); + } else { + cons_show("PGP logging (/pgp log) : Redacted"); + } + prefs_free_string(log_value); + + cons_alert(); +} + +void cons_show_themes(GSList *themes) { cons_show(""); @@ -1437,6 +1476,8 @@ cons_prefs(void) cons_show(""); cons_show_otr_prefs(); cons_show(""); + cons_show_pgp_prefs(); + cons_show(""); cons_alert(); } @@ -1548,7 +1589,8 @@ cons_show_contacts(GSList *list) void cons_alert(void) { - if (ui_current_win_type() != WIN_CONSOLE) { + ProfWin *current = wins_get_current(); + if (current->type != WIN_CONSOLE) { status_bar_new(1); } } diff --git a/src/ui/core.c b/src/ui/core.c index e7059ef0..fa419e45 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -72,7 +72,7 @@ #include "ui/statusbar.h" #include "ui/inputwin.h" #include "ui/window.h" -#include "ui/windows.h" +#include "window_list.h" #include "xmpp/xmpp.h" #include "event/ui_events.h" @@ -254,7 +254,7 @@ ui_resize(void) resizeterm(w.ws_row, w.ws_col); refresh(); - log_info("Resizing UI"); + log_debug("Resizing UI"); title_bar_resize(); wins_resize_all(); status_bar_resize(); @@ -405,12 +405,6 @@ ui_get_chat_recipients(void) return recipients; } -ProfChatWin * -ui_get_current_chat(void) -{ - return wins_get_current_chat(); -} - void ui_message_receipt(const char * const barejid, const char * const id) { @@ -422,25 +416,16 @@ ui_message_receipt(const char * const barejid, const char * const id) } void -ui_incoming_msg(const char * const barejid, const char * const resource, const char * const message, GTimeVal *tv_stamp) +ui_incoming_msg(ProfChatWin *chatwin, const char * const resource, const char * const message, GDateTime *timestamp, gboolean win_created) { - gboolean win_created = FALSE; - - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin == NULL) { - ProfWin *window = wins_new_chat(barejid); - chatwin = (ProfChatWin*)window; - win_created = TRUE; - } - - ProfWin *window = (ProfWin*) chatwin; + ProfWin *window = (ProfWin*)chatwin; int num = wins_get_num(window); - char *display_name = roster_get_msg_display_name(barejid, resource); + char *display_name = roster_get_msg_display_name(chatwin->barejid, resource); // currently viewing chat window with sender if (wins_is_current(window)) { - win_print_incoming_message(window, tv_stamp, display_name, message); + win_print_incoming_message(window, timestamp, display_name, message); title_bar_set_typing(FALSE); status_bar_active(num); @@ -455,18 +440,18 @@ ui_incoming_msg(const char * const barejid, const char * const resource, const c chatwin->unread++; if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { - _win_show_history(chatwin, barejid); + _win_show_history(chatwin, chatwin->barejid); } // show users status first, when receiving message via delayed delivery - if (tv_stamp && (win_created)) { - PContact pcontact = roster_get_contact(barejid); + if (timestamp && win_created) { + PContact pcontact = roster_get_contact(chatwin->barejid); if (pcontact) { win_show_contact(window, pcontact); } } - win_print_incoming_message(window, tv_stamp, display_name, message); + win_print_incoming_message(window, timestamp, display_name, message); } if (prefs_get_boolean(PREF_BEEP)) { @@ -481,7 +466,7 @@ ui_incoming_msg(const char * const barejid, const char * const resource, const c } void -ui_incoming_private_msg(const char * const fulljid, const char * const message, GTimeVal *tv_stamp) +ui_incoming_private_msg(const char * const fulljid, const char * const message, GDateTime *timestamp) { char *display_from = NULL; display_from = get_nick_from_full_jid(fulljid); @@ -497,7 +482,7 @@ ui_incoming_private_msg(const char * const fulljid, const char * const message, // currently viewing chat window with sender if (wins_is_current(window)) { - win_print_incoming_message(window, tv_stamp, display_from, message); + win_print_incoming_message(window, timestamp, display_from, message); title_bar_set_typing(FALSE); status_bar_active(num); @@ -506,7 +491,7 @@ ui_incoming_private_msg(const char * const fulljid, const char * const message, privatewin->unread++; status_bar_new(num); cons_show_incoming_message(display_from, num); - win_print_incoming_message(window, tv_stamp, display_from, message); + win_print_incoming_message(window, timestamp, display_from, message); if (prefs_get_boolean(PREF_FLASH)) { flash(); @@ -695,7 +680,8 @@ ui_invalid_command_usage(const char * const usage, void (*setting_func)(void)) } else { cons_show(""); cons_show("Usage: %s", usage); - if (ui_current_win_type() == WIN_CHAT) { + ProfWin *current = wins_get_current(); + if (current->type == WIN_CHAT) { char usage_cpy[strlen(usage) + 8]; sprintf(usage_cpy, "Usage: %s", usage); ui_current_print_line(usage_cpy); @@ -909,7 +895,7 @@ ui_gone_secure(const char * const barejid, gboolean trusted) } chatwin->enc_mode = PROF_ENC_OTR; - chatwin->is_trusted = trusted; + chatwin->otr_is_trusted = trusted; if (trusted) { win_print(window, '!', NULL, 0, THEME_OTR_STARTED_TRUSTED, "", "OTR session started (trusted)."); } else { @@ -937,7 +923,7 @@ ui_gone_insecure(const char * const barejid) ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin) { chatwin->enc_mode = PROF_ENC_NONE; - chatwin->is_trusted = FALSE; + chatwin->otr_is_trusted = FALSE; ProfWin *window = (ProfWin*)chatwin; win_print(window, '!', NULL, 0, THEME_OTR_ENDED, "", "OTR session ended."); @@ -1056,7 +1042,7 @@ ui_trust(const char * const barejid) ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin) { chatwin->enc_mode = PROF_ENC_OTR; - chatwin->is_trusted = TRUE; + chatwin->otr_is_trusted = TRUE; ProfWin *window = (ProfWin*)chatwin; win_print(window, '!', NULL, 0, THEME_OTR_TRUSTED, "", "OTR session trusted."); @@ -1072,7 +1058,7 @@ ui_untrust(const char * const barejid) ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin) { chatwin->enc_mode = PROF_ENC_OTR; - chatwin->is_trusted = FALSE; + chatwin->otr_is_trusted = FALSE; ProfWin *window = (ProfWin*)chatwin; win_print(window, '!', NULL, 0, THEME_OTR_UNTRUSTED, "", "OTR session untrusted."); @@ -1083,12 +1069,6 @@ ui_untrust(const char * const barejid) } void -ui_clear_current(void) -{ - wins_clear_current(); -} - -void ui_close_win(int index) { ProfWin *window = wins_get_by_num(index); @@ -1105,16 +1085,10 @@ ui_close_win(int index) status_bar_active(1); } -void +gboolean ui_tidy_wins(void) { - gboolean tidied = wins_tidy(); - - if (tidied) { - cons_show("Windows tidied."); - } else { - cons_show("No tidy needed."); - } + return wins_tidy(); } void @@ -1163,26 +1137,6 @@ ui_swap_wins(int source_win, int target_win) } win_type_t -ui_current_win_type(void) -{ - ProfWin *current = wins_get_current(); - return current->type; -} - -gboolean -ui_current_win_is_otr(void) -{ - ProfWin *current = wins_get_current(); - if (current->type == WIN_CHAT) { - ProfChatWin *chatwin = (ProfChatWin*)current; - assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); - return chatwin->enc_mode == PROF_ENC_OTR; - } else { - return FALSE; - } -} - -win_type_t ui_win_type(int index) { ProfWin *window = wins_get_by_num(index); @@ -1314,12 +1268,6 @@ ui_new_chat_win(const char * const barejid) ProfWin *window = wins_new_chat(barejid); ProfChatWin *chatwin = (ProfChatWin *)window; -#ifdef HAVE_LIBOTR - if (otr_is_secure(barejid)) { - chatwin->enc_mode = PROF_ENC_OTR; - } -#endif - if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { _win_show_history(chatwin, barejid); } @@ -1717,7 +1665,7 @@ ui_room_nick_change(const char * const roomjid, const char * const nick) void ui_room_history(const char * const roomjid, const char * const nick, - GTimeVal tv_stamp, const char * const message) + GDateTime *timestamp, const char * const message) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); if (window == NULL) { @@ -1736,7 +1684,7 @@ ui_room_history(const char * const roomjid, const char * const nick, g_string_append(line, message); } - win_print(window, '-', &tv_stamp, NO_COLOUR_DATE, 0, "", line->str); + win_print(window, '-', timestamp, NO_COLOUR_DATE, 0, "", line->str); g_string_free(line, TRUE); } } @@ -2229,6 +2177,12 @@ ui_clear_win_title(void) } void +ui_clear_win(ProfWin *window) +{ + win_clear(window); +} + +void ui_goodbye_title(void) { int result = system("/bin/echo -ne \"\033]0;Thanks for using Profanity\007\""); @@ -2854,11 +2808,9 @@ _win_show_history(ProfChatWin *chatwin, const char * const contact) char hh[3]; memcpy(hh, &line[0], 2); hh[2] = '\0'; int ihh = atoi(hh); char mm[3]; memcpy(mm, &line[3], 2); mm[2] = '\0'; int imm = atoi(mm); char ss[3]; memcpy(ss, &line[6], 2); ss[2] = '\0'; int iss = atoi(ss); - GDateTime *time = g_date_time_new_local(2000, 1, 1, ihh, imm, iss); - GTimeVal tv; - g_date_time_to_timeval(time, &tv); - win_print((ProfWin*)chatwin, '-', &tv, NO_COLOUR_DATE, 0, "", curr->data+11); - g_date_time_unref(time); + GDateTime *timestamp = g_date_time_new_local(2000, 1, 1, ihh, imm, iss); + win_print((ProfWin*)chatwin, '-', timestamp, NO_COLOUR_DATE, 0, "", curr->data+11); + g_date_time_unref(timestamp); // header } else { win_print((ProfWin*)chatwin, '-', NULL, 0, 0, "", curr->data); diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index caea8ea9..2c42a628 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -62,7 +62,8 @@ #include "ui/ui.h" #include "ui/statusbar.h" #include "ui/inputwin.h" -#include "ui/windows.h" +#include "ui/window.h" +#include "window_list.h" #include "event/ui_events.h" #include "xmpp/xmpp.h" @@ -245,15 +246,8 @@ inp_get_password(void) get_password = TRUE; while (!password) { password = inp_readline(); - ui_update(); - werase(inp_win); - wmove(inp_win, 0, 0); - pad_start = 0; - _inp_win_update_virtual(); - doupdate(); } get_password = FALSE; - status_bar_clear(); return password; } @@ -414,7 +408,8 @@ _inp_rl_getc(FILE *stream) { int ch = rl_getc(stream); if (_inp_printable(ch)) { - cmd_reset_autocomplete(); + ProfWin *window = wins_get_current(); + cmd_reset_autocomplete(window); } return ch; } @@ -422,7 +417,8 @@ _inp_rl_getc(FILE *stream) static int _inp_rl_clear_handler(int count, int key) { - ui_clear_current(); + ProfWin *win = wins_get_current(); + win_clear(win); return 0; } @@ -433,17 +429,21 @@ _inp_rl_tab_handler(int count, int key) return 0; } - if ((strncmp(rl_line_buffer, "/", 1) != 0) && (ui_current_win_type() == WIN_MUC)) { - char *result = muc_autocomplete(rl_line_buffer); + ProfWin *current = wins_get_current(); + if ((strncmp(rl_line_buffer, "/", 1) != 0) && (current->type == WIN_MUC)) { + char *result = muc_autocomplete(current, rl_line_buffer); if (result) { rl_replace_line(result, 0); rl_point = rl_end; + free(result); } } else if (strncmp(rl_line_buffer, "/", 1) == 0) { - char *result = cmd_autocomplete(rl_line_buffer); + ProfWin *window = wins_get_current(); + char *result = cmd_autocomplete(window, rl_line_buffer); if (result) { rl_replace_line(result, 0); rl_point = rl_end; + free(result); } } diff --git a/src/ui/notifier.c b/src/ui/notifier.c index 76290daf..12367190 100644 --- a/src/ui/notifier.c +++ b/src/ui/notifier.c @@ -48,7 +48,7 @@ #include "log.h" #include "muc.h" #include "ui/ui.h" -#include "ui/windows.h" +#include "window_list.h" #include "config/preferences.h" static void _notify(const char * const message, int timeout, const char * const category); diff --git a/src/ui/occupantswin.c b/src/ui/occupantswin.c index bba9d0b9..fe4a600c 100644 --- a/src/ui/occupantswin.c +++ b/src/ui/occupantswin.c @@ -36,7 +36,7 @@ #include "ui/ui.h" #include "ui/window.h" -#include "ui/windows.h" +#include "window_list.h" #include "config/preferences.h" static void @@ -124,4 +124,4 @@ occupantswin_occupants(const char * const roomjid) g_list_free(occupants); } -} \ No newline at end of file +} diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c index 763490c3..00bc28a4 100644 --- a/src/ui/rosterwin.c +++ b/src/ui/rosterwin.c @@ -38,7 +38,7 @@ #include "contact.h" #include "ui/ui.h" #include "ui/window.h" -#include "ui/windows.h" +#include "window_list.h" #include "config/preferences.h" #include "roster_list.h" @@ -192,4 +192,4 @@ rosterwin_roster(void) } free(by); } -} \ No newline at end of file +} diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index f3d204f1..5541f648 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -140,6 +140,7 @@ status_bar_resize(void) } else { mvwprintw(status_bar, 0, 1, message); } + prefs_free_string(time_pref); } if (last_time) { g_date_time_unref(last_time); @@ -316,6 +317,7 @@ status_bar_print_message(const char * const msg) } else { mvwprintw(status_bar, 0, 1, message); } + prefs_free_string(time_pref); int cols = getmaxx(stdscr); int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET); @@ -455,6 +457,7 @@ _status_bar_draw(void) wattroff(status_bar, bracket_attrs); g_free(date_fmt); } + prefs_free_string(time_pref); _update_win_statuses(); wnoutrefresh(status_bar); diff --git a/src/ui/statusbar.h b/src/ui/statusbar.h index 7d2c5ea0..c37f43f3 100644 --- a/src/ui/statusbar.h +++ b/src/ui/statusbar.h @@ -42,10 +42,6 @@ void status_bar_clear(void); void status_bar_clear_message(void); void status_bar_get_password(void); void status_bar_print_message(const char * const msg); -void status_bar_inactive(const int win); -void status_bar_active(const int win); -void status_bar_new(const int win); -void status_bar_set_all_inactive(void); void status_bar_current(int i); -#endif \ No newline at end of file +#endif diff --git a/src/ui/titlebar.c b/src/ui/titlebar.c index 9bb84f9d..16a9eaff 100644 --- a/src/ui/titlebar.c +++ b/src/ui/titlebar.c @@ -44,7 +44,7 @@ #include "ui/ui.h" #include "ui/titlebar.h" #include "ui/inputwin.h" -#include "ui/windows.h" +#include "window_list.h" #include "ui/window.h" #include "roster_list.h" #include "chat_session.h" @@ -58,9 +58,7 @@ static GTimer *typing_elapsed; static void _title_bar_draw(void); static void _show_self_presence(void); static void _show_contact_presence(ProfChatWin *chatwin); -#ifdef HAVE_LIBOTR static void _show_privacy(ProfChatWin *chatwin); -#endif void create_title_bar(void) @@ -174,10 +172,7 @@ _title_bar_draw(void) ProfChatWin *chatwin = (ProfChatWin*) current; assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); _show_contact_presence(chatwin); - -#ifdef HAVE_LIBOTR _show_privacy(chatwin); -#endif if (typing) { wprintw(win, " (typing...)"); @@ -246,66 +241,81 @@ _show_self_presence(void) wattroff(win, bracket_attrs); } -#ifdef HAVE_LIBOTR static void _show_privacy(ProfChatWin *chatwin) { int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET); + int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED); + int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED); + int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED); + int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED); + + switch (chatwin->enc_mode) { + case PROF_ENC_NONE: + if (prefs_get_boolean(PREF_ENC_WARN)) { + wprintw(win, " "); + wattron(win, bracket_attrs); + wprintw(win, "["); + wattroff(win, bracket_attrs); + wattron(win, unencrypted_attrs); + wprintw(win, "unencrypted"); + wattroff(win, unencrypted_attrs); + wattron(win, bracket_attrs); + wprintw(win, "]"); + wattroff(win, bracket_attrs); + } + break; - if (chatwin->enc_mode == PROF_ENC_NONE) { - if (prefs_get_boolean(PREF_OTR_WARN)) { - int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED); + case PROF_ENC_OTR: wprintw(win, " "); wattron(win, bracket_attrs); wprintw(win, "["); wattroff(win, bracket_attrs); - wattron(win, unencrypted_attrs); - wprintw(win, "unencrypted"); - wattroff(win, unencrypted_attrs); + wattron(win, encrypted_attrs); + wprintw(win, "OTR"); + wattroff(win, encrypted_attrs); wattron(win, bracket_attrs); wprintw(win, "]"); wattroff(win, bracket_attrs); - } - } else { - int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED); - wprintw(win, " "); - wattron(win, bracket_attrs); - wprintw(win, "["); - wattroff(win, bracket_attrs); - wattron(win, encrypted_attrs); - wprintw(win, "OTR"); - wattroff(win, encrypted_attrs); - wattron(win, bracket_attrs); - wprintw(win, "]"); - wattroff(win, bracket_attrs); - if (chatwin->is_trusted) { - int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED); - wprintw(win, " "); - wattron(win, bracket_attrs); - wprintw(win, "["); - wattroff(win, bracket_attrs); - wattron(win, trusted_attrs); - wprintw(win, "trusted"); - wattroff(win, trusted_attrs); - wattron(win, bracket_attrs); - wprintw(win, "]"); - wattroff(win, bracket_attrs); - } else { - int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED); + if (chatwin->otr_is_trusted) { + wprintw(win, " "); + wattron(win, bracket_attrs); + wprintw(win, "["); + wattroff(win, bracket_attrs); + wattron(win, trusted_attrs); + wprintw(win, "trusted"); + wattroff(win, trusted_attrs); + wattron(win, bracket_attrs); + wprintw(win, "]"); + wattroff(win, bracket_attrs); + } else { + wprintw(win, " "); + wattron(win, bracket_attrs); + wprintw(win, "["); + wattroff(win, bracket_attrs); + wattron(win, untrusted_attrs); + wprintw(win, "untrusted"); + wattroff(win, untrusted_attrs); + wattron(win, bracket_attrs); + wprintw(win, "]"); + wattroff(win, bracket_attrs); + } + break; + + case PROF_ENC_PGP: wprintw(win, " "); wattron(win, bracket_attrs); wprintw(win, "["); wattroff(win, bracket_attrs); - wattron(win, untrusted_attrs); - wprintw(win, "untrusted"); - wattroff(win, untrusted_attrs); + wattron(win, encrypted_attrs); + wprintw(win, "PGP"); + wattroff(win, encrypted_attrs); wattron(win, bracket_attrs); wprintw(win, "]"); wattroff(win, bracket_attrs); - } + break; } } -#endif static void _show_contact_presence(ProfChatWin *chatwin) diff --git a/src/ui/ui.h b/src/ui/ui.h index 0ee21be4..7682f57b 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -35,21 +35,14 @@ #ifndef UI_UI_H #define UI_UI_H -#include "config.h" +#include "ui/win_types.h" +#include "muc.h" -#include <wchar.h> - -#include <glib.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif - -#include "contact.h" -#include "jid.h" -#include "ui/window.h" -#include "xmpp/xmpp.h" +#define NO_ME 1 +#define NO_DATE 2 +#define NO_EOL 4 +#define NO_COLOUR_FROM 8 +#define NO_COLOUR_DATE 16 // ui startup and control void ui_init(void); @@ -93,12 +86,6 @@ int ui_close_all_wins(void); int ui_close_read_wins(void); // current window actions -void ui_clear_current(void); -win_type_t ui_current_win_type(void); -gboolean ui_current_win_is_otr(void); - -ProfChatWin *ui_get_current_chat(void); - void ui_current_print_line(const char * const msg, ...); void ui_current_print_formatted_line(const char show_char, int attrs, const char * const msg, ...); void ui_current_error_line(const char * const msg); @@ -114,8 +101,8 @@ void ui_handle_stanza(const char * const msg); // ui events void ui_contact_online(char *barejid, Resource *resource, GDateTime *last_activity); void ui_contact_typing(const char * const barejid, const char * const resource); -void ui_incoming_msg(const char * const from, const char * const resource, const char * const message, GTimeVal *tv_stamp); -void ui_incoming_private_msg(const char * const fulljid, const char * const message, GTimeVal *tv_stamp); +void ui_incoming_msg(ProfChatWin *chatwin, const char * const resource, const char * const message, GDateTime *timestamp, gboolean win_created); +void ui_incoming_private_msg(const char * const fulljid, const char * const message, GDateTime *timestamp); void ui_message_receipt(const char * const barejid, const char * const id); void ui_disconnected(void); @@ -142,7 +129,7 @@ void ui_room_occupant_role_and_affiliation_change(const char * const roomjid, co const char * const affiliation, const char * const actor, const char * const reason); void ui_room_roster(const char * const roomjid, GList *occupants, const char * const presence); void ui_room_history(const char * const roomjid, const char * const nick, - GTimeVal tv_stamp, const char * const message); + GDateTime *timestamp, const char * const message); void ui_room_message(const char * const roomjid, const char * const nick, const char * const message); void ui_room_subject(const char * const roomjid, const char * const nick, const char * const subject); @@ -216,7 +203,7 @@ void ui_show_all_room_rosters(void); void ui_hide_all_room_rosters(void); gboolean ui_chat_win_exists(const char * const barejid); -void ui_tidy_wins(void); +gboolean ui_tidy_wins(void); void ui_prune_wins(void); gboolean ui_swap_wins(int source_win, int target_win); @@ -224,6 +211,7 @@ void ui_page_up(void); void ui_page_down(void); void ui_subwin_page_up(void); void ui_subwin_page_down(void); +void ui_clear_win(ProfWin *window); void ui_auto_away(void); void ui_end_auto_away(void); @@ -262,6 +250,7 @@ void cons_show_log_prefs(void); void cons_show_presence_prefs(void); void cons_show_connection_prefs(void); void cons_show_otr_prefs(void); +void cons_show_pgp_prefs(void); void cons_show_account(ProfAccount *account); void cons_debug(const char * const msg, ...); void cons_show_time(void); @@ -300,11 +289,13 @@ void cons_privileges_setting(void); void cons_beep_setting(void); void cons_flash_setting(void); void cons_splash_setting(void); +void cons_encwarn_setting(void); void cons_vercheck_setting(void); void cons_occupants_setting(void); void cons_roster_setting(void); void cons_presence_setting(void); void cons_wrap_setting(void); +void cons_winstidy_setting(void); void cons_time_setting(void); void cons_mouse_setting(void); void cons_statuses_setting(void); @@ -331,12 +322,43 @@ void cons_show_contact_online(PContact contact, Resource *resource, GDateTime *l void cons_show_contact_offline(PContact contact, char *resource, char *status); void cons_theme_colours(void); +// status bar +void status_bar_inactive(const int win); +void status_bar_active(const int win); +void status_bar_new(const int win); +void status_bar_set_all_inactive(void); + // roster window void rosterwin_roster(void); // occupants window void occupantswin_occupants(const char * const room); +// window interface +ProfWin* win_create_console(void); +ProfWin* win_create_xmlconsole(void); +ProfWin* win_create_chat(const char * const barejid); +ProfWin* win_create_muc(const char * const roomjid); +ProfWin* win_create_muc_config(const char * const title, DataForm *form); +ProfWin* win_create_private(const char * const fulljid); + +void win_update_virtual(ProfWin *window); +void win_free(ProfWin *window); +int win_unread(ProfWin *window); +void win_resize(ProfWin *window); +void win_hide_subwin(ProfWin *window); +void win_show_subwin(ProfWin *window); +void win_refresh_without_subwin(ProfWin *window); +void win_refresh_with_subwin(ProfWin *window); +void win_print(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message); +void win_vprint(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message, ...); +char* win_get_title(ProfWin *window); +void win_show_occupant(ProfWin *window, Occupant *occupant); +void win_show_occupant_info(ProfWin *window, const char * const room, Occupant *occupant); +void win_show_contact(ProfWin *window, PContact contact); +void win_show_info(ProfWin *window, PContact contact); +void win_println(ProfWin *window, const char * const message); + // desktop notifier actions void notifier_initialise(void); void notifier_uninit(void); diff --git a/src/ui/win_types.h b/src/ui/win_types.h new file mode 100644 index 00000000..3214fa94 --- /dev/null +++ b/src/ui/win_types.h @@ -0,0 +1,146 @@ +/* + * win_types.h + * + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#ifndef UI_WIN_TYPES_H +#define UI_WIN_TYPES_H + +#include "config.h" + +#include <wchar.h> +#include <glib.h> +#ifdef HAVE_NCURSESW_NCURSES_H +#include <ncursesw/ncurses.h> +#elif HAVE_NCURSES_H +#include <ncurses.h> +#endif + +#include "xmpp/xmpp.h" +#include "ui/buffer.h" +#include "chat_state.h" + +#define LAYOUT_SPLIT_MEMCHECK 12345671 +#define PROFCHATWIN_MEMCHECK 22374522 +#define PROFMUCWIN_MEMCHECK 52345276 +#define PROFPRIVATEWIN_MEMCHECK 77437483 +#define PROFCONFWIN_MEMCHECK 64334685 +#define PROFXMLWIN_MEMCHECK 87333463 + +typedef enum { + LAYOUT_SIMPLE, + LAYOUT_SPLIT +} layout_type_t; + +typedef struct prof_layout_t { + layout_type_t type; + WINDOW *win; + ProfBuff buffer; + int y_pos; + int paged; +} ProfLayout; + +typedef struct prof_layout_simple_t { + ProfLayout base; +} ProfLayoutSimple; + +typedef struct prof_layout_split_t { + ProfLayout base; + WINDOW *subwin; + int sub_y_pos; + unsigned long memcheck; +} ProfLayoutSplit; + +typedef enum { + WIN_CONSOLE, + WIN_CHAT, + WIN_MUC, + WIN_MUC_CONFIG, + WIN_PRIVATE, + WIN_XML +} win_type_t; + +typedef enum { + PROF_ENC_NONE, + PROF_ENC_OTR, + PROF_ENC_PGP +} prof_enc_t; + +typedef struct prof_win_t { + win_type_t type; + ProfLayout *layout; +} ProfWin; + +typedef struct prof_console_win_t { + ProfWin window; +} ProfConsoleWin; + +typedef struct prof_chat_win_t { + ProfWin window; + char *barejid; + int unread; + ChatState *state; + prof_enc_t enc_mode; + gboolean otr_is_trusted; + char *resource_override; + gboolean history_shown; + unsigned long memcheck; +} ProfChatWin; + +typedef struct prof_muc_win_t { + ProfWin window; + char *roomjid; + int unread; + gboolean showjid; + unsigned long memcheck; +} ProfMucWin; + +typedef struct prof_mucconf_win_t { + ProfWin window; + char *roomjid; + DataForm *form; + unsigned long memcheck; +} ProfMucConfWin; + +typedef struct prof_private_win_t { + ProfWin window; + char *fulljid; + int unread; + unsigned long memcheck; +} ProfPrivateWin; + +typedef struct prof_xml_win_t { + ProfWin window; + unsigned long memcheck; +} ProfXMLWin; + +#endif diff --git a/src/ui/window.c b/src/ui/window.c index 60b47659..c008e44d 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -136,7 +136,7 @@ win_create_chat(const char * const barejid) new_win->barejid = strdup(barejid); new_win->resource_override = NULL; new_win->enc_mode = PROF_ENC_NONE; - new_win->is_trusted = FALSE; + new_win->otr_is_trusted = FALSE; new_win->history_shown = FALSE; new_win->unread = 0; new_win->state = chat_state_new(); @@ -460,6 +460,46 @@ win_sub_page_up(ProfWin *window) } void +win_clear(ProfWin *window) +{ + werase(window->layout->win); + win_update_virtual(window); +} + +void +win_resize(ProfWin *window) +{ + int subwin_cols = 0; + int cols = getmaxx(stdscr); + + if (window->layout->type == LAYOUT_SPLIT) { + ProfLayoutSplit *layout = (ProfLayoutSplit*)window->layout; + if (layout->subwin) { + if (window->type == WIN_CONSOLE) { + subwin_cols = win_roster_cols(); + } else if (window->type == WIN_MUC) { + subwin_cols = win_occpuants_cols(); + } + wresize(layout->base.win, PAD_SIZE, cols - subwin_cols); + wresize(layout->subwin, PAD_SIZE, subwin_cols); + if (window->type == WIN_CONSOLE) { + rosterwin_roster(); + } else if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin *)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + occupantswin_occupants(mucwin->roomjid); + } + } else { + wresize(layout->base.win, PAD_SIZE, cols); + } + } else { + wresize(window->layout->win, PAD_SIZE, cols); + } + + win_redraw(window); +} + +void win_mouse(ProfWin *window, const wint_t ch, const int result) { int rows = getmaxy(stdscr); @@ -532,6 +572,37 @@ win_update_virtual(ProfWin *window) } void +win_refresh_without_subwin(ProfWin *window) +{ + int rows, cols; + getmaxyx(stdscr, rows, cols); + + if ((window->type == WIN_MUC) || (window->type == WIN_CONSOLE)) { + pnoutrefresh(window->layout->win, window->layout->y_pos, 0, 1, 0, rows-3, cols-1); + } +} + +void +win_refresh_with_subwin(ProfWin *window) +{ + int rows, cols; + getmaxyx(stdscr, rows, cols); + int subwin_cols = 0; + + if (window->type == WIN_MUC) { + ProfLayoutSplit *layout = (ProfLayoutSplit*)window->layout; + subwin_cols = win_occpuants_cols(); + pnoutrefresh(layout->base.win, layout->base.y_pos, 0, 1, 0, rows-3, (cols-subwin_cols)-1); + pnoutrefresh(layout->subwin, layout->sub_y_pos, 0, 1, (cols-subwin_cols), rows-3, cols-1); + } else if (window->type == WIN_CONSOLE) { + ProfLayoutSplit *layout = (ProfLayoutSplit*)window->layout; + subwin_cols = win_roster_cols(); + pnoutrefresh(layout->base.win, layout->base.y_pos, 0, 1, 0, rows-3, (cols-subwin_cols)-1); + pnoutrefresh(layout->subwin, layout->sub_y_pos, 0, 1, (cols-subwin_cols), rows-3, cols-1); + } +} + +void win_move_to_end(ProfWin *window) { window->layout->paged = 0; @@ -852,14 +923,14 @@ win_show_status_string(ProfWin *window, const char * const from, } void -win_print_incoming_message(ProfWin *window, GTimeVal *tv_stamp, +win_print_incoming_message(ProfWin *window, GDateTime *timestamp, const char * const from, const char * const message) { switch (window->type) { case WIN_CHAT: case WIN_PRIVATE: - win_print(window, '-', tv_stamp, NO_ME, THEME_TEXT_THEM, from, message); + win_print(window, '-', timestamp, NO_ME, THEME_TEXT_THEM, from, message); break; default: assert(FALSE); @@ -868,31 +939,25 @@ win_print_incoming_message(ProfWin *window, GTimeVal *tv_stamp, } void -win_vprint(ProfWin *window, const char show_char, GTimeVal *tstamp, +win_vprint(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message, ...) { va_list arg; va_start(arg, message); GString *fmt_msg = g_string_new(NULL); g_string_vprintf(fmt_msg, message, arg); - win_print(window, show_char, tstamp, flags, theme_item, from, fmt_msg->str); + win_print(window, show_char, timestamp, flags, theme_item, from, fmt_msg->str); g_string_free(fmt_msg, TRUE); } void -win_print(ProfWin *window, const char show_char, GTimeVal *tstamp, +win_print(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message) { - GDateTime *time; + if (timestamp == NULL) timestamp = g_date_time_new_now_local(); - if (tstamp == NULL) { - time = g_date_time_new_now_local(); - } else { - time = g_date_time_new_from_timeval_utc(tstamp); - } - - buffer_push(window->layout->buffer, show_char, time, flags, theme_item, from, message, NULL); - _win_print(window, show_char, time, flags, theme_item, from, message, NULL); + buffer_push(window->layout->buffer, show_char, timestamp, flags, theme_item, from, message, NULL); + _win_print(window, show_char, timestamp, flags, theme_item, from, message, NULL); // TODO: cross-reference.. this should be replaced by a real event-based system ui_input_nonblocking(TRUE); } @@ -954,17 +1019,17 @@ _win_print(ProfWin *window, const char show_char, GDateTime *time, int colour = theme_attrs(THEME_ME); size_t indent = 0; - if ((flags & NO_DATE) == 0) { - gchar *date_fmt = NULL; - char *time_pref = prefs_get_string(PREF_TIME); - date_fmt = g_date_time_format(time, time_pref); - free(time_pref); - assert(date_fmt != NULL); - - if(strlen(date_fmt) != 0){ - indent = 3 + strlen(date_fmt); - } + gchar *date_fmt = NULL; + char *time_pref = prefs_get_string(PREF_TIME); + date_fmt = g_date_time_format(time, time_pref); + free(time_pref); + assert(date_fmt != NULL); + if(strlen(date_fmt) != 0){ + indent = 3 + strlen(date_fmt); + } + + if ((flags & NO_DATE) == 0) { if (date_fmt && strlen(date_fmt)) { if ((flags & NO_COLOUR_DATE) == 0) { wattron(window->layout->win, theme_attrs(THEME_TIME)); diff --git a/src/ui/window.h b/src/ui/window.h index d5e57971..2728c66c 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -39,159 +39,42 @@ #include <wchar.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif - #include "contact.h" #include "muc.h" +#include "ui/ui.h" #include "ui/buffer.h" #include "xmpp/xmpp.h" #include "chat_state.h" -#define NO_ME 1 -#define NO_DATE 2 -#define NO_EOL 4 -#define NO_COLOUR_FROM 8 -#define NO_COLOUR_DATE 16 +#ifdef HAVE_NCURSESW_NCURSES_H +#include <ncursesw/ncurses.h> +#elif HAVE_NCURSES_H +#include <ncurses.h> +#endif #define PAD_SIZE 1000 -#define LAYOUT_SPLIT_MEMCHECK 12345671 -#define PROFCHATWIN_MEMCHECK 22374522 -#define PROFMUCWIN_MEMCHECK 52345276 -#define PROFPRIVATEWIN_MEMCHECK 77437483 -#define PROFCONFWIN_MEMCHECK 64334685 -#define PROFXMLWIN_MEMCHECK 87333463 - -typedef enum { - LAYOUT_SIMPLE, - LAYOUT_SPLIT -} layout_type_t; - -typedef struct prof_layout_t { - layout_type_t type; - WINDOW *win; - ProfBuff buffer; - int y_pos; - int paged; -} ProfLayout; - -typedef struct prof_layout_simple_t { - ProfLayout base; -} ProfLayoutSimple; - -typedef struct prof_layout_split_t { - ProfLayout base; - WINDOW *subwin; - int sub_y_pos; - unsigned long memcheck; -} ProfLayoutSplit; - -typedef enum { - WIN_CONSOLE, - WIN_CHAT, - WIN_MUC, - WIN_MUC_CONFIG, - WIN_PRIVATE, - WIN_XML -} win_type_t; - -typedef enum { - PROF_ENC_NONE, - PROF_ENC_OTR -} prof_enc_t; - -typedef struct prof_win_t { - win_type_t type; - ProfLayout *layout; -} ProfWin; - -typedef struct prof_console_win_t { - ProfWin window; -} ProfConsoleWin; - -typedef struct prof_chat_win_t { - ProfWin window; - char *barejid; - int unread; - ChatState *state; - prof_enc_t enc_mode; - gboolean is_trusted; - char *resource_override; - gboolean history_shown; - unsigned long memcheck; -} ProfChatWin; - -typedef struct prof_muc_win_t { - ProfWin window; - char *roomjid; - int unread; - gboolean showjid; - unsigned long memcheck; -} ProfMucWin; - -typedef struct prof_mucconf_win_t { - ProfWin window; - char *roomjid; - DataForm *form; - unsigned long memcheck; -} ProfMucConfWin; - -typedef struct prof_private_win_t { - ProfWin window; - char *fulljid; - int unread; - unsigned long memcheck; -} ProfPrivateWin; - -typedef struct prof_xml_win_t { - ProfWin window; - unsigned long memcheck; -} ProfXMLWin; - -ProfWin* win_create_console(void); -ProfWin* win_create_chat(const char * const barejid); -ProfWin* win_create_muc(const char * const roomjid); -ProfWin* win_create_muc_config(const char * const title, DataForm *form); -ProfWin* win_create_private(const char * const fulljid); -ProfWin* win_create_xmlconsole(void); - -char *win_get_title(ProfWin *window); - -void win_free(ProfWin *window); -void win_update_virtual(ProfWin *window); void win_move_to_end(ProfWin *window); -void win_show_contact(ProfWin *window, PContact contact); -void win_show_occupant(ProfWin *window, Occupant *occupant); void win_show_status_string(ProfWin *window, const char * const from, const char * const show, const char * const status, GDateTime *last_activity, const char * const pre, const char * const default_show); -void win_print_incoming_message(ProfWin *window, GTimeVal *tv_stamp, +void win_print_incoming_message(ProfWin *window, GDateTime *timestamp, const char * const from, const char * const message); -void win_show_info(ProfWin *window, PContact contact); -void win_show_occupant_info(ProfWin *window, const char * const room, Occupant *occupant); -void win_vprint(ProfWin *window, const char show_char, GTimeVal *tstamp, int flags, theme_item_t theme_item, const char * const from, const char * const message, ...); -void win_print(ProfWin *window, const char show_char, GTimeVal *tstamp, int flags, theme_item_t theme_item, const char * const from, const char * const message); void win_print_with_receipt(ProfWin *window, const char show_char, GTimeVal *tstamp, int flags, theme_item_t theme_item, const char * const from, const char * const message, char *id); -void win_println(ProfWin *window, const char * const message); void win_newline(ProfWin *window); void win_redraw(ProfWin *window); -void win_hide_subwin(ProfWin *window); -void win_show_subwin(ProfWin *window); int win_roster_cols(void); int win_occpuants_cols(void); void win_printline_nowrap(WINDOW *win, char *msg); void win_mouse(ProfWin *current, const wint_t ch, const int result); void win_mark_received(ProfWin *window, const char * const id); -int win_unread(ProfWin *window); gboolean win_has_active_subwin(ProfWin *window); +void win_clear(ProfWin *window); + void win_page_up(ProfWin *window); void win_page_down(ProfWin *window); void win_sub_page_down(ProfWin *window); diff --git a/src/ui/windows.c b/src/window_list.c index 2334efc8..2892cc53 100644 --- a/src/ui/windows.c +++ b/src/window_list.c @@ -1,5 +1,5 @@ /* - * windows.c + * window_list.c * * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * @@ -40,24 +40,16 @@ #include <glib.h> -#ifdef HAVE_NCURSESW_NCURSES_H -#include <ncursesw/ncurses.h> -#elif HAVE_NCURSES_H -#include <ncurses.h> -#endif - #include "common.h" #include "roster_list.h" #include "config/theme.h" #include "ui/ui.h" #include "ui/statusbar.h" -#include "ui/window.h" -#include "ui/windows.h" +#include "window_list.h" #include "event/ui_events.h" static GHashTable *windows; static int current; -static int max_cols; void wins_init(void) @@ -65,7 +57,6 @@ wins_init(void) windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)win_free); - max_cols = getmaxx(stdscr); ProfWin *console = win_create_console(); g_hash_table_insert(windows, GINT_TO_POINTER(1), console); @@ -176,74 +167,6 @@ wins_get_current(void) } } -ProfChatWin * -wins_get_current_chat(void) -{ - if (windows) { - ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(current)); - if (window) { - ProfChatWin *chatwin = (ProfChatWin*)window; - assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); - return chatwin; - } else { - return NULL; - } - } else { - return NULL; - } -} - -ProfMucWin * -wins_get_current_muc(void) -{ - if (windows) { - ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(current)); - if (window) { - ProfMucWin *mucwin = (ProfMucWin*)window; - assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); - return mucwin; - } else { - return NULL; - } - } else { - return NULL; - } -} - -ProfPrivateWin * -wins_get_current_private(void) -{ - if (windows) { - ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(current)); - if (window) { - ProfPrivateWin *privatewin = (ProfPrivateWin*)window; - assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK); - return privatewin; - } else { - return NULL; - } - } else { - return NULL; - } -} - -ProfMucConfWin * -wins_get_current_muc_conf(void) -{ - if (windows) { - ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(current)); - if (window) { - ProfMucConfWin *confwin = (ProfMucConfWin*)window; - assert(confwin->memcheck == PROFCONFWIN_MEMCHECK); - return confwin; - } else { - return NULL; - } - } else { - return NULL; - } -} - GList * wins_get_nums(void) { @@ -386,14 +309,6 @@ wins_close_by_num(int i) } } -void -wins_clear_current(void) -{ - ProfWin *window = wins_get_current(); - werase(window->layout->win); - win_update_virtual(window); -} - gboolean wins_is_current(ProfWin *window) { @@ -480,39 +395,11 @@ wins_get_total_unread(void) void wins_resize_all(void) { - int cols = getmaxx(stdscr); - GList *values = g_hash_table_get_values(windows); GList *curr = values; while (curr) { ProfWin *window = curr->data; - int subwin_cols = 0; - - if (window->layout->type == LAYOUT_SPLIT) { - ProfLayoutSplit *layout = (ProfLayoutSplit*)window->layout; - if (layout->subwin) { - if (window->type == WIN_CONSOLE) { - subwin_cols = win_roster_cols(); - } else if (window->type == WIN_MUC) { - subwin_cols = win_occpuants_cols(); - } - wresize(layout->base.win, PAD_SIZE, cols - subwin_cols); - wresize(layout->subwin, PAD_SIZE, subwin_cols); - if (window->type == WIN_CONSOLE) { - rosterwin_roster(); - } else if (window->type == WIN_MUC) { - ProfMucWin *mucwin = (ProfMucWin *)window; - assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); - occupantswin_occupants(mucwin->roomjid); - } - } else { - wresize(layout->base.win, PAD_SIZE, cols); - } - } else { - wresize(window->layout->win, PAD_SIZE, cols); - } - - win_redraw(window); + win_resize(window); curr = g_list_next(curr); } g_list_free(values); @@ -524,38 +411,19 @@ wins_resize_all(void) void wins_hide_subwin(ProfWin *window) { - int rows, cols; - getmaxyx(stdscr, rows, cols); - win_hide_subwin(window); ProfWin *current_win = wins_get_current(); - if ((current_win->type == WIN_MUC) || (current_win->type == WIN_CONSOLE)) { - pnoutrefresh(current_win->layout->win, current_win->layout->y_pos, 0, 1, 0, rows-3, cols-1); - } + win_refresh_without_subwin(current_win); } void wins_show_subwin(ProfWin *window) { - int rows, cols; - getmaxyx(stdscr, rows, cols); - int subwin_cols = 0; - win_show_subwin(window); ProfWin *current_win = wins_get_current(); - if (current_win->type == WIN_MUC) { - ProfLayoutSplit *layout = (ProfLayoutSplit*)current_win->layout; - subwin_cols = win_occpuants_cols(); - pnoutrefresh(layout->base.win, layout->base.y_pos, 0, 1, 0, rows-3, (cols-subwin_cols)-1); - pnoutrefresh(layout->subwin, layout->sub_y_pos, 0, 1, (cols-subwin_cols), rows-3, cols-1); - } else if (current_win->type == WIN_CONSOLE) { - ProfLayoutSplit *layout = (ProfLayoutSplit*)current_win->layout; - subwin_cols = win_roster_cols(); - pnoutrefresh(layout->base.win, layout->base.y_pos, 0, 1, 0, rows-3, (cols-subwin_cols)-1); - pnoutrefresh(layout->subwin, layout->sub_y_pos, 0, 1, (cols-subwin_cols), rows-3, cols-1); - } + win_refresh_with_subwin(current_win); } ProfXMLWin * diff --git a/src/ui/windows.h b/src/window_list.h index 97183d51..74073bd6 100644 --- a/src/ui/windows.h +++ b/src/window_list.h @@ -1,5 +1,5 @@ /* - * windows.h + * window_list.h * * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * @@ -32,8 +32,10 @@ * */ -#ifndef UI_WINDOWS_H -#define UI_WINDOWS_H +#ifndef WINDOW_LIST_H +#define WINDOW_LIST_H + +#include "ui/ui.h" void wins_init(void); @@ -51,10 +53,6 @@ ProfPrivateWin *wins_get_private(const char * const fulljid); ProfXMLWin * wins_get_xmlconsole(void); ProfWin * wins_get_current(void); -ProfChatWin * wins_get_current_chat(void); -ProfMucWin * wins_get_current_muc(void); -ProfPrivateWin * wins_get_current_private(void); -ProfMucConfWin * wins_get_current_muc_conf(void); void wins_set_current_by_num(int i); @@ -66,7 +64,6 @@ int wins_get_num(ProfWin *window); int wins_get_current_num(void); void wins_close_current(void); void wins_close_by_num(int i); -void wins_clear_current(void); gboolean wins_is_current(ProfWin *window); int wins_get_total_unread(void); void wins_resize_all(void); diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 70d49b7c..3c9ba214 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -194,7 +194,7 @@ jabber_disconnect(void) xmpp_disconnect(jabber_conn.conn); while (jabber_get_connection_status() == JABBER_DISCONNECTING) { - jabber_process_events(); + jabber_process_events(10); } _connection_free_saved_account(); _connection_free_saved_details(); @@ -222,10 +222,11 @@ jabber_shutdown(void) _connection_free_session_data(); xmpp_shutdown(); free(jabber_conn.log); + jabber_conn.log = NULL; } void -jabber_process_events(void) +jabber_process_events(int millis) { int reconnect_sec; @@ -234,7 +235,7 @@ jabber_process_events(void) case JABBER_CONNECTED: case JABBER_CONNECTING: case JABBER_DISCONNECTING: - xmpp_run_once(jabber_conn.ctx, 10); + xmpp_run_once(jabber_conn.ctx, millis); break; case JABBER_DISCONNECTED: reconnect_sec = prefs_get_reconnect(); @@ -365,6 +366,7 @@ _jabber_connect(const char * const fulljid, const char * const passwd, } else if (jid->fulljid == NULL) { log_error("Full JID required to connect, received: %s", fulljid); jabber_conn.conn_status = JABBER_DISCONNECTED; + jid_destroy(jid); return jabber_conn.conn_status; } @@ -577,4 +579,4 @@ _xmpp_get_file_logger() file_log->userdata = &level; return file_log; -} \ No newline at end of file +} diff --git a/src/xmpp/message.c b/src/xmpp/message.c index bc702199..9aa278c1 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -50,6 +50,7 @@ #include "roster_list.h" #include "xmpp/stanza.h" #include "xmpp/xmpp.h" +#include "pgp/gpg.h" #define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_MESSAGE, type, ctx) @@ -76,37 +77,57 @@ message_add_handlers(void) HANDLE(STANZA_NS_RECEIPTS, NULL, _receipt_received_handler); } -char * -message_send_chat(const char * const barejid, const char * const msg) +static char* +_session_jid(const char * const barejid) { - xmpp_conn_t * const conn = connection_get_conn(); - xmpp_ctx_t * const ctx = connection_get_ctx(); - ChatSession *session = chat_session_get(barejid); - char *state = NULL; char *jid = NULL; if (session) { - if (prefs_get_boolean(PREF_STATES) && session->send_states) { - state = STANZA_NAME_ACTIVE; - } Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource); jid = strdup(jidp->fulljid); jid_destroy(jidp); + } else { + jid = strdup(barejid); + } + return jid; +} + +static char* +_session_state(const char * const barejid) +{ + ChatSession *session = chat_session_get(barejid); + char *state = NULL; + if (session) { + if (prefs_get_boolean(PREF_STATES) && session->send_states) { + state = STANZA_NAME_ACTIVE; + } } else { if (prefs_get_boolean(PREF_STATES)) { state = STANZA_NAME_ACTIVE; } - jid = strdup(barejid); } + return state; +} + +char * +message_send_chat(const char * const barejid, const char * const msg) +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + + char *state = _session_state(barejid); + char *jid = _session_jid(barejid); char *id = create_unique_id("msg"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg); free(jid); if (state) { stanza_attach_state(ctx, message, state); } + if (prefs_get_boolean(PREF_RECEIPTS_REQUEST)) { stanza_attach_receipt_request(ctx, message); } @@ -118,36 +139,81 @@ message_send_chat(const char * const barejid, const char * const msg) } char * -message_send_chat_encrypted(const char * const barejid, const char * const msg) +message_send_chat_pgp(const char * const barejid, const char * const msg) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - ChatSession *session = chat_session_get(barejid); - char *state = NULL; - char *jid = NULL; - if (session) { - if (prefs_get_boolean(PREF_STATES) && session->send_states) { - state = STANZA_NAME_ACTIVE; + char *state = _session_state(barejid); + char *jid = _session_jid(barejid); + char *id = create_unique_id("msg"); + + xmpp_stanza_t *message = NULL; +#ifdef HAVE_LIBGPGME + char *account_name = jabber_get_account_name(); + ProfAccount *account = accounts_get_account(account_name); + if (account->pgp_keyid) { + Jid *jidp = jid_create(jid); + char *encrypted = p_gpg_encrypt(jidp->barejid, msg); + if (encrypted) { + message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, "This message is encrypted."); + xmpp_stanza_t *x = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(x, STANZA_NAME_X); + xmpp_stanza_set_ns(x, STANZA_NS_ENCRYPTED); + xmpp_stanza_t *enc_st = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(enc_st, encrypted); + xmpp_stanza_add_child(x, enc_st); + xmpp_stanza_release(enc_st); + xmpp_stanza_add_child(message, x); + xmpp_stanza_release(x); + free(encrypted); + } else { + message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg); } - Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource); - jid = strdup(jidp->fulljid); jid_destroy(jidp); } else { - if (prefs_get_boolean(PREF_STATES)) { - state = STANZA_NAME_ACTIVE; - } - jid = strdup(barejid); + message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg); + } +#else + message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg); +#endif + free(jid); + + if (state) { + stanza_attach_state(ctx, message, state); + } + + stanza_attach_carbons_private(ctx, message); + + if (prefs_get_boolean(PREF_RECEIPTS_REQUEST)) { + stanza_attach_receipt_request(ctx, message); } + xmpp_send(conn, message); + xmpp_stanza_release(message); + + return id; +} + +char * +message_send_chat_otr(const char * const barejid, const char * const msg) +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + + char *state = _session_state(barejid); + char *jid = _session_jid(barejid); char *id = create_unique_id("msg"); + xmpp_stanza_t *message = stanza_create_message(ctx, id, barejid, STANZA_TYPE_CHAT, msg); free(jid); if (state) { stanza_attach_state(ctx, message, state); } + stanza_attach_carbons_private(ctx, message); + if (prefs_get_boolean(PREF_RECEIPTS_REQUEST)) { stanza_attach_receipt_request(ctx, message); } @@ -384,6 +450,7 @@ _conference_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void // XEP-0249 char *room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID); if (!room) { + jid_destroy(jidp); return 1; } @@ -492,10 +559,10 @@ _groupchat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void } // determine if the notifications happened whilst offline - GTimeVal tv_stamp; - gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - if (delayed) { - sv_ev_room_history(jid->barejid, jid->resourcepart, tv_stamp, message); + GDateTime *timestamp = stanza_get_delay(stanza); + if (timestamp) { + sv_ev_room_history(jid->barejid, jid->resourcepart, timestamp, message); + g_date_time_unref(timestamp); } else { sv_ev_room_message(jid->barejid, jid->resourcepart, message); } @@ -596,10 +663,10 @@ _private_chat_handler(xmpp_stanza_t * const stanza, const char * const fulljid) return; } - GTimeVal tv_stamp; - gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - if (delayed) { - sv_ev_delayed_private_message(fulljid, message, tv_stamp); + GDateTime *timestamp = stanza_get_delay(stanza); + if (timestamp) { + sv_ev_delayed_private_message(fulljid, message, timestamp); + g_date_time_unref(timestamp); } else { sv_ev_incoming_private_message(fulljid, message); } @@ -640,11 +707,11 @@ _handle_carbons(xmpp_stanza_t * const stanza) if (message) { // if we are the recipient, treat as standard incoming message if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){ - sv_ev_incoming_message(jid_from->barejid, jid_from->resourcepart, message); + sv_ev_incoming_carbon(jid_from->barejid, jid_from->resourcepart, message); } // else treat as a sent message else{ - sv_ev_carbon(jid_to->barejid, message); + sv_ev_outgoing_carbon(jid_to->barejid, message); } xmpp_free(ctx, message); } @@ -689,21 +756,25 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * con // private message from chat room use full jid (room/nick) if (muc_active(jid->barejid)) { _private_chat_handler(stanza, jid->fulljid); + jid_destroy(jid); return 1; } // standard chat message, use jid without resource - GTimeVal tv_stamp; - gboolean delayed = stanza_get_delay(stanza, &tv_stamp); - + GDateTime *timestamp = stanza_get_delay(stanza); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); if (body) { char *message = xmpp_stanza_get_text(body); if (message) { - if (delayed) { - sv_ev_delayed_message(jid->barejid, message, tv_stamp); + if (timestamp) { + sv_ev_delayed_message(jid->barejid, message, timestamp); } else { - sv_ev_incoming_message(jid->barejid, jid->resourcepart, message); + char *enc_message = NULL; + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_ENCRYPTED); + if (x) { + enc_message = xmpp_stanza_get_text(x); + } + sv_ev_incoming_message(jid->barejid, jid->resourcepart, message, enc_message); } _receipt_request_handler(stanza); @@ -714,7 +785,7 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * con } // handle chat sessions and states - if (!delayed && jid->resourcepart) { + if (!timestamp && jid->resourcepart) { gboolean gone = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL; gboolean typing = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL; gboolean paused = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL; @@ -734,6 +805,7 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * con } } + if (timestamp) g_date_time_unref(timestamp); jid_destroy(jid); return 1; } diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index e46730e3..42215322 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -193,7 +193,7 @@ presence_reset_sub_request_search(void) } void -presence_send(const resource_presence_t presence_type, const char * const msg, const int idle) +presence_send(const resource_presence_t presence_type, const char * const msg, const int idle, char *signed_status) { if (jabber_get_connection_status() != JABBER_CONNECTED) { log_warning("Error setting presence, not connected."); @@ -218,7 +218,21 @@ presence_send(const resource_presence_t presence_type, const char * const msg, c char *id = create_unique_id("presence"); xmpp_stanza_set_id(presence, id); stanza_attach_show(ctx, presence, show); + stanza_attach_status(ctx, presence, msg); + + if (signed_status) { + xmpp_stanza_t *x = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(x, STANZA_NAME_X); + xmpp_stanza_set_ns(x, STANZA_NS_SIGNED); + xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(signed_text, signed_status); + xmpp_stanza_add_child(x, signed_text); + xmpp_stanza_release(signed_text); + xmpp_stanza_add_child(presence, x); + xmpp_stanza_release(x); + } + stanza_attach_priority(ctx, presence, pri); stanza_attach_last_activity(ctx, presence, idle); stanza_attach_caps(ctx, presence); @@ -603,7 +617,14 @@ _available_handler(xmpp_conn_t * const conn, if (g_strcmp0(xmpp_presence->jid->barejid, my_jid->barejid) == 0) { connection_add_available_resource(resource); } else { - sv_ev_contact_online(xmpp_presence->jid->barejid, resource, xmpp_presence->last_activity); + char *pgpsig = NULL; + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_SIGNED); + if (x) { + pgpsig = xmpp_stanza_get_text(x); + } + sv_ev_contact_online(xmpp_presence->jid->barejid, resource, xmpp_presence->last_activity, pgpsig); + xmpp_ctx_t *ctx = connection_get_ctx(); + xmpp_free(ctx, pgpsig); } jid_destroy(my_jid); @@ -649,6 +670,7 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * // invalid from attribute Jid *from_jid = jid_create(from); if (from_jid == NULL || from_jid->resourcepart == NULL) { + jid_destroy(from_jid); return 1; } @@ -783,4 +805,4 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * jid_destroy(from_jid); return 1; -} \ No newline at end of file +} diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 1f25239b..beb03f45 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -982,17 +982,21 @@ stanza_create_ping_iq(xmpp_ctx_t *ctx, const char * const target) return iq; } -gboolean -stanza_get_delay(xmpp_stanza_t * const stanza, GTimeVal *tv_stamp) +GDateTime* +stanza_get_delay(xmpp_stanza_t * const stanza) { + GTimeVal utc_stamp; // first check for XEP-0203 delayed delivery xmpp_stanza_t *delay = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_DELAY); if (delay) { char *xmlns = xmpp_stanza_get_attribute(delay, STANZA_ATTR_XMLNS); if (xmlns && (strcmp(xmlns, "urn:xmpp:delay") == 0)) { char *stamp = xmpp_stanza_get_attribute(delay, STANZA_ATTR_STAMP); - if (stamp && (g_time_val_from_iso8601(stamp, tv_stamp))) { - return TRUE; + if (stamp && (g_time_val_from_iso8601(stamp, &utc_stamp))) { + GDateTime *utc_datetime = g_date_time_new_from_timeval_utc(&utc_stamp); + GDateTime *local_datetime = g_date_time_to_local(utc_datetime); + g_date_time_unref(utc_datetime); + return local_datetime; } } } @@ -1004,13 +1008,16 @@ stanza_get_delay(xmpp_stanza_t * const stanza, GTimeVal *tv_stamp) char *xmlns = xmpp_stanza_get_attribute(x, STANZA_ATTR_XMLNS); if (xmlns && (strcmp(xmlns, "jabber:x:delay") == 0)) { char *stamp = xmpp_stanza_get_attribute(x, STANZA_ATTR_STAMP); - if (stamp && (g_time_val_from_iso8601(stamp, tv_stamp))) { - return TRUE; + if (stamp && (g_time_val_from_iso8601(stamp, &utc_stamp))) { + GDateTime *utc_datetime = g_date_time_new_from_timeval_utc(&utc_stamp); + GDateTime *local_datetime = g_date_time_to_local(utc_datetime); + g_date_time_unref(utc_datetime); + return local_datetime; } } } - return FALSE; + return NULL; } char * diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 89dbda57..2dd1a141 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -160,6 +160,8 @@ #define STANZA_NS_CARBONS "urn:xmpp:carbons:2" #define STANZA_NS_FORWARD "urn:xmpp:forward:0" #define STANZA_NS_RECEIPTS "urn:xmpp:receipts" +#define STANZA_NS_SIGNED "jabber:x:signed" +#define STANZA_NS_ENCRYPTED "jabber:x:encrypted" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -221,7 +223,7 @@ xmpp_stanza_t* stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char * const gboolean stanza_contains_chat_state(xmpp_stanza_t *stanza); -gboolean stanza_get_delay(xmpp_stanza_t * const stanza, GTimeVal *tv_stamp); +GDateTime* stanza_get_delay(xmpp_stanza_t * const stanza); gboolean stanza_is_muc_presence(xmpp_stanza_t * const stanza); gboolean stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 398c9f46..575f9ae1 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -136,7 +136,7 @@ jabber_conn_status_t jabber_connect_with_details(const char * const jid, jabber_conn_status_t jabber_connect_with_account(const ProfAccount * const account); void jabber_disconnect(void); void jabber_shutdown(void); -void jabber_process_events(void); +void jabber_process_events(int millis); const char * jabber_get_fulljid(void); const char * jabber_get_domain(void); jabber_conn_status_t jabber_get_connection_status(void); @@ -146,7 +146,8 @@ GList * jabber_get_available_resources(void); // message functions char* message_send_chat(const char * const barejid, const char * const msg); -char* message_send_chat_encrypted(const char * const barejid, const char * const msg); +char* message_send_chat_otr(const char * const barejid, const char * const msg); +char* message_send_chat_pgp(const char * const barejid, const char * const msg); void message_send_private(const char * const fulljid, const char * const msg); void message_send_groupchat(const char * const roomjid, const char * const msg); void message_send_groupchat_subject(const char * const roomjid, const char * const subject); @@ -168,8 +169,7 @@ char * presence_sub_request_find(const char * const search_str); void presence_join_room(char *room, char *nick, char * passwd); void presence_change_room_nick(const char * const room, const char * const nick); void presence_leave_chat_room(const char * const room_jid); -void presence_send(resource_presence_t status, const char * const msg, - int idle); +void presence_send(resource_presence_t status, const char * const msg, int idle, char *signed_status); gboolean presence_sub_request_exists(const char * const bare_jid); // iq functions diff --git a/tests/functionaltests/functionaltests.c b/tests/functionaltests/functionaltests.c new file mode 100644 index 00000000..fac7685c --- /dev/null +++ b/tests/functionaltests/functionaltests.c @@ -0,0 +1,119 @@ +#include <stdarg.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <sys/stat.h> + +#include "config.h" + +#include "proftest.h" +#include "test_connect.h" +#include "test_ping.h" +#include "test_rooms.h" +#include "test_presence.h" +#include "test_message.h" +#include "test_chat_session.h" + +int main(int argc, char* argv[]) { + + const UnitTest all_tests[] = { + + unit_test_setup_teardown(connect_jid_requests_roster, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(connect_jid_sends_presence_after_receiving_roster, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(connect_jid_requests_bookmarks, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(connect_bad_password, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(connect_shows_presence_updates, + init_prof_test, + close_prof_test), + + unit_test_setup_teardown(ping_multiple, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(ping_responds, + init_prof_test, + close_prof_test), + + unit_test_setup_teardown(rooms_query, + init_prof_test, + close_prof_test), + + unit_test_setup_teardown(presence_away, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_away_with_message, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_online, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_online_with_message, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_xa, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_xa_with_message, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_dnd, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_dnd_with_message, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_chat, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_chat_with_message, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_set_priority, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_includes_priority, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(presence_received, + init_prof_test, + close_prof_test), + + unit_test_setup_teardown(message_send, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(message_receive, + init_prof_test, + close_prof_test), + + unit_test_setup_teardown(sends_message_to_barejid_when_contact_offline, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(sends_message_to_barejid_when_contact_online, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(sends_message_to_fulljid_when_received_from_fulljid, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(sends_subsequent_messages_to_fulljid, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(resets_to_barejid_after_presence_received, + init_prof_test, + close_prof_test), + unit_test_setup_teardown(new_session_when_message_received_from_different_fulljid, + init_prof_test, + close_prof_test), + }; + + return run_tests(all_tests); +} diff --git a/tests/functionaltests/proftest.c b/tests/functionaltests/proftest.c new file mode 100644 index 00000000..613c2c7a --- /dev/null +++ b/tests/functionaltests/proftest.c @@ -0,0 +1,238 @@ +#include <sys/stat.h> +#include <glib.h> + +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> +#include <cmocka.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +char *config_orig; +char *data_orig; + +int fd = 0; + +gboolean +_create_dir(char *name) +{ + struct stat sb; + + if (stat(name, &sb) != 0) { + if (errno != ENOENT || mkdir(name, S_IRWXU) != 0) { + return FALSE; + } + } else { + if ((sb.st_mode & S_IFDIR) != S_IFDIR) { + return FALSE; + } + } + + return TRUE; +} + +gboolean +_mkdir_recursive(const char *dir) +{ + int i; + gboolean result = TRUE; + + for (i = 1; i <= strlen(dir); i++) { + if (dir[i] == '/' || dir[i] == '\0') { + gchar *next_dir = g_strndup(dir, i); + result = _create_dir(next_dir); + g_free(next_dir); + if (!result) { + break; + } + } + } + + return result; +} + +void +_create_config_dir(void) +{ + GString *profanity_dir = g_string_new(XDG_CONFIG_HOME); + g_string_append(profanity_dir, "/profanity"); + + if (!_mkdir_recursive(profanity_dir->str)) { + assert_true(FALSE); + } + + g_string_free(profanity_dir, TRUE); +} + +void +_create_data_dir(void) +{ + GString *profanity_dir = g_string_new(XDG_DATA_HOME); + g_string_append(profanity_dir, "/profanity"); + + if (!_mkdir_recursive(profanity_dir->str)) { + assert_true(FALSE); + } + + g_string_free(profanity_dir, TRUE); +} + +void +_create_chatlogs_dir(void) +{ + GString *chatlogs_dir = g_string_new(XDG_DATA_HOME); + g_string_append(chatlogs_dir, "/profanity/chatlogs"); + + if (!_mkdir_recursive(chatlogs_dir->str)) { + assert_true(FALSE); + } + + g_string_free(chatlogs_dir, TRUE); +} + +void +_create_logs_dir(void) +{ + GString *logs_dir = g_string_new(XDG_DATA_HOME); + g_string_append(logs_dir, "/profanity/logs"); + + if (!_mkdir_recursive(logs_dir->str)) { + assert_true(FALSE); + } + + g_string_free(logs_dir, TRUE); +} + +void +_cleanup_dirs(void) +{ + int res = system("rm -rf ./tests/functionaltests/files"); + if (res == -1) { + assert_true(FALSE); + } +} + +void +prof_start(void) +{ + // helper script sets terminal columns, avoids assertions failing + // based on the test runner terminal size + fd = exp_spawnl("sh", + "sh", + "-c", + "./tests/functionaltests/start_profanity.sh", + NULL); + FILE *fp = fdopen(fd, "r+"); + + assert_true(fp != NULL); + + setbuf(fp, (char *)0); +} + +void +init_prof_test(void **state) +{ + if (stbbr_start(STBBR_LOGDEBUG ,5230, 0) != 0) { + assert_true(FALSE); + return; + } + + config_orig = getenv("XDG_CONFIG_HOME"); + data_orig = getenv("XDG_DATA_HOME"); + + setenv("XDG_CONFIG_HOME", XDG_CONFIG_HOME, 1); + setenv("XDG_DATA_HOME", XDG_DATA_HOME, 1); + + _cleanup_dirs(); + + _create_config_dir(); + _create_data_dir(); + _create_chatlogs_dir(); + _create_logs_dir(); + + prof_start(); + assert_true(prof_output_exact("Profanity")); + + // set UI options to make expect assertions faster and more reliable + prof_input("/inpblock timeout 5"); + assert_true(prof_output_exact("Input blocking set to 5 milliseconds")); + prof_input("/inpblock dynamic off"); + assert_true(prof_output_exact("Dynamic input blocking disabled")); + prof_input("/notify message off"); + assert_true(prof_output_exact("Message notifications disabled")); + prof_input("/wrap off"); + assert_true(prof_output_exact("Word wrap disabled")); + prof_input("/roster hide"); + assert_true(prof_output_exact("Roster disabled")); + prof_input("/time off"); +} + +void +close_prof_test(void **state) +{ + prof_input("/quit"); + waitpid(exp_pid, NULL, 0); + _cleanup_dirs(); + + setenv("XDG_CONFIG_HOME", config_orig, 1); + setenv("XDG_DATA_HOME", data_orig, 1); + + stbbr_stop(); +} + +void +prof_input(char *input) +{ + GString *inp_str = g_string_new(input); + g_string_append(inp_str, "\r"); + write(fd, inp_str->str, inp_str->len); + g_string_free(inp_str, TRUE); +} + +int +prof_output_exact(char *text) +{ + return (1 == exp_expectl(fd, exp_exact, text, 1, exp_end)); +} + +int +prof_output_regex(char *text) +{ + return (1 == exp_expectl(fd, exp_regexp, text, 1, exp_end)); +} + +void +prof_connect(void) +{ + stbbr_for_query("jabber:iq:roster", + "<iq type=\"result\" to=\"stabber@localhost/profanity\">" + "<query xmlns=\"jabber:iq:roster\" ver=\"362\">" + "<item jid=\"buddy1@localhost\" subscription=\"both\" name=\"Buddy1\"/>" + "<item jid=\"buddy2@localhost\" subscription=\"both\" name=\"Buddy2\"/>" + "</query>" + "</iq>" + ); + stbbr_for_id("prof_presence_1", + "<presence id=\"prof_presence_1\" lang=\"en\" to=\"stabber@localhost/profanity\" from=\"stabber@localhost/profanity\">" + "<priority>0</priority>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" node=\"http://www.profanity.im\" ver=\"f8mrtdyAmhnj8Ca+630bThSL718=\"/>" + "</presence>" + ); + + prof_input("/connect stabber@localhost port 5230"); + prof_input("password"); + + // Allow time for profanity to connect + exp_timeout = 30; + assert_true(prof_output_regex("stabber@localhost logged in successfully, .+online.+ \\(priority 0\\)\\.")); + exp_timeout = 10; + stbbr_wait_for("prof_presence_1"); +} diff --git a/tests/functionaltests/proftest.h b/tests/functionaltests/proftest.h new file mode 100644 index 00000000..2283ab01 --- /dev/null +++ b/tests/functionaltests/proftest.h @@ -0,0 +1,17 @@ +#ifndef __H_PROFTEST +#define __H_PROFTEST + +#define XDG_CONFIG_HOME "./tests/functionaltests/files/xdg_config_home" +#define XDG_DATA_HOME "./tests/functionaltests/files/xdg_data_home" + +void init_prof_test(void **state); +void close_prof_test(void **state); + +void prof_start(void); +void prof_connect(void); +void prof_input(char *input); + +int prof_output_exact(char *text); +int prof_output_regex(char *text); + +#endif diff --git a/tests/functionaltests/start_profanity.sh b/tests/functionaltests/start_profanity.sh new file mode 100755 index 00000000..58ceadd7 --- /dev/null +++ b/tests/functionaltests/start_profanity.sh @@ -0,0 +1,2 @@ +export COLUMNS=300 +./profanity -l DEBUG diff --git a/tests/functionaltests/test_chat_session.c b/tests/functionaltests/test_chat_session.c new file mode 100644 index 00000000..d1229e90 --- /dev/null +++ b/tests/functionaltests/test_chat_session.c @@ -0,0 +1,207 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +sends_message_to_barejid_when_contact_offline(void **state) +{ + prof_connect(); + + prof_input("/msg buddy1@localhost Hi there"); + + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost\" type=\"chat\">" + "<body>Hi there</body>" + "</message>" + )); +} + +void +sends_message_to_barejid_when_contact_online(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost/profanity\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is online")); + + prof_input("/msg buddy1@localhost Hi there"); + + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost\" type=\"chat\">" + "<body>Hi there</body>" + "</message>" + )); +} + +void +sends_message_to_fulljid_when_received_from_fulljid(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is online")); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>First message</body>" + "</message>" + ); + assert_true(prof_output_exact("<< incoming from Buddy1/mobile (2)")); + + prof_input("/msg buddy1@localhost Hi there"); + + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Hi there</body>" + "</message>" + )); +} + +void +sends_subsequent_messages_to_fulljid(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is online")); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>First message</body>" + "</message>" + ); + assert_true(prof_output_exact("<< incoming from Buddy1/mobile (2)")); + + prof_input("/msg buddy1@localhost Outgoing 1"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Outgoing 1</body>" + "</message>" + )); + + prof_input("/msg buddy1@localhost Outgoing 2"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Outgoing 2</body>" + "</message>" + )); + + prof_input("/msg buddy1@localhost Outgoing 3"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Outgoing 3</body>" + "</message>" + )); +} + +void +resets_to_barejid_after_presence_received(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is online")); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>First message</body>" + "</message>" + ); + assert_true(prof_output_exact("<< incoming from Buddy1/mobile (2)")); + + prof_input("/msg buddy1@localhost Outgoing 1"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Outgoing 1</body>" + "</message>" + )); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/laptop\">" + "<priority>5</priority>" + "<show>dnd</show>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (laptop) is dnd")); + + prof_input("/msg buddy1@localhost Outgoing 2"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost\" type=\"chat\">" + "<body>Outgoing 2</body>" + "</message>" + )); +} + +void +new_session_when_message_received_from_different_fulljid(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is online")); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/laptop\">" + "<priority>8</priority>" + "<show>away</show>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (laptop) is away")); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>From first resource</body>" + "</message>" + ); + assert_true(prof_output_exact("<< incoming from Buddy1/mobile (2)")); + + prof_input("/msg buddy1@localhost Outgoing 1"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/mobile\" type=\"chat\">" + "<body>Outgoing 1</body>" + "</message>" + )); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"buddy1@localhost/laptop\" type=\"chat\">" + "<body>From second resource</body>" + "</message>" + ); + assert_true(prof_output_regex("Buddy1/laptop:.+From second resource")); + + prof_input("/msg buddy1@localhost Outgoing 2"); + assert_true(stbbr_received( + "<message id=\"*\" to=\"buddy1@localhost/laptop\" type=\"chat\">" + "<body>Outgoing 2</body>" + "</message>" + )); +} diff --git a/tests/functionaltests/test_chat_session.h b/tests/functionaltests/test_chat_session.h new file mode 100644 index 00000000..2ba75e05 --- /dev/null +++ b/tests/functionaltests/test_chat_session.h @@ -0,0 +1,7 @@ +void sends_message_to_barejid_when_contact_offline(void **state); +void sends_message_to_barejid_when_contact_online(void **state); +void sends_message_to_fulljid_when_received_from_fulljid(void **state); +void sends_subsequent_messages_to_fulljid(void **state); +void resets_to_barejid_after_presence_received(void **state); +void new_session_when_message_received_from_different_fulljid(void **state); + diff --git a/tests/functionaltests/test_connect.c b/tests/functionaltests/test_connect.c new file mode 100644 index 00000000..5fcb8a2f --- /dev/null +++ b/tests/functionaltests/test_connect.c @@ -0,0 +1,95 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +connect_jid_requests_roster(void **state) +{ + prof_connect(); + + assert_true(stbbr_received( + "<iq id=\"*\" type=\"get\"><query xmlns=\"jabber:iq:roster\"/></iq>" + )); +} + +void +connect_jid_sends_presence_after_receiving_roster(void **state) +{ + prof_connect(); + + assert_true(stbbr_received( + "<presence id=\"*\">" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); +} + +void +connect_jid_requests_bookmarks(void **state) +{ + prof_connect(); + + assert_true(stbbr_received( + "<iq id=\"*\" type=\"get\">" + "<query xmlns=\"jabber:iq:private\">" + "<storage xmlns=\"storage:bookmarks\"/>" + "</query>" + "</iq>" + )); +} + +void +connect_bad_password(void **state) +{ + prof_input("/connect stabber@localhost port 5230"); + prof_input("badpassword"); + + assert_true(prof_output_exact("Login failed.")); +} + +void +connect_shows_presence_updates(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<show>dnd</show>" + "<status>busy!</status>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is dnd, \"busy!\"")); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/laptop\">" + "<show>chat</show>" + "<status>Talk to me!</status>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (laptop) is chat, \"Talk to me!\"")); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy2@localhost/work\">" + "<show>away</show>" + "<status>Out of office</status>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy2 (work) is away, \"Out of office\"")); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<show>xa</show>" + "<status>Gone :(</status>" + "</presence>" + ); + assert_true(prof_output_exact("Buddy1 (mobile) is xa, \"Gone :(\"")); +} diff --git a/tests/functionaltests/test_connect.h b/tests/functionaltests/test_connect.h new file mode 100644 index 00000000..66010e25 --- /dev/null +++ b/tests/functionaltests/test_connect.h @@ -0,0 +1,6 @@ +void connect_jid_requests_roster(void **state); +void connect_jid_sends_presence_after_receiving_roster(void **state); +void connect_jid_requests_bookmarks(void **state); +void connect_bad_password(void **state); +void connect_shows_presence_updates(void **state); + diff --git a/tests/functionaltests/test_message.c b/tests/functionaltests/test_message.c new file mode 100644 index 00000000..0957b309 --- /dev/null +++ b/tests/functionaltests/test_message.c @@ -0,0 +1,42 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +message_send(void **state) +{ + prof_connect(); + + prof_input("/msg somejid@someserver.com Hi there"); + + assert_true(stbbr_received( + "<message id=\"*\" to=\"somejid@someserver.com\" type=\"chat\">" + "<body>Hi there</body>" + "</message>" + )); + + assert_true(prof_output_regex("me: .+Hi there")); +} + +void +message_receive(void **state) +{ + prof_connect(); + + stbbr_send( + "<message id=\"message1\" to=\"stabber@localhost\" from=\"someuser@chatserv.org/laptop\" type=\"chat\">" + "<body>How are you?</body>" + "</message>" + ); + + assert_true(prof_output_exact("<< incoming from someuser@chatserv.org/laptop (2)")); +} diff --git a/tests/functionaltests/test_message.h b/tests/functionaltests/test_message.h new file mode 100644 index 00000000..b8f03a7e --- /dev/null +++ b/tests/functionaltests/test_message.h @@ -0,0 +1,2 @@ +void message_send(void **state); +void message_receive(void **state); diff --git a/tests/functionaltests/test_ping.c b/tests/functionaltests/test_ping.c new file mode 100644 index 00000000..76fd979c --- /dev/null +++ b/tests/functionaltests/test_ping.c @@ -0,0 +1,57 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +ping_multiple(void **state) +{ + stbbr_for_id("prof_ping_2", + "<iq id=\"prof_ping_2\" type=\"result\" to=\"stabber@localhost/profanity\"/>" + ); + stbbr_for_id("prof_ping_3", + "<iq id=\"prof_ping_3\" type=\"result\" to=\"stabber@localhost/profanity\"/>" + ); + + prof_connect(); + + prof_input("/ping"); + assert_true(stbbr_received( + "<iq id=\"prof_ping_2\" type=\"get\">" + "<ping xmlns=\"urn:xmpp:ping\"/>" + "</iq>" + )); + assert_true(prof_output_exact("Ping response from server")); + + prof_input("/ping"); + assert_true(stbbr_received( + "<iq id=\"prof_ping_3\" type=\"get\">" + "<ping xmlns=\"urn:xmpp:ping\"/>" + "</iq>" + )); + assert_true(prof_output_exact("Ping response from server")); +} + +void +ping_responds(void **state) +{ + prof_connect(); + + stbbr_send( + "<iq id=\"pingtest1\" type=\"get\" to=\"stabber@localhost/profanity\" from=\"localhost\">" + "<ping xmlns=\"urn:xmpp:ping\"/>" + "</iq>" + ); + + assert_true(stbbr_received( + "<iq id=\"pingtest1\" type=\"result\" from=\"stabber@localhost/profanity\" to=\"localhost\"/>" + )); +} diff --git a/tests/functionaltests/test_ping.h b/tests/functionaltests/test_ping.h new file mode 100644 index 00000000..a222a486 --- /dev/null +++ b/tests/functionaltests/test_ping.h @@ -0,0 +1,2 @@ +void ping_multiple(void **state); +void ping_responds(void **state); diff --git a/tests/functionaltests/test_presence.c b/tests/functionaltests/test_presence.c new file mode 100644 index 00000000..cb2eacd3 --- /dev/null +++ b/tests/functionaltests/test_presence.c @@ -0,0 +1,243 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +presence_online(void **state) +{ + prof_connect(); + + prof_input("/online"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to online (priority 0)")); +} + +void +presence_online_with_message(void **state) +{ + prof_connect(); + + prof_input("/online \"Hi there\""); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<status>Hi there</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to online (priority 0), \"Hi there\".")); +} + +void +presence_away(void **state) +{ + prof_connect(); + + prof_input("/away"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>away</show>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to away (priority 0)")); +} + +void +presence_away_with_message(void **state) +{ + prof_connect(); + + prof_input("/away \"I'm not here for a bit\""); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>away</show>" + "<status>I'm not here for a bit</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to away (priority 0), \"I'm not here for a bit\".")); +} + +void +presence_xa(void **state) +{ + prof_connect(); + + prof_input("/xa"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>xa</show>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to xa (priority 0)")); +} + +void +presence_xa_with_message(void **state) +{ + prof_connect(); + + prof_input("/xa \"Gone to the shops\""); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>xa</show>" + "<status>Gone to the shops</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to xa (priority 0), \"Gone to the shops\".")); +} + +void +presence_dnd(void **state) +{ + prof_connect(); + + prof_input("/dnd"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>dnd</show>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to dnd (priority 0)")); +} + +void +presence_dnd_with_message(void **state) +{ + prof_connect(); + + prof_input("/dnd \"Working\""); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>dnd</show>" + "<status>Working</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to dnd (priority 0), \"Working\".")); +} + +void +presence_chat(void **state) +{ + prof_connect(); + + prof_input("/chat"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>chat</show>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to chat (priority 0)")); +} + +void +presence_chat_with_message(void **state) +{ + prof_connect(); + + prof_input("/chat \"Free to talk\""); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<show>chat</show>" + "<status>Free to talk</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Status set to chat (priority 0), \"Free to talk\".")); +} + +void +presence_set_priority(void **state) +{ + prof_connect(); + + prof_input("/priority 25"); + + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<priority>25</priority>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + + assert_true(prof_output_exact("Priority set to 25.")); +} + +void +presence_includes_priority(void **state) +{ + prof_connect(); + + prof_input("/priority 25"); + assert_true(stbbr_received( + "<presence id=\"prof_presence_2\">" + "<priority>25</priority>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + assert_true(prof_output_exact("Priority set to 25.")); + + prof_input("/chat \"Free to talk\""); + assert_true(stbbr_received( + "<presence id=\"prof_presence_3\">" + "<priority>25</priority>" + "<show>chat</show>" + "<status>Free to talk</status>" + "<c hash=\"sha-1\" xmlns=\"http://jabber.org/protocol/caps\" ver=\"*\" node=\"http://www.profanity.im\"/>" + "</presence>" + )); + assert_true(prof_output_exact("Status set to chat (priority 25), \"Free to talk\".")); +} + +void +presence_received(void **state) +{ + prof_connect(); + + stbbr_send( + "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">" + "<priority>10</priority>" + "<status>I'm here</status>" + "</presence>" + ); + + assert_true(prof_output_exact("Buddy1 (mobile) is online, \"I'm here\"")); +} diff --git a/tests/functionaltests/test_presence.h b/tests/functionaltests/test_presence.h new file mode 100644 index 00000000..0603732a --- /dev/null +++ b/tests/functionaltests/test_presence.h @@ -0,0 +1,13 @@ +void presence_away(void **state); +void presence_away_with_message(void **state); +void presence_online(void **state); +void presence_online_with_message(void **state); +void presence_xa(void **state); +void presence_xa_with_message(void **state); +void presence_dnd(void **state); +void presence_dnd_with_message(void **state); +void presence_chat(void **state); +void presence_chat_with_message(void **state); +void presence_set_priority(void **state); +void presence_includes_priority(void **state); +void presence_received(void **state); diff --git a/tests/functionaltests/test_rooms.c b/tests/functionaltests/test_rooms.c new file mode 100644 index 00000000..c81ded6b --- /dev/null +++ b/tests/functionaltests/test_rooms.c @@ -0,0 +1,38 @@ +#include <glib.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> + +#include <stabber.h> +#include <expect.h> + +#include "proftest.h" + +void +rooms_query(void **state) +{ + stbbr_for_id("confreq", + "<iq id=\"confreq\" type=\"result\" to=\"stabber@localhost/profanity\" from=\"conference.localhost\">" + "<query xmlns=\"http://jabber.org/protocol/disco#items\">" + "<item jid=\"chatroom@conference.localhost\" name=\"A chat room\"/>" + "<item jid=\"hangout@conference.localhost\" name=\"Another chat room\"/>" + "</query>" + "</iq>" + ); + + prof_connect(); + + prof_input("/rooms"); + + assert_true(prof_output_exact("chatroom@conference.localhost, (A chat room)")); + assert_true(prof_output_exact("hangout@conference.localhost, (Another chat room)")); + + assert_true(stbbr_last_received( + "<iq id=\"confreq\" to=\"conference.localhost\" type=\"get\">" + "<query xmlns=\"http://jabber.org/protocol/disco#items\"/>" + "</iq>" + )); +} diff --git a/tests/functionaltests/test_rooms.h b/tests/functionaltests/test_rooms.h new file mode 100644 index 00000000..a0cf5db8 --- /dev/null +++ b/tests/functionaltests/test_rooms.h @@ -0,0 +1,2 @@ +void rooms_query(void **state); + diff --git a/tests/config/stub_accounts.c b/tests/unittests/config/stub_accounts.c index 32a80fda..c046be86 100644 --- a/tests/config/stub_accounts.c +++ b/tests/unittests/config/stub_accounts.c @@ -122,6 +122,7 @@ void accounts_set_otr_policy(const char * const account_name, const char * const } void accounts_set_last_presence(const char * const account_name, const char * const value) {} +void accounts_set_pgp_keyid(const char * const account_name, const char * const value) {} void accounts_set_login_presence(const char * const account_name, const char * const value) { @@ -182,4 +183,5 @@ void accounts_clear_eval_password(const char * const account_name) {} void accounts_clear_server(const char * const account_name) {} void accounts_clear_port(const char * const account_name) {} void accounts_clear_otr(const char * const account_name) {} +void accounts_clear_pgp_keyid(const char * const account_name) {} void accounts_add_otr_policy(const char * const account_name, const char * const contact_jid, const char * const policy) {} diff --git a/tests/helpers.c b/tests/unittests/helpers.c index 564b2716..564b2716 100644 --- a/tests/helpers.c +++ b/tests/unittests/helpers.c diff --git a/tests/helpers.h b/tests/unittests/helpers.h index 75d446d0..75d446d0 100644 --- a/tests/helpers.h +++ b/tests/unittests/helpers.h diff --git a/tests/log/stub_log.c b/tests/unittests/log/stub_log.c index f88871a7..3baddb69 100644 --- a/tests/log/stub_log.c +++ b/tests/unittests/log/stub_log.c @@ -49,14 +49,20 @@ log_level_t log_level_from_string(char *log_level) return (log_level_t)mock(); } +void log_stderr_init(log_level_t level) {} +void log_stderr_close(void) {} +void log_stderr_handler(void) {} + void chat_log_init(void) {} void chat_log_msg_out(const char * const barejid, const char * const msg) {} void chat_log_otr_msg_out(const char * const barejid, const char * const msg) {} +void chat_log_pgp_msg_out(const char * const barejid, const char * const msg) {} void chat_log_msg_in(const char * const barejid, const char * const msg) {} -void chat_log_msg_in_delayed(const char * const barejid, const char * msg, GTimeVal *tv_stamp) {} +void chat_log_msg_in_delayed(const char * const barejid, const char * msg, GDateTime *timestamp) {} void chat_log_otr_msg_in(const char * const barejid, const char * const msg, gboolean was_decrypted) {} +void chat_log_pgp_msg_in(const char * const barejid, const char * const msg) {} void chat_log_close(void) {} GSList * chat_log_get_previous(const gchar * const login, diff --git a/tests/otr/stub_otr.c b/tests/unittests/otr/stub_otr.c index 482f0a7f..098484d5 100644 --- a/tests/otr/stub_otr.c +++ b/tests/unittests/otr/stub_otr.c @@ -41,8 +41,14 @@ char* otr_start_query(void) void otr_poll(void) {} void otr_on_connect(ProfAccount *account) {} -void otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message) {} -void otr_on_message_send(ProfChatWin *chatwin, const char * const message) {} +char* otr_on_message_recv(const char * const barejid, const char * const resource, const char * const message, gboolean *was_decrypted) +{ + return NULL; +} +gboolean otr_on_message_send(ProfChatWin *chatwin, const char * const message) +{ + return FALSE; +} void otr_keygen(ProfAccount *account) { diff --git a/tests/unittests/pgp/stub_gpg.c b/tests/unittests/pgp/stub_gpg.c new file mode 100644 index 00000000..671b2092 --- /dev/null +++ b/tests/unittests/pgp/stub_gpg.c @@ -0,0 +1,49 @@ +#include <glib.h> + +#include "pgp/gpg.h" + +void p_gpg_init(void) {} +void p_gpg_close(void) {} + +GSList* p_gpg_list_keys(void) +{ + return NULL; +} + +GHashTable* +p_gpg_fingerprints(void) +{ + return NULL; +} + +const char* p_gpg_libver(void) +{ + return NULL; +} + +void p_gpg_free_key(ProfPGPKey *key) {} + +void p_gpg_verify(const char * const barejid, const char *const sign) {} + +char* p_gpg_sign(const char * const str, const char * const fp) +{ + return NULL; +} + +gboolean p_gpg_available(const char * const barejid) +{ + return FALSE; +} +char * p_gpg_decrypt(const char * const barejid, const char * const cipher) +{ + return NULL; +} + +void p_gpg_on_connect(const char * const barejid) {} +void p_gpg_on_disconnect(void) {} + +gboolean p_gpg_addkey(const char * const jid, const char * const keyid) +{ + return TRUE; +} + diff --git a/tests/test_autocomplete.c b/tests/unittests/test_autocomplete.c index f6ef8653..f6ef8653 100644 --- a/tests/test_autocomplete.c +++ b/tests/unittests/test_autocomplete.c diff --git a/tests/test_autocomplete.h b/tests/unittests/test_autocomplete.h index 4ad327c0..4ad327c0 100644 --- a/tests/test_autocomplete.h +++ b/tests/unittests/test_autocomplete.h diff --git a/tests/test_chat_session.c b/tests/unittests/test_chat_session.c index b5e1f7b6..b5e1f7b6 100644 --- a/tests/test_chat_session.c +++ b/tests/unittests/test_chat_session.c diff --git a/tests/test_chat_session.h b/tests/unittests/test_chat_session.h index 4ce03fd5..4ce03fd5 100644 --- a/tests/test_chat_session.h +++ b/tests/unittests/test_chat_session.h diff --git a/tests/test_cmd_account.c b/tests/unittests/test_cmd_account.c index bddc4c6d..51213eb5 100644 --- a/tests/test_cmd_account.c +++ b/tests/unittests/test_cmd_account.c @@ -25,7 +25,7 @@ void cmd_account_shows_usage_when_not_connected_and_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -36,7 +36,7 @@ void cmd_account_shows_account_when_connected_and_no_args(void **state) { CommandHelp *help = malloc(sizeof(CommandHelp)); ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); gchar *args[] = { NULL }; will_return(jabber_get_connection_status, JABBER_CONNECTED); @@ -46,7 +46,7 @@ void cmd_account_shows_account_when_connected_and_no_args(void **state) expect_memory(cons_show_account, account, account, sizeof(ProfAccount)); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -67,7 +67,7 @@ void cmd_account_list_shows_accounts(void **state) expect_memory(cons_show_account_list, accounts, accounts, sizeof(accounts)); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -81,7 +81,7 @@ void cmd_account_show_shows_usage_when_no_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -98,7 +98,7 @@ void cmd_account_show_shows_message_when_account_does_not_exist(void **state) expect_cons_show("No such account."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -109,14 +109,14 @@ void cmd_account_show_shows_account_when_exists(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "show", "account_name", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expect_any(accounts_get_account, name); will_return(accounts_get_account, account); expect_memory(cons_show_account, account, account, sizeof(account)); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -130,7 +130,7 @@ void cmd_account_add_shows_usage_when_no_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -147,7 +147,7 @@ void cmd_account_add_adds_account(void **state) expect_cons_show("Account created."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -161,7 +161,7 @@ void cmd_account_enable_shows_usage_when_no_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -178,7 +178,7 @@ void cmd_account_enable_enables_account(void **state) expect_cons_show("Account enabled."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -195,7 +195,7 @@ void cmd_account_enable_shows_message_when_account_doesnt_exist(void **state) expect_cons_show("No such account: account_name"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -209,7 +209,7 @@ void cmd_account_disable_shows_usage_when_no_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -226,7 +226,7 @@ void cmd_account_disable_disables_account(void **state) expect_cons_show("Account disabled."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -243,7 +243,7 @@ void cmd_account_disable_shows_message_when_account_doesnt_exist(void **state) expect_cons_show("No such account: account_name"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -257,7 +257,7 @@ void cmd_account_rename_shows_usage_when_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -271,7 +271,7 @@ void cmd_account_rename_shows_usage_when_one_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -289,7 +289,7 @@ void cmd_account_rename_renames_account(void **state) expect_cons_show("Account renamed."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -307,7 +307,7 @@ void cmd_account_rename_shows_message_when_not_renamed(void **state) expect_cons_show("Either account original_name doesn't exist, or account new_name already exists."); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -321,7 +321,7 @@ void cmd_account_set_shows_usage_when_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -335,7 +335,7 @@ void cmd_account_set_shows_usage_when_one_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -349,7 +349,7 @@ void cmd_account_set_shows_usage_when_two_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -366,7 +366,7 @@ void cmd_account_set_shows_message_when_account_doesnt_exist(void **state) expect_cons_show("Account a_account doesn't exist"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -382,7 +382,7 @@ void cmd_account_set_jid_shows_message_for_malformed_jid(void **state) expect_cons_show("Malformed jid: @malformed"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -402,7 +402,7 @@ void cmd_account_set_jid_sets_barejid(void **state) expect_cons_show("Updated jid for account a_account: a_local@a_domain"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -427,7 +427,7 @@ void cmd_account_set_jid_sets_resource(void **state) expect_cons_show("Updated resource for account a_account: a_resource"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -447,7 +447,7 @@ void cmd_account_set_server_sets_server(void **state) expect_cons_show("Updated server for account a_account: a_server"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -458,6 +458,8 @@ void cmd_account_set_resource_sets_resource(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "resource", "a_resource", NULL }; + will_return(jabber_get_connection_status, JABBER_DISCONNECTED); + expect_any(accounts_account_exists, account_name); will_return(accounts_account_exists, TRUE); @@ -467,7 +469,29 @@ void cmd_account_set_resource_sets_resource(void **state) expect_cons_show("Updated resource for account a_account: a_resource"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); + assert_true(result); + + free(help); +} + +void cmd_account_set_resource_sets_resource_with_online_message(void **state) +{ + CommandHelp *help = malloc(sizeof(CommandHelp)); + gchar *args[] = { "set", "a_account", "resource", "a_resource", NULL }; + + will_return(jabber_get_connection_status, JABBER_CONNECTED); + + expect_any(accounts_account_exists, account_name); + will_return(accounts_account_exists, TRUE); + + expect_string(accounts_set_resource, account_name, "a_account"); + expect_string(accounts_set_resource, value, "a_resource"); + + expect_cons_show("Updated resource for account a_account: a_resource, you will need to reconnect to pick up the change."); + expect_cons_show(""); + + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -478,7 +502,7 @@ void cmd_account_set_password_sets_password(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "password", "a_password", NULL }; ProfAccount *account = account_new("a_account", NULL, NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expect_any(accounts_account_exists, account_name); @@ -493,7 +517,7 @@ void cmd_account_set_password_sets_password(void **state) expect_cons_show("Updated password for account a_account"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -504,7 +528,7 @@ void cmd_account_set_eval_password_sets_eval_password(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "eval_password", "a_password", NULL }; ProfAccount *account = account_new("a_account", NULL, NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expect_any(accounts_account_exists, account_name); @@ -519,7 +543,7 @@ void cmd_account_set_eval_password_sets_eval_password(void **state) expect_cons_show("Updated eval_password for account a_account"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -529,7 +553,7 @@ void cmd_account_set_password_when_eval_password_set(void **state) { CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "password", "a_password", NULL }; ProfAccount *account = account_new("a_account", NULL, NULL, "a_password", - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expect_any(accounts_account_exists, account_name); @@ -540,7 +564,7 @@ void cmd_account_set_password_when_eval_password_set(void **state) { expect_cons_show("Cannot set password when eval_password is set."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -550,7 +574,7 @@ void cmd_account_set_eval_password_when_password_set(void **state) { CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "eval_password", "a_password", NULL }; ProfAccount *account = account_new("a_account", NULL, "a_password", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expect_any(accounts_account_exists, account_name); @@ -561,7 +585,7 @@ void cmd_account_set_eval_password_when_password_set(void **state) { expect_cons_show("Cannot set eval_password when password is set."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -581,7 +605,7 @@ void cmd_account_set_muc_sets_muc(void **state) expect_cons_show("Updated muc service for account a_account: a_muc"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -601,7 +625,7 @@ void cmd_account_set_nick_sets_nick(void **state) expect_cons_show("Updated muc nick for account a_account: a_nick"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -615,7 +639,7 @@ void cmd_account_show_message_for_missing_otr_policy(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -631,7 +655,7 @@ void cmd_account_show_message_for_invalid_otr_policy(void **state) expect_cons_show("OTR policy must be one of: manual, opportunistic or always."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -651,7 +675,7 @@ void cmd_account_set_otr_sets_otr(void **state) expect_cons_show("Updated OTR policy for account a_account: opportunistic"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -668,7 +692,7 @@ void cmd_account_set_status_shows_message_when_invalid_status(void **state) expect_cons_show("Invalid status: bad_status"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -688,7 +712,7 @@ void cmd_account_set_status_sets_status_when_valid(void **state) expect_cons_show("Updated login status for account a_account: away"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -708,7 +732,7 @@ void cmd_account_set_status_sets_status_when_last(void **state) expect_cons_show("Updated login status for account a_account: last"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -725,7 +749,7 @@ void cmd_account_set_invalid_presence_string_priority_shows_message(void **state expect_cons_show("Invalid property: blah"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -742,7 +766,7 @@ void cmd_account_set_last_priority_shows_message(void **state) expect_cons_show("Invalid property: last"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -764,7 +788,7 @@ void cmd_account_set_online_priority_sets_preference(void **state) expect_cons_show("Updated online priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -786,7 +810,7 @@ void cmd_account_set_chat_priority_sets_preference(void **state) expect_cons_show("Updated chat priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -808,7 +832,7 @@ void cmd_account_set_away_priority_sets_preference(void **state) expect_cons_show("Updated away priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -830,7 +854,7 @@ void cmd_account_set_xa_priority_sets_preference(void **state) expect_cons_show("Updated xa priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -852,7 +876,7 @@ void cmd_account_set_dnd_priority_sets_preference(void **state) expect_cons_show("Updated dnd priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -868,7 +892,7 @@ void cmd_account_set_priority_too_low_shows_message(void **state) expect_cons_show("Value -150 out of range. Must be in -128..127."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -884,7 +908,7 @@ void cmd_account_set_priority_too_high_shows_message(void **state) expect_cons_show("Value 150 out of range. Must be in -128..127."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -900,7 +924,7 @@ void cmd_account_set_priority_when_not_number_shows_message(void **state) expect_cons_show("Could not convert \"abc\" to a number."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -916,7 +940,7 @@ void cmd_account_set_priority_when_empty_shows_message(void **state) expect_cons_show("Could not convert \"\" to a number."); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -927,6 +951,7 @@ void cmd_account_set_priority_updates_presence_when_account_connected_with_prese CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "set", "a_account", "online", "10", NULL }; + expect_any(accounts_account_exists, account_name); will_return(accounts_account_exists, TRUE); @@ -934,21 +959,32 @@ void cmd_account_set_priority_updates_presence_when_account_connected_with_prese expect_any(accounts_set_priority_online, value); will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(jabber_get_account_name, "a_account"); expect_any(accounts_get_last_presence, account_name); will_return(accounts_get_last_presence, RESOURCE_ONLINE); + will_return(jabber_get_account_name, "a_account"); + +#ifdef HAVE_LIBGPGME + ProfAccount *account = account_new("a_account", "a_jid", NULL, NULL, TRUE, NULL, 5222, "a_resource", + NULL, NULL, 10, 10, 10, 10, 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + will_return(jabber_get_account_name, "a_account"); + expect_any(accounts_get_account, name); + will_return(accounts_get_account, account); +#endif + will_return(jabber_get_presence_message, "Free to chat"); expect_value(presence_send, status, RESOURCE_ONLINE); expect_string(presence_send, msg, "Free to chat"); expect_value(presence_send, idle, 0); + expect_value(presence_send, signed_status, NULL); expect_cons_show("Updated online priority for account a_account: 10"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -962,7 +998,7 @@ void cmd_account_clear_shows_usage_when_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -976,7 +1012,7 @@ void cmd_account_clear_shows_usage_when_one_arg(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -993,7 +1029,7 @@ void cmd_account_clear_shows_message_when_account_doesnt_exist(void **state) expect_cons_show("Account a_account doesn't exist"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); @@ -1010,7 +1046,7 @@ void cmd_account_clear_shows_message_when_invalid_property(void **state) expect_cons_show("Invalid property: badproperty"); expect_cons_show(""); - gboolean result = cmd_account(args, *help); + gboolean result = cmd_account(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_account.h b/tests/unittests/test_cmd_account.h index 91bd1e70..e8806c4f 100644 --- a/tests/test_cmd_account.h +++ b/tests/unittests/test_cmd_account.h @@ -25,6 +25,7 @@ void cmd_account_set_jid_sets_barejid(void **state); void cmd_account_set_jid_sets_resource(void **state); void cmd_account_set_server_sets_server(void **state); void cmd_account_set_resource_sets_resource(void **state); +void cmd_account_set_resource_sets_resource_with_online_message(void **state); void cmd_account_set_password_sets_password(void **state); void cmd_account_set_eval_password_sets_eval_password(void **state); void cmd_account_set_password_when_eval_password_set(void **state); diff --git a/tests/test_cmd_alias.c b/tests/unittests/test_cmd_alias.c index 10ab7f53..37513f8d 100644 --- a/tests/test_cmd_alias.c +++ b/tests/unittests/test_cmd_alias.c @@ -24,7 +24,7 @@ void cmd_alias_add_shows_usage_when_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -38,7 +38,7 @@ void cmd_alias_add_shows_usage_when_no_value(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -52,7 +52,7 @@ void cmd_alias_remove_shows_usage_when_no_args(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -66,7 +66,7 @@ void cmd_alias_show_usage_when_invalid_subcmd(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -79,7 +79,7 @@ void cmd_alias_add_adds_alias(void **state) expect_cons_show("Command alias added /hc -> /help commands"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); char *returned_val = prefs_get_alias("hc"); @@ -100,7 +100,7 @@ void cmd_alias_add_shows_message_when_exists(void **state) expect_cons_show("Command or alias '/hc' already exists."); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -115,7 +115,7 @@ void cmd_alias_remove_removes_alias(void **state) expect_cons_show("Command alias removed -> /hn"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); char *returned_val = prefs_get_alias("hn"); @@ -132,7 +132,7 @@ void cmd_alias_remove_shows_message_when_no_alias(void **state) expect_cons_show("No such command alias /hn"); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); @@ -152,7 +152,7 @@ void cmd_alias_list_shows_all_aliases(void **state) // write a custom checker to check the correct list is passed expect_any(cons_show_aliases, aliases); - gboolean result = cmd_alias(args, *help); + gboolean result = cmd_alias(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_alias.h b/tests/unittests/test_cmd_alias.h index bd93ef1a..bd93ef1a 100644 --- a/tests/test_cmd_alias.h +++ b/tests/unittests/test_cmd_alias.h diff --git a/tests/test_cmd_bookmark.c b/tests/unittests/test_cmd_bookmark.c index 695e7362..04326f98 100644 --- a/tests/test_cmd_bookmark.c +++ b/tests/unittests/test_cmd_bookmark.c @@ -27,7 +27,7 @@ static void test_with_connection_status(jabber_conn_status_t status) will_return(jabber_get_connection_status, status); expect_cons_show("You are not currently connected."); - gboolean result = cmd_bookmark(NULL, *help); + gboolean result = cmd_bookmark(NULL, NULL, *help); assert_true(result); free(help); @@ -63,13 +63,14 @@ void cmd_bookmark_shows_usage_when_no_args(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); help->usage = "some usage"; gchar *args[] = { NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_cons_show("Usage: some usage"); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -103,6 +104,8 @@ void cmd_bookmark_list_shows_bookmarks(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "list", NULL }; GList *bookmarks = NULL; + ProfWin window; + window.type = WIN_CONSOLE; Bookmark *bm1 = malloc(sizeof(Bookmark)); bm1->jid = strdup("room1@conf.org"); @@ -132,14 +135,13 @@ void cmd_bookmark_list_shows_bookmarks(void **state) bookmarks = g_list_append(bookmarks, bm5); will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); will_return(bookmark_get_list, bookmarks); // TODO - Custom list compare glist_set_cmp((GCompareFunc)_cmp_bookmark); expect_any(cons_show_bookmarks, list); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -151,13 +153,14 @@ void cmd_bookmark_add_shows_message_when_invalid_jid(void **state) char *jid = "room"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "add", jid, NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_cons_show("Can't add bookmark with JID 'room'; should be 'room@domain.tld'"); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -168,9 +171,10 @@ void cmd_bookmark_add_adds_bookmark_with_jid(void **state) char *jid = "room@conf.server"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "add", jid, NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_string(bookmark_add, jid, jid); expect_any(bookmark_add, nick); @@ -180,7 +184,7 @@ void cmd_bookmark_add_adds_bookmark_with_jid(void **state) expect_cons_show("Bookmark added for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -191,9 +195,10 @@ void cmd_bookmark_add_adds_bookmark_with_jid_nick(void **state) char *nick = "bob"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "add", jid, "nick", nick, NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_string(bookmark_add, jid, jid); expect_string(bookmark_add, nick, nick); @@ -203,7 +208,7 @@ void cmd_bookmark_add_adds_bookmark_with_jid_nick(void **state) expect_cons_show("Bookmark added for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -214,9 +219,10 @@ void cmd_bookmark_add_adds_bookmark_with_jid_autojoin(void **state) char *jid = "room@conf.server"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "add", jid, "autojoin", "on", NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_string(bookmark_add, jid, jid); expect_any(bookmark_add, nick); @@ -226,7 +232,7 @@ void cmd_bookmark_add_adds_bookmark_with_jid_autojoin(void **state) expect_cons_show("Bookmark added for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -238,9 +244,10 @@ void cmd_bookmark_add_adds_bookmark_with_jid_nick_autojoin(void **state) char *nick = "bob"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "add", jid, "nick", nick, "autojoin", "on", NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_string(bookmark_add, jid, jid); expect_string(bookmark_add, nick, nick); @@ -250,7 +257,7 @@ void cmd_bookmark_add_adds_bookmark_with_jid_nick_autojoin(void **state) expect_cons_show("Bookmark added for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -261,16 +268,17 @@ void cmd_bookmark_remove_removes_bookmark(void **state) char *jid = "room@conf.server"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "remove", jid, NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_string(bookmark_remove, jid, jid); will_return(bookmark_remove, TRUE); expect_cons_show("Bookmark removed for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); @@ -281,16 +289,17 @@ void cmd_bookmark_remove_shows_message_when_no_bookmark(void **state) char *jid = "room@conf.server"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "remove", jid, NULL }; + ProfWin window; + window.type = WIN_CONSOLE; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CONSOLE); expect_any(bookmark_remove, jid); will_return(bookmark_remove, FALSE); expect_cons_show("No bookmark exists for room@conf.server."); - gboolean result = cmd_bookmark(args, *help); + gboolean result = cmd_bookmark(&window, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_bookmark.h b/tests/unittests/test_cmd_bookmark.h index 9505e105..9505e105 100644 --- a/tests/test_cmd_bookmark.h +++ b/tests/unittests/test_cmd_bookmark.h diff --git a/tests/test_cmd_connect.c b/tests/unittests/test_cmd_connect.c index e2089a09..b812bf23 100644 --- a/tests/test_cmd_connect.c +++ b/tests/unittests/test_cmd_connect.c @@ -22,7 +22,7 @@ static void test_with_connection_status(jabber_conn_status_t status) expect_cons_show("You are either connected already, or a login is in process."); - gboolean result = cmd_connect(NULL, *help); + gboolean result = cmd_connect(NULL, NULL, *help); assert_true(result); free(help); @@ -59,7 +59,7 @@ void cmd_connect_shows_usage_when_no_server_value(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -76,7 +76,7 @@ void cmd_connect_shows_usage_when_server_no_port_value(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -93,7 +93,7 @@ void cmd_connect_shows_usage_when_no_port_value(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -110,7 +110,7 @@ void cmd_connect_shows_usage_when_port_no_server_value(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -126,7 +126,7 @@ void cmd_connect_shows_message_when_port_0(void **state) expect_cons_show("Value 0 out of range. Must be in 1..65535."); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -142,7 +142,7 @@ void cmd_connect_shows_message_when_port_minus1(void **state) expect_cons_show("Value -1 out of range. Must be in 1..65535."); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -158,7 +158,7 @@ void cmd_connect_shows_message_when_port_65536(void **state) expect_cons_show("Value 65536 out of range. Must be in 1..65535."); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -174,7 +174,7 @@ void cmd_connect_shows_message_when_port_contains_chars(void **state) expect_cons_show("Could not convert \"52f66\" to a number."); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -191,7 +191,7 @@ void cmd_connect_shows_usage_when_server_provided_twice(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -208,7 +208,7 @@ void cmd_connect_shows_usage_when_port_provided_twice(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -225,7 +225,7 @@ void cmd_connect_shows_usage_when_invalid_first_property(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -242,7 +242,7 @@ void cmd_connect_shows_usage_when_invalid_second_property(void **state) expect_cons_show("Usage: some usage"); expect_cons_show(""); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -268,7 +268,7 @@ void cmd_connect_when_no_account(void **state) expect_value(jabber_connect_with_details, port, 0); will_return(jabber_connect_with_details, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -294,7 +294,7 @@ void cmd_connect_with_server_when_provided(void **state) expect_value(jabber_connect_with_details, port, 0); will_return(jabber_connect_with_details, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -320,7 +320,7 @@ void cmd_connect_with_port_when_provided(void **state) expect_value(jabber_connect_with_details, port, 5432); will_return(jabber_connect_with_details, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -346,7 +346,7 @@ void cmd_connect_with_server_and_port_when_provided(void **state) expect_value(jabber_connect_with_details, port, 5432); will_return(jabber_connect_with_details, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -374,7 +374,7 @@ void cmd_connect_fail_message(void **state) expect_cons_show_error("Connection attempt for user@server.org failed."); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -400,7 +400,7 @@ void cmd_connect_lowercases_argument(void **state) expect_any(jabber_connect_with_details, port); will_return(jabber_connect_with_details, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -411,7 +411,7 @@ void cmd_connect_asks_password_when_not_in_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); will_return(jabber_get_connection_status, JABBER_DISCONNECTED); @@ -425,7 +425,7 @@ void cmd_connect_asks_password_when_not_in_account(void **state) expect_any(jabber_connect_with_account, account); will_return(jabber_connect_with_account, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -436,7 +436,7 @@ void cmd_connect_shows_message_when_connecting_with_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "user@jabber.org", "password", NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); will_return(jabber_get_connection_status, JABBER_DISCONNECTED); @@ -448,7 +448,7 @@ void cmd_connect_shows_message_when_connecting_with_account(void **state) expect_any(jabber_connect_with_account, account); will_return(jabber_connect_with_account, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); @@ -459,7 +459,7 @@ void cmd_connect_connects_with_account(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "jabber_org", NULL }; ProfAccount *account = account_new("jabber_org", "me@jabber.org", "password", NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); will_return(jabber_get_connection_status, JABBER_DISCONNECTED); @@ -471,7 +471,7 @@ void cmd_connect_connects_with_account(void **state) expect_memory(jabber_connect_with_account, account, account, sizeof(account)); will_return(jabber_connect_with_account, JABBER_CONNECTING); - gboolean result = cmd_connect(args, *help); + gboolean result = cmd_connect(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_connect.h b/tests/unittests/test_cmd_connect.h index ad27a0a5..ad27a0a5 100644 --- a/tests/test_cmd_connect.h +++ b/tests/unittests/test_cmd_connect.h diff --git a/tests/test_cmd_disconnect.c b/tests/unittests/test_cmd_disconnect.c index 68253820..957516c2 100644 --- a/tests/test_cmd_disconnect.c +++ b/tests/unittests/test_cmd_disconnect.c @@ -25,7 +25,7 @@ void clears_chat_sessions(void **state) will_return(jabber_get_fulljid, "myjid@myserver.com"); expect_any_cons_show(); - gboolean result = cmd_disconnect(NULL, *help); + gboolean result = cmd_disconnect(NULL, NULL, *help); assert_true(result); @@ -34,4 +34,4 @@ void clears_chat_sessions(void **state) assert_null(session1); assert_null(session2); free(help); -} \ No newline at end of file +} diff --git a/tests/test_cmd_disconnect.h b/tests/unittests/test_cmd_disconnect.h index 856b501e..856b501e 100644 --- a/tests/test_cmd_disconnect.h +++ b/tests/unittests/test_cmd_disconnect.h diff --git a/tests/test_cmd_join.c b/tests/unittests/test_cmd_join.c index 19824b3a..cdb275d9 100644 --- a/tests/test_cmd_join.c +++ b/tests/unittests/test_cmd_join.c @@ -24,7 +24,7 @@ static void test_with_connection_status(jabber_conn_status_t status) expect_cons_show("You are not currently connected."); - gboolean result = cmd_join(NULL, *help); + gboolean result = cmd_join(NULL, NULL, *help); assert_true(result); free(help); @@ -60,7 +60,7 @@ void cmd_join_shows_error_message_when_invalid_room_jid(void **state) expect_cons_show_error("Specified room has incorrect format."); expect_cons_show(""); - gboolean result = cmd_join(args, *help); + gboolean result = cmd_join(NULL, args, *help); assert_true(result); free(help); @@ -76,7 +76,7 @@ void cmd_join_uses_account_mucservice_when_no_service_specified(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "nick", nick, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, NULL, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -90,7 +90,7 @@ void cmd_join_uses_account_mucservice_when_no_service_specified(void **state) expect_string(presence_join_room, nick, nick); expect_value(presence_join_room, passwd, NULL); - gboolean result = cmd_join(args, *help); + gboolean result = cmd_join(NULL, args, *help); assert_true(result); free(help); @@ -104,7 +104,7 @@ void cmd_join_uses_supplied_nick(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "nick", nick, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -118,7 +118,7 @@ void cmd_join_uses_supplied_nick(void **state) expect_string(presence_join_room, nick, nick); expect_value(presence_join_room, passwd, NULL); - gboolean result = cmd_join(args, *help); + gboolean result = cmd_join(NULL, args, *help); assert_true(result); free(help); @@ -132,7 +132,7 @@ void cmd_join_uses_account_nick_when_not_supplied(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, account_nick, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -146,7 +146,7 @@ void cmd_join_uses_account_nick_when_not_supplied(void **state) expect_string(presence_join_room, nick, account_nick); expect_value(presence_join_room, passwd, NULL); - gboolean result = cmd_join(args, *help); + gboolean result = cmd_join(NULL, args, *help); assert_true(result); free(help); @@ -163,7 +163,7 @@ void cmd_join_uses_password_when_supplied(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { room, "password", password, NULL }; ProfAccount *account = account_new(account_name, "user@server.org", NULL, NULL, - TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, account_service, account_nick, NULL, NULL, NULL, NULL, NULL); muc_init(); @@ -177,7 +177,7 @@ void cmd_join_uses_password_when_supplied(void **state) expect_string(presence_join_room, nick, account_nick); expect_value(presence_join_room, passwd, password); - gboolean result = cmd_join(args, *help); + gboolean result = cmd_join(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_join.h b/tests/unittests/test_cmd_join.h index a96fa435..a96fa435 100644 --- a/tests/test_cmd_join.h +++ b/tests/unittests/test_cmd_join.h diff --git a/tests/test_cmd_otr.c b/tests/unittests/test_cmd_otr.c index dae17947..7d4a3291 100644 --- a/tests/test_cmd_otr.c +++ b/tests/unittests/test_cmd_otr.c @@ -17,6 +17,7 @@ #include "command/command.h" #include "command/commands.h" +#include "window_list.h" #include "ui/ui.h" #include "ui/stub_ui.h" @@ -30,7 +31,7 @@ void cmd_otr_shows_usage_when_no_args(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -46,7 +47,7 @@ void cmd_otr_shows_usage_when_invalid_subcommand(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -60,7 +61,7 @@ void cmd_otr_log_shows_usage_when_no_args(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -74,7 +75,7 @@ void cmd_otr_log_shows_usage_when_invalid_subcommand(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -89,7 +90,7 @@ void cmd_otr_log_on_enables_logging(void **state) expect_cons_show("OTR messages will be logged as plaintext."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); assert_true(result); @@ -108,7 +109,7 @@ void cmd_otr_log_on_shows_warning_when_chlog_disabled(void **state) expect_cons_show("OTR messages will be logged as plaintext."); expect_cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -123,7 +124,7 @@ void cmd_otr_log_off_disables_logging(void **state) expect_cons_show("OTR message logging disabled."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); assert_true(result); @@ -141,7 +142,7 @@ void cmd_otr_redact_redacts_logging(void **state) expect_cons_show("OTR messages will be logged as '[redacted]'."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); assert_true(result); @@ -160,74 +161,12 @@ void cmd_otr_log_redact_shows_warning_when_chlog_disabled(void **state) expect_cons_show("OTR messages will be logged as '[redacted]'."); expect_cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); } -void cmd_otr_warn_shows_usage_when_no_args(void **state) -{ - CommandHelp *help = malloc(sizeof(CommandHelp)); - help->usage = "Some usage"; - gchar *args[] = { "warn", NULL }; - - expect_cons_show("Usage: Some usage"); - - gboolean result = cmd_otr(args, *help); - assert_true(result); - - free(help); -} - -void cmd_otr_warn_shows_usage_when_invalid_arg(void **state) -{ - CommandHelp *help = malloc(sizeof(CommandHelp)); - help->usage = "Some usage"; - gchar *args[] = { "warn", "badarg", NULL }; - - expect_cons_show("Usage: Some usage"); - - gboolean result = cmd_otr(args, *help); - assert_true(result); - - free(help); -} - -void cmd_otr_warn_on_enables_unencrypted_warning(void **state) -{ - CommandHelp *help = malloc(sizeof(CommandHelp)); - gchar *args[] = { "warn", "on", NULL }; - prefs_set_boolean(PREF_OTR_WARN, FALSE); - - expect_cons_show("OTR warning message enabled."); - - gboolean result = cmd_otr(args, *help); - gboolean otr_warn_enabled = prefs_get_boolean(PREF_OTR_WARN); - - assert_true(result); - assert_true(otr_warn_enabled); - - free(help); -} - -void cmd_otr_warn_off_disables_unencrypted_warning(void **state) -{ - CommandHelp *help = malloc(sizeof(CommandHelp)); - gchar *args[] = { "warn", "off", NULL }; - prefs_set_boolean(PREF_OTR_WARN, TRUE); - - expect_cons_show("OTR warning message disabled."); - - gboolean result = cmd_otr(args, *help); - gboolean otr_warn_enabled = prefs_get_boolean(PREF_OTR_WARN); - - assert_true(result); - assert_false(otr_warn_enabled); - - free(help); -} - void cmd_otr_libver_shows_libotr_version(void **state) { CommandHelp *help = malloc(sizeof(CommandHelp)); @@ -240,7 +179,7 @@ void cmd_otr_libver_shows_libotr_version(void **state) expect_cons_show(message->str); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); g_string_free(message, TRUE); @@ -256,7 +195,7 @@ void cmd_otr_gen_shows_message_when_not_connected(void **state) expect_cons_show("You must be connected with an account to load OTR information."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -271,7 +210,7 @@ static void test_with_command_and_connection_status(char *command, jabber_conn_s expect_cons_show("You must be connected with an account to load OTR information."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -308,7 +247,7 @@ void cmd_otr_gen_generates_key_for_connected_account(void **state) gchar *args[] = { "gen", NULL }; char *account_name = "myaccount"; ProfAccount *account = account_new(account_name, "me@jabber.org", NULL, NULL, - TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); + TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); will_return(jabber_get_connection_status, JABBER_CONNECTED); will_return(jabber_get_account_name, account_name); @@ -319,7 +258,7 @@ void cmd_otr_gen_generates_key_for_connected_account(void **state) expect_memory(otr_keygen, account, account, sizeof(ProfAccount)); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -360,7 +299,7 @@ void cmd_otr_myfp_shows_message_when_no_key(void **state) expect_ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); @@ -380,7 +319,7 @@ void cmd_otr_myfp_shows_my_fingerprint(void **state) expect_ui_current_print_formatted_line('!', 0, message->str); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); g_string_free(message, TRUE); @@ -392,13 +331,14 @@ test_cmd_otr_theirfp_from_wintype(win_type_t wintype) { CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "theirfp", NULL }; + ProfWin window; + window.type = wintype; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, wintype); expect_ui_current_print_line("You must be in a regular chat window to view a recipient's fingerprint."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(&window, args, *help); assert_true(result); free(help); @@ -424,13 +364,17 @@ void cmd_otr_theirfp_shows_message_when_non_otr_chat_window(void **state) CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "theirfp", NULL }; + ProfWin window; + window.type = WIN_CHAT; + ProfChatWin chatwin; + chatwin.window = window; + chatwin.memcheck = PROFCHATWIN_MEMCHECK; + will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CHAT); - will_return(ui_current_win_is_otr, FALSE); expect_ui_current_print_formatted_line('!', 0, "You are not currently in an OTR session."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr((ProfWin*)&chatwin, args, *help); assert_true(result); free(help); @@ -442,29 +386,30 @@ void cmd_otr_theirfp_shows_fingerprint(void **state) char *fingerprint = "AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "theirfp", NULL }; - ProfChatWin *chatwin = malloc(sizeof(ProfChatWin)); - chatwin->barejid = strdup(recipient); - GString *message = g_string_new(chatwin->barejid); + GString *message = g_string_new(recipient); g_string_append(message, "'s OTR fingerprint: "); g_string_append(message, fingerprint); + ProfWin window; + window.type = WIN_CHAT; + ProfChatWin chatwin; + chatwin.window = window; + chatwin.barejid = recipient; + chatwin.memcheck = PROFCHATWIN_MEMCHECK; + chatwin.enc_mode = PROF_ENC_OTR; + will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CHAT); - will_return(ui_get_current_chat, chatwin); - will_return(ui_current_win_is_otr, TRUE); - expect_string(otr_get_their_fingerprint, recipient, chatwin->barejid); + expect_string(otr_get_their_fingerprint, recipient, recipient); will_return(otr_get_their_fingerprint, strdup(fingerprint)); expect_ui_current_print_formatted_line('!', 0, message->str); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr((ProfWin*)&chatwin, args, *help); assert_true(result); g_string_free(message, TRUE); free(help); - free(chatwin->barejid); - free(chatwin); } static void @@ -472,13 +417,14 @@ test_cmd_otr_start_from_wintype(win_type_t wintype) { CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "start", NULL }; + ProfWin window; + window.type = wintype; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, wintype); expect_ui_current_print_line("You must be in a regular chat window to start an OTR session."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(&window, args, *help); assert_true(result); free(help); @@ -501,16 +447,23 @@ void cmd_otr_start_shows_message_when_in_private(void **state) void cmd_otr_start_shows_message_when_already_started(void **state) { + char *recipient = "someone@server.org"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "start", NULL }; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CHAT); - will_return(ui_current_win_is_otr, TRUE); + + ProfWin window; + window.type = WIN_CHAT; + ProfChatWin chatwin; + chatwin.window = window; + chatwin.barejid = recipient; + chatwin.memcheck = PROFCHATWIN_MEMCHECK; + chatwin.enc_mode = PROF_ENC_OTR; expect_ui_current_print_formatted_line('!', 0, "You are already in an OTR session."); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr((ProfWin*)&chatwin, args, *help); assert_true(result); free(help); @@ -518,17 +471,24 @@ void cmd_otr_start_shows_message_when_already_started(void **state) void cmd_otr_start_shows_message_when_no_key(void **state) { + char *recipient = "someone@server.org"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "start", NULL }; will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CHAT); - will_return(ui_current_win_is_otr, FALSE); will_return(otr_key_loaded, FALSE); + ProfWin window; + window.type = WIN_CHAT; + ProfChatWin chatwin; + chatwin.window = window; + chatwin.barejid = recipient; + chatwin.memcheck = PROFCHATWIN_MEMCHECK; + chatwin.enc_mode = PROF_ENC_NONE; + expect_ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr((ProfWin*)&chatwin, args, *help); assert_true(result); free(help); @@ -538,28 +498,29 @@ void cmd_otr_start_sends_otr_query_message_to_current_recipeint(void **state) { char *recipient = "buddy@chat.com"; - ProfChatWin *chatwin = malloc(sizeof(ProfChatWin)); - chatwin->barejid = strdup(recipient); char *query_message = "?OTR?"; CommandHelp *help = malloc(sizeof(CommandHelp)); gchar *args[] = { "start", NULL }; + ProfWin window; + window.type = WIN_CHAT; + ProfChatWin chatwin; + chatwin.window = window; + chatwin.barejid = recipient; + chatwin.memcheck = PROFCHATWIN_MEMCHECK; + chatwin.enc_mode = PROF_ENC_NONE; + will_return(jabber_get_connection_status, JABBER_CONNECTED); - will_return(ui_current_win_type, WIN_CHAT); - will_return(ui_get_current_chat, chatwin); - will_return(ui_current_win_is_otr, FALSE); will_return(otr_key_loaded, TRUE); will_return(otr_start_query, query_message); - expect_string(message_send_chat_encrypted, barejid, chatwin->barejid); - expect_string(message_send_chat_encrypted, msg, query_message); + expect_string(message_send_chat_otr, barejid, recipient); + expect_string(message_send_chat_otr, msg, query_message); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr((ProfWin*)&chatwin, args, *help); assert_true(result); free(help); - free(chatwin->barejid); - free(chatwin); } #else @@ -570,7 +531,7 @@ void cmd_otr_shows_message_when_otr_unsupported(void **state) expect_cons_show("This version of Profanity has not been built with OTR support enabled"); - gboolean result = cmd_otr(args, *help); + gboolean result = cmd_otr(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_otr.h b/tests/unittests/test_cmd_otr.h index 8ef182e9..469d7c54 100644 --- a/tests/test_cmd_otr.h +++ b/tests/unittests/test_cmd_otr.h @@ -10,10 +10,6 @@ void cmd_otr_log_off_disables_logging(void **state); void cmd_otr_redact_redacts_logging(void **state); void cmd_otr_log_on_shows_warning_when_chlog_disabled(void **state); void cmd_otr_log_redact_shows_warning_when_chlog_disabled(void **state); -void cmd_otr_warn_shows_usage_when_no_args(void **state); -void cmd_otr_warn_shows_usage_when_invalid_arg(void **state); -void cmd_otr_warn_on_enables_unencrypted_warning(void **state); -void cmd_otr_warn_off_disables_unencrypted_warning(void **state); void cmd_otr_libver_shows_libotr_version(void **state); void cmd_otr_gen_shows_message_when_not_connected(void **state); void cmd_otr_gen_generates_key_for_connected_account(void **state); diff --git a/tests/unittests/test_cmd_pgp.c b/tests/unittests/test_cmd_pgp.c new file mode 100644 index 00000000..aef4baf7 --- /dev/null +++ b/tests/unittests/test_cmd_pgp.c @@ -0,0 +1,129 @@ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> + +#include "config.h" + +#include "command/commands.h" + +#include "ui/stub_ui.h" + +#ifdef HAVE_LIBGPGME +void cmd_pgp_shows_usage_when_no_args(void **state) +{ + CommandHelp *help = malloc(sizeof(CommandHelp)); + help->usage = "Some usage"; + gchar *args[] = { NULL }; + + expect_cons_show("Usage: Some usage"); + + gboolean result = cmd_pgp(NULL, args, *help); + assert_true(result); + + free(help); +} + +void cmd_pgp_start_shows_message_when_connection(jabber_conn_status_t conn_status) +{ + CommandHelp *help = malloc(sizeof(CommandHelp)); + help->usage = "Some usage"; + gchar *args[] = { "start", NULL }; + ProfWin window; + window.type = WIN_CHAT; + + will_return(jabber_get_connection_status, conn_status); + + expect_cons_show("You must be connected to start PGP encrpytion."); + + gboolean result = cmd_pgp(&window, args, *help); + assert_true(result); + + free(help); +} + +void cmd_pgp_start_shows_message_when_disconnected(void **state) +{ + cmd_pgp_start_shows_message_when_connection(JABBER_DISCONNECTED); +} + +void cmd_pgp_start_shows_message_when_disconnecting(void **state) +{ + cmd_pgp_start_shows_message_when_connection(JABBER_DISCONNECTING); +} + +void cmd_pgp_start_shows_message_when_connecting(void **state) +{ + cmd_pgp_start_shows_message_when_connection(JABBER_CONNECTING); +} + +void cmd_pgp_start_shows_message_when_undefined(void **state) +{ + cmd_pgp_start_shows_message_when_connection(JABBER_UNDEFINED); +} + +void cmd_pgp_start_shows_message_when_started(void **state) +{ + cmd_pgp_start_shows_message_when_connection(JABBER_STARTED); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_wintype(win_type_t wintype) +{ + CommandHelp *help = malloc(sizeof(CommandHelp)); + help->usage = "Some usage"; + gchar *args[] = { "start", NULL }; + ProfWin window; + window.type = wintype; + + will_return(jabber_get_connection_status, JABBER_CONNECTED); + + expect_cons_show("You must be in a regular chat window to start PGP encrpytion."); + + gboolean result = cmd_pgp(&window, args, *help); + assert_true(result); + + free(help); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_console(void **state) +{ + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_CONSOLE); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_muc(void **state) +{ + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_MUC); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_mucconf(void **state) +{ + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_MUC_CONFIG); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_private(void **state) +{ + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_PRIVATE); +} + +void cmd_pgp_start_shows_message_when_no_arg_in_xmlconsole(void **state) +{ + cmd_pgp_start_shows_message_when_no_arg_in_wintype(WIN_XML); +} + +#else +void cmd_pgp_shows_message_when_pgp_unsupported(void **state) +{ + CommandHelp *help = malloc(sizeof(CommandHelp)); + gchar *args[] = { "gen", NULL }; + + expect_cons_show("This version of Profanity has not been built with PGP support enabled"); + + gboolean result = cmd_pgp(NULL, args, *help); + assert_true(result); + + free(help); +} +#endif diff --git a/tests/unittests/test_cmd_pgp.h b/tests/unittests/test_cmd_pgp.h new file mode 100644 index 00000000..fcb24500 --- /dev/null +++ b/tests/unittests/test_cmd_pgp.h @@ -0,0 +1,17 @@ +#include "config.h" + +#ifdef HAVE_LIBGPGME +void cmd_pgp_shows_usage_when_no_args(void **state); +void cmd_pgp_start_shows_message_when_disconnected(void **state); +void cmd_pgp_start_shows_message_when_disconnecting(void **state); +void cmd_pgp_start_shows_message_when_connecting(void **state); +void cmd_pgp_start_shows_message_when_undefined(void **state); +void cmd_pgp_start_shows_message_when_started(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_console(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_muc(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_mucconf(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_private(void **state); +void cmd_pgp_start_shows_message_when_no_arg_in_xmlconsole(void **state); +#else +void cmd_pgp_shows_message_when_pgp_unsupported(void **state); +#endif diff --git a/tests/test_cmd_rooms.c b/tests/unittests/test_cmd_rooms.c index 5114bfbf..7a336561 100644 --- a/tests/test_cmd_rooms.c +++ b/tests/unittests/test_cmd_rooms.c @@ -22,7 +22,7 @@ static void test_with_connection_status(jabber_conn_status_t status) expect_cons_show("You are not currently connected."); - gboolean result = cmd_rooms(NULL, *help); + gboolean result = cmd_rooms(NULL, NULL, *help); assert_true(result); free(help); @@ -80,7 +80,7 @@ void cmd_rooms_uses_account_default_when_no_arg(void **state) expect_string(iq_room_list_request, conferencejid, "default_conf_server"); - gboolean result = cmd_rooms(args, *help); + gboolean result = cmd_rooms(NULL, args, *help); assert_true(result); @@ -96,7 +96,7 @@ void cmd_rooms_arg_used_when_passed(void **state) expect_string(iq_room_list_request, conferencejid, "conf_server_arg"); - gboolean result = cmd_rooms(args, *help); + gboolean result = cmd_rooms(NULL, args, *help); assert_true(result); diff --git a/tests/test_cmd_rooms.h b/tests/unittests/test_cmd_rooms.h index a9a7af83..a9a7af83 100644 --- a/tests/test_cmd_rooms.h +++ b/tests/unittests/test_cmd_rooms.h diff --git a/tests/test_cmd_roster.c b/tests/unittests/test_cmd_roster.c index a7160cf5..0fd1647a 100644 --- a/tests/test_cmd_roster.c +++ b/tests/unittests/test_cmd_roster.c @@ -16,12 +16,13 @@ static void test_with_connection_status(jabber_conn_status_t status) { CommandHelp *help = malloc(sizeof(CommandHelp)); + gchar *args[] = { NULL }; will_return(jabber_get_connection_status, status); expect_cons_show("You are not currently connected."); - gboolean result = cmd_roster(NULL, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -60,7 +61,7 @@ void cmd_roster_shows_roster_when_no_args(void **state) expect_memory(cons_show_roster, list, roster, sizeof(roster)); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -77,7 +78,7 @@ void cmd_roster_add_shows_message_when_no_jid(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -95,7 +96,7 @@ void cmd_roster_add_sends_roster_add_request(void **state) expect_string(roster_send_add_new, barejid, jid); expect_string(roster_send_add_new, name, nick); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -111,7 +112,7 @@ void cmd_roster_remove_shows_message_when_no_jid(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -127,7 +128,7 @@ void cmd_roster_remove_sends_roster_remove_request(void **state) expect_string(roster_send_remove, barejid, jid); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -143,7 +144,7 @@ void cmd_roster_nick_shows_message_when_no_jid(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -159,7 +160,7 @@ void cmd_roster_nick_shows_message_when_no_nick(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -177,7 +178,7 @@ void cmd_roster_nick_shows_message_when_no_contact_exists(void **state) expect_cons_show("Contact not found in roster: bob@server.org"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -204,7 +205,7 @@ void cmd_roster_nick_sends_name_change_request(void **state) expect_cons_show("Nickname for bob@server.org set to: bobster."); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); PContact contact = roster_get_contact(jid); @@ -224,7 +225,7 @@ void cmd_roster_clearnick_shows_message_when_no_jid(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -242,7 +243,7 @@ void cmd_roster_clearnick_shows_message_when_no_contact_exists(void **state) expect_cons_show("Contact not found in roster: bob@server.org"); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); free(help); @@ -268,7 +269,7 @@ void cmd_roster_clearnick_sends_name_change_request_with_empty_nick(void **state expect_cons_show("Nickname for bob@server.org removed."); - gboolean result = cmd_roster(args, *help); + gboolean result = cmd_roster(NULL, args, *help); assert_true(result); PContact contact = roster_get_contact(jid); diff --git a/tests/test_cmd_roster.h b/tests/unittests/test_cmd_roster.h index 79f69ec8..79f69ec8 100644 --- a/tests/test_cmd_roster.h +++ b/tests/unittests/test_cmd_roster.h diff --git a/tests/test_cmd_statuses.c b/tests/unittests/test_cmd_statuses.c index ed37021a..0ecb22ae 100644 --- a/tests/test_cmd_statuses.c +++ b/tests/unittests/test_cmd_statuses.c @@ -21,7 +21,7 @@ void cmd_statuses_shows_usage_when_bad_subcmd(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); assert_true(result); free(help); @@ -35,7 +35,7 @@ void cmd_statuses_shows_usage_when_bad_console_setting(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); assert_true(result); free(help); @@ -49,7 +49,7 @@ void cmd_statuses_shows_usage_when_bad_chat_setting(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); assert_true(result); free(help); @@ -63,7 +63,7 @@ void cmd_statuses_shows_usage_when_bad_muc_setting(void **state) expect_cons_show("Usage: some usage"); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); assert_true(result); free(help); @@ -76,7 +76,7 @@ void cmd_statuses_console_sets_all(void **state) expect_cons_show("All presence updates will appear in the console."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CONSOLE); assert_non_null(setting); @@ -93,7 +93,7 @@ void cmd_statuses_console_sets_online(void **state) expect_cons_show("Only online/offline presence updates will appear in the console."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CONSOLE); assert_non_null(setting); @@ -110,7 +110,7 @@ void cmd_statuses_console_sets_none(void **state) expect_cons_show("Presence updates will not appear in the console."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CONSOLE); assert_non_null(setting); @@ -127,7 +127,7 @@ void cmd_statuses_chat_sets_all(void **state) expect_cons_show("All presence updates will appear in chat windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CHAT); assert_non_null(setting); @@ -144,7 +144,7 @@ void cmd_statuses_chat_sets_online(void **state) expect_cons_show("Only online/offline presence updates will appear in chat windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CHAT); assert_non_null(setting); @@ -161,7 +161,7 @@ void cmd_statuses_chat_sets_none(void **state) expect_cons_show("Presence updates will not appear in chat windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_CHAT); assert_non_null(setting); @@ -178,7 +178,7 @@ void cmd_statuses_muc_sets_all(void **state) expect_cons_show("All presence updates will appear in chat room windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_MUC); assert_non_null(setting); @@ -195,7 +195,7 @@ void cmd_statuses_muc_sets_online(void **state) expect_cons_show("Only join/leave presence updates will appear in chat room windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_MUC); assert_non_null(setting); @@ -212,7 +212,7 @@ void cmd_statuses_muc_sets_none(void **state) expect_cons_show("Presence updates will not appear in chat room windows."); - gboolean result = cmd_statuses(args, *help); + gboolean result = cmd_statuses(NULL, args, *help); char *setting = prefs_get_string(PREF_STATUSES_MUC); assert_non_null(setting); diff --git a/tests/test_cmd_statuses.h b/tests/unittests/test_cmd_statuses.h index 306a6fc7..306a6fc7 100644 --- a/tests/test_cmd_statuses.h +++ b/tests/unittests/test_cmd_statuses.h diff --git a/tests/test_cmd_sub.c b/tests/unittests/test_cmd_sub.c index 80b85f15..55b9de60 100644 --- a/tests/test_cmd_sub.c +++ b/tests/unittests/test_cmd_sub.c @@ -22,7 +22,7 @@ void cmd_sub_shows_message_when_not_connected(void **state) expect_cons_show("You are currently not connected."); - gboolean result = cmd_sub(args, *help); + gboolean result = cmd_sub(NULL, args, *help); assert_true(result); free(help); @@ -38,7 +38,7 @@ void cmd_sub_shows_usage_when_no_arg(void **state) expect_cons_show("Usage: Some usage"); - gboolean result = cmd_sub(args, *help); + gboolean result = cmd_sub(NULL, args, *help); assert_true(result); free(help); diff --git a/tests/test_cmd_sub.h b/tests/unittests/test_cmd_sub.h index 6e8addd3..6e8addd3 100644 --- a/tests/test_cmd_sub.h +++ b/tests/unittests/test_cmd_sub.h diff --git a/tests/test_common.c b/tests/unittests/test_common.c index 980f2198..980f2198 100644 --- a/tests/test_common.c +++ b/tests/unittests/test_common.c diff --git a/tests/test_common.h b/tests/unittests/test_common.h index b4b98e5a..b4b98e5a 100644 --- a/tests/test_common.h +++ b/tests/unittests/test_common.h diff --git a/tests/test_contact.c b/tests/unittests/test_contact.c index cad88907..cad88907 100644 --- a/tests/test_contact.c +++ b/tests/unittests/test_contact.c diff --git a/tests/test_contact.h b/tests/unittests/test_contact.h index c9d8c1fd..c9d8c1fd 100644 --- a/tests/test_contact.h +++ b/tests/unittests/test_contact.h diff --git a/tests/test_form.c b/tests/unittests/test_form.c index b3158a83..b3158a83 100644 --- a/tests/test_form.c +++ b/tests/unittests/test_form.c diff --git a/tests/test_form.h b/tests/unittests/test_form.h index 65911d0a..65911d0a 100644 --- a/tests/test_form.h +++ b/tests/unittests/test_form.h diff --git a/tests/test_jid.c b/tests/unittests/test_jid.c index ff5f4c9a..ff5f4c9a 100644 --- a/tests/test_jid.c +++ b/tests/unittests/test_jid.c diff --git a/tests/test_jid.h b/tests/unittests/test_jid.h index 9b96d0b8..9b96d0b8 100644 --- a/tests/test_jid.h +++ b/tests/unittests/test_jid.h diff --git a/tests/test_keyhandlers.c b/tests/unittests/test_keyhandlers.c index a6d39143..a6d39143 100644 --- a/tests/test_keyhandlers.c +++ b/tests/unittests/test_keyhandlers.c diff --git a/tests/test_keyhandlers.h b/tests/unittests/test_keyhandlers.h index 4be429a9..4be429a9 100644 --- a/tests/test_keyhandlers.h +++ b/tests/unittests/test_keyhandlers.h diff --git a/tests/test_muc.c b/tests/unittests/test_muc.c index e3b7f9b0..e3b7f9b0 100644 --- a/tests/test_muc.c +++ b/tests/unittests/test_muc.c diff --git a/tests/test_muc.h b/tests/unittests/test_muc.h index 8df54a5d..8df54a5d 100644 --- a/tests/test_muc.h +++ b/tests/unittests/test_muc.h diff --git a/tests/test_parser.c b/tests/unittests/test_parser.c index faefc9c7..faefc9c7 100644 --- a/tests/test_parser.c +++ b/tests/unittests/test_parser.c diff --git a/tests/test_parser.h b/tests/unittests/test_parser.h index 51d768fe..51d768fe 100644 --- a/tests/test_parser.h +++ b/tests/unittests/test_parser.h diff --git a/tests/test_preferences.c b/tests/unittests/test_preferences.c index c4bcbf77..c4bcbf77 100644 --- a/tests/test_preferences.c +++ b/tests/unittests/test_preferences.c diff --git a/tests/test_preferences.h b/tests/unittests/test_preferences.h index 5bf79a6a..5bf79a6a 100644 --- a/tests/test_preferences.h +++ b/tests/unittests/test_preferences.h diff --git a/tests/test_roster_list.c b/tests/unittests/test_roster_list.c index 41ccb8cf..41ccb8cf 100644 --- a/tests/test_roster_list.c +++ b/tests/unittests/test_roster_list.c diff --git a/tests/test_roster_list.h b/tests/unittests/test_roster_list.h index 080bca9f..080bca9f 100644 --- a/tests/test_roster_list.h +++ b/tests/unittests/test_roster_list.h diff --git a/tests/test_server_events.c b/tests/unittests/test_server_events.c index 58489807..fac1ac38 100644 --- a/tests/test_server_events.c +++ b/tests/unittests/test_server_events.c @@ -26,7 +26,7 @@ void console_shows_online_presence_when_set_online(void **state) expect_memory(ui_contact_online, resource, resource, sizeof(resource)); expect_value(ui_contact_online, last_activity, NULL); - sv_ev_contact_online(barejid, resource, NULL); + sv_ev_contact_online(barejid, resource, NULL, NULL); roster_clear(); } @@ -43,7 +43,7 @@ void console_shows_online_presence_when_set_all(void **state) expect_memory(ui_contact_online, resource, resource, sizeof(resource)); expect_value(ui_contact_online, last_activity, NULL); - sv_ev_contact_online(barejid, resource, NULL); + sv_ev_contact_online(barejid, resource, NULL, NULL); roster_clear(); } @@ -60,7 +60,7 @@ void console_shows_dnd_presence_when_set_all(void **state) expect_memory(ui_contact_online, resource, resource, sizeof(resource)); expect_value(ui_contact_online, last_activity, NULL); - sv_ev_contact_online(barejid, resource, NULL); + sv_ev_contact_online(barejid, resource, NULL, NULL); roster_clear(); } diff --git a/tests/test_server_events.h b/tests/unittests/test_server_events.h index 81a436f4..81a436f4 100644 --- a/tests/test_server_events.h +++ b/tests/unittests/test_server_events.h diff --git a/tests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c index 52c38570..71a577f5 100644 --- a/tests/ui/stub_ui.c +++ b/tests/unittests/ui/stub_ui.c @@ -7,7 +7,7 @@ #include "ui/window.h" #include "ui/ui.h" -#include "tests/ui/stub_ui.h" +#include "tests/unittests/ui/stub_ui.h" // mock state @@ -121,21 +121,6 @@ int ui_close_read_wins(void) // current window actions void ui_clear_current(void) {} -win_type_t ui_current_win_type(void) -{ - return (win_type_t)mock(); -} - -gboolean ui_current_win_is_otr(void) -{ - return (gboolean)mock(); -} - -ProfChatWin *ui_get_current_chat(void) -{ - return (ProfChatWin*)mock(); -} - void ui_current_print_line(const char * const msg, ...) { va_list args; @@ -176,6 +161,7 @@ void ui_page_up(void) {} void ui_page_down(void) {} void ui_subwin_page_up(void) {} void ui_subwin_page_down(void) {} +void ui_clear_win(ProfWin *window) {} char * ui_ask_password(void) { @@ -193,10 +179,10 @@ void ui_contact_online(char *barejid, Resource *resource, GDateTime *last_activi } void ui_contact_typing(const char * const barejid, const char * const resource) {} -void ui_incoming_msg(const char * const from, const char * const resource, const char * const message, GTimeVal *tv_stamp) {} +void ui_incoming_msg(ProfChatWin *chatwin, const char * const resource, const char * const message, GDateTime *timestamp, gboolean win_created) {} void ui_message_receipt(const char * const barejid, const char * const id) {} -void ui_incoming_private_msg(const char * const fulljid, const char * const message, GTimeVal *tv_stamp) {} +void ui_incoming_private_msg(const char * const fulljid, const char * const message, GDateTime *timestamp) {} void ui_disconnected(void) {} void ui_recipient_gone(const char * const barejid, const char * const resource) {} @@ -222,7 +208,7 @@ void ui_room_occupant_role_and_affiliation_change(const char * const roomjid, co const char * const affiliation, const char * const actor, const char * const reason) {} void ui_room_roster(const char * const roomjid, GList *occupants, const char * const presence) {} void ui_room_history(const char * const roomjid, const char * const nick, - GTimeVal tv_stamp, const char * const message) {} + GDateTime *timestamp, const char * const message) {} void ui_room_message(const char * const roomjid, const char * const nick, const char * const message) {} void ui_room_subject(const char * const roomjid, const char * const nick, const char * const subject) {} @@ -315,7 +301,9 @@ void ui_redraw_all_room_rosters(void) {} void ui_show_all_room_rosters(void) {} void ui_hide_all_room_rosters(void) {} -void ui_tidy_wins(void) {} +gboolean ui_tidy_wins(void) { + return TRUE; +} void ui_prune_wins(void) {} gboolean ui_swap_wins(int source_win, int target_win) { @@ -381,6 +369,7 @@ void cons_show_log_prefs(void) {} void cons_show_presence_prefs(void) {} void cons_show_connection_prefs(void) {} void cons_show_otr_prefs(void) {} +void cons_show_pgp_prefs(void) {} void cons_show_account(ProfAccount *account) { @@ -458,6 +447,8 @@ void cons_occupants_setting(void) {} void cons_roster_setting(void) {} void cons_presence_setting(void) {} void cons_wrap_setting(void) {} +void cons_winstidy_setting(void) {} +void cons_encwarn_setting(void) {} void cons_time_setting(void) {} void cons_mouse_setting(void) {} void cons_statuses_setting(void) {} @@ -490,12 +481,68 @@ void cons_show_contact_online(PContact contact, Resource *resource, GDateTime *l void cons_show_contact_offline(PContact contact, char *resource, char *status) {} void cons_theme_colours(void) {} +// status bar +void status_bar_inactive(const int win) {} +void status_bar_active(const int win) {} +void status_bar_new(const int win) {} +void status_bar_set_all_inactive(void) {} + // roster window void rosterwin_roster(void) {} // occupants window void occupantswin_occupants(const char * const room) {} +// window interface +ProfWin* win_create_console(void) +{ + return NULL; +} +ProfWin* win_create_xmlconsole(void) +{ + return NULL; +} +ProfWin* win_create_chat(const char * const barejid) +{ + return (ProfWin*)mock(); +} +ProfWin* win_create_muc(const char * const roomjid) +{ + return NULL; +} +ProfWin* win_create_muc_config(const char * const title, DataForm *form) +{ + return NULL; +} +ProfWin* win_create_private(const char * const fulljid) +{ + return NULL; +} + +void win_update_virtual(ProfWin *window) {} +void win_free(ProfWin *window) {} +int win_unread(ProfWin *window) +{ + return 0; +} + +void win_resize(ProfWin *window) {} +void win_hide_subwin(ProfWin *window) {} +void win_show_subwin(ProfWin *window) {} +void win_refresh_without_subwin(ProfWin *window) {} +void win_refresh_with_subwin(ProfWin *window) {} +void win_print(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message) {} +void win_vprint(ProfWin *window, const char show_char, GDateTime *timestamp, int flags, theme_item_t theme_item, const char * const from, const char * const message, ...) {} +char* win_get_title(ProfWin *window) +{ + return NULL; +} +void win_show_occupant(ProfWin *window, Occupant *occupant) {} +void win_show_occupant_info(ProfWin *window, const char * const room, Occupant *occupant) {} +void win_show_contact(ProfWin *window, PContact contact) {} +void win_show_info(ProfWin *window, PContact contact) {} +void win_println(ProfWin *window, const char * const message) {} + // desktop notifier actions void notifier_uninit(void) {} diff --git a/tests/ui/stub_ui.h b/tests/unittests/ui/stub_ui.h index 81357a86..81357a86 100644 --- a/tests/ui/stub_ui.h +++ b/tests/unittests/ui/stub_ui.h diff --git a/tests/testsuite.c b/tests/unittests/unittests.c index 3f860178..61c58e33 100644 --- a/tests/testsuite.c +++ b/tests/unittests/unittests.c @@ -21,6 +21,7 @@ #include "test_cmd_sub.h" #include "test_cmd_statuses.h" #include "test_cmd_otr.h" +#include "test_cmd_pgp.h" #include "test_jid.h" #include "test_parser.h" #include "test_roster_list.h" @@ -324,6 +325,7 @@ int main(int argc, char* argv[]) { unit_test(cmd_account_set_jid_sets_resource), unit_test(cmd_account_set_server_sets_server), unit_test(cmd_account_set_resource_sets_resource), + unit_test(cmd_account_set_resource_sets_resource_with_online_message), unit_test(cmd_account_set_password_sets_password), unit_test(cmd_account_set_eval_password_sets_eval_password), unit_test(cmd_account_set_password_when_eval_password_set), @@ -499,14 +501,6 @@ int main(int argc, char* argv[]) { unit_test_setup_teardown(cmd_otr_log_redact_shows_warning_when_chlog_disabled, load_preferences, close_preferences), - unit_test(cmd_otr_warn_shows_usage_when_no_args), - unit_test(cmd_otr_warn_shows_usage_when_invalid_arg), - unit_test_setup_teardown(cmd_otr_warn_on_enables_unencrypted_warning, - load_preferences, - close_preferences), - unit_test_setup_teardown(cmd_otr_warn_off_disables_unencrypted_warning, - load_preferences, - close_preferences), unit_test(cmd_otr_libver_shows_libotr_version), unit_test(cmd_otr_gen_shows_message_when_not_connected), unit_test(cmd_otr_gen_generates_key_for_connected_account), @@ -539,6 +533,22 @@ int main(int argc, char* argv[]) { unit_test(cmd_otr_shows_message_when_otr_unsupported), #endif +#ifdef HAVE_LIBGPGME + unit_test(cmd_pgp_shows_usage_when_no_args), + unit_test(cmd_pgp_start_shows_message_when_disconnected), + unit_test(cmd_pgp_start_shows_message_when_disconnecting), + unit_test(cmd_pgp_start_shows_message_when_connecting), + unit_test(cmd_pgp_start_shows_message_when_undefined), + unit_test(cmd_pgp_start_shows_message_when_started), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_console), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_muc), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_mucconf), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_private), + unit_test(cmd_pgp_start_shows_message_when_no_arg_in_xmlconsole), +#else + unit_test(cmd_pgp_shows_message_when_pgp_unsupported), +#endif + unit_test(cmd_join_shows_message_when_disconnecting), unit_test(cmd_join_shows_message_when_connecting), unit_test(cmd_join_shows_message_when_disconnected), diff --git a/tests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index cc9580bf..79f2595a 100644 --- a/tests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -26,7 +26,7 @@ jabber_conn_status_t jabber_connect_with_account(const ProfAccount * const accou void jabber_disconnect(void) {} void jabber_shutdown(void) {} -void jabber_process_events(void) {} +void jabber_process_events(int millis) {} const char * jabber_get_fulljid(void) { return (char *)mock(); @@ -65,13 +65,18 @@ char* message_send_chat(const char * const barejid, const char * const msg) return NULL; } -char* message_send_chat_encrypted(const char * const barejid, const char * const msg) +char* message_send_chat_otr(const char * const barejid, const char * const msg) { check_expected(barejid); check_expected(msg); return NULL; } +char* message_send_chat_pgp(const char * const barejid, const char * const msg) +{ + return NULL; +} + void message_send_private(const char * const fulljid, const char * const msg) {} void message_send_groupchat(const char * const roomjid, const char * const msg) {} void message_send_groupchat_subject(const char * const roomjid, const char * const subject) {} @@ -114,11 +119,12 @@ void presence_join_room(char *room, char *nick, char * passwd) void presence_change_room_nick(const char * const room, const char * const nick) {} void presence_leave_chat_room(const char * const room_jid) {} -void presence_send(resource_presence_t status, const char * const msg, int idle) +void presence_send(resource_presence_t status, const char * const msg, int idle, char *signed_status) { check_expected(status); check_expected(msg); check_expected(idle); + check_expected(signed_status); } gboolean presence_sub_request_exists(const char * const bare_jid) diff --git a/theme_template b/theme_template index c088e181..e2380b44 100644 --- a/theme_template +++ b/theme_template @@ -58,7 +58,7 @@ time= privileges= presence= intype= -otr.warn= +enc.warn= resource.title= resource.message= statuses.console= @@ -72,3 +72,4 @@ roster.size= occupants= occupants.size= occupants.jid= +wins.autotidy= diff --git a/themes/boothj5 b/themes/boothj5 index 9ed3fe69..090f7bc3 100644 --- a/themes/boothj5 +++ b/themes/boothj5 @@ -17,7 +17,7 @@ statusbar=blue statusbar.text=bold_white statusbar.brackets=white statusbar.active=bold_cyan -statusbar.new=bold_green +statusbar.new=bold_white main.text=white main.text.me=cyan main.text.them=bold_white @@ -59,7 +59,7 @@ time.statusbar=seconds privileges=true presence=true intype=true -otr.warn=true +enc.warn=true resource.title=true resource.message=true statuses.console=all @@ -73,3 +73,4 @@ roster.size=25 occupants=true occupants.size=15 occupants.jid=true +wins.autotidy=true diff --git a/themes/complex b/themes/complex index a5510baa..46e926c2 100644 --- a/themes/complex +++ b/themes/complex @@ -21,4 +21,4 @@ roster.size=25 privileges=true presence=true intype=true -otr.warn=true +enc.warn=true diff --git a/themes/simple b/themes/simple index 2885db12..e873723b 100644 --- a/themes/simple +++ b/themes/simple @@ -20,4 +20,5 @@ roster.size=25 privileges=false presence=false intype=false -otr.warn=false +enc.warn=false +wins.autotidy=false |