/*
	Copyright 2003 by Marc J. Rochkind. All rights reserved.
	May be copied only for purposes and under conditions described
	on the Web page www.basepath.com/aup/copyright.htm.

	The Example Files are provided "as is," without any warranty;
	without even the implied warranty of merchantability or fitness
	for a particular purpose. The author and his publisher are not
	responsible for any damages, direct or incidental, resulting
	from the use or non-use of these Example Files.

	The Example Files may contain defects, and some contain deliberate
	coding mistakes that were included for educational reasons.
	You are responsible for determining if and how the Example Files
	are to be used.

*/

#include "defs.h"
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "JtuxSysVIPC.h" // generated by javah
#include "jtux_util.h"
#include "JNI_macros.h"

static bool field_jtoc_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
  struct ipc_perm *perm)
{
	jfieldID fid;
	jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
	jobject objperm;
	int mode;

	if (cls == NULL || clsperm == NULL)
		return false;
	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
		return false;
	if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
		JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
		return false;
	}
	if (!field_jtoc_long(env, clsperm, "uid", objperm, &perm->uid))
		return false;
	if (!field_jtoc_long(env, clsperm, "gid", objperm, &perm->gid))
		return false;
	if (!field_jtoc_long(env, clsperm, "cuid", objperm, &perm->cuid))
		return false;
	if (!field_jtoc_long(env, clsperm, "cgid", objperm, &perm->cgid))
		return false;
	if (!field_jtoc_int(env, clsperm, "mode", objperm, &mode))
		return false;
	perm->mode = mode;
	return true;
}

static bool field_ctoj_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
  struct ipc_perm *perm)
{
	jfieldID fid;
	jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
	jobject objperm;

	if (cls == NULL || clsperm == NULL)
		return false;
	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
		return false;
	if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
		JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
		return false;
	}
	if (!field_ctoj_long(env, clsperm, "uid", objperm, perm->uid))
		return false;
	if (!field_ctoj_long(env, clsperm, "gid", objperm, perm->gid))
		return false;
	if (!field_ctoj_long(env, clsperm, "cuid", objperm, perm->cuid))
		return false;
	if (!field_ctoj_long(env, clsperm, "cgid", objperm, perm->cgid))
		return false;
	if (!field_ctoj_int(env, clsperm, "mode", objperm, perm->mode))
		return false;
	return true;
}

JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_ftok(JNIEnv *env, jclass obj,
  jstring path, jint id)
{
	JSTR_GET_DECL(path_c, path)
	key_t k;

	JSTR_NULLTEST_V(path_c, -1)
	JTHROW_neg1(k = ftok(path_c, id))
	JSTR_REL(path_c, path)
	return k;
}

JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msg_1set_1type(JNIEnv *env, jclass obj,
  jlong msgtype, jbyteArray msgp)
{
	void *msgp_c;

	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
		return 0;
	*(long *)msgp_c = (long)msgtype;
	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
	return sizeof(long);
}

JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgctl(JNIEnv *env, jclass obj,
  jint msqid, jint cmd, jobject data)
{
	struct msqid_ds data_c;
	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_msqid_ds");
	int n, r;

	memset(&data_c, 0, sizeof(data_c));
	if (cmd == IPC_SET) {
		if (!field_jtoc_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
			return;
		if (!field_jtoc_int(env, cls, "msg_qbytes", data, &n))
			return;
		data_c.msg_qbytes = n;
	}
	JTHROW_neg1(r = msgctl(msqid, cmd, &data_c))
	if (r == -1)
		return;
	if (cmd == IPC_STAT) {
		if (!field_ctoj_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
			return;
		if (!field_ctoj_int(env, cls, "msg_qnum", data, data_c.msg_qnum))
			return;
		if (!field_ctoj_int(env, cls, "msg_qbytes", data, data_c.msg_qbytes))
			return;
		if (!field_ctoj_long(env, cls, "msg_lspid", data, data_c.msg_lspid))
			return;
		if (!field_ctoj_long(env, cls, "msg_lrpid", data, data_c.msg_lrpid))
			return;
		if (!field_ctoj_long(env, cls, "msg_stime", data, data_c.msg_stime))
			return;
		if (!field_ctoj_long(env, cls, "msg_rtime", data, data_c.msg_rtime))
			return;
		if (!field_ctoj_long(env, cls, "msg_ctime", data, data_c.msg_ctime))
			return;
	}
}

JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgget(JNIEnv *env, jclass obj,
  jlong key, jint flags)
{
	int msqid;

	JTHROW_neg1(msqid = msgget(key, flags))
	return msqid;
}

JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgrcv(JNIEnv *env, jclass obj,
  jint msqid, jbyteArray msgp, jint mtextsize, jlong msgtype, jint flags)
{
	void *msgp_c;
	ssize_t nrcv;

	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
		return -1;
	JTHROW_neg1(nrcv = msgrcv(msqid, msgp_c, mtextsize, msgtype, flags))
	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
	return nrcv;
}

JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgsnd(JNIEnv *env, jclass obj,
  jint msqid, jbyteArray msgp, jint msgsize, jint flags)
{
	void *msgp_c;

	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
		return;
	JTHROW_neg1(msgsnd(msqid, msgp_c, msgsize, flags))
	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
}

JNIEXPORT int JNICALL Java_jtux_USysVIPC_semctl(JNIEnv *env, jclass obj,
  jint semid, jint semnum, jint cmd, jobject arg)
{
	struct semid_ds data_c;
	jclass cls_s_semid_ds = (*env)->FindClass(env, "jtux/USysVIPC$s_semid_ds");
	jclass cls_u_semun_int = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_int");
	jclass cls_u_semun_struct = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_struct");
	jclass cls_u_semun_array = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_array");
	jfieldID fid;
	jobject objds;
	jshortArray array;
	int r;
	union semun {
		int val;
		struct semid_ds *buf;
		unsigned short *array;
	} arg_c;

	memset(&data_c, 0, sizeof(data_c));
	switch (cmd) {
	case IPC_SET:
		if (cls_u_semun_struct == NULL)
			return -1;
		if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
			return -1;
		if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
			JNU_ThrowByName(env, "NullPointerException", "buf field not initialized");
			return -1;
		}
		if (!field_jtoc_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
			return -1;
		/* fall through */
	case IPC_STAT:
		arg_c.buf = &data_c;
		break;
	case SETVAL:
		if (!field_jtoc_int(env, cls_u_semun_int, "val", arg, &arg_c.val))
			return -1;
		break;
	case SETALL:
	case GETALL:
		arg_c.buf = &data_c;
		JTHROW_neg1(r = semctl(semid, 0, IPC_STAT, arg_c))
		if (r == -1)
			return -1;
		if (cls_u_semun_array == NULL)
			return -1;
		if ((fid = (*env)->GetFieldID(env, cls_u_semun_array, "array", "[S")) == NULL)
			return -1;
		if ((array = (*env)->GetObjectField(env, arg, fid)) == NULL) {
			JNU_ThrowByName(env, "NullPointerException", "array field not initialized");
			return -1;
		}
		if ((arg_c.array = (*env)->GetShortArrayElements(env, array, NULL)) == NULL)
			return -1;
	}
	JTHROW_neg1(r = semctl(semid, semnum, cmd, arg_c))
	if (r == -1)
		return r;
	switch (cmd) {
	case IPC_STAT:
		if (cls_u_semun_struct == NULL)
			return -1;
		if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
			return -1;
		if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
			JNU_ThrowByName(env, "NullPointerException", "s_semid_ds field not initialized");
			return -1;
		}
		if (!field_ctoj_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
			return -1;
		if (!field_ctoj_short(env, cls_s_semid_ds, "sem_nsems", objds, data_c.sem_nsems))
			return -1;
		if (!field_ctoj_long(env, cls_s_semid_ds, "sem_otime", objds, data_c.sem_otime))
			return -1;
		if (!field_ctoj_long(env, cls_s_semid_ds, "sem_ctime", objds, data_c.sem_ctime))
			return -1;
		break;
	case SETALL:
		(*env)->ReleaseShortArrayElements(env, array, arg_c.array, JNI_ABORT);
		break;
	case GETALL:
		(*env)->ReleaseShortArrayElements(env, array, arg_c.array, 0);
	}
	return r;
}

JNIEXPORT jint JNICALL Java_jtux_USysVIPC_semget(JNIEnv *env, jclass obj,
  jlong key, jint msems, jint flags)
{
	int semid;

	JTHROW_neg1(semid = semget(key, msems, flags))
	return semid;
}

JNIEXPORT void JNICALL Java_jtux_USysVIPC_semop(JNIEnv *env, jclass obj,
  jint semid, jobjectArray sops, jint nsops)
{
	struct sembuf *sops_c;
	int i;
	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_sembuf");

	JTHROW_null(sops_c = malloc(nsops * sizeof(struct sembuf)))
	if (sops_c == NULL)
		return;
	for (i = 0; i < nsops; i++) {
		jobject sb_obj = (*env)->GetObjectArrayElement(env, sops, i);

		if (sb_obj == NULL) {
			free(sops_c);
			return;
		}
		if (!field_jtoc_short(env, cls, "sem_num", sb_obj, &sops_c[i].sem_num))
			return;
		if (!field_jtoc_short(env, cls, "sem_op", sb_obj, &sops_c[i].sem_op))
			return;
		if (!field_jtoc_short(env, cls, "sem_flg", sb_obj, &sops_c[i].sem_flg))
			return;
	}
	JTHROW_neg1(semop(semid, sops_c, nsops))
	free(sops_c);
}

JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_shmat(JNIEnv *env, jclass obj,
  jint shmid, jlong shmaddr, jint flags)
{
	intptr_t p;

	JTHROW_neg1(p = (intptr_t)shmat(shmid, (const void *)(intptr_t)shmaddr, flags))
	return p;
}

JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmctl(JNIEnv *env, jclass obj,
  jint shmid, jint cmd, jobject data)
{
	struct shmid_ds data_c;
	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_shmid_ds");
	int r;

	memset(&data_c, 0, sizeof(data_c));
	if (cmd == IPC_SET) {
		if (!field_jtoc_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
			return;
	}
	JTHROW_neg1(r = shmctl(shmid, cmd, &data_c))
	if (r == -1)
		return;
	if (cmd == IPC_STAT) {
		if (!field_ctoj_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
			return;
		if (!field_ctoj_int(env, cls, "shm_segsz", data, data_c.shm_segsz))
			return;
		if (!field_ctoj_long(env, cls, "shm_lpid", data, data_c.shm_lpid))
			return;
		if (!field_ctoj_long(env, cls, "shm_cpid", data, data_c.shm_cpid))
			return;
		if (!field_ctoj_int(env, cls, "shm_nattch", data, data_c.shm_nattch))
			return;
		if (!field_ctoj_long(env, cls, "shm_atime", data, data_c.shm_atime))
			return;
		if (!field_ctoj_long(env, cls, "shm_dtime", data, data_c.shm_dtime))
			return;
		if (!field_ctoj_long(env, cls, "shm_ctime", data, data_c.shm_ctime))
			return;
	}
}

JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmdt(JNIEnv *env, jclass obj,
  jlong shmaddr)
{
	JTHROW_neg1(shmdt((void *)(intptr_t)shmaddr))
}

JNIEXPORT jint JNICALL Java_jtux_USysVIPC_shmget(JNIEnv *env, jclass obj,
  jlong key, jint size, jint flags)
{
	int shmid;

	JTHROW_neg1(shmid = shmget(key, size, flags))
	return shmid;
}
