/* * Copyright 2011 Marian Ohligs, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #include #include #include void showlogo() { printf("\n\n"); printf("================================================================================\n"); printf(" m(etalsvm)shell\n\n"); printf("================================================================================\n"); } void help() { printf("shell builtin commands: \n"); printf("cd :\t change current working directory to path\n"); printf("pwd :\t show current working directory\n"); printf("cat :\t print files\n"); printf("ls :\t list directory entrys in pwd\n"); printf("help :\t this short help\n"); printf("exit :\t exit the shell \n"); } #define MAXARGS 16 #define MAXPATH 128 #define MAXCMDLINE 1024 #define ST_WHITE 0 #define ST_ARG 1 #define ST_QUOTE 2 #define USE_STAT 1 char** splitargs(char* args) { static char* ret[MAXARGS+1]; int i = 0; int state = ST_WHITE; while (*args != '\0') { if (state == ST_WHITE) { if (!isspace(*args)) { if(*args == '"') { args++; state = ST_QUOTE; if (*args == '\0') break; } else { state = ST_ARG; } ret[i++] = args; if (i == MAXARGS) break; } } else { if ((state == ST_QUOTE && *args == '"') || isspace(*args)) { *args = '\0'; state = ST_WHITE; } } args++; } ret[i] = NULL; return ret; } char* ms_getcwd() { return getenv("PWD"); } void ms_setcwd(char* path) { static char newpath[MAXPATH]; static struct stat stats; if (path == NULL) return; if (*path == NULL) return; if (*path == '/') { strcpy(newpath, path); } else { char* oldpath = ms_getcwd(); if(oldpath[strlen(oldpath)-1] == '/') sprintf(newpath,"%s%s", oldpath, path); else sprintf(newpath,"%s/%s", oldpath, path); } #if USE_STAT if (stat(newpath, &stats)) { printf("mshell: %s is not a valid path\n XY", newpath); return; } if (!S_ISDIR(stats.st_mode)) { printf("mshell: %s is not a directory\n", newpath); return; } #endif setenv("PWD", newpath, 1); } int ms_cat(char* filename) { int fd, r = 0; char* buffer = malloc(1024*sizeof(char)); fd = open(filename, 0, "wr"); if (fd < 0) { printf("cat: No such file or directory"); printf("\n"); return -1; } do { r = read(fd, buffer, 1024); write(1, buffer, r); } while (r > 0); printf("\n"); close(fd); return 0; } int ms_ls() { DIR* dir; dirent_t* dirent; char* dirname = malloc(sizeof(char)*1024); strcpy(dirname, ms_getcwd()); dir = opendir(dirname); if (dir < 1) { printf("ls: No such file or directory"); printf("\n"); return -1; } do { dirent = readdir(dir); if (dirent == NULL) break; printf("%s", dirent->d_name); printf("\n"); } while (dirent != NULL); closedir(dir); return 0; } int main(int argc, char** argv) { char commandline[MAXCMDLINE]; char* command; int status = 0; pid_t pid; system("clear"); showlogo(); while(1) { char** newargv; printf("mshell> "); gets(commandline); newargv = splitargs(commandline); command = newargv[0]; if(command == NULL) { continue; } if(!strcmp(command, "exit")) { return 0; } if(!strcmp(command, "help")) { help(); } else if (!strcmp(command, "pwd")) { printf("%s\n", ms_getcwd()); } else if (!strcmp(command, "cd")) { ms_setcwd(newargv[1]); } else if (!strcmp(command, "cat")) { ms_cat(newargv[1]); } else if (!strcmp(command, "ls")) { ms_ls(); } else { char path[MAXPATH]; sprintf(path, "/bin/%s", command); pid = fork(); if (pid == 0) { //child status = execve(path, newargv, environ); if (status) printf("mshell: %s: command not found\n", path); return errno; } else { wait(&status); } } } return errno; }