// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (c) 2015-2017 Daniel Borkmann */
/* Copyright (c) 2018 Netronome Systems, Inc. */

#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/magic.h>
#include <fcntl.h>
#include <sys/vfs.h>

#include "main.h"

#ifndef TRACEFS_MAGIC
# define TRACEFS_MAGIC	0x74726163
#endif

#define _textify(x)	#x
#define textify(x)	_textify(x)

FILE *trace_pipe_fd;
char *buff;

static int validate_tracefs_mnt(const char *mnt, unsigned long magic)
{
	struct statfs st_fs;

	if (statfs(mnt, &st_fs) < 0)
		return -ENOENT;
	if ((unsigned long)st_fs.f_type != magic)
		return -ENOENT;

	return 0;
}

static bool
find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt)
{
	size_t src_len;

	if (validate_tracefs_mnt(mntpt, magic))
		return false;

	src_len = strlen(mntpt);
	if (src_len + 1 >= PATH_MAX) {
		p_err("tracefs mount point name too long");
		return false;
	}

	strcpy(mnt, mntpt);
	return true;
}

static bool get_tracefs_pipe(char *mnt)
{
	static const char * const known_mnts[] = {
		"/sys/kernel/tracing",
		"/sys/kernel/debug/tracing",
	};
	const char *pipe_name = "/trace_pipe";
	const char *fstype = "tracefs";
	char type[100], format[32];
	const char * const *ptr;
	bool found = false;
	FILE *fp;

	for (ptr = known_mnts; ptr < known_mnts + ARRAY_SIZE(known_mnts); ptr++)
		if (find_tracefs_mnt_single(TRACEFS_MAGIC, mnt, *ptr))
			goto exit_found;

	fp = fopen("/proc/mounts", "r");
	if (!fp)
		return false;

	/* Allow room for NULL terminating byte and pipe file name */
	snprintf(format, sizeof(format), "%%*s %%%zus %%99s %%*s %%*d %%*d\\n",
		 PATH_MAX - strlen(pipe_name) - 1);
	while (fscanf(fp, format, mnt, type) == 2)
		if (strcmp(type, fstype) == 0) {
			found = true;
			break;
		}
	fclose(fp);

	/* The string from fscanf() might be truncated, check mnt is valid */
	if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
		goto exit_found;

	if (block_mount)
		return false;

	p_info("could not find tracefs, attempting to mount it now");
	strcpy(mnt, known_mnts[0]);
	if (mount_tracefs(mnt))
		return false;

exit_found:
	strcat(mnt, pipe_name);
	return true;
}

static void exit_tracelog(int signum)
{
	fclose(trace_pipe_fd);
	free(buff);

	if (json_output) {
		jsonw_end_array(json_wtr);
		jsonw_destroy(&json_wtr);
	}

	exit(0);
}

int do_tracelog(int argc, char **argv)
{
	const struct sigaction act = {
		.sa_handler = exit_tracelog
	};
	char trace_pipe[PATH_MAX];
	size_t buff_len = 0;

	if (json_output)
		jsonw_start_array(json_wtr);

	if (!get_tracefs_pipe(trace_pipe))
		return -1;

	trace_pipe_fd = fopen(trace_pipe, "r");
	if (!trace_pipe_fd) {
		p_err("could not open trace pipe: %s", strerror(errno));
		return -1;
	}

	sigaction(SIGHUP, &act, NULL);
	sigaction(SIGINT, &act, NULL);
	sigaction(SIGTERM, &act, NULL);
	while (1) {
		ssize_t ret;

		ret = getline(&buff, &buff_len, trace_pipe_fd);
		if (ret <= 0) {
			p_err("failed to read content from trace pipe: %s",
			      strerror(errno));
			break;
		}
		if (json_output)
			jsonw_string(json_wtr, buff);
		else
			printf("%s", buff);
	}

	fclose(trace_pipe_fd);
	free(buff);
	return -1;
}
