diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9fca309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +#ignore a test version of the cat.java file +cat2.java diff --git a/GdBShell.java b/GdBShell.java new file mode 100644 index 0000000..dd3e22c --- /dev/null +++ b/GdBShell.java @@ -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 concatPosition = new ArrayList(); + //save the positions of concats + for (int i=0; i0){ + + //split the inputArray into singular commands that were separated by && + + ArrayList> commandsList = new ArrayList>(); + for (int i=0;i()); + } + //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> 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 pipePos = new ArrayList(); + 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;j1){ + pipe(pipefd); + returnValue= execute(commands[0],fd_in,pipefd[1]); + for(int i=1;i-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 +#include "KernelWrapper.h" + +#include +#include // calloc +#include // _exit, fork, lseek, read, write, close, dup2 +#include // open +#include // waitpid, opendir, closedir, open, lseek +#include // waitpid +#include // open +#include // opendir, readdir, closedir +#include + + +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; +} diff --git a/cTools/KernelWrapper.class b/cTools/KernelWrapper.class new file mode 100644 index 0000000..d02d156 Binary files /dev/null and b/cTools/KernelWrapper.class differ diff --git a/cTools/KernelWrapper.h b/cTools/KernelWrapper.h new file mode 100644 index 0000000..d7d751b --- /dev/null +++ b/cTools/KernelWrapper.h @@ -0,0 +1,133 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* 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 diff --git a/cTools/KernelWrapper.java b/cTools/KernelWrapper.java new file mode 100644 index 0000000..c96f0d4 --- /dev/null +++ b/cTools/KernelWrapper.java @@ -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); +} diff --git a/cTools/Makefile b/cTools/Makefile new file mode 100644 index 0000000..a8f69ae --- /dev/null +++ b/cTools/Makefile @@ -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 diff --git a/cTools/libKernelWrapper.so b/cTools/libKernelWrapper.so new file mode 100644 index 0000000..93e8c0c Binary files /dev/null and b/cTools/libKernelWrapper.so differ diff --git a/cat.java b/cat.java new file mode 100644 index 0000000..81884d7 --- /dev/null +++ b/cat.java @@ -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;i1){ + 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;i2&&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 + Report cat translation bugs to + +COPYRIGHT + Copyright © 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later . + 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: + or available locally via: info '(coreutils) cat invocation' + +GNU coreutils 8.28 January 2018 CAT(1) diff --git a/executeToCheck.java b/executeToCheck.java new file mode 100644 index 0000000..05c4220 --- /dev/null +++ b/executeToCheck.java @@ -0,0 +1,8 @@ +import static cTools.KernelWrapper.*; + +class executeToCheck { + public static void main(String[] args) { + System.out.println("Successfully sourced KernelWrapper!"); + exit(0); + } +} diff --git a/java_use_me b/java_use_me new file mode 100755 index 0000000..fd055ca --- /dev/null +++ b/java_use_me @@ -0,0 +1,3 @@ +#!/bin/bash +export LD_LIBRARY_PATH=./cTools +/etc/alternatives/java $* diff --git a/source_me b/source_me new file mode 100644 index 0000000..3e96b22 --- /dev/null +++ b/source_me @@ -0,0 +1 @@ +export LD_LIBRARY_PATH=./cTools diff --git a/test b/test new file mode 100644 index 0000000..ddf93d2 --- /dev/null +++ b/test @@ -0,0 +1,8 @@ +next line nothing + +next two nothing + + +now random text +1231248017413 +\test?