/*

   nsjail - useful procedures
   -----------------------------------------

   Copyright 2016 Google Inc. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

#include "util.h"

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <sstream>
#include <string>
#include <vector>

#include "logs.h"
#include "macros.h"

namespace util {

ssize_t readFromFd(int fd, void* buf, size_t len) {
	uint8_t* charbuf = (uint8_t*)buf;

	size_t readSz = 0;
	while (readSz < len) {
		ssize_t sz = TEMP_FAILURE_RETRY(read(fd, &charbuf[readSz], len - readSz));
		if (sz <= 0) {
			break;
		}
		readSz += sz;
	}
	return readSz;
}

ssize_t readFromFile(const char* fname, void* buf, size_t len) {
	int fd;
	TEMP_FAILURE_RETRY(fd = open(fname, O_RDONLY | O_CLOEXEC));
	if (fd == -1) {
		LOG_E("open('%s', O_RDONLY|O_CLOEXEC)", fname);
		return -1;
	}
	ssize_t ret = readFromFd(fd, buf, len);
	close(fd);
	return ret;
}

ssize_t writeToFd(int fd, const void* buf, size_t len) {
	const uint8_t* charbuf = (const uint8_t*)buf;

	size_t writtenSz = 0;
	while (writtenSz < len) {
		ssize_t sz = TEMP_FAILURE_RETRY(write(fd, &charbuf[writtenSz], len - writtenSz));
		if (sz < 0) {
			return false;
		}
		writtenSz += sz;
	}
	return true;
}

bool writeBufToFile(const char* filename, const void* buf, size_t len, int open_flags) {
	int fd;
	TEMP_FAILURE_RETRY(fd = open(filename, open_flags, 0644));
	if (fd == -1) {
		PLOG_E("Couldn't open '%s' for writing", filename);
		return false;
	}

	if (!writeToFd(fd, buf, len)) {
		PLOG_E("Couldn't write '%zu' bytes to file '%s' (fd='%d')", len, filename, fd);
		close(fd);
		if (open_flags & O_CREAT) {
			unlink(filename);
		}
		return false;
	}

	LOG_D("Written '%zu' bytes to '%s'", len, filename);

	close(fd);
	return true;
}

bool createDirRecursively(const char* dir) {
	if (dir[0] != '/') {
		LOG_W("The directory path must start with '/': '%s' provided", dir);
		return false;
	}

	int prev_dir_fd = open("/", O_RDONLY | O_CLOEXEC);
	if (prev_dir_fd == -1) {
		PLOG_W("open('/', O_RDONLY | O_CLOEXEC)");
		return false;
	}

	char path[PATH_MAX];
	snprintf(path, sizeof(path), "%s", dir);
	char* curr = path;
	for (;;) {
		while (*curr == '/') {
			curr++;
		}

		char* next = strchr(curr, '/');
		if (next == NULL) {
			close(prev_dir_fd);
			return true;
		}
		*next = '\0';

		if (mkdirat(prev_dir_fd, curr, 0755) == -1 && errno != EEXIST) {
			PLOG_W("mkdir('%s', 0755)", curr);
			close(prev_dir_fd);
			return false;
		}

		int dir_fd = TEMP_FAILURE_RETRY(openat(prev_dir_fd, curr, O_DIRECTORY | O_CLOEXEC));
		if (dir_fd == -1) {
			PLOG_W("openat('%d', '%s', O_DIRECTORY | O_CLOEXEC)", prev_dir_fd, curr);
			close(prev_dir_fd);
			return false;
		}
		close(prev_dir_fd);
		prev_dir_fd = dir_fd;
		curr = next + 1;
	}
}

std::string* StrAppend(std::string* str, const char* format, ...) {
	char* strp;

	va_list args;
	va_start(args, format);
	int ret = vasprintf(&strp, format, args);
	va_end(args);

	if (ret == -1) {
		PLOG_E("Memory allocation failed during asprintf()");
		str->append(" [ERROR: mem_allocation_failed] ");
		return str;
	}

	str->append(strp, ret);
	free(strp);
	return str;
}

bool isANumber(const char* s) {
	for (size_t i = 0; s[i]; s++) {
		if (!isdigit(s[i]) && s[i] != 'x') {
			return false;
		}
	}
	return true;
}

static __thread pthread_once_t rndThreadOnce = PTHREAD_ONCE_INIT;
static __thread uint64_t rndX;

/* MMIX LCG PRNG */
static const uint64_t a = 6364136223846793005ULL;
static const uint64_t c = 1442695040888963407ULL;

static void rndInitThread(void) {
#if defined(__NR_getrandom)
	if (syscall(__NR_getrandom, &rndX, sizeof(rndX), 0) == sizeof(rndX)) {
		return;
	}
#endif /* defined(__NR_getrandom) */
	int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
	if (fd == -1) {
		PLOG_D(
		    "Couldn't open /dev/urandom for reading. Using gettimeofday "
		    "fall-back");
		struct timeval tv;
		gettimeofday(&tv, NULL);
		rndX = tv.tv_usec + ((uint64_t)tv.tv_sec << 32);
		return;
	}
	if (readFromFd(fd, (uint8_t*)&rndX, sizeof(rndX)) != sizeof(rndX)) {
		PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
		close(fd);
	}
	close(fd);
}

uint64_t rnd64(void) {
	pthread_once(&rndThreadOnce, rndInitThread);
	rndX = a * rndX + c;
	return rndX;
}

const std::string sigName(int signo) {
	std::string res;

	struct {
		const int signo;
		const char* const name;
	} static const sigNames[] = {
	    NS_VALSTR_STRUCT(SIGINT),
	    NS_VALSTR_STRUCT(SIGILL),
	    NS_VALSTR_STRUCT(SIGABRT),
	    NS_VALSTR_STRUCT(SIGFPE),
	    NS_VALSTR_STRUCT(SIGSEGV),
	    NS_VALSTR_STRUCT(SIGTERM),
	    NS_VALSTR_STRUCT(SIGHUP),
	    NS_VALSTR_STRUCT(SIGQUIT),
	    NS_VALSTR_STRUCT(SIGTRAP),
	    NS_VALSTR_STRUCT(SIGKILL),
	    NS_VALSTR_STRUCT(SIGBUS),
	    NS_VALSTR_STRUCT(SIGSYS),
	    NS_VALSTR_STRUCT(SIGPIPE),
	    NS_VALSTR_STRUCT(SIGALRM),
	    NS_VALSTR_STRUCT(SIGURG),
	    NS_VALSTR_STRUCT(SIGSTOP),
	    NS_VALSTR_STRUCT(SIGTSTP),
	    NS_VALSTR_STRUCT(SIGCONT),
	    NS_VALSTR_STRUCT(SIGCHLD),
	    NS_VALSTR_STRUCT(SIGTTIN),
	    NS_VALSTR_STRUCT(SIGTTOU),
	    NS_VALSTR_STRUCT(SIGPOLL),
	    NS_VALSTR_STRUCT(SIGXCPU),
	    NS_VALSTR_STRUCT(SIGXFSZ),
	    NS_VALSTR_STRUCT(SIGVTALRM),
	    NS_VALSTR_STRUCT(SIGPROF),
	    NS_VALSTR_STRUCT(SIGUSR1),
	    NS_VALSTR_STRUCT(SIGUSR2),
	    NS_VALSTR_STRUCT(SIGWINCH),
	};

	for (const auto& i : sigNames) {
		if (signo == i.signo) {
			res.append(i.name);
			return res;
		}
	}

	if (signo > SIGRTMIN) {
		res.append("SIG");
		res.append(std::to_string(signo));
		res.append("-RTMIN+");
		res.append(std::to_string(signo - SIGRTMIN));
		return res;
	}

	res.append("SIGUNKNOWN(");
	res.append(std::to_string(signo));
	res.append(")");
	return res;
}

const std::string timeToStr(time_t t) {
	char timestr[128];
	struct tm utctime;
	localtime_r(&t, &utctime);
	if (strftime(timestr, sizeof(timestr) - 1, "%FT%T%z", &utctime) == 0) {
		return "[Time conv error]";
	}
	return timestr;
}

std::vector<std::string> strSplit(const std::string str, char delim) {
	std::vector<std::string> vec;
	std::istringstream stream(str);
	for (std::string word; std::getline(stream, word, delim);) {
		vec.push_back(word);
	}
	return vec;
}

}  // namespace util
