//level1.c /* Author: William P. Henry Jr. Name: level1.c Class: CS 360 Started: Fall 2006 Updated: November 21, 2006 */ #define FILE_SYSTEM_LOCAL #include "fileSystemGlobals.h" //sets up "cwd" node reference for the path stuff #define DIRECTORY_LOCAL #include "directoryGlobals.h" //places globals for the path in this main file #define PATH_LOCAL #include "pathGlobals.h" #include "pathProcessing.h" //contains static global variable for operations //including a string table for commands #define COMMAND_LOCAL #include "commandGlobals.h" #include "commandProcessing.h" //lseek, write, close, read #include //malloc, free #include #include "type.h" #include "super.h" #include "gd.h" #include "bmap.h" #include "imap.h" #include "inode.h" #include "dir.h" #include "block.h" #include "util.h" #include "alloc_dealloc.h" //initialize array of recognized commands (global from //the commandGlobals.h file change the size there if you //make any additions or removals here */ const char *cmd[] = {"mkdir", "rmdir", "ls", "cd", "pwd", "creat", "rm", "quit", "help", "?", "menu", "reload", "echo", "exit", 0}; //full list of enums kept in program to preserve //concepts from legacy code (lab 1) enum commandEnums {MKDIR = 0, RMDIR, LS, CD, PWD, CREAT, RM, QUIT, HELP, QUESTION, MENU, RELOAD, ECHO, EXIT }; int main(int argc,char** argv, char** env) { //need program name and file system to mount //otherwise, return if(argc != 2) { printf("\nusage: \"level1 \"\n\n"); return -1; }//end if inappropriate arguments //initialize globals for file system if(0==initFileSystemGlobals(argv[1])) { printf("initialized!\n"); }//end if initialized else { printf("not initialized. quitting.\n"); return -1; }//end if error //************************************************************** //****************BEGIN RUNNING CODE SECTION******************** //************************************************************** // int i; /* for(i=0;i<15;++i) { printf("index %u is %s\n",i,cmd[i]); } */ printf("\n*************BEGIN LEVEL1.C MAIN****************\n"); //CREATE PROGRAM-LOCAL VARIABLES int ID = 0; char* fullInputString = malloc(256*(sizeof(char))); char* command = malloc(256*(sizeof(char))); char* arguments = malloc(256*(sizeof(char))); char localBuf[256]; //used for getting content from strtok without //obliterating areas, follow up strok with strcpy //using this variable char* tmpCharPtr=0; //used in child process char* fullCmd = malloc(256*(sizeof(char))); char* fullFilePath = malloc(256*(sizeof(char))); // printf("address of fullFilePath 0x%x\n",(&(fullFilePath))); // printf("address of fullInputString 0x%x\n",(&(fullInputString))); // printf("address of command 0x%x\n",(&(command))); // printf("address of fullCmd 0x%x\n",(&(fullCmd))); // printf("address of arguments 0x%x\n",(&(arguments))); //do I need these? // int pid = 0; // int retval = 0; // int status = 0; //MAIN PROCESSING LOOP* while(1) { //PROMPT, THEN PROCESS LINE INPUT printf("wphix $: "); fgets(inputLine, 256, stdin); //copy the full input string for use passing into //other functions, overwrite the final '\n' //leftover from user hitting "enter" strcpy(fullInputString, inputLine); fullInputString[strlen(fullInputString)-1] = '\0'; inputLine[strlen(inputLine)-1] = '\0'; //get command, don't obliterate heap memory //SCOTT--ORIGINALLY THIS WAS command=strtok(inputLine, " "); tmpCharPtr = strtok(inputLine, " "); if(0 == tmpCharPtr) { strcpy(command,""); }//end if else { strcpy(command,tmpCharPtr); }//end else //SCOTT--ORIGINALLY THIS WAS command=strtok(0, "\n"); //get args to command, don't obliterate heap memory tmpCharPtr = strtok(0, "\n"); if(0 == tmpCharPtr) { strcpy(arguments,""); }//end if else { strcpy(arguments,tmpCharPtr); }//end else //*COMMAND PROCESSING: IF CAN HANDLE LOCALLY, DO SO* //returns values as enumerated above ID = findCmd(command); switch(ID) { case(MKDIR): printf("in case <>. not implemented.\n"); break; case(RMDIR): printf("in case <>. not implemented.\n"); break; case(LS): printf("in case <>. not implemented.\n"); break; case(CD): printf("in case <>. not implemented.\n"); //printf("found %s at index %d\n", cmd[ID], ID); //if( 0 == arguments ) //{ //printf("no argument given for cd\n"); // chdir(homeBuf); // localBuf[0]='\0'; // if( 0 == getcwd(localBuf, 256) ) // { // printf("getcwd(localBuf, 256) failed\n"); // }//end if // else // { // printf("PWD is: %s\n", localBuf); // }//end else (so getcwd worked) //}//end if no arguments are passed //else if( 0 == chdir( arguments ) ) //{ //printf("was given %s to change to\n", arguments); // localBuf[0]='\0'; // if( 0 == getcwd(localBuf, 256) ) // { // printf("getcwd(localBuf, 256) failed\n"); // }//end if // else // { // printf("PWD is: %s\n", localBuf); // }//end else (so getcwd worked) //}//end if worked, print blah //else //{ // printf("%s isn't a recognized directory\n", arguments); //}//else failed to chdir break; case(PWD): printf("in case <>. not implemented.\n"); break; case(CREAT): printf("in case <>. not implemented.\n"); break; case(RM): printf("in case <>. not implemented.\n"); break; case(QUIT): printf("quitting\n"); //using goto to handle freeing of malloc'ed stuff goto quitCleanUp; break; case(QUESTION): printf("in case <>. not implemented.\n"); break; case(MENU): printf("in case <>. not implemented.\n"); break; case(RELOAD): printf("in case <>. not implemented.\n"); break; case(ECHO): if( 0 == arguments ) { printf("\n"); }//end if null else { printf("%s\n", arguments); }//end else print args break; case(EXIT): printf("exiting\n"); free(fullFilePath); free(fullInputString); free(command); free(arguments); // free(fullCmd); exit(0); break; //*COMMAND PROCESSING: MAKE A SYSTEM CALL TO HANDLE THINGS I CAN'T default: { //I HATE THAT THIS HAS TO BE HERE...BUT THE CODE WON'T //COMPILE WITHOUT THIS //***IT IS A KNOWN BUG FOR GCC (I FILED A BUG REPORT //WITH THEM AND THEY TOLD ME IT WAS BEING WORKED ON)*** //arguments to pass in to new function //pointers will point to memory in parent that //will not be modified during child's execution printf("IN THE DEFAULT CASE!!\n"); printf("IMPLEMENT WHATEVER IT IS YOU "); printf("ASKED FOR.\n"); /* char *myArgv[64]; //-***********COPY ARGUMENTS INTO NEW ARGV************* //using fullInputString, tokenized, as the argv's to pass in int counter = 0; myArgv[counter] = (char*)strtok( fullInputString, " " ); do { //strtok returns null on last call, so the //index past the last valid path will hold zero myArgv[++counter] = (char*)strtok( NULL , " " ); }//end while return not null while( 0 != myArgv[counter] ); //-************FORK********************* printf("parent mysh with PID:%d forks child\n", getpid()); pid = fork(); if(0 == pid) { //CHILD printf("in child\n"); //-see if argv[1] is "<", ">" or ">>" //-if argv[2] is absolute, try opening the file //-else iteratively try creating its path from //the pathPointers stuff (fullFilePath will hold //the file path) //used for call to "close" int fileDesToClose=0; //a decision below relies on this being -1 to start with int openedFile=-1; //treated as a boolean int needToOpenFile=0; //used for the flags for the call to open int my_oflags; printf("before checks\n"); //-*****CHECK FOR <, >, OR >> ***** //and set variables if they are found if( 0 != myArgv[1] ) { if( 0 == strcmp("<", myArgv[1]) ) { // printf("compare for \"<\"\n"); //close stdin fileDesToClose=0; needToOpenFile=1; my_oflags=O_RDONLY; }//end if is input else if( 0 == strcmp(">", myArgv[1]) ) { // printf("compare for \">\"\n"); //close stdout fileDesToClose=1; needToOpenFile=1; my_oflags=O_WRONLY|O_CREAT|O_TRUNC; }//end else if is output else if( 0 == strcmp(">>", myArgv[1]) ) { // printf("compare for \">>\"\n"); //close stdout but will use concatenation fileDesToClose=1; needToOpenFile=1; my_oflags=O_WRONLY|O_CREAT|O_APPEND; }//end else if is output with concatenation }//end if there is a myargv[1] printf("needToOpenFile holds %d\n", needToOpenFile); if( 1 == needToOpenFile ) { printf("need to open file...\n"); close(fileDesToClose); if( isAbsolute(myArgv[2]) ) { // printf("file to open is abs path\n"); if( -1 == open(myArgv[2],my_oflags) ) { // printf("open %s failed\n", myArgv[2]); exit(2); }//end if failed }//end if is absolute else { printf("file to open is NOT abs path\n"); int idx = 0; do { fullFilePath[0]='\0'; strcpy(fullFilePath,pathPointers[idx]); strcat(fullFilePath,"/"); strcat(fullFilePath, myArgv[2]); // printf("trying %s, ", fullFilePath); openedFile = open(fullFilePath, my_oflags); if( -1 != openedFile ) { // printf("file was opened\n"); }//if file was opened else { // printf("file not opened\n"); ++idx; } }//end do while( 0 != pathPointers[idx] && -1 == openedFile ); printf("\n"); //try to open a file in the pwd if( -1 == openedFile ) { // printf("trying to open in pwd\n"); fullFilePath[0]='\0'; strcpy(fullFilePath,getenv("PWD")); strcat(fullFilePath,"/"); strcat(fullFilePath, myArgv[2]); // printf("trying %s, ", fullFilePath); openedFile = open(fullFilePath, my_oflags); }//end if -1 = openedFile try to open from pwd if( -1 == openedFile ) { printf("after all efforts, file not opened\n"); exit(3); }//end if file not opened else { //should I iterate through it all //and copy stuff down? or just leave //it as it is and put a "zero" at the //appropriate index? myArgv[1] = 0; }//end else file was opened, so modify argv[1] }//end else is not absolute }//end if need to open file //if path is absolute, pass it as argument //if path is relative, rebuild path from cwd if( isAbsolute(command) ) { if( -1 == execve(command, myArgv, env) ) { printf("attempt to run \"%s\" failed\n", command); exit(2); }//end if }//end if is absolute path else { int num = 0; do { fullCmd[0]='\0'; strcpy(fullCmd,pathPointers[num]); strcat(fullCmd,"/"); strcat(fullCmd, command); // printf("trying %s, ", fullCmd); execve(fullCmd, myArgv, env); ++num; }//end do while( 0 != pathPointers[num] ); printf("\n"); }//end else is relative exit(3); }//end if zero is pid, so in child else { //PARENT retval = waitpid(pid, &status, 0); printf("in parent\n"); if( WIFEXITED(status) ) { printf("child pid:%d exited normally\n", pid); printf("with exit status:%d\n", WEXITSTATUS(status)); if( retval != pid ) { printf("and waitpid's retval:%d\n", retval); }//end if inequal retval and pid }//end if exited normally }//end else */ break; //I HATE THAT THIS HAS TO BE HERE, AND I HAVE NO IDEA WHY, //BUT AFTER I DOWNLOADED A NEW COMPILER VERSION IT GAVE //ME THE STRANGEST ERROR ON CODE THAT HAD BEEN WORKING //SO I MESSED WITH IT AND FINALLY FOUND THE PROBLEM BY //PUTTING CURLY BRACES AROUND THE CODE BLOCK //***IT IS A KNOWN BUG FOR GCC (I FILED A BUG REPORT //WITH THEM AND THEY TOLD ME IT WAS BEING WORKED ON)*** }//end default block }//end switch }//end while loop quitCleanUp: // printf("address of fullFilePath 0x%x\n",(&(fullFilePath))); free(fullFilePath); // printf("address of fullInputString 0x%x\n",(&(fullInputString))); free(fullInputString); // printf("address of command 0x%x\n",(&(command))); free(command); // printf("address of fullCmd 0x%x\n",(&(fullCmd))); free(fullCmd); // printf("arguments: %s\n", arguments); // printf("address of arguments 0x%x\n",(&(arguments))); free(arguments); printf("**************END LEVEL1.C MAIN*****************\n\n"); //************************************************************** //******************END RUNNING CODE SECTION******************** //************************************************************** return 0; }//end main