Compare commits

...

9 Commits
1.9 ... master

Author SHA1 Message Date
Quentin Rameau 39907c79a4 usage: Normalize a bit the usage and man-page 2022-09-05 23:19:14 +02:00
Hiltjo Posthuma 25c000bf98 ii.1: fix some lint warnings from mandoc -Tlint 2022-09-02 12:25:11 +02:00
Hiltjo Posthuma 5bd50577a9 ii: fix mistake in usage, the host is actually mandatory
Reported by Petr Vaněk <arkamar@atlas.cz>, thanks!
2022-09-02 12:23:40 +02:00
Hiltjo Posthuma 00698e45ea Makefile: fix make dist if it is run more than once
... and stream directly to compressed tarball.
2022-09-02 11:52:58 +02:00
Hiltjo Posthuma 3fab03ea0b remove unmaintained changelog 2022-09-02 11:50:51 +02:00
Hiltjo Posthuma 36c77931fd Makefile: simplify and use system flags by default 2022-09-02 11:49:34 +02:00
Hiltjo Posthuma acbc72748d LICENSE: bump license year 2022-09-02 11:35:15 +02:00
Hiltjo Posthuma 2d0480ce81 ii.1: improve documentation of usage options
* Also improve the order of options and consistency with the usage in ii.c.
* Remove some redundant sections.

Adapted from a patch by Petr Vaněk <arkamar@atlas.cz>, thanks!
2022-09-02 11:33:46 +02:00
Tom Schwindl 71c1e50da0 ii: Add a die() function to replace fprintf(3) + exit(3) calls 2022-08-12 09:10:20 +02:00
6 changed files with 138 additions and 204 deletions

73
CHANGES
View File

@ -1,73 +0,0 @@
1.8 (2018-02-04):
- 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
expose the password in the process list.
- Fix parsing of JOIN messages for certain servers.
Thanks Ivan Kanakarakis!
- Use , rather than _ for slash characters in channel names.
As per RFC , is not allowed in a channel name, while _ is.
Thanks plomplomplom and Nils Dagsson Moskopp!
1.6 (2011-01-31):
- fix regression introduced for handling unknown commands
1.5 (2011-01-24):
- fix channel name comparison in add_channel(), compare lowercase
to prevent leaking file descriptors in the long run => Thanks samurai!
- only handle commands ii explicitely understands and treat the rest
as raw irc (only worked for raw commands in capital lettersin the past) => Thanks samurai!
- create in FIFO on receiving a privmsg directly instead of requiring a new
/j command first => Thanks Evan Gates
this also implies that in FIFOs aren't deleted on channel leaves any longer because
this itself creates a channel event again which in turn would recreate the file
- minor changes
1.4 (2008-08-09):
- fix directory traversal on servers that support SAJOIN
NOTE: not marking as security relevant as it is only possible to
create directories outside (which is of course annoying) of the irc
hierarchy but not overwriting arbitrary files with the channel name.
- documentation fixes
- general cleanup
1.3 (2007-07-14):
- server messages about users (QUIT,JOIN) will no longer
go to the user directories but to the server out file to
give an easy method to monitor it and to prevent spamming
the irc directory.
1.2 (2007-06-23):
- Exit on channel creation failure, thanks Michael Prokop
- Implemented joining of password protected channels
- Removed -v option from the manpage since it's not implemented

View File

@ -1,6 +1,6 @@
MIT/X Consortium License
(C)opyright 2014-2018 Hiltjo Posthuma <hiltjo at codemadness dot org>
(C)opyright 2014-2022 Hiltjo Posthuma <hiltjo at codemadness dot org>
(C)opyright 2005-2006 Anselm R. Garbe <garbeam@wmii.de>
(C)opyright 2005-2011 Nico Golde <nico at ngolde dot de>

View File

@ -1,26 +1,38 @@
# See LICENSE file for copyright and license details.
.POSIX:
include config.mk
VERSION = 1.9
# paths
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man
DOCPREFIX = $(PREFIX)/share/doc
SRC = ii.c
OBJ = $(SRC:.c=.o)
IICFLAGS = -DVERSION=\"$(VERSION)\" -D_DEFAULT_SOURCE $(CFLAGS)
# use system flags.
II_CFLAGS = $(CFLAGS)
II_LDFLAGS = $(LDFLAGS)
# on systems which provide strlcpy(3),
# remove NEED_STRLCPY from CPPFLAGS and
# remove strlcpy.o from LIBS
II_CPPFLAGS = $(CPPFLAGS) -DVERSION=\"$(VERSION)\" -D_DEFAULT_SOURCE -DNEED_STRLCPY
LIBS = strlcpy.o
all: ii
options:
@echo ii build options:
@echo "CFLAGS = $(IICFLAGS)"
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
.c.o:
$(CC) $(IICFLAGS) -c $<
$(CC) -c $< $(II_CFLAGS) $(II_CPPFLAGS)
ii: $(OBJ) $(LIBS)
$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
$(CC) -o $@ $(OBJ) $(LIBS) $(II_LDFLAGS)
$(OBJ): arg.h
@ -28,7 +40,7 @@ install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
mkdir -p $(DESTDIR)$(DOCPREFIX)/ii
install -m 644 CHANGES README FAQ LICENSE $(DESTDIR)$(DOCPREFIX)/ii
install -m 644 README FAQ LICENSE $(DESTDIR)$(DOCPREFIX)/ii
install -m 775 ii $(DESTDIR)$(PREFIX)/bin
sed "s/VERSION/$(VERSION)/g" < ii.1 > $(DESTDIR)$(MANPREFIX)/man1/ii.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/ii.1
@ -39,10 +51,9 @@ uninstall: all
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
cp -R Makefile README FAQ LICENSE strlcpy.c arg.h \
ii.c ii.1 ii-$(VERSION)
tar -cf - ii-$(VERSION) | gzip -c > ii-$(VERSION).tar.gz
rm -rf ii-$(VERSION)
clean:

View File

@ -1,14 +0,0 @@
# Customize to fit your system
VERSION = 1.9
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
DOCPREFIX = ${PREFIX}/share/doc
# on systems which provide strlcpy(3),
# remove NEED_STRLCPY from CFLAGS and
# remove strlcpy.o from LIBS
CFLAGS = -DNEED_STRLCPY -Os
LDFLAGS = -s
LIBS = strlcpy.o

125
ii.1
View File

@ -1,6 +1,23 @@
.TH II 1 ii\-VERSION
.TH II 1 ii-VERSION
.SH NAME
ii \- irc it or irc improved
ii - irc it or irc improved
.SH SYNOPSIS
.B ii
.B -s
.I host
.RB [ -p
.I port
|
.B -u
.IR sockname ]
.RB [ -i
.IR ircdir ]
.RB [ -n
.IR nickname ]
.RB [ -f
.IR realname ]
.RB [ -k
.IR env_pass ]
.SH DESCRIPTION
.B ii
is a minimalistic FIFO and filesystem based IRC client.
@ -15,45 +32,34 @@ The basic idea of this is to be able to communicate with an IRC
server with basic command line tools.
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 [ \-p
.IR port ]
.RB [ \-k
.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"
server to connect to, for example: irc.freenode.net
.BI -s " host"
server/host 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"
.BI -p " port"
lets you override the default port (6667)
.TP
.BI \-k " environment variable"
lets you specify an environment variable that contains your IRC password, e.g. IIPASS="foobar" ii -k IIPASS.
This is done in order to prevent other users from eavesdropping the server password via the process list.
.BI -u " sockname"
connect to a UNIX domain socket instead of directly to a server.
If set, the
.B -p
option will be ignored.
.TP
.BI \-i " prefix"
.BI -i " ircdir"
lets you override the default irc path (~/irc)
.TP
.BI \-n " nickname"
.BI -n " nickname"
lets you override the default nick ($USER)
.TP
.BI \-f " realname"
.BI -f " realname"
lets you specify your real name associated with your nick
.TP
.BI -k " env_pass"
lets you specify an environment variable that contains your IRC password,
e.g. IIPASS="foobar" ii -k IIPASS.
This is done in order to prevent other users from eavesdropping the server
password via the process list.
.SH DIRECTORIES
.TP
.B ~/irc
@ -61,40 +67,55 @@ 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.
will be created in the
.BI ~/irc/ servername /
directory.
.SH COMMANDS
.TP
.BI /a " [<message>]"
mark yourself as away
.BI /a " [message]"
mark yourself as away,
with the optional
.I message
as an away reason.
.TP
.BI /j " #channel/nickname [<message>]"
join a channel or open private conversation with user
.BI /j " #channel [password]"
join a
.IR #channel ,
with the optional
.IR password .
.TP
.BI /j " nickname [message]"
open private conversation with user
.I nickname
and directly send the optional
.IR message .
.TP
.BI /l " [reason]"
leave a channel or query
leave a channel or query,
giving the optional
.I reason
message.
.TP
.BI /n " nick"
change the nick name
change the nick name to
.IR nick .
.TP
.BI /q " [reason]"
quit ii
quit ii,
giving the optional
.I reason
message.
.TP
.BI /t " topic"
set the topic of a channel
set the topic of a channel with
.IR topic.
.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
.LP
Subscribe to the mailinglist and write to dev (at) suckless (dot) org for suggestions, fixes, etc.
.SH AUTHORS
ii engineers, see LICENSE file
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/TLS PROTOCOL SUPPORT
For SSL/TLS protocol support you can connect to a local tunnel, for example
with stunnel or socat.
.SH SEE ALSO
.BR echo (1),
.BR tail (1)
.SH BUGS
Please report them!

95
ii.c
View File

@ -56,6 +56,7 @@ static int channel_reopen(Channel *);
static void channel_rm(Channel *);
static void create_dirtree(const char *);
static void create_filepath(char *, size_t, const char *, const char *, const char *);
static void die(const char *, ...);
static void ewritestr(int, const char *);
static void handle_channels_input(int, Channel *);
static void handle_server_output(int);
@ -83,13 +84,22 @@ static char _nick[32]; /* nickname at startup */
static char ircpath[PATH_MAX]; /* irc dir (-i) */
static char msg[IRC_MSG_MAX]; /* message buf used for communication */
static void
die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
static void
usage(void)
{
fprintf(stderr, "usage: %s <-s host> [-i <irc dir>] [-p <port>] "
"[-u <sockname>] [-n <nick>] [-k <password>] "
"[-f <fullname>]\n", argv0);
exit(1);
die("usage: %s -s host [-p port | -u sockname] [-i ircdir]\n"
" [-n nickname] [-f fullname] [-k env_pass]\n", argv0);
}
static void
@ -103,10 +113,8 @@ ewritestr(int fd, const char *s)
if ((w = write(fd, s + off, len - off)) == -1)
break;
}
if (w == -1) {
fprintf(stderr, "%s: write: %s\n", argv0, strerror(errno));
exit(1);
}
if (w == -1)
die("%s: write: %s\n", argv0, strerror(errno));
}
/* creates directories bottom-up, if necessary */
@ -184,8 +192,7 @@ create_filepath(char *filepath, size_t len, const char *path,
return;
error:
fprintf(stderr, "%s: path to irc directory too long\n", argv0);
exit(1);
die("%s: path to irc directory too long\n", argv0);
}
static int
@ -229,10 +236,8 @@ channel_new(const char *name)
strlcpy(channelpath, name, sizeof(channelpath));
channel_normalize_path(channelpath);
if (!(c = calloc(1, sizeof(Channel)))) {
fprintf(stderr, "%s: calloc: %s\n", argv0, strerror(errno));
exit(1);
}
if (!(c = calloc(1, sizeof(Channel))))
die("%s: calloc: %s\n", argv0, strerror(errno));
strlcpy(c->name, name, sizeof(c->name));
channel_normalize_name(c->name);
@ -341,21 +346,17 @@ udsopen(const char *uds)
size_t len;
int fd;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "%s: socket: %s\n", argv0, strerror(errno));
exit(1);
}
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
die("%s: socket: %s\n", argv0, strerror(errno));
sun.sun_family = AF_UNIX;
if (strlcpy(sun.sun_path, uds, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
fprintf(stderr, "%s: UNIX domain socket path truncation\n", argv0);
exit(1);
}
if (strlcpy(sun.sun_path, uds, sizeof(sun.sun_path)) >= sizeof(sun.sun_path))
die("%s: UNIX domain socket path truncation\n", argv0);
len = strlen(sun.sun_path) + 1 + sizeof(sun.sun_family);
if (connect(fd, (struct sockaddr *)&sun, len) == -1) {
fprintf(stderr, "%s: connect: %s\n", argv0, strerror(errno));
exit(1);
}
if (connect(fd, (struct sockaddr *)&sun, len) == -1)
die("%s: connect: %s\n", argv0, strerror(errno));
return fd;
}
@ -370,10 +371,8 @@ tcpopen(const char *host, const char *service)
hints.ai_flags = AI_NUMERICSERV; /* avoid name lookup for port */
hints.ai_socktype = SOCK_STREAM;
if ((e = getaddrinfo(host, service, &hints, &res))) {
fprintf(stderr, "%s: getaddrinfo: %s\n", argv0, gai_strerror(e));
exit(1);
}
if ((e = getaddrinfo(host, service, &hints, &res)))
die("%s: getaddrinfo: %s\n", argv0, gai_strerror(e));
for (rp = res; rp; rp = rp->ai_next) {
fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
@ -386,11 +385,9 @@ tcpopen(const char *host, const char *service)
}
break; /* success */
}
if (fd == -1) {
fprintf(stderr, "%s: could not connect to %s:%s: %s\n",
if (fd == -1)
die("%s: could not connect to %s:%s: %s\n",
argv0, host, service, strerror(errno));
exit(1);
}
freeaddrinfo(res);
return fd;
@ -705,11 +702,9 @@ handle_server_output(int ircfd)
{
char buf[IRC_MSG_MAX];
if (read_line(ircfd, buf, sizeof(buf)) == -1) {
fprintf(stderr, "%s: remote host closed connection: %s\n",
argv0, strerror(errno));
exit(1);
}
if (read_line(ircfd, buf, sizeof(buf)) == -1)
die("%s: remote host closed connection: %s\n", argv0, strerror(errno));
fprintf(stdout, "%lu %s\n", (unsigned long)time(NULL), buf);
fflush(stdout);
proc_server_cmd(ircfd, buf);
@ -758,8 +753,7 @@ run(int ircfd, const char *host)
if (r < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "%s: select: %s\n", argv0, strerror(errno));
exit(1);
die("%s: select: %s\n", argv0, strerror(errno));
} else if (r == 0) {
if (time(NULL) - last_response >= PING_TIMEOUT) {
channel_print(channelmaster, "-!- ii shutting down: ping timeout");
@ -791,10 +785,9 @@ main(int argc, char *argv[])
int ircfd, r;
/* use nickname and home dir of user by default */
if (!(spw = getpwuid(getuid()))) {
fprintf(stderr, "%s: getpwuid: %s\n", argv0, strerror(errno));
exit(1);
}
if (!(spw = getpwuid(getuid())))
die("%s: getpwuid: %s\n", argv0, strerror(errno));
strlcpy(nick, spw->pw_name, sizeof(nick));
snprintf(prefix, sizeof(prefix), "%s/irc", spw->pw_dir);
@ -835,17 +828,13 @@ main(int argc, char *argv[])
#ifdef __OpenBSD__
/* OpenBSD pledge(2) support */
if (pledge("stdio rpath wpath cpath dpath", NULL) == -1) {
fprintf(stderr, "%s: pledge: %s\n", argv0, strerror(errno));
exit(1);
}
if (pledge("stdio rpath wpath cpath dpath", NULL) == -1)
die("%s: pledge: %s\n", argv0, strerror(errno));
#endif
r = snprintf(ircpath, sizeof(ircpath), "%s/%s", prefix, host);
if (r < 0 || (size_t)r >= sizeof(ircpath)) {
fprintf(stderr, "%s: path to irc directory too long\n", argv0);
exit(1);
}
if (r < 0 || (size_t)r >= sizeof(ircpath))
die("%s: path to irc directory too long\n", argv0);
create_dirtree(ircpath);
channelmaster = channel_add(""); /* master channel */