/*
 * System call table mapper
 *
 * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 */

#include "syscalltbl.h"
#include <stdlib.h>
#include <linux/compiler.h>

#ifdef HAVE_SYSCALL_TABLE
#include <string.h>
#include "string2.h"
#include "util.h"

#if defined(__x86_64__)
#include <asm/syscalls_64.c>
const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
static const char **syscalltbl_native = syscalltbl_x86_64;
#elif defined(__s390x__)
#include <asm/syscalls_64.c>
const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
static const char **syscalltbl_native = syscalltbl_s390_64;
#endif

struct syscall {
	int id;
	const char *name;
};

static int syscallcmpname(const void *vkey, const void *ventry)
{
	const char *key = vkey;
	const struct syscall *entry = ventry;

	return strcmp(key, entry->name);
}

static int syscallcmp(const void *va, const void *vb)
{
	const struct syscall *a = va, *b = vb;

	return strcmp(a->name, b->name);
}

static int syscalltbl__init_native(struct syscalltbl *tbl)
{
	int nr_entries = 0, i, j;
	struct syscall *entries;

	for (i = 0; i <= syscalltbl_native_max_id; ++i)
		if (syscalltbl_native[i])
			++nr_entries;

	entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
	if (tbl->syscalls.entries == NULL)
		return -1;

	for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
		if (syscalltbl_native[i]) {
			entries[j].name = syscalltbl_native[i];
			entries[j].id = i;
			++j;
		}
	}

	qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
	tbl->syscalls.nr_entries = nr_entries;
	return 0;
}

struct syscalltbl *syscalltbl__new(void)
{
	struct syscalltbl *tbl = malloc(sizeof(*tbl));
	if (tbl) {
		if (syscalltbl__init_native(tbl)) {
			free(tbl);
			return NULL;
		}
	}
	return tbl;
}

void syscalltbl__delete(struct syscalltbl *tbl)
{
	zfree(&tbl->syscalls.entries);
	free(tbl);
}

const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
{
	return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
}

int syscalltbl__id(struct syscalltbl *tbl, const char *name)
{
	struct syscall *sc = bsearch(name, tbl->syscalls.entries,
				     tbl->syscalls.nr_entries, sizeof(*sc),
				     syscallcmpname);

	return sc ? sc->id : -1;
}

int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
{
	int i;
	struct syscall *syscalls = tbl->syscalls.entries;

	for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
		if (strglobmatch(syscalls[i].name, syscall_glob)) {
			*idx = i;
			return syscalls[i].id;
		}
	}

	return -1;
}

int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
{
	*idx = -1;
	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
}

#else /* HAVE_SYSCALL_TABLE */

#include <libaudit.h>

struct syscalltbl *syscalltbl__new(void)
{
	struct syscalltbl *tbl = malloc(sizeof(*tbl));
	if (tbl)
		tbl->audit_machine = audit_detect_machine();
	return tbl;
}

void syscalltbl__delete(struct syscalltbl *tbl)
{
	free(tbl);
}

const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
{
	return audit_syscall_to_name(id, tbl->audit_machine);
}

int syscalltbl__id(struct syscalltbl *tbl, const char *name)
{
	return audit_name_to_syscall(name, tbl->audit_machine);
}

int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
				  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
{
	return -1;
}

int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
{
	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
}
#endif /* HAVE_SYSCALL_TABLE */
