/*
 * Copyright (c) 2015 Fujitsu Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <errno.h>
#include "test.h"
#include "safe_net_fn.h"

char *tst_sock_addr(const struct sockaddr *sa, socklen_t salen, char *res,
		    size_t len)
{
	char portstr[8];

	switch (sa->sa_family) {

	case AF_INET: {
		struct sockaddr_in *sin = (struct sockaddr_in *)sa;

		if (!inet_ntop(AF_INET, &sin->sin_addr, res, len))
			return NULL;

		if (ntohs(sin->sin_port) != 0) {
			snprintf(portstr, sizeof(portstr), ":%d",
				 ntohs(sin->sin_port));
			strcat(res, portstr);
		}

		return res;
	}

	case AF_INET6: {
		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;

		res[0] = '[';
		if (!inet_ntop(AF_INET6, &sin6->sin6_addr, res + 1, len - 1))
			return NULL;

		if (ntohs(sin6->sin6_port) != 0) {
			snprintf(portstr, sizeof(portstr), "]:%d",
				 ntohs(sin6->sin6_port));
			strcat(res, portstr);
			return res;
		}

		return res + 1;
	}

	case AF_UNIX: {
		struct sockaddr_un *unp = (struct sockaddr_un *)sa;

		if (unp->sun_path[0] == '\0')
			strcpy(res, "(no pathname bound)");
		else
			snprintf(res, len, "%s", unp->sun_path);

		return res;
	}

	default: {
		snprintf(res, len,
			 "sock_ntop: unknown AF_xxx: %d, len: %d",
			 sa->sa_family, salen);

		return res;
	}

	}
}

int safe_socket(const char *file, const int lineno, void (cleanup_fn)(void),
		int domain, int type, int protocol)
{
	int rval;

	rval = socket(domain, type, protocol);

	if (rval < 0) {
		tst_brkm(TBROK | TERRNO, cleanup_fn,
			 "%s:%d: socket(%d, %d, %d) failed", file, lineno,
			 domain, type, protocol);
	}

	return rval;
}

int safe_bind(const char *file, const int lineno, void (cleanup_fn)(void),
	      int socket, const struct sockaddr *address,
	      socklen_t address_len)
{
	int i;
	char buf[128];

	for (i = 0; i < 120; i++) {
		if (!bind(socket, address, address_len))
			return 0;

		if (errno != EADDRINUSE) {
			tst_brkm(TBROK | TERRNO, cleanup_fn,
				 "%s:%d: bind(%d, %s, %d) failed", file, lineno,
				 socket, tst_sock_addr(address, address_len,
						       buf, sizeof(buf)),
				 address_len);
		}

		if ((i + 1) % 10 == 0) {
			tst_resm(TINFO, "address is in use, waited %3i sec",
				 i + 1);
		}

		sleep(1);
	}

	tst_brkm(TBROK | TERRNO, cleanup_fn,
		 "%s:%d: Failed to bind(%d, %s, %d) after 120 retries", file,
		 lineno, socket,
		 tst_sock_addr(address, address_len, buf, sizeof(buf)),
		 address_len);
}

int safe_listen(const char *file, const int lineno, void (cleanup_fn)(void),
		int socket, int backlog)
{
	int rval;

	rval = listen(socket, backlog);

	if (rval < 0) {
		tst_brkm(TBROK | TERRNO, cleanup_fn,
			 "%s:%d: listen(%d, %d) failed", file, lineno, socket,
			 backlog);
	}

	return rval;
}

int safe_connect(const char *file, const int lineno, void (cleanup_fn)(void),
		 int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
	int rval;
	char buf[128];

	rval = connect(sockfd, addr, addrlen);

	if (rval < 0) {
		tst_brkm(TBROK | TERRNO, cleanup_fn,
			 "%s:%d: connect(%d, %s, %d) failed", file, lineno,
			 sockfd, tst_sock_addr(addr, addrlen, buf,
					       sizeof(buf)), addrlen);
	}

	return rval;
}

int safe_getsockname(const char *file, const int lineno,
		     void (cleanup_fn)(void), int sockfd, struct sockaddr *addr,
		     socklen_t *addrlen)
{
	int rval;
	char buf[128];

	rval = getsockname(sockfd, addr, addrlen);

	if (rval < 0) {
		tst_brkm(TBROK | TERRNO, cleanup_fn,
			 "%s:%d: getsockname(%d, %s, %d) failed", file, lineno,
			 sockfd, tst_sock_addr(addr, *addrlen, buf,
					       sizeof(buf)), *addrlen);
	}

	return rval;
}
