-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain_loop.c
More file actions
135 lines (131 loc) · 3.75 KB
/
main_loop.c
File metadata and controls
135 lines (131 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <errno.h>
#include "main_loop.h"
#include "run_programs.h"
#include "structures_constants.h"
#include "string_manipulations.h"
#include "error.h"
void run_shell(char *batch_name)
{
FILE *file = NULL;
char *line;
Environment environment;
environment.paths = DEFAULT_PATHS;
environment.path_set_by_user = false;
environment.cwd[0] = '\0';
/* https://stackoverflow.com/questions/298510/how-to-get-the-current-directory-in-a-c-program */
if (getcwd(environment.cwd, PATH_MAX) == NULL)
{
error("Can't get current working directory.\n");
exit(0);
}
/* Open file if patch file operation. */
if (batch_name != NULL)
{
if ((file = fopen(batch_name, "r")) == NULL) {
error("Couldn't open batch file.\n");
exit(1);
}
}
while (true)
{
line = get_next_input(batch_name, file);
if (line == NULL) {
break;
}
else if (line[0] == '\0') {
/* If there is nothing to be processed, just continue. */
}
else if (line[0] == '&') {
/* Check for nonsense command character at the beginning. */
error("& character is used for parralel prosessing. Not okay alone.\n");
}
/* Check buildin commands. */
else if (strncmp(line, "exit", 4) == 0)
{
/* Check there is no parameters for exit build in. */
if (line[4] != '\0') {
error("Exit does not take any parameters.\n");
} else {
free(line);
break;
}
}
else if (strncmp(line, "path", 4) == 0)
{
if (environment.path_set_by_user == true)
{
/* Cleanup previous path memory. */
free(environment.paths - 5);
}
environment.paths = line + 5;
environment.path_set_by_user = true;
/* Continue so new path variable memory will be reserved. */
continue;
}
else if (strncmp(line, "cd ", 3) == 0)
{
/* https://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists */
/* Check does new directory exist. */
char new_cwd[PATH_MAX];
get_absolute_path(line + 3, environment.cwd, new_cwd);
DIR *dir = opendir(new_cwd);
if (dir)
{
strncpy(environment.cwd, new_cwd, PATH_MAX);
chdir(new_cwd);
closedir(dir);
}
else
{
error("Couldn't find folder.\n");
}
} else
{
handle_commands(line, &environment);
}
/* Free dynamically allocated line variable. */
free(line);
}
/* Close batch file if there is one. */
if (file != NULL)
{
fclose(file);
}
/* Cleanup user path. */
if (environment.path_set_by_user == true) {
free(environment.paths - 5);
}
}
char *get_next_input(char *batch_name, FILE *file)
{
char *line = NULL;
size_t length = 0;
if (batch_name == NULL)
{
/* Get input directly from user if there is no argument to shell. */
line = readline("wish> ");
}
else
{
/* return next line of the file. */
if (getline(&line, &length, file) == -1)
{
/* Enf of file reached. */
free(line);
return NULL;
}
}
clean_line(line);
return line;
}