diff options
| -rw-r--r-- | degesch.c | 110 | 
1 files changed, 63 insertions, 47 deletions
| @@ -3057,8 +3057,11 @@ on_irc_disconnected (struct server *s)  	while ((channel = str_map_iter_next (&iter)))  		irc_left_channel (channel); -	user_unref (s->irc_user); -	s->irc_user = NULL; +	if (s->irc_user) +	{ +		user_unref (s->irc_user); +		s->irc_user = NULL; +	}  	free (s->irc_user_mode);  	s->irc_user_mode = NULL; @@ -3251,14 +3254,6 @@ irc_register (struct server *s)  	irc_send (s, "NICK %s", nickname);  	// IRC servers may ignore the last argument if it's empty  	irc_send (s, "USER %s 8 * :%s", username, *realname ? realname : " "); - -	// XXX: maybe we should wait for the first message from the server -	// FIXME: the user may exist already after we've reconnected. Either -	//   make sure that there's no reference of this nick upon disconnection, -	//   or search in "irc_users" first... or something. -	s->irc_user = irc_make_user (s, xstrdup (nickname)); -	s->irc_user_mode = xstrdup (""); -	s->irc_user_host = NULL;  }  static void @@ -3507,6 +3502,8 @@ make_prompt (struct app_context *ctx, struct str *output)  		str_append_c (output, ' ');  		if (!irc_is_connected (s))  			str_append (output, "(disconnected)"); +		else if (s->state != IRC_REGISTERED) +			str_append (output, "(unregistered)");  		else  		{  			str_append (output, s->irc_user->nickname); @@ -3561,6 +3558,11 @@ irc_find_userhost (const char *prefix)  static bool  irc_is_this_us (struct server *s, const char *prefix)  { +	// This shouldn't be called before successfully registering. +	// Better safe than sorry, though. +	if (!s->irc_user) +		return false; +  	char *nick = irc_cut_nickname (prefix);  	bool result = !irc_strcmp (nick, s->irc_user->nickname);  	free (nick); @@ -3610,6 +3612,10 @@ irc_get_buffer_for_message (struct server *s,  static bool  irc_is_highlight (struct server *s, const char *message)  { +	// This may be called by notices before even successfully registering +	if (!s->irc_user) +		return false; +  	// Well, this is rather crude but it should make most users happy.  	// Ideally we could do this at least in proper Unicode.  	char *copy = xstrdup (message); @@ -4205,12 +4211,36 @@ irc_try_parse_welcome_for_userhost (struct server *s, const char *m)  }  static void +irc_on_registered (struct server *s, const char *nickname) +{ +	s->irc_user = irc_get_or_make_user (s, nickname); +	s->irc_user_mode = xstrdup (""); +	s->irc_user_host = NULL; + +	s->state = IRC_REGISTERED; +	refresh_prompt (s->ctx); + +	// TODO: parse any response and store the result for us in app_context; +	//   this enables proper message splitting on output; +	//   we can also use WHOIS if it's not supported (optional by RFC 2812) +	irc_send (s, "USERHOST %s", s->irc_user->nickname); + +	const char *autojoin = get_config_string (s->ctx, "server.autojoin"); +	if (autojoin) +		irc_send (s, "JOIN :%s", autojoin); + +	// TODO: rejoin all current channels (mark those we've left manually?) +} + +static void  irc_process_numeric (struct server *s,  	const struct irc_message *msg, unsigned long numeric)  {  	// Numerics typically have human-readable information  	// TODO: try to output certain replies in more specific buffers +	// TODO: fail the connection if there's no first parameter +  	// Get rid of the first parameter, if there's any at all,  	// as it contains our nickname and is of no practical use to the user  	struct str_vector copy; @@ -4228,6 +4258,8 @@ irc_process_numeric (struct server *s,  	switch (numeric)  	{  	case IRC_RPL_WELCOME: +		irc_on_registered (s, msg->params.vector[0]); +  		// We still issue a USERHOST anyway as this is in general unreliable  		if (msg->params.len == 2)  			irc_try_parse_welcome_for_userhost (s, msg->params.vector[1]); @@ -4270,28 +4302,6 @@ irc_process_message (const struct irc_message *msg,  		input_show (&s->ctx->input);  	} -	// XXX: or is the 001 numeric enough?  For what? -	if (s->state == IRC_CONNECTED && (!strcasecmp (msg->command, "MODE") -		|| !strcasecmp (msg->command, "376")    // RPL_ENDOFMOTD -		|| !strcasecmp (msg->command, "422")))  // ERR_NOMOTD -	{ -		// XXX: should we really print this? -		buffer_send_status (s->ctx, s->buffer, "Successfully connected"); -		s->state = IRC_REGISTERED; -		refresh_prompt (s->ctx); - -		// TODO: parse any response and store the result for us in app_context; -		//   this enables proper message splitting on output; -		//   we can also use WHOIS if it's not supported (optional by RFC 2812) -		irc_send (s, "USERHOST %s", s->irc_user->nickname); - -		const char *autojoin = get_config_string (s->ctx, "server.autojoin"); -		if (autojoin) -			irc_send (s, "JOIN :%s", autojoin); - -		// TODO: rejoin all current channels (mark those we've left manually?) -	} -  	struct irc_handler key = { .name = msg->command };  	struct irc_handler *handler = bsearch (&key, g_irc_handlers,  		N_ELEMENTS (g_irc_handlers), sizeof key, irc_handler_cmp_by_name); @@ -4402,7 +4412,7 @@ irc_autosplit_message (struct server *s, const char *message,  {  	// :<nick>!<user>@<host> <fixed-part><message>  	int space_in_one_message = 0; -	if (s->irc_user_host) +	if (s->irc_user && s->irc_user_host)  		space_in_one_message = 510  			- 1 - (int) strlen (s->irc_user->nickname)  			- 1 - (int) strlen (s->irc_user_host) @@ -4468,7 +4478,7 @@ log_outcoming_action (struct server *s,  {  	(void) a; -	if (buffer) +	if (buffer && soft_assert (s->irc_user))  		buffer_send (s->ctx, buffer, BUFFER_LINE_ACTION, 0,  			.who  = irc_to_utf8 (s->ctx, s->irc_user->nickname),  			.text = irc_to_utf8 (s->ctx, line)); @@ -4485,7 +4495,7 @@ static void  log_outcoming_privmsg (struct server *s,  	struct send_autosplit_args *a, struct buffer *buffer, const char *line)  { -	if (buffer) +	if (buffer && soft_assert (s->irc_user))  		buffer_send (s->ctx, buffer, BUFFER_LINE_PRIVMSG, 0,  			.who  = irc_to_utf8 (s->ctx, s->irc_user->nickname),  			.text = irc_to_utf8 (s->ctx, line)); @@ -4503,7 +4513,7 @@ static void  log_outcoming_notice (struct server *s,  	struct send_autosplit_args *a, struct buffer *buffer, const char *line)  { -	if (buffer) +	if (buffer && soft_assert (s->irc_user))  		buffer_send (s->ctx, buffer, BUFFER_LINE_NOTICE, 0,  			.who  = irc_to_utf8 (s->ctx, s->irc_user->nickname),  			.text = irc_to_utf8 (s->ctx, line)); @@ -4693,8 +4703,12 @@ try_decode_buffer (struct app_context *ctx, const char *word)  }  static bool -server_command_check (struct app_context *ctx, const char *action) +server_command_check (struct app_context *ctx, const char *action, +	bool need_registration)  { +	// "need_registration" is primarily for message sending commands, +	// as they may want to log buffer lines and use our current nickname +  	if (ctx->current_buffer->type == BUFFER_GLOBAL)  		buffer_send_error (ctx, ctx->current_buffer,  			"Can't do this from a global buffer (%s)", action); @@ -4703,6 +4717,8 @@ server_command_check (struct app_context *ctx, const char *action)  		struct server *s = ctx->current_buffer->server;  		if (!irc_is_connected (s))  			buffer_send_error (ctx, s->buffer, "Not connected"); +		else if (s->state != IRC_REGISTERED && need_registration) +			buffer_send_error (ctx, s->buffer, "Not registered");  		else  			return true;  	} @@ -4973,7 +4989,7 @@ handle_command_save (struct app_context *ctx, char *arguments)  static bool  handle_command_msg (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "send messages")) +	if (!server_command_check (ctx, "send messages", true))  		return true;  	if (!*arguments)  		return false; @@ -4990,7 +5006,7 @@ handle_command_msg (struct app_context *ctx, char *arguments)  static bool  handle_command_query (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "send messages")) +	if (!server_command_check (ctx, "send messages", true))  		return true;  	if (!*arguments)  		return false; @@ -5012,7 +5028,7 @@ handle_command_query (struct app_context *ctx, char *arguments)  static bool  handle_command_notice (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "send messages")) +	if (!server_command_check (ctx, "send messages", true))  		return true;  	if (!*arguments)  		return false; @@ -5029,7 +5045,7 @@ handle_command_notice (struct app_context *ctx, char *arguments)  static bool  handle_command_ctcp (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "send messages")) +	if (!server_command_check (ctx, "send messages", true))  		return true;  	if (!*arguments)  		return false; @@ -5056,7 +5072,7 @@ handle_command_ctcp (struct app_context *ctx, char *arguments)  static bool  handle_command_me (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "send messages")) +	if (!server_command_check (ctx, "send messages", true))  		return true;  	struct server *s = ctx->current_buffer->server; @@ -5087,7 +5103,7 @@ handle_command_quit (struct app_context *ctx, char *arguments)  static bool  handle_command_join (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "join")) +	if (!server_command_check (ctx, "join", true))  		return true;  	struct server *s = ctx->current_buffer->server; @@ -5116,7 +5132,7 @@ handle_command_join (struct app_context *ctx, char *arguments)  static bool  handle_command_part (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "part")) +	if (!server_command_check (ctx, "part", true))  		return true;  	struct server *s = ctx->current_buffer->server; @@ -5178,7 +5194,7 @@ handle_command_disconnect (struct app_context *ctx, char *arguments)  static bool  handle_command_list (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "list channels")) +	if (!server_command_check (ctx, "list channels", true))  		return true;  	struct server *s = ctx->current_buffer->server; @@ -5192,7 +5208,7 @@ handle_command_list (struct app_context *ctx, char *arguments)  static bool  handle_command_nick (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "change nickname")) +	if (!server_command_check (ctx, "change nickname", false))  		return true;  	if (!*arguments)  		return false; @@ -5205,7 +5221,7 @@ handle_command_nick (struct app_context *ctx, char *arguments)  static bool  handle_command_quote (struct app_context *ctx, char *arguments)  { -	if (!server_command_check (ctx, "quote")) +	if (!server_command_check (ctx, "quote", true))  		return true;  	struct server *s = ctx->current_buffer->server; | 
