39 Commits
0.1 ... 0.8

Author SHA1 Message Date
Anselm R. Garbe
0a903a0c79 using Tcmd successors more carefully 2007-01-31 11:01:34 +01:00
Anselm R. Garbe
8edb0e23f4 Added tag 0.7 for changeset 643a6e8b8634 2007-01-11 11:44:41 +01:00
Anselm R. Garbe
44e0417e14 applied some segfault patches of Adrien Krunch Kunysz (thanks to Adrien!) 2007-01-11 11:35:02 +01:00
arg@mig29
148029905b V7 2006-12-14 16:52:12 +01:00
arg@mig29
f8d2e7f236 fixed sizeof stuff 2006-11-26 15:53:33 +01:00
arg@mig29
dc15c0d639 Added tag 0.6 for changeset d7923d9e717c1c6f1ed3b17ec90bfdd7e7bfcca0 2006-11-09 17:38:01 +01:00
arg@mig29
73e181ce5b fixed a small grammar typo 2006-11-09 17:37:57 +01:00
arg@mig29
9197fee8a9 new time info 2006-11-03 14:32:05 +01:00
arg@mig29
45ff5ccf31 Added tag 0.5 for changeset 70d49a37b35695f2f771bddaf309f05ea60af8bc 2006-10-26 12:16:42 +02:00
Anselm R. Garbe
fe306465d0 same problem in sic as in dmenu 2006-10-23 10:56:06 +02:00
Anselm R. Garbe
1f3f048ab7 Added tag 0.4 for changeset a3549fb4c72ff0edb816c8c29be7ff289db5b003 2006-10-13 11:10:41 +02:00
Anselm R. Garbe
3160fd2bed hotfix 2006-10-12 08:03:37 +02:00
Anselm R. Garbe
560111d4ba hotfix 2006-10-11 18:23:03 +02:00
Anselm R. Garbe
48fc6f1b10 removed useless crap 2006-10-09 18:01:26 +02:00
Anselm R. Garbe
4120182a49 changed version 2006-10-09 07:28:43 +02:00
Anselm R. Garbe
516c1cafaf fixed arg processing 2006-10-09 07:26:24 +02:00
Anselm R. Garbe
3a24553892 code polishing, removed useless crap 2006-10-09 07:20:07 +02:00
arg@zarathustra
83e05870ce small change to man page 2006-09-26 17:52:37 +02:00
arg@mmvi
089bad0eb0 updated README 2006-09-26 14:32:24 +02:00
arg@mmvi
1ad6394622 Added tag 0.3 for changeset d77f00af559258679a0fad5d264685d663e6975a 2006-09-26 14:27:34 +02:00
arg@mmvi
78e0c4f9ee new tag 2006-09-26 14:27:31 +02:00
arg@wmii.de
b3412f0a14 new stuff 2006-09-26 14:24:26 +02:00
arg@mmvi
1230561e3d Added tag 0.3 for changeset dc05747ec127039afaa350094add73d151d17b72 2006-09-26 14:14:48 +02:00
arg@wmii.de
b8950627a7 hotfix 2006-09-20 11:18:27 +02:00
arg@mmvi
5d19f0415e simplified sic 2006-09-19 16:54:52 +02:00
Anselm R. Garbe
2c257c70bc fixed several annoyances 2006-09-05 09:47:15 +02:00
Anselm R. Garbe
fb185a5e18 removed html crap 2006-09-05 07:32:24 +02:00
Anselm R. Garbe
c9668b78f2 preparing new sic version 2006-09-05 07:31:46 +02:00
Anselm R. Garbe
c2fcf48e6d applied Adriens patch 2006-09-04 08:54:14 +02:00
arg@10ksloc.org
ee77b8efae Added tag 0.2 for changeset 56350a01f27753cfbdbb3dbc25f2a53dd4c2ac45 2006-07-21 21:12:33 +02:00
arg@10ksloc.org
e9f9154ab7 made sic 0.2 2006-07-21 21:12:29 +02:00
arg@10ksloc.org
9d87b90d50 fixed fullname handling in login 2006-07-21 15:46:05 +02:00
arg@10ksloc.org
6255ad68d6 I don't care if irc server is truncated 2006-07-21 13:45:34 +02:00
arg@10ksloc.org
348c5b3afc made more error safe 2006-07-21 10:05:51 +02:00
arg@10ksloc.org
718c4bca32 removed dbeug 2006-07-21 08:36:20 +02:00
arg@10ksloc.org
b1989c74e6 urgent fix 2006-07-21 08:28:25 +02:00
arg@10ksloc.org
5b23d0e6b8 improved output printf's 2006-07-21 07:30:04 +02:00
arg@10ksloc.org
a1237900a9 added sys/time.h inclusion 2006-07-20 17:27:30 +02:00
arg@10ksloc.org
8693d1725f Added tag 0.1 for changeset de32c537aaf66554894712563ffba8d9bc4c2714 2006-07-20 10:45:51 +02:00
7 changed files with 181 additions and 232 deletions

7
.hgtags Normal file
View File

@@ -0,0 +1,7 @@
de32c537aaf66554894712563ffba8d9bc4c2714 0.1
56350a01f27753cfbdbb3dbc25f2a53dd4c2ac45 0.2
d77f00af559258679a0fad5d264685d663e6975a 0.3
a3549fb4c72ff0edb816c8c29be7ff289db5b003 0.4
70d49a37b35695f2f771bddaf309f05ea60af8bc 0.5
d7923d9e717c1c6f1ed3b17ec90bfdd7e7bfcca0 0.6
643a6e8b8634b70d2459637fcfff6eca776fc919 0.7

View File

@@ -1,59 +1,57 @@
# ii - irc it - simple but flexible IRC client
# (C)opyright MMV Anselm R. Garbe, Nico Golde
# sic - simple irc client
# (C)opyright MMVI Anselm R. Garbe
include config.mk
SRC = sic.c
OBJ = ${SRC:.c=.o}
MAN1 = sic.1
BIN = sic
all: options sic
@echo built sic
options:
@echo ii build options:
@echo "LIBS = ${LIBS}"
@echo sic build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@echo "LD = ${LD}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.mk
sic: ${OBJ}
@echo LD $@
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:
rm -f sic *.o core sic-${VERSION}.tar.gz
@echo cleaning
@rm -f sic ${OBJ} sic-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
@mkdir -p sic-${VERSION}
@cp -R Makefile README LICENSE config.mk sic.c sic.1 sic-${VERSION}
@cp -R LICENSE Makefile README config.mk sic.1 ${SRC} sic-${VERSION}
@tar -cf sic-${VERSION}.tar sic-${VERSION}
@gzip sic-${VERSION}.tar
@rm -rf sic-${VERSION}
sic: ${OBJ}
@echo LD $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
@for i in ${BIN}; do \
chmod 755 ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
done
@echo installed executable files to ${DESTDIR}${PREFIX}/bin
@cp -f sic ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/sic
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
@for i in ${MAN1}; do \
chmod 444 ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
done
@echo installed manual pages to ${DESTDIR}${MANPREFIX}/man1
@sed 's/VERSION/${VERSION}/g' < sic.1 > ${DESTDIR}${MANPREFIX}/man1/sic.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/sic.1
uninstall:
for i in ${BIN}; do \
rm -f ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
done
for i in ${MAN1}; do \
rm -f ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
done
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/sic
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/sic.1
.PHONY: all options clean dist install uninstall

10
README
View File

@@ -1,11 +1,11 @@
sic - simple irc client
-----------------------
=======================
sic is an extremly fast, small and simple irc client. It reads commands from
standard input and prints all server output to standard output. It multiplexes
also all channel traffic into one output, that you don't have to switch
different channel buffers, that's actually a feature.
Installation
------------
Edit config.mk to match your local setup. sic is installed into
@@ -16,11 +16,7 @@ Afterwards enter the following command to build and install sic
$ make clean install
Running sic
-----------
Simply invoke the 'sic' command with the required arguments.
Configuration
-------------
No configuration is needed.

View File

@@ -1,18 +1,22 @@
# Customize to fit your system
# sic version
VERSION = 0.8
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
VERSION = 0.1
# includes and libs
LIBS = -L${PREFIX}/lib -L/usr/lib -lc
INCS = -I. -I/usr/include
LIBS = -L/usr/lib -lc
# compiler
CFLAGS = -Os -I${PREFIX}/include -I/usr/include \
-DVERSION=\"${VERSION}\"
# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 -I${PREFIX}/include -I/usr/include \
# -DVERSION=\"${VERSION}\"
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# compiler and linker
CC = cc
LD = ${CC}

38
sic.1
View File

@@ -1,19 +1,13 @@
.TH SIC 1 sic-0.1
.TH SIC 1 sic-VERSION
.SH NAME
sic \- simple irc client
.SH SYNOPSIS
.B sic
.RB [ \-s
.IR server ]
.RB [ \-p
.IR port ]
.RB [ \-n
.IR nick ]
.RB [ \-k
.IR keyword ]
.RB [ \-f
.IR fullname ]
.RB \-v
.RB [ \-s " <server>"]
.RB [ \-p " <port>"]
.RB [ \-n " <nick>"]
.RB [ \-k " <keyword>"]
.RB [ \-f " <fullname>"]
.RB [ \-v ]
.SH DESCRIPTION
.B sic
@@ -23,38 +17,38 @@ also all channel traffic into one output, that you don't have to switch
different channel buffers, that's actually a feature.
.SH OPTIONS
.TP
.BI \-s " server"
.B \-s <server>
Overrides the default server (irc.oftc.net)
.TP
.BI \-p " port"
.B \-p <port>
Overrides the default port (6667)
.TP
.BI \-n " nickname"
.B \-n <nickname>
Override the default nick ($USER)
.TP
.BI \-k " keyword"
.B \-k <keyword>
Specifies the keyword to authenticate your nick on the server
.TP
.BI \-f " fullname"
.B \-f <fullname>
Specify the real name (default is $USER)
.TP
.BI \-v
Prints version information to standard output, then exits.
.SH COMMANDS
.TP
.BI /j " #channel "
.B /j #channel
Join a channel
.TP
.BI /l " #channel "
.B /l #channel
Leave a channel
.TP
.BI /m " #channel/user msg "
.B /m #channel/user msg
Write a message to #channel/user
.TP
.BI /s " #channel/user "
.B /s #channel/user
Set default channel/user
.TP
.BI /t " topic"
.B /t topic
Set the channel topic
.TP
Everything which is not a command will simply be posted into the channel or to

233
sic.c
View File

@@ -1,17 +1,17 @@
/*
* (C)opyright MMV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* (C)opyright MMV-MMVI Nico Golde <nico at ngolde dot de>
* See LICENSE file for license details.
*/
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#define PINGTIMEOUT 300
#define MAXMSG 4096
@@ -19,7 +19,7 @@
enum { Tnick, Tuser, Tcmd, Tchan, Targ, Ttext, Tlast };
static char *server = "irc.oftc.net";
static int port = 6667;
static unsigned short port = 6667;
static char *nick = NULL;
static char *fullname = NULL;
static char *password = NULL;
@@ -30,10 +30,10 @@ static int srv;
static time_t trespond;
static int
getline(int fd, unsigned int len, char *buf)
{
getline(int fd, unsigned int len, char *buf) {
unsigned int i = 0;
char c;
do {
if(read(fd, &c, sizeof(char)) != sizeof(char))
return -1;
@@ -45,69 +45,58 @@ getline(int fd, unsigned int len, char *buf)
}
static void
pout(char *channel, char *msg)
{
pout(char *channel, char *msg) {
static char timestr[18];
time_t t = time(0);
strftime(timestr, sizeof(timestr), "%a %R", localtime(&t));
fprintf(stdout, "%s: %s %s\n", channel, timestr, msg);
strftime(timestr, sizeof timestr, "%F %R", localtime(&t));
fprintf(stdout, "%-8.8s: %s %s\n", channel, timestr, msg);
}
static void
privmsg(char *channel, char *msg)
{
snprintf(bufout, sizeof(bufout), "<%s> %s", nick, msg);
privmsg(char *channel, char *msg) {
snprintf(bufout, sizeof bufout, "<%s> %s", nick, msg);
pout(channel, bufout);
snprintf(bufout, sizeof(bufout), "PRIVMSG %s :%s\r\n", channel, msg);
snprintf(bufout, sizeof bufout, "PRIVMSG %s :%s\r\n", channel, msg);
write(srv, bufout, strlen(bufout));
}
static void
parsein(char *msg)
{
parsein(char *msg) {
char *p;
if(msg[0] == 0)
return;
if(msg[0] != '/') {
privmsg(channel, msg);
return;
}
if(!strncmp(msg + 1, "j ", 2) && (msg[3] == '#'))
snprintf(bufout, sizeof bufout, "JOIN %s\r\n", &msg[3]);
else if(!strncmp(msg + 1, "l ", 2))
snprintf(bufout, sizeof bufout, "PART %s :sic\r\n", &msg[3]);
else if(!strncmp(msg + 1, "m ", 2)) {
if((p = strchr(&msg[3], ' ')))
*(p++) = 0;
switch (msg[1]) {
default:
snprintf(bufout, sizeof(bufout), "%s\r\n", &msg[1]);
break;
case 'j':
if(msg[3] == '#')
snprintf(bufout, sizeof(bufout), "JOIN %s\r\n", &msg[3]);
else if(p) {
privmsg(&msg[3], p + 1);
return;
}
break;
case 'l':
if(p)
snprintf(bufout, sizeof(bufout), "PART %s :%s\r\n", &msg[3], p);
else
snprintf(bufout, sizeof(bufout), "PART %s :sic\r\n", &msg[3]);
break;
case 'm':
privmsg(&msg[3], p);
return;
case 's':
strncpy(channel, &msg[3], sizeof(channel));
return;
case 't':
snprintf(bufout, sizeof(bufout), "TOPIC %s :%s\r\n", &msg[3], p);
break;
}
else if(!strncmp(msg + 1, "s ", 2)) {
strncpy(channel, &msg[3], sizeof channel);
return;
}
else if(!strncmp(msg + 1, "t ", 2)) {
if((p = strchr(&msg[3], ' ')))
*(p++) = 0;
snprintf(bufout, sizeof bufout, "TOPIC %s :%s\r\n", &msg[3], p);
}
else
snprintf(bufout, sizeof bufout, "%s\r\n", &msg[1]);
write(srv, bufout, strlen(bufout));
}
static unsigned int
tokenize(char **result, unsigned int reslen, char *str, char delim)
{
tokenize(char **result, unsigned int reslen, char *str, char delim) {
char *p, *n;
unsigned int i = 0;
@@ -132,29 +121,29 @@ tokenize(char **result, unsigned int reslen, char *str, char delim)
}
static void
parsesrv(char *msg)
{
parsesrv(char *msg) {
char *argv[Tlast], *cmd, *p;
int i;
if(!msg || !(*msg))
return;
for(i = 0; i < Tlast; i++)
argv[i] = NULL;
/*
<bufout> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
<prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <server> ]
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including NUL or CR or LF>
<crlf> ::= CR LF
/* <bufout> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
* <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <server> ]
* <command> ::= <letter> { <letter> } | <number> <number> <number>
* <SPACE> ::= ' ' { ' ' }
* <params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
* <middle> ::= <Any *non-empty* sequence of octets not including SPACE
* or NUL or CR or LF, the first of which may not be ':'>
* <trailing> ::= <Any, possibly *empty*, sequence of octets not including NUL or CR or LF>
* <crlf> ::= CR LF
*/
if(msg[0] == ':') { /* check prefix */
p = strchr(msg, ' ');
if (!(p = strchr(msg, ' ')))
return;
*p = 0;
for(++p; *p == ' '; p++);
cmd = p;
@@ -165,30 +154,29 @@ parsesrv(char *msg)
}
} else
cmd = msg;
/* remove CRLFs */
for(p = cmd; p && *p != 0; p++)
if(*p == '\r' || *p == '\n')
*p = 0;
if((p = strchr(cmd, ':'))) {
*p = 0;
argv[Ttext] = ++p;
}
tokenize(&argv[Tcmd], Tlast - Tcmd, cmd, ' ');
if(!strncmp("PONG", argv[Tcmd], 5)) {
if(!argv[Tcmd] || !strncmp("PONG", argv[Tcmd], 5))
return;
} else if(!strncmp("PING", argv[Tcmd], 5)) {
snprintf(bufout, sizeof(bufout), "PONG %s\r\n", argv[Ttext]);
else if(!strncmp("PING", argv[Tcmd], 5)) {
snprintf(bufout, sizeof bufout, "PONG %s\r\n", argv[Ttext]);
write(srv, bufout, strlen(bufout));
return;
} else if(!argv[Tnick] || !argv[Tuser]) { /* server command */
snprintf(bufout, sizeof(bufout), "%s", argv[Ttext] ? argv[Ttext] : "");
}
else if(!argv[Tnick] || !argv[Tuser]) { /* server command */
snprintf(bufout, sizeof bufout, "%s", argv[Ttext] ? argv[Ttext] : "");
pout(server, bufout);
return;
} else if(!strncmp("ERROR", argv[Tcmd], 6))
snprintf(bufout, sizeof(bufout), "-!- error %s",
}
else if(!strncmp("ERROR", argv[Tcmd], 6))
snprintf(bufout, sizeof bufout, "-!- error %s",
argv[Ttext] ? argv[Ttext] : "unknown");
else if(!strncmp("JOIN", argv[Tcmd], 5)) {
if(argv[Ttext]!=NULL){
@@ -197,33 +185,37 @@ parsesrv(char *msg)
*p = 0;
}
argv[Tchan] = argv[Ttext];
snprintf(bufout, sizeof(bufout), "-!- %s(%s) has joined %s",
snprintf(bufout, sizeof bufout, "-!- %s(%s) has joined %s",
argv[Tnick], argv[Tuser], argv[Ttext]);
} else if(!strncmp("PART", argv[Tcmd], 5)) {
snprintf(bufout, sizeof(bufout), "-!- %s(%s) has left %s",
}
else if(!strncmp("PART", argv[Tcmd], 5)) {
snprintf(bufout, sizeof bufout, "-!- %s(%s) has left %s",
argv[Tnick], argv[Tuser], argv[Tchan]);
} else if(!strncmp("MODE", argv[Tcmd], 5))
snprintf(bufout, sizeof(bufout), "-!- %s changed mode/%s -> %s %s",
argv[Tnick], argv[Tcmd + 1],
argv[Tcmd + 2], argv[Tcmd + 3]);
}
else if(!strncmp("MODE", argv[Tcmd], 5))
snprintf(bufout, sizeof bufout, "-!- %s changed mode/%s -> %s %s",
argv[Tnick], argv[Tcmd + 1] ? argv[Tcmd + 1] : "",
argv[Tcmd + 2] ? argv[Tcmd + 2] : "",
argv[Tcmd + 3] ? argv[Tcmd + 3] : "");
else if(!strncmp("QUIT", argv[Tcmd], 5))
snprintf(bufout, sizeof(bufout), "-!- %s(%s) has quit \"%s\"",
snprintf(bufout, sizeof bufout, "-!- %s(%s) has quit \"%s\"",
argv[Tnick], argv[Tuser],
argv[Ttext] ? argv[Ttext] : "");
else if(!strncmp("NICK", argv[Tcmd], 5))
snprintf(bufout, sizeof(bufout), "-!- %s changed nick to %s",
snprintf(bufout, sizeof bufout, "-!- %s changed nick to %s",
argv[Tnick], argv[Ttext]);
else if(!strncmp("TOPIC", argv[Tcmd], 6))
snprintf(bufout, sizeof(bufout), "-!- %s changed topic to \"%s\"",
snprintf(bufout, sizeof bufout, "-!- %s changed topic to \"%s\"",
argv[Tnick], argv[Ttext] ? argv[Ttext] : "");
else if(!strncmp("KICK", argv[Tcmd], 5))
snprintf(bufout, sizeof(bufout), "-!- %s kicked %s (\"%s\")",
snprintf(bufout, sizeof bufout, "-!- %s kicked %s (\"%s\")",
argv[Tnick], argv[Targ],
argv[Ttext] ? argv[Ttext] : "");
else if(!strncmp("NOTICE", argv[Tcmd], 7))
snprintf(bufout, sizeof(bufout), "-!- \"%s\")",
snprintf(bufout, sizeof bufout, "-!- \"%s\")",
argv[Ttext] ? argv[Ttext] : "");
else if(!strncmp("PRIVMSG", argv[Tcmd], 8)) snprintf(bufout, sizeof(bufout), "<%s> %s",
else if(!strncmp("PRIVMSG", argv[Tcmd], 8))
snprintf(bufout, sizeof bufout, "<%s> %s",
argv[Tnick], argv[Ttext] ? argv[Ttext] : "");
if(!argv[Tchan] || !strncmp(argv[Tchan], nick, strlen(nick)))
pout(argv[Tnick], bufout);
@@ -232,43 +224,39 @@ parsesrv(char *msg)
}
int
main(int argc, char *argv[])
{
main(int argc, char *argv[]) {
int i;
struct timeval tv;
struct hostent *hp;
struct sockaddr_in addr = { 0 };
static struct sockaddr_in addr; /* initially filled with 0's */
char ping[256];
fd_set rd;
nick = fullname = getenv("USER");
for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
switch (argv[i][1]) {
default:
for(i = 1; i < argc; i++)
if(!strncmp(argv[i], "-s", 3)) {
if(++i < argc) server = argv[i];
}
else if(!strncmp(argv[i], "-p", 3)) {
if(++i < argc) port = (unsigned short)atoi(argv[i]);
}
else if(!strncmp(argv[i], "-n", 3)) {
if(++i < argc) nick = argv[i];
}
else if(!strncmp(argv[i], "-k", 3)) {
if(++i < argc) password = argv[i];
}
else if(!strncmp(argv[i], "-f", 3)) {
if(++i < argc) fullname = argv[i];
}
else if(!strncmp(argv[i], "-v", 3)) {
fputs("sic-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
exit(EXIT_SUCCESS);
}
else {
fputs("usage: sic [-s server] [-p port] [-n nick]"
" [-k keyword] [-f fullname] [-v]\n", stderr);
exit(EXIT_FAILURE);
break;
case 's':
server = argv[++i];
break;
case 'p':
port = atoi(argv[++i]);
break;
case 'n':
nick = argv[++i];
break;
case 'k':
password = argv[++i];
break;
case 'f':
fullname = argv[++i];
break;
case 'v':
fputs("sic-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
exit(EXIT_SUCCESS);
break;
}
}
/* init */
@@ -276,30 +264,32 @@ main(int argc, char *argv[])
fprintf(stderr, "sic: cannot connect server '%s'\n", server);
exit(EXIT_FAILURE);
}
hp = gethostbyname(server);
if (NULL == (hp = gethostbyname(server))) {
fprintf(stderr, "sic: cannot resolve hostname '%s'\n", server);
exit(EXIT_FAILURE);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
if(connect(srv, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))) {
close(srv);
fprintf(stderr, "sic: cannot connect server '%s'\n", server);
exit(EXIT_FAILURE);
}
/* login */
if(password)
snprintf(bufout, sizeof(bufout),
"PASS %s\r\nNICK %s\r\nUSER %s localserver %s :%s\r\n",
password, nick, nick, server, fullname ? fullname : nick);
snprintf(bufout, sizeof bufout,
"PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n",
password, nick, nick, server, fullname);
else
snprintf(bufout, sizeof(bufout), "NICK %s\r\nUSER %s localserver %s :%s\r\n",
nick, nick, server, fullname ? fullname : nick);
snprintf(bufout, sizeof bufout, "NICK %s\r\nUSER %s localhost %s :%s\r\n",
nick, nick, server, fullname);
write(srv, bufout, strlen(bufout));
snprintf(ping, sizeof(ping), "PING %s\r\n", server);
snprintf(ping, sizeof ping, "PING %s\r\n", server);
channel[0] = 0;
setbuf(stdout, NULL); /* unbuffered stdout */
for(;;) {
for(;;) { /* main loop */
FD_ZERO(&rd);
FD_SET(0, &rd);
FD_SET(srv, &rd);
@@ -313,14 +303,14 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE);
} else if(i == 0) {
if(time(NULL) - trespond >= PINGTIMEOUT) {
pout(server, "-!- sic shutting down: parseing timeout");
pout(server, "-!- sic shutting down: parse timeout");
exit(EXIT_FAILURE);
}
write(srv, ping, strlen(ping));
continue;
}
if(FD_ISSET(srv, &rd)) {
if(getline(srv, sizeof(bufin), bufin) == -1) {
if(getline(srv, sizeof bufin, bufin) == -1) {
perror("sic: remote server closed connection");
exit(EXIT_FAILURE);
}
@@ -328,13 +318,12 @@ main(int argc, char *argv[])
trespond = time(NULL);
}
if(FD_ISSET(0, &rd)) {
if(getline(0, sizeof(bufin), bufin) == -1) {
if(getline(0, sizeof bufin, bufin) == -1) {
perror("sic: broken pipe");
exit(EXIT_FAILURE);
}
parsein(bufin);
}
}
return 0;
}

View File

@@ -1,39 +0,0 @@
<html>
<head>
<title>sic - simple irc client</title>
<meta name="author" content="Anselm R. Garbe">
<meta name="generator" content="ed">
<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe">
<style type="text/css">
body {
color: #000000;
font-family: sans-serif;
margin: 20px 20px 20px 20px;
}
</style>
</head>
<body>
<center>
<h3>simple irc client</h3>
</center>
<h3>Description</h3>
<p>
sic is an extremly simple IRC client. It consists of lesser than 400 lines of code.
</p>
<ul>
<li><a href="http://10kloc.org/cgi-bin/man/man2html?query=sic">Man page</a></li>
</ul>
<h3>Download</h3>
<ul>
<li><a href="http://10kloc.org/download/sic-0.1.tar.gz">sic 0.1</a> (5kb) (20060720)</li>
</ul>
<h3>Development</h3>
<p>
You can <a href="http://10kloc.org/cgi-bin/hgwebdir.cgi/sic">browse</a> its source code repository or get a copy using <a href="http://www.selenic.com/mercurial/">Mercurial</a> with following command:
</p>
<p>
<code>hg clone http://10kloc.org/cgi-bin/hgwebdir.cgi/sic</code>
</p>
<p><small>--Anselm (20060719)</small></p>
</body>
</html>