Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Authors:
- Laura Manninen and Joni Suomalainen
- 27.11.2015 */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <unistd.h>
- #include <limits.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <glob.h>
- #include <unistd.h>
- #include <ctype.h>
- #define LOGOUT 100
- #define MAXNUM 40
- #define MAXLEN 160
- #define die(msg) do {perror(msg); exit(EXIT_FAILURE);} while (0);
- void sighandler(int sig)
- {
- switch (sig) {
- case SIGALRM:
- printf("\nautologout\n");
- exit(0);
- default:
- break;
- }
- return;
- }
- /*reding history file*/
- void histRead(char* currentdir){
- char* line;
- size_t len = 0;
- ssize_t read;
- int id = 1;
- FILE *filee;
- filee = fopen(currentdir, "r");
- while((read = getline(&line, &len, filee)) != -1) {
- printf("%d %s", id, line);
- id ++;
- }
- fclose(filee);
- }
- /*Reads specified command from history*/
- char* historynum(int i, char* currentdir) {
- char* line;
- size_t len = 0;
- ssize_t read;
- int j = 1;
- char * cmd;
- int pid;
- FILE *file2;
- file2 = fopen(currentdir, "r");
- while((read = getline(&line, &len, file2)) != -1) {
- if (i==j) {
- printf("%s", line);
- cmd = line;
- break;
- }
- else {
- j++;
- }
- }
- fclose(file2);
- return cmd;
- }
- int main(void)
- {
- char * cmd, line[MAXLEN], * args[MAXNUM];
- int background;
- int i = 0;
- int pid;
- char buff[PATH_MAX + 1];
- char* cwd;
- char buf[512];
- char* histline;
- int cmd_in = 0;
- FILE *f;
- signal(SIGALRM, sighandler);
- signal(SIGINT, sighandler);
- char currentdir[1234];
- if ((getcwd(currentdir, sizeof(currentdir)) != NULL))
- strcat(currentdir, "/history.txt");
- while (1) {
- int argc = i;
- int k = 0;
- int output_mode = 0;
- int input_mode = 0;
- char input[MAXNUM];
- char output[MAXNUM];
- char pipeput[MAXNUM];
- background = 0;
- cwd = getcwd(buff, PATH_MAX + 1);
- /* print the prompt */
- if (cwd != NULL) {
- printf("%s ", cwd);
- };
- /* set the timeout for alarm signal (autologout) */
- alarm(LOGOUT);
- /* read the users command */
- if (fgets(line,MAXLEN,stdin) == NULL) {
- printf("\nlogout\n");
- exit(0);
- }
- line[strlen(line) - 1] = '\0';
- if (strlen(line) == 0)
- continue;
- /* start to background? */
- if (line[strlen(line)-1] == '&') {
- line[strlen(line)-1] = 0;
- background = 1;
- }
- /* write history log */
- if (strlen(line) != 0) {
- FILE* file3 = fopen(currentdir, "a");
- fprintf(file3, "%s\n", line);
- fclose(file3);
- }
- /*check if there is pipe and splits the command line */
- i = 0;
- cmd = line;
- if((strchr(line, '|'))!=NULL){
- while ( (args[i] = strtok(cmd, "|")) != NULL) {
- i++;
- cmd = NULL;
- //break;
- }
- args[0][strlen(args[0]) - 1] = '\0';
- args[1] = args[1] + 1;
- printf("arg 0: %s\n", args[0]);
- printf("arg 1: %s\n", args[1]);
- FILE *pipein, *pipeout;
- char readbuf[80];
- /* PIPE with popen */
- pipein = popen(args[0], "r");
- pipeout = popen(args[1], "w");
- while(fgets(readbuf, 80, pipein)){
- fputs(readbuf, pipeout);
- }
- pclose(pipein);
- pclose(pipeout);
- continue;
- }
- else{
- while ( (args[i] = strtok(cmd, " ")) != NULL) {
- printf("arg %d: %s\n", i, args[i]);
- i++;
- cmd = NULL;
- }
- }
- int cmd_in = 0;
- /*executes the specified command from history again*/
- if (strlen(args[0]) >= 2 && args[0][0] == '!' && atoi(args[0]+1)) {
- int i = atoi(args[0]+1);
- histline = historynum(i, currentdir);
- histline[strlen(histline) - 1] = '\0';
- if((strchr(histline, '|'))!=NULL) {
- while ( (args[i] = strtok(cmd, "|")) != NULL) {
- i++;
- cmd = NULL;
- }
- args[0][strlen(args[0]) - 1] = '\0';
- args[1] = args[1] + 1;
- }
- else {
- while ( (args[cmd_in] = strtok(histline, " ")) != NULL) {
- printf("arg %d: %s\n", cmd_in, args[cmd_in]);
- cmd_in++;
- histline = NULL;
- }
- }
- }
- /*checks if there is redirect and also if there is wildcard*/
- int bonari = 0;
- while(args[k] != NULL){
- if(strcmp(args[k], "<") == 0){
- input_mode = 1;
- args[k] = NULL;
- strcpy(input, args[k+1]);
- }else if(strcmp(args[k], ">") == 0){
- output_mode = 1;
- args[k] = NULL;
- strcpy(output, args[k+1]);
- }else if (strstr(args[k], "*") != NULL) {
- bonari = 1;
- }
- k++;
- }
- if (strcmp(args[0],"exit")==0) {
- exit(0);
- }
- if (strcmp(args[0], "cd")==0) {
- if (args[1] == NULL) {
- const char* home = getenv("HOME");
- chdir(home);
- }
- char *token = args[1];
- chdir(token);
- continue;
- }
- /* print history log */
- if (strcmp(args[0],"history")==0) {
- histRead(currentdir);
- continue;
- }
- /* wildcard bonus feature*/
- int jj;
- glob_t globbuf;
- if (bonari == 1){
- for (jj = 0; jj < argc; jj++) {
- if (jj == 0)
- glob(args[0],GLOB_NOCHECK, NULL, &globbuf);
- else
- glob(args[jj], GLOB_NOCHECK | GLOB_APPEND, NULL, &globbuf);
- }
- }
- char reout;
- char rein;
- switch (pid = fork()) {
- case -1:
- /* error */
- perror("fork");
- continue;
- case 0:
- /* child process */
- /*Redirect*/
- if (output_mode == 1) {
- reout = creat(output, 0644);
- dup2(reout, STDOUT_FILENO);
- close(reout);
- }
- if (input_mode == 1) {
- rein = open(input, O_RDONLY, 0);
- dup2(rein, STDIN_FILENO);
- close(rein);
- }
- if (bonari == 1){
- execvp(&globbuf.gl_pathv[0][0], &globbuf.gl_pathv[0]);
- perror("execvp");
- exit(1);
- }
- else{
- execvp(args[0], args);
- perror("execvp");
- exit(1);
- }
- default:
- /* parent (shell) */
- if (!background) {
- alarm(0);
- while (wait(NULL)!=pid)
- printf("some other child process exited\n");
- }
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement