/*
 * Copyright (c) 2008, 2022, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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 "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"

#include <sys/param.h>
#include <sys/mount.h>
#ifdef ST_RDONLY
#define statfs statvfs
#define getfsstat getvfsstat
#define f_flags f_flag
#define ISREADONLY ST_RDONLY
#else
#define ISREADONLY MNT_RDONLY
#endif
#include <sys/attr.h>
#include <unistd.h>

#include <stdlib.h>
#include <string.h>
#include <sys/attr.h>
#include <sys/clonefile.h>

static jfieldID entry_name;
static jfieldID entry_dir;
static jfieldID entry_fstype;
static jfieldID entry_options;

struct fsstat_iter {
    struct statfs *buf;
    int pos;
    int nentries;
};

#include "sun_nio_fs_BsdNativeDispatcher.h"

static void throwUnixException(JNIEnv* env, int errnum) {
    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
        "(I)V", errnum);
    if (x != NULL) {
        (*env)->Throw(env, x);
    }
}

/**
 * Initialize jfieldIDs
 */
JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_initIDs(JNIEnv* env, jclass this)
{
    jclass clazz;

    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
    CHECK_NULL(clazz);
    entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
    CHECK_NULL(entry_name);
    entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
    CHECK_NULL(entry_dir);
    entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
    CHECK_NULL(entry_fstype);
    entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
    CHECK_NULL(entry_options);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_getfsstat(JNIEnv* env, jclass this)
{
    int nentries;
    size_t bufsize;
    struct fsstat_iter *iter = malloc(sizeof(*iter));

    if (iter == NULL) {
        JNU_ThrowOutOfMemoryError(env, "native heap");
        return 0;
    }

    iter->pos = 0;
    iter->nentries = 0;
    iter->buf = NULL;

    nentries = getfsstat(NULL, 0, MNT_NOWAIT);

    if (nentries <= 0) {
        free(iter);
        throwUnixException(env, errno);
        return 0;
    }

    // It's possible that a new filesystem gets mounted between
    // the first getfsstat and the second so loop until consistent

    while (nentries != iter->nentries) {
        if (iter->buf != NULL)
            free(iter->buf);

        bufsize = nentries * sizeof(struct statfs);
        iter->nentries = nentries;

        iter->buf = malloc(bufsize);
        if (iter->buf == NULL) {
            free(iter);
            JNU_ThrowOutOfMemoryError(env, "native heap");
            return 0;
        }

        nentries = getfsstat(iter->buf, bufsize, MNT_WAIT);
        if (nentries <= 0) {
            free(iter->buf);
            free(iter);
            throwUnixException(env, errno);
            return 0;
        }
    }

    return (jlong)iter;
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry(JNIEnv* env, jclass this,
    jlong value, jobject entry)
{
    struct fsstat_iter *iter = jlong_to_ptr(value);
    jsize len;
    jbyteArray bytes;
    char* name;
    char* dir;
    char* fstype;
    char* options;

    if (iter == NULL || iter->pos >= iter->nentries)
       return -1;

    name = iter->buf[iter->pos].f_mntfromname;
    dir = iter->buf[iter->pos].f_mntonname;
    fstype = iter->buf[iter->pos].f_fstypename;
    if (iter->buf[iter->pos].f_flags & ISREADONLY)
        options="ro";
    else
        options="";

    iter->pos++;

    len = strlen(name);
    bytes = (*env)->NewByteArray(env, len);
    if (bytes == NULL)
        return -1;
    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
    (*env)->SetObjectField(env, entry, entry_name, bytes);

    len = strlen(dir);
    bytes = (*env)->NewByteArray(env, len);
    if (bytes == NULL)
        return -1;
    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
    (*env)->SetObjectField(env, entry, entry_dir, bytes);

    len = strlen(fstype);
    bytes = (*env)->NewByteArray(env, len);
    if (bytes == NULL)
        return -1;
    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
    (*env)->SetObjectField(env, entry, entry_fstype, bytes);

    len = strlen(options);
    bytes = (*env)->NewByteArray(env, len);
    if (bytes == NULL)
        return -1;
    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
    (*env)->SetObjectField(env, entry, entry_options, bytes);

    return 0;
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_endfsstat(JNIEnv* env, jclass this, jlong value)
{
    struct fsstat_iter *iter = jlong_to_ptr(value);

    if (iter != NULL) {
        free(iter->buf);
        free(iter);
    }
}

JNIEXPORT jbyteArray JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_getmntonname0(JNIEnv *env, jclass this,
    jlong pathAddress)
{
    struct statfs buf;
    const char* path = (const char*)jlong_to_ptr(pathAddress);

    if (statfs(path, &buf) != 0) {
        throwUnixException(env, errno);
    }

    jsize len = strlen(buf.f_mntonname);
    jbyteArray mntonname = (*env)->NewByteArray(env, len);
    if (mntonname != NULL) {
        (*env)->SetByteArrayRegion(env, mntonname, 0, len,
            (jbyte*)buf.f_mntonname);
    }

    return mntonname;
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_clonefile0(JNIEnv* env, jclass this,
    jlong srcAddress, jlong dstAddress, jint flags)
{
    const char* src = (const char*)jlong_to_ptr(srcAddress);
    const char* dst = (const char*)jlong_to_ptr(dstAddress);

    int ret = clonefile(src, dst, flags);
    if (ret != 0) {
        throwUnixException(env, errno);
        return ret;
    }

    return 0;
}

size_t initattrlist(jint commonattr, jlong modTime, jlong accTime,
    jlong createTime, const int attrsize, char* buf, struct attrlist *attrList)
{
    int count = 0;

    // attributes are ordered per the getattrlist(2) spec
    if ((commonattr & ATTR_CMN_CRTIME) != 0) {
        struct timespec* t = (struct timespec*)buf;
        t->tv_sec   = createTime / 1000000000;
        t->tv_nsec  = createTime % 1000000000;
        count++;
    }
    if ((commonattr & ATTR_CMN_MODTIME) != 0) {
        struct timespec* t = (struct timespec*)(buf + count*attrsize);
        t->tv_sec   = modTime / 1000000000;
        t->tv_nsec  = modTime % 1000000000;
        count++;
    }
    if ((commonattr & ATTR_CMN_ACCTIME) != 0) {
        struct timespec* t = (struct timespec*)(buf + count*attrsize);
        t->tv_sec   = accTime / 1000000000;
        t->tv_nsec  = accTime % 1000000000;
        count++;
    }

    memset(attrList, 0, sizeof(struct attrlist));
    attrList->bitmapcount = ATTR_BIT_MAP_COUNT;
    attrList->commonattr = commonattr;

    return count*attrsize;
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_setattrlist0(JNIEnv* env, jclass this,
    jlong pathAddress, int commonattr, jlong modTime, jlong accTime,
    jlong createTime, jlong options)
{
    const char* path = (const char*)jlong_to_ptr(pathAddress);
    // attributes must align on 4-byte boundaries per the getattrlist(2) spec
    const int attrsize = ((sizeof(struct timespec) + 3)/4)*4;
    char buf[3*attrsize];

    struct attrlist attrList;
    size_t attrBufSize = initattrlist(commonattr, modTime, accTime, createTime,
                                      attrsize, buf, &attrList);

    if (setattrlist(path, &attrList, (void*)buf, attrBufSize, options) != 0) {
        throwUnixException(env, errno);
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_fsetattrlist0(JNIEnv* env, jclass this,
    jint fd, int commonattr, jlong modTime, jlong accTime,
    jlong createTime, jlong options)
{
    // attributes must align on 4-byte boundaries per the getattrlist(2) spec
    const int attrsize = ((sizeof(struct timespec) + 3)/4)*4;
    char buf[3*attrsize];

    struct attrlist attrList;
    size_t attrBufSize = initattrlist(commonattr, modTime, accTime, createTime,
                                      attrsize, buf, &attrList);

    if (fsetattrlist(fd, &attrList, (void*)buf, attrBufSize, options) != 0) {
        throwUnixException(env, errno);
    }
}
