merge my changes to master

Special thanks to:
- Wolfgang Corcoran-Mathe for sending patches and testing.
- Nico Golde for maintaining ii for so long.
This commit is contained in:
Hiltjo Posthuma 2017-06-02 09:54:54 +02:00
parent 714bd0cb6a
commit 704ab925e9
12 changed files with 942 additions and 469 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
ii
*.a
*.o

31
CHANGES
View File

@ -1,3 +1,34 @@
1.8 (2017-??-??, unreleased):
- prevent nick collisions by only setting the nick after the server
accepted it and print a message about change to server log.
- remove query.sh.
- add OpenBSD pledge(2) support.
- fix QUIT message string.
- raw IRC output to stdout.
- add quit command (/q [string]).
- write timestamp in outfile as UNIX timestamp (UTC+0).
- server host (-s) doesn't default to irc.freenode and is now required.
- add option (-u) to connect directly to a UNIX domain socket, this
is useful for tunneling connections.
- remove "in" file when leaving a channel (enabled commented code).
- remove "in" files on exit.
- use IRC_MAX (512), instead of PIPE_BUF (4096) on most systems.
PIPE_BUF is guaranteed to be atleast 512 bytes for atomic operations.
- Makefile: always be verbose.
- use C99 and -D_DEFAULT_SOURCE
- remove obsolete gethostbyname, use getaddrinfo.
- IPV6 support.
- timeout now uses separate exit statuscode 2.
- cleanup:
- use arg.h for command-line option parsing.
- use sbase util functions (estrtol, eprintf).
- use and import OpenBSD strlcpy().
- man page typos.
- style:
- linewrap to 79 characters.
- coding style fixes.
- non-roman numerals for LICENSE period.
1.7 (2013-01-05)
- -k now specifies an environment variable that contains the
server key. This behaviour has been changed in order to not

19
FAQ
View File

@ -6,6 +6,7 @@ Where is IRC command xy (ignore etc.)?
ii is for advanced users, please use standard tools like awk, sed and grep for
this. This can be done easily and will not bloat the code.
Where is a graphical interface?
-------------------------------
Basically ii follows the UNIX philosophy so it is only file based. But it
@ -14,12 +15,14 @@ the FIFOs and output files. Feel free to implement or wait until we have done
this. Actually I use ii in combination with vim, multitail and screen and it works
like a charm.
Which commands are supported?
-----------------------------
j (join or msg), t (topic), a (away), n (nick), l (leave). The missing are
obsolete or can be easily used by typing the IRC commands itself (i.e. /WHO
instead of /who).
How can I recognize queries?
----------------------------
ii itself doesn't support this but the queries.sh script is an example
@ -28,9 +31,23 @@ To get an instant notice of a new file other mechanisms like inotify/dnotify
could be used as well but I was too lazy to try it out since the script
is enough for me.
What other fancy stuff can I do with ii?
----------------------------------------
It is very easy to write irc bots in ii:
tail -f \#/out | while read foo; do name=echo $foo | awk '{print $2}' | sed 's,<\\(.*\\)>,\\1,'; if 0 -eq expr $RANDOM % 10 then echo "$name: WHAT??" ; fi; done
#!/bin/sh
chan="#yourchannel"
tail -f "${chan}/out" | while read -r line; do
cmd=$(printf '%s\n' "$line" | cut -d ' ' -f 4-)
name=$(printf '%s\n' "$line" | cut -d ' ' -f 3 | tr -d '<>')
if [ "$cmd" = "!rand" ]; then
r="$RANDOM"
if expr "$r" "%" "10"; then
echo "$name: $r" >> "${chan}/in"
fi
fi
done
This will just spam a channel but think about using nagios2irc or you can
use ii to generate channel stats. Your imagination should be boundless.

View File

@ -1,7 +1,8 @@
MIT/X Consortium License
(C)opyright MMV-MMVI Anselm R. Garbe <garbeam@wmii.de>
(C)opyright MMV-MMVIII Nico Golde <nico at ngolde dot de>
(C)opyright 2005-2006 Anselm R. Garbe <garbeam@wmii.de>
(C)opyright 2005-2011 Nico Golde <nico at ngolde dot de>
(C)opyright 2014-2017 Hiltjo Posthuma <hiltjo at codemadness dot org>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

View File

@ -1,55 +1,48 @@
# ii - irc it - simple but flexible IRC client
# (C)opyright MMV-MMVI Anselm R. Garbe
# (C)opyright MMV-MMVII Anselm R. Garbe, Nico Golde
# See LICENSE file for copyright and license details.
include config.mk
SRC = ii.c
OBJ = ${SRC:.c=.o}
SRC = ii.c strlcpy.c
OBJ = ${SRC:.c=.o}
all: options ii
@echo built ii
all: ii
options:
@echo ii build options:
@echo "LIBS = ${LIBS}"
@echo "INCLUDES = ${INCLUDES}"
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
.o:
$(LD) -o $@ $< $(LDFLAGS)
dist: clean
@mkdir -p ii-${VERSION}
@cp -R query.sh Makefile CHANGES README FAQ LICENSE config.mk ii.c ii.1 ii-${VERSION}
@tar -cf ii-${VERSION}.tar ii-${VERSION}
@gzip ii-${VERSION}.tar
@rm -rf ii-${VERSION}
@echo created distribution ii-${VERSION}.tar.gz
.c.o:
$(CC) -c -o $@ $< $(CFLAGS)
ii: ${OBJ}
@echo LD $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
${CC} -o $@ ${OBJ} ${LDFLAGS}
install: all
@mkdir -p ${DESTDIR}${DOCDIR}
@mkdir -p ${DESTDIR}${BINDIR}
@mkdir -p ${DESTDIR}${MAN1DIR}
@install -d ${DESTDIR}${BINDIR} ${DESTDIR}${MAN1DIR}
@install -m 644 CHANGES README query.sh FAQ LICENSE ${DESTDIR}${DOCDIR}
@install -m 775 ii ${DESTDIR}${BINDIR}
@install -m 444 ii.1 ${DESTDIR}${MAN1DIR}
@echo "installed ii"
mkdir -p ${DESTDIR}${DOCDIR}
mkdir -p ${DESTDIR}${BINDIR}
mkdir -p ${DESTDIR}${MAN1DIR}
install -d ${DESTDIR}${BINDIR} ${DESTDIR}${MAN1DIR}
install -m 644 CHANGES README FAQ LICENSE ${DESTDIR}${DOCDIR}
install -m 775 ii ${DESTDIR}${BINDIR}
sed "s/VERSION/${VERSION}/g" < ii.1 > ${DESTDIR}${MAN1DIR}/ii.1
chmod 644 ${DESTDIR}${MAN1DIR}/ii.1
uninstall: all
@rm -f ${DESTDIR}${MAN1DIR}/ii.1
@rm -rf ${DESTDIR}${DOCDIR}
@rm -f ${DESTDIR}${BINDIR}/ii
@echo "uninstalled ii"
rm -f ${DESTDIR}${MAN1DIR}/ii.1 \
${DESTDIR}${BINDIR}/ii
rm -rf ${DESTDIR}${DOCDIR}
dist: clean
mkdir -p ii-${VERSION}
cp -R Makefile CHANGES README FAQ LICENSE strlcpy.c arg.h \
config.mk ii.c ii.1 ii-${VERSION}
tar -cf ii-${VERSION}.tar ii-${VERSION}
gzip ii-${VERSION}.tar
rm -rf ii-${VERSION}
clean:
rm -f ii *~ *.o *core *.tar.gz
rm -f ii *.o

51
README
View File

@ -1,7 +1,7 @@
Abstract
--------
ii is a minimalistic FIFO and filesystem based IRC client. It creates an irc
directory tree with server, channel and nick name directories. In every
directory tree with server, channel and nick name directories. In every
directory a FIFO file (in) and normal file (out) is placed.
The in file is used to communicate with the servers and the out files include
@ -13,6 +13,7 @@ standard command line tools. For example if you want to join a channel just do
echo "/j #channel" > in and ii creates a new channel directory with in and out
file.
Installation
------------
Edit config.mk to match your local setup. ii is installed into
@ -23,6 +24,7 @@ necessary as root):
$ make clean install
Running ii
------------
Simply invoke the 'ii' command with required arguments
@ -41,19 +43,50 @@ Thanks to Matthias Kopfermann for this hint.
You can find an example of how this nested environment could look like on:
http://nion.modprobe.de/blog/archives/440-Using-the-ii-irc-client.html
SSL/TLS support
---------------
Below is an example using OpenBSD relayd which sets up a TCP TLS relay
connection on localhost. A similar setup can be accomplished using
stunnel or netcat with TLS support. This also works for other programs
that don't support TLS natively.
/etc/relayd.conf:
table <freenode> { irc.freenode.net }
table <oftc> { irc.oftc.net }
protocol "irctls" {
tcp { nodelay, sack }
}
relay "freenode" {
listen on 127.0.0.1 port 6668
protocol "irctls"
forward with tls to <freenode> port 6697
}
relay "oftc" {
listen on 127.0.0.1 port 6669
protocol "irctls"
forward with tls to <oftc> port 6697
}
Then connect:
./irc -n nick -u name -s 127.0.0.1 -p 6668
./irc -n nick -u name -s 127.0.0.1 -p 6669
Configuration
-------------
No configuration is needed.
Changelog
---------
Since I missed the chance to add a proper changelog right from the beginning,
please have a look at the commit messages on http://code.suckless.org/hg/ii/
please have a look at the commit messages on http://git.suckless.org/ii/
they are fairly descriptive on releases prior to 1.2.
Contact
-------
If you want to contact the developers just write a mail to
ii (at) modprobe (dot) de
-- Nico Golde, Anselm R. Garbe

49
arg.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef ARG_H__
#define ARG_H__
extern char *argv0;
/* use main(int argc, char *argv[]) */
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
argv[0] && argv[0][0] == '-'\
&& argv[0][1];\
argc--, argv++) {\
char argc_;\
char **argv_;\
int brk_;\
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
argv++;\
argc--;\
break;\
}\
for (brk_ = 0, argv[0]++, argv_ = argv;\
argv[0][0] && !brk_;\
argv[0]++) {\
if (argv_ != argv)\
break;\
argc_ = argv[0][0];\
switch (argc_)
#define ARGEND }\
}
#define ARGC() argc_
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
((x), abort(), (char *)0) :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
(char *)0 :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#endif

View File

@ -1,4 +1,5 @@
# Customize to fit your system
VERSION = 1.7
# paths
PREFIX = /usr/local
@ -12,17 +13,18 @@ DESTDIR =
INCDIR = ${PREFIX}/include
LIBDIR = ${PREFIX}/lib
VERSION = 1.7
# includes and libs
INCLUDES = -I. -I${INCDIR} -I/usr/include
LIBS = -L${LIBDIR} -L/usr/lib -lc
# uncomment and comment other variables for compiling on Solaris
#LIBS = -L${LIBDIR} -L/usr/lib -lc -lsocket -lnsl
#CFLAGS = -g ${INCLUDES} -DVERSION=\"${VERSION}\"
# compiler
CC = cc
CFLAGS = -g -O0 -W -Wall ${INCLUDES} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
# debug
#CFLAGS = -g -O0 -pedantic -Wall ${INCLUDES} -DVERSION=\"${VERSION}\" -std=c99 -D_DEFAULT_SOURCE
#LDFLAGS = ${LIBS}
# release
CFLAGS = -Os ${INCLUDES} -DVERSION=\"${VERSION}\" -std=c99 -D_DEFAULT_SOURCE
LDFLAGS = -s

61
ii.1
View File

@ -1,10 +1,6 @@
.de FN
\fI\|\\$1\|\fP\\$2
..
.TH ii 1
.TH II 1 ii\-VERSION
.SH NAME
ii \- irc it or irc improved
.SH DESCRIPTION
.B ii
is a minimalistic FIFO and filesystem based IRC client.
@ -21,23 +17,27 @@ For example if you will join a channel just do echo "/j #channel" > in
and ii creates a new channel directory with in and out file.
.SH SYNOPSIS
.B ii
.RB [ \-s
.IR servername ]
.RB < \-s
.IR servername >
.RB [ \-p
.IR port ]
.RB [ \-k
.IR environment variable ]
.IR "environment variable" ]
.RB [ \-i
.IR prefix ]
.RB [ \-n
.IR nickname ]
.RB [ \-f
.IR realname ]
.RB < \-u
.IR sockname >
.SH OPTIONS
.TP
.BI \-s " servername"
lets you override the default servername (irc.freenode.net)
server to connect to, for example: irc.freenode.net
.TP
.BI \-u " sockname"
connect to a UNIX domain socket instead of directly to a server.
.TP
.BI \-p " port"
lets you override the default port (6667)
@ -54,44 +54,47 @@ lets you override the default nick ($USER)
.TP
.BI \-f " realname"
lets you specify your real name associated with your nick
.SH DIRECTORIES
.TP
.FN ~/irc
.B ~/irc
In this directory the irc tree will be created. In this directory you
will find a directory for your server (default: irc.freenode.net) in
which the FIFO and the output file will be stored.
If you join a channel a new directory with the name of the channel
will be created in the ~/irc/$servername/ directory.
.SH COMMANDS
.TP
.FN /a " [<message>]"
.BI /a " [<message>]"
mark yourself as away
.TP
.FN /j " #channel/nickname [<message>]"
.BI /j " #channel/nickname [<message>]"
join a channel or open private conversation with user
.TP
.FN /l " #channel/nickname"
.BI /l " [reason]"
leave a channel or query
.TP
.FN /n " nick"
.BI /n " nick"
change the nick name
.TP
.FN /t " topic"
.BI /q " [reason]"
quit ii
.TP
.BI /t " topic"
set the topic of a channel
.TP
Everything which is not a command will simply be posted into the channel or to the server.
So if you need /who just write /WHO as described in the RFC to the server in FIFO.
.TP
.FN "out file usage"
Write wrappers, pagers or use your tools of choice to display the out file contents (loco, multitail, etc.).
.SH RAW COMMANDS
.LP
Everything which is not a command will be posted into the channel or to the server.
So if you need /who just write /WHO as described in RFC#1459 to the server in FIFO.
.SH SSL PROTOCOL SUPPORT
.LP
For TLS/SSL protocol support you can connect to a local tunnel, for example with stunnel or socat.
.SH CONTACT
.TP
Write to ii (at) modprobe (dot) de for suggestions, fixes, 7|-|>< ;) etc.
.LP
Subscribe to the mailinglist and write to dev (at) suckless (dot) org for suggestions, fixes, etc.
.SH AUTHORS
Copyright \(co 2005-2006 by Anselm R. Garbe <garbeam (at) gmail (dot) com> and
Copyright \(co 2005-2008 by Nico Golde <nico (at) ngolde (dot) de>
ii engineers, see LICENSE file
.SH SEE ALSO
.BR echo (1),
.BR tail (1),
.BR tail (1)
.SH BUGS
Please report them!

1053
ii.c

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
#!/bin/sh
# ----------------------------------------------------
# Nico Golde <nico@ngolde.de>
# License: do whatever you want with this code
# Purpose: locate new queries for the ii irc client
# ----------------------------------------------------
IRCPATH=$HOME/irc
TMPFILE=$IRCPATH/queries.tmp
if [ ! -f $TMPFILE ]; then
touch $TMPFILE
fi
echo "searching new query data"
for i in `find $IRCPATH -newer $TMPFILE -name 'out'`
do
grep -v '\-!\-' $i > /dev/null 2>&1 # if file doesnt just contain server stuff
if [ $? -ne 1 ]; then
# strip server, nickserv and channel out files
echo $i | egrep -v -i "nickserv|#|$IRCPATH/(irc\.freenode\.net|irc\.oftc\.net)/out" > /dev/null 2>&1
if [ $? -ne 1 ]; then
printf "new data in: %s\n========================================================\n" "$i"
tail -5 $i
fi
fi
done
touch $TMPFILE

32
strlcpy.c Normal file
View File

@ -0,0 +1,32 @@
/* Taken from OpenBSD */
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}