Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/wait.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <termios.h>
- #include <fcntl.h>
- #include <dirent.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <assert.h>
- #define BUFFERSIZE 4096
- char * history_path = "./history.log";
- int argument_count;
- int pipe_count;
- void display_error(char *, char *);
- int copyDir(char *src, char *dest);
- int copyFiles(char *src, char *dest);
- int dostat(char *filename);
- int mode_isReg(struct stat info);
- int custom_cd(char **args);
- int custom_cp(char **args);
- int custom_help(char **args);
- int custom_exit(char **args);
- int custom_version(char **args);
- int custom_pipe(char **args);
- int custom_mv(char **args);
- int custom_dirname(char **args);
- int custom_pipe(char **args);
- char *custom_Function_names[] = {
- "cd",
- "help",
- "exit",
- "version",
- "cp",
- "mv",
- "dirname"
- };
- int (*builtin_func[]) (char **) = {
- &custom_cd,
- &custom_help,
- &custom_exit,
- &custom_version,
- &custom_cp,
- &custom_mv,
- &custom_dirname
- };
- int builtin_function_count() {
- return sizeof(custom_Function_names) / sizeof(char *);
- }
- int custom_version(char ** args)
- {
- printf("Basic command interpretor:\n");
- printf("Proiect pentru disciplina \"Sisteme de Operare \":\n");
- printf("Echipa 11 : Gavra Andrei si Galbenu Dorin\n");
- return 1;
- }
- int custom_dirname(char **args)
- {
- int slash_index =-1,i;
- if(argument_count==2)
- {
- for(i=0;i<strlen(args[1]);i++)
- if(args[1][i]=='/')
- slash_index=i;
- if(slash_index==-1)
- printf(".");
- else
- {
- char* output_string = (char*)(malloc(strlen(args[1])));
- strcpy(output_string,args[1]);
- output_string[slash_index]=NULL;
- printf("%s ",output_string);
- }
- printf("\n");
- }
- else
- printf("Dirname function must receive 2 parameters");
- return 1;
- }
- int custom_mv(char **args)
- {
- if(argument_count < 3)
- {
- printf("Not enough argument passed to function \n");
- return 1;
- }
- char* source = args[1];
- char* destination = (char*)(malloc(sizeof(args[1])+sizeof(args[2])+1));
- strcpy(destination,args[2]);
- char* buf[2];
- int fd1,fd2,i;
- if(destination[0]=='/')
- {
- strcat(destination,"/");
- strcat(destination,source);
- }
- fd1=open(source,O_RDONLY,0777);
- fd2=creat(destination,S_IWUSR);
- while(i=read(fd1,buf,1)>0)
- {
- write(fd2,buf,1);
- }
- if(fd2!=-1)
- remove(source);
- close(fd1);
- close(fd2);
- return 1;
- }
- int custom_pipe(char **args) {
- const int commands = pipe_count + 1;
- int i = 0;
- int pipefds[2*pipe_count];
- for(i = 0; i < pipe_count; i++){
- if(pipe(pipefds + i*2) < 0) {
- perror("Couldn't Pipe");
- exit(EXIT_FAILURE);
- }
- }
- int pid;
- int status;
- int j = 0;
- int k = 0;
- int s = 1;
- int place;
- int commandStarts[10];
- commandStarts[0] = 0;
- while (args[k] != NULL){
- if(!strcmp(args[k], "|")){
- args[k] = NULL;
- commandStarts[s] = k+1;
- s++;
- }
- k++;
- }
- for (i = 0; i < commands; ++i) {
- place = commandStarts[i];
- pid = fork();
- if(pid == 0) {
- //if not last command
- if(i < pipe_count){
- if(dup2(pipefds[j + 1], 1) < 0){
- perror("dup2");
- exit(EXIT_FAILURE);
- }
- }
- //if not first command&& j!= 2*pipe_count
- if(j != 0 ){
- if(dup2(pipefds[j-2], 0) < 0){
- perror("dup2");
- exit(EXIT_FAILURE);
- }
- }
- int q;
- for(q = 0; q < 2*pipe_count; q++){
- close(pipefds[q]);
- }
- // The commands are executed here,
- if( execvp(args[place], args+place) < 0){
- perror(*args);
- exit(EXIT_FAILURE);
- }
- }
- else if(pid < 0){
- perror("error");
- exit(EXIT_FAILURE);
- }
- j+=2;
- }
- for(i = 0; i < 2 * pipe_count; i++){
- close(pipefds[i]);
- }
- for(i = 0; i < pipe_count + 1; i++){
- wait(&status);
- }
- }
- int custom_cp(char **args)
- {
- if(argument_count < 3)
- {
- printf("Not enough arguments passed to function \n");
- return 1;
- }
- char * src= args[1];
- char * dest = args[2];
- if( src[0] != '/' && dest[0] != '/' )//cp1 file1.txt file2.txt
- {
- copyFiles(src, dest);
- }
- else if( src[0] != '/' && dest[0] == '/' )
- {
- int i;
- for(i=1; i<=strlen(dest); i++)
- {
- dest[(i-1)] = dest[i];
- }
- strcat(dest, "/");
- strcat(dest, src);
- copyFiles(src, dest);
- }
- else if( src[0] == '/' && dest[0] == '/' )//cp1 /dir1 /dir2
- { //- copies all regular files from /dir1 to /dir2
- int i;
- for(i=1; i<=strlen(dest); i++)
- {
- dest[(i-1)] = dest[i];
- }
- for(i=1; i<=strlen(src); i++)
- {
- src[(i-1)] = src[i];
- }
- copyDir(src, dest);
- }
- return 1;
- }
- int custom_cd(char **args)
- {
- if (args[1] == NULL) {
- fprintf(stderr, "Eroare: Introduceti un argument pentru comanda \"cd\"\n");
- } else {
- if (chdir(args[1]) != 0) {
- perror("shell");
- }
- }
- return 1;
- }
- int custom_help(char **args)
- {
- int i;
- printf("Urmatoarele comenzi sunt implementate:\n");
- for (i = 0; i < builtin_function_count(); i++) {
- printf(" %s\n", custom_Function_names[i]);
- }
- printf("Folositi comanda \'man\' pentru informatii despre alte comenzi .\n");
- return 1;
- }
- int custom_exit(char **args)
- {
- write_history (history_path);
- return 0;
- }
- int launch_process(char **args)
- {
- pid_t pid, wpid;
- int command_result;
- pid = fork();
- if (pid == 0) {
- if (execvp(args[0], args) == -1) {
- perror("shell");
- }
- exit(EXIT_FAILURE);
- } else if (pid < 0) {
- perror("shell");
- } else {
- do {
- wpid = waitpid(pid, &
- command_result, WUNTRACED);
- } while (!WIFEXITED(
- command_result) && !WIFSIGNALED(
- command_result));
- }
- return 1;
- }
- int execute_command(char **args)
- {
- int i,j;
- if (args[0] == NULL) {
- return 1;
- }
- //Check if the command contains pipes and if so
- //Call the custom pipe function
- pipe_count=0;
- for(i=0;i<argument_count;i++)
- {
- for(j=0;j<strlen(args[i]);j++)
- if(args[i][j]=='|')
- {
- pipe_count++;
- }
- }
- if(pipe_count>0)
- {
- pipe_count++;
- return custom_pipe(args);
- }
- for (i = 0; i < builtin_function_count(); i++)
- if (strcmp(args[0], custom_Function_names[i]) == 0)
- { // read old history
- read_history (history_path);
- return (*builtin_func[i])(args);
- }
- return launch_process(args);
- }
- char *read_line(void)
- {
- char *line = NULL;
- ssize_t bufsize = 0;
- getline(&line, &bufsize, stdin);
- add_history(line);
- return line;
- }
- char **split_line(char *line)
- {
- int maximum_arguments = 32, pos = 0;
- char * separator = " \t\r\n\a";
- char **parameters = malloc(maximum_arguments * sizeof(char*));
- char *token;
- if (!parameters) {
- fprintf(stderr, "Eroare de alocare a memoriei \n");
- exit(EXIT_FAILURE);
- }
- token = strtok(line, separator);
- while (token != NULL) {
- parameters[pos++] = token;
- if (pos >= maximum_arguments) {
- fprintf(stderr, "Prea multe argumente au fost gasite in comanda. \n");
- exit(EXIT_FAILURE);
- }
- token = strtok(NULL, separator);
- }
- parameters[pos] = NULL;
- argument_count=pos;
- return parameters;
- }
- int copyDir(char *source, char *destination)
- {
- DIR *dir_ptr = NULL;
- struct dirent *direntp;
- char tempDest[strlen(destination)+1];
- char tempSrc[strlen(source)+1];
- strcat(destination, "/");
- strcat(source, "/");
- strcpy(tempDest, destination);
- strcpy(tempSrc, source);
- struct stat fileinfo;
- if( (dir_ptr = opendir(source)) == NULL )
- {
- fprintf(stderr, "cp1: cannot open %s for copying\n", source);
- return 0; // read old history
- }
- else
- {
- while( (direntp = readdir(dir_ptr)))
- {
- if(dostat(direntp->d_name))
- {
- strcat(tempDest, direntp->d_name);
- strcat(tempSrc, direntp->d_name);
- copyFiles(tempSrc, tempDest);
- strcpy(tempDest, destination);
- strcpy(tempSrc, source);
- }
- }
- closedir(dir_ptr);
- return 1;
- }
- }
- int dostat(char *filename)
- {
- struct stat fileInfo;
- //printf("Next File %s\n", filename);
- if(stat(filename, &fileInfo) >=0)
- if(S_ISREG(fileInfo.st_mode))
- return 1;
- else return 0;
- return 1;
- }
- int copyFiles(char *source, char *destination)
- {
- int in_fd, out_fd, n_chars;
- char buf[BUFFERSIZE];
- /* open files */
- if( (in_fd=open(source, O_RDONLY)) == -1 )
- {
- display_error("Cannot open ", source);
- }
- if( (out_fd=creat(destination, 0644)) == -1 )
- {
- display_error("Cannot creat ", destination);
- }
- /* copy files */
- while( (n_chars = read(in_fd, buf, BUFFERSIZE)) > 0 )
- {
- if( write(out_fd, buf, n_chars) != n_chars )
- {
- display_error("Write error to ", destination);
- }
- if( n_chars == -1 )
- {
- display_error("Read error from ", source);
- }
- }
- /* close files */
- if( close(in_fd) == -1 || close(out_fd) == -1 )
- {
- display_error("Error closing files", "");
- }
- return 1;
- }
- void display_error(char *s1, char *s2)
- {
- fprintf(stderr, "Error: %s ", s1);
- perror(s2);
- }
- void shell_loop()
- {
- char *line, *prompt;
- char **args;
- int status;
- // read old history
- read_history (history_path);
- do {
- prompt = malloc(1+strlen("$> "));
- strcpy(prompt, "$> ");
- line = readline(prompt);
- //add new commandline
- add_history(line);
- args = split_line(line);
- status = execute_command(args);
- free(line);
- free(args);
- }
- while (status);
- }
- int main(int argc, char **argv)
- {
- shell_loop();
- return EXIT_SUCCESS;
- }
Add Comment
Please, Sign In to add comment