/* $OpenBSD: esc.c,v 1.5 2016/09/03 22:16:39 gilles Exp $	 */

/*
 * Copyright (c) 2014 Gilles Chehade <gilles@poolp.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "includes.h"

#include <stdio.h>
#include <limits.h>

#include "smtpd-defines.h"
#include "smtpd-api.h"

static struct escode {
	enum enhanced_status_code	code;
	const char		       *description;
} esc[] = {
	/* 0.0 */
	{ ESC_OTHER_STATUS,				"Other/Undefined" },

	/* 1.x */
	{ ESC_OTHER_ADDRESS_STATUS,			"Other/Undefined address status" },
	{ ESC_BAD_DESTINATION_MAILBOX_ADDRESS,		"Bad destination mailbox address" },
	{ ESC_BAD_DESTINATION_SYSTEM_ADDRESS,		"Bad destination system address" },
	{ ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX,	"Bad destination mailbox address syntax" },
	{ ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS,	"Destination mailbox address ambiguous" },
	{ ESC_DESTINATION_ADDRESS_VALID,		"Destination address valid" },
	{ ESC_DESTINATION_MAILBOX_HAS_MOVED,		"Destination mailbox has moved, No forwarding address" },
	{ ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX,	"Bad sender's mailbox address syntax" },
	{ ESC_BAD_SENDER_SYSTEM_ADDRESS,		"Bad sender's system address syntax" },

	/* 2.x */
	{ ESC_OTHER_MAILBOX_STATUS,			"Other/Undefined mailbox status" },
	{ ESC_MAILBOX_DISABLED,				"Mailbox disabled, not accepting messages" },
	{ ESC_MAILBOX_FULL,				"Mailbox full" },
	{ ESC_MESSAGE_LENGTH_TOO_LARGE,			"Message length exceeds administrative limit" },
	{ ESC_MAILING_LIST_EXPANSION_PROBLEM,		"Mailing list expansion problem" },

	/* 3.x */
	{ ESC_OTHER_MAIL_SYSTEM_STATUS,			"Other/Undefined mail system status" },
	{ ESC_MAIL_SYSTEM_FULL,				"Mail system full" },
	{ ESC_SYSTEM_NOT_ACCEPTING_MESSAGES,		"System not accepting network messages" },
	{ ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES,	"System not capable of selected features" },
	{ ESC_MESSAGE_TOO_BIG_FOR_SYSTEM,		"Message too big for system" },
	{ ESC_SYSTEM_INCORRECTLY_CONFIGURED,		"System incorrectly configured" },

	/* 4.x */
	{ ESC_OTHER_NETWORK_ROUTING_STATUS,		"Other/Undefined network or routing status" },
	{ ESC_NO_ANSWER_FROM_HOST,			"No answer from host" },
	{ ESC_BAD_CONNECTION,				"Bad connection" },
	{ ESC_DIRECTORY_SERVER_FAILURE,			"Directory server failure" },
	{ ESC_UNABLE_TO_ROUTE,				"Unable to route" },
	{ ESC_MAIL_SYSTEM_CONGESTION,			"Mail system congestion" },
	{ ESC_ROUTING_LOOP_DETECTED,			"Routing loop detected" },
	{ ESC_DELIVERY_TIME_EXPIRED,			"Delivery time expired" },

	/* 5.x */
	{ ESC_INVALID_RECIPIENT,			"Invalid recipient" },
	{ ESC_INVALID_COMMAND,				"Invalid command" },
	{ ESC_SYNTAX_ERROR,				"Syntax error" },
	{ ESC_TOO_MANY_RECIPIENTS,			"Too many recipients" },
	{ ESC_INVALID_COMMAND_ARGUMENTS,		"Invalid command arguments" },
	{ ESC_WRONG_PROTOCOL_VERSION,			"Wrong protocol version" },

	/* 6.x */
	{ ESC_OTHER_MEDIA_ERROR,			"Other/Undefined media error" },
	{ ESC_MEDIA_NOT_SUPPORTED,			"Media not supported" },
	{ ESC_CONVERSION_REQUIRED_AND_PROHIBITED,	"Conversion required and prohibited" },
	{ ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED,	"Conversion required but not supported" },
	{ ESC_CONVERSION_WITH_LOSS_PERFORMED,		"Conversion with loss performed" },
	{ ESC_CONVERSION_FAILED,			"Conversion failed" },

	/* 7.x */
	{ ESC_OTHER_SECURITY_STATUS,			"Other/Undefined security status" },
	{ ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED,	"Delivery not authorized, message refused" },
	{ ESC_MAILING_LIST_EXPANSION_PROHIBITED,       	"Mailing list expansion prohibited" },
	{ ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE,"Security conversion required but not possible" },
	{ ESC_SECURITY_FEATURES_NOT_SUPPORTED,		"Security features not supported" },
	{ ESC_CRYPTOGRAPHIC_FAILURE,			"Cryptographic failure" },
	{ ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED,	"Cryptographic algorithm not supported" },
	{ ESC_MESSAGE_TOO_BIG_FOR_SYSTEM,		"Message integrity failure" },
};

const char *
esc_code(enum enhanced_status_class class, enum enhanced_status_code code)
{
	static char buffer[6];

	(void)snprintf(buffer, sizeof buffer, "%d.%d.%d", class, code / 10, code % 10);
	return buffer;

}

const char *
esc_description(enum enhanced_status_code code)
{
	uint32_t	i;

	for (i = 0; i < nitems(esc); ++i)
		if (code == esc[i].code)
			return esc[i].description;
	return "Other/Undefined";
}
