111 Commits
v0.9 ... v0.9.2

Author SHA1 Message Date
312d0783cf Bump version 2015-12-31 23:46:17 +01:00
8564297e2a degesch: fix segfault on /quit under libedit 2015-12-31 23:42:43 +01:00
c015835d3a Update README 2015-12-31 05:07:28 +01:00
1d14abd875 Cleanup 2015-12-31 05:07:28 +01:00
74bed4bc02 degesch: Alt-Tab switch to the last buffer 2015-12-31 05:07:28 +01:00
8f229f41e1 degesch: avoid fileno() after fork()
It's not guaranteed to be async-signal-safe, which may matter once
we start using threads. And it's also cleaner to just pass the FD.
2015-12-31 05:07:28 +01:00
b4d6decc06 degesch: typos 2015-12-31 03:57:09 +01:00
04f87b7587 degesch: enable configuration in Lua plugins 2015-12-28 04:08:45 +01:00
b7dd384048 degesch: little step towards localisation
We don't use LC_MESSAGES, though, so it doesn't really matter as of now.

liberty currently isn't prepared for non-ASCII errors or filenames,
and just silently expects everything to be in the same all-compatible
encoding.  degesch further expects the encoding to be UTF-8.

All strings should ideally be converted to UTF-8 as soon as possible.
2015-12-25 21:36:56 +01:00
e101afab38 degesch: allow launching an editor for input
Useful for editing multiline text (such as making it single-line).

Some refactoring and cleanup.
2015-12-25 05:20:50 +01:00
37e9165548 degesch: better handling of terminal suspension 2015-12-25 05:03:02 +01:00
25bb7a978d degesch: refactoring 2015-12-25 05:02:58 +01:00
7d531a9bbf Bump liberty 2015-12-13 22:44:27 +01:00
1c009f394a Bump liberty 2015-12-11 03:01:25 +01:00
649ea0baf7 Refactor config schema initialization
Now the configuration module seems to be fit for inclusion in liberty.
2015-12-11 02:27:29 +01:00
de942e40ac Cleanup 2015-12-11 02:27:29 +01:00
5d3c2bea95 utm-filter.lua: filter out "gclid" as well 2015-12-10 21:48:04 +01:00
620418fa3b degesch: add a test for configuration 2015-12-10 21:26:17 +01:00
28e4bc1399 degesch: add more tests, bump liberty
The UTF-8 common prefix test discovered a bug in UTF-8 parsing.

Made $[1-9] in aliases insert nothing if there's no argument at that index.
2015-12-10 20:04:26 +01:00
a0becea2fc Update Travis CI and bump CMake 2015-12-09 21:07:01 +01:00
6a72c7382b Fix Travis CI 2015-12-09 21:07:01 +01:00
86d7b7aed5 degesch: add a unit test for message wrapping algo 2015-12-09 21:07:01 +01:00
07201b7bdc degesch: compactify word wrapping algorithm 2015-12-08 23:24:40 +01:00
2ae916fc1a degesch: clarify text wrapping algorithm 2015-12-08 22:11:11 +01:00
2ba8908024 degesch: fix timer hook resource leak 2015-11-29 17:55:35 +01:00
4a287a724e degesch: Lua: add a "server" property to buffers 2015-11-24 21:52:31 +01:00
87e1236b30 degesch: Lua: add a "buffer" property to servers 2015-11-24 21:42:08 +01:00
0044672b85 ping-timeout.lua: simplify 2015-11-24 20:45:51 +01:00
e921a619b0 degesch: readline fixups
When a new buffer was created automatically (channel was joined),
we didn't bother to erase the current line buffer.
2015-11-24 03:04:14 +01:00
25282cfe23 degesch: fix a segfault-inducing typo in hooks 2015-11-24 02:32:11 +01:00
8187bedcb6 degesch: add a URL cleaning Lua plugin 2015-11-24 02:26:07 +01:00
79140c3abc degesch: make auto-away less spammy 2015-11-23 08:33:58 +01:00
4d11be0b85 degesch: implement auto-away 2015-11-22 23:12:18 +01:00
b746c014aa Fix searching for Lua 5.3 on OpenBSD 2015-11-22 19:10:59 +01:00
f69edd6606 degesch: optimize prompt changes
We used to do lots of unnecessary redisplays.
2015-11-22 17:49:27 +01:00
385de6f4fe degesch: better terminal suspension
Don't print date changes while something else is using the terminal.
2015-11-22 16:43:21 +01:00
0fdffa0e50 degesch: fix hook debug logs
Obviously we can receive back the same pointer with different contents.

I just didn't think of that.
2015-11-22 03:01:38 +01:00
36c59ff375 Enable TCP_NODELAY 2015-11-22 02:12:52 +01:00
71f3532e04 degesch: add the first Lua plugin to distribution
This required separate plugin directories for both pluginized executables.
2015-11-21 22:47:52 +01:00
d135728424 degesch: pop() the Lua error in timer dispatch 2015-11-21 21:29:56 +01:00
2185af0b7d Update README 2015-11-21 21:23:59 +01:00
f22764ec56 degesch: update dependencies in README 2015-11-21 19:50:37 +01:00
02c7c6dcd6 degesch: export timers to Lua 2015-11-21 19:48:15 +01:00
364eb009ca degesch: hook implementation cleanup 2015-11-21 19:00:56 +01:00
d4cbc576e2 degesch: typos, cleanups 2015-11-21 19:00:56 +01:00
9bb9c9868c degesch: advertise Lua support 2015-11-21 14:09:34 +01:00
cd8e3d6d41 degesch: make Ctrl-L also fix window size 2015-11-21 14:09:34 +01:00
fa965a85e4 degesch: make /buffer with no arguments print list 2015-11-21 14:09:34 +01:00
59a4c356dd degesch: export input and IRC hooks 2015-11-21 14:09:34 +01:00
c912726f49 degesch: add ability to hook IRC and user input
We're going to make this available to the Lua API soon.
2015-11-21 14:09:34 +01:00
fbfe0ba18a degesch: add a stubbed Lua plugin loader 2015-11-21 14:09:33 +01:00
5ee210a5b7 degesch: stubplement plugins 2015-11-21 14:09:33 +01:00
5d55d7f6de degesch: refcountify "struct {buffer,server}" 2015-11-19 19:11:35 +01:00
b952fc1f6d degesch: extend weak pointers 2015-11-18 23:03:21 +01:00
89065e4d34 degesch: fix highlights 2015-11-17 00:06:48 +01:00
bc4b8ee19f Update NEWS 2015-11-15 16:32:52 +01:00
281ef2e93e degesch: split input text at newlines
This makes pasting multiline text possible again.
2015-11-15 15:56:33 +01:00
9b22d72fd1 Extend split_str() for multiple split chars 2015-11-15 15:56:10 +01:00
f11635ed7f degesch: better SIGTSTP handling 2015-11-15 15:36:03 +01:00
a1e47ca4c9 degesch: cleanup
Unnecessary oneliner function.
2015-11-15 01:48:10 +01:00
6c7a2ce3c8 degesch: unseen PMs show up as highlights
I used to miss them.
2015-11-15 01:43:00 +01:00
153d8c55d9 degesch: don't spam with all unseen messages
On high-traffic channels, it has shown to take quite some time.
2015-11-15 01:32:49 +01:00
d14bc2df53 degesch: have just one input buffer 2015-11-15 01:23:32 +01:00
d8299a1231 degesch: enable and use bracketed paste mode
urxvt, xterm and maybe others support quoting text pasted by the user
from clipboard, which prevents leading tabs from changing into
highlights.

The handling isn't perfect so far, just wrong in a different way, as
we mishandle newlines.
2015-11-15 01:07:12 +01:00
465c2e4082 degesch: mv input_insert{_c,}() 2015-11-15 01:07:09 +01:00
2a97c01215 degesch: make the libedit backend work again 2015-11-15 01:07:05 +01:00
152ba0847d Add a CMake target for clang-tidy 2015-11-13 09:22:48 +01:00
fe88e30bf5 degesch: fix beeping on "unimportant" PM events
Which in practice means stop beeping on quits in PM buffers.
2015-10-30 23:49:43 +01:00
a8a852d4b3 degesch: fix reconnect delays 2015-10-28 03:46:41 +01:00
e41f503202 degesch: add an /oper command
Mostly just because bitlbee suggested it to me and it didn't work.
2015-10-01 21:39:47 +02:00
762aaffecf degesch: make text attributes toggle formatting
Instead of just setting it on.

Fixes bitlbee.
2015-10-01 21:06:34 +02:00
99ac971b66 Little fixes to the README
Finally learned how to use this asciidoc{,tor} thing.
2015-09-27 01:12:03 +02:00
e75e840346 Convert README to AsciiDoc
So that it looks nice on GitHub.

Neither Markdown nor RST worked for me.
2015-09-27 00:38:20 +02:00
3d59a94554 Fix build instructions in README 2015-09-27 00:19:42 +02:00
f42ecedd42 Update release date 2015-09-25 17:12:29 +02:00
63a7980329 Bump version, add NEWS 2015-09-24 16:17:40 +02:00
bc54bf520d degesch: add Meta-H to open the full log file
As opposed to just the visible backlog.
2015-09-24 16:16:31 +02:00
11aaf1b325 degesch: fix logging of outgoing status messages
"/msg @#test test" would log "MSG(): test"
2015-09-24 15:41:39 +02:00
5ca07656a1 degesch: fix handling of status messages
That is, messages using the STATUSMSG feature.
2015-09-24 15:41:39 +02:00
f20c6fb28e degesch: fix logging of RPL_INVITING 2015-09-24 15:41:39 +02:00
1613e75a48 mv 'struct config_item'{_,}
Finally we can get rid of the trailing underscore.
2015-08-17 00:13:05 +02:00
abd892cbd7 Bump liberty 2015-08-17 00:13:05 +02:00
4ae95be9db degesch: add self to completion in server buffers 2015-08-13 00:23:56 +02:00
328bf9af1e degesch: display ERROR messages
So that the user knows he was killed.
2015-08-12 23:21:11 +02:00
ce83f8244c degesch: don't ignore data right before an EOF 2015-08-12 23:20:46 +02:00
8a8ff11887 degesch: don't use black for nicks on 256-color
Except for self.
2015-08-11 21:38:28 +02:00
131aee6f08 degesch: update comments 2015-08-10 23:24:57 +02:00
07f6d0b350 degesch: enable bright backgrounds on 8-color terms 2015-08-10 23:07:05 +02:00
1cc8656368 degesch: precompute the filtered color cube 2015-08-10 07:53:03 +02:00
4c81112840 degesch: show CTCPs to channels as such 2015-08-10 07:39:43 +02:00
5dda5661ae degesch: send after-connect joins more cleverly 2015-08-10 07:35:42 +02:00
628facf286 degesch: properly flush the read marker 2015-08-10 00:09:43 +02:00
7225b68f74 degesch: safer defaults for backlog helper 2015-08-09 15:05:49 +02:00
e188de5501 degesch: don't show joins etc. as new activity
It's mostly just spam that shouldn't get your attention.
2015-08-08 21:19:25 +02:00
cdf6544c94 degesch: use formatting in the backlog
It's a rather crude solution to just pipe the raw terminfo strings
to less but hey, it works.
2015-08-08 20:44:24 +02:00
a28528d260 degesch: add backlog/scrollback functionality
Finally!  I went with possibly the simplest solution, which is to
run less, instead of badly reimplementing its functionality.
2015-08-08 20:44:24 +02:00
27f185e8aa Update README 2015-08-07 00:14:44 +02:00
d207c90577 degesch: properly flush formatting resets 2015-08-06 23:58:42 +02:00
2afc9f99c3 degesch: better name resolution failure messages 2015-08-06 23:53:00 +02:00
4ab247ead0 degesch: fix /server usage 2015-08-06 23:27:35 +02:00
1dd464f35c degesch; fix handling of CTCP requests 2015-08-06 23:23:56 +02:00
955b3728a3 degesch: don't send PART on /close when not joined 2015-08-06 21:58:34 +02:00
aa77bc41d0 Fix library searching 2015-08-06 21:58:13 +02:00
5b208547c4 Bump liberty
Pulling in kqueue support.
2015-08-06 21:38:36 +02:00
c8890953b3 SOCKS: make use of the str_pack_* API
I forgot I had it.
2015-08-06 21:32:01 +02:00
cfc78ffdf0 Fix OpenBSD build 2015-07-30 18:29:12 +02:00
637a3d2bf7 More SSL -> TLS renaming 2015-07-28 20:31:42 +02:00
a912b3f28c degesch: use hopefully better colors for nicks
- exclude white from the 16-color range
 - use colors from the 256-color cube when available
2015-07-27 01:29:44 +02:00
27cd8b3a63 degesch: fix memory leak 2015-07-27 00:08:28 +02:00
2bde385dc7 degesch: order the nicknames in /names 2015-07-26 23:27:39 +02:00
74c9759932 degesch: make showing all prefixes optional 2015-07-26 22:44:34 +02:00
17 changed files with 3203 additions and 1930 deletions

View File

@@ -1,3 +1,5 @@
sudo: required
dist: trusty
language: c language: c
notifications: notifications:
irc: irc:
@@ -25,15 +27,18 @@ compiler:
before_install: before_install:
# We need this PPA for a recent version of libedit # We need this PPA for a recent version of libedit
- sudo add-apt-repository ppa:ondrej/php5-5.6 -y - sudo add-apt-repository ppa:ondrej/php5-5.6 -y
# We need this PPA for Lua 5.3
- sudo add-apt-repository ppa:vbernat/haproxy-1.6 -y
- sudo apt-get update -qq - sudo apt-get update -qq
install: install:
- sudo apt-get install -y help2man libedit-dev expect - sudo apt-get install -y libncursesw5-dev libreadline-dev libedit-dev
liblua5.3-dev help2man expect
before_script: before_script:
- mkdir build - mkdir build
- cd build - cd build
script: script:
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr - cmake .. -DCMAKE_INSTALL_PREFIX=/usr
-DWANT_READLINE=$readline -DWANT_LIBEDIT=$libedit -DWANT_READLINE=$readline -DWANT_LIBEDIT=$libedit
- make - make all test
- cpack -G DEB - cpack -G DEB
- ../test - ../test

View File

@@ -1,5 +1,5 @@
project (uirc3 C) project (uirc3 C)
cmake_minimum_required (VERSION 2.8.5) cmake_minimum_required (VERSION 2.8.11)
# Options # Options
option (WANT_READLINE "Use GNU Readline for the UI (better)" ON) option (WANT_READLINE "Use GNU Readline for the UI (better)" ON)
@@ -14,7 +14,7 @@ endif ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUC)
# Version # Version
set (project_VERSION_MAJOR "0") set (project_VERSION_MAJOR "0")
set (project_VERSION_MINOR "9") set (project_VERSION_MINOR "9")
set (project_VERSION_PATCH "0") set (project_VERSION_PATCH "2")
set (project_VERSION "${project_VERSION_MAJOR}") set (project_VERSION "${project_VERSION_MAJOR}")
set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}") set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}")
@@ -27,18 +27,40 @@ pkg_check_modules (libssl REQUIRED libssl libcrypto)
pkg_check_modules (ncursesw ncursesw) pkg_check_modules (ncursesw ncursesw)
if ("${CMAKE_SYSTEM_NAME}" MATCHES "BSD") if ("${CMAKE_SYSTEM_NAME}" MATCHES "BSD")
# iconv() doesn't have to be present in libc include_directories(/usr/local/include)
# FIXME: detect if we need the library independently on the platform link_directories(/usr/local/lib)
list (APPEND project_libraries iconv) # Need this for SIGWINCH in FreeBSD and OpenBSD respectively;
# Need this for SIGWINCH; our POSIX version macros make it undefined # our POSIX version macros make it undefined
add_definitions (-D__BSD_VISIBLE=1) add_definitions (-D__BSD_VISIBLE=1 -D_BSD_SOURCE=1)
endif ("${CMAKE_SYSTEM_NAME}" MATCHES "BSD") endif ("${CMAKE_SYSTEM_NAME}" MATCHES "BSD")
list (APPEND project_libraries ${libssl_LIBRARIES})
include_directories (${libssl_INCLUDE_DIRS})
link_directories (${libssl_LIBRARY_DIRS})
# FIXME: other Lua versions may be acceptable, don't know yet
pkg_search_module (lua lua53 lua5.3 lua-5.3 lua>=5.3)
option (WITH_LUA "Enable experimental support for Lua plugins" ${lua_FOUND})
if (WITH_LUA)
if (NOT lua_FOUND)
message (FATAL_ERROR "Lua library not found")
endif (NOT lua_FOUND)
list (APPEND project_libraries ${lua_LIBRARIES})
include_directories (${lua_INCLUDE_DIRS})
link_directories (${lua_LIBRARY_DIRS})
endif (WITH_LUA)
# -lpthread is only there for debugging (gdb & errno) # -lpthread is only there for debugging (gdb & errno)
# -lrt is only for glibc < 2.17 # -lrt is only for glibc < 2.17
list (APPEND project_libraries ${libssl_LIBRARIES} rt pthread) # -liconv may or may not be a part of libc
include_directories (${libssl_INCLUDE_DIRS}) foreach (extra iconv rt pthread)
link_directories (${libssl_LIBRARY_DIRS}) find_library (extra_lib_${extra} ${extra})
if (extra_lib_${extra})
list (APPEND project_libraries ${extra})
endif (extra_lib_${extra})
endforeach (extra)
if (ncursesw_FOUND) if (ncursesw_FOUND)
list (APPEND project_libraries ${ncursesw_LIBRARIES}) list (APPEND project_libraries ${ncursesw_LIBRARIES})
@@ -53,7 +75,13 @@ endif (ncursesw_FOUND)
if ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT)) if ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT))
message (SEND_ERROR "You have to choose either GNU Readline or libedit") message (SEND_ERROR "You have to choose either GNU Readline or libedit")
elseif (WANT_READLINE) elseif (WANT_READLINE)
list (APPEND project_libraries readline) # OpenBSD's default readline is too old
if ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
include_directories (/usr/local/include/ereadline)
list (APPEND project_libraries ereadline)
else ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
list (APPEND project_libraries readline)
endif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
elseif (WANT_LIBEDIT) elseif (WANT_LIBEDIT)
pkg_check_modules (libedit REQUIRED libedit) pkg_check_modules (libedit REQUIRED libedit)
list (APPEND project_libraries ${libedit_LIBRARIES}) list (APPEND project_libraries ${libedit_LIBRARIES})
@@ -61,16 +89,13 @@ elseif (WANT_LIBEDIT)
endif ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT)) endif ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT))
# Generate a configuration file # Generate a configuration file
if (WANT_READLINE) set (HAVE_READLINE "${WANT_READLINE}")
set (HAVE_READLINE 1) set (HAVE_EDITLINE "${WANT_LIBEDIT}")
endif (WANT_READLINE) set (HAVE_LUA "${WITH_LUA}")
if (WANT_LIBEDIT)
set (HAVE_EDITLINE 1)
endif (WANT_LIBEDIT)
include (GNUInstallDirs) include (GNUInstallDirs)
set (plugin_dir ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}) # ZyklonB is currently an odd duck but degesch follows normal XDG rules
set (zyklonb_plugin_dir ${CMAKE_INSTALL_LIBDIR}/zyklonb/plugins)
configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h) configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
@@ -97,13 +122,44 @@ target_link_libraries (degesch ${project_libraries})
add_executable (kike kike.c kike-replies.c ${common_sources} ${common_headers}) add_executable (kike kike.c kike-replies.c ${common_sources} ${common_headers})
target_link_libraries (kike ${project_libraries}) target_link_libraries (kike ${project_libraries})
# Tests
function (make_tests_for target_name)
get_target_property (sources ${target_name} SOURCES)
get_target_property (libraries ${target_name} LINK_LIBRARIES)
set (test test-${target_name})
add_executable (${test} ${sources})
target_link_libraries (${test} ${libraries})
add_test (NAME ${test} COMMAND ${test})
set_target_properties (${test} PROPERTIES COMPILE_DEFINITIONS TESTING)
endfunction (make_tests_for)
include (CTest)
if (BUILD_TESTING)
make_tests_for (degesch)
endif (BUILD_TESTING)
# Various clang-based diagnostics, loads of fake positives and spam
file (GLOB clang_tidy_sources *.c)
set (clang_tidy_checks misc-* readability-*
-readability-braces-around-statements
-readability-named-parameter)
string (REPLACE ";" "," clang_tidy_checks "${clang_tidy_checks}")
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_custom_target (clang-tidy
COMMAND clang-tidy -p ${PROJECT_BINARY_DIR} -checks=${clang_tidy_checks}
${clang_tidy_sources} 1>&2
USES_TERMINAL
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
# Installation # Installation
install (TARGETS zyklonb degesch kike DESTINATION ${CMAKE_INSTALL_BINDIR}) install (TARGETS zyklonb degesch kike DESTINATION ${CMAKE_INSTALL_BINDIR})
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install (DIRECTORY plugins/zyklonb/
foreach (plugin coin eval script youtube ${plugins}) DESTINATION ${zyklonb_plugin_dir} USE_SOURCE_PERMISSIONS)
install (FILES plugins/${plugin} DESTINATION ${plugin_dir}) install (DIRECTORY plugins/degesch/
endforeach (plugin) DESTINATION ${CMAKE_INSTALL_DATADIR}/degesch/plugins)
# Generate documentation from program help # Generate documentation from program help
find_program (HELP2MAN_EXECUTABLE help2man) find_program (HELP2MAN_EXECUTABLE help2man)

57
NEWS Normal file
View File

@@ -0,0 +1,57 @@
0.9.2 (2015-12-31)
* degesch: added rudimentary support for Lua scripting
* degesch: added detection of pasting, so that it doesn't trigger other
keyboard shortcuts, such as for autocomplete
* degesch: added auto-away capability
* degesch: added an /oper command
* degesch: libedit backend works again
* degesch: added capability to edit the input line using VISUAL/EDITOR
* degesch: added Meta-Tab to switch to the last used buffer
* degesch: correctly respond to stopping and resuming (SIGTSTP)
* degesch: fixed decoding of text formatting
* degesch: unseen PMs now show up as highlights
* degesch: various bugfixes
0.9.1 (2015-09-25)
* All "ssl" options have been renamed to "tls"
* The project now builds on OpenBSD
* Pulled in kqueue support
* degesch: added backlog/scrollback functionality using less(1)
* degesch: made showing the entire set of channel mode user prefixes optional
* degesch: nicknames in /names are now ordered
* degesch: nicknames now use the 256-color terminal palette if available
* degesch: now we skip entries in the "addresses" list that can't be resolved
to an address, along with displaying a more helpful message
* degesch: joins, parts, nick changes and quits don't count as new buffer
activity anymore
* degesch: added Meta-H to open the full log file
* degesch: various bugfixes and little improvements
0.9.0 (2015-07-23)
* Initial release

View File

@@ -1,43 +1,54 @@
uirc3 uirc3
===== =====
:compact-option:
The unethical IRC trinity. This project consists of an experimental IRC client, The unethical IRC trinity. This project consists of an experimental IRC client,
daemon, and bot. It's all you're ever going to need for chatting. daemon, and bot. It's all you're ever going to need for chatting, as long as
you can make do with minimalist software.
All of them have these potentially interesting properties: All of them have these potentially interesting properties:
- full IPv6 support - full IPv6 support
- TLS support, including client certificates - TLS support, including client certificates
- minimal dependencies - minimal dependencies
- very compact and easy to hack on - compact and arguably easy to hack on
- permissive license - permissive license
degesch degesch
------- -------
The IRC client. It is largely defined by being built on top of GNU Readline. The IRC client. It is largely defined by being built on top of GNU Readline
Its interface should however feel familiar for weechat or irssi users. that has been hacked to death. Its interface should feel somewhat familiar for
weechat or irssi users.
This is the youngest and largest application within the project. It has most of This is the largest application within the project. It has most of the stuff
the stuff you'd expect of an IRC client, such as being able to set up multiple you'd expect of an IRC client, such as being able to set up multiple servers,
servers, powerful configuration system, integrated help, mIRC text formatting, a powerful configuration system, integrated help, text formatting, CTCP queries,
CTCP queries, automatic splitting of overlong messages, autocomplete, logging automatic splitting of overlong messages, autocomplete, logging to file,
to file, and command aliases. auto-away, command aliases and rudimentary support for Lua scripting.
kike kike
---- ----
The IRC daemon. It is designed to be used as a regular user application rather The IRC daemon. It is designed to be used as a regular user application rather
than a system-wide daemon. If all you want is a decent, minimal IRCd for than a system-wide daemon. If all you want is a decent, minimal IRCd for
a small network of respectful users (or bots), or testing, this one will do it. testing purposes or a small network of respectful users (or bots), this one will
do it just fine.
Notable features: Notable features:
- TLS autodetection (why doesn't everyone have this?)
- IRCop authentication through TLS client certificates - TLS autodetection (why doesn't everyone have this?), using secure defaults
- epoll support on Linux; it should be able to handle quite a number of users - IRCop authentication via TLS client certificates
- epoll/kqueue support; this means that it should be able to handle quite
a number of concurrent user connections
- partial IRCv3 support - partial IRCv3 support
Not supported: Not supported:
- server linking (which also means no services); I consider existing protocols - server linking (which also means no services); I consider existing protocols
for this purpose ugly and tricky to implement correctly for this purpose ugly and tricky to implement correctly; I've also found no
- online changes to configuration; the config system from degesch could be used use for this feature yet
- limits of almost any kind, just connections and mode +l - online changes to configuration; the configuration system from degesch could
be used to implement this feature if needed
- limits of almost any kind, just connections and mode `+l`
ZyklonB ZyklonB
------- -------
@@ -45,64 +56,66 @@ The IRC bot. It builds upon the concept of my other VitaminA IRC bot. The main
characteristic of these two bots is that they run plugins as coprocesses, which characteristic of these two bots is that they run plugins as coprocesses, which
allows for enhanced reliability and programming language freedom. allows for enhanced reliability and programming language freedom.
While originally intended to be a simple C99 rewrite of the original bot, which While originally intended to be a simple rewrite of the original AWK bot in C,
was written in the GNU dialect of AWK, it fairly quickly became a playground it fairly quickly became a playground, and it eventually got me into writing
where I added everything that seemed nice, and it eventually got me into writing the rest of the package.
the rest of this package.
Notable features: It survives crashes, server disconnects and timeouts, and also has native SOCKS
- resilient against crashes, server disconnects and timeouts support (even though socksify can add that easily to any program).
- SOCKS support (even though socksify can add that easily to any program)
Building Building
-------- --------
Build dependencies: CMake, pkg-config, help2man, awk, sh, liberty (included) Build dependencies: CMake, pkg-config, help2man, awk, sh, liberty (included) +
Runtime dependencies: openssl, curses (degesch), Runtime dependencies: openssl, curses (degesch),
readline or libedit >= 2013-07-12 (degesch) readline >= 6.0 or libedit >= 2013-07-12 (degesch),
lua >= 5.3 (degesch, optional)
$ git clone https://github.com/pjanouch/uirc3.git $ git clone --recursive https://github.com/pjanouch/uirc3.git
$ git submodule init $ mkdir uirc3/build
$ git submodule update $ cd uirc3/build
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug \ $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug \
-DWANT_READLINE=ON -DWANT_LIBEDIT=OFF -DWANT_READLINE=ON -DWANT_LIBEDIT=OFF -DWANT_LUA=ON
$ make $ make
To install the application, you can do either the usual: To install the application, you can do either the usual:
# make install # make install
Or you can try telling CMake to make a package for you. For Debian it is: Or you can try telling CMake to make a package for you. For Debian it is:
$ cpack -G DEB $ cpack -G DEB
# dpkg -i uirc3-*.deb # dpkg -i uirc3-*.deb
Note that for versions of CMake before 2.8.9, you need to prefix cpack with Note that for versions of CMake before 2.8.9, you need to prefix `cpack` with
`fakeroot' or file ownership will end up wrong. `fakeroot` or file ownership will end up wrong.
Running Running
------- -------
`degesch' has in-program configuration. Just run it and read the instructions. 'degesch' has in-program configuration. Just run it and read the instructions.
For the rest you might want to generate a configuration file: For the rest you might want to generate a configuration file:
$ zyklonb --write-default-config $ zyklonb --write-default-config
$ kike --write-default-config $ kike --write-default-config
After making any necessary edits to the file (there are comments to aid you in After making any necessary edits to the file (there are comments to aid you in
doing that), simply run the appropriate program with no arguments: doing that), simply run the appropriate program with no arguments:
$ zyklonb $ zyklonb
$ kike $ kike
`ZyklonB' stays running in the foreground, therefore I recommend launching it 'ZyklonB' stays running in the foreground, therefore I recommend launching it
inside a Screen or tmux session. inside a Screen or tmux session.
`kike', on the other hand, immediately forks into the background. Use the PID 'kike', on the other hand, immediately forks into the background. Use the PID
file or something like `killall' if you want to terminate it. You can run it file or something like `killall` if you want to terminate it. You can run it
as a `forking' type systemd user service. as a `forking` type systemd user service.
Client Certificates Client Certificates
------------------- -------------------
`kike' uses SHA1 fingerprints of TLS client certificates to authenticate users. 'kike' uses SHA1 fingerprints of TLS client certificates to authenticate users.
To get the fingerprint from a certificate file in the required form, use: To get the fingerprint from a certificate file in the required form, use:
$ openssl x509 -in public.pem -outform DER | sha1sum $ openssl x509 -in public.pem -outform DER | sha1sum
Contributing and Support Contributing and Support
@@ -118,7 +131,7 @@ And no, I'm not going to change the names.
License License
------- -------
`uirc3' is written by Přemysl Janouch <p.janouch@gmail.com>. 'uirc3' is written by Přemysl Janouch <p.janouch@gmail.com>.
You may use the software under the terms of the ISC license, the text of which You may use the software under the terms of the ISC license, the text of which
is included within the package, or, at your option, you may relicense the work is included within the package, or, at your option, you may relicense the work

1430
common.c

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,10 @@
#define CONFIG_H #define CONFIG_H
#define PROGRAM_VERSION "${project_VERSION}" #define PROGRAM_VERSION "${project_VERSION}"
#define PLUGIN_DIR "${CMAKE_INSTALL_PREFIX}/${plugin_dir}" #define ZYKLONB_PLUGIN_DIR "${CMAKE_INSTALL_PREFIX}/${zyklonb_plugin_dir}"
#cmakedefine HAVE_READLINE #cmakedefine HAVE_READLINE
#cmakedefine HAVE_EDITLINE #cmakedefine HAVE_EDITLINE
#cmakedefine HAVE_LUA
#endif // ! CONFIG_H #endif // ! CONFIG_H

3235
degesch.c

File diff suppressed because it is too large Load Diff

61
kike.c
View File

@@ -34,7 +34,7 @@ enum { PIPE_READ, PIPE_WRITE };
// Just get rid of the crappiest ciphers available by default // Just get rid of the crappiest ciphers available by default
#define DEFAULT_CIPHERS "DEFAULT:!MEDIUM:!LOW" #define DEFAULT_CIPHERS "DEFAULT:!MEDIUM:!LOW"
static struct config_item g_config_table[] = static struct simple_config_item g_config_table[] =
{ {
{ "pid_file", NULL, "Path or name of the PID file" }, { "pid_file", NULL, "Path or name of the PID file" },
{ "server_name", NULL, "Server name" }, { "server_name", NULL, "Server name" },
@@ -44,9 +44,9 @@ static struct config_item g_config_table[] =
{ "bind_host", NULL, "Address of the IRC server" }, { "bind_host", NULL, "Address of the IRC server" },
{ "bind_port", "6667", "Port of the IRC server" }, { "bind_port", "6667", "Port of the IRC server" },
{ "ssl_cert", NULL, "Server TLS certificate (PEM)" }, { "tls_cert", NULL, "Server TLS certificate (PEM)" },
{ "ssl_key", NULL, "Server TLS private key (PEM)" }, { "tls_key", NULL, "Server TLS private key (PEM)" },
{ "ssl_ciphers", DEFAULT_CIPHERS, "OpenSSL cipher list" }, { "tls_ciphers", DEFAULT_CIPHERS, "OpenSSL cipher list" },
{ "operators", NULL, "IRCop TLS cert. fingerprints" }, { "operators", NULL, "IRCop TLS cert. fingerprints" },
@@ -666,7 +666,7 @@ server_context_init (struct server_context *self)
str_map_init (&self->config); str_map_init (&self->config);
self->config.free = free; self->config.free = free;
load_config_defaults (&self->config, g_config_table); simple_config_load_defaults (&self->config, g_config_table);
str_vector_init (&self->motd); str_vector_init (&self->motd);
self->catalog = (nl_catd) -1; self->catalog = (nl_catd) -1;
@@ -1784,7 +1784,7 @@ mode_processor_do_user (struct mode_processor *self, int mode)
target, self->channel->name); target, self->channel->name);
else if (irc_modify_mode (&target_user->modes, mode, self->adding)) else if (irc_modify_mode (&target_user->modes, mode, self->adding))
{ {
str_append_c (self->output, self->mode_char); \ str_append_c (self->output, self->mode_char);
str_vector_add (self->output_params, client->nickname); str_vector_add (self->output_params, client->nickname);
} }
} }
@@ -3106,7 +3106,7 @@ irc_try_read (struct client *c)
} }
static bool static bool
irc_try_read_ssl (struct client *c) irc_try_read_tls (struct client *c)
{ {
if (c->ssl_tx_want_rx) if (c->ssl_tx_want_rx)
return true; return true;
@@ -3174,7 +3174,7 @@ irc_try_write (struct client *c)
} }
static bool static bool
irc_try_write_ssl (struct client *c) irc_try_write_tls (struct client *c)
{ {
if (c->ssl_rx_want_tx) if (c->ssl_rx_want_tx)
return true; return true;
@@ -3212,7 +3212,7 @@ irc_try_write_ssl (struct client *c)
} }
static bool static bool
irc_autodetect_ssl (struct client *c) irc_autodetect_tls (struct client *c)
{ {
// Trivial SSL/TLS autodetection. The first block of data returned by // Trivial SSL/TLS autodetection. The first block of data returned by
// recv() must be at least three bytes long for this to work reliably, // recv() must be at least three bytes long for this to work reliably,
@@ -3251,7 +3251,7 @@ start:
} }
static bool static bool
client_initialize_ssl (struct client *c) client_initialize_tls (struct client *c)
{ {
const char *error_info = NULL; const char *error_info = NULL;
if (!c->ctx->ssl_ctx) if (!c->ctx->ssl_ctx)
@@ -3288,7 +3288,7 @@ on_client_ready (const struct pollfd *pfd, void *user_data)
if (!c->initialized) if (!c->initialized)
{ {
hard_assert (pfd->events == POLLIN); hard_assert (pfd->events == POLLIN);
if (irc_autodetect_ssl (c) && !client_initialize_ssl (c)) if (irc_autodetect_tls (c) && !client_initialize_tls (c))
{ {
client_kill (c, NULL); client_kill (c, NULL);
return; return;
@@ -3301,7 +3301,7 @@ on_client_ready (const struct pollfd *pfd, void *user_data)
{ {
// Reads may want to write, writes may want to read, poll() may // Reads may want to write, writes may want to read, poll() may
// return unexpected things in `revents'... let's try both // return unexpected things in `revents'... let's try both
if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c)) if (!irc_try_read_tls (c) || !irc_try_write_tls (c))
return; return;
} }
else if (!irc_try_read (c) || !irc_try_write (c)) else if (!irc_try_read (c) || !irc_try_write (c))
@@ -3421,6 +3421,13 @@ irc_try_fetch_client (struct server_context *ctx, int listen_fd)
c->ping_timer.dispatcher = on_client_ping_timer; c->ping_timer.dispatcher = on_client_ping_timer;
c->ping_timer.user_data = c; c->ping_timer.user_data = c;
// A little bit questionable once the traffic gets high enough (IMO),
// but it reduces silly latencies that we don't need because we already
// do buffer our output
int yes = 1;
soft_assert (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY,
&yes, sizeof yes) != -1);
set_blocking (fd, false); set_blocking (fd, false);
client_update_poller (c, NULL); client_update_poller (c, NULL);
client_set_kill_timer (c); client_set_kill_timer (c);
@@ -3510,7 +3517,7 @@ irc_initialize_ssl_ctx (struct server_context *ctx,
SSL_CTX_set_options (ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); SSL_CTX_set_options (ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
// XXX: perhaps we should read the files ourselves for better messages // XXX: perhaps we should read the files ourselves for better messages
const char *ciphers = str_map_find (&ctx->config, "ssl_ciphers"); const char *ciphers = str_map_find (&ctx->config, "tls_ciphers");
if (!SSL_CTX_set_cipher_list (ctx->ssl_ctx, ciphers)) if (!SSL_CTX_set_cipher_list (ctx->ssl_ctx, ciphers))
error_set (e, "failed to select any cipher from the cipher list"); error_set (e, "failed to select any cipher from the cipher list");
else if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path)) else if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
@@ -3531,33 +3538,33 @@ irc_initialize_ssl_ctx (struct server_context *ctx,
} }
static bool static bool
irc_initialize_ssl (struct server_context *ctx, struct error **e) irc_initialize_tls (struct server_context *ctx, struct error **e)
{ {
const char *ssl_cert = str_map_find (&ctx->config, "ssl_cert"); const char *tls_cert = str_map_find (&ctx->config, "tls_cert");
const char *ssl_key = str_map_find (&ctx->config, "ssl_key"); const char *tls_key = str_map_find (&ctx->config, "tls_key");
// Only try to enable SSL support if the user configures it; it is not // Only try to enable SSL support if the user configures it; it is not
// a failure if no one has requested it. // a failure if no one has requested it.
if (!ssl_cert && !ssl_key) if (!tls_cert && !tls_key)
return true; return true;
if (!ssl_cert) if (!tls_cert)
error_set (e, "no TLS certificate set"); error_set (e, "no TLS certificate set");
else if (!ssl_key) else if (!tls_key)
error_set (e, "no TLS private key set"); error_set (e, "no TLS private key set");
if (!ssl_cert || !ssl_key) if (!tls_cert || !tls_key)
return false; return false;
bool result = false; bool result = false;
char *cert_path = resolve_filename char *cert_path = resolve_filename
(ssl_cert, resolve_relative_config_filename); (tls_cert, resolve_relative_config_filename);
char *key_path = resolve_filename char *key_path = resolve_filename
(ssl_key, resolve_relative_config_filename); (tls_key, resolve_relative_config_filename);
if (!cert_path) if (!cert_path)
error_set (e, "%s: %s", "cannot open file", ssl_cert); error_set (e, "%s: %s", "cannot open file", tls_cert);
else if (!key_path) else if (!key_path)
error_set (e, "%s: %s", "cannot open file", ssl_key); error_set (e, "%s: %s", "cannot open file", tls_key);
else else
result = irc_initialize_ssl_ctx (ctx, cert_path, key_path, e); result = irc_initialize_ssl_ctx (ctx, cert_path, key_path, e);
@@ -3982,7 +3989,7 @@ main (int argc, char *argv[])
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n"); printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
case 'w': case 'w':
call_write_default_config (optarg, g_config_table); call_simple_config_write_default (optarg, g_config_table);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
default: default:
print_error ("wrong options"); print_error ("wrong options");
@@ -4007,7 +4014,7 @@ main (int argc, char *argv[])
irc_register_cap_handlers (&ctx); irc_register_cap_handlers (&ctx);
struct error *e = NULL; struct error *e = NULL;
if (!read_config_file (&ctx.config, &e)) if (!simple_config_update_from_file (&ctx.config, &e))
{ {
print_error ("error loading configuration: %s", e->message); print_error ("error loading configuration: %s", e->message);
error_free (e); error_free (e);
@@ -4019,7 +4026,7 @@ main (int argc, char *argv[])
ctx.signal_event.user_data = &ctx; ctx.signal_event.user_data = &ctx;
poller_fd_set (&ctx.signal_event, POLLIN); poller_fd_set (&ctx.signal_event, POLLIN);
if (!irc_initialize_ssl (&ctx, &e) if (!irc_initialize_tls (&ctx, &e)
|| !irc_initialize_server_name (&ctx, &e) || !irc_initialize_server_name (&ctx, &e)
|| !irc_initialize_motd (&ctx, &e) || !irc_initialize_motd (&ctx, &e)
|| !irc_initialize_catalog (&ctx, &e) || !irc_initialize_catalog (&ctx, &e)

Submodule liberty updated: 02708608a9...f6d74544f8

View File

@@ -0,0 +1,33 @@
--
-- ping-timeout.lua: ping timeout readability enhancement plugin
--
-- Copyright (c) 2015, Přemysl Janouch <p.janouch@gmail.com>
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
degesch.hook_irc (function (hook, server, line)
local start, timeout =
line:match ("^(:[^ ]* QUIT :Ping timeout:) (%d+) seconds$")
if not start then
return line
end
local minutes = timeout // 60
if minutes == 0 then
return line
end
local seconds = timeout % 60
return ("%s %d minutes, %d seconds"):format (start, minutes, seconds)
end)

View File

@@ -0,0 +1,63 @@
--
-- utm-filter.lua: filter out Google Analytics bullshit from URLs
--
-- Copyright (c) 2015, Přemysl Janouch <p.janouch@gmail.com>
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- A list of useless URL parameters that don't affect page function
local banned = {
gclid = 1,
utm_source = 1,
utm_medium = 1,
utm_term = 1,
utm_content = 1,
utm_campaign = 1,
}
-- Go through a parameter list and throw out any banned elements
local do_args = function (args)
local filtered = {}
for part in args:gmatch ("[^&]+") do
if not banned[part:match ("^[^=]*")] then
table.insert (filtered, part)
end
end
return table.concat (filtered, "&")
end
-- Filter parameters in both the query and the fragment part of an URL
local do_single_url = function (url)
return url:gsub ('^([^?#]*)%?([^#]*)', function (start, query)
local clean = do_args (query)
return #clean > 0 and start .. "?" .. clean or start
end, 1):gsub ('^([^#]*)#(.*)', function (start, fragment)
local clean = do_args (fragment)
return #clean > 0 and start .. "#" .. clean or start
end, 1)
end
local do_text = function (text)
return text:gsub ('%f[%g]https?://%g+', do_single_url)
end
degesch.hook_irc (function (hook, server, line)
local start, message = line:match ("^(.* :)(.*)$")
return message and start .. do_text (message) or line
end)
degesch.hook_input (function (hook, buffer, input)
return do_text (input)
end)

View File

@@ -19,12 +19,13 @@
#include "config.h" #include "config.h"
#define PROGRAM_NAME "ZyklonB" #define PROGRAM_NAME "ZyklonB"
#define PLUGIN_DIR ZYKLONB_PLUGIN_DIR
#include "common.c" #include "common.c"
// --- Configuration (application-specific) ------------------------------------ // --- Configuration (application-specific) ------------------------------------
static struct config_item g_config_table[] = static struct simple_config_item g_config_table[] =
{ {
{ "nickname", "ZyklonB", "IRC nickname" }, { "nickname", "ZyklonB", "IRC nickname" },
{ "username", "bot", "IRC user name" }, { "username", "bot", "IRC user name" },
@@ -32,11 +33,11 @@ static struct config_item g_config_table[] =
{ "irc_host", NULL, "Address of the IRC server" }, { "irc_host", NULL, "Address of the IRC server" },
{ "irc_port", "6667", "Port of the IRC server" }, { "irc_port", "6667", "Port of the IRC server" },
{ "ssl", "off", "Whether to use SSL" }, { "tls", "off", "Whether to use TLS" },
{ "ssl_cert", NULL, "Client SSL certificate (PEM)" }, { "tls_cert", NULL, "Client TLS certificate (PEM)" },
{ "ssl_verify", "on", "Whether to verify certificates" }, { "tls_verify", "on", "Whether to verify certificates" },
{ "ssl_ca_file", NULL, "OpenSSL CA bundle file" }, { "tls_ca_file", NULL, "OpenSSL CA bundle file" },
{ "ssl_ca_path", NULL, "OpenSSL CA bundle path" }, { "tls_ca_path", NULL, "OpenSSL CA bundle path" },
{ "autojoin", NULL, "Channels to join on start" }, { "autojoin", NULL, "Channels to join on start" },
{ "reconnect", "on", "Whether to reconnect on error" }, { "reconnect", "on", "Whether to reconnect on error" },
{ "reconnect_delay", "5", "Time between reconnecting" }, { "reconnect_delay", "5", "Time between reconnecting" },
@@ -153,7 +154,7 @@ bot_context_init (struct bot_context *self)
{ {
str_map_init (&self->config); str_map_init (&self->config);
self->config.free = free; self->config.free = free;
load_config_defaults (&self->config, g_config_table); simple_config_load_defaults (&self->config, g_config_table);
self->admin_re = NULL; self->admin_re = NULL;
self->irc_fd = -1; self->irc_fd = -1;
@@ -320,7 +321,7 @@ irc_initialize_ssl_ctx (struct bot_context *ctx, struct error **e)
SSL_CTX_set_options (ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); SSL_CTX_set_options (ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
bool verify; bool verify;
if (!irc_get_boolean_from_config (ctx, "ssl_verify", &verify, e)) if (!irc_get_boolean_from_config (ctx, "tls_verify", &verify, e))
return false; return false;
SSL_CTX_set_verify (ctx->ssl_ctx, SSL_CTX_set_verify (ctx->ssl_ctx,
verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
@@ -363,7 +364,7 @@ ca_error:
} }
static bool static bool
irc_initialize_ssl (struct bot_context *ctx, struct error **e) irc_initialize_tls (struct bot_context *ctx, struct error **e)
{ {
const char *error_info = NULL; const char *error_info = NULL;
ctx->ssl_ctx = SSL_CTX_new (SSLv23_client_method ()); ctx->ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
@@ -376,17 +377,17 @@ irc_initialize_ssl (struct bot_context *ctx, struct error **e)
if (!ctx->ssl) if (!ctx->ssl)
goto error_ssl_2; goto error_ssl_2;
const char *ssl_cert = str_map_find (&ctx->config, "ssl_cert"); const char *tls_cert = str_map_find (&ctx->config, "tls_cert");
if (ssl_cert) if (tls_cert)
{ {
char *path = resolve_filename char *path = resolve_filename
(ssl_cert, resolve_relative_config_filename); (tls_cert, resolve_relative_config_filename);
if (!path) if (!path)
print_error ("%s: %s", "cannot open file", ssl_cert); print_error ("%s: %s", "cannot open file", tls_cert);
// XXX: perhaps we should read the file ourselves for better messages // XXX: perhaps we should read the file ourselves for better messages
else if (!SSL_use_certificate_file (ctx->ssl, path, SSL_FILETYPE_PEM) else if (!SSL_use_certificate_file (ctx->ssl, path, SSL_FILETYPE_PEM)
|| !SSL_use_PrivateKey_file (ctx->ssl, path, SSL_FILETYPE_PEM)) || !SSL_use_PrivateKey_file (ctx->ssl, path, SSL_FILETYPE_PEM))
print_error ("%s: %s", "setting the SSL client certificate failed", print_error ("%s: %s", "setting the TLS client certificate failed",
ERR_error_string (ERR_get_error (), NULL)); ERR_error_string (ERR_get_error (), NULL));
free (path); free (path);
} }
@@ -418,7 +419,7 @@ error_ssl_1:
// multiple errors on the OpenSSL stack. // multiple errors on the OpenSSL stack.
if (!error_info) if (!error_info)
error_info = ERR_error_string (ERR_get_error (), NULL); error_info = ERR_error_string (ERR_get_error (), NULL);
error_set (e, "%s: %s", "could not initialize SSL", error_info); error_set (e, "%s: %s", "could not initialize TLS", error_info);
return false; return false;
} }
@@ -1444,7 +1445,7 @@ enum irc_read_result
}; };
static enum irc_read_result static enum irc_read_result
irc_fill_read_buffer_ssl (struct bot_context *ctx, struct str *buf) irc_fill_read_buffer_tls (struct bot_context *ctx, struct str *buf)
{ {
int n_read; int n_read;
start: start:
@@ -1608,7 +1609,7 @@ on_irc_readable (const struct pollfd *fd, struct bot_context *ctx)
struct str *buf = &ctx->read_buffer; struct str *buf = &ctx->read_buffer;
enum irc_read_result (*fill_buffer)(struct bot_context *, struct str *) enum irc_read_result (*fill_buffer)(struct bot_context *, struct str *)
= ctx->ssl = ctx->ssl
? irc_fill_read_buffer_ssl ? irc_fill_read_buffer_tls
: irc_fill_read_buffer; : irc_fill_read_buffer;
bool disconnected = false; bool disconnected = false;
while (true) while (true)
@@ -1754,8 +1755,8 @@ irc_connect (struct bot_context *ctx, struct error **e)
return false; return false;
} }
bool use_ssl; bool use_tls;
if (!irc_get_boolean_from_config (ctx, "ssl", &use_ssl, e)) if (!irc_get_boolean_from_config (ctx, "tls", &use_tls, e))
return false; return false;
bool connected = socks_host bool connected = socks_host
@@ -1765,7 +1766,7 @@ irc_connect (struct bot_context *ctx, struct error **e)
if (!connected) if (!connected)
return false; return false;
if (use_ssl && !irc_initialize_ssl (ctx, e)) if (use_tls && !irc_initialize_tls (ctx, e))
{ {
xclose (ctx->irc_fd); xclose (ctx->irc_fd);
ctx->irc_fd = -1; ctx->irc_fd = -1;
@@ -1965,7 +1966,7 @@ main (int argc, char *argv[])
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n"); printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
case 'w': case 'w':
call_write_default_config (optarg, g_config_table); call_simple_config_write_default (optarg, g_config_table);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
default: default:
print_error ("wrong options"); print_error ("wrong options");
@@ -1988,7 +1989,7 @@ main (int argc, char *argv[])
bot_context_init (&ctx); bot_context_init (&ctx);
struct error *e = NULL; struct error *e = NULL;
if (!read_config_file (&ctx.config, &e) if (!simple_config_update_from_file (&ctx.config, &e)
|| !setup_recovery_handler (&ctx, &e)) || !setup_recovery_handler (&ctx, &e))
{ {
print_error ("%s", e->message); print_error ("%s", e->message);