diff options
Diffstat (limited to '')
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | and | 0 | ||||
-rw-r--r-- | kirc.c | 170 | ||||
-rw-r--r-- | kirc.h | 2 |
4 files changed, 121 insertions, 53 deletions
@@ -3,7 +3,7 @@ ALL_WARNING = -Wall -Werror -Wextra -Wno-unused-result -pedantic -std=c99 PREFIX ?= /usr/local BINDIR = $(PREFIX)/bin MANDIR = $(PREFIX)/share/man -CFLAGS = -march=native -O3 -pipe +CFLAGS = -march=native -O2 -pipe # CFLAGS = -march=native -O0 -pipe -g3 # CFLAGS += -fsanitize=address @@ -598,6 +598,53 @@ static char *ctime_now(char *buf) return buf; } +static inline void fast_itoa(int value, char *str) { + char *ptr; + char tmp; + + ptr = str; + while (value > 0) { + *ptr = (value % 10) + 48; + value /= 10; + ptr++; + } + *ptr = '\0'; + for (char *a = str, *b = ptr - 1; a < b; a++, b--) { + tmp = *a; + *a = *b; + *b = tmp; + } +} + +static inline int hash(const char* str) { + int hash = 1760977460; + char *ptr; + ptr = (char*)str; + while (*ptr != '\0') { + hash = (hash << 5) | (hash >> 27); + hash ^= *ptr; + hash *= 0x27220a95; + ptr++; + } + return (abs(hash) % 14) + 1; +} + +static inline void set_color(char* cbuf, const char *str) { + char buf[3] = ""; + int c = hash(str); + + if (c < 8) { + c += 30; + } + else { + c += 90 - 7; + } + strcpy(cbuf, "\x1b["); + fast_itoa(c, buf); + strcat(cbuf, buf); + strcat(cbuf, "m"); +} + static void print_error(char *fmt, ...) { va_list ap; @@ -695,21 +742,26 @@ static int connection_initialize(void) return 0; } -static void message_wrap(param p) +static void message_wrap(param p, const char *nick) { if (!p->message) { return; } + char color[8]; + color[0] = '\0'; + if (strstr(p->message, nick) != NULL) { + strcpy(color, "\x1b[36;1m"); + } char *tok; - size_t spaceleft = p->maxcols - (p->nicklen + p->offset); + size_t spaceleft = p->maxcols - (9 + strlen(p->nickname) + p->offset); for (tok = strtok(p->message, " "); tok != NULL; tok = strtok(NULL, " ")) { size_t wordwidth, spacewidth = 1; wordwidth = strnlen(tok, MSG_MAX); if ((wordwidth + spacewidth) > spaceleft) { - printf("\r\n%*.s%s ", (int)p->nicklen + 1, " ", tok); - spaceleft = p->maxcols - (p->nicklen + 1); + printf("\r\n%s%*.s%s ", color, (int)(9 + strlen(p->nickname)), " ", tok); + spaceleft = p->maxcols - (9 + strlen(p->nickname)); } else { - printf("%s ", tok); + printf("%s%s ", color, tok); } spaceleft -= wordwidth + spacewidth; } @@ -717,28 +769,43 @@ static void message_wrap(param p) static inline void param_print_nick(param p) { - printf("\x1b[35;1m%*s\x1b[0m ", p->nicklen - 4, p->nickname); - printf("--> \x1b[35;1m%s\x1b[0m", p->message); + char color[6]; + + set_color(color, p->nickname); + printf("%s%*s\x1b[0m ", color, p->nicklen - 4, p->nickname); + set_color(color, p->message); + printf("--> %s%s\x1b[0m", color, p->message); } static void param_print_part(param p) { - printf("%*s<-- \x1b[34;1m%s\x1b[0m", p->nicklen - 3, "", p->nickname); + char color[6]; + + set_color(color, p->nickname); + printf("%*s<-- %s%s\x1b[0m", p->nicklen - 3, "", color, p->nickname); if (p->channel != NULL && strcmp(p->channel + 1, chan)) { - printf(" [\x1b[33m%s\x1b[0m] ", p->channel); + set_color(color, p->channel + 1); + printf(" [%s%s\x1b[0m] ", color, p->channel); } } static inline void param_print_quit(param p) { - printf("%*s<<< \x1b[34;1m%s\x1b[0m", p->nicklen - 3, "", p->nickname); + char color[6]; + + set_color(color, p->nickname); + printf("%*s<<< %s%s\x1b[0m", p->nicklen - 3, "", color, p->nickname); } static void param_print_join(param p) { - printf("%*s--> \x1b[32;1m%s\x1b[0m", p->nicklen - 3, "", p->nickname); + char color[6]; + + set_color(color, p->nickname); + printf("%*s--> %s%s\x1b[0m", p->nicklen - 3, "", color, p->nickname); if (p->channel != NULL && strcmp(p->channel + 1, chan)) { - printf(" [\x1b[33m%s\x1b[0m] ", p->channel); + set_color(color, p->channel + 1); + printf(" [%s%s\x1b[0m] ", color, p->channel); } } @@ -1056,7 +1123,7 @@ static void filter_colors(char *string) return; } -static void print_timestamp(void) +static inline void print_timestamp(void) { time_t rawtime; struct tm *timeinfo; @@ -1080,34 +1147,40 @@ static void print_timestamp(void) static void param_print_private(param p) { + char color[6]; + + set_color(color, p->nickname); print_timestamp(); if (strnlen(p->nickname, p->nicklen) > (size_t)p->nicklen - 8) { *(p->nickname + p->nicklen - 8) = '\0'; } if (p->channel != NULL && (strcmp(p->channel, nick) == 0)) { handle_ctcp(p); - printf("\x1b[33;1m<%-.*s> [PRIVMSG]\x1b[36m ", p->nicklen, p->nickname); + printf("%s<%s> \x1b[33;1m[PRIVMSG]\x1b[36;1m ", color, p->nickname); p->offset += sizeof(" [PRIVMSG]"); } else if (p->channel != NULL && strcmp(p->channel + 1, chan)) { - printf("\x1b[33;1m<%-.*s>\x1b[0m", p->nicklen, p->nickname); - printf(" [\x1b[33m%s\x1b[0m] ", p->channel); + printf("%s<%s>\x1b[0m", color, p->nickname); + set_color(color, p->channel + 1); + printf(" [%s%s\x1b[0m] ", color, p->channel); p->offset += 12 + strnlen(p->channel, CHA_MAX); } else { if (!memcmp(p->message, "\x01" "ACTION", sizeof("\x01" "ACTION") - 1)) { p->message += sizeof("ACTION"); p->offset += sizeof(" \x1b[33;1m* "); - printf(" \x1b[33;1m* "); - printf("\x1b[33;1m%-.*s\x1b[0m ", p->nicklen, p->nickname); + printf(" %s* %s\x1b[0m ", color, p->nickname); } else { - printf("\x1b[33;1m<%-.*s>\x1b[0m ", p->nicklen, p->nickname); + printf("%s<%s>\x1b[0m ", color, p->nickname); } } } static void param_print_channel(param p) { - printf(" \x1b[33;1m%-.*s\x1b[0m ", p->nicklen, p->nickname); + char color[6]; + + set_color(color, p->nickname); + printf(" %s%s\x1b[0m ", color, p->nickname); if (p->params) { printf("%s", p->params); p->offset += strnlen(p->params, CHA_MAX); @@ -1195,12 +1268,12 @@ static void raw_parser(char *string) }if ((!memcmp(p.command, "PRIVMSG", sizeof("PRIVMSG") - 1)) || (!memcmp(p.command, "NOTICE", sizeof("NOTICE") - 1))) { filter_colors(p.message); /* this can be slow if -f is passed to kirc */ param_print_private(&p); - message_wrap(&p); + message_wrap(&p, nick); printf("\x1b[0m\r\n"); return; } param_print_channel(&p); - message_wrap(&p); + message_wrap(&p, nick); printf("\x1b[0m\r\n"); } @@ -1247,14 +1320,11 @@ static int handle_server_message(void) static inline void join_command(state l) { if (!strchr(l->buf, '#')){ - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); - printf("\x1b[35mIllegal channel!\x1b[0m\r\n"); + printf("\x1b[35m%s: illegal channel!\x1b[0m\r\n", l->buf); return; } *stpncpy(chan, strchr(l->buf, '#') + 1, MSG_MAX - 1) = '\0'; raw("JOIN #%s\r\n", chan); - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); - printf("\x1b[35mJoined #%s!\x1b[0m\r\n", chan); l->nick_privmsg = 0; } @@ -1264,9 +1334,6 @@ static inline void part_command(state l) tok = strchr(l->buf, '#'); if (tok){ raw("PART %s\r\n", tok); - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); - printf("\x1b[35mLeft %s!\r\n", tok); - printf("\x1b[35mYou need to use /join or /# to speak in a channel!\x1b[0m\r\n"); strcpy(chan, ""); return; } @@ -1276,19 +1343,17 @@ static inline void part_command(state l) } if (*tok == '#' || *tok == '\0') { raw("PART #%s\r\n", chan); - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); - printf("\x1b[35mLeft #%s!\r\n", chan); - printf("\x1b[35mYou need to use /join or /# to speak in a channel!\x1b[0m\r\n"); strcpy(chan, ""); return; } - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); - printf("\x1b[35mIllegal channel!\x1b[0m\r\n"); + printf("\x1b[35m%s: illegal channel!\x1b[0m\r\n", l->buf); } static inline void msg_command(state l) { + char color[6]; char *tok; + print_timestamp(); strtok_r(l->buf + sizeof("msg"), " ", &tok); int offset = 0; while (*(l->buf + sizeof("msg") + offset) == ' ') { @@ -1296,19 +1361,21 @@ static inline void msg_command(state l) } raw("PRIVMSG %s :%s\r\n", l->buf + sizeof("msg") + offset, tok); if (memcmp(l->buf + sizeof("msg") + offset, "NickServ", sizeof("NickServ") - 1)) { - printf("\x1b[35mprivmsg %s :%s\x1b[0m\r\n", l->buf + sizeof("msg") + offset, tok); + set_color(color, l->buf + sizeof("msg") + offset); + printf("\x1b[33m<%s>\x1b[0m \x1b[33;1m[PRIVMSG:\x1b[0m %s%s\x1b[33;1m] \x1b[32;1m%s\x1b[0m\r\n", nick, color, l->buf + sizeof("msg") + offset, tok); } } -static inline void action_command(state l) +static inline void action_command(state l, const char *nick) { int offset = 0; while (*(l->buf + sizeof("action") + offset) == ' ') { offset ++; } + print_timestamp(); raw("PRIVMSG #%s :\001ACTION %s\001\r\n", chan, l->buf + sizeof("action") + offset); - printf("\x1b[35mprivmsg #%s :ACTION %s\x1b[0m\r\n", chan, l->buf + sizeof("action") + offset); + printf(" \x1b[33m* %s\x1b[0m %s\n", nick, l->buf + sizeof("action") + offset); } static inline void query_command(state l) @@ -1319,8 +1386,6 @@ static inline void query_command(state l) } strcpy(chan, l->buf + sizeof("query") + offset); - - printf("\x1b[35mNew privmsg target: %s\x1b[0m\r\n", l->buf + sizeof("query") + offset); l->nick_privmsg = 1; } @@ -1329,7 +1394,6 @@ static inline void nick_command(state l) { char *tok; raw("%s\r\n", l->buf + 1); - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); tok = l->buf + sizeof("nick"); while (*tok == ' ') { tok++; @@ -1616,19 +1680,23 @@ close_fd: static inline void chan_privmsg(state l, char *channel, int offset, const char *nick, char default_chan) { + + char color[6]; + print_timestamp(); if(l->nick_privmsg == 0) { raw("PRIVMSG #%s :%s\r\n", channel, l->buf + offset); if (default_chan == 1) { - printf("\x1b[32;1m<%s>\x1b[0m %s\r\n", nick, l->buf + offset); + printf("\x1b[33m<%s>\x1b[0m %s\r\n", nick, l->buf + offset); return; } - printf("\x1b[32;1m<%s>\x1b[0m [\x1b[33m#%s\x1b[0m] %s\x1b[0m\r\n", nick, channel, l->buf + offset); + set_color(color, channel); + printf("\x1b[33m<%s>\x1b[0m [%s#%s\x1b[0m] %s\x1b[0m\r\n", nick, color, channel, l->buf + offset); } else { - // TODO: here raw("PRIVMSG %s :%s\r\n", channel, l->buf + offset); - printf("\x1b[35mprivmsg %s :%s\x1b[0m\r\n", channel, l->buf + offset); + set_color(color, channel); + printf("\x1b[33m<%s>\x1b[0m \x1b[33;1m[PRIVMSG:\x1b[0m %s%s\x1b[33;1m]\x1b[32;1m %s\x1b[0m\r\n", nick, color, channel, l->buf + offset); } } @@ -1650,6 +1718,7 @@ static void handle_user_input(state l, const char *nick) return; } char *tok; + char color[6]; size_t msg_len = strnlen(l->buf, MSG_MAX); if (msg_len > 0 && l->buf[msg_len - 1] == '\n') { l->buf[msg_len - 1] = '\0'; @@ -1686,7 +1755,7 @@ static void handle_user_input(state l, const char *nick) return; } if (!memcmp(l->buf + 1, "ACTION", sizeof("ACTION") - 1) || !memcmp(l->buf + 1, "action", sizeof("action") - 1)) { - action_command(l); + action_command(l, nick); return; } if (!memcmp(l->buf + 1, "QUERY", sizeof("QUERY") - 1) || !memcmp(l->buf + 1, "query", sizeof("query") - 1)) { @@ -1700,28 +1769,27 @@ static void handle_user_input(state l, const char *nick) if (l->buf[1] == '#') { strcpy(chan, l->buf + 2); l->nick_privmsg = 0; - printf("\x1b[35mnew channel: #%s\x1b[0m\r\n", chan); return; } raw("%s\r\n", l->buf + 1); - printf("\x1b[35m%s\x1b[0m\r\n", l->buf); return; case '@': /* send private message to target channel or user */ strtok_r(l->buf, " ", &tok); if (l->buf[1] != '@') { raw("PRIVMSG %s :%s\r\n", l->buf + 1, tok); - // printf("\x1b[35mprivmsg %s :%s\x1b[0m\r\n", l->buf + 1, tok); print_timestamp(); if (l->buf[1] == '#') { - printf("\x1b[32;1m<%s>\x1b[0m [\x1b[33m#%s\x1b[0m] %s\r\n", nick, l->buf + 2, tok); + set_color(color, l->buf + 2); + printf("\x1b[33m<%s>\x1b[0m [%s#%s\x1b[0m] %s\r\n", nick, color, l->buf + 2, tok); } else { - printf("\x1b[32;1m<%s>\x1b[0m \x1b[33;1m[PRIVMSG: <%s>]\x1b[32;1m %s\x1b[0m\r\n", nick, l->buf + 1, tok); + set_color(color, l->buf + 1); + printf("\x1b[33m<%s>\x1b[0m \x1b[33;1m[PRIVMSG:\x1b[0m %s%s\x1b[33;1m] \x1b[32;1m%s\x1b[0m\r\n", nick, color, l->buf + 1, tok); } return; } raw("PRIVMSG %s :\001ACTION %s\001\r\n", l->buf + 2, tok); - printf("\x1b[35mprivmsg %s :ACTION %s\x1b[0m\r\n", l->buf + 2, tok); + printf("\x1b[35mprivmsg %s: ACTION %s\x1b[0m\r\n", l->buf + 2, tok); return; default: /* send private message to default channel */ chan_privmsg(l, chan, 0, nick, 1); @@ -12,7 +12,7 @@ #define TESTCHARS "\xe1\xbb\xa4" #define MSG_MAX 512 /* irc rfc says lines are 512 char's max, but servers can accept more */ #define CHA_MAX 200 -#define WRAP_LEN 26 +#define WRAP_LEN 22 #define ABUF_LEN (sizeof("\r") - 1 + CHA_MAX + sizeof("> ") - 1 + MSG_MAX + sizeof("\x1b[0K") - 1 + 32 + 1) /* this is as big as the ab buffer can get */ #define HIS_MAX 100 |