hirc

IRC client
Log | Files | Refs

commit fc9a7b8e501ffacf92de6bd4397f45242f2bdbd7
parent 1f6d02a39ebad76585e9ddb1e1383275c548c6d3
Author: hhvn <dev@hhvn.uk>
Date:   Mon, 20 Dec 2021 17:01:05 +0000

s/commands.c s/handle.c s/ui.c s/config.c s/struct.h: /nick

Diffstat:
Msrc/commands.c | 15+++++++++++++++
Msrc/config.c | 9+++++++--
Msrc/handle.c | 21+++++++++++++++------
Msrc/struct.h | 1+
Msrc/ui.c | 1+
5 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/commands.c b/src/commands.c @@ -38,6 +38,7 @@ static void command_join(struct Server *server, char *str); static void command_part(struct Server *server, char *str); static void command_kick(struct Server *server, char *str); static void command_mode(struct Server *server, char *str); +static void command_nick(struct Server *server, char *str); static void command_whois(struct Server *server, char *str); static void command_whowas(struct Server *server, char *str); static void command_ping(struct Server *server, char *str); @@ -102,6 +103,9 @@ struct Command commands[] = { {"mode", command_mode, 1, { "usage: /mode <channel> modes...", "Set/unset channel modes", NULL}}, + {"nick", command_nick, 1, { + "usage: /nick <nick>", + "Get a new nick", NULL}}, {"whois", command_whois, 1, { "usage: /whois [server] [nick]", "Request information on a nick or oneself", NULL}}, @@ -421,6 +425,17 @@ command_mode(struct Server *server, char *str) { } static void +command_nick(struct Server *server, char *str) { + if (!str || strchr(str, ' ')) { + ui_error("/nick takes 1 argument", NULL); + return; + } + + ircprintf(server, "NICK %s\r\n", str); + handle_expect(server, Expect_nicknameinuse, str); +} + +static void command_whois(struct Server *server, char *str) { char *tserver, *nick; diff --git a/src/config.c b/src/config.c @@ -400,6 +400,11 @@ struct Config config[] = { .strhandle = config_redraws, .description = { "Format of notices", NULL}}, + {"format.nick", 1, Val_string, + .str = "%{nick:${nick}}${nick}%{o}%{=}is now known as %{nick:${1}}${1}", + .strhandle = config_redraws, + .description = { + "Format of NICK messages", NULL}}, {"format.join", 1, Val_string, .str = "%{b}%{c:44}+%{o}%{=}%{nick:${nick}}${nick}%{o} (${ident}@${host})", .strhandle = config_redraws, @@ -948,12 +953,12 @@ struct Config config[] = { .description = { "Format of ERR_NONICKNAMEGIVEN (431) numeric", NULL}}, {"format.err.erroneusnickname", 1, Val_string, - .str = "${2-}", + .str = "Erroneous nickname: ${2}", .strhandle = config_redraws, .description = { "Format of ERR_ERRONEUSNICKNAME (432) numeric", NULL}}, {"format.err.nicknameinuse", 1, Val_string, - .str = "${2-}", + .str = "Nickname already in use: ${2}", .strhandle = config_redraws, .description = { "Format of ERR_NICKNAMEINUSE (433) numeric", NULL}}, diff --git a/src/handle.c b/src/handle.c @@ -425,11 +425,16 @@ handle_ERR_NICKNAMEINUSE(char *msg, char **params, struct Server *server, time_t char nick[64]; /* should be limited to 9 chars, but newer servers *shrug*/ hist_add(server->history, NULL, msg, params, Activity_status, timestamp, HIST_DFL); - snprintf(nick, sizeof(nick), "%s_", server->self->nick); - nick_free(server->self); - server->self = nick_create(nick, ' ', server); - server->self->self = 1; - ircprintf(server, "NICK %s\r\n", nick); + + if (handle_expect_get(server, Expect_nicknameinuse) == NULL) { + snprintf(nick, sizeof(nick), "%s_", server->self->nick); + nick_free(server->self); + server->self = nick_create(nick, ' ', server); + server->self->self = 1; + ircprintf(server, "NICK %s\r\n", nick); + } else { + handle_expect(server, Expect_nicknameinuse, NULL); + } } static void @@ -438,6 +443,7 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) { struct Channel *chan; char prefix[128]; char *newnick; + char priv; if (**params != ':' || !*(params+1) || !*(params+2)) return; @@ -453,14 +459,17 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) { nick_free(server->self); server->self = nick_create(newnick, ' ', server); server->self->self = 1; + handle_expect(server, Expect_nicknameinuse, NULL); } for (chan = server->channels; chan; chan = chan->next) { if ((chnick = nick_get(&chan->nicks, nick->nick)) != NULL) { snprintf(prefix, sizeof(prefix), ":%s!%s@%s", newnick, chnick->ident, chnick->host); + priv = chnick->priv; nick_remove(&chan->nicks, nick->nick); - nick_add(&chan->nicks, prefix, chnick->priv, server); + nick_add(&chan->nicks, prefix, priv, server); + hist_add(chan->history, nick, msg, params, Activity_status, timestamp, HIST_SHOW); if (selected.channel == chan) windows[Win_nicklist].refresh = 1; } diff --git a/src/struct.h b/src/struct.h @@ -115,6 +115,7 @@ enum Expect { Expect_topic, Expect_topicwhotime, Expect_channelmodeis, + Expect_nicknameinuse, Expect_last, }; diff --git a/src/ui.c b/src/ui.c @@ -96,6 +96,7 @@ struct { {"PART", "format.part"}, {"KICK", "format.kick"}, {"QUIT", "format.quit"}, + {"NICK", "format.nick"}, /* START: misc/rpl-ui-gen.awk */ {"200", "format.rpl.tracelink"}, {"201", "format.rpl.traceconnecting"},