X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2FCLIShell_src%2Fmain.c;h=6de92df42d99804328e83ec3cf86e74025ad2b8c;hb=13078002b01ee4f63eb2001d2ef479a2a006ea32;hp=836c6f50ec718f6ebc5860b7acbdbb19cb676bc4;hpb=95a7eaaa4a1065334125b65130866f8d1048ddb7;p=tpg%2Facess2.git diff --git a/Usermode/Applications/CLIShell_src/main.c b/Usermode/Applications/CLIShell_src/main.c index 836c6f50..6de92df4 100644 --- a/Usermode/Applications/CLIShell_src/main.c +++ b/Usermode/Applications/CLIShell_src/main.c @@ -1,19 +1,22 @@ /* * AcessOS Shell Version 3 */ +#define USE_READLINE 1 #include #include #include #include #include "header.h" +#include +#include +#include #define _stdin 0 #define _stdout 1 #define _stderr 2 // ==== PROTOTYPES ==== -char *ReadCommandLine(int *Length); -void Parse_Args(char *str, char **dest); + int Parse_Args(const char *str, char **dest); void CallCommand(char **Args); void Command_Logout(int argc, char **argv); void Command_Clear(int argc, char **argv); @@ -30,11 +33,11 @@ struct { {"help", Command_Help}, {"clear", Command_Clear}, {"cd", Command_Cd}, {"dir", Command_Dir} }; -static char *cDEFAULT_PATH[] = {"/Acess/Bin"}; +static char *cDEFAULT_PATH[] = {"/Acess/Bin","/Acess/SBin"}; #define BUILTIN_COUNT (sizeof(cBUILTINS)/sizeof(cBUILTINS[0])) // ==== LOCAL VARIABLES ==== - int giNumPathDirs = 1; + int giNumPathDirs = 2; char **gasPathDirs = cDEFAULT_PATH; char **gasEnvironment; char gsCommandBuffer[1024]; @@ -44,18 +47,17 @@ char **gasCommandHistory; int giCommandSpace = 0; // ==== CODE ==== -int main(int argc, char *argv[], char *envp[]) +int main(int argc, char *argv[], char **envp) { char *sCommandStr; char *saArgs[32] = {0}; - int length = 0; int i; int iArgCount = 0; - int bCached = 1; + tReadline *readline_state = Readline_Init(1); gasEnvironment = envp; - Command_Clear(0, NULL); +// Command_Clear(0, NULL); { char *tmp = getenv("CWD"); @@ -68,44 +70,25 @@ int main(int argc, char *argv[], char *envp[]) } } - write(_stdout, 22, "Acess Shell Version 3\n"); - write(_stdout, 2, "\n"); + printf("Acess Shell Version 3\n\n"); for(;;) { // Free last command & arguments - if(saArgs[0]) free(saArgs); - if(!bCached) free(sCommandStr); - bCached = 0; + if(saArgs[0]) free(saArgs[0]); - write(_stdout, strlen(gsCurrentDirectory), gsCurrentDirectory); - write(_stdout, 2, "$ "); + printf("%s$ ", gsCurrentDirectory); + fflush(stdout); // Read Command line - sCommandStr = ReadCommandLine( &length ); - - if(!sCommandStr) { - write(_stdout, 25, "PANIC: Out of heap space\n"); - return -1; - } - - // Check if the command should be cached - if(gasCommandHistory == NULL || strcmp(sCommandStr, gasCommandHistory[giLastCommand]) != 0) - { - if(giLastCommand >= giCommandSpace) { - giCommandSpace += 12; - gasCommandHistory = realloc(gasCommandHistory, giCommandSpace*sizeof(char*)); - } - giLastCommand ++; - gasCommandHistory[ giLastCommand ] = sCommandStr; - bCached = 1; + sCommandStr = Readline( readline_state ); + printf("\n"); + if( !sCommandStr ) { + perror("Readline"); + return 1; } // Parse Command Line into arguments - Parse_Args(sCommandStr, saArgs); - - // Count Arguments - iArgCount = 0; - while(saArgs[iArgCount]) iArgCount++; + iArgCount = Parse_Args(sCommandStr, saArgs); // Silently Ignore all empty commands if(saArgs[1][0] == '\0') continue; @@ -123,170 +106,24 @@ int main(int argc, char *argv[], char *envp[]) // Shall we? CallCommand( &saArgs[1] ); - } -} - -/** - * \fn char *ReadCommandLine(int *Length) - * \brief Read from the command line - */ -char *ReadCommandLine(int *Length) -{ - char *ret; - int len, pos, space = 1023; - char ch; - #if 1 - int scrollbackPos = giLastCommand; - #endif - - // Preset Variables - ret = malloc( space+1 ); - if(!ret) return NULL; - len = 0; pos = 0; - - // Read In Command Line - do { - read(_stdin, 1, &ch); // Read Character from stdin (read is a blocking call) - if(ch == '\n') break; - - switch(ch) - { - // Control characters - case '\x1B': - read(_stdin, 1, &ch); // Read control character - switch(ch) - { - //case 'D': if(pos) pos--; break; - //case 'C': if(pos 0 ) break; - - free(ret); - ret = strdup( gasCommandHistory[--scrollbackPos] ); - - len = strlen(ret); - while(pos--) write(_stdout, 3, "\x1B[D"); - write(_stdout, len, ret); pos = len; - while(pos++ < oldLen) write(_stdout, 1, " "); - } - break; - case 'B': // Down - { - int oldLen = len; - if( scrollbackPos < giLastCommand-1 ) break; - - free(ret); - ret = strdup( gasCommandHistory[++scrollbackPos] ); - - len = strlen(ret); - while(pos--) write(_stdout, 3, "\x1B[D"); - write(_stdout, len, ret); pos = len; - while(pos++ < oldLen) write(_stdout, 1, " "); - } - break; - #endif - case 'D': // Left - if(pos == 0) break; - pos --; - write(_stdout, 3, "\x1B[D"); - break; - case 'C': // Right - if(pos == len) break; - pos++; - write(_stdout, 3, "\x1B[C"); - break; - } - } - break; - - // Backspace - case '\b': - if(len <= 0) break; // Protect against underflows - write(_stdout, 1, &ch); - if(pos == len) { // Simple case of end of string - len --; - pos--; - } - else { - char buf[7] = "\x1B[000D"; - buf[2] += ((len-pos+1)/100) % 10; - buf[3] += ((len-pos+1)/10) % 10; - buf[4] += (len-pos+1) % 10; - write(_stdout, len-pos, &ret[pos]); // Move Text - ch = ' '; write(_stdout, 1, &ch); ch = '\b'; // Clear deleted character - write(_stdout, 7, buf); // Update Cursor - // Alter Buffer - memmove(&ret[pos-1], &ret[pos], len-pos); - pos --; - len --; - } - break; - - // Tab - case '\t': - //TODO: Implement Tab-Completion - //Currently just ignore tabs - break; - - default: - // Expand Buffer - if(len+1 > space) { - space += 256; - ret = realloc(ret, space+1); - if(!ret) return NULL; - } - - // Editing inside the buffer - if(pos != len) { - char buf[7] = "\x1B[000D"; - buf[2] += ((len-pos)/100) % 10; - buf[3] += ((len-pos)/10) % 10; - buf[4] += (len-pos) % 10; - write(_stdout, 1, &ch); // Print new character - write(_stdout, len-pos, &ret[pos]); // Move Text - write(_stdout, 7, buf); // Update Cursor - memmove( &ret[pos+1], &ret[pos], len-pos ); - } - else { - write(_stdout, 1, &ch); - } - ret[pos++] = ch; - len ++; - break; - } - } while(ch != '\n'); - - // Cap String - ret[len] = '\0'; - printf("\n"); - - // Return length - if(Length) *Length = len; - - return ret; + free( sCommandStr ); + } } /** - * \fn void Parse_Args(char *str, char **dest) + * \fn int Parse_Args(const char *str, char **dest) * \brief Parse a string into an argument array */ -void Parse_Args(char *str, char **dest) +int Parse_Args(const char *str, char **dest) { int i = 1; char *buf = malloc( strlen(str) + 1 ); if(buf == NULL) { dest[0] = NULL; - Print("Parse_Args: Out of heap space!\n"); - return ; + printf("Parse_Args: Out of heap space!\n"); + return 0; } strcpy(buf, str); @@ -313,10 +150,8 @@ void Parse_Args(char *str, char **dest) if(*buf == '\0') break; } dest[i] = NULL; - if(i == 1) { - free(buf); - dest[0] = NULL; - } + + return i; } /** @@ -337,20 +172,19 @@ void CallCommand(char **Args) { GeneratePath(exefile, gsCurrentDirectory, sTmpBuffer); // Check file existence - fd = open(sTmpBuffer, OPENFLAG_EXEC); + fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC); if(fd == -1) { - Print("Unknown Command: `");Print(Args[0]);Print("'\n"); // Error Message + printf("Unknown Command: `%s'\n", Args[0]); // Error Message return ; } // Get File info and close file - finfo( fd, &info, 0 ); - close( fd ); + _SysFInfo( fd, &info, 0 ); + _SysClose( fd ); // Check if the file is a directory if(info.flags & FILEFLAG_DIRECTORY) { - Print("`");Print(sTmpBuffer); // Error Message - Print("' is a directory.\n"); + printf("`%s' is a directory.\n", sTmpBuffer); return ; } } @@ -362,10 +196,10 @@ void CallCommand(char **Args) for( i = 0; i < giNumPathDirs; i++ ) { GeneratePath(exefile, gasPathDirs[i], sTmpBuffer); - fd = open(sTmpBuffer, OPENFLAG_EXEC); + fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC); if(fd == -1) continue; - finfo( fd, &info, 0 ); - close( fd ); + _SysFInfo( fd, &info, 0 ); + _SysClose( fd ); if(info.flags & FILEFLAG_DIRECTORY) continue; // Woohoo! We found a valid command break; @@ -373,22 +207,34 @@ void CallCommand(char **Args) // Exhausted path directories if( i == giNumPathDirs ) { - Print("Unknown Command: `");Print(exefile);Print("'\n"); + printf("Unknown Command: `%s'\n", exefile); return ; } } // Create new process - pid = clone(CLONE_VM, 0); - // Start Task - if(pid == 0) - execve(sTmpBuffer, Args, gasEnvironment); + int fds[] = {0, 1, 2}; + int status; + pid = _SysSpawn(sTmpBuffer, (const char **)Args, (const char **)gasEnvironment, 3, fds, NULL); if(pid <= 0) { - Print("Unablt to create process: `");Print(sTmpBuffer);Print("'\n"); // Error Message + printf("Unable to create process: `%s'\n", sTmpBuffer); // Error Message + status = 0; } else { - int status; - waittid(pid, &status); + _SysIOCtl(0, PTY_IOCTL_SETPGRP, &pid); + _SysWaitTID(pid, &status); + } + + // Return terminal to a sane state + { + int zero = 0; + _SysIOCtl(0, PTY_IOCTL_SETPGRP, &zero); + printf("\x1b[0m"); + } + // Print a status message if termination was non-clean + if( status ) + { + printf("[%i] exited %i\n", pid, status); } } @@ -407,17 +253,16 @@ void Command_Logout(int argc, char **argv) */ void Command_Help(int argc, char **argv) { - Print("Acess 2 Command Line Interface\n"); - Print(" By John Hodge (thePowersGang / [TPG])\n"); - Print("\n"); - Print("Builtin Commands:\n"); - Print(" logout: Return to the login prompt\n"); - Print(" exit: Same\n"); - Print(" help: Display this message\n"); - Print(" clear: Clear the screen\n"); - Print(" cd: Change the current directory\n"); - Print(" dir: Print the contents of the current directory\n"); - //Print("\n"); + printf( "Acess 2 Command Line Interface\n" + " By John Hodge (thePowersGang / [TPG])\n" + "\n" + "Builtin Commands:\n" + " logout: Return to the login prompt\n" + " exit: Same\n" + " help: Display this message\n" + " clear: Clear the screen\n" + " cd: Change the current directory\n" + " dir: Print the contents of the current directory\n"); return; } @@ -427,7 +272,7 @@ void Command_Help(int argc, char **argv) */ void Command_Clear(int argc, char **argv) { - write(_stdout, 4, "\x1B[2J"); //Clear Screen + _SysWrite(_stdout, "\x1B[2J", 4); //Clear Screen } /** @@ -442,22 +287,22 @@ void Command_Cd(int argc, char **argv) if(argc < 2) { - Print(gsCurrentDirectory);Print("\n"); + printf("%s\n", gsCurrentDirectory); return; } GeneratePath(argv[1], gsCurrentDirectory, tmpPath); - fp = open(tmpPath, 0); + fp = _SysOpen(tmpPath, 0); if(fp == -1) { - write(_stdout, 26, "Directory does not exist\n"); + printf("Directory does not exist\n"); return; } - finfo(fp, &stats, 0); - close(fp); + _SysFInfo(fp, &stats, 0); + _SysClose(fp); if( !(stats.flags & FILEFLAG_DIRECTORY) ) { - write(_stdout, 17, "Not a Directory\n"); + printf("Not a Directory\n"); return; } @@ -466,7 +311,7 @@ void Command_Cd(int argc, char **argv) strcpy(gsCurrentDirectory, tmpPath); // Register change with kernel - chdir( gsCurrentDirectory ); + _SysChdir( gsCurrentDirectory ); } /** @@ -475,115 +320,101 @@ void Command_Cd(int argc, char **argv) */ void Command_Dir(int argc, char **argv) { - int dp, fp, dirLen; + int dp, fp; char modeStr[11] = "RWXrwxRWX "; - char tmpPath[1024]; - char *fileName; + char fileName[256]; t_sysFInfo info; t_sysACL acl; + + // -- Generate and open directory -- // Generate Directory Path + char tmpPath[1024]; if(argc > 1) - dirLen = GeneratePath(argv[1], gsCurrentDirectory, tmpPath); + GeneratePath(argv[1], gsCurrentDirectory, tmpPath); else - { strcpy(tmpPath, gsCurrentDirectory); - } - dirLen = strlen(tmpPath); - // Open Directory - dp = open(tmpPath, OPENFLAG_READ); - // Check if file opened - if(dp == -1) - { + dp = _SysOpen(tmpPath, OPENFLAG_READ); + if(dp == -1) { printf("Unable to open directory `%s', File cannot be found\n", tmpPath); return; } // Get File Stats - if( finfo(dp, &info, 0) == -1 ) + if( _SysFInfo(dp, &info, 0) == -1 ) { - close(dp); - write(_stdout, 34, "stat Failed, Bad File Descriptor\n"); + _SysClose(dp); + printf("stat Failed, Bad File Descriptor\n"); return; } // Check if it's a directory if(!(info.flags & FILEFLAG_DIRECTORY)) { - close(dp); - write(_stdout, 27, "Unable to open directory `"); - write(_stdout, strlen(tmpPath)+1, tmpPath); - write(_stdout, 20, "', Not a directory\n"); + _SysClose(dp); + printf("Unable to open directory `%s', Not a directory\n", tmpPath); return; } - // Append Shash for file paths - if(tmpPath[dirLen-1] != '/') - { - tmpPath[dirLen++] = '/'; - tmpPath[dirLen] = '\0'; - } - - fileName = (char*)(tmpPath+dirLen); - // Read Directory Content - while( (fp = readdir(dp, fileName)) ) + // -- Read Directory Contents -- + while( (fp = _SysReadDir(dp, fileName)) ) { if(fp < 0) { if(fp == -3) - write(_stdout, 42, "Invalid Permissions to traverse directory\n"); + printf("Invalid Permissions to traverse directory\n"); break; } // Open File - fp = open(tmpPath, 0); + fp = _SysOpenChild(dp, fileName, 0); if(fp == -1) continue; // Get File Stats - finfo(fp, &info, 0); + _SysFInfo(fp, &info, 0); if(info.flags & FILEFLAG_DIRECTORY) - write(_stdout, 1, "d"); + printf("d"); else - write(_stdout, 1, "-"); + printf("-"); // Print Mode // - Owner - acl.group = 0; acl.id = info.uid; + acl.object = info.uid; _SysGetACL(fp, &acl); if(acl.perms & 1) modeStr[0] = 'r'; else modeStr[0] = '-'; if(acl.perms & 2) modeStr[1] = 'w'; else modeStr[1] = '-'; if(acl.perms & 8) modeStr[2] = 'x'; else modeStr[2] = '-'; // - Group - acl.group = 1; acl.id = info.gid; + acl.object = info.gid | 0x80000000; _SysGetACL(fp, &acl); if(acl.perms & 1) modeStr[3] = 'r'; else modeStr[3] = '-'; if(acl.perms & 2) modeStr[4] = 'w'; else modeStr[4] = '-'; if(acl.perms & 8) modeStr[5] = 'x'; else modeStr[5] = '-'; // - World - acl.group = 1; acl.id = -1; + acl.object = 0xFFFFFFFF; _SysGetACL(fp, &acl); if(acl.perms & 1) modeStr[6] = 'r'; else modeStr[6] = '-'; if(acl.perms & 2) modeStr[7] = 'w'; else modeStr[7] = '-'; if(acl.perms & 8) modeStr[8] = 'x'; else modeStr[8] = '-'; - write(_stdout, 10, modeStr); - close(fp); + printf(modeStr); + _SysClose(fp); // Colour Code if(info.flags & FILEFLAG_DIRECTORY) // Directory: Green - write(_stdout, 6, "\x1B[32m"); + printf("\x1B[32m"); // Default: White // Print Name - write(_stdout, strlen(fileName), fileName); + printf("%s", fileName); // Print slash if applicable if(info.flags & FILEFLAG_DIRECTORY) - write(_stdout, 1, "/"); + printf("/"); // Revert Colour - write(_stdout, 6, "\x1B[37m"); + printf("\x1B[37m"); // Newline! - write(_stdout, 1, "\n"); + printf("\n"); } // Close Directory - close(dp); + _SysClose(dp); }