/*******************************************************************/ /* OS Shell / /* By; Simon Foucher /* 360 223 197 /* /* Purpose: Unix OS shell / /* / /* / /*******************************************************************/ /*******************************************************************/ /* /* Includes /*******************************************************************/ #include #include #include #include /*******************************************************************/ /* /* Global variables: /* verbose: 1 = ON, 0 = OFF /* userprompt: User defined prompt display (can be modified /* using shell function PROMPT [VALUE]) /*******************************************************************/ int verbose = 0; //Global variable, 1=ON, 0=OFF char userprompt[] = ".$"; /* Functions /* /*******************************************************************/ /* Big help file / /* / /* Purpose: Displays help file when user inputs -H or HELP / /* / /* / /*******************************************************************/ void Help (void) { printf("Shell commands (ALL IN UPPER CASES):\n\n" " -H --Returns a help screen describing the execution syntax\n" " -V --Sets the shell in verbose mode\n\n" " SET VAR VALUE --put VALUE into the shell memory with the variable name VAR\n" " GET VAR --Display the value stored in VAR\n" " VER --Returns shell's programmer's name, info\n" " CLR --Clears the screen\n" " PROMPT VALUE --Permits user to customize prompt with the string in VALUE\n" " SCRIPT [*.txt]--Interpres the specified script file\n" " HELP --Display all the commands you defined in the shell\n" " VERBOSE ON/OFF--Toggles verbose mode on or off (VERBOSE ON = -V)\n" " EXIT --Terminates the shell (Return 1=error occured\n" " [ANY OTHER COMMAND] will be passed to the OS in lower cases\n\n"); } /*******************************************************************/ /* Small help file / /* /* Displayed when user fails to properly initialize shell / /* Purpose: tells user how to launch shell / /* / /*******************************************************************/ void help(void) { printf("\nTo launch the shell, type: \nmysh [parameter] [parameter]\n" " -v Launches shell in verbose mode\n" " -h Launches shell and displys help file\n"); } /*******************************************************************/ /* /* Shell /* /* Purpose: Interprets user commands and acts accordingly /* The commands are outlined in the 'Big Help file' function /* /*******************************************************************/ int shell(void) { char userinput[100]; //100 characters should be more than ennough to gather user input /*******************************************************************/ /* Here we will prepare memory space for the shell in a manner /* easily convertive to a "user adjustabe" value /* /* In the meantine, since the memory pointer we are using (memprt) /* is 8 bits, we will restrict memory to 255 characters (2^8) /* /* The memory data structure consists of a single string, containing /* "NAME1 VALUE1 NAME2 VALUE2 ETC..." /* /* By separating name and value by a space, we reduce the risk of an accidental /* collision when searching memory (For example, given a data structure like /* NAME1VALUE1NAME2VALUE2, a variable named "E1VA" would be found both at /* it's real location and partly in NAME1 and VALUE1 /* /* We will use varname and varvalue (both strings) as tokens containing the /* name of a user variable and its value. This will facilitate the searching process. /* /* memleft will keep track of how much memory is left in the shell /* and warn user when the shell is out of memory /*******************************************************************/ int memptr =0, memleft = 255; char proceed[3]; int i, j; //Will be used as a counter a few times char shellmemory[memleft]; char varname[30], varvalue[30]; char getlocation[100]; FILE *fp; /* file pointer */ /*******************************************************************/ /* /* The shell will be executing until the user types EXIT /* Implemented using exitshell (exit if exitshell = 0 /*******************************************************************/ int exitshell = 1; while(exitshell) { if(verbose)printf("\nPlease enter a command\n(-H or HELP to display help file)\n"); printf("%s ",userprompt); gets(userinput); //Command line interpreter: //First we extract the command, recycling the string varname i = 0; while(userinput[i] != ' ') { varname[i] = userinput[i]; i++; } varname[i] = '\0'; //Now varname contains the user command //**************************************SET***************************************************************** switch(varname) { case "SET": //First, we extract the new VARIABLE's name and store it into varname //If userinput = SET VARIABLE VALUE, i+4 points to the 1st letter of variable //We will transfer characters from the user input to varname until we hit a ' ' i = 0; while(userinput[i+4] != ' ') { varname[i] = userinput[i+4]; i++; } varname[i] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it //Then we extract the new VARIABLE's value and store it into varvalue //At this point, i points to the " " between VARIABLE and VALUE i++; //Now i points to the first element of the VALUE j = 0; //Because VARIABLE name has an arbitrary lenght, we'll use a second pointer for varvalue reset at 0 while(userinput[i+4] != '\0') { varvalue[j] = userinput[i+4]; i++; j++; } varvalue[j] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it //Perform a memory test to make sure that the variable name is not already taken if(strstr(shellmemory, varname)) { printf("ERROR: Variable name already taken. Please choose a different name\nOperation cancelled\n\n"); } else{ //Now we perform a memory test to ensure that there is ennough space to store new data // 'i' counted the lenght of varname and varvalue. When stored, they will take i+1 bits of space (1 for the space seperating variables) if(memleft - i > 0) { //Verbose mode prompt if(verbose) { printf("Are you sure you want to create a variable \nnamed: '%s' with value: '%s' to shell memory?\n" "(FYI, You have %d bits of memory left) [Y/N]", varname, varvalue, memleft); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { //First we enter the VARIABLE name into the shell memory i=0; while(varname[i] != '\0') { shellmemory[memptr] = varname[i]; i++; memptr++; } shellmemory[memptr] = ' '; //Add a space after variable name in memory memptr++; //Then we enter the variable's VALUE into the shell's memory i=0; while(varvalue[i] != '\0') { shellmemory[memptr] = varvalue[i]; i++; memptr++; } shellmemory[memptr] = ' '; //Add a space after variable name in memory memptr++; memleft = 255 - memptr; } }//End of if there was ennough memory else { printf("Operation cancelled => need %d bits of space and only %d left in shell memory.\n" "Delete variables of free more memory before proceeding\n", i, memleft); } }//End of variable name not already taken break;//End of case SET //**************************************GET******************************************************************** case "GET": //First, we extract the VARIABLE's name and store it into varname //If userinput = GET VARIABLE, i+4 points to the 1st letter of variable //We will transfer characters from the user input to varname until we hit a '\0' i = 0; while(userinput[i+4] != '\0') { varname[i] = userinput[i+4]; i++; } varname[i] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it //Verbose mode prompt if(verbose) { printf("Are you sure you want to read the value of '%s'?[Y/N]", varname); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { //strspn Returns a pointer to the first element of the VARIABLE's name //By adding 'i' (=varname's lenght + NULL), we are pointing at the value j = strcspn(shellmemory, varname) + i + 1; // 'j' points at the start of the value. The following code will extract and display that value i = 0; while(shellmemory[j] != ' ') { varvalue[i] = shellmemory[j]; i++; j++; } varvalue[i] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it printf("The variable '%s' has a value of '%s'\n", varname, varvalue); } break;//End of GET operation //**************************************EXIT******************************************************************* case "EXIT": if(verbose) { printf("Are you sure you want to quit? [Y/N]\n"); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { printf("Thank you for using the shell.\nExiting Shell\n\n"); exitshell = !strstr(userinput, "EXIT"); //exitshell=0 if user typed 'EXIT' } break; //**************************************HELP******************************************************************* if(strstr(userinput, "-H") || strstr(userinput, "HELP")) { if(verbose) { printf("Are you sure you want display help file? [Y/N]\n"); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { Help(); } } //**************************************VERBOSE MODE*********************************************************** if(strstr(userinput, "-V") || strstr(userinput, "VERBOSE ON")) //Verbose mode is turned on { if(verbose)printf("The shell is already in verbose mode\n\n"); else { verbose = 1; printf("Shell is now in Verbose mode\n\n"); } } if(strstr(userinput, "VERBOSE OFF")) //Verbose mode is turned off { if(verbose) { printf("Are you sure you want turn off verbose mode?\nYou won't get these helpfull prompts anymore [Y/N]\n"); gets(proceed); if(strstr(proceed, "Y")) { verbose = 0; printf("Verbose mode turned OFF\n\n"); } } else//Verbose was already turned off { printf("Verbose mode was already turned off\n\n"); } } //**************************************VERSION***************************************************************** if(strstr(userinput, "VER") && userinput[3] == '\0') //To avoid launching VER if VERBOSE is typed { if(verbose) { printf("Are you sure you want display Shell info? [Y/N]\n"); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { printf("\n\nOS Shell ver 1.01beta\n" "Created on 2008.09.25\n" "By Simon Foucher\n\n"); } } //**************************************CLEAR SCREEN************************************************************ if(strstr(userinput, "CLR")) { if(verbose) { printf("Are you sure you want to clear screen?\n(Unsaved data will be permanently lost)[Y/N]"); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { clrscr(); } } //**************************************EDIT USER PROMPT******************************************************** if(strstr(userinput, "PROMPT")) { i = 6; while(userinput[i] != '\0') { varname[i-7] = userinput[i]; i++; } varname[i-7] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it if(verbose) { printf("Are you sure you want to change the prompt\nfrom '%s' to '%s'? [Y/N]", userprompt, varname); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { strcpy(userprompt, varname); } } //**************************************SCRIPT TEXT FILE******************************************************** if(strstr(userinput, "SCRIPT")) { i = 6; while(userinput[i] != '\0') { varname[i-7] = userinput[i]; i++; } varname[i-7] = '\0'; //Since the loop breaks b4 null is transfered, we manually enter it if(verbose) { printf("Are you sure you want to script file '%s'[Y/N]", varname); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { /* open file for output */ if ((fp = fopen("varname", "w"))==NULL) { printf("Cannot open file \n"); } //fp points to the start of the text file fclose(fp); } } //**************************************SYSTEM CALLS*********************************************************** else //The user input was not recognised by the command line interpreter; it will pass it to OS { if(verbose) { printf("Are you sure you want to call the OS for the command '%s'? [Y/N]", userinput); gets(proceed); } if(!verbose || strstr(proceed, "Y")) { printf("Calling the OS"); system(userinput); } } }//End of the switch //************************************************************************************************************** //While EXIT!=1, loop back to top of shell } return 0; } int main() { char launchinput[300]; gets(launchinput); /*Get shell launch command*/ int launch, hlp, ver; if(strstr(launchinput, "mysh")) //Shell is launched { printf("Loading shell\n"); if(strstr(launchinput, "-h")) //user typed -h; help is displayed { help(); } if(strstr(launchinput, "-v")){ //Verbose mode is turned on verbose = 1; //Global boolean variable to keep track of verbose mode printf("[Verbose mode = ON]"); } shell(); } else { //Help file displayed and error code returned printf("INVALID ENTRY\n\n"); help(); return(1); } return (0); }