degesch: avoid crashing on null user info

This commit is contained in:
Přemysl Eric Janouch 2015-05-16 12:39:30 +02:00
parent ca8540e217
commit c2c82d20dd
1 changed files with 42 additions and 41 deletions

View File

@ -3269,14 +3269,52 @@ end:
// --- Connection establishment ------------------------------------------------
static void
irc_register (struct server *s)
static bool
irc_autofill_user_info (struct server *s, struct error **e)
{
const char *nickname = get_config_string (s->config, "nickname");
const char *username = get_config_string (s->config, "username");
const char *realname = get_config_string (s->config, "realname");
// These are filled automatically if needed
if (nickname && username && realname)
return true;
// Read POSIX user info and fill the configuration if needed
struct passwd *pwd = getpwuid (geteuid ());
if (!pwd)
FAIL ("cannot retrieve user information: %s", strerror (errno));
// FIXME: set_config_strings() writes errors on its own
if (!nickname)
set_config_string (s->config, "nickname", pwd->pw_name);
if (!username)
set_config_string (s->config, "username", pwd->pw_name);
// Not all systems have the GECOS field but the vast majority does
if (!realname)
{
char *gecos = pwd->pw_gecos;
// The first comma, if any, ends the user's real name
char *comma = strchr (gecos, ',');
if (comma)
*comma = '\0';
set_config_string (s->config, "realname", gecos);
}
return true;
}
static void
irc_register (struct server *s)
{
// Fill in user information automatically if needed
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 *realname = get_config_string (s->config, "realname");
hard_assert (nickname && username && realname);
irc_send (s, "NICK %s", nickname);
@ -6318,43 +6356,6 @@ app_editline_init (struct input *self)
// --- Configuration loading ---------------------------------------------------
static bool
autofill_user_info (struct server *s, struct error **e)
{
const char *nickname = get_config_string (s->config, "nickname");
const char *username = get_config_string (s->config, "username");
const char *realname = get_config_string (s->config, "realname");
if (nickname && username && realname)
return true;
// Read POSIX user info and fill the configuration if needed
struct passwd *pwd = getpwuid (geteuid ());
if (!pwd)
FAIL ("cannot retrieve user information: %s", strerror (errno));
// FIXME: set_config_strings() writes errors on its own
if (!nickname)
set_config_string (s->config, "nickname", pwd->pw_name);
if (!username)
set_config_string (s->config, "username", pwd->pw_name);
// Not all systems have the GECOS field but the vast majority does
if (!realname)
{
char *gecos = pwd->pw_gecos;
// The first comma, if any, ends the user's real name
char *comma = strchr (gecos, ',');
if (comma)
*comma = '\0';
set_config_string (s->config, "realname", gecos);
}
return true;
}
static bool
read_file (const char *filename, struct str *output, struct error **e)
{
@ -6664,7 +6665,7 @@ create_server (struct app_context *ctx)
s->reconnect_delay = get_config_integer (s->config, "reconnect_delay");
struct error *e = NULL;
if (!autofill_user_info (s, &e))
if (!irc_autofill_user_info (s, &e))
{
print_error ("%s: %s", "failed to fill in user details", e->message);
error_free (e);