--- ii.1 | 11 +++++------ ii.c | 56 +++++++++++++------------------------------------------- 2 files changed, 18 insertions(+), 49 deletions(-) diff --git a/ii.1 b/ii.1 index 11e4e2a..0dd5d7d 100644 --- a/ii.1 +++ b/ii.1 _AT_@ -15,37 +15,35 @@ is placed. This will be for example ~/irc/irc.freenode.net/. The in file is used to communicate with the servers and the out files includes the server messages. For every channel and every nick name there will be new in and out files. 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. +.P +Server communication is carried out by standard input (reads) and +output (writes). .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 ] .SH OPTIONS .TP .BI \-s " servername" lets you override the default servername (irc.freenode.net) .TP -.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. .TP .BI \-i " prefix" lets you override the default irc path (~/irc) .TP _AT_@ -87,11 +85,12 @@ So if you need /who just write /WHO as described in the RFC to the server in FIF .FN "out file usage" Write wrappers, pagers or use your tools of choice to display the out file contents (loco, multitail, etc.). .SH CONTACT .TP Write to ii (at) modprobe (dot) de for suggestions, fixes, 7|-|>< ;) 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> +Copyright \(co 2005-2008 by Nico Golde <nico (at) ngolde (dot) de> and +minor further carving by Vasily Kolobkov dedicated to public domain .SH SEE ALSO .BR echo (1), .BR tail (1), diff --git a/ii.c b/ii.c index 9ea8bbc..e881aaa 100644 --- a/ii.c +++ b/ii.c _AT_@ -1,17 +1,15 @@ /* (C)opyright MMV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMV-MMXI Nico Golde <nico at ngolde dot de> * See LICENSE file for license details. */ #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/stat.h> -#include <sys/socket.h> #include <sys/select.h> -#include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <fcntl.h> #include <string.h> #include <pwd.h> #include <signal.h> _AT_@ -29,29 +27,28 @@ enum { TOK_NICKSRV = 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, TOK_LAST typedef struct Channel Channel; struct Channel { int fd; char *name; Channel *next; }; -static int irc; static time_t last_response; static Channel *channels = NULL; static char *host = "irc.freenode.net"; static char nick[32]; /* might change while running */ static char _nick[32]; /* might change while running */ static char path[_POSIX_PATH_MAX]; static char message[PIPE_BUF]; /* message buf used for communication */ static void usage() { fputs("ii - irc it - " VERSION "\n" "(C)opyright MMV-MMVI Anselm R. Garbe\n" "(C)opyright MMV-MMXI Nico Golde\n" - "usage: ii [-i <irc dir>] [-s <host>] [-p <port>]\n" - " [-n <nick>] [-k <password>] [-f <fullname>]\n", stderr); + "usage: ii [-i <irc dir>] [-s <host>] [-n <nick>]\n" + " [-k <password>] [-f <fullname>]\n", stderr); exit(EXIT_FAILURE); } static char *striplower(char *s) { char *p = NULL; for(p = s; p && *p; p++) { if(*p == '/') *p = ','; _AT_@ -110,15 +107,15 @@ static void add_channel(char *cname) { for(c = channels; c; c = c->next) if(!strcmp(name, c->name)) return; /* already handled */ fd = open_channel(name); if(fd == -1) { - printf("ii: exiting, cannot create in channel: %s\n", name); + fprintf(stderr, "ii: exiting, cannot create in channel: %s\n", name); exit(EXIT_FAILURE); } c = calloc(1, sizeof(Channel)); if(!c) { perror("ii: cannot allocate memory"); exit(EXIT_FAILURE); } _AT_@ -145,39 +142,15 @@ static void rm_channel(Channel *c) { static void login(char *key, char *fullname) { if(key) snprintf(message, PIPE_BUF, "PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n", key, nick, nick, host, fullname ? fullname : nick); else snprintf(message, PIPE_BUF, "NICK %s\r\nUSER %s localhost %s :%s\r\n", nick, nick, host, fullname ? fullname : nick); - write(irc, message, strlen(message)); /* login */ -} - -static int tcpopen(unsigned short port) { - int fd; - struct sockaddr_in sin; - struct hostent *hp = gethostbyname(host); - - memset(&sin, 0, sizeof(struct sockaddr_in)); - if(!hp) { - perror("ii: cannot retrieve host information"); - exit(EXIT_FAILURE); - } - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); - sin.sin_port = htons(port); - if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("ii: cannot create socket"); - exit(EXIT_FAILURE); - } - if(connect(fd, (const struct sockaddr *) &sin, sizeof(sin)) < 0) { - perror("ii: cannot connect to host"); - exit(EXIT_FAILURE); - } - return fd; + write(STDOUT_FILENO, message, strlen(message)); /* login */ } static size_t tokenize(char **result, size_t reslen, char *str, char delim) { char *p = NULL, *n = NULL; size_t i; if(!str) _AT_@ -216,15 +189,15 @@ static void print_out(char *channel, char *buf) { fclose(out); } static void proc_channels_privmsg(char *channel, char *buf) { snprintf(message, PIPE_BUF, "<%s> %s", nick, buf); print_out(channel, message); snprintf(message, PIPE_BUF, "PRIVMSG %s :%s\r\n", channel, buf); - write(irc, message, strlen(message)); + write(STDOUT_FILENO, message, strlen(message)); } static void proc_channels_input(Channel *c, char *buf) { /* static char infile[256]; */ char *p = NULL; if(buf[0] != '/' && buf[0] != 0) { _AT_@ -270,30 +243,30 @@ static void proc_channels_input(Channel *c, char *buf) { if(c->name[0] == 0) return; if(buf[2] == ' ' && strlen(buf)>=3) snprintf(message, PIPE_BUF, "PART %s :%s\r\n", c->name, &buf[3]); else snprintf(message, PIPE_BUF, "PART %s :ii - 500 SLOC are too much\r\n", c->name); - write(irc, message, strlen(message)); + write(STDOUT_FILENO, message, strlen(message)); close(c->fd); /*create_filepath(infile, sizeof(infile), c->name, "in"); unlink(infile); */ rm_channel(c); return; break; default: snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]); break; } else snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]); if (message[0] != '\0') - write(irc, message, strlen(message)); + write(STDOUT_FILENO, message, strlen(message)); } static void proc_server_cmd(char *buf) { char *argv[TOK_LAST], *cmd = NULL, *p = NULL; int i; if(!buf || *buf=='\0') _AT_@ -336,15 +309,15 @@ static void proc_server_cmd(char *buf) { tokenize(&argv[TOK_CMD], TOK_LAST - TOK_CMD, cmd, ' '); if(!argv[TOK_CMD] || !strncmp("PONG", argv[TOK_CMD], 5)) { return; } else if(!strncmp("PING", argv[TOK_CMD], 5)) { snprintf(message, PIPE_BUF, "PONG %s\r\n", argv[TOK_TEXT]); - write(irc, message, strlen(message)); + write(STDOUT_FILENO, message, strlen(message)); return; } else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) { /* server command */ snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); print_out(0, message); return; } else if(!strncmp("ERROR", argv[TOK_CMD], 6)) snprintf(message, PIPE_BUF, "-!- error %s", argv[TOK_TEXT] ? argv[TOK_TEXT] : "unknown"); _AT_@ -403,15 +376,15 @@ static void handle_channels_input(Channel *c) { return; } proc_channels_input(c, buf); } static void handle_server_output() { static char buf[PIPE_BUF]; - if(read_line(irc, PIPE_BUF, buf) == -1) { + if(read_line(STDIN_FILENO, PIPE_BUF, buf) == -1) { perror("ii: remote host closed connection"); exit(EXIT_FAILURE); } proc_server_cmd(buf); } static void run() { _AT_@ -420,16 +393,16 @@ static void run() { fd_set rd; struct timeval tv; char ping_msg[512]; snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host); for(;;) { FD_ZERO(&rd); - maxfd = irc; - FD_SET(irc, &rd); + maxfd = STDIN_FILENO; + FD_SET(STDIN_FILENO, &rd); for(c = channels; c; c = c->next) { if(maxfd < c->fd) maxfd = c->fd; FD_SET(c->fd, &rd); } tv.tv_sec = 120; _AT_@ -441,30 +414,29 @@ static void run() { perror("ii: error on select()"); exit(EXIT_FAILURE); } else if(r == 0) { if(time(NULL) - last_response >= PING_TIMEOUT) { print_out(NULL, "-!- ii shutting down: ping timeout"); exit(EXIT_FAILURE); } - write(irc, ping_msg, strlen(ping_msg)); + write(STDOUT_FILENO, ping_msg, strlen(ping_msg)); continue; } - if(FD_ISSET(irc, &rd)) { + if(FD_ISSET(STDIN_FILENO, &rd)) { handle_server_output(); last_response = time(NULL); } for(c = channels; c; c = c->next) if(FD_ISSET(c->fd, &rd)) handle_channels_input(c); } } int main(int argc, char *argv[]) { int i; - unsigned short port = SERVER_PORT; struct passwd *spw = getpwuid(getuid()); char *key = NULL, *fullname = NULL; char prefix[_POSIX_PATH_MAX]; if(!spw) { fputs("ii: getpwuid() failed\n", stderr); exit(EXIT_FAILURE); _AT_@ -473,22 +445,20 @@ int main(int argc, char *argv[]) { snprintf(prefix, sizeof(prefix),"%s/irc", spw->pw_dir); if (argc <= 1 || (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage(); for(i = 1; (i + 1 < argc) && (argv[i][0] == '-'); i++) { switch (argv[i][1]) { case 'i': snprintf(prefix,sizeof(prefix),"%s", argv[++i]); break; case 's': host = argv[++i]; break; - case 'p': port = strtol(argv[++i], NULL, 10); break; case 'n': snprintf(nick,sizeof(nick),"%s", argv[++i]); break; case 'k': key = getenv(argv[++i]); break; case 'f': fullname = argv[++i]; break; default: usage(); break; } } - irc = tcpopen(port); if(!snprintf(path, sizeof(path), "%s/%s", prefix, host)) { fputs("ii: path to irc directory too long\n", stderr); exit(EXIT_FAILURE); } create_dirtree(path); add_channel(""); /* master channel */ -- 2.7.0 --aBMpbC6MBql7ybx5--Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Thu Feb 25 2016 - 19:24:11 CET