// File: /workspace/github_cpp_makefile_star2_O2/sanaa-khan[P]mini-linux-shell/gbsh.cpp
// Function: main
int main(int argc, char *argv[]) {

	signal(SIGINT, handle_signal); // program will ignore ctrl+c

	int len = 50;
	char host[len], user[len], cwd[len];
	string command;

	gethostname(host, len);
	getlogin_r(user, len);

	while (true) {
		getcwd(cwd, len);
		cout << "\033[1;36m" << user << "@" << host << "\033[0m";
		cout << "\033[1;35m " << cwd << "\033[0m > ";
		
		getline(cin, command);

		if (command == "exit") {
			exit(0);
		}

		else if (command == "clear")
			cout << "\033c";

		// building vector of commands
		else {
			vector<string> tokens;
			string temp;

			for (int i = 0; i < command.size(); i++) {

				while (command[i] != ' ' and command[i] != '\n' and command[i] != '\t' and command[i] != '\0') {
					temp += command[i];
					i++;
				}

				tokens.push_back(temp);
				temp = "";
			}

			displayVector(tokens);

			string cmd = tokens.front();

			if (cmd == "ls")
				listDirectory(tokens);

			else if (cmd == "pwd")
				printWorkingDirectory(tokens);

			else if (cmd == "cd") 
				changeDirectory(tokens);

			else if (cmd == "environ")
				listEnvVars(tokens);

			else if (cmd == "setenv")
				setEnvVar(tokens);

			else if (cmd == "unsetenv")
				unsetEnvVar(tokens);

			else {
				bool background = false;

				// for background execution
				if (tokens[tokens.size() - 1].size() == 1 and tokens[tokens.size() - 1][0] == '&') {
					background = true;
					tokens.pop_back();
				}

				bool skip = false;

				/// detecting pipe
				for (int i = 0; i < tokens.size(); i++) {
					if (tokens[i].size() == 1 and tokens[i][0] == '|') {
						pipeCommands(tokens);
						skip = true;
					}
				}

				if (!skip) {
					pid_t pid = fork();

					if (pid > 0) { // parent process
						if (!background)
							waitpid(pid, 0, 0); // wait until child of pid is terminated

						if (oRedirect) { // redirect output back to stdout 
							fflush(stdout); 

							dup2(output, 1);
							close(output);

							oRedirect = false;
						}

						if (iRedirect) { // redirect input back to stdin
							fflush(stdin); 

							dup2(input, 0);
							close(input);

							iRedirect = false;
						}
					}

					else if (pid == 0) { // child process
						setenv("SHELL", cwd, 1);
						executeProgram(tokens);
					}

					else
						cout << "Fork unsuccessful";
				}
			}

			tokens.clear();

			pid_t anyChild = 1;

			while (anyChild > 0) { // reaping zombie processes (that may have been running in background previously)
				anyChild = waitpid(-1, 0, WNOHANG);
			}
		} 
	}

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
leaq -0x19(%rip), %rsi       # 0x243c
pushq $0x2
popq %rdi
callq 0x21b0
leaq 0x58(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x160(%rsp), %rbp
pushq $0x32
popq %rbx
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x2250
leaq 0x1e0(%rsp), %rdi
movq %rbx, %rsi
callq 0x22d0
leaq 0x28(%rsp), %rbx
movabsq $0x100000601, %r14      # imm = 0x100000601
leaq 0x10(%rsp), %r15
leaq 0xf8(%rsp), %r13
leaq 0x1a0(%rsp), %rdi
pushq $0x32
popq %rsi
callq 0x20b0
movq 0x4b01(%rip), %rdi      # 0x6fc8
leaq 0x2b52(%rip), %rsi      # 0x5020
callq 0x2170
movq %rax, %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x2170
movq %rax, %rdi
leaq 0x2b3b(%rip), %rsi      # 0x5028
callq 0x2170
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2170
movq %rax, %rdi
leaq 0x2b23(%rip), %rsi      # 0x502a
callq 0x2170
movq 0x4ab5(%rip), %rdi      # 0x6fc8
leaq 0x2b15(%rip), %rsi      # 0x502f
callq 0x2170
movq %rax, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x2170
movq %rax, %rdi
leaq 0x2aff(%rip), %rsi      # 0x5038
callq 0x2170
movq 0x4a9b(%rip), %rdi      # 0x6fe0
leaq 0x48(%rsp), %rsi
callq 0x2040
movq %rbp, %r12
leaq 0x48(%rsp), %rbp
movq %rbp, %rdi
leaq 0x2adf(%rip), %rsi      # 0x5040
callq 0x3d23
testb %al, %al
jne 0x298d
movq %rbp, %rdi
leaq 0x2acd(%rip), %rsi      # 0x5045
callq 0x3d23
testb %al, %al
je 0x259c
movq 0x4a40(%rip), %rdi      # 0x6fc8
leaq 0x2abc(%rip), %rsi      # 0x504b
callq 0x2170
movq %r12, %rbp
jmp 0x24b0
andq $0x0, 0x20(%rsp)
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
andq $0x0, 0x30(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movb $0x0, 0x38(%rsp)
xorl %ebp, %ebp
movslq %ebp, %rbp
cmpq %rbp, 0x50(%rsp)
jbe 0x260d
incq %rbp
movq 0x48(%rsp), %rax
movzbl -0x1(%rax,%rbp), %eax
cmpq $0x20, %rax
ja 0x25e4
btq %rax, %r14
jb 0x25f1
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2120
jmp 0x25cb
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3d30
movq %rbx, %rdi
leaq 0x2ac6(%rip), %rsi      # 0x50cc
callq 0x22f0
jmp 0x25c1
leaq 0x148(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
callq 0x3db8
movq %rbp, %rdi
callq 0x3d5c
movq %r13, %r12
movq %rbp, %rdi
callq 0x3e0c
movq 0x10(%rsp), %rsi
leaq 0x110(%rsp), %r13
movq %r13, %rdi
callq 0x2220
movq %r13, %rdi
leaq 0x29fc(%rip), %rsi      # 0x504e
callq 0x3d23
testb %al, %al
je 0x2681
movq %r12, %r13
movq %r12, %rdi
movq %r15, %rsi
callq 0x3db8
leaq 0x160(%rsp), %rbp
movq %r13, %rdi
callq 0x2a5c
movq %r13, %rdi
jmp 0x27a8
movq %r13, %rdi
leaq 0x29c6(%rip), %rsi      # 0x5051
callq 0x3d23
testb %al, %al
leaq 0x160(%rsp), %rbp
je 0x26c4
leaq 0xe0(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %r13
leaq 0xe0(%rsp), %r12
movq %r12, %rdi
callq 0x2dcf
jmp 0x27a5
movq %r13, %rdi
leaq 0x2987(%rip), %rsi      # 0x5055
callq 0x3d23
testb %al, %al
je 0x26ff
leaq 0xc8(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %r13
leaq 0xc8(%rsp), %r12
movq %r12, %rdi
callq 0x2f37
jmp 0x27a5
movq %r13, %rdi
leaq 0x294f(%rip), %rsi      # 0x5058
callq 0x3d23
testb %al, %al
je 0x2737
leaq 0xb0(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %r13
leaq 0xb0(%rsp), %r12
movq %r12, %rdi
callq 0x2ffa
jmp 0x27a5
movq %r13, %rdi
leaq 0x2921(%rip), %rsi      # 0x5062
callq 0x3d23
testb %al, %al
je 0x276f
leaq 0x98(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %r13
leaq 0x98(%rsp), %r12
movq %r12, %rdi
callq 0x320f
jmp 0x27a5
movq %r13, %rdi
leaq 0x28e7(%rip), %rsi      # 0x5060
callq 0x3d23
testb %al, %al
je 0x27ed
leaq 0x80(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %r13
leaq 0x80(%rsp), %r12
movq %r12, %rdi
callq 0x33cd
movq %r12, %rdi
callq 0x3e0c
movq %r15, %rdi
callq 0x3e2e
pushq $0x1
popq %rax
testl %eax, %eax
jle 0x27cb
pushq $-0x1
popq %rdi
xorl %esi, %esi
pushq $0x1
popq %rdx
callq 0x2110
jmp 0x27b8
leaq 0x110(%rsp), %rdi
callq 0x20a0
movq %rbx, %rdi
callq 0x20a0
movq %r15, %rdi
callq 0x3e0c
jmp 0x24b0
movq 0x18(%rsp), %rdi
cmpq $0x1, -0x18(%rdi)
jne 0x2824
movq 0x10(%rsp), %rax
movq %rdi, %rcx
subq %rax, %rcx
movq -0x20(%rax,%rcx), %rax
cmpb $0x26, (%rax)
jne 0x2824
addq $-0x20, %rdi
movq %rdi, 0x18(%rsp)
callq 0x20a0
movb $0x1, %al
movl %eax, 0xc(%rsp)
jmp 0x282c
movl $0x0, 0xc(%rsp)
xorl %esi, %esi
pushq $0x8
popq %rbp
xorl %eax, %eax
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %rdx
subq %rcx, %rdx
sarq $0x5, %rdx
cmpq %rsi, %rdx
jbe 0x288e
movq %rsi, %r13
cmpq $0x1, (%rcx,%rbp)
jne 0x2882
movq -0x8(%rcx,%rbp), %rcx
cmpb $0x7c, (%rcx)
jne 0x2882
leaq 0x130(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x3db8
movq %r12, %rdi
callq 0x3527
movq %r12, %rdi
callq 0x3e0c
movb $0x1, %al
movq %r13, %rsi
incq %rsi
addq $0x20, %rbp
jmp 0x2833
testb $0x1, %al
leaq 0xf8(%rsp), %r13
leaq 0x160(%rsp), %rbp
jne 0x27ad
callq 0x2050
testl %eax, %eax
jle 0x293d
cmpb $0x0, 0xc(%rsp)
jne 0x28c5
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2110
cmpb $0x1, 0x48e4(%rip)      # 0x71b0
jne 0x28fd
movq 0x46d3(%rip), %rax      # 0x6fa8
movq (%rax), %rdi
callq 0x21a0
movl 0x48c5(%rip), %edi      # 0x71a8
pushq $0x1
popq %rsi
callq 0x2150
movl 0x48b7(%rip), %edi      # 0x71a8
callq 0x2300
movb $0x0, 0x48b3(%rip)      # 0x71b0
cmpb $0x1, 0x48ad(%rip)      # 0x71b1
jne 0x27ad
movq 0x46af(%rip), %rax      # 0x6fc0
movq (%rax), %rdi
callq 0x21a0
movl 0x488d(%rip), %edi      # 0x71ac
xorl %esi, %esi
callq 0x2150
movl 0x4880(%rip), %edi      # 0x71ac
callq 0x2300
movb $0x0, 0x4879(%rip)      # 0x71b1
jmp 0x27ad
je 0x2957
movq 0x4682(%rip), %rdi      # 0x6fc8
leaq 0x2722(%rip), %rsi      # 0x506f
callq 0x2170
jmp 0x27ad
leaq 0x270b(%rip), %rdi      # 0x5069
leaq 0x1a0(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x2270
leaq 0x68(%rsp), %rdi
movq %r15, %rsi
callq 0x3db8
leaq 0x68(%rsp), %r12
movq %r12, %rdi
callq 0x363d
jmp 0x27a5
xorl %edi, %edi
callq 0x21c0
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
jmp 0x29fb
jmp 0x2a1f
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
jmp 0x29fb
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
jmp 0x29fb
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
jmp 0x29fb
jmp 0x2a1f
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
jmp 0x29fb
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
jmp 0x29fb
movq %rax, %rbx
leaq 0xe0(%rsp), %rdi
jmp 0x29fb
movq %rax, %rbx
leaq 0xf8(%rsp), %rdi
callq 0x3e0c
jmp 0x2a22
jmp 0x2a1f
jmp 0x2a33
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x3e0c
jmp 0x2a36
jmp 0x2a33
movq %rax, %rbx
jmp 0x2a4a
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x20a0
jmp 0x2a36
jmp 0x2a33
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x20a0
leaq 0x10(%rsp), %rdi
callq 0x3e0c
leaq 0x48(%rsp), %rdi
callq 0x20a0
movq %rbx, %rdi
callq 0x22e0