degesch: "nickname" -> "nicks"
Now you can specify multiple nicknames to try.
This commit is contained in:
parent
2b2da0beab
commit
5e7f9882dd
72
degesch.c
72
degesch.c
|
@ -1138,6 +1138,7 @@ struct server
|
||||||
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
||||||
|
|
||||||
struct user *irc_user; ///< Our own user
|
struct user *irc_user; ///< Our own user
|
||||||
|
int nick_counter; ///< Iterates "nicks" when registering
|
||||||
struct str irc_user_mode; ///< Our current user modes
|
struct str irc_user_mode; ///< Our current user modes
|
||||||
char *irc_user_host; ///< Our current user@host
|
char *irc_user_host; ///< Our current user@host
|
||||||
|
|
||||||
|
@ -1488,9 +1489,9 @@ config_validate_nonnegative
|
||||||
|
|
||||||
static struct config_schema g_config_server[] =
|
static struct config_schema g_config_server[] =
|
||||||
{
|
{
|
||||||
{ .name = "nickname",
|
{ .name = "nicks",
|
||||||
.comment = "IRC nickname",
|
.comment = "IRC nickname",
|
||||||
.type = CONFIG_ITEM_STRING,
|
.type = CONFIG_ITEM_STRING_ARRAY,
|
||||||
.validate = config_validate_nonjunk_string },
|
.validate = config_validate_nonjunk_string },
|
||||||
{ .name = "username",
|
{ .name = "username",
|
||||||
.comment = "IRC user name",
|
.comment = "IRC user name",
|
||||||
|
@ -4003,11 +4004,11 @@ static struct transport g_transport_tls =
|
||||||
static bool
|
static bool
|
||||||
irc_autofill_user_info (struct server *s, struct error **e)
|
irc_autofill_user_info (struct server *s, struct error **e)
|
||||||
{
|
{
|
||||||
const char *nickname = get_config_string (s->config, "nickname");
|
const char *nicks = get_config_string (s->config, "nicks");
|
||||||
const char *username = get_config_string (s->config, "username");
|
const char *username = get_config_string (s->config, "username");
|
||||||
const char *realname = get_config_string (s->config, "realname");
|
const char *realname = get_config_string (s->config, "realname");
|
||||||
|
|
||||||
if (nickname && username && realname)
|
if (nicks && *nicks && username && *username && realname)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Read POSIX user info and fill the configuration if needed
|
// Read POSIX user info and fill the configuration if needed
|
||||||
|
@ -4016,9 +4017,9 @@ irc_autofill_user_info (struct server *s, struct error **e)
|
||||||
FAIL ("cannot retrieve user information: %s", strerror (errno));
|
FAIL ("cannot retrieve user information: %s", strerror (errno));
|
||||||
|
|
||||||
// FIXME: set_config_strings() writes errors on its own
|
// FIXME: set_config_strings() writes errors on its own
|
||||||
if (!nickname)
|
if (!nicks || !*nicks)
|
||||||
set_config_string (s->config, "nickname", pwd->pw_name);
|
set_config_string (s->config, "nicks", pwd->pw_name);
|
||||||
if (!username)
|
if (!username || !*username)
|
||||||
set_config_string (s->config, "username", pwd->pw_name);
|
set_config_string (s->config, "username", pwd->pw_name);
|
||||||
|
|
||||||
// Not all systems have the GECOS field but the vast majority does
|
// Not all systems have the GECOS field but the vast majority does
|
||||||
|
@ -4037,16 +4038,33 @@ irc_autofill_user_info (struct server *s, struct error **e)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
irc_fetch_next_nickname (struct server *s)
|
||||||
|
{
|
||||||
|
struct str_vector v;
|
||||||
|
str_vector_init (&v);
|
||||||
|
split_str_ignore_empty (get_config_string (s->config, "nicks"), ',', &v);
|
||||||
|
|
||||||
|
char *result = NULL;
|
||||||
|
if (s->nick_counter >= 0 && s->nick_counter < v.len)
|
||||||
|
result = str_vector_steal (&v, s->nick_counter++);
|
||||||
|
if (s->nick_counter >= v.len)
|
||||||
|
// Exhausted all nicknames
|
||||||
|
s->nick_counter = -1;
|
||||||
|
|
||||||
|
str_vector_free (&v);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_register (struct server *s)
|
irc_register (struct server *s)
|
||||||
{
|
{
|
||||||
// Fill in user information automatically if needed
|
// Fill in user information automatically if needed
|
||||||
irc_autofill_user_info (s, NULL);
|
irc_autofill_user_info (s, NULL);
|
||||||
|
|
||||||
const char *nickname = get_config_string (s->config, "nickname");
|
|
||||||
const char *username = get_config_string (s->config, "username");
|
const char *username = get_config_string (s->config, "username");
|
||||||
const char *realname = get_config_string (s->config, "realname");
|
const char *realname = get_config_string (s->config, "realname");
|
||||||
hard_assert (nickname && username && realname);
|
hard_assert (username && realname);
|
||||||
|
|
||||||
// Start IRCv3.1 capability negotiation;
|
// Start IRCv3.1 capability negotiation;
|
||||||
// at worst the server will ignore this or send a harmless error message
|
// at worst the server will ignore this or send a harmless error message
|
||||||
|
@ -4056,7 +4074,15 @@ irc_register (struct server *s)
|
||||||
if (password)
|
if (password)
|
||||||
irc_send (s, "PASS :%s", password);
|
irc_send (s, "PASS :%s", password);
|
||||||
|
|
||||||
irc_send (s, "NICK %s", nickname);
|
s->nick_counter = 0;
|
||||||
|
|
||||||
|
char *nickname = irc_fetch_next_nickname (s);
|
||||||
|
if (nickname)
|
||||||
|
irc_send (s, "NICK :%s", nickname);
|
||||||
|
else
|
||||||
|
log_server_error (s, s->buffer, "No nicks present in configuration");
|
||||||
|
free (nickname);
|
||||||
|
|
||||||
// IRC servers may ignore the last argument if it's empty
|
// IRC servers may ignore the last argument if it's empty
|
||||||
irc_send (s, "USER %s 8 * :%s", username, *realname ? realname : " ");
|
irc_send (s, "USER %s 8 * :%s", username, *realname ? realname : " ");
|
||||||
}
|
}
|
||||||
|
@ -5647,6 +5673,28 @@ irc_handle_rpl_inviting (struct server *s, const struct irc_message *msg)
|
||||||
"You have invited #n to #S", nickname, channel_name);
|
"You have invited #n to #S", nickname, channel_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_err_nicknameinuse (struct server *s, const struct irc_message *msg)
|
||||||
|
{
|
||||||
|
if (msg->params.len < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_server_error (s, s->buffer,
|
||||||
|
"Nickname is already in use: #S", msg->params.vector[1]);
|
||||||
|
|
||||||
|
// Only do this while we haven't successfully registered yet
|
||||||
|
if (s->state != IRC_CONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *nickname = irc_fetch_next_nickname (s);
|
||||||
|
if (nickname)
|
||||||
|
{
|
||||||
|
log_server_status (s, s->buffer, "Retrying with #s...", nickname);
|
||||||
|
irc_send (s, "NICK :%s", nickname);
|
||||||
|
free (nickname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -5848,9 +5896,7 @@ irc_process_numeric (struct server *s,
|
||||||
irc_handle_rpl_inviting (s, msg); buffer = NULL; break;
|
irc_handle_rpl_inviting (s, msg); buffer = NULL; break;
|
||||||
|
|
||||||
case IRC_ERR_NICKNAMEINUSE:
|
case IRC_ERR_NICKNAMEINUSE:
|
||||||
// TODO: if (state == IRC_CONNECTED), use a different nick;
|
irc_handle_err_nicknameinuse (s, msg); buffer = NULL; break;
|
||||||
// either use a number suffix, or accept commas in "nickname" config
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRC_RPL_LIST:
|
case IRC_RPL_LIST:
|
||||||
case IRC_RPL_WHOREPLY:
|
case IRC_RPL_WHOREPLY:
|
||||||
|
|
Loading…
Reference in New Issue