sasl_input_clientdata(const struct sasl_message *const restrict smsg, struct sasl_session *const restrict p)
{
	/* This is complicated.
	 *
	 * Clients are restricted to sending us 300 bytes (400 Base-64 characters), but the mechanism
	 * that they have chosen could require them to send more than this amount, so they have to send
	 * it 400 Base-64 characters at a time in stages. When we receive data less than 400 characters,
	 * we know we don't need to buffer any more data, and can finally process it.
	 *
	 * However, if the client wants to send us a multiple of 400 characters and no more, we would be
	 * waiting forever for them to send 'the rest', even though there isn't any. This is solved by
	 * having them send a single '+' character to indicate that they have no more data to send.
	 *
	 * This is also what clients send us when they do not want to send us any data at all, and in
	 * either event, this is *NOT* *DATA* we are receiving, and we should not buffer it.
	 *
	 * Also, if the data is a single '*' character, the client is aborting authentication. Servers
	 * should send us a 'D' packet instead of a 'C *' packet in this case, but this is for if they
	 * don't. Note that this will usually result in the client getting a 904 numeric instead of 906,
	 * but the alternative is not treating '*' specially and then going on to fail to decode it in
	 * sasl_process_input() above, which will result in ... an aborted session and a 904 numeric.
	 * So this just saves time.
	 */

	const size_t len = strlen(smsg->parv[0]);

	// Abort?
	if (len == 1 && smsg->parv[0][0] == '*')
		return false;

	// End of data?
	if (len == 1 && smsg->parv[0][0] == '+')
	{
		if (p->buf)
			return sasl_process_buffer(p);

		// This function already deals with the special case of 1 '+' character
		return sasl_process_packet(p, smsg->parv[0], len);
	}

	/* Optimisation: If there is no buffer yet and this data is less than 400 characters, we don't
	 * need to buffer it at all, and can process it immediately.
	 */
	if (! p->buf && len < SASL_S2S_MAXLEN_ATONCE_B64)
		return sasl_process_packet(p, smsg->parv[0], len);

	/* We need to buffer the data now, but first check if the client hasn't sent us an excessive
	 * amount already.
	 */
	if ((p->len + len) > SASL_S2S_MAXLEN_TOTAL_B64)
	{
		(void) slog(LG_DEBUG, "%s: client %s has exceeded allowed data length", MOWGLI_FUNC_NAME, p->uid);
		return false;
	}

	// (Re)allocate a buffer, append the received data to it, and update its recorded length.
	p->buf = srealloc(p->buf, p->len + len + 1);
	(void) memcpy(p->buf + p->len, smsg->parv[0], len);
	p->len += len;

	// Messages not exactly 400 characters are the end of data.
	if (len < SASL_S2S_MAXLEN_ATONCE_B64)
		return sasl_process_buffer(p);

	return true;
}
sasl_input_clientdata(const struct sasl_message *const restrict smsg, struct sasl_session *const restrict p)
{
	 

	const size_t len = strlen(smsg->parv[0]);

	 
	if (len == 1 && smsg->parv[0][0] == '*')
		return false;

	 
	if (len == 1 && smsg->parv[0][0] == '+')
	{
		if (p->buf)
			return sasl_process_buffer(p);

		 
		return sasl_process_packet(p, smsg->parv[0], len);
	}

	 
	if (! p->buf && len < SASL_S2S_MAXLEN_ATONCE_B64)
		return sasl_process_packet(p, smsg->parv[0], len);

	 
	if ((p->len + len) > SASL_S2S_MAXLEN_TOTAL_B64)
	{
		(void) slog(LG_DEBUG, "%s: client %s has exceeded allowed data length", MOWGLI_FUNC_NAME, p->uid);
		return false;
	}

	 
	p->buf = srealloc(p->buf, p->len + len + 1);
	(void) memcpy(p->buf + p->len, smsg->parv[0], len);
	p->len += len;

	 
	if (len < SASL_S2S_MAXLEN_ATONCE_B64)
		return sasl_process_buffer(p);

	return true;
}