diff --git a/4-ShellP2/.dshlib.c.swp b/4-ShellP2/.dshlib.c.swp
new file mode 100644
index 0000000000000000000000000000000000000000..7b1c66f6e023becd69f71d5ed390e4de36e131a8
Binary files /dev/null and b/4-ShellP2/.dshlib.c.swp differ
diff --git a/4-ShellP2/bats/assignment_test.sh b/4-ShellP2/bats/assignment_test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..30b12ec1661cd179396f1e2ee3fd8ef39de7eb96
--- /dev/null
+++ b/4-ShellP2/bats/assignment_test.sh
@@ -0,0 +1,118 @@
+#!/usr/bin/env bats
+
+############################ DO NOT EDIT THIS FILE #####################################
+# File: assignement_tests.sh
+# 
+# DO NOT EDIT THIS FILE
+#
+# Add/Edit Student tests in student_tests.sh
+# 
+# All tests in this file must pass - it is used as part of grading!
+########################################################################################
+
+@test "Change directory" {
+    current=$(pwd)
+
+    cd /tmp
+    mkdir -p dsh-test
+
+    run "${current}/dsh" <<EOF                
+cd dsh-test
+pwd
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="/tmp/dsh-testdsh2>dsh2>dsh2>cmdloopreturned0"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+    echo "${stripped_output} -> ${expected_output}"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+}
+
+@test "Change directory - no args" {
+    current=$(pwd)
+
+    cd /tmp
+    mkdir -p dsh-test
+
+    run "${current}/dsh" <<EOF                
+cd
+pwd
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="/tmpdsh2>dsh2>dsh2>cmdloopreturned0"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+    echo "${stripped_output} -> ${expected_output}"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+
+    # Assertions
+    [ "$status" -eq 0 ]
+}
+
+
+@test "Which which ... which?" {
+    run "./dsh" <<EOF                
+which which
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '[:space:]')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output="/usr/bin/whichdsh2>dsh2>cmdloopreturned0"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+    echo "${stripped_output} -> ${expected_output}"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+}
+
+@test "It handles quoted spaces" {
+    run "./dsh" <<EOF                
+   echo " hello     world     " 
+EOF
+
+    # Strip all whitespace (spaces, tabs, newlines) from the output
+    stripped_output=$(echo "$output" | tr -d '\t\n\r\f\v')
+
+    # Expected output with all whitespace removed for easier matching
+    expected_output=" hello     world     dsh2> dsh2> cmd loop returned 0"
+
+    # These echo commands will help with debugging and will only print
+    #if the test fails
+    echo "Captured stdout:" 
+    echo "Output: $output"
+    echo "Exit Status: $status"
+    echo "${stripped_output} -> ${expected_output}"
+
+    # Check exact match
+    [ "$stripped_output" = "$expected_output" ]
+}
diff --git a/4-ShellP2/bats/student_test.sh b/4-ShellP2/bats/student_test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..638bc341446f7580a80c2aff52971b8023407ea8
--- /dev/null
+++ b/4-ShellP2/bats/student_test.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bats
+
+# File: student_tests.sh
+# 
+# Create your unit tests suit in this file
+
+@test "Example: check ls runs without errors" {
+    run ./dsh <<EOF                
+ls
+EOF
+
+    # Assertions
+    [ "$status" -eq 0 ]
+}
diff --git a/4-ShellP2/dragon.c b/4-ShellP2/dragon.c
new file mode 100644
index 0000000000000000000000000000000000000000..b5ac87f2c407c82436f71ae95472bccb5ff0b9be
--- /dev/null
+++ b/4-ShellP2/dragon.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "dshlib.h"
+
+// EXTRA CREDIT - print the drexel dragon from the readme.md
+extern void print_dragon(){
+	// TODO implement
+	FILE *dragon = fopen("dragon.txt", "r");
+	if (dragon == NULL) {
+		return;
+  	}
+
+	char *s = NULL;
+	size_t nbyte;
+	ssize_t nchar;
+
+	while (1) {
+		nchar = getline(&s, &nbyte, dragon);
+		if (nchar == -1) { // end of file reached
+            break;
+        }
+        if (nchar == 0) {
+            continue;
+        }
+        if (s == NULL) { // out of memory
+            exit(1);
+        }
+        if (s[nchar - 1] == '\n') {
+            s[nchar - 1] = '\0'; // remove newline
+            nchar--; // newline removed
+        }
+
+        printf("%s\n", s);
+	}
+	free(s);
+	fclose(dragon);
+}
diff --git a/4-ShellP2/dragon.txt b/4-ShellP2/dragon.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a9177fd41bb14d2fa0fd439742e74d3f61f60d2d
--- /dev/null
+++ b/4-ShellP2/dragon.txt
@@ -0,0 +1,38 @@
+                                                                        @%%%%                       
+                                                                     %%%%%%                         
+                                                                    %%%%%%                          
+                                                                 % %%%%%%%           @              
+                                                                %%%%%%%%%%        %%%%%%%           
+                                       %%%%%%%  %%%%@         %%%%%%%%%%%%@    %%%%%%  @%%%%        
+                                  %%%%%%%%%%%%%%%%%%%%%%      %%%%%%%%%%%%%%%%%%%%%%%%%%%%          
+                                %%%%%%%%%%%%%%%%%%%%%%%%%%   %%%%%%%%%%%% %%%%%%%%%%%%%%%           
+                               %%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%     %%%            
+                             %%%%%%%%%%%%%%%%%%%%%%%%%%%%@ @%%%%%%%%%%%%%%%%%%        %%            
+                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%                
+                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              
+                            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@%%%%%%@              
+      %%%%%%%%@           %%%%%%%%%%%%%%%%        %%%%%%%%%%%%%%%%%%%%%%%%%%      %%                
+    %%%%%%%%%%%%%         %%@%%%%%%%%%%%%           %%%%%%%%%%% %%%%%%%%%%%%      @%                
+  %%%%%%%%%%   %%%        %%%%%%%%%%%%%%            %%%%%%%%%%%%%%%%%%%%%%%%                        
+ %%%%%%%%%       %         %%%%%%%%%%%%%             %%%%%%%%%%%%@%%%%%%%%%%%                       
+%%%%%%%%%@                % %%%%%%%%%%%%%            @%%%%%%%%%%%%%%%%%%%%%%%%%                     
+%%%%%%%%@                 %%@%%%%%%%%%%%%            @%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  
+%%%%%%%@                   %%%%%%%%%%%%%%%           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              
+%%%%%%%%%%                  %%%%%%%%%%%%%%%          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%      %%%%  
+%%%%%%%%%@                   @%%%%%%%%%%%%%%         %%%%%%%%%%%%@ %%%% %%%%%%%%%%%%%%%%%   %%%%%%%%
+%%%%%%%%%%                  %%%%%%%%%%%%%%%%%        %%%%%%%%%%%%%      %%%%%%%%%%%%%%%%%% %%%%%%%%%
+%%%%%%%%%@%%@                %%%%%%%%%%%%%%%%@       %%%%%%%%%%%%%%     %%%%%%%%%%%%%%%%%%%%%%%%  %%
+ %%%%%%%%%%                  % %%%%%%%%%%%%%%@        %%%%%%%%%%%%%%   %%%%%%%%%%%%%%%%%%%%%%%%%% %%
+  %%%%%%%%%%%%  @           %%%%%%%%%%%%%%%%%%        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%% 
+   %%%%%%%%%%%%% %%  %  %@ %%%%%%%%%%%%%%%%%%          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %%% 
+    %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%           @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %%%%%%% 
+     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              %%%%%%%%%%%%%%%%%%%%%%%%%%%%        %%%   
+      @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  %%%%%%%%%%%%%%%%%%%%%%%%%               
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                      %%%%%%%%%%%%%%%%%%%  %%%%%%%          
+           %%%%%%%%%%%%%%%%%%%%%%%%%%                           %%%%%%%%%%%%%%%  @%%%%%%%%%         
+              %%%%%%%%%%%%%%%%%%%%           @%@%                  @%%%%%%%%%%%%%%%%%%   %%%        
+                  %%%%%%%%%%%%%%%        %%%%%%%%%%                    %%%%%%%%%%%%%%%    %         
+                %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                      %%%%%%%%%%%%%%            
+                %%%%%%%%%%%%%%%%%%%%%%%%%%  %%%% %%%                      %%%%%%%%%%  %%%@          
+                     %%%%%%%%%%%%%%%%%%% %%%%%% %%                          %%%%%%%%%%%%%@          
+                                                                                 %%%%%%%@       
diff --git a/4-ShellP2/dsh b/4-ShellP2/dsh
new file mode 100755
index 0000000000000000000000000000000000000000..bc71f23f06921448398c90d8c8ef9609de2dbfd4
Binary files /dev/null and b/4-ShellP2/dsh differ
diff --git a/4-ShellP2/dsh_cli.c b/4-ShellP2/dsh_cli.c
new file mode 100644
index 0000000000000000000000000000000000000000..ef8029b132addbe6e3428c7547bfc37796e15669
--- /dev/null
+++ b/4-ShellP2/dsh_cli.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dshlib.h"
+
+/* DO NOT EDIT
+ * main() logic moved to exec_local_cmd_loop() in dshlib.c
+*/
+int main(){
+  int rc = exec_local_cmd_loop();
+  printf("cmd loop returned %d\n", rc);
+}
diff --git a/4-ShellP2/dshlib.c b/4-ShellP2/dshlib.c
new file mode 100644
index 0000000000000000000000000000000000000000..c168f6dc0858734439c9fa1cbd0fd50290b4fcea
--- /dev/null
+++ b/4-ShellP2/dshlib.c
@@ -0,0 +1,275 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include "dshlib.h"
+
+int numInstanceOf(char *str, const char c) {
+	int count = 0;
+	while (*str != '\0') {
+		if (*str == c) count++;
+		str++;
+	}
+	return count;
+}
+
+int alloc_cmd_buff(cmd_buff_t *cmd_buff) {
+	if (cmd_buff == NULL) {
+		return ERR_MEMORY;
+	}
+	cmd_buff->argc = 0;
+	
+	cmd_buff->argv = (char**)malloc(CMD_ARGV_MAX * sizeof(char *));
+	if (cmd_buff->argv == NULL) {
+    	free(cmd_buff);
+    	return ERR_MEMORY;
+	}
+
+	for (int i = 0; i < CMD_ARGV_MAX; i++) {
+        cmd_buff->argv[i] = (char *)malloc(ARG_MAX);
+        if (cmd_buff->argv[i] == NULL) {
+            for (int j = 0; j < i; j++) {
+                free(cmd_buff->argv[j]);
+            }
+            free(cmd_buff->argv);
+            return ERR_MEMORY;
+        }
+    }
+
+	cmd_buff->_cmd_buffer = (char *)malloc(SH_CMD_MAX);
+	if (cmd_buff->_cmd_buffer == NULL) {
+        free(cmd_buff->_cmd_buffer);
+		for (int i = 0; i < CMD_ARGV_MAX; i++) {
+            free(cmd_buff->argv[i]);
+        }
+        free(cmd_buff->argv);
+        return ERR_MEMORY;
+    }
+
+
+	return OK_EXIT;
+}
+
+int free_cmd_buff(cmd_buff_t *cmd_buff) {
+	free(cmd_buff->_cmd_buffer);
+	 
+	for (int i = 0; i < CMD_ARGV_MAX - 1; i++) free(cmd_buff->argv[i]);
+	free(cmd_buff);
+	return OK_EXIT;
+}
+
+int clear_cmd_buff(cmd_buff_t *cmd_buff) {
+	cmd_buff->argc = 0;
+	free(cmd_buff->_cmd_buffer);
+	
+	for (int i = 0; i < CMD_ARGV_MAX; i++) cmd_buff->argv[i] = NULL;
+	return OK_EXIT;
+}
+
+char* trim_whitespace(char *str) {
+	int start = 0;
+	while (isspace((unsigned char)str[start])) {
+		start++;
+	}
+
+  	int end = strlen(str) - 1;
+  	while (end > start && isspace((unsigned char)str[end])) {
+    	end--;
+  	}
+
+  	int j = 0;
+  	for (int i = start; i <= end; i++) {
+    	str[j++] = str[i];
+  	}
+  	str[j] = '\0';
+  	
+  	return str;
+}
+
+int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) {
+	if ((int)strlen(cmd_line) > SH_CMD_MAX) return ERR_CMD_OR_ARGS_TOO_BIG;
+
+	if ((int)strlen(cmd_line) == 0) return WARN_NO_CMDS;	
+	
+	cmd_buff->_cmd_buffer = strdup(trim_whitespace(cmd_line));
+	if (cmd_buff->_cmd_buffer == NULL) {
+		free(cmd_buff);
+		return ERR_MEMORY;
+	}
+	
+	char *token = cmd_buff->_cmd_buffer;
+	bool quotes = false;
+	char *p = NULL;
+
+	while (*token) {
+		if (*token == DOUBLE_QUOTE_CHAR) {
+			quotes = !quotes;
+			if (quotes) p = token + 1;
+			else *token = '\0';
+		} else if (!quotes && (*token == SPACE_CHAR || *token == '\t')) {
+			*token = '\0';
+
+			if (p != NULL) {
+				cmd_buff->argv[cmd_buff->argc++] = p;
+				p = NULL;
+			}
+		} else if (p == NULL) {
+			p = token;
+		}
+		token++;
+	}
+
+	if (p != NULL) cmd_buff->argv[cmd_buff->argc++] = p;
+
+	cmd_buff->argv[cmd_buff->argc] = NULL;
+	return OK_EXIT;
+}
+/*
+ * Implement your exec_local_cmd_loop function by building a loop that prompts the 
+ * user for input.  Use the SH_PROMPT constant from dshlib.h and then
+ * use fgets to accept user input.
+ * 
+ *      while(1){
+ *        printf("%s", SH_PROMPT);
+ *        if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
+ *           printf("\n");
+ *           break;
+ *        }
+ *        //remove the trailing \n from cmd_buff
+ *        cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
+ * 
+ *        //IMPLEMENT THE REST OF THE REQUIREMENTS
+ *      }
+ * 
+ *   Also, use the constants in the dshlib.h in this code.  
+ *      SH_CMD_MAX              maximum buffer size for user input
+ *      EXIT_CMD                constant that terminates the dsh program
+ *      SH_PROMPT               the shell prompt
+ *      OK                      the command was parsed properly
+ *      WARN_NO_CMDS            the user command was empty
+ *      ERR_TOO_MANY_COMMANDS   too many pipes used
+ *      ERR_MEMORY              dynamic memory management failure
+ * 
+ *   errors returned
+ *      OK                     No error
+ *      ERR_MEMORY             Dynamic memory management failure
+ *      WARN_NO_CMDS           No commands parsed
+ *      ERR_TOO_MANY_COMMANDS  too many pipes used
+ *   
+ *   console messages
+ *      CMD_WARN_NO_CMD        print on WARN_NO_CMDS
+ *      CMD_ERR_PIPE_LIMIT     print on ERR_TOO_MANY_COMMANDS
+ *      CMD_ERR_EXECUTE        print on execution failure of external command
+ * 
+ *  Standard Library Functions You Might Want To Consider Using (assignment 1+)
+ *      malloc(), free(), strlen(), fgets(), strcspn(), printf()
+ * 
+ *  Standard Library Functions You Might Want To Consider Using (assignment 2+)
+ *      fork(), execvp(), exit(), chdir()
+ */
+int exec_local_cmd_loop()
+{
+    char *cmd_buff = malloc(ARG_MAX * sizeof(char));
+	int rc = 0;
+    cmd_buff_t *cmd = malloc(CMD_ARGV_MAX * sizeof(char *));
+	
+	if ((rc = alloc_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+
+    // TODO IMPLEMENT MAIN LOOP
+	while(1){
+ 		printf("%s", SH_PROMPT);
+ 		if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
+ 			printf("\n");
+ 			break;
+ 		}
+ 		//remove the trailing \n from cmd_buff
+ 		cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
+
+ 		//IMPLEMENT THE REST OF THE REQUIREMENTS
+		if (strcmp(cmd_buff, EXIT_CMD) == 0) {
+            exit(rc);
+        }
+
+        if (strcmp(cmd_buff, "rc") == 0) {
+        	printf("%d\n", rc);
+			if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+			continue;
+		}
+
+        if (strcmp(cmd_buff, "\0") == 0) {
+            rc = WARN_NO_CMDS;
+            printf(CMD_WARN_NO_CMD);
+            //if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+            continue;
+        }
+		
+		// TODO IMPLEMENT parsing input to cmd_buff_t *cmd_buff
+		if ((rc = build_cmd_buff(cmd_buff, cmd)) != OK_EXIT) {
+            exit(rc);
+            rc = 0;
+    	}
+		/*
+		if (strcmp(cmd->argv[0], "echo") == 0) {
+			for (int i = 1; i < CMD_ARGV_MAX; i++) {
+				printf("%s ", cmd->argv[i]);
+			}
+			printf("\n");
+			if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+			continue;
+		}*/
+		
+		// TODO IMPLEMENT if built-in command, execute builtin logic for exit, cd (extra credit: dragon)
+		if (strcmp(cmd_buff, "dragon") == 0) {
+            print_dragon();
+            if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+            rc = 0;
+            continue;
+        }
+
+    	// the cd command should chdir to the provided directory; if no directory is provided, do nothing
+    	if (strcmp(cmd->argv[0], "cd") == 0) {
+			if (cmd->argc < 2) {
+				if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+				rc = 0;
+				continue;
+			}
+			if (chdir(cmd->argv[1]) != 0) {
+				perror("chdir failed");
+				rc = 1;
+			}
+			if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+			rc = 0;
+			continue;
+    	}
+
+    	// TODO IMPLEMENT if not built-in command, fork/exec as an external command
+    	// for example, if the user input is "ls -l", you would fork/exec the command "ls" with the arg "-l"
+    	pid_t pid = fork();
+    	if (pid < 0) {
+			printf("fork failed");
+			if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+			continue;
+    	} else if (pid == 0) {
+			execvp(cmd->argv[0], cmd->argv);
+			perror(CMD_ERR_EXECUTE);
+			exit(1);
+    	} else {
+			int status;
+			waitpid(pid, &status, 0);
+			if (WIFEXITED(status)) {
+				rc = WEXITSTATUS(status);
+			} else {
+				rc = 1;
+			}
+    	}
+		if ((rc = clear_cmd_buff(cmd)) != OK_EXIT) exit(rc);
+	}
+	free(cmd_buff);
+	free_cmd_buff(cmd);
+    return OK;
+}
diff --git a/4-ShellP2/dshlib.h b/4-ShellP2/dshlib.h
new file mode 100644
index 0000000000000000000000000000000000000000..df2f9a4d0061aee7f57b947ccba254178756c4b4
--- /dev/null
+++ b/4-ShellP2/dshlib.h
@@ -0,0 +1,85 @@
+#ifndef __DSHLIB_H__
+    #define __DSHLIB_H__
+
+
+//Constants for command structure sizes
+#define EXE_MAX 64
+#define ARG_MAX 256
+#define CMD_MAX 8
+#define CMD_ARGV_MAX (CMD_MAX + 1)
+// Longest command that can be read from the shell
+#define SH_CMD_MAX EXE_MAX + ARG_MAX
+
+typedef struct cmd_buff
+{
+    int  argc;
+    char **argv;
+    char *_cmd_buffer;
+} cmd_buff_t;
+
+/* WIP - Move to next assignment 
+#define N_ARG_MAX    15     //MAX number of args for a command
+typedef struct command{
+    char exe [EXE_MAX];
+    char args[ARG_MAX];
+    int  argc;
+    char *argv[N_ARG_MAX + 1];  //last argv[LAST] must be \0
+}command_t;
+*/
+
+
+//Special character #defines
+#define SPACE_CHAR  ' '
+#define SPACE_STRING " "
+#define PIPE_CHAR   '|'
+#define PIPE_STRING "|"
+#define DOUBLE_QUOTE_CHAR '"' 
+
+#define SH_PROMPT "dsh2> "
+#define EXIT_CMD "exit"
+
+//Standard Return Codes
+#define OK                       0
+#define WARN_NO_CMDS            -1
+#define ERR_TOO_MANY_COMMANDS   -2
+#define ERR_CMD_OR_ARGS_TOO_BIG -3
+#define ERR_CMD_ARGS_BAD        -4      //for extra credit
+#define ERR_MEMORY              -5
+#define ERR_EXEC_CMD            -6
+#define OK_EXIT                 -7
+
+//prototypes
+int alloc_cmd_buff();
+int free_cmd_buff(cmd_buff_t *);
+int clear_cmd_buff(cmd_buff_t *);
+int build_cmd_buff(char *, cmd_buff_t *);
+void exeCD(char *path);
+void execFork(char *);
+extern void print_dragon();
+
+//built in command stuff
+typedef enum {
+    BI_CMD_EXIT,
+    BI_CMD_DRAGON,
+    BI_CMD_CD,
+    BI_NOT_BI,
+    BI_EXECUTED,
+    BI_RC,
+} Built_In_Cmds;
+Built_In_Cmds match_command(const char *input); 
+Built_In_Cmds exec_built_in_cmd(cmd_buff_t *cmd);
+
+//main execution context
+int exec_local_cmd_loop();
+int exec_cmd(cmd_buff_t *cmd);
+
+
+
+
+//output constants
+#define CMD_OK_HEADER       "PARSED COMMAND LINE - TOTAL COMMANDS %d\n"
+#define CMD_WARN_NO_CMD     "warning: no commands provided\n"
+#define CMD_ERR_PIPE_LIMIT  "error: piping limited to %d commands\n"
+#define CMD_ERR_EXECUTE     "Command not found in PATH\n"
+
+#endif
diff --git a/4-ShellP2/makefile b/4-ShellP2/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a079ef4946ce8578836606ceab3f553b305b1875
--- /dev/null
+++ b/4-ShellP2/makefile
@@ -0,0 +1,31 @@
+# Compiler settings
+CC = gcc
+CFLAGS = -Wall -Wextra -g
+
+# Target executable name
+TARGET = dsh
+
+# Find all source and header files
+SRCS = $(wildcard *.c)
+HDRS = $(wildcard *.h)
+
+# Default target
+all: $(TARGET)
+
+# Compile source to executable
+$(TARGET): $(SRCS) $(HDRS)
+	$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
+
+# Clean up build files
+clean:
+	rm -f $(TARGET)
+
+test:
+	bats $(wildcard ./bats/*.sh)
+
+valgrind:
+	echo "pwd\nexit" | valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./$(TARGET) 
+	echo "pwd\nexit" | valgrind --tool=helgrind --error-exitcode=1 ./$(TARGET) 
+
+# Phony targets
+.PHONY: all clean test