Initial commit pushing project source

This commit is contained in:
eneller
2020-07-18 20:10:15 +02:00
parent 9b60b8ec0f
commit 1fb60aaa0d
14 changed files with 1206 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
#ignore a test version of the cat.java file
cat2.java

596
GdBShell.java Normal file
View File

@@ -0,0 +1,596 @@
import static cTools.KernelWrapper.*; //imports a Java Wrapper for C kernel functions, needs the sourced source_me
import java.util.ArrayList;
import java.util.Scanner;
import java.lang.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
//TODO: switch case for printcolor
//TODO: implement auto source?
public class main{
public static void main(String[] args){
System.out.println("Welcome!");
String shellPrefix = "EN@GdBShell:";//print actual user instead of EN??
int runningInt = 0;
Scanner scn = new Scanner(System.in);
while (true){
parseInput(getInput(runningInt,shellPrefix, scn));
runningInt++;
}
}
static String[] getInput(int runningInt, String shellPrefix, Scanner scn){
String directoryPath = System.getProperty("user.dir");
String[] directoryArray = directoryPath.split("/");
StringBuffer buffer = new StringBuffer("~");
//gets rid of the home/user directory and builds a string
for (int i=3;(i<directoryArray.length);i++){
buffer.append("/");
buffer.append(directoryArray[i]);
}
System.out.print("("+runningInt+")");
printColor(shellPrefix,"purple",false);
printColor(buffer.toString()+"$ ","cyan",false);
String input= scn.nextLine();//get input
String[] inputArray = input.split(" ");
//get rid of spaces and tabs
int countInputs = 0;
int[] countArray = new int[inputArray.length];
//count all inputs that actually contain something and put them in a new array in the second for loop
for (int i =0;i< inputArray.length;i++){
if (inputArray[i].equals(" ")||inputArray[i].equals(" ")||inputArray[i].equals("")){
;
}
else{
countArray[countInputs]=i;
countInputs++;
}
}
//System.out.println(Arrays.toString(countArray));
String[] returnArray = new String[countInputs];
for (int i=0; i<countInputs;i++){
returnArray[i]= inputArray[(countArray[i])];
}
return returnArray;
//return replaceCat(returnArray);
}
static void parseInput(String[] inputArray){
//System.out.println(inputArray.length + Arrays.toString(inputArray));
//check for empty inputs
if (inputArray.length<=1){
if(inputArray.length==0){return;}
if(inputArray[0].equals(" ")){return;}
if(inputArray[0].equals(" ")){return;}
}
//implements the exit terminal function
if (inputArray[0].equals("exit")){
if (inputArray.length==1){
printColor("Session ended by user","red",true);
System.exit(0);
}
else{
printColor( "\"exit\" doesn't take parameters. It will end this current shell. Did you try to find a different executable?","red",true);
return;
}
}
//find concats with && in input and execute only if previous command was successful
ArrayList<Integer> concatPosition = new ArrayList<Integer>();
//save the positions of concats
for (int i=0; i<inputArray.length;i++){
if(inputArray[i].equals("&&")){
concatPosition.add(i);
}
}
/*
//for testing***************, prints the positions of the concats
for (int i=0;i<concatPosition.size();i++){
printColor(Integer.toString(concatPosition.get(i))+" ","yellow",false);
}
//**************************
*/
//if there are any concats
if(concatPosition.size()>0){
//split the inputArray into singular commands that were separated by &&
ArrayList<ArrayList<String>> commandsList = new ArrayList<ArrayList<String>>();
for (int i=0;i<concatPosition.size()+1;i++){
commandsList.add( new ArrayList<String>());
}
//upper Arraylist used with fixed size, doesnt throw warning like using an array would
//because one concat splits the input into two parts --->+1
//iterate over every command except last, because no concat comes after the last one
int prevConcatPos=0;
for (int i=0;i<concatPosition.size();i++){
for(int j=prevConcatPos;j<concatPosition.get(i);j++){
(commandsList.get(i)).add(inputArray[j]);
}
prevConcatPos=concatPosition.get(i)+1;
}
//add last command
for (int i=concatPosition.get(concatPosition.size()-1)+1;i<inputArray.length;i++){
(commandsList.get(commandsList.size()-1)).add(inputArray[i]);
}
//execute commands in commandsList if previous command was successful, ie terminated with code 0
int returnValue = 0;
for(int i=0;i<commandsList.size();i++){
//if previous command successful
if (returnValue==0){
//build array from arraylist that contains command
String[] command = new String[commandsList.get(i).size()];
for (int j=0;j<command.length;j++){
command[j]= commandsList.get(i).get(j);
}
//execute command and save return value
returnValue = parseRedirect(command);
}
//if it wasnt successful
else{
//build command as string that wasnt succcessful
int failedCommandNumber = i-1;
StringBuffer buffer = new StringBuffer();
for (int j=0;j<commandsList.get(failedCommandNumber).size();j++){
buffer.append(commandsList.get(failedCommandNumber).get(j));
}
printColor("Stopped concatenation at command number "+ failedCommandNumber +" \""+buffer.toString()+"\"","red",true);
if(returnValue==Integer.MIN_VALUE){
printColor("Couldn't find executable assigned to \""+ commandsList.get(failedCommandNumber).get(0)+"\"","red",true);
}
else{
printColor("Exited with error code "+returnValue,"red",true);
}
break;
}
}
}
// if its only one command without concats
else{
int returnValue = parseRedirect(inputArray);
if (returnValue==0){
printColor("Process exited without error","green",true);
}
else{
if(returnValue == Integer.MIN_VALUE){
printColor("Couldn't find executable assigned to \""+ inputArray[0]+"\"","red",true);
}
else{
printColor("Process exited with code "+ returnValue,"red",true);
}
}
}
return;//TODO: clean up error messages
}
static int parseRedirect(String[] inputArray){//should take pipe and read/write,, add >> for append?
//find last occurrences of < and >
int redirectInPos = -1;
int redirectOutPos = -1;
boolean setFirstBool = true;
int firstPos = inputArray.length;
for(int i=0;i< inputArray.length;i++){
if(inputArray[i].equals("<")){
redirectInPos = i;
if(setFirstBool){
firstPos=i;
setFirstBool = false;
}
}
if(inputArray[i].equals(">")){
redirectOutPos = i;
if(setFirstBool){
firstPos=i;
setFirstBool = false;
}
}
/*if(inputArray[i].equals(">>")){
appendOutPos = i;
}*/
}
int fd_in=-1;
if(redirectInPos!=-1){
if(checkls(inputArray[redirectInPos+1])){
fd_in = open(inputArray[redirectInPos+1],O_RDONLY);
}
else{return -10;}//throw error because invalid input file
}
int fd_out=-1;
if(redirectOutPos!=-1){
fd_out = open(inputArray[redirectOutPos+1],O_WRONLY|O_CREAT|O_TRUNC);//create file if non existent, overwrite if it is
}
String[] commands = new String[firstPos];
for (int i=0;i< commands.length;i++){
commands[i]=inputArray[i];
}
int returnValue= parsePipe(commands,fd_in,fd_out);
if(fd_in!=-1){
close(fd_in);
}
if(fd_out!= -1){
close(fd_out);
}
return returnValue;
}
static int parsePipe(String[] inputArray,int fd_in, int fd_out){
int returnValue = -5;
ArrayList<Integer> pipePos = new ArrayList<Integer>();
int count =0;
for (int i =0;i< inputArray.length; i++){
if (inputArray[i].equals("|")){
pipePos.add(count);
count=0;
}
else{count++;}
}
pipePos.add(count);
//populate array of commands separated by |
String[][] commands = new String[pipePos.size()][];
int prevPipePos = 0;
for (int i=0;i< pipePos.size();i++){
commands[i] = new String[pipePos.get(i)];
for (int j=0;j<commands[i].length;j++){
commands[i][j]=inputArray[j+prevPipePos];
}
prevPipePos = prevPipePos + pipePos.get(i)+1;
}
//execute commands
//first command gets stdin
int lastIn = -1;
int[] pipefd = new int[2];
if(commands.length>1){
pipe(pipefd);
returnValue= execute(commands[0],fd_in,pipefd[1]);
for(int i=1;i<commands.length-1;i++){
returnValue = execute(commands[i],pipefd[0],pipefd[1]);
}
lastIn = pipefd[0];
System.err.println("here");
}
else{
lastIn = fd_in;
}
// execute last (or only) command
returnValue = execute(commands[commands.length-1],lastIn,fd_out);
return returnValue;
}
static int execute(String[] inputArray,int fd_in, int fd_out){//0 for read, 1 for write
int[] intArray = new int[]{Integer.MIN_VALUE};//to pass to the waitpid function
//split the Array into path and arguments
//tries to find the executable at first position of input
String path = null;
if (inputArray.length!=0){
String input = inputArray[0];
/*
if (input.indexOf("/")>-1){
if (checkls(input)==true){
path = input;
}
}
else{*/
path = which(input);
//}
}
else{return Integer.MIN_VALUE+1;}// add error in parseInput for this number
//if path found, compile argslist and start execv
if (isNumeric(path)==false){
printColor("Executing program at "+path,"green",true);
//System.out.println();
//int[] pipeArray = new int[]{0};//sets the pip
int forkInt = fork();// saves the return value because every call will fork the process again
//baby process
if (forkInt==0){
//Array[0] mit rest als parameter ausführen (path, args[])
//read from pipe or write to it
if(fd_in!=-1){
close(0);
dup2(fd_in,0);
}
if(fd_out!=-1){
close(1);
dup2(fd_out,1);
}
//execute the program
execv(path, inputArray);
printColor("execv fatal error","red",true);
exit(0);
}
//papa process
else{
waitpid(forkInt,intArray,0);
//read from pipe HEEERE???
}
}
return intArray[0];
}
public static String which(String arguments){
ProcessBuilder prcBuilder = new ProcessBuilder();
prcBuilder.command("bash","-c","which "+arguments);
try {
Process process = prcBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line =null;
StringBuffer buffer = new StringBuffer();
while ((line=reader.readLine())!=null){
buffer.append(line);
}
String path = buffer.toString();
if (path.contains("/")){
return path;
}
else{
int exitCode = process.waitFor();
return Integer.toString(exitCode);
//System.out.println("\nExited with error code : " + exitCode);
}
}
catch (IOException e) {
printColor("err1","red",true); //e.toString();
}
catch (InterruptedException e) {
printColor("err2","red",true); //e.toString();
}
return "t";
}
public static boolean checkls(String input){
//check what ls does in this program if executed locally
String[] inputArray = input.split("/");
String checkfile = inputArray[inputArray.length-1];
StringBuffer buffer1 = new StringBuffer();
if (input.indexOf("/")==0){
buffer1.append("/");
}
for (int i=0;i<inputArray.length;i++){
buffer1.append(inputArray[i]);
if(i<inputArray.length-1){
buffer1.append("/");
}
}
//System.out.println(buffer1);
ProcessBuilder prcBuilder = new ProcessBuilder();
prcBuilder.command("bash","-c","ls "+buffer1.toString());
try {
Process process = prcBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line =null;
StringBuffer buffer2 = new StringBuffer();
while ((line=reader.readLine())!=null){
buffer2.append(line);
buffer2.append(" ");
}
String path = buffer2.toString();
//printColor(path,"yellow",true);//for test purposes
if (path.contains(checkfile)){
return true;
}
else{
int exitCode = process.waitFor();
return false;
//System.out.println("\nExited with error code : " + exitCode);
}
}
catch (IOException e) {
printColor("err1","red",true); //e.toString();
}
catch (InterruptedException e) {
printColor("err2","red",true); //e.toString();
}
return false;
}
public static boolean isNumeric(String toCheck){
try{
double d = Double.parseDouble(toCheck);
}
catch(NumberFormatException nsfw){
return false;
}
catch(NullPointerException npe){
return false;
}
return true;
}
static boolean printColor(String text, String colorvar, boolean lineBreak){// maybe rainbow??
//takes two Strings and one boolean that specify the text to print, the color and if there should be a linebreak (ie print or println)
String ANSI_RESET = "\u001B[0m";
String ANSI_BLACK = "\u001B[30m";
String ANSI_RED = "\u001B[31m";
String ANSI_YELLOW = "\u001B[33m";
String ANSI_BLUE = "\u001B[34m";
String ANSI_PURPLE = "\u001B[35m";
String ANSI_CYAN = "\u001B[36m";
String ANSI_WHITE = "\u001B[37m";
String ANSI_GREEN = "\u001B[32m";
boolean returnBool= true;
String color= colorvar.toLowerCase();
if (color.equals("white")){
color=ANSI_WHITE;
}
else{
if (color.equals("black")){
color=ANSI_BLACK;
}
else{
if (color.equals("yellow")){
color=ANSI_YELLOW;
}
else{
if (color.equals("blue")){
color=ANSI_BLUE;
}
else{
if (color.equals("purple")){
color=ANSI_PURPLE;
}
else{
if (color.equals("cyan")){
color=ANSI_CYAN;
}
else{
if (color.equals("red")){
color=ANSI_RED;
}
else{
if (color.equals("green")){
color=ANSI_GREEN;
}
else{
System.out.print(text);
returnBool = false;
}
}
}
}
}
}
}
}
System.out.print(color+text + ANSI_RESET);
if (lineBreak){
System.out.println("");
}
return returnBool;
}
static String[] replaceCat(String[] args){//used to integrate custom cat into shell
if (args[0].equals("jcat")){
String[] changed = new String[args.length+1];
changed[0]= "java";
changed[1]= "cat.java";
for (int i=1;i<args.length;i++){//ignore the "jcat" at first pos
changed[i+1]=args[i];
}
return changed;
}
else{return args;}
}
}

138
cTools/KernelWrapper.c Normal file
View File

@@ -0,0 +1,138 @@
#include <jni.h>
#include "KernelWrapper.h"
#include <stdio.h>
#include <stdlib.h> // calloc
#include <unistd.h> // _exit, fork, lseek, read, write, close, dup2
#include <fcntl.h> // open
#include <sys/types.h> // waitpid, opendir, closedir, open, lseek
#include <sys/wait.h> // waitpid
#include <sys/stat.h> // open
#include <dirent.h> // opendir, readdir, closedir
#include <errno.h>
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_exit(JNIEnv *env, jclass clazz, jint rc) {
_exit(rc);
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_fork(JNIEnv *env, jclass clazz) {
pid_t pid;
if ( (pid = fork()) == -1) { perror("KernelWrapper fork"); }
return pid;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_waitpid(JNIEnv *env, jclass clazz, jint pid, jintArray status, jint options) {
int *stat = (*env)->GetIntArrayElements(env, status, 0);
pid_t p = waitpid(pid, stat, options);
if (p==-1) perror("KernelWrapper waitpid");
(*env)->ReleaseIntArrayElements(env, status, stat, 0);
return p;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_execv( JNIEnv *env, jclass clazz, jstring path, jobjectArray argv ) {
const char *c_path = (*env)->GetStringUTFChars(env, path, 0);
char **c_argv = calloc(sizeof(char*), (*env)->GetArrayLength(env, argv)+2);
for (int i = 0; i < (*env)->GetArrayLength(env, argv); i++)
c_argv[i] = (char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectArrayElement(env, argv, i), 0);
if (execv(c_path, (char *const*)c_argv) == -1) { perror("KernelWrapper execv"); return -1; }
fprintf(stderr, "\nHow did you get here?!?\n"); exit(1);
}
JNIEXPORT jobjectArray JNICALL Java_cTools_KernelWrapper_readdir(JNIEnv *env, jclass clazz, jstring path) {
DIR *dp;
struct dirent *ep;
const char *c_path = (*env)->GetStringUTFChars(env, path, 0);
if ( ! (dp = opendir(c_path)) ) { perror("KernelWrapper opendir"); return 0; }
int size = -1;
do {
size++;
errno = 0;
ep = readdir(dp);
if (errno) { perror("KernelWrapper readdir"); return 0; }
} while (ep);
rewinddir(dp);
jobjectArray array = (*env)->NewObjectArray(env, size, (*env)->FindClass(env, "java/lang/String"), 0);
for (int i = 0; ep = readdir(dp); i++)
(*env)->SetObjectArrayElement(env, array, i, (*env)->NewStringUTF(env, ep->d_name));
closedir(dp);
(*env)->ReleaseStringUTFChars(env, path, c_path);
return array;
}
JNIEXPORT jstring JNICALL Java_cTools_KernelWrapper_get_1current_1dir_1name(JNIEnv *env, jclass clazz) {
char *xxx=get_current_dir_name();
return (*env)->NewStringUTF(env, xxx);
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_open( JNIEnv *env, jclass clazz, jstring path, jint flags ) {
const char *c_path = (*env)->GetStringUTFChars(env, path, 0);
int file;
if ( (file = open(c_path, flags, 0666)) == -1) { perror("KernelWrapper open"); }
(*env)->ReleaseStringUTFChars(env, path, c_path);
return file;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_close( JNIEnv *env, jclass clazz, jint fd ) {
int err;
if ( (err = close(fd)) == -1) { perror("KernelWrapper close"); }
return err;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_lseek( JNIEnv *env, jclass clazz, jint fd, jint offset, jint whence ) {
int bytes;
if ( (bytes = lseek(fd, offset, whence)) == -1) { perror("KernelWrapper lseek"); exit(1); }
return bytes;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_read( JNIEnv *env, jclass clazz, jint fd, jbyteArray buf, jint count ) {
unsigned char *c_buf = (*env)->GetByteArrayElements(env, buf, 0);
int bytes;
if ( (bytes = read(fd, c_buf, count)) == -1) { perror("KernelWrapper read"); exit(1); }
(*env)->ReleaseByteArrayElements(env, buf, c_buf, 0);
return bytes;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_readOffset( JNIEnv *env, jclass clazz, jint fd, jbyteArray buf, jint offset, jint count ) {
unsigned char *c_buf = (*env)->GetByteArrayElements(env, buf, 0);
int bytes;
if ( (bytes = read(fd, c_buf+offset, count)) == -1) { perror("KernelWrapper read"); }
(*env)->ReleaseByteArrayElements(env, buf, c_buf, 0);
return bytes;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_write( JNIEnv *env, jclass clazz, jint fd, jbyteArray buf, jint count ) {
unsigned char *c_buf = (*env)->GetByteArrayElements(env, buf, 0);
int bytes;
if ( (bytes = write(fd, c_buf, count)) == -1) { perror("KernelWrapper write"); }
if (bytes != count) { fprintf(stderr, "Could not write everything!\nThis should not happen!\n"); }
(*env)->ReleaseByteArrayElements(env, buf, c_buf, 0);
return bytes;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_writeOffset( JNIEnv *env, jclass clazz, jint fd, jbyteArray buf, jint offset, jint count ) {
unsigned char *c_buf = (*env)->GetByteArrayElements(env, buf, 0);
int bytes;
if ( (bytes = write(fd, c_buf+offset, count)) == -1) { perror("KernelWrapper write"); }
if (bytes != count) { fprintf(stderr, "Could not write everything!\nThis should not happen!\n"); }
(*env)->ReleaseByteArrayElements(env, buf, c_buf, 0);
return bytes;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_dup2( JNIEnv *env, jclass clazz, jint oldfd, jint newfd ) {
int fd;
if ( (fd = dup2(oldfd, newfd)) == -1) perror("KernelWrapper dup2");
return fd;
}
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_pipe( JNIEnv *env, jclass clazz, jintArray pipefd ) {
int *ary = (*env)->GetIntArrayElements(env, pipefd, 0);
int rc = pipe(ary);
if (rc==-1) { perror("KernelWrapper pipe"); }
(*env)->ReleaseIntArrayElements(env, pipefd, ary, 0);
return rc;
}

BIN
cTools/KernelWrapper.class Normal file

Binary file not shown.

133
cTools/KernelWrapper.h Normal file
View File

@@ -0,0 +1,133 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cTools_KernelWrapper */
#ifndef _Included_cTools_KernelWrapper
#define _Included_cTools_KernelWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cTools_KernelWrapper
* Method: exit
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_exit
(JNIEnv *, jclass, jint);
/*
* Class: cTools_KernelWrapper
* Method: fork
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_fork
(JNIEnv *, jclass);
/*
* Class: cTools_KernelWrapper
* Method: waitpid
* Signature: (I[II)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_waitpid
(JNIEnv *, jclass, jint, jintArray, jint);
/*
* Class: cTools_KernelWrapper
* Method: execv
* Signature: (Ljava/lang/String;[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_execv
(JNIEnv *, jclass, jstring, jobjectArray);
/*
* Class: cTools_KernelWrapper
* Method: get_current_dir_name
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cTools_KernelWrapper_get_1current_1dir_1name
(JNIEnv *, jclass);
/*
* Class: cTools_KernelWrapper
* Method: open
* Signature: (Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_open
(JNIEnv *, jclass, jstring, jint);
/*
* Class: cTools_KernelWrapper
* Method: close
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_close
(JNIEnv *, jclass, jint);
/*
* Class: cTools_KernelWrapper
* Method: lseek
* Signature: (III)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_lseek
(JNIEnv *, jclass, jint, jint, jint);
/*
* Class: cTools_KernelWrapper
* Method: read
* Signature: (I[BI)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_read
(JNIEnv *, jclass, jint, jbyteArray, jint);
/*
* Class: cTools_KernelWrapper
* Method: readOffset
* Signature: (I[BII)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_readOffset
(JNIEnv *, jclass, jint, jbyteArray, jint, jint);
/*
* Class: cTools_KernelWrapper
* Method: write
* Signature: (I[BI)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_write
(JNIEnv *, jclass, jint, jbyteArray, jint);
/*
* Class: cTools_KernelWrapper
* Method: writeOffset
* Signature: (I[BII)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_writeOffset
(JNIEnv *, jclass, jint, jbyteArray, jint, jint);
/*
* Class: cTools_KernelWrapper
* Method: pipe
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_pipe
(JNIEnv *, jclass, jintArray);
/*
* Class: cTools_KernelWrapper
* Method: readdir
* Signature: (Ljava/lang/String;)[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_cTools_KernelWrapper_readdir
(JNIEnv *, jclass, jstring);
/*
* Class: cTools_KernelWrapper
* Method: dup2
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cTools_KernelWrapper_dup2
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

38
cTools/KernelWrapper.java Normal file
View File

@@ -0,0 +1,38 @@
package cTools;
public class KernelWrapper {
static {
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("KernelWrapper"); // actually: libKernelWrapper.so
}
public static int O_RDONLY = 0;
public static int O_WRONLY = 1;
public static int O_RDWR = 2;
public static int O_CREAT = 64;
public static int O_TRUNC = 512;
public static int SEEK_SET = 0;
public static int SEEK_CUR = 1;
public static int SEEK_END = 2;
public static int STDIN_FILENO = 0;
public static int STDOUT_FILENO = 1;
public static int STDERR_FILENO = 2;
public static native int exit(int rc);
public static native int fork();
public static native int waitpid(int pid, int[] status, int options);
public static native int execv(String path, String[] argv);
//public static native String get_current_dir_name();
public static native int open(String path, int flags);
public static native int close(int fd);
public static native int lseek(int fd, int offset, int whence);
public static native int read(int fd, byte[] buf, int count);
public static native int readOffset(int fd, byte[] buf, int offset, int count);
public static native int write(int fd, byte[] buf, int count);
public static native int writeOffset(int fd, byte[] buf, int offset, int count);
public static native int pipe(int[] pipefd);
public static native String[] readdir(String path);
public static native int dup2(int oldfd, int newfd);
}

8
cTools/Makefile Normal file
View File

@@ -0,0 +1,8 @@
KernelWrapper:
javac KernelWrapper.java
(cd ..; javah -o cTools/KernelWrapper.h cTools.KernelWrapper)
gcc -std=c99 -shared -fpic -I /opt/jdk/include -I /opt/jdk/include/linux -o libKernelWrapper.so KernelWrapper.c
#gcc -std=c99 -shared -fpic -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux -o libKernelWrapper.so KernelWrapper.c
clean:
/bin/rm -f *.class KernelWrapper.h libKernelWrapper.so

BIN
cTools/libKernelWrapper.so Normal file

Binary file not shown.

202
cat.java Normal file
View File

@@ -0,0 +1,202 @@
//the cat version that doesnt use lseek(), only read()
import static cTools.KernelWrapper.*; //imports a Java Wrapper for C kernel functions, needs the sourced source_me
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
//implement
public class cat{
public static void main(String[] args) {
//double start = System.nanoTime();
boolean[] errarr = {false};
int count =0;
boolean [] params = parseArgs(args);//extract parameters and remove them from args
//System.out.println(Arrays.toString(args));//for testing
boolean argsnull=true;
for(int i=0;i<args.length;i++){
if(args[i]!=null){
argsnull=false;
break;
}
}
if (args.length==0||argsnull){//get input if without params
inputLoop(params,count);
}
else{
//System.out.println(Arrays.toString(args));//for testing
if (params[0]){
//System.out.println("If you always seek help from others, you will never be able to achieve greatness on your own.");// r/im14andthisisdeep
printFile("cat.txt",params,errarr,count);
}
else{
for (int i=0; i<args.length;i++){
if (args[i]!=null){
if (args[i].equals("-")){//get input if file name is "-"
count = inputLoop(params,count);
}
else{
count = printFile(args[i],params,errarr,count); //output file
}
}
}
}
}
/*
double end = System.nanoTime()-start;
end=end/(1000*1000*1000);
System.out.println(end);
*/
//System.out.println();
if(errarr[0]){System.exit(1);}
else{System.exit(0);}
}
static boolean[] parseArgs(String[] args){
boolean[] params = new boolean[3];
for (int i =0;i<args.length;i++){
if(args[i].equals("--help")||args[i].equals("-s")||args[i].equals("-n")){
if (args[i].equals("--help")){params[0]=true;} //display help
if (args[i].equals("-s")){params[1]=true;} //suppress empty lines
if (args[i].equals("-n")){params[2]=true;} //enumerate lines
args[i] = null;
}
}
return params;
}
static int inputLoop(boolean[] params, int count){
Scanner scn = new Scanner(System.in);
int countEmpty=0;
boolean printThisLine = true;
while (true){
try{
String buf = scn.nextLine();
if(params[1]&&buf.length()==0){
countEmpty++;
if(countEmpty>1){
printThisLine = false;
}
}
else{
countEmpty=0;
printThisLine= true;
}
if(printThisLine){
if(params[2]){
System.out.print("\u001B[33m"+"["+Integer.toString(count)+"]"+"\u001B[0m");
count++;
}
System.out.println(buf);
}
}
catch(NoSuchElementException e){
break;
}
}
return count;
}
static int printFile(String f, boolean[] params, boolean[] errarr, int count){
//System.out.println(Arrays.toString(params));
int fd = open(f,O_RDONLY);
int bufsz = Integer.MAX_VALUE/8; //test values?
if (fd!=-1){
byte[] bytes = new byte[bufsz];//add length
int rd = read(fd,bytes,bufsz);
close(fd);
byte[] cleanbytes = new byte[rd];
for (int i=0;i<rd;i++){
cleanbytes[i]= bytes[i];
}
String s = new String(cleanbytes, StandardCharsets.UTF_8);
String t = "";//length 0
String u = "";
if(params[1]){//suppress multiple empty lines
for (int i=0;i<s.length();i++){
if(params[1]==true&&s.charAt(i)=='\n'&&(t.length()>2&&t.charAt(t.length()-1)=='\n'&&t.charAt(t.length()-2)=='\n')){;}
else{t = t+s.charAt(i);}
}
}
else{t=s;}
if(params[2]){//enumerate lines
u = u + "\u001B[33m"+"["+Integer.toString(count)+"]"+"\u001B[0m";
count++;
for (int i=0;i<t.length();i++){
u = u + t.charAt(i);
if((t.charAt(i)=='\n')&&(i<(t.length()-1))){//if we just appended a line break and we arent at the end of the file
u = u+"\u001B[33m"+"["+Integer.toString(count)+"]"+"\u001B[0m";
//t=t+Integer.toString(count)+" ";
count++;
}
}
}
else{u=t;}
//possibly append newline at end of file?
/*
if(u.charAt(u.length()-1)!='\n'){
u = u+ '\n';
}
*/
System.out.print(u);
//System.out.println();
return count;
}
else{
errarr[0]=true;
return count;
}
}
}

69
cat.txt Normal file
View File

@@ -0,0 +1,69 @@
CAT(1) User Commands CAT(1)
NAME
cat - concatenate files and print on the standard output
SYNOPSIS
cat [OPTION]... [FILE]...
DESCRIPTION
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-A, --show-all
equivalent to -vET
-b, --number-nonblank
number nonempty output lines, overrides -n
-e equivalent to -vE
-E, --show-ends
display $ at end of each line
-n, --number
number all output lines
-s, --squeeze-blank
suppress repeated empty output lines
-t equivalent to -vT
-T, --show-tabs
display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting
use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version
output version information and exit
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
cat Copy standard input to standard output.
AUTHOR
Written by Torbjorn Granlund and Richard M. Stallman.
REPORTING BUGS
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report cat translation bugs to <http://translationproject.org/team/>
COPYRIGHT
Copyright © 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
SEE ALSO
tac(1)
Full documentation at: <http://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'
GNU coreutils 8.28 January 2018 CAT(1)

8
executeToCheck.java Normal file
View File

@@ -0,0 +1,8 @@
import static cTools.KernelWrapper.*;
class executeToCheck {
public static void main(String[] args) {
System.out.println("Successfully sourced KernelWrapper!");
exit(0);
}
}

3
java_use_me Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
export LD_LIBRARY_PATH=./cTools
/etc/alternatives/java $*

1
source_me Normal file
View File

@@ -0,0 +1 @@
export LD_LIBRARY_PATH=./cTools

8
test Normal file
View File

@@ -0,0 +1,8 @@
next line nothing
next two nothing
now random text
1231248017413
\test?