/*
 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include <door.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <thread.h>
#include <unistd.h>
#include "jvm_dtrace.h"

// NOTE: These constants are used in JVM code as well.
// KEEP JVM CODE IN SYNC if you are going to change these...

#define DTRACE_ALLOC_PROBES   0x1
#define DTRACE_METHOD_PROBES  0x2
#define DTRACE_MONITOR_PROBES 0x4
#define DTRACE_ALL_PROBES     -1

// generic error messages
#define JVM_ERR_OUT_OF_MEMORY            "out of memory (native heap)"
#define JVM_ERR_INVALID_PARAM            "invalid input parameter(s)"
#define JVM_ERR_NULL_PARAM               "input paramater is NULL"

// error messages for attach
#define JVM_ERR_CANT_OPEN_DOOR           "cannot open door file"
#define JVM_ERR_CANT_CREATE_ATTACH_FILE  "cannot create attach file"
#define JVM_ERR_DOOR_FILE_PERMISSION     "door file is not secure"
#define JVM_ERR_CANT_SIGNAL              "cannot send SIGQUIT to target"

// error messages for enable probe
#define JVM_ERR_DOOR_CMD_SEND            "door command send failed"
#define JVM_ERR_DOOR_CANT_READ_STATUS    "cannot read door command status"
#define JVM_ERR_DOOR_CMD_STATUS          "door command error status"

// error message for detach
#define JVM_ERR_CANT_CLOSE_DOOR          "cannot close door file"

#define RESTARTABLE(_cmd, _result) do { \
    do { \
        _result = _cmd; \
    } while((_result == -1) && (errno == EINTR)); \
} while(0)

struct _jvm_t {
    pid_t pid;
    int door_fd;
};

static int libjvm_dtrace_debug;
static void print_debug(const char* fmt,...) {
    if (libjvm_dtrace_debug) {
        va_list alist;
        va_start(alist, fmt);
        fputs("libjvm_dtrace DEBUG: ", stderr);
        vfprintf(stderr, fmt, alist);
        va_end(alist);
    }
}

/* Key for thread local error message */
static thread_key_t jvm_error_key;

/* init function for this library */
static void init_jvm_dtrace() {
    /* check for env. var for debug mode */
    libjvm_dtrace_debug = getenv("LIBJVM_DTRACE_DEBUG") != NULL;
    /* create key for thread local error message */
    if (thr_keycreate(&jvm_error_key, NULL) != 0) {
        print_debug("can't create thread_key_t for jvm error key\n");
        // exit(1); ?
    }
}

#pragma init(init_jvm_dtrace)

/* set thread local error message */
static void set_jvm_error(const char* msg) {
    thr_setspecific(jvm_error_key, (void*)msg);
}

/* clear thread local error message */
static void clear_jvm_error() {
    thr_setspecific(jvm_error_key, NULL);
}

/* file handling functions that can handle interrupt */

static int file_open(const char* path, int flag) {
    int ret;
    RESTARTABLE(open(path, flag), ret);
    return ret;
}

static int file_close(int fd) {
    return close(fd);
}

static int file_read(int fd, char* buf, int len) {
    int ret;
    RESTARTABLE(read(fd, buf, len), ret);
    return ret;
}

/* send SIGQUIT signal to given process */
static int send_sigquit(pid_t pid) {
    int ret;
    RESTARTABLE(kill(pid, SIGQUIT), ret);
    return ret;
}

/* called to check permissions on attach file */
static int check_permission(const char* path) {
    struct stat64 sb;
    uid_t uid, gid;
    int res;

    /*
     * Check that the path is owned by the effective uid/gid of this
     * process. Also check that group/other access is not allowed.
     */
    uid = geteuid();
    gid = getegid();

    res = stat64(path, &sb);
    if (res != 0) {
        print_debug("stat failed for %s\n", path);
        return -1;
    }

    if ((sb.st_uid != uid) || (sb.st_gid != gid) ||
        ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0)) {
        print_debug("well-known file %s is not secure\n", path);
        return -1;
    }
    return 0;
}

#define ATTACH_FILE_PATTERN "/tmp/.attach_pid%d"

/* fill-in the name of attach file name in given buffer */
static void fill_attach_file_name(char* path, int len, pid_t pid) {
    memset(path, 0, len);
    sprintf(path, ATTACH_FILE_PATTERN, pid);
}

#define DOOR_FILE_PATTERN "/tmp/.java_pid%d"

/* open door file for the given JVM */
static int open_door(pid_t pid) {
    char path[PATH_MAX + 1];
    int fd;

    sprintf(path, DOOR_FILE_PATTERN, pid);
    fd = file_open(path, O_RDONLY);
    if (fd < 0) {
        set_jvm_error(JVM_ERR_CANT_OPEN_DOOR);
        print_debug("cannot open door file %s\n", path);
        return -1;
    }
    print_debug("opened door file %s\n", path);
    if (check_permission(path) != 0) {
        set_jvm_error(JVM_ERR_DOOR_FILE_PERMISSION);
        print_debug("check permission failed for %s\n", path);
        file_close(fd);
        fd = -1;
    }
    return fd;
}

/* create attach file for given process */
static int create_attach_file(pid_t pid) {
    char path[PATH_MAX + 1];
    int fd;
    fill_attach_file_name(path, sizeof(path), pid);
    fd = file_open(path, O_CREAT | O_RDWR);
    if (fd < 0) {
        set_jvm_error(JVM_ERR_CANT_CREATE_ATTACH_FILE);
        print_debug("cannot create file %s\n", path);
    } else {
        print_debug("created attach file %s\n", path);
    }
    return fd;
}

/* delete attach file for given process */
static void delete_attach_file(pid_t pid) {
    char path[PATH_MAX + 1];
    fill_attach_file_name(path, sizeof(path), pid);
    int res = unlink(path);
    if (res) {
        print_debug("cannot delete attach file %s\n", path);
    } else {
        print_debug("deleted attach file %s\n", path);
    }
}

/* attach to given JVM */
jvm_t* jvm_attach(pid_t pid) {
    jvm_t* jvm;
    int door_fd, attach_fd, i;

    jvm = (jvm_t*) calloc(1, sizeof(jvm_t));
    if (jvm == NULL) {
        set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
        print_debug("calloc failed in %s at %d\n", __FILE__, __LINE__);
        return NULL;
    }
    jvm->pid = pid;
    attach_fd = -1;

    door_fd = open_door(pid);
    if (door_fd < 0) {
        print_debug("trying to create attach file\n");
        if ((attach_fd = create_attach_file(pid)) < 0) {
            goto quit;
        }

        /* send QUIT signal to the target so that it will
         * check for the attach file.
         */
        if (send_sigquit(pid) != 0) {
            set_jvm_error(JVM_ERR_CANT_SIGNAL);
            print_debug("sending SIGQUIT failed\n");
            goto quit;
        }

        /* give the target VM time to start the attach mechanism */
        do {
            int res;
            RESTARTABLE(poll(0, 0, 200), res);
            door_fd = open_door(pid);
            i++;
        } while (i <= 50 && door_fd == -1);
        if (door_fd < 0) {
            print_debug("Unable to open door to process %d\n", pid);
            goto quit;
        }
    }

quit:
    if (attach_fd >= 0) {
        file_close(attach_fd);
        delete_attach_file(jvm->pid);
    }
    if (door_fd >= 0) {
        jvm->door_fd = door_fd;
        clear_jvm_error();
    } else {
        free(jvm);
        jvm = NULL;
    }
    return jvm;
}

/* return the last thread local error message */
const char* jvm_get_last_error() {
    const char* res = NULL;
    thr_getspecific(jvm_error_key, (void**)&res);
    return res;
}

/* detach the givenb JVM */
int jvm_detach(jvm_t* jvm) {
    if (jvm) {
        int res;
        if (jvm->door_fd != -1) {
            if (file_close(jvm->door_fd) != 0) {
                set_jvm_error(JVM_ERR_CANT_CLOSE_DOOR);
                res = -1;
            } else {
                clear_jvm_error();
                res = 0;
            }
        }
        free(jvm);
        return res;
    } else {
        set_jvm_error(JVM_ERR_NULL_PARAM);
        print_debug("jvm_t* is NULL\n");
        return -1;
    }
}

/*
 * A simple table to translate some known errors into reasonable
 * error messages
 */
static struct {
    int err;
    const char* msg;
} const error_messages[] = {
    { 100,      "Bad request" },
    { 101,      "Protocol mismatch" },
    { 102,      "Resource failure" },
    { 103,      "Internal error" },
    { 104,      "Permission denied" },
};

/*
 * Lookup the given error code and return the appropriate
 * message. If not found return NULL.
 */
static const char* translate_error(int err) {
    int table_size = sizeof(error_messages) / sizeof(error_messages[0]);
    int i;

    for (i=0; i<table_size; i++) {
        if (err == error_messages[i].err) {
            return error_messages[i].msg;
        }
    }
    return NULL;
}

/*
 * Current protocol version
 */
static const char* PROTOCOL_VERSION = "1";

#define RES_BUF_SIZE 128

/*
 * Enqueue attach-on-demand command to the given JVM
 */
static
int enqueue_command(jvm_t* jvm, const char* cstr, int arg_count, const char** args) {
    size_t size;
    door_arg_t door_args;
    char res_buffer[RES_BUF_SIZE];
    int rc, i;
    char* buf = NULL;
    int result = -1;

    /*
     * First we get the command string and create the start of the
     * argument string to send to the target VM:
     * <ver>\0<cmd>\0
     */
    if (cstr == NULL) {
        print_debug("command name is NULL\n");
        goto quit;
    }
    size = strlen(PROTOCOL_VERSION) + strlen(cstr) + 2;
    buf = (char*)malloc(size);
    if (buf != NULL) {
        char* pos = buf;
        strcpy(buf, PROTOCOL_VERSION);
        pos += strlen(PROTOCOL_VERSION)+1;
        strcpy(pos, cstr);
    } else {
        set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
        print_debug("malloc failed at %d in %s\n", __LINE__, __FILE__);
        goto quit;
    }

    /*
     * Next we iterate over the arguments and extend the buffer
     * to include them.
     */
    for (i=0; i<arg_count; i++) {
        cstr = args[i];
        if (cstr != NULL) {
            size_t len = strlen(cstr);
            char* newbuf = (char*)realloc(buf, size+len+1);
            if (newbuf == NULL) {
                set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
                print_debug("realloc failed in %s at %d\n", __FILE__, __LINE__);
                goto quit;
            }
            buf = newbuf;
            strcpy(buf+size, cstr);
            size += len+1;
        }
    }

    /*
     * The arguments to the door function are in 'buf' so we now
     * do the door call
     */
    door_args.data_ptr = buf;
    door_args.data_size = size;
    door_args.desc_ptr = NULL;
    door_args.desc_num = 0;
    door_args.rbuf = (char*)&res_buffer;
    door_args.rsize = sizeof(res_buffer);

    RESTARTABLE(door_call(jvm->door_fd, &door_args), rc);

    /*
     * door_call failed
     */
    if (rc == -1) {
        print_debug("door_call failed\n");
    } else {
        /*
         * door_call succeeded but the call didn't return the the expected jint.
         */
        if (door_args.data_size < sizeof(int)) {
            print_debug("Enqueue error - reason unknown as result is truncated!");
        } else {
            int* res = (int*)(door_args.data_ptr);
            if (*res != 0) {
                const char* msg = translate_error(*res);
                if (msg == NULL) {
                    print_debug("Unable to enqueue command to target VM: %d\n", *res);
                } else {
                    print_debug("Unable to enqueue command to target VM: %s\n", msg);
                }
            } else {
                /*
                 * The door call should return a file descriptor to one end of
                 * a socket pair
                 */
                if ((door_args.desc_ptr != NULL) &&
                    (door_args.desc_num == 1) &&
                    (door_args.desc_ptr->d_attributes & DOOR_DESCRIPTOR)) {
                    result = door_args.desc_ptr->d_data.d_desc.d_descriptor;
                } else {
                    print_debug("Reply from enqueue missing descriptor!\n");
                }
            }
        }
    }

quit:
    if (buf) free(buf);
    return result;
}

/* read status code for a door command */
static int read_status(int fd) {
    char ch, buf[16];
    int index = 0;

    while (1) {
        if (file_read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
            set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS);
            print_debug("door cmd status: read status failed\n");
            return -1;
        }
        buf[index++] = ch;
        if (ch == '\n') {
            buf[index - 1] = '\0';
            return atoi(buf);
        }
        if (index == sizeof(buf)) {
            set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS);
            print_debug("door cmd status: read status overflow\n");
            return -1;
        }
    }
}

static const char* ENABLE_DPROBES_CMD = "enabledprobes";

/* enable one or more DTrace probes for a given JVM */
int jvm_enable_dtprobes(jvm_t* jvm, int num_probe_types, const char** probe_types) {
    int fd, status = 0;
    char ch;
    const char* args[1];
    char buf[16];
    int probe_type = 0, index;
    int count = 0;

    if (jvm == NULL) {
        set_jvm_error(JVM_ERR_NULL_PARAM);
        print_debug("jvm_t* is NULL\n");
        return -1;
    }

    if (num_probe_types == 0 || probe_types == NULL ||
        probe_types[0] == NULL) {
        set_jvm_error(JVM_ERR_INVALID_PARAM);
        print_debug("invalid probe type argument(s)\n");
        return -1;
    }

    for (index = 0; index < num_probe_types; index++) {
        const char* p = probe_types[index];
        if (strcmp(p, JVM_DTPROBE_OBJECT_ALLOC) == 0) {
            probe_type |= DTRACE_ALLOC_PROBES;
            count++;
        } else if (strcmp(p, JVM_DTPROBE_METHOD_ENTRY) == 0 ||
                   strcmp(p, JVM_DTPROBE_METHOD_RETURN) == 0) {
            probe_type |= DTRACE_METHOD_PROBES;
            count++;
        } else if (strcmp(p, JVM_DTPROBE_MONITOR_ENTER) == 0   ||
                   strcmp(p, JVM_DTPROBE_MONITOR_ENTERED) == 0 ||
                   strcmp(p, JVM_DTPROBE_MONITOR_EXIT) == 0    ||
                   strcmp(p, JVM_DTPROBE_MONITOR_WAIT) == 0    ||
                   strcmp(p, JVM_DTPROBE_MONITOR_WAITED) == 0  ||
                   strcmp(p, JVM_DTPROBE_MONITOR_NOTIFY) == 0  ||
                   strcmp(p, JVM_DTPROBE_MONITOR_NOTIFYALL) == 0) {
            probe_type |= DTRACE_MONITOR_PROBES;
            count++;
        } else if (strcmp(p, JVM_DTPROBE_ALL) == 0) {
            probe_type |= DTRACE_ALL_PROBES;
            count++;
        }
    }

    if (count == 0) {
        return count;
    }
    sprintf(buf, "%d", probe_type);
    args[0] = buf;

    fd = enqueue_command(jvm, ENABLE_DPROBES_CMD, 1, args);
    if (fd < 0) {
        set_jvm_error(JVM_ERR_DOOR_CMD_SEND);
        return -1;
    }

    status = read_status(fd);
    // non-zero status is error
    if (status) {
        set_jvm_error(JVM_ERR_DOOR_CMD_STATUS);
        print_debug("%s command failed (status: %d) in target JVM\n",
                    ENABLE_DPROBES_CMD, status);
        file_close(fd);
        return -1;
    }
    // read from stream until EOF
    while (file_read(fd, &ch, sizeof(ch)) == sizeof(ch)) {
        if (libjvm_dtrace_debug) {
            printf("%c", ch);
        }
    }

    file_close(fd);
    clear_jvm_error();
    return count;
}
