// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2019 Daniel Borkmann <daniel@iogearbox.net> */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/syscall.h>

#include "l2md.h"

bool verbose_enabled;

void *xmalloc(size_t size)
{
	void *ptr;

	if (!size)
		panic("xmalloc: zero size\n");
	ptr = malloc(size);
	if (ptr == NULL)
		panic("xmalloc: out of memory (allocating %zu bytes)\n", size);
	return ptr;
}

void *xzmalloc(size_t size)
{
	void *ptr = xmalloc(size);

	memset(ptr, 0, size);
	return ptr;
}

void *xrealloc(void *old, size_t size)
{
	void *new;

	if (size == 0)
		panic("xrealloc: zero size\n");
	new = realloc(old, size);
	if (new == NULL)
		panic("xrealloc: out of memory (allocating %zu bytes)\n", size);
	return new;
}

void xfree(void *ptr)
{
	free(ptr);
}

void xmkdir1(const char *path)
{
	struct stat sb = {};
	int ret;

	ret = stat(path, &sb);
	if (ret) {
		ret = mkdir(path, S_IRWXU);
		if (ret)
			panic("mkdir %s failed: %s\n", path, strerror(errno));
	}
}

void xmkdir1_with_subdirs(const char *path)
{
	char tmp[PATH_MAX], *ptr;
	size_t len;

	slprintf(tmp, sizeof(tmp),"%s", path);
	len = strlen(tmp);
	if (tmp[len - 1] == '/')
		tmp[len - 1] = 0;
	for (ptr = tmp + 1; *ptr; ptr++) {
		if (*ptr == '/') {
			*ptr = 0;
			xmkdir1(tmp);
			*ptr = '/';
		}
	}
	xmkdir1(tmp);
}

void xmkdir2(const char *base, const char *name)
{
	char path[PATH_MAX];

	slprintf(path, sizeof(path), "%s/%s", base, name);
	xmkdir1(path);
}

int xread_file(const char *file, char *to, size_t len, bool fatal)
{
	loff_t ret;
	int fd;

	fd = open(file, O_RDONLY);
	if (fd < 0) {
		if (fatal)
			panic("Cannot open %s: %s\n", file, strerror(errno));
		else
			return fd;
	}

	do {
		ret = read(fd, to, len);
		if (ret <= 0) {
			if (fatal) {
				if (ret)
					panic("Cannot read file %s: %s\n",
					      file, strerror(errno));
				else
					panic("Unexpected end of file %s\n",
					      file);
			} else {
				if (!ret)
					warn("Unexpected end of file %s\n",
					     file);
				close(fd);
				return -1;
			}
		}
		to  += ret;
		len -= ret;
	} while (len > 0);

	close(fd);
	return 0;
}

int xwrite_file(const char *file, const char *to, size_t len, bool fatal)
{
	loff_t ret;
	int fd;

	fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0600);
	if (fd < 0) {
		if (fatal)
			panic("Cannot open %s: %s\n", file, strerror(errno));
		else
			return fd;
	}

	do {
		ret = write(fd, to, len);
		if (ret < 0) {
			if (fatal) {
				panic("Cannot write file %s: %s\n", file,
				      strerror(errno));
			} else {
				close(fd);
				return -1;
			}
		}
		to  += ret;
		len -= ret;
	} while (len > 0);

	close(fd);
	return 0;
}

void xpipe(int pipefd[2])
{
	if (pipe(pipefd) < 0)
		panic("Cannot create pipe: %s\n", strerror(errno));
}

void xwrite(int fd, const char *to, size_t len)
{
	loff_t ret;

	do {
		ret = write(fd, to, len);
		if (ret < 0)
			panic("Cannot write to file descriptor %d: %s",
			      fd, strerror(errno));
		to  += ret;
		len -= ret;
	} while (len > 0);
}

int timeval_sub(struct timeval *res, struct timeval *x,
		struct timeval *y)
{
	if (x->tv_usec < y->tv_usec) {
		int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;

		y->tv_usec -= 1000000 * nsec;
		y->tv_sec += nsec;
	}

	if (x->tv_usec - y->tv_usec > 1000000) {
		int nsec = (x->tv_usec - y->tv_usec) / 1000000;

		y->tv_usec += 1000000 * nsec;
		y->tv_sec -= nsec;
	}

	res->tv_sec  = x->tv_sec  - y->tv_sec;
	res->tv_usec = x->tv_usec - y->tv_usec;

	return x->tv_sec < y->tv_sec;
}

size_t strlcpy(char *dest, const char *src, size_t size)
{
	size_t ret = strlen(src);

	if (size) {
		size_t len = (ret >= size) ? size - 1 : ret;

		memcpy(dest, src, len);
		dest[len] = '\0';
	}

	return ret;
}

static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
{
	int ret;

	ret = vsnprintf(dst, size, fmt, ap);
	dst[size - 1] = '\0';

	return ret;
}

int slprintf(char *dst, size_t size, const char *fmt, ...)
{
	va_list ap;
	int ret;

	va_start(ap, fmt);
	ret = vslprintf(dst, size, fmt, ap);
	va_end(ap);

	return ret;
}

void die(void)
{
	exit(EXIT_FAILURE);
}

void panic(const char *format, ...)
{
	va_list vl;

	va_start(vl, format);
	vfprintf(stderr, format, vl);
	va_end(vl);

	die();
}

void warn(const char *format, ...)
{
	va_list vl;

	va_start(vl, format);
	vfprintf(stderr, format, vl);
	va_end(vl);
}

void verbose(const char *format, ...)
{
	va_list vl;

	if (verbose_enabled) {
		va_start(vl, format);
		vfprintf(stderr, format, vl);
		va_end(vl);
	}
}
