/*
 * Class:     org_mortbay_setuid_SetUID
 * Method:    getrlimitnofiles
 * Signature: ()Lorg/mortbay/setuid/RLimit;
 */
JNIEXPORT jobject JNICALL Java_org_mortbay_setuid_SetUID_getrlimitnofiles
  (JNIEnv *env, jclass j)
{
    struct rlimit rlim;
    int success = getrlimit(RLIMIT_NOFILE, &rlim);
    if (success < 0)
    {
        throwNewJavaSecurityException(env, "getrlimit failed");
        return NULL;
    }

    // get The java class org.mortbay.setuid.RLimit
    jclass cls = (*env)->FindClass(env, "org/mortbay/setuid/RLimit");
    if(!cls)
    {
        throwNewJavaSecurityException(env, "Class: org.mortbay.setuid.RLimit is not found!!!");
        return NULL;
    }
    
    // get the default constructor  of org.mortbay.setuid.RLimit
    jmethodID constructorMethod = getJavaMethodId(env, cls, "<init>", "()V");
    
    // construct org.mortbay.setuid.RLimit java object
    jobject retVal = (*env)->NewObject(env, cls,constructorMethod);
    if(!retVal)
    {
        throwNewJavaSecurityException(env, "Object Construction Error of Class: org.mortbay.setuid.RLimit!!!");
        return NULL;
    }
    setJavaFieldInt(env, retVal, "_soft", rlim.rlim_cur);
    setJavaFieldInt(env, retVal, "_hard", rlim.rlim_max);

    (*env)->DeleteLocalRef(env, cls);
    return retVal;
}
JNIEXPORT jobject JNICALL 
Java_org_mortbay_setuid_SetUID_getpwuid(JNIEnv * env, jclass j, jint uid)
{
    struct passwd* pw;
    pw=getpwuid((uid_t) uid);
    if (!pw) 
    {
        char strErr[255];
        sprintf(strErr, "User with uid %d is not found!!!", uid);
        throwNewJavaSecurityException(env, strErr);
        return NULL;
    }
    

    // get The java class org.mortbay.setuid.Passwd
    
    jclass cls;
    cls = (*env)->FindClass(env,"org/mortbay/setuid/Passwd");
    if(!cls)
    {
        throwNewJavaSecurityException(env, "Class: org.mortbay.setuid.Passwd is not found!!!");
        return NULL;
    }
    
    // get the default constructor  of org.mortbay.setuid.Passwd
    jmethodID constructorMethod = getJavaMethodId(env, cls, "<init>", "()V");
    
    // construct org.mortbay.setuid.Passwd java object
    jobject retVal = (*env)->NewObject(env, cls,constructorMethod);
    if(!retVal)
    {
        throwNewJavaSecurityException(env, "Object Construction error of Class: org.mortbay.setuid.Passwd!!!");
        return NULL;
    }
    
    
    // copy the struct passwd values to java object org.mortbay.setuid.Passwd
    //char *pw_name;
    setJavaFieldString(env, retVal, "_pwName", pw->pw_name);
	//char *pw_passwd;
    setJavaFieldString(env, retVal, "_pwPasswd", pw->pw_passwd);
	//uid_t pw_uid;
    setJavaFieldInt(env, retVal, "_pwUid", pw->pw_uid);   
	//gid_t pw_gid;
    setJavaFieldInt(env, retVal, "_pwGid", pw->pw_gid);
	//char *pw_gecos;
    setJavaFieldString(env, retVal, "_pwGecos", pw->pw_gecos);
	//char *pw_dir;
    setJavaFieldString(env, retVal, "_pwDir", pw->pw_dir);
	//char *pw_shell;
    setJavaFieldString(env, retVal, "_pwShell", pw->pw_shell);
	
    (*env)->DeleteLocalRef(env, cls);
    return retVal;
}
JNIEXPORT jobject JNICALL 
Java_org_mortbay_setuid_SetUID_getgrgid(JNIEnv * env, jclass j, jint gid)
{
    struct group* gr;
    
    gr=getgrgid(gid);
    if (!gr) 
    {
        char strErr[255];
        sprintf(strErr, "Group with gid %d is not found!!!", gid);
        throwNewJavaSecurityException(env, strErr);
        return NULL;
    }
    

    // get The java class org.mortbay.setuid.Passwd
    jclass cls;
    cls = (*env)->FindClass(env,"org/mortbay/setuid/Group");
    if(!cls)
    {
        throwNewJavaSecurityException(env, "Class: org.mortbay.setuid.Group is not found!!!");
        return NULL;
    }
    
    // get the default constructor  of org.mortbay.setuid.Group
    jmethodID constructorMethod = getJavaMethodId(env, cls, "<init>", "()V");
    
    // construct org.mortbay.setuid.Group java object
    jobject retVal = (*env)->NewObject(env, cls,constructorMethod);
    if(!retVal)
    {
        throwNewJavaSecurityException(env, "Object Construction Error of Class: org.mortbay.setuid.Group!!!");
        return NULL;
    }
    
    
    
    // copy the struct grpup values to java object org.mortbay.setuid.Group
    //char *gr_name;
    setJavaFieldString(env, retVal, "_grName", gr->gr_name);
	//char *gr_passwd;
    setJavaFieldString(env, retVal, "_grPasswd", gr->gr_passwd);
	//gid_t   gr_gid;
    setJavaFieldInt(env, retVal, "_grGid", gr->gr_gid);
	
    
    
    
    if (gr->gr_mem != NULL) 
    {
        int array_size, i;
        jobjectArray gr_mems;
        
        for(array_size =0; gr->gr_mem[array_size] != NULL; array_size++); 
        
        if(array_size)
        {
            jobjectArray strArr =  (*env)->NewObjectArray(env, array_size, 
                                                          (*env)->FindClass(env, "java/lang/String"), 
                                                          (*env)->NewStringUTF(env, ""));
            
            for(i=0;i<array_size;i++) 
            {
                (*env)->SetObjectArrayElement(env,strArr,i,
                                              (*env)->NewStringUTF(env, gr->gr_mem[i]));
            }

            // set string array field;
            // find field
            jfieldID fieldId =  (*env)->GetFieldID(env, cls, "_grMem", "[Ljava/lang/String;");
            if(!fieldId)
            {
                throwNewJavaSecurityException(env, "Java Object Field is not found: String _grMem!!!");
            }
            
            (*env)->SetObjectField(env, retVal, fieldId, strArr); 
        }
    }
    
    (*env)->DeleteLocalRef(env, cls);
    return retVal;
}
JNIEXPORT jobject JNICALL 
Java_org_eclipse_jetty_setuid_SetUID_getpwnam(JNIEnv * env, jclass j, jstring name)
{
    struct passwd* pw;
    jboolean iscopy;
    char *pname; 
    pname = (char*) (*env)->GetStringUTFChars(env, name, &iscopy);
    
    pw=getpwnam((char *) pname);
    if (!pw) 
    {
        char strErr[255];
        sprintf(strErr, "User %s is not found!!!", pname);
        throwNewJavaSecurityException(env, strErr);
        return NULL;
    }
    
    // free as in amnesty
    (*env)->ReleaseStringUTFChars( env, name, pname ); 
    

    // get The java class org.eclipse.jetty.setuid.Passwd
    jclass cls;
    cls = (*env)->FindClass(env,"org/eclipse/jetty/setuid/Passwd");
    if(!cls)
    {
        throwNewJavaSecurityException(env, "Class: org.eclipse.jetty.setuid.Passwd is not found!!!");
        return NULL;
    }
    
    // get the default constructor  of org.eclipse.jetty.setuid.Passwd
    jmethodID constructorMethod = getJavaMethodId(env, cls, "<init>", "()V");
    
    // construct org.eclipse.jetty.setuid.Passwd java object
    jobject retVal = (*env)->NewObject(env, cls,constructorMethod);
    if(!retVal)
    {
        throwNewJavaSecurityException(env, "Object Construction error of Class: org.eclipse.jetty.setuid.Passwd!!!");
        return NULL;
    }
    
    
    // copy the struct passwd values to java object org.eclipse.jetty.setuid.Passwd
    //char *pw_name;
    setJavaFieldString(env, retVal, "_pwName", pw->pw_name);
	//char *pw_passwd;
    setJavaFieldString(env, retVal, "_pwPasswd", pw->pw_passwd);
	//uid_t pw_uid;
    setJavaFieldInt(env, retVal, "_pwUid", pw->pw_uid);   
	//gid_t pw_gid;
    setJavaFieldInt(env, retVal, "_pwGid", pw->pw_gid);
	//char *pw_gecos;
    setJavaFieldString(env, retVal, "_pwGecos", pw->pw_gecos);
	//char *pw_dir;
    setJavaFieldString(env, retVal, "_pwDir", pw->pw_dir);
	//char *pw_shell;
    setJavaFieldString(env, retVal, "_pwShell", pw->pw_shell);
	
    (*env)->DeleteLocalRef(env, cls);
    return retVal;


}