Index: libuirc/libuirc.c =================================================================== --- libuirc/libuirc.c (revision 20985) +++ libuirc/libuirc.c (revision 20986) @@ -13,6 +13,19 @@ return -1; } +static int uirc_query_search(uirc_t *ctx, char *name) +{ + int n; + for(n = 0; n < UIRC_MAX_QUERIES; n++) { + if ((ctx->query[n].type != UIRC_CHAN) && (ctx->query[n].type != UIRC_PRIV)) + continue; + if (strcmp(name, ctx->query[n].name) == 0) + return n; + } + return -1; +} + + int uirc_connect(uirc_t *ctx, const char *server, int port, char *user) { if (P_tcp4_connect(&ctx->sk, server, port, NULL, 0, P_net_nonblock_full) != 0) @@ -40,7 +53,7 @@ } -static uirc_event_t uic_parse_001(uirc_t *ctx, char *arg) +static uirc_event_t uirc_parse_001(uirc_t *ctx, char *arg) { /*:hu.irc.libgpmi.org 001 libuirc :Welcome to the Internet Relay Network libuirc!~libuirc@78-131-56-146.static.hdsnet.hu*/ if (ctx->on_connect != NULL) @@ -48,9 +61,49 @@ return UIRC_CONNECT; } +#define irc_strcasecmp strcasecmp + +static uirc_event_t uirc_parse_join(uirc_t *ctx, char *nick, char *arg) +{ + int q; +/*:libuirc!~libuirc@78-131-56-146.static.hdsnet.hu JOIN :#dev*/ + + if (*arg == ':') arg++; + + q = uirc_query_search(ctx, arg); + if (irc_strcasecmp(nick, ctx->nick) == 0) { + uirc_event_t res = 0; + if (q < 0) { + q = uirc_query_alloc(ctx); + if (q < 0) { + gds_append_str(&ctx->obuf, "part "); + gds_append_str(&ctx->obuf, arg); + gds_append_str(&ctx->obuf, " :I am on too many channels already.\n"); + return 0; + } + ctx->query[q].type = UIRC_CHAN; + ctx->query[q].name = strdup(arg); + ctx->last_new_query = q; + res |= UIRC_QUERY_BEGIN; + } + + if (ctx->on_me_join != NULL) + ctx->on_me_join(ctx, q, arg); + return res | UIRC_ME_JOIN; + } + + if ((q >= 0) && (ctx->on_join != NULL)) { + ctx->on_join(ctx, nick, q, arg); + return UIRC_JOIN; + } + + return 0; +} + + static uirc_event_t uirc_parse(uirc_t *ctx, char *line) { - char *arg, *cmd, *from = line; + char *end, *arg, *cmd, *from = line; uirc_event_t res = 0; printf("line='%s'\n", line); @@ -73,6 +126,13 @@ res |= UIRC_GOT_MISC; } + end = strchr(from, '!'); + if (end != NULL) { + if (*from == ':') + from++; + *end = 0; + } + arg = strpbrk(cmd, " \t\r\n"); if (arg != NULL) { *arg = '\0'; @@ -79,8 +139,13 @@ arg++; } - if (strcmp(cmd, "001") == 0) return res | uic_parse_001(ctx, arg); + end = strpbrk(arg, "\r\n"); + if (end != NULL) + *end = '\0'; + if (strcmp(cmd, "001") == 0) return res | uirc_parse_001(ctx, arg); + if (strcasecmp(cmd, "join") == 0) return res | uirc_parse_join(ctx, from, arg); + return res; } Index: libuirc/libuirc.h =================================================================== --- libuirc/libuirc.h (revision 20985) +++ libuirc/libuirc.h (revision 20986) @@ -22,13 +22,15 @@ } uirc_query_t; typedef enum { /* bitfield */ - UIRC_CONNECT = 0x01, - UIRC_DISCONNECT = 0x02, - UIRC_GOT_MSG = 0x04, - UIRC_GOT_MISC = 0x08, - UIRC_GOT_QUERY_BEGIN = 0x10, - UIRC_GOT_QUERY_END = 0x20, - UIRC_GOT_ME_QUIT = 0x40, + UIRC_CONNECT = 0x0001, + UIRC_DISCONNECT = 0x0002, + UIRC_GOT_MSG = 0x0004, + UIRC_GOT_MISC = 0x0008, + UIRC_QUERY_BEGIN = 0x0010, + UIRC_QUERY_END = 0x0020, + UIRC_ME_QUIT = 0x0040, + UIRC_ME_JOIN = 0x0080, + UIRC_JOIN = 0x0100 } uirc_event_t; typedef struct uirc_s uirc_t; @@ -35,7 +37,7 @@ struct uirc_s { char *nick; uirc_query_t query[UIRC_MAX_QUERIES]; /* query 0 is special: server "window" */ - int curr_query; + int curr_query, last_new_query; void *user_data; void (*on_connect)(uirc_t *ctx); @@ -45,6 +47,8 @@ void (*on_query_begin)(uirc_t *ctx, int query_to); void (*on_query_end)(uirc_t *ctx, int query_to); /* called on leaving the channel for any reason */ void (*on_me_quit)(uirc_t *ctx); + void (*on_me_join)(uirc_t *ctx, int query, char *chan); + void (*on_join)(uirc_t *ctx, char *nick, int query, char *chan); /* internal */