morpheus

suckless linux distro
git clone git://git.2f30.org/morpheus
Log | Files | Refs | Submodules | README | LICENSE

commit e31b8c428aaaeca1dd53dd902d3651774255494b
parent d14045ba151562934b8e2ebdf77441d1c489db81
Author: sin <sin@2f30.org>
Date:   Thu, 13 Feb 2014 12:33:51 +0000

Remove irc - we have sic

Diffstat:
Dpkgs/irc | 13-------------
Dstuff/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); -}