#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <miscfs/tcfs/tcfs.h>
#include "kdes.h"
#include "tcfs_rw.h"
#ifndef _TCFS_KEYTAB_H_
#include "tcfs_keytab.h"
#endif
#include "tcfs_cmd.h"

#define DKS des_key_schedule
#define DCB des_cblock

int tcfs_exec_cmd(struct tcfs_mount *mp, struct tcfs_args *req)
{
	des_key_schedule *ks;
	des_cblock tmp[8];
	
	switch (req->cmd)
	{
	 	case TCFS_PUT_UIDKEY:
			ks=(DKS*)malloc(sizeof(DKS),M_FREE,M_NOWAIT);
			if(!ks)
				return ENOMEM;
			strncpy((char*)&tmp,req->des_key,KEYSIZE);
			des_set_key((DCB*)&tmp,*ks);
			return tcfs_keytab_push_uid(mp->tcfs_uid_kt,req->user,ks);

	 	case TCFS_RM_UIDKEY:
			return tcfs_keytab_rm_uid(mp->tcfs_uid_kt,req->user);

	 	case TCFS_PUT_PIDKEY:
			ks=(DKS*)malloc(sizeof(DKS),M_FREE,M_NOWAIT);
			if(!ks)
				return ENOMEM;
			strncpy((char*)&tmp,req->des_key,KEYSIZE);
			des_set_key((DCB*)&tmp,*ks);
			return tcfs_keytab_push_pid(mp->tcfs_uid_kt,req->user,req->proc,ks);

	 	case TCFS_RM_PIDKEY:
			return tcfs_keytab_rm_pid(mp->tcfs_uid_kt,req->user,req->proc);
		case TCFS_PUT_GIDKEY:
			return tcfs_keytab_push_gid(mp->tcfs_gid_kt,req->user,req->group,req->treshold,req->des_key);

		case TCFS_RM_GIDKEY:
			return tcfs_keytab_rm_gid(mp->tcfs_gid_kt,req->user,req->group);

	}
	return 0;
}
	
des_key_schedule *tcfs_getukey(struct ucred *c, struct proc *p, struct vnode *vp)
{
	tcfs_keytab_node *n;

	n=tcfs_keytab_fetch_uid(TCFS_VP2UKT(vp),c->cr_uid);

	if(n)
		return n->kn_key;
	else
		return (des_key_schedule*)NULL;
}

des_key_schedule *tcfs_getpkey(struct ucred *c, struct proc *p, struct vnode *vp)
{
	tcfs_keytab_node *n;
	struct proc *cp;

	if(!p)
		cp=curproc;
	else
		cp=p;
	
	n=tcfs_keytab_fetch_pid(TCFS_VP2UKT(vp),c->cr_uid,cp->p_pid);

	if(n)
		return n->kn_key;
	else
		return (des_key_schedule*)NULL;
}

des_key_schedule *tcfs_getgkey(struct ucred *c, struct proc *p, struct vnode *vp)
{
	tcfs_keytab_node *n;

	n=tcfs_keytab_fetch_gid(TCFS_VP2GKT(vp),c->cr_gid);

	if(n)
		return n->kn_key;
	else
		return (des_key_schedule*)NULL;
}

