hirc

IRC client
Log | Files | Refs

commit de8dc859614b4fc9acffb96776b5c7eb854aaf76
parent bc4ddc6513f2a5e0f7a792f13318d0b7c90784f8
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 28 Nov 2021 21:44:15 +0000

commands.c handle.c hirc.h serv.c struct.h: schedule msgs to run on certain events

Diffstat:
Mcommands.c | 17++++++++++++++---
Mhandle.c | 5+++++
Mhirc.h | 2++
Mserv.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mstruct.h | 8++++++++
5 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/commands.c b/commands.c @@ -89,15 +89,26 @@ command_quit(struct Server *server, char *str) { static void command_join(struct Server *server, char *str) { + char *chantypes, msg[512]; if (!str) { ui_error("/join requires argument", NULL); return; } - if (strchr(support_get(server, "CHANTYPES"), *str)) - ircprintf(server, "JOIN %s\r\n", str); + chantypes = support_get(server, "CHANTYPES"); + if (strchr(chantypes, *str)) + snprintf(msg, sizeof(msg), "JOIN %s\r\n", str); else - ircprintf(server, "JOIN #%s\r\n", str); + snprintf(msg, sizeof(msg), "JOIN %c%s\r\n", chantypes ? *chantypes : '#', str); + + if (server->status == ConnStatus_connected) + ircprintf(server, "%s", msg); + else + schedule_push(server, "376" /* RPL_ENDOFMOTD */, msg); + + /* Perhaps we should update expect from schedule? + * That'd make more sense if different stuff gets + * scheduled for events that happen at different times */ handle_expect(server, Expect_join, str); } diff --git a/handle.c b/handle.c @@ -483,6 +483,7 @@ handle(int rfd, struct Server *server) { time_t timestamp; char **params; char *cmd; + char *schmsg; char *msg; char buf[511]; /* using a buffer size of 511: @@ -521,6 +522,10 @@ handle(int rfd, struct Server *server) { else cmd = *(params); + /* Fire off any scheduled events for the current cmd */ + while ((schmsg = schedule_pull(server, cmd)) != NULL) + ircprintf(server, "%s", schmsg); + for (i=0; cmd && handlers[i].cmd; i++) { if (strcmp(handlers[i].cmd, cmd) == 0) { if (handlers[i].func) diff --git a/hirc.h b/hirc.h @@ -83,6 +83,8 @@ int serv_selected(struct Server *server); void serv_disconnect(struct Server *server, int reconnect, char *msg); char * support_get(struct Server *server, char *key); void support_set(struct Server *server, char *key, char *value); +void schedule_push(struct Server *server, char *tmsg, char *msg); +char * schedule_pull(struct Server *server, char *tmsg); /* handle.c */ void handle(int rfd, struct Server *server); diff --git a/serv.c b/serv.c @@ -336,3 +336,64 @@ support_set(struct Server *server, char *key, char *value) { p->next->key = key ? strdup(key) : NULL; p->next->value = value ? strdup(value) : NULL; } + +void +schedule_push(struct Server *server, char *tmsg, char *msg) { + struct Schedule *p; + + if (!server) + return; + + if (!server->schedule) { + server->schedule = malloc(sizeof(struct Schedule)); + server->schedule->prev = server->schedule->next = NULL; + server->schedule->tmsg = strdup(tmsg); + server->schedule->msg = strdup(msg); + return; + } + + for (p = server->schedule; p && p->next; p = p->next); + + p->next = malloc(sizeof(struct Schedule)); + p->next->prev = p; + p->next->next = NULL; + p->next->tmsg = strdup(tmsg); + p->next->msg = strdup(msg); +} + +char * +schedule_pull(struct Server *server, char *tmsg) { + static char *ret = NULL; + struct Schedule *p; + + if (!server || !tmsg) + return NULL; + + for (p = server->schedule; p; p = p->next) { + if (strcmp(p->tmsg, tmsg) == 0) { + free(p->tmsg); + + /* Don't free p->msg, instead save it to + * a static pointer that we free the next + * time schedule_pull is invoked. Since + * schedule_pull will probably be used in + * while loops until it equals NULL, this + * will likely be set free quite quickly */ + free(ret); + ret = p->msg; + + if (p->prev) p->prev->next = p->next; + if (p->next) p->next->prev = p->prev; + + if (!p->prev && !p->next) + server->schedule = NULL; + + free(p); + return ret; + } + } + + free(ret); + ret = NULL; + return NULL; +} diff --git a/struct.h b/struct.h @@ -95,6 +95,13 @@ enum Expect { Expect_last, }; +struct Schedule { + struct Schedule *prev; + char *tmsg; + char *msg; + struct Schedule *next; +}; + struct Server { struct Server *prev; int wfd; @@ -112,6 +119,7 @@ struct Server { struct HistInfo *history; struct Channel *channels; struct Channel *privs; + struct Schedule *schedule; int reconnect; char *expect[Expect_last]; int connectfail; /* number of failed connections */