commit e31b8c428aaaeca1dd53dd902d3651774255494b
parent d14045ba151562934b8e2ebdf77441d1c489db81
Author: sin <sin@2f30.org>
Date: Thu, 13 Feb 2014 12:33:51 +0000
Remove irc - we have sic
Diffstat:
D | pkgs/irc | | | 13 | ------------- |
D | stuff/irc.c | | | 624 | ------------------------------------------------------------------------------- |
2 files changed, 0 insertions(+), 637 deletions(-)
diff --git a/pkgs/irc b/pkgs/irc
@@ -1,13 +0,0 @@
-fetch() {
- cp $top/stuff/irc.c src
-}
-
-build() {
- pushd src
- x86_64-linux-musl-gcc -o irc irc.c -static -I$libcroot/include/ncurses -lncurses || return 1
- popd
-}
-
-install() {
- cp src/irc $root/bin
-}
diff --git a/stuff/irc.c b/stuff/irc.c
@@ -1,624 +0,0 @@
-/*% cc -g -Wall -lncurses -o # %
- */
-#include <assert.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include <curses.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <locale.h>
-
-#define CTRL(c) ((c) & 037)
-
-#define SCROLL 15
-#define DATEFMT "%H:%M"
-#define PFMT "%-12s < %s"
-#define SRV "chat.freenode.org"
-#define PORT 6667
-
-enum { ChanLen = 64, LineLen = 512, MaxChans = 16, BufSz = 2048, LogSz = 4096 };
-
-char nick[64];
-int quit, winchg;
-int sfd; /* Server file descriptor. */
-struct {
- int x;
- int y;
- WINDOW *sw, *mw, *iw;
-} scr; /* Screen relative data. */
-struct Chan {
- char name[ChanLen];
- char *buf, *eol;
- int n; /* Scroll offset. */
- size_t sz; /* size of buf. */
-} chl[MaxChans];
-int nch, ch; /* Current number of channels, and current channel. */
-char outb[BufSz], *outp=outb; /* Output buffer. */
-
-static void scmd(char *, char *, char *, char *);
-static void tdrawbar(void);
-static void tredraw(void);
-static void treset(void);
-
-static void
-panic(const char *m)
-{
- treset();
- fprintf(stderr, "Panic: %s\n", m);
- exit(1);
-}
-
-static void
-sndf(const char *fmt, ...)
-{
- va_list vl;
- size_t n, l=BufSz-(outp-outb);
-
- if (l<2) return;
- va_start(vl, fmt);
- n=vsnprintf(outp, l-2, fmt, vl);
- va_end(vl);
- outp += n>l-2 ? l-2 : n;
- *outp++ = '\r';
- *outp++ = '\n';
-}
-
-static int
-srd(void)
-{
- static char l[BufSz], *p=l;
- char *s, *usr, *cmd, *par, *data;
- int rd;
-
- if (p-l>=BufSz) p=l; /* Input buffer overflow, there should something better to do. */
- rd=read(sfd, p, BufSz-(p-l));
- if (rd<0) {
- if (errno==EINTR) return 1;
- panic("IO error while reading.");
- }
- if (rd==0) return 0;
- p+=rd;
- for (;;) { /* Cycle on all received lines. */
- if (!(s=memchr(l, '\n', p-l)))
- return 1;
- if (s>l && s[-1]=='\r')
- s[-1]=0;
- *s++ = 0;
- if (*l==':') {
- if (!(cmd=strchr(l, ' '))) goto lskip;
- *cmd++ = 0;
- usr = l+1;
- } else {
- usr = 0;
- cmd = l;
- }
- if (!(par=strchr(cmd, ' '))) goto lskip;
- *par++ = 0;
- if ((data=strchr(par, ':')))
- *data++ = 0;
- scmd(usr, cmd, par, data);
- lskip:
- memmove(l, s, p-s);
- p-=s-l;
- }
-}
-
-static int
-dial(const char *host, short port)
-{
- int f;
- struct sockaddr_in sin;
- struct addrinfo *ai, hai = { 0 };
-
- hai.ai_family = AF_INET;
- hai.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(host, 0, &hai, &ai))
- panic("Cannot resolve host.");
- memcpy(&sin, ai->ai_addr, sizeof sin);
- sin.sin_port = htons(port);
- freeaddrinfo(ai);
- f = socket(AF_INET, SOCK_STREAM, 0);
- if (f<0)
- panic("Cannot create socket.");
- if (connect(f, (struct sockaddr *)&sin, sizeof sin)<0)
- panic("Cannot connect to host.");
- return f;
-}
-
-static int
-chadd(char *name)
-{
- if (nch>=MaxChans || strlen(name)>=ChanLen)
- return -1;
- strcpy(chl[nch].name, name);
- chl[nch].sz=LogSz;
- chl[nch].buf=malloc(LogSz);
- if (!chl[nch].buf)
- panic("Out of memory.");
- chl[nch].eol=chl[nch].buf;
- chl[nch].n=0;
- ch=nch++;
- tdrawbar();
- return nch;
-}
-
-static inline int
-chfind(char *name)
-{
- int i;
-
- assert(name);
- for (i=nch-1; i>0; i--)
- if (!strcmp(chl[i].name, name))
- break;
- return i;
-}
-
-static int
-chdel(char *name)
-{
- int n;
-
- if (!(n=chfind(name))) return 0;
- nch--;
- free(chl[n].buf);
- memmove(&chl[n], &chl[n+1], (nch-n)*sizeof(struct Chan));
- ch=nch-1;
- tdrawbar();
- return 1;
-}
-
-static void
-pushf(int cn, const char *fmt, ...)
-{
- struct Chan *const c=&chl[cn];
- size_t n, blen=c->eol-c->buf;
- va_list vl;
- time_t t;
- struct tm *tm;
-
- if (blen+LineLen>=c->sz) {
- c->sz *= 2;
- c->buf=realloc(c->buf, c->sz);
- if (!c->buf) panic("Out of memory.");
- c->eol=c->buf+blen;
- }
- t=time(0);
- if (!(tm=localtime(&t))) panic("Localtime failed.");
- n=strftime(c->eol, LineLen, DATEFMT, tm);
- c->eol[n++] = ' ';
- va_start(vl, fmt);
- n+=vsnprintf(c->eol+n, LineLen-n-1, fmt, vl);
- va_end(vl);
- strcat(c->eol, "\n");
- if (n>=LineLen-1)
- c->eol+=LineLen-1;
- else
- c->eol+=n+1;
- if (cn==ch && c->n==0) {
- char *p=c->eol-n-1;
- if (p!=c->buf) waddch(scr.mw, '\n');
- for (; p<c->eol-1; p++)
- waddch(scr.mw, *p);
- wrefresh(scr.mw);
- }
-}
-
-static void
-scmd(char *usr, char *cmd, char *par, char *data)
-{
- int s;
- char *pm=strtok(par, " ");
-
- if (!usr) usr="?";
- else {
- char *bang=strchr(usr, '!');
- if (bang)
- *bang=0;
- }
- if (!strcmp(cmd, "PRIVMSG")) {
- if (!pm || !data) return;
- pushf(chfind(pm), PFMT, usr, data);
- } else if (!strcmp(cmd, "PING")) {
- sndf("PONG :%s", data?data:"(null)");
- } else if (!strcmp(cmd, "PART")) {
- if (!pm) return;
- pushf(chfind(pm), "-!- %s has left %s", usr, pm);
- } else if (!strcmp(cmd, "JOIN")) {
- if (!pm) return;
- pushf(chfind(pm), "-!- %s has joined %s", usr, pm);
- } else if (!strcmp(cmd, "470")) { /* Channel forwarding. */
- char *ch=strtok(0, " "), *fch=strtok(0, " ");
- if (!ch || !fch || !(s=chfind(ch))) return;
- chl[s].name[0] = 0;
- strncat(chl[s].name, fch, ChanLen-1);
- tdrawbar();
- } else if (!strcmp(cmd, "471") || !strcmp(cmd, "473")
- || !strcmp(cmd, "474") || !strcmp(cmd, "475")) { /* Join error. */
- if ((pm=strtok(0, " "))) {
- chdel(pm);
- pushf(0, "-!- Cannot join channel %s (%s)", pm, cmd);
- tredraw();
- }
- } else if (!strcmp(cmd, "QUIT")) { /* Commands we don't care about. */
- return;
- } else if (!strcmp(cmd, "NOTICE") || !strcmp(cmd, "375")
- || !strcmp(cmd, "372") || !strcmp(cmd, "376")) {
- pushf(0, "%s", data?data:"");
- } else
- pushf(0, "%s - %s %s", cmd, par, data?data:"(null)");
-}
-
-static void
-uparse(char *m)
-{
- char *p=m;
-
- if (!p[0] || (p[1]!=' ' && p[1]!=0)) {
- pmsg:
- if (ch==0) return;
- m+=strspn(m, " ");
- if (!*m) return;
- pushf(ch, PFMT, nick, m);
- sndf("PRIVMSG %s :%s", chl[ch].name, m);
- return;
- }
- switch (*p) {
- case 'j': /* Join channels. */
- p+=1+(p[1]==' ');
- p=strtok(p, " ");
- while (p) {
- if (chadd(p)<0) break;
- sndf("JOIN %s", p);
- p=strtok(0, " ");
- }
- tredraw();
- return;
- case 'l': /* Leave channels. */
- p+=1+(p[1]==' ');
- if (!*p) {
- if (ch==0) return; /* Cannot leave server window. */
- strcat(p, chl[ch].name);
- }
- p=strtok(p, " ");
- while (p) {
- if (chdel(p))
- sndf("PART %s", p);
- p=strtok(0, " ");
- }
- tredraw();
- return;
- case 'm': /* Private message. */
- m=p+1+(p[1]==' ');
- if (!(p=strchr(m, ' '))) return;
- *p++ = 0;
- sndf("PRIVMSG %s :%s", m, p);
- return;
- case 'r': /* Send raw. */
- if (p[1])
- sndf("%s", &p[2]);
- return;
- case 'q': /* Quit. */
- quit=1;
- return;
- default: /* Send on current channel. */
- goto pmsg;
- }
-}
-
-static void
-sigwinch(int sig)
-{
- if (sig) winchg=1;
-}
-
-static void
-tinit(void)
-{
- setlocale(LC_ALL, "");
- signal(SIGWINCH, sigwinch);
- initscr();
- raw();
- noecho();
- getmaxyx(stdscr, scr.y, scr.x);
- if (scr.y<4) panic("Screen too small.");
- if ((scr.sw=newwin(1, scr.x, 0, 0))==0
- || (scr.mw=newwin(scr.y-2, scr.x, 1, 0))==0
- || (scr.iw=newwin(1, scr.x, scr.y-1, 0))==0)
- panic("Cannot create windows.");
- keypad(scr.iw, 1);
- scrollok(scr.mw, 1);
- if (has_colors()==TRUE) {
- start_color();
- init_pair(1, COLOR_WHITE, COLOR_BLUE);
- wbkgd(scr.sw, COLOR_PAIR(1));
- }
-}
-
-static void
-tresize(void)
-{
- struct winsize ws;
-
- winchg=0;
- if (ioctl(0, TIOCGWINSZ, &ws)<0)
- panic("Ioctl (TIOCGWINSZ) failed.");
- resizeterm(scr.y=ws.ws_row, scr.x=ws.ws_col);
- if (scr.y<3 || scr.x<10)
- panic("Screen too small.");
- wresize(scr.mw, scr.y-2, scr.x);
- wresize(scr.iw, 1, scr.x);
- wresize(scr.sw, 1, scr.x);
- mvwin(scr.iw, scr.y-1, 0);
- tredraw();
- tdrawbar();
-}
-
-static void
-tredraw(void)
-{
- struct Chan *const c=&chl[ch];
- char *q, *p;
- int llen=0, nl=-1;
-
- if (c->eol==c->buf) {
- wclear(scr.mw);
- wrefresh(scr.mw);
- return;
- }
- p=c->eol-1;
- if (c->n) {
- int i=c->n;
- for (; p>c->buf; p--)
- if (*p=='\n' && !i--) break;
- if (p==c->buf) c->n-=i;
- }
- q=p;
- while (nl<scr.y-2) {
- llen=0;
- while (*q!='\n' && q>c->buf)
- q--, llen++;
- nl += 1+llen/scr.x;
- if (q==c->buf) break;
- q--;
- }
- if (q!=c->buf) q+=2;
- for (llen=0; nl>scr.y-2; ) { /* Maybe we must split the top line. */
- if (q[llen]=='\n' || llen>=scr.x) {
- q+=llen+(q[llen]=='\n');
- llen=0;
- nl--;
- } else llen++;
- }
- wclear(scr.mw);
- wmove(scr.mw, 0, 0);
- for (; q<p; q++)
- waddch(scr.mw, *q);
- wrefresh(scr.mw);
-}
-
-static void
-tdrawbar(void)
-{
- size_t l;
- int fst=ch;
-
- for (l=0; fst>0 && l<scr.x/2; fst--)
- l+=strlen(chl[fst].name)+3;
-
- werase(scr.sw);
- for (l=0; fst<nch && l<scr.x; fst++) {
- char *p=chl[fst].name;
-
- if (fst==ch) wattron(scr.sw, A_BOLD);
- waddch(scr.sw, '['), l++;
- for (; *p && l<scr.x; p++, l++)
- waddch(scr.sw, *p);
- if (l<scr.x-1)
- waddstr(scr.sw, "] "), l+=2;
- if (fst==ch) wattroff(scr.sw, A_BOLD);
- }
- wrefresh(scr.sw);
-}
-
-static void
-tgetch(void)
-{
- static char l[BufSz];
- static size_t shft, cu, len;
- size_t dirty=len+1, i;
- int c;
-
- c=wgetch(scr.iw);
- switch (c) {
- case CTRL('n'):
- ch=(ch+1)%nch;
- tdrawbar();
- tredraw();
- return;
- case CTRL('p'):
- ch=(ch+nch-1)%nch;
- tdrawbar();
- tredraw();
- return;
- case KEY_PPAGE:
- chl[ch].n+=SCROLL;
- tredraw();
- return;
- case KEY_NPAGE:
- chl[ch].n-=SCROLL;
- if (chl[ch].n<0) chl[ch].n=0;
- tredraw();
- return;
- case CTRL('a'):
- cu=0;
- break;
- case CTRL('e'):
- cu=len;
- break;
- case CTRL('b'):
- case KEY_LEFT:
- if (cu) cu--;
- break;
- case CTRL('f'):
- case KEY_RIGHT:
- if (cu<len) cu++;
- break;
- case CTRL('k'):
- dirty=len=cu;
- break;
- case CTRL('u'):
- if (cu==0) return;
- len-=cu;
- memmove(l, &l[cu], len);
- dirty=cu=0;
- break;
- case CTRL('d'):
- if (cu>=len) return;
- memmove(&l[cu], &l[cu+1], len-cu-1);
- dirty=cu;
- len--;
- break;
- case KEY_BACKSPACE:
- if (cu==0) return;
- memmove(&l[cu-1], &l[cu], len-cu);
- dirty=--cu;
- len--;
- break;
- case '\n':
- l[len]=0;
- uparse(l);
- dirty=cu=len=0;
- break;
- default:
- if (c>CHAR_MAX || len>=BufSz-1) return; /* Skip other curses codes. */
- memmove(&l[cu+1], &l[cu], len-cu);
- dirty=cu;
- len++;
- l[cu++]=c;
- break;
- }
- while (cu<shft)
- dirty=0, shft -= shft>=scr.x/2 ? scr.x/2 : shft;
- while (cu>=scr.x+shft)
- dirty=0, shft += scr.x/2;
- if (dirty<=shft)
- i=shft;
- else if (dirty>scr.x+shft || dirty>len)
- goto mvcur;
- else
- i=dirty;
- wmove(scr.iw, 0, i-shft);
- wclrtoeol(scr.iw);
- for (; i-shft<scr.x && i<len; i++)
- waddch(scr.iw, l[i]);
-mvcur: wmove(scr.iw, 0, cu-shft);
-}
-
-static void
-treset(void)
-{
- if (scr.mw) delwin(scr.mw);
- if (scr.sw) delwin(scr.sw);
- if (scr.iw) delwin(scr.iw);
- endwin();
-}
-
-int
-main(int argc, char *argv[])
-{
- const char *user = getenv("USER");
- const char *ircnick = getenv("IRCNICK");
- const char *server = SRV;
- unsigned short port = PORT;
- int o;
-
- while ((o=getopt(argc, argv, "hn:u:s:p:"))>=0)
- switch (o) {
- case 'h':
- case '?':
- usage:
- fputs("Usage: irc [-n NICK] [-u USER] [-s SERVER] [-p PORT] [-h]\n", stderr);
- exit(0);
- case 'n':
- if (strlen(optarg)>=sizeof nick) goto usage;
- strcpy(nick, optarg);
- break;
- case 'u':
- user = optarg;
- break;
- case 's':
- server = optarg;
- break;
- case 'p':
- if (!(port=strtol(optarg, 0, 0))) goto usage;
- break;
- }
- if (!nick[0] && ircnick && strlen(ircnick)<sizeof nick)
- strcpy(nick, ircnick);
- if (!nick[0]) goto usage;
- if (!user) user = "Unknown";
- tinit();
- sfd = dial(server, port);
- chadd("*server*");
- sndf("NICK %s", nick);
- sndf("USER %s 8 * :%s", user, user);
- sndf("MODE %s +i", nick);
- while (!quit) {
- fd_set rfs, wfs;
- int ret;
-
- if (winchg)
- tresize();
- FD_ZERO(&wfs);
- FD_ZERO(&rfs);
- FD_SET(0, &rfs);
- FD_SET(sfd, &rfs);
- if (outp!=outb)
- FD_SET(sfd, &wfs);
- ret=select(sfd+1, &rfs, &wfs, 0, 0);
- if (ret<0) {
- if (errno==EINTR) continue;
- panic("Select failed.");
- }
- if (FD_ISSET(sfd, &rfs)) {
- if (!srd())
- quit=1;
- }
- if (FD_ISSET(sfd, &wfs)) {
- int wr;
-
- wr=write(sfd, outb, outp-outb);
- if (wr<0) {
- if (errno==EINTR) continue;
- panic("Write error.");
- }
- if (wr==0) continue;
- outp-=wr;
- memmove(outb, outb+wr, outp-outb);
- }
- if (FD_ISSET(0, &rfs)) {
- tgetch();
- wrefresh(scr.iw);
- }
- }
- close(sfd);
- while (nch--)
- free(chl[nch].buf);
- treset();
- exit(0);
-}