From dea6bf757aa9a875eab35b2b650412e7605f1308 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Wed, 12 Feb 2003 17:48:37 +0000 Subject: CVS moved to erdgeist.org --- Makefile | 85 +++ README | 78 +++ TODO | 26 + debian/changelog | 16 + debian/control | 12 + debian/copyright | 12 + debian/dirs | 1 + debian/docs | 2 + debian/rules | 57 ++ filters | 20 + sample-count.fmt | 73 +++ sample-erdgeist.fmt | 74 +++ sample-mAsq.fmt | 73 +++ sample-oldstyle.fmt | 73 +++ vchat-client.c | 536 ++++++++++++++++++ vchat-client.sgml | 376 +++++++++++++ vchat-commands.c | 368 +++++++++++++ vchat-config.h | 127 +++++ vchat-help.h | 66 +++ vchat-keygen | 156 ++++++ vchat-messages.h | 120 ++++ vchat-protocol.c | 1060 ++++++++++++++++++++++++++++++++++++ vchat-ui.c | 1504 +++++++++++++++++++++++++++++++++++++++++++++++++++ vchat-user.c | 374 +++++++++++++ vchat.h | 210 +++++++ vchatrc.ex | 61 +++ 26 files changed, 5560 insertions(+) create mode 100755 Makefile create mode 100755 README create mode 100755 TODO create mode 100755 debian/changelog create mode 100755 debian/control create mode 100755 debian/copyright create mode 100755 debian/dirs create mode 100755 debian/docs create mode 100755 debian/rules create mode 100755 filters create mode 100755 sample-count.fmt create mode 100755 sample-erdgeist.fmt create mode 100755 sample-mAsq.fmt create mode 100755 sample-oldstyle.fmt create mode 100755 vchat-client.c create mode 100755 vchat-client.sgml create mode 100755 vchat-commands.c create mode 100755 vchat-config.h create mode 100755 vchat-help.h create mode 100755 vchat-keygen create mode 100755 vchat-messages.h create mode 100755 vchat-protocol.c create mode 100755 vchat-ui.c create mode 100755 vchat-user.c create mode 100755 vchat.h create mode 100755 vchatrc.ex diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..9f47d28 --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +# +# vchat-client - alpha version +# + +############################################## +# configuration # +############################################## + +CFLAGS = -Wall -Os #-g -ggdb + +## use this line when you've got an readline before 4.(x|2) +#CFLAGS += -DOLDREADLINE + +## you might need one or more of these: +#CFLAGS += -I/usr/local/ssl/include -L/usr/local/ssl/lib +#CFLAGS += -I/usr/local/include -L/usr/local/lib +#CFLAGS += -I/usr/pkg/include -L/usr/pkg/lib + +## enable dietlibc +#CC = diet cc +#CFLAGS += -static + +## enable debug code +#CFLAGS += -DDEBUG + +## the install prefix best is /usr/local +PREFIX=/usr/local + +LIBS = -lncurses -lreadline -lssl -lcrypto +OBJS = vchat-client.o vchat-ui.o vchat-protocol.o vchat-user.o vchat-commands.o + + +############################################## +# general targets # +############################################## + + +all: vchat-client #vchat-client.1 + +install: vchat-client vchat-keygen vchatrc.ex + install -d $(DESTDIR)/etc + install -d $(DESTDIR)$(PREFIX)/bin + install -d $(DESTDIR)$(PREFIX)/share/man/man1 + install -m 0755 ./vchat-client $(DESTDIR)$(PREFIX)/bin + install -m 0755 ./vchat-keygen $(DESTDIR)$(PREFIX)/bin + install -m 0644 ./vchat-client.1 $(DESTDIR)$(PREFIX)/share/man/man1 + install -m 0644 ./vchatrc.ex $(DESTDIR)/etc/vchatrc + + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/vchat-client + rm -f $(DESTDIR)$(PREFIX)/bin/vchat-keygen + rm -f $(DESTDIR)$(PREFIX)/share/man/man1/vchat-client.1 + rm -f $(DESTDIR)/etc/vchatrc + + +clean: + rm -f .\#* debian/*~ *~ .*~ *.o vchat-client core *.strace \ + *.ltrace vchat.err vchat.debug* vchat-client.1 manpage.* + + +############################################## +# compile targets # +############################################## + +vchat-client: $(OBJS) + $(CC) $(CFLAGS) -o vchat-client $(OBJS) $(LIBS) + +vchat-client.o: vchat-client.c vchat-config.h Makefile + $(CC) $(CFLAGS) -o vchat-client.o -c vchat-client.c + +vchat-ui.o: vchat-ui.c vchat.h + $(CC) $(CFLAGS) -o vchat-ui.o -c vchat-ui.c + +vchat-protocol.o: vchat-protocol.c vchat-messages.h vchat.h Makefile + $(CC) $(CFLAGS) -o vchat-protocol.o -c vchat-protocol.c + +vchat-user.o: vchat-user.c vchat.h + $(CC) $(CFLAGS) -o vchat-user.o -c vchat-user.c + +vchat-commands.o: vchat-commands.c vchat.h vchat-config.h + $(CC) $(CFLAGS) -o vchat-commands.o -c vchat-commands.c + +#vchat-client.1: vchat-client.sgml +# docbook2man vchat-client.sgml diff --git a/README b/README new file mode 100755 index 0000000..4e5310f --- /dev/null +++ b/README @@ -0,0 +1,78 @@ +Hi! + +this is vchat-client, a GPLed (SSL) client for the vchat protocol. + +You can get the most recent version of vchat-client via CVS, e.g: + +cvs -d:pserver:anonymous@pulse.flatline.de:/home/cvsroot login +cvs -z3 -d:pserver:anonymous@pulse.flatline.de:/home/cvsroot co vchat-client + +(press return at password prompt) + +no autoconf yet, sorry. required libs: + +openssl (0.9.6+ preferred) +readline (4.2+ preferred) +ncurses (5.2 preferred) + +please adjust the Makefile according to your need, then run 'make' to compile, +./vchat-client to start the binary. nope, I don't have any intention to use +autoconf for this hack. + +run 'fakeroot make -f debian/rules binary' to build a debian package from the +source. + +Keyboard commands: + +^J - clear private window +^O - clear channel window +^L - redraw screen +^F - scroll window up +^B - scroll window down +^R - change active scrolling window + (see rightmost character of topic/console lines) +^T - shrink private window size +^G - grow private window size +^X - toggle private window + (pops up on private messages) +TAB - nick completion + +We also do provide a set of IRC like / - commands, there are: + +/CONFIG - not implemented yet, but will be used for configuration +/QUIT reason - issue .x reason +/USER regex - list users matching regex +/FLT C regex - add regex to filter list... read ./filters for details +/RMFLT regex|id - remove filter regex or id from filter list +/LSFLT (C) - list all filter rules (matching C) +/CLFLT (C) - remove all filter rules (matching C) +/M(SG) user msg - issue .m user msg +/LH - print hilitelist +/ME action - issue .a action + +if you want to use an own window for messages set "messages" to a value in +~./vchat/config .. + +if you want to use an SSL certificate with the default configuration you need +to put the key in ~/.vchat/key and the certificate in ~/.vchat/cert, both in +PEM format. You can generate a key and a certificate by calling vchat-keygen, +but the server you connect needs to know the anon CA provided by vchat-keygen, +which currently isn't the case anywhere. + +FILES: + + README - you're reading it. + TODO - list of things to do + vchat-client.c - main() and utility functions + vchat-config.h - configuration defaults + vchat-keygen - key generator with anon CA - server support required + vchat-messages.h - server messages <-> function correlation + vchat-protocol.c - handling of server connection & messages + vchat-ui.c - user-interface and readline handling + vchat-user.c - userlist handling + vchat.h - global structures and functions + +everything should be self-explantory, but please don't refrain to ask and/or +give bug reports, feature requests, hints and tricks, etc etc .. + + Andreas Kotes diff --git a/TODO b/TODO new file mode 100755 index 0000000..ef91851 --- /dev/null +++ b/TODO @@ -0,0 +1,26 @@ +- more documentation + +- .i with nickchanges + +- autologon +- message-window +- clock +- config-file load/safe +- saveable ignore list +- known_hosts +- bell +- signon / no longer idle notify + +- better .u parsing + +- non-blocking sends + +- url-catcher +- expire of old messages in scrollbuffer +- signon/signoff colors +- don't quit when disconnected externally + +- quitmessage (output + config) +- last line from server sometimes isn't parsed realtime +- optionally quit when idled out + diff --git a/debian/changelog b/debian/changelog new file mode 100755 index 0000000..17e8bf7 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,16 @@ +vchat-client (0.15-2) unstable; urgency=low + + * changed debian/rules using "make install" + * added manpage + + -- Hans Freitag Wed, 30 Nov 2001 14:47:54 +0200 + +vchat-client (0.15-1) unstable; urgency=low + + * Current Version + + -- Andreas Kotes Wed, 28 Nov 2001 23:28:54 +0200 + +Local variables: +mode: debian-changelog +End: diff --git a/debian/control b/debian/control new file mode 100755 index 0000000..d106fd5 --- /dev/null +++ b/debian/control @@ -0,0 +1,12 @@ +Source: vchat-client +Section: unknown +Priority: optional +Maintainer: Andreas Kotes +Build-Depends: debhelper (>> 3.0.0), libreadline4-dev, libncurses-dev, libssl-dev, docbook-to-man +Standards-Version: 3.5.2 + +Package: vchat-client +Architecture: any +Depends: ${shlibs:Depends} +Description: client for the vchat + This client uses ssl diff --git a/debian/copyright b/debian/copyright new file mode 100755 index 0000000..e066d1d --- /dev/null +++ b/debian/copyright @@ -0,0 +1,12 @@ +This package was debianized by Sebastian Klemke on +Thu, 23 Aug 2001 18:41:57 +0200. + +It was downloaded from berlin.ccc.de + +Upstream Author(s): Andreas Kotes + +Copyright: + +The client is copyright (c) 2001 Andreas Kotes, it is distributed under the +terms of the GNU General Public License, the GPL should be in +/usr/share/common-licenses/GPL on a debian system. diff --git a/debian/dirs b/debian/dirs new file mode 100755 index 0000000..e772481 --- /dev/null +++ b/debian/dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/docs b/debian/docs new file mode 100755 index 0000000..724e084 --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +README +TODO diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..389c597 --- /dev/null +++ b/debian/rules @@ -0,0 +1,57 @@ +#!/usr/bin/make -f +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +export DH_COMPAT=3 + +configure: configure-stamp +configure-stamp: + dh_testdir + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + $(MAKE) + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + -$(MAKE) clean + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + $(MAKE) install DESTDIR=$(CURDIR)/debian/vchat-client PREFIX=/usr + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installchangelogs + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/filters b/filters new file mode 100755 index 0000000..4bb8626 --- /dev/null +++ b/filters @@ -0,0 +1,20 @@ +vchat-client now offers a new model of shaping your messages: +Filters. + +Filters can have different colours, where [0-9] stand for +colour pairs, certain letters of [a-zA-Z] mean character +attributes. The two "special colours" [+-] are used for +black/whitelisting your messages, from now on called +ignore/zoom. + +While the alphanumeric colours are used to highlight the +regex associated with them, the latter case may be used +to select some of the messages from your scrollback buffer. + +This may mean - regex "all but those messages containing +the regex" or + regex "only those messages containing the +regex". + +When you have ignore regexes, zooming always supersedes +ignorance, i.e. a message that once is declared as white- +listed wont be ignored. diff --git a/sample-count.fmt b/sample-count.fmt new file mode 100755 index 0000000..019c46e --- /dev/null +++ b/sample-count.fmt @@ -0,0 +1,73 @@ +# !!! This file must be named ~/.vchat/formats in order to work !!! + +# please be REALLY REALLY careful here +# the following lines will be used as +# format strings + +# ^ introduces a style change: +# TODO: ^^ == '^' + +# 0 - default colorpair for window +# 1 - colorpair 1 RED +# 2 - colorpair 2 GREEN +# 3 - colorpair 3 YELLOW +# 4 - colorpair 4 BLUE +# 5 - colorpair 5 MAGENTA +# 6 - colorpair 6 CYAN +# 7 - colorpair 7 WHITE +# 8 - colorpair 8 WHITE on RED +# 9 - colorpair 9 WHITE on BLUE +# aA - alternate charset on/off +# bB - bold on/off +# dD - dim on/off +# iI - invisible on/off +# lL - blink on/off +# nN - normal on/off +# pP - protected on/off +# rR - reverse on/off +# sS - standout on/off +# uU - underlined on/off + + +# Counts defaults: + +FS_PLAIN = "%s" +FS_CHAN = "%s" +FS_PRIV = "%s" +FS_SERV = "^2%s" +FS_GLOB = "^2%s" +FS_DBG = "^3%s" +FS_ERR = "^1%s" +FS_IDLE = "^8%s" +FS_TIME = "^5[%H:%M]-- ^0" +FS_TOPICW = "[ Channel %d: %s" +FS_NOTOPICW = "[ Channel %d has no topic" +FS_CONSOLE = "[ %s@%s:%d, use .h to get help, send bugs reports and feature requests to vchat@pulse.flatline.de ..." +FS_CONNECTED = "^2# Connected to '^6%s^2', port ^6%d^2 ..." +FS_TOPIC = "^2# Channel ^6%d^2 topic is: '^0%s^2'" +FS_NOTOPIC = "^2# Channel ^6%d^2 has no topic" +FS_CHGTOPIC = "^2# ^6%s^2 changes topic to: '^0%s^2'" +FS_USONLINE = "^2# Users online: %s" +FS_USMATCH = "^2# Users matching \"%s\":%s" +FS_SIGNON = "^2# ^6%s^2 %s" +FS_SIGNOFF = "^2# ^6%s^2 %s" +FS_JOIN = "^2# ^6%s^2 %s ^6%d" +FS_LEAVE = "^2# ^6%s^2 %s ^6%d" +FS_NICKCHANGE = "^2# ^6%s^2 ^6%s^2 %s" +FS_UNKNOWNMSG = "?? unknown message: %s" +FS_BOGUSMSG = "?? bogus message: %s" +FS_RXPUBURL = "^5[^6%s^5]^0 %s" +FS_MYPUBURL = "^5[^6^u%s^U^5]^0 %s" +FS_RXPUBMSG = "^5<^6%s^5>^0 %s" +FS_MYPUBMSG = "^5<^6^u%s^U^5>^0 %s" +FS_TXPUBMSG = "^5<^6^b%s^B^5>^0 %s" +FS_RXPRIVMSG = "^5*^6%s^5*^0 %s" +FS_TXPRIVMSG = "^5-> *^6%s^5*^0 %s" +FS_BGPRIVMSG = "^1! Bogus message, not sent." +FS_PUBACTION = "^5*^0 ^6%s^0 %s" +FS_TXPUBACTION = "^5*^0 ^6^b%s^B^0 %s" +FS_BGTXPUBACTION = "^1! No action taken." +FS_COMMAND = "^2## command: %s" +FS_LOCALCOMMAND = "^2## local command (not executed yet): %s" +FS_BOGUSCOMMAND = "^2## bogus command (not executed or sent): %s" +FS_SBINF = " [%d/%d] " diff --git a/sample-erdgeist.fmt b/sample-erdgeist.fmt new file mode 100755 index 0000000..cce9ef2 --- /dev/null +++ b/sample-erdgeist.fmt @@ -0,0 +1,74 @@ +# !!! This file must be named ~/.vchat/formats in order to work !!! + +# please be REALLY REALLY careful here +# the following lines will be used as +# format strings + +# ^ introduces a style change: +# TODO: ^^ == '^' + +# 0 - default colorpair for window +# 1 - colorpair 1 RED +# 2 - colorpair 2 GREEN +# 3 - colorpair 3 YELLOW +# 4 - colorpair 4 BLUE +# 5 - colorpair 5 MAGENTA +# 6 - colorpair 6 CYAN +# 7 - colorpair 7 WHITE +# 8 - colorpair 8 WHITE on RED +# 9 - colorpair 9 WHITE on BLUE +# aA - alternate charset on/off +# bB - bold on/off +# dD - dim on/off +# iI - invisible on/off +# lL - blink on/off +# nN - normal on/off +# pP - protected on/off +# rR - reverse on/off +# sS - standout on/off +# uU - underlined on/off + +# erdgeists colorset + +FS_PLAIN = "%s" +FS_CHAN = "%s" +FS_PRIV = "%s" +FS_SERV = "^1%s" +FS_GLOB = "^1%s" +FS_DBG = "^3%s" +FS_ERR = "^1%s" +FS_IDLE = "^8%s" +FS_TIME = "^9[%H:%M]^0 " +FS_TOPICW = "[ Channel %d: %s" +FS_NOTOPICW = "[ Channel %d has no topic" +FS_CONSOLE = "[ %s@%s:%d, use .h to get help" +FS_CONNECTED = "^2# Connected to '^0%s^2', port ^0%d^2 ..." +FS_TOPIC = "^1# Channel ^6%d^2 topic is: '^0%s^2'" +FS_NOTOPIC = "^1# Channel ^6%d^2 has no topic" +FS_CHGTOPIC = "^1# ^4%s^1 changes topic to: '^0%s^1'" +FS_USONLINE = "^0# Users online: %s" +FS_USMATCH = "^0# Users matching \"%s\":%s" +FS_SIGNON = "^1# ^4%s^1 %s" +FS_SIGNOFF = "^1# ^4%s^1 %s" +FS_JOIN = "^1# ^4%s^1 %s ^0%d" +FS_LEAVE = "^1# ^4%s^1 %s ^0%d" +FS_NICKCHANGE = "^1# ^4%s^1 ^4%s^1 %s" +FS_UNKNOWNMSG = "?? unknown message: %s" +FS_BOGUSMSG = "?? bogus message: %s" +FS_RXPUBURL = "^0[^4%s^0] %s" +FS_MYPUBURL = "^0[^4^u%s^U^0] %s" +FS_RXPUBMSG = "^0<^4%s^0> %s" +FS_MYPUBMSG = "^0<^4^u%s^U^0> %s" +FS_TXPUBMSG = "^0<^4^b%s^B^0> %s" +FS_RXPRIVMSG = "^2>^4%s^2<^0 %s" +FS_TXPRIVMSG = "^1*^4%s^1*^0 %s" +FS_BGPRIVMSG = "^1! Bogus message, not sent." +FS_PUBACTION = "^1*^0 ^4%s^0 %s" +FS_TXPUBACTION = "^1*^0 ^4^b%s^B^0 %s" +FS_BGTXPUBACTION = "^1! No action taken." +FS_COMMAND = "^2## command: %s" +FS_LOCALCOMMAND = "^2## local command (not executed yet): %s" +FS_BOGUSCOMMAND = "^2## bogus command (not executed or sent): %s" +FS_SBINF = " [%d/%d] " +FS_SBINF_SCROLL = " ^8[%d/%d]^0 " + diff --git a/sample-mAsq.fmt b/sample-mAsq.fmt new file mode 100755 index 0000000..02908b0 --- /dev/null +++ b/sample-mAsq.fmt @@ -0,0 +1,73 @@ +# !!! This file must be named ~/.vchat/formats in order to work !!! + +# please be REALLY REALLY careful here +# the following lines will be used as +# format strings + +# ^ introduces a style change: +# TODO: ^^ == '^' + +# 0 - default colorpair for window +# 1 - colorpair 1 RED +# 2 - colorpair 2 GREEN +# 3 - colorpair 3 YELLOW +# 4 - colorpair 4 BLUE +# 5 - colorpair 5 MAGENTA +# 6 - colorpair 6 CYAN +# 7 - colorpair 7 WHITE +# 8 - colorpair 8 WHITE on RED +# 9 - colorpair 9 WHITE on BLUE +# aA - alternate charset on/off +# bB - bold on/off +# dD - dim on/off +# iI - invisible on/off +# lL - blink on/off +# nN - normal on/off +# pP - protected on/off +# rR - reverse on/off +# sS - standout on/off +# uU - underlined on/off + + +# Counts defaults: + +FS_PLAIN = "%s" +FS_CHAN = "%s" +FS_PRIV = "%s" +FS_SERV = "^2%s" +FS_GLOB = "^2%s" +FS_DBG = "^3%s" +FS_ERR = "^1%s" +FS_IDLE = "^8%s" +FS_TIME = "^5%H:%M^0 " +FS_TOPICW = "[ Channel %d: %s" +FS_NOTOPICW = "[ Channel %d has no topic" +FS_CONSOLE = "[ %s@%s:%d, use .h to get help, send bugs reports and feature requests to vchat@pulse.flatline.de ..." +FS_CONNECTED = "^2*^0C^2* Connected to '^6%s^2', port ^6%d^2 ..." +FS_TOPIC = "^2*^0T^2* Channel ^6%d^2 topic is: '^0%s^2'" +FS_NOTOPIC = "^2*^0T^2* Channel ^6%d^2 has no topic" +FS_CHGTOPIC = "^5*^0T^2* ^6%s^2 changes topic to: '^0%s^2'" +FS_USONLINE = "^2*^0+^2* Users online: %s" +FS_USMATCH = "^2*^0=^2* Users matching \"%s\":%s" +FS_SIGNON = "^3*^0>^3* ^6%s^2 %s" +FS_SIGNOFF = "^1*^0<^1* ^6%s^2 %s" +FS_JOIN = "^3*^0^b>^B^3* ^6%s^2 %s ^6%d" +FS_LEAVE = "^1*^0^b<^B^1* ^6%s^2 %s ^6%d" +FS_NICKCHANGE = "^5*^0N^5* ^6%s^2 ^6%s^2 %s" +FS_UNKNOWNMSG = "^5*^1!^5*^1 unknown message: %s" +FS_BOGUSMSG = "^5*^1!^5*^1 bogus message: %s" +FS_RXPUBURL = "^5[^6%s^5]^0 ^u%s^U" +FS_MYPUBURL = "^5[^6^u%s^U^5]^0 %s" +FS_RXPUBMSG = "^5<^6%s^5>^0 %s" +FS_MYPUBMSG = "^5<^6^u%s^U^5>^0 %s" +FS_TXPUBMSG = "^5<^6^b%s^B^5>^0 %s" +FS_RXPRIVMSG = "^5[^6^u%s^U^5]^0 %s" +FS_TXPRIVMSG = "^5>^6^b%s^B^5<^0 %s" +FS_BGPRIVMSG = "^5*^1!^5*^1 Bogus message, not sent." +FS_PUBACTION = "^5*^0 ^6%s^0 %s" +FS_TXPUBACTION = "^5*^0 ^6^b%s^B^0 %s" +FS_BGTXPUBACTION = "^1! No action taken." +FS_COMMAND = "^2*^5I^2* command: %s" +FS_LOCALCOMMAND = "^5*^1!^5^1 local command (not executed yet): %s" +FS_BOGUSCOMMAND = "^5*^1!^5^1 bogus command (not executed or sent): %s" +FS_SBINF = " [%d/%d] " diff --git a/sample-oldstyle.fmt b/sample-oldstyle.fmt new file mode 100755 index 0000000..a1b0eb5 --- /dev/null +++ b/sample-oldstyle.fmt @@ -0,0 +1,73 @@ +# !!! This file must be named ~/.vchat/formats in order to work !!! + +# please be REALLY REALLY careful here +# the following lines will be used as +# format strings + +# ^ introduces a style change: +# TODO: ^^ == '^' + +# 0 - default colorpair for window +# 1 - colorpair 1 RED +# 2 - colorpair 2 GREEN +# 3 - colorpair 3 YELLOW +# 4 - colorpair 4 BLUE +# 5 - colorpair 5 MAGENTA +# 6 - colorpair 6 CYAN +# 7 - colorpair 7 WHITE +# 8 - colorpair 8 WHITE on RED +# 9 - colorpair 9 WHITE on BLUE +# aA - alternate charset on/off +# bB - bold on/off +# dD - dim on/off +# iI - invisible on/off +# lL - blink on/off +# nN - normal on/off +# pP - protected on/off +# rR - reverse on/off +# sS - standout on/off +# uU - underlined on/off + + +# Counts defaults: + +FS_PLAIN = "^0%s" +FS_CHAN = "^0%s" +FS_PRIV = "^0%s" +FS_SERV = "^0%s" +FS_GLOB = "^0%s" +FS_DBG = "^0%s" +FS_ERR = "^0^b%s^B" +FS_IDLE = "^0^r%s^R" +FS_TIME = "^0%H:%M " +FS_TOPICW = "Channel %d: %s" +FS_NOTOPICW = "Channel %d has no topic" +FS_CONSOLE = "-=- VChat V0.1 -=- type .h for help -=-" +FS_CONNECTED = "^0* Connected to '%s', port %d ..." +FS_TOPIC = "^0* Channel %d topic is: '%s'" +FS_NOTOPIC = "^0* Channel %d has no topic" +FS_CHGTOPIC = "^0* %s changed the channel topic to '%s'" +FS_USONLINE = "^0* Users online: %s" +FS_USMATCH = "^0* Users matching \"%s\":%s" +FS_SIGNON = "^0* %s %s" +FS_SIGNOFF = "^0* %s %s" +FS_JOIN = "^0* %s %s %d" +FS_LEAVE = "^0* %s %s %d" +FS_NICKCHANGE = "^0* %s changed h** nick to %s" +FS_UNKNOWNMSG = "^0* unknown message: %s" +FS_BOGUSMSG = "^0* bogus message: %s" +FS_RXPUBURL = "^0[%s] %s" +FS_MYPUBURL = "^0[%s] %s" +FS_RXPUBMSG = "^0<%s> %s" +FS_MYPUBMSG = "^0<^u%s^U> %s" +FS_TXPUBMSG = "^0<%s> ^b%s^B" +FS_RXPRIVMSG = "^0*%s* %s" +FS_TXPRIVMSG = "^0^b.m %s %s^B" +FS_BGPRIVMSG = "^0* Bogus message, not sent." +FS_PUBACTION = "^0%s %s" +FS_TXPUBACTION = "^0^b.a %s %s^B" +FS_BGTXPUBACTION = "^1! No action taken." +FS_COMMAND = "^0* command: %s" +FS_LOCALCOMMAND = "^0* local command (not executed yet): %s" +FS_BOGUSCOMMAND = "^0* bogus command (not executed or sent): %s" +FS_SBINF = " %d/%d " diff --git a/vchat-client.c b/vchat-client.c new file mode 100755 index 0000000..ae369ab --- /dev/null +++ b/vchat-client.c @@ -0,0 +1,536 @@ +/* + * vchat-client - alpha version + * vchat-client.c - main() and utility functions + * + * Copyright (C) 2001 Andreas Kotes + * + * This program is free software. It can be redistributed and/or modified, + * provided that this copyright notice is kept intact. This program is + * distributed in the hope that it will be useful, but without any warranty; + * without even the implied warranty of merchantability or fitness for a + * particular purpose. In no event shall the copyright holder be liable for + * any direct, indirect, incidental or special damages arising in any way out + * of the use of this software. + * + */ + +/* general includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vchat.h" + +/* version of this module */ +unsigned char *vchat_cl_version = "$Id$"; + +/* externally used variables */ +/* we're logged in */ +unsigned int loggedin = 0; +/* we run as long as this is true */ +unsigned int status = 1; +/* error string to show after exit */ +unsigned char errstr[ERRSTRSIZE] = "\0"; + +/* locally global variables */ +/* our list of filedescriptors */ +static fd_set masterfds; + +/* declaration of configuration array */ +#include "vchat-config.h" + +/* servers filedescriptor from vchat-protocol.c */ +extern int serverfd; + +void setnoption (unsigned char *, unsigned char *); + +static void parsecfg(unsigned char *line) { + int bytes; + unsigned char *param=line; + unsigned char *value=NULL; + + /* handle quotes value is empty, so wecan use it */ + value = strchr(line,'#'); + if (value) { /* the line contains a cute little quote */ + value[0]='\0'; /* ignore the rest of the line */ + } + + /* now split the line into two parts */ + value = strchr(line,'='); + if (!value) return; /* exit if strchr fails */ + value[0]='\0'; + value++; + + /* "trim" values */ + while ((value[0] == ' ')||(value[0] == '\t')) + value++; + bytes = strlen(value); + while ((value[bytes-1] == ' ')||(value[bytes-1] == '\t')) { + value[bytes-1] = '\0'; + bytes=strlen(value); + } + /* bytes should be strlen(value) */ + if ( value[bytes-1] == '"' ) value[bytes-1] = '\0'; + if ( value[0] == '"' ) value++; + + /* "trim" param */ + while ((param[0] == ' ')||(param[0] == '\t')) + param++; + bytes = strlen(param); + while ((param[bytes-1] == ' ')||(param[bytes-1] == '\t')) { + param[bytes-1] = '\0'; + bytes=strlen(param); + } + /* bytes should be strlen(param) */ + if ( param[bytes-1] == '\"' ) param[bytes-1] = '\0'; + if ( param[0] == '\"' ) param++; + + if ((!param)||(!value)) return; /* failsave */ + + //fprintf(stderr,"\"%s\" -> \"%s\"\n",param,value); + setnoption(param,value); +} + +static void parseformats(unsigned char *line) { + int i; + unsigned char *tmp = NULL; + + /* read a format line from file, syntax is + FS_XXX = "formatstring" + */ + + while( *line == ' ') line++; + + if( *line != '#') /* allow to comment out the line */ + for (i = 0; formatstrings[i].formatstr; i++) + if (!strncasecmp(formatstrings[i].idstring, line, strlen( formatstrings[i].idstring) )) + { + unsigned char *tail = line + strlen( formatstrings[i].idstring); + while( *tail==' ' || *tail=='\t') tail++; /* and skip whitespaces */ + + if( *tail++ == '=' ) + { + while( *tail==' ' || *tail=='\t') tail++; + if( *(tail++)=='\"' ) + { + int j, k = 0, stringends = 0, backslash=0; + for ( j = 0; tail[j] && !stringends; j++) + { + switch( tail[j] ) { + case '^': + if ( tail[j+1] != '^' ) + tmpstr[k++] = 1; + break; + case '\\': + backslash=1-backslash; + tmpstr[k++] = '\\'; + break; + case '\"': + if (backslash) k--; else stringends = 1; + default: + tmpstr[k++] = tail[j]; + backslash = 0; + } + } + + if ( stringends && ( (tmp = (unsigned char *)malloc( 1 + j )) != NULL ) ) + { + memcpy( tmp, tmpstr, k); + tmp[k-1]=0; + formatstrings[i].formatstr = tmp; + } + } + } + } + +} + +/* UNUSED uncomment if needed +static void parseknownhosts(unsigned char *line) { +} +*/ + +/* load config file */ +static void +loadcfg (unsigned char *file,void (*lineparser) (unsigned char *)) +{ + int fd; + int bytes,bufoff=0; + unsigned char *tmp = NULL; +#define BUFSIZE 4096 + unsigned char buf[BUFSIZE]; /* data buffer */ + unsigned char *ltmp = buf; + unsigned char *tildex = NULL; + buf[BUFSIZE-1] = '\0'; /* sanity stop */ + + if (!file) return; + if (!file[0]) return; + if (file[0] == '~') + tildex = tilde_expand(file); + else + tildex = file; + fd = open(tildex,O_RDONLY); + if (fd == -1) { + snprintf (errstr, TMPSTRSIZE, "Can't open config-file \"%s\": %s.", tildex, sys_errlist[errno]); + } else { + while ((bytes = read(fd,&buf[bufoff],BUFSIZE-bufoff-1))) { + if (bytes < 0) { + close(fd); + return; + } else { + /* terminate string */ + buf[bytes + bufoff] = '\0'; + /* as long as there are lines .. */ + while ((tmp = strchr (ltmp, '\n')) != NULL) { + /* did the server send CR+LF instead of LF with the last line? */ + if (tmp[-1] == '\r') + tmp[-1] = '\0'; + + /* remove newline from previous message, advance pointer of next + * message */ + tmp[0] = '\0'; + tmp++; + + /* we have a last message? give away to line handler! */ + if (ltmp[0]) + { + lineparser(ltmp); + } + + /* move line along .. */ + ltmp = tmp; + } + /* buffer exhausted, move partial line to start of buffer and go + * on .. */ + bufoff = (bytes+bufoff) - (ltmp-buf); + if (bufoff > 0) + memmove (buf, ltmp, bufoff); + else + bufoff = 0; + } + } + close(fd); + } +} + +void +loadconfig (unsigned char *file) +{ + loadcfg(file,parsecfg); +} + +void +loadformats (unsigned char *file) +{ + loadcfg(file,parseformats); +} + +/* get-format-string */ +unsigned char * +getformatstr (formtstr id) +{ + int i; + for (i = 0; formatstrings[i].formatstr; i++) + if (formatstrings[i].id == id) return formatstrings[i].formatstr; + return NULL; +} + +/* get-string-option, fetches *char-value of variable named by option */ +unsigned char * +getstroption (confopt option) +{ + int i; +#ifdef DEBUG + fprintf(stderr,"getstroption: %d\n",option); +#endif + for (i = 0; configoptions[i].type != CO_NIL; i++) + if ((configoptions[i].id == option) && (configoptions[i].type == CO_STR)) { + if (!configoptions[i].value) + return configoptions[i].defaultvalue; + else + return configoptions[i].value; + } + return NULL; +} + +/* set-string-option, puts *char-value to variable named by option */ +void +setstroption (confopt option, unsigned char *string) +{ + int i; +#ifdef DEBUG + fprintf(stderr,"setstroption: %d to %s\n",option,string); +#endif + for (i = 0; configoptions[i].type != CO_NIL; i++) + if ((configoptions[i].id == option) && (configoptions[i].type == CO_STR)) { + if (configoptions[i].value) + free(configoptions[i].value); + if (string) + configoptions[i].value = strdup(string); + else + configoptions[i].value = NULL; + if (configoptions[i].localvar) + *configoptions[i].localvar = configoptions[i].value; + } +} + +/* set-named-option, puts string to variable named by name */ +void +setnoption (unsigned char *name, unsigned char *string) +{ + int i; +#ifdef DEBUG + fprintf(stderr,"setstrnoption: %s to %s\n",name,string); +#endif + for (i = 0; configoptions[i].type != CO_NIL; i++) + if (!strcmp(configoptions[i].varname,name)) { + if (configoptions[i].type == CO_STR) { + if (configoptions[i].value) + free(configoptions[i].value); + if (string) + configoptions[i].value = strdup(string); + else + configoptions[i].value = NULL; + } else if (configoptions[i].type == CO_INT) { + configoptions[i].value = (char *) atoi(string); + } + if (configoptions[i].localvar) + *configoptions[i].localvar = configoptions[i].value; + } +} + +/* get-integer-option, fetches int-value of variable named by option */ +int +getintoption (confopt option) +{ + int i; +#ifdef DEBUG + fprintf(stderr,"getintoption: %d\n",option); +#endif + for (i = 0; configoptions[i].type != CO_NIL; i++) + if ((configoptions[i].id == option) && (configoptions[i].type == CO_INT)) { + if ((int)configoptions[i].value == -1) + return (int) configoptions[i].defaultvalue; + else + return (int) configoptions[i].value; + } + return 0; +} + +/* set-integer-option, puts int-value to variable named by option */ +void +setintoption (confopt option, int value) +{ + int i; +#ifdef DEBUG + fprintf(stderr,"setintoption: %d to %d\n",option,value); +#endif + for (i = 0; configoptions[i].type != CO_NIL; i++) + if ((configoptions[i].id == option) && (configoptions[i].type == CO_INT)) { + configoptions[i].value = (char *) value; + if (configoptions[i].localvar) + *configoptions[i].localvar = configoptions[i].value; + } +} + +int quitrequest = 0; + +/* cleanup-hook, for SIGINT */ +void +cleanup (int signal) +{ + if( signal == SIGINT ) { + switch( quitrequest >> 2 ) { + case 0: + flushout( ); + writeout( " Press Ctrl+C twice now to confirm "); + showout( ); + quitrequest+=4; + return; + break; + case 1: + flushout( ); + writeout( " Press Ctrl+C twice now to confirm "); + writeout( " Press Ctrl+C once now to confirm "); + showout( ); + quitrequest+=4; + return; + break; + default: + break; + } + } + /* restore terminal state */ + exitui (); + /* clear userlist */ + ul_clear (); + /* close server connection */ + if (serverfd > 0) + close (serverfd); + /* inform user if we where killed by signal */ + if (signal > 1) + { + fprintf (stderr, "vchat-client: terminated with signal %d.\n", signal); + } else if (errstr[0]) + fprintf (stderr, errstr); + /* end of story */ + exit (0); +} + +void calleverysecond( void ) { + /* timetriggered execution, don't rely on being called every 1000us */ + /* rather see it as a chance for being called 9 times in 10 seconds */ + /* so check time() */ + + if(quitrequest) + quitrequest--; + if(outputcountdown && !--outputcountdown) + hideout( ); +} + +/* this function is called in the master loop */ +void +eventloop (void) +{ + /* get fresh copy of filedescriptor list */ + fd_set readfds = masterfds; + struct timeval tv = { 1, 0}; + + switch (select (serverfd + 1, &readfds, NULL, NULL, &tv)) + { + case -1: + /* EINTR is most likely a SIGWINCH - ignore for now */ + if (errno != EINTR) + { + snprintf (tmpstr, TMPSTRSIZE, "Select fails, %s.", sys_errlist[errno]); + strncpy(errstr,tmpstr,TMPSTRSIZE-2); + errstr[TMPSTRSIZE-2] = '\0'; + strcat(errstr,"\n"); + writecf (FS_ERR,tmpstr); + /* see this as an error condition and bail out */ + status = 0; + } + break; + case 0: + /* time out reached */ + calleverysecond(); + break; + default: + /* something to read from user & we're logged in or have a cert? */ + if (FD_ISSET (0, &readfds) && loggedin) + userinput (); + + /* something to read from server? */ + if (FD_ISSET (serverfd, &readfds)) + networkinput (); + break; + } +} + +void usage(unsigned char *name) { + printf("usage: %s [-C config-file] [-l] [-z] [-s host] [-p port] [-c channel] [-n nickname]\n",name); + printf(" -C load a second config-file, overriding the first one\n"); + printf(" -l local connect (no SSL + connects localhost:2323)\n"); + printf(" -z don't use certificate files\n"); + printf(" -s set server (default \"%s\")\n",getstroption(CF_SERVERHOST)); + printf(" -p set port (default %d)\n",getintoption(CF_SERVERPORT)); + printf(" -c set channel (default %d)\n",getintoption(CF_CHANNEL)); + if (nick) + printf(" -n set nickname (default \"%s\")\n",nick); + else + printf(" -n set nickname\n"); + printf(" -f set from (default \"%s\")\n",getstroption(CF_FROM)); + printf(" -h gives this help\n"); +} + +/* main - d'oh */ +int +main (int argc, char **argv) +{ + int pchar; + int cmdsunparsed = 1; + + loadconfig (GLOBAL_CONFIG_FILE); + loadconfig (getstroption (CF_CONFIGFILE)); + loadformats(GLOBAL_FORMAT_FILE); + loadformats(getstroption (CF_FORMFILE)); + + /* parse commandline */ + while (cmdsunparsed) { + pchar = getopt(argc,argv,"C:lzs:p:c:n:f:h"); +#ifdef DEBUG + fprintf(stderr,"parse commandline: %d ('%c'): %s\n",pchar,pchar,optarg); +#endif + + switch (pchar) { + case -1 : cmdsunparsed = 0; break; + case 'C': loadconfig(optarg); break; + case 'l': setintoption(CF_USESSL,0); break; + case 'z': setintoption(CF_USECERT,0); break; + case 's': setstroption(CF_SERVERHOST,optarg); break; + case 'p': setintoption(CF_SERVERPORT,strtol(optarg,NULL,10)); break; + case 'c': setintoption(CF_CHANNEL,strtol(optarg,NULL,10)); break; + case 'n': setstroption(CF_NICK,optarg); break; + case 'f': setstroption(CF_FROM,optarg); break; + case 'h': usage(argv[0]); exit(0); break; + default : usage(argv[0]); exit(1); + } + } + + if (optind < argc) { usage(argv[0]); exit(1); } + + if (!getintoption(CF_USESSL)) { + setstroption(CF_SERVERHOST,"localhost"); + setintoption(CF_SERVERPORT,2323); + } else { + SSL_library_init (); + SSL_load_error_strings (); + } + + + /* install signal handler */ + signal (SIGINT, cleanup); + signal (SIGHUP, cleanup); + signal (SIGTERM, cleanup); + signal (SIGQUIT, cleanup); + + /* initialize userinterface */ + initui (); + + /* attempt connection */ + if (!vcconnect (getstroption(CF_SERVERHOST), getintoption(CF_SERVERPORT))) + { + snprintf (tmpstr, TMPSTRSIZE, "Could not connect to server, %s.", + sys_errlist[errno]); + strncpy(errstr,tmpstr,TMPSTRSIZE-2); + errstr[TMPSTRSIZE-2] = '\0'; + strcat(errstr,"\n"); + writecf (FS_ERR,tmpstr); + /* exit condition */ + status = 0; + } + else + { + /* add stdin & server to masterdfs */ + FD_ZERO (&masterfds); + FD_SET (0, &masterfds); + FD_SET (serverfd, &masterfds); + } + + while (status) + eventloop (); + + /* sanely close connection to server */ + vcdisconnect (); + + /* call cleanup-hook without signal */ + cleanup (0); + return 0; +} diff --git a/vchat-client.sgml b/vchat-client.sgml new file mode 100755 index 0000000..ee0dc36 --- /dev/null +++ b/vchat-client.sgml @@ -0,0 +1,376 @@ + + + 1"> + macrotron@president.eu.org"> + +]> + + + + +
+ &dhemail; +
+ + Hans + Freitag + + + 2001 + Andreas Kotes + +
+ + + + vchat-client + &dhsection; + + + +vchat-clientthis is vchat-client, a GPLed (SSL) +client for the vchat protocol. + + + + +vchat-client +-C configfile +-l +-z +-s host +-p port +-c channel +-n nickname +-f from + + + + + +DESCRIPTION +vchat-client connects to vchat chat system via ssl + + + + +OPTIONS + + + + configfile +load an alternative configuration file, +overiding the parameters in the default config files. -C should +be the first parameter, options set before this parameter can be +overridden in the configfile. + + + + +local connect (no SSL + connects localhost:2323) + + + + +don't use certificate files + + + + host +local connect (no SSL + connects localhost:2323) + + + + port +set port (default 2325) + + + + nickname +set nickname + + + + from +set from (default "vc-alpha-0.15") + + + + +prints out a help screen + + + + + + + + +CONFIGFILE +/etc/vchatrc and ~/.vchat/config +are the default config files of vchat-client. A third config file can be +given as command line Parameter. + + + +Hierachie of config files and Options. + 1. /etc/vchatrc + 2. ~/vchat/config + 3. options set before -C option + 4. options in the config + file set with -C option + 5. options set after -C option + + + +The config file syntax is "option=value"! it can be used to +configure the behavior of vchat-client + + + + + +Sets the nickname (default is NULL) + + + + +Sets the from (default is "vc-alpha-0.15") + + + + +Sets the host to connect to (default is pulse.flatline.de) + + + + +Set the port (default 2325) + + + + +Set ciphers ("HIGH:MEDIUM") + + + + +Set the certfile (default ~/.vchat/cert) + + + + +Set the keyfile (default ~/.vchat/key) + + + + +Set the formatfile (default ~/.vchat/formats) not impemented yet! + + + + +1|0 default=1 + + + + +1|0 default=1 + + + + +1|0 default=1 + + + + +set the heigth of the messages window default +is 0 (no messages window) + + + + +default=5 I don't know what this does, but I will +know in future. maybe you want to tell me. + + + + +number (default=0) + + + + +default=2048 + + + + +default=8192 + + + + +default=0 + + + + +default=86400 + + + + + + + + +KEYS + + +Ctrl+J clear private window +Ctrl+O clear channel window +Ctrl+L redraw screen +Ctrl+F scroll window up +Ctrl+B scroll window down +Ctrl+R change active scrolling window + (see rightmost character of + topic/console lines) +Ctrl-T shrink private window size +Ctrl-G grow private window size +Ctrl+X toggle private window + (pops up on private messages) +TAB nick completion + + + + + + + + + +DEVEL + +You can get the most recent version of vchat-client via CVS, e.g: + +$ cvs -d:pserver:anonymous@pulse.flatline.de:/home/cvsroot login +$ cvs -z3 -d:pserver:anonymous@pulse.flatline.de:/home/cvsroot co vchat-client + + + +(press return at password prompt) no autoconf yet, sorry. required libs: + + - openssl (0.9.6+ preferred) + - readline (4.2+ preferred) + - ncurses (5.2 preferred) + + + +please adjust the Makefile according to your need, then run 'make' to compile, +'make install' to install and ./vchat-client to start the binary. +nope, I don't have any intention to use autoconf for this hack. + +run 'fakeroot make -f debian/rules binary' or +'dpkg-buildpackage -rfakeroot' to build a debian +package from the source. + +The Makefile knows the targets "all, install, uninstall, clean" + + + +FILES: + README - you're reading it. + TODO - list of things to do + vchat-client.c - main() and utility functions + vchat-config.h - configuration defaults + vchat-keygen - key generator with anon CA - + server support required + vchat-messages.h - server messages -- function + correlation + vchat-protocol.c - handling of server + connection & messages + vchat-ui.c - user-interface and readline + handling + vchat-user.c - userlist handling + vchat.h - global structures and functions + debian/ - the debian package build + directory + + +everything should be self-explantory, but please don't refrain to ask and/or +give bug reports, feature requests, hints and tricks, etc etc .. + +Andreas Kotes count@flatline.de + + + + + + +SSL + +if you want to use an SSL certificate with the default configuration you need +to put the key in ~/.vchat/key and the certificate in ~/.vchat/cert, both in +PEM format. You can generate a key and a certificate by calling vchat-keygen, +but the server you connect needs to know same anon CA provided by +vchat-keygen, which currently isn't supported anywhere. + +to upload your certificate use nick-request.pl from the vchat-server +source available at ftp://vchat.vaxbusters.org. Thisfor at least one of +the admins has to be logged in. + + + + + + + +SEE ALSO +gcc (1), cvs (1). + + + + + + +AUTHOR +This manual page was written by Hans Freitag &dhemail; for +vchat-client system. Permission is granted to copy, distribute +and/or modify this document under the terms of the +GNU Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover +Texts and no Back-Cover Texts. + + + + +
+ + diff --git a/vchat-commands.c b/vchat-commands.c new file mode 100755 index 0000000..c81bf36 --- /dev/null +++ b/vchat-commands.c @@ -0,0 +1,368 @@ +/* + * vchat-client - alpha version + * vchat-commands.c - handling of client commands + * + * Copyright (C) 2001 Andreas Kotes + * + * This program is free software. It can be redistributed and/or modified, + * provided that this copyright notice is kept intact. This program is + * distributed in the hope that it will be useful, but without any warranty; + * without even the implied warranty of merchantability or fitness for a + * particular purpose. In no event shall the copyright holder be liable for + * any direct, indirect, incidental or special damages arising in any way out + * of the use of this software. + * + */ + +/* general includes */ +#include +#include +#include +#include + +/* local includes */ +#include "vchat.h" +#include "vchat-help.h" + +/* version of this module */ +unsigned char *vchat_cm_version = "$Id$"; + +/* our "/command " table */ +enum { +COMMAND_VERSION, +COMMAND_FILTERS, +COMMAND_LSFLT, +COMMAND_RMFLT, +COMMAND_CLFLT, +COMMAND_HELP, +COMMAND_KEYS, +COMMAND_QUIT, +COMMAND_USER, +COMMAND_FLT, +COMMAND_PM, +COMMAND_ACTION, +COMMAND_PMSHORT, +COMMAND_PLAIN, +COMMAND_NONE +}; + +static void command_quit ( unsigned char *tail); +static void command_user ( unsigned char *tail); +static void command_pm ( unsigned char *tail); +static void command_action ( unsigned char *tail); +static void command_help ( unsigned char *tail); +static void command_flt ( unsigned char *tail); +static void command_lsflt ( unsigned char *tail); +static void command_clflt ( unsigned char *tail); +static void command_rmflt ( unsigned char *tail); + void command_version ( unsigned char *tail); +static void command_none ( unsigned char *line); + +static void output_default ( unsigned char *tail); + +/* commandentry defined in vchat.h */ + +static commandentry +commandtable[] = { +{ COMMAND_VERSION, "VERSION", 7, command_version, SHORT_HELPTEXT_VERSION, LONG_HELPTEXT_VERSION }, +{ COMMAND_LSFLT, "LSFLT", 5, command_lsflt, NULL, LONG_HELPTEXT_LSFLT }, +{ COMMAND_RMFLT, "RMFLT", 5, command_rmflt, NULL, LONG_HELPTEXT_RMFLT }, +{ COMMAND_CLFLT, "CLFLT", 5, command_clflt, NULL, LONG_HELPTEXT_CLFLT }, +{ COMMAND_HELP, "HELP", 4, command_help, SHORT_HELPTEXT_HELP, LONG_HELPTEXT_HELP }, +{ COMMAND_FILTERS, "FILTERS", 7, command_help, SHORT_HELPTEXT_FILTERS, LONG_HELPTEXT_FILTERS }, +{ COMMAND_KEYS, "KEYS", 4, command_help, SHORT_HELPTEXT_KEYS, LONG_HELPTEXT_KEYS }, +{ COMMAND_QUIT, "QUIT", 4, command_quit, SHORT_HELPTEXT_QUIT, LONG_HELPTEXT_QUIT }, +{ COMMAND_USER, "USER", 4, command_user, SHORT_HELPTEXT_USER, LONG_HELPTEXT_USER }, +{ COMMAND_FLT, "FLT", 3, command_flt, NULL, LONG_HELPTEXT_FLT }, +{ COMMAND_PM, "MSG", 3, command_pm, SHORT_HELPTEXT_MSG, LONG_HELPTEXT_MSG }, +{ COMMAND_ACTION, "ME", 2, command_action, SHORT_HELPTEXT_ME, LONG_HELPTEXT_ME }, +{ COMMAND_PMSHORT, "M", 1, command_pm, NULL, SHORT_HELPTEXT_MSG }, +{ COMMAND_PLAIN, "/", 1, output_default, NULL, NULL }, +{ COMMAND_NONE, "", 0, command_none, NULL, NULL } +}; + +/* parse "/command" */ +static int +translatecommand( unsigned char **cmd) +{ + int result; + int cut = 0; + int maxcut = 0; + + while( (*cmd)[maxcut] && ((*cmd)[maxcut] != 0x20) && ((*cmd)[maxcut] != '\n')) maxcut++; + if( maxcut ) maxcut--; + + do { + for( result = 0; + (result != COMMAND_NONE) && + (strncasecmp(*cmd, commandtable[result].name, commandtable[result].len - + ((commandtable[result].len - maxcut - cut > 0) ? cut : 0))); + result++); + } while ((cut < commandtable[0].len) && (commandtable[result].number == COMMAND_NONE) && (++cut)); + + (*cmd) += commandtable[result].len; + if( commandtable[result].number != COMMAND_NONE ) + (*cmd) -= cut; + + return result; +} + +/* handle action */ +static void +doaction( unsigned char *tail ) +{ + while( *tail == ' ' ) tail++; + + if( *tail ) { + /* send users message to server */ + snprintf (tmpstr, TMPSTRSIZE, ".a %s", tail); + networkoutput (tmpstr); + + /* show action in channel window */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBACTION), nick, tail); + writechan (tmpstr); + } else { + + /* missing action */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGTXPUBACTION)); + writechan (tmpstr); + } +} + +/* handle private message outgoing */ +static void +privatemessagetx ( unsigned char *tail ) { + unsigned char *mesg; + + /* find nick */ + while( *tail==' ') tail++; + + /* find message */ + mesg = tail; + while ( *mesg && *mesg!=' ') mesg++; + + /* check for nick && message */ + if(*tail && *mesg) { + + /* terminate nick, move to rel start */ + *mesg++ = '\0'; + + /* form message and send to server */ + snprintf (tmpstr, TMPSTRSIZE, ".m %s %s", tail, mesg); + networkoutput (tmpstr); + + /* show message in private window */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPRIVMSG), tail, mesg); + writepriv (tmpstr); + + /* note we messaged someone */ + ul_msgto(tail); + + } else { + + /* missing nick or message body inform user */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_BGPRIVMSG)); + writepriv (tmpstr); + } +} + +/* handle line entered by user */ +void +handleline (unsigned char *line) +{ +#ifdef DEBUG + /* debugging? log users input! */ + fprintf (stderr, "=| %s\n", line); +#endif + + switch ( line[0] ) + { + case '.': + switch ( line[1] ) { + case 'm': /* sending a private message? */ + privatemessagetx( line+2 ); + break; + case 'a': + doaction( line+2 ); + break; + case '.': + /* .. on start of line is public */ + if( line[2] != 'm' ) { + output_default( line ); + } else { + /* oopsi, "..m " detected */ + /* dunno what to do */ + flushout( ); + writeout("? You probably misstyped ?"); + writeout(" "); + writeout(line ); + showout( ); + } + break; + default: + + /* generic server command, send to server, show to user */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_COMMAND), line); + networkoutput (line); + writechan (tmpstr); + break; + } + break; + case '/': + line++; + commandtable[translatecommand(&line)].handler(line); + break; + case '0': + break; + default: + output_default( line ); + break; + } +} + +static void +output_default( unsigned char *line ) { + /* prepare for output on display */ + snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_TXPUBMSG), nick, line); + + /* send original line to server */ + networkoutput (line); + + /* output message to channel window */ + writechan (tmpstr); +} + +/* handle a "/user " request */ +static void +command_user( unsigned char *tail) +{ + while( *tail == ' ') tail++; + if( strlen(tail) >= 3) { + unsigned char * out = ul_matchuser( tail); + if( *out ) { + snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_USMATCH), tail, out); + } else { + snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "No user matched that substring"); + } + } else { + snprintf( tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Specify at least 3 characters to match users"); + } + writechan( tmpstr ); +} + +/* handle a "/msg " request */ +static void +command_pm (unsigned char *tail) +{ + privatemessagetx( tail ); +} + +/* handle a help request */ +static void +command_help (unsigned char *line) { + flushout( ); + while( *line==' ') line++; + if( *line ) { /* Get help on command */ + int i; + if( ( i = translatecommand( &line ) ) != COMMAND_NONE ) { + snprintf( tmpstr, TMPSTRSIZE, "Help on command: %s", commandtable[i].name); + writeout( tmpstr ); + writeout(" "); + if( commandtable[i].short_help && !commandtable[i].help ) + writeout(commandtable[i].short_help ); + line = commandtable[i].help; + if( line ) { + while( *line ) { + unsigned char *tmp = tmpstr; + while( *line && (*line != '\n') ) + *tmp++ = *line++; + *tmp = '\0'; if( *line == '\n') line++; + writeout ( tmpstr ); + } + } + } else { + command_help( " " ); + } + } else { /* Get overall help */ + int i; + for( i = 0; commandtable[i].number != COMMAND_NONE; i++ ) { + if( commandtable[i].short_help ) + writeout( commandtable[i].short_help ); + } + } + showout(); +} + +/* handle an unknown command */ +static void +command_none( unsigned char *line) { + flushout( ); + snprintf(tmpstr, TMPSTRSIZE, " Unknown client command: %s ", line); + writeout(tmpstr); + showout( ); +} + +/* handle a "/flt " request */ +static void +command_flt( unsigned char *tail){ + unsigned char colour; + while(*tail==' ') tail++; + colour = *tail++; + while( colour && *tail == ' ') tail++; + if( colour && *tail) { + addfilter( colour, tail); + } +} + +/* handle a "/clflt " request */ +static void +command_clflt ( unsigned char *tail) { + while( *tail == ' ') tail++; + clearfilters( *tail ); +} + +/* handle a "/rmflt " request */ +static void +command_rmflt ( unsigned char *tail) { + while( *tail == ' ') tail++; + removefilter( tail ); +} + +/* list filters */ +static void +command_lsflt ( unsigned char *tail) { + listfilters(); +} + +/* handle a "/me " action */ +static void +command_action( unsigned char *tail) +{ + doaction( tail); +} + +/* handle a "/quit " exit */ +static void +command_quit ( unsigned char *tail) +{ + /* send users message to server */ + snprintf (tmpstr, TMPSTRSIZE, ".x %s", tail); + networkoutput (tmpstr); + + /* show action in channel window */ + writechan (tmpstr); +} + +/* print out version */ +void +command_version( unsigned char *tail) +{ + /* output internal versions of all modules */ + flushout(); + writeout (vchat_cl_version); + writeout (vchat_ui_version); + writeout (vchat_io_version); + writeout (vchat_us_version); + writeout (vchat_cm_version); + showout(); +} diff --git a/vchat-config.h b/vchat-config.h new file mode 100755 index 0000000..d7e7305 --- /dev/null +++ b/vchat-config.h @@ -0,0 +1,127 @@ +/* + * vchat-client - alpha version + * vchat-config.h - declaration of configuration array and default values + * + * Copyright (C) 2001 Andreas Kotes + * + * This program is free software. It can be redistributed and/or modified, + * provided that this copyright notice is kept intact. This program is + * distributed in the hope that it will be useful, but without any warranty; + * without even the implied warranty of merchantability or fitness for a + * particular purpose. In no event shall the copyright holder be liable for + * any direct, indirect, incidental or special damages arising in any way out + * of the use of this software. + * + */ + +#ifndef GLOBAL_CONFIG_FILE +# define GLOBAL_CONFIG_FILE "/etc/vchatrc" +#endif + +#ifndef GLOBAL_FORMAT_FILE +# define GLOBAL_FORMAT_FILE "/etc/vchatformats" +#endif + +/* configuration array with structure as defined in vchat.h */ +extern int usessl; +extern int usetime; +extern unsigned int hscroll; + +static volatile configoption configoptions[] = { +/* config-option type name in file default value value localvar */ + {CF_NICK, CO_STR, "nick", NULL, NULL, &nick }, + {CF_FROM, CO_STR, "from", "vc-alpha-0.16", NULL, NULL }, + {CF_SERVERHOST, CO_STR, "host", "pulse.flatline.de",NULL, NULL }, + {CF_SERVERPORT, CO_INT, "port", (char *) 2325, (char *)-1, NULL }, + {CF_CIPHERSUITE, CO_STR, "ciphers", "HIGH:MEDIUM", NULL, NULL }, + {CF_CONFIGFILE, CO_STR, "conffile", "~/.vchat/config", NULL, NULL }, + {CF_CERTFILE, CO_STR, "certfile", "~/.vchat/cert", NULL, NULL }, + {CF_KEYFILE, CO_STR, "keyfile", "~/.vchat/key", NULL, NULL }, + {CF_FORMFILE, CO_STR, "formatfile", "~/.vchat/formats", NULL, NULL }, + {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, (unsigned char **)&usessl }, + {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, NULL }, + {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, (unsigned char **)&usetime }, + {CF_PRIVHEIGHT, CO_INT, "messages", (char *) 0, (char *)-1, NULL }, + {CF_HSCROLL, CO_INT, "hscroll", (char *) 5, (char *)-1, (unsigned char **)&hscroll }, + {CF_CHANNEL, CO_INT, "channel", (char *) 0, (char *)-1, NULL }, + {CF_SCROLLBPRIV, CO_INT, "privscrollb",(char *) 2048, (char *)-1, NULL }, + {CF_SCROLLBACK, CO_INT, "scrollback", (char *) 8192, (char *)-1, NULL }, + {CF_SCROLLBPRIVT,CO_INT, "privscrollt",(char *) 0, (char *)-1, NULL }, + {CF_SCROLLBACKT, CO_INT, "scrolltime", (char *) 86400, (char *)-1, NULL }, + {CF_NIL, CO_NIL, NULL, NULL, NULL, NULL }, +}; + +/* +choose option with \001 + +0 - default colorpair for window +1 - colorpair 1 RED +2 - colorpair 2 GREEN +3 - colorpair 3 YELLOW +4 - colorpair 4 BLUE +5 - colorpair 5 MAGENTA +6 - colorpair 6 CYAN +7 - colorpair 7 WHITE +8 - colorpair 8 WHITE on RED +9 - colorpair 9 WHITE on BLUE +aA - alternate charset on/off +bB - bold on/off +dD - dim on/off +iI - invisible on/off +lL - blink on/off +nN - normal on/off +pP - protected on/off +rR - reverse on/off +sS - standout on/off +uU - underlined on/off +*/ + +#define FE( ID, STRING) { ID, #ID, STRING } + +static formatstring formatstrings[] = { +/* format-string string */ + FE( FS_PLAIN, "%s"), + FE( FS_CHAN, "%s"), + FE( FS_PRIV, "%s"), + FE( FS_SERV, "\0012%s"), + FE( FS_GLOB, "\0012%s"), + FE( FS_DBG, "\0013%s"), + FE( FS_ERR, "\0011%s"), + FE( FS_ERR_STRING, "\0011%s %s"), + FE( FS_IDLE, "\0018%s"), + FE( FS_TIME, "\0015[%H:%M]\0010 "), + FE( FS_TOPICW, "[ Channel %d: %s"), + FE( FS_NOTOPICW, "[ Channel %d has no topic"), + FE( FS_CONSOLE, "[ %s@%s:%d, use .h to get help, send bugs reports and feature requests to vchat@pulse.flatline.de ..."), + FE( FS_CONNECTED, "\0012# Connected to '\0016%s\0012', port \0016%d\0012 ..."), + FE( FS_TOPIC, "\0012# Channel \0016%d\0012 topic is: '\0010%s\0012'"), + FE( FS_NOTOPIC, "\0012# Channel \0016%d\0012 has no topic"), + FE( FS_CHGTOPIC, "\0012# \0016%s\0012 changes topic to: '\0010%s\0012'"), + FE( FS_USMATCH, "\0012# Users matching \"%s\":%s"), + FE( FS_USONLINE, "\0012# Users online: %s"), + FE( FS_SIGNON, "\0012# \0016%s\0012 %s"), + FE( FS_SIGNOFF, "\0012# \0016%s\0012 %s"), + FE( FS_JOIN, "\0012# \0016%s\0012 %s \0016%d"), + FE( FS_LEAVE, "\0012# \0016%s\0012 %s \0016%d"), + FE( FS_NICKCHANGE, "\0012# \0016%s\0012 \0016%s\0012 %s"), + FE( FS_UNKNOWNMSG, "?? unknown message: %s"), + FE( FS_BOGUSMSG, "?? bogus message: %s"), + FE( FS_RXPUBURL, "\0015[\0016%s\0015]\0010 %s"), + FE( FS_MYPUBURL, "\0015[\0016\001u%s\001U\0015]\0010 %s"), + FE( FS_RXPUBMSG, "\0015<\0016%s\0015>\0010 %s"), + FE( FS_MYPUBMSG, "\0015<\0016\001u%s\001U\0015>\0010 %s"), + FE( FS_TXPUBMSG, "\0015<\0016\001b%s\001B\0015>\0010 %s"), + FE( FS_RXPRIVMSG, "\0015*\0016%s\0015*\0010 %s"), + FE( FS_TXPRIVMSG, "\0015-> *\0016%s\0015*\0010 %s"), + FE( FS_BGPRIVMSG, "\0011! Bogus message, not sent."), + FE( FS_PUBACTION, "\0015*\0010 \0016%s\0010 %s"), + FE( FS_TXPUBACTION, "\0015*\0010 \0016\001b%s\001B\0010 %s"), + FE( FS_BGTXPUBACTION,"\0011! No action taken."), + FE( FS_COMMAND, "\0012## command: %s"), + FE( FS_LOCALCOMMAND, "\0012## local command (not executed yet): %s"), + FE( FS_BOGUSCOMMAND, "\0012## bogus command (not executed or sent): %s"), + FE( FS_SBINF, " [%d/%d] "), + FE( FS_MISSTYPED, "\0011* Probably misstyped? Not sent: %s"), + FE( FS_UNKNCMD, "\0011* Unknown client command: %s"), + FE( FS_BADREGEX, "\0011* Could not compile regex: %s"), + FE( FS_PLAIN, NULL) +}; diff --git a/vchat-help.h b/vchat-help.h new file mode 100755 index 0000000..9cfe04b --- /dev/null +++ b/vchat-help.h @@ -0,0 +1,66 @@ +/* + * vchat-client - alpha version + * vchat-help.h - definitions for help on comands + * + * Copyright (C) 2001 Andreas Kotes + * + * This program is free software. It can be redistributed and/or modified, + * provided that this copyright notice is kept intact. This program is + * distributed in the hope that it will be useful, but without any warranty; + * without even the implied warranty of merchantability or fitness for a + * particular purpose. In no event shall the copyright holder be liable for + * any direct, indirect, incidental or special damages arising in any way out + * of the use of this software. + * + */ + +/* Help strings */ + +#define SHORT_HELPTEXT_VERSION "/VERSION Prints out version number of all modules" +#define LONG_HELPTEXT_VERSION NULL +#define SHORT_HELPTEXT_CONFIG "/CONFIG This feature is not implemented, yet" +#define LONG_HELPTEXT_CONFIG NULL +#define SHORT_HELPTEXT_HELP "/HELP [COMMAND] Display this help, or help on COMMAND" +#define LONG_HELPTEXT_HELP NULL +#define SHORT_HELPTEXT_RMFLT "/RMFLT [REGEX | ID] Remove regex or id from filter list" +#define LONG_HELPTEXT_RMFLT SHORT_HELPTEXT_RMFLT +#define SHORT_HELPTEXT_CLFLT "/CLFLT (C) Remove all filter rules (matching C)" +#define LONG_HELPTEXT_CLFLT SHORT_HELPTEXT_CLFLT +#define SHORT_HELPTEXT_LSFLT "/LSFLT (C) List all filter rules (matching C)" +#define LONG_HELPTEXT_LSFLT SHORT_HELPTEXT_LSFLT +#define SHORT_HELPTEXT_FLT "/FLT C REGEX Add regex to filter list" +#define LONG_HELPTEXT_FLT SHORT_HELPTEXT_FLT "\n C may be + - zoom, - - ignore,\n\ + 0 - default, 1 - red, 2 - green,\n\ + 3 - yello, 4 - blue, 5 - magenta,\n\ + 6 - magenta, 7 - white, 8 - white/red\n\ + 9 - blue/red, aA - alt, bB - bold\n\ + dD - dim, iL - invis, lL - blink\n\ + nN - normal, pP - protect, rR - reverse,\n\ + sS - standout, uU - underline" +#define SHORT_HELPTEXT_KEYS "/HELP KEYS Show summary of key commands" +#define LONG_HELPTEXT_KEYS " - - List of Commands:\n\ + ^J - clear private window\n\ + ^O - clear channel window\n\ + ^L - redraw screen/scroll to bottom\n\ + ^F - scroll window up\n\ + ^B - scroll window down\n\ + ^R - change active window\n\ + (watch the *)\n\ + ^T - shrink private window size\n\ + ^G - grow private window size\n\ + ^X - switch off message window or\n\ + toggle private window\n\ + TAB - nick completion" +#define SHORT_HELPTEXT_QUIT "/QUIT [REASON] Leave the chat for reason Reason" +#define LONG_HELPTEXT_QUIT NULL +#define SHORT_HELPTEXT_USER "/USER REGEX Lists all users matching regex REGEX" +#define LONG_HELPTEXT_USER NULL +#define SHORT_HELPTEXT_MSG "/M[SG] USER MESSAGE Send private message to user USER" +#define LONG_HELPTEXT_MSG NULL +#define SHORT_HELPTEXT_ME "/ME ACTION Let the user do an action" +#define LONG_HELPTEXT_ME NULL +#define SHORT_HELPTEXT_M SHORT_HELPTEXT_MSG +#define LONG_HELPTEXT_M LONG_HELPTEXT_MSG +#define SHORT_HELPTEXT_FILTERS "/HELP FILTERS Show summary of filter commands" +#define LONG_HELPTEXT_FILTERS SHORT_HELPTEXT_FLT "\n" SHORT_HELPTEXT_RMFLT "\n" SHORT_HELPTEXT_LSFLT "\n" SHORT_HELPTEXT_CLFLT + diff --git a/vchat-keygen b/vchat-keygen new file mode 100755 index 0000000..08c3b6e --- /dev/null +++ b/vchat-keygen @@ -0,0 +1,156 @@ +#!/bin/sh + +# +# vchat-client - alpha version +# vchat-keygen - generate keypair for SSL with anon CA +# +# Copyright (C) 2001 Andreas Kotes +# +# This program is free software. It can be redistributed and/or modified, +# provided that this copyright notice is kept intact. This program is +# distributed in the hope that it will be useful, but without any warranty; +# without even the implied warranty of merchantability or fitness for a +# particular purpose. In no event shall the copyright holder be liable for +# any direct, indirect, incidental or special damages arising in any way out +# of the use of this software. +# + +# where do we want to store the key? +KEYBASE=$1 +if [ "x$KEYBASE" = "x" ] ; then + KEYBASE=$HOME/.vchat +fi + +# no key? generate one ... +if [ ! -e $KEYBASE.key ]; then + echo "vchat-keygen: generating RSA key $KEYBASE.key" + echo "vchat-keygen: please set passphrase for local security" + umask 0077 + openssl genrsa -des3 -out $KEYBASE.key 2048 +else + echo "vchat-keygen: private key $KEYBASE.key exists" +fi + +# no certificate? dump anonymous CA to disk. +if [ ! -e $KEYBASE.cert ]; then + if [ ! -e $KEYBASE.ca.key ]; then + echo "vchat-keygen: saving CA key to $KEYBASE.ca.key" + cat >$KEYBASE.ca.key <$KEYBASE.ca.crt <$KEYBASE.ca.conf <$KEYBASE.ca.db.index + echo 00 >$KEYBASE.ca.db.serial + fi + if [ ! -e $KEYBASE.csr ]; then + if [ ! -e $KEYBASE.ca.keyconf ]; then + echo "vchat-keygen: generating config-file for self-signing $KEYBASE.ca.keyconf" + cat >$KEYBASE.ca.keyconf < + * + * This program is free software. It can be redistributed and/or modified, + * provided that this copyright notice is kept intact. This program is + * distributed in the hope that it will be useful, but without any warranty; + * without even the implied warranty of merchantability or fitness for a + * particular purpose. In no event shall the copyright holder be liable for + * any direct, indirect, incidental or special damages arising in any way out + * of the use of this software. + * + */ + +/* servermessage array with structure as defined in vchat.h */ + +servermessage servermessages[] = { +/* 100 + Informational message for human consumption */ + {"100", SM_INFO, NULL, NULL}, +/* 110 + User status summary */ + {"110", SM_USERINFO, NULL, NULL}, +/* 111