This repository was archived by the owner on May 24, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path439shell.cpp
More file actions
206 lines (176 loc) · 5.67 KB
/
Copy path439shell.cpp
File metadata and controls
206 lines (176 loc) · 5.67 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include <sstream>
#include "src/shell_type.h"
using std::getline;
using std::stringstream;
vector<string> SplitString(const string&, char);
CommandInfo TryExecute(const string&, Shell&);
CommandInfo TryExecute(vector<string>&, Shell&);
CommandInfo TryExecute(char**, const int, Shell&);
/// @brief takes command line args
int main(int argc, char** argv) {
CommandInfo cmd;
string input;
Shell shell; // default is 1024
// TryExecute("wc test.txt", shell);
cout << "COSC 439 Shell (" << OS << ")" << endl;
// if run from command line with args
if (argc > 1) {
if (argc == 2)
cmd = TryExecute(argv[1], shell);
else
cmd = TryExecute(argv, argc, shell);
if (cmd.Type == INVALID) exit(1);
exit(0);
}
while (cmd.Type != QUIT) {
cout << endl;
shell.Print_Working_Directory();
cout << ">> ";
getline(cin, input);
if (input.empty()) continue; // skip empty
cmd = TryExecute(input, shell);
}
// shell.Help(CommandType::cd, "help <command>");
}
/*stuff under here could be moved to a separate file */
/// @brief Splits string by delimiter
/// @param str
/// @param delimiter
/// @return vector of strings
vector<string> SplitString(const string& input, char delimiter = ' ') {
vector<string> args;
stringstream ss(input);
string arg;
while (getline(ss, arg, delimiter)) args.push_back(arg);
return args;
}
/// @brief Deletes spaces before [0] index
/// @note this exists so commands commands like " echo text1 text2 " can
/// still work like the normal echo cmd
/// @param args
void DeleteStartingSpaces(vector<string>& args) {
while (args.size() > 0 && (args[0].empty() || args[0] == " "))
args.erase(args.begin());
}
/// @brief try execute with vector
/// @param args raw args
/// @param shell
/// @return command info
CommandInfo TryExecute(vector<string>& args, Shell& shell) {
CommandInfo cmd_info = shell.GetCommandType(Shell::SanitizeString(args[0]));
/// @note for things that need atleast 1 arg
string text = (args.size() > 1) ? args[1] : string();
switch (cmd_info.Type) {
case CD:
shell.Change_Directory(text);
break;
case CLR:
shell.Clear_Screen();
break;
case LIST_DIR:
shell.List_Directory(text);
break;
case ENVIRON:
shell.Environment_Variables();
break;
case ECHO:
text.clear();
for (size_t i = 1; i < args.size(); ++i) text.append(args[i] + ' ');
shell.Echo(text);
break;
case HELP:
shell.Help();
break;
case PAUSE:
shell.Pause();
break;
case QUIT:
shell.Quit();
break;
case CHMOD:
if (args.size() < 3)
fprintf(stderr, "Not enough arguments");
else
shell.Change_Mode(vector<string>(args.begin() + 1, args.end()));
break;
case CHOWN:
shell.Change_Ownership(
vector<string>(args.begin() + 1, args.end()));
break;
case LS:
shell.List();
break;
case PWD:
shell.Print_Working_Directory();
break;
case CAT:
shell.Concatenate(vector<string>(args.begin() + 1, args.end()));
break;
case MKDIR:
shell.Make_Directories(
vector<string>(args.begin() + 1, args.end()));
break;
case RMDIR:
shell.Remove_Directories(
vector<string>(args.begin() + 1, args.end()));
break;
case RM:
shell.Remove(vector<string>(args.begin() + 1, args.end()));
break;
case CP:
shell.Copy(vector<string>(args.begin() + 1, args.end()));
break;
case MV:
shell.Move(vector<string>(args.begin() + 1, args.end()));
break;
case TOUCH:
shell.Create_Empty_Files(
vector<string>(args.begin() + 1, args.end()));
break;
case GREP:
// must have atleast 2 args or segfault
if (args.size() < 3)
fprintf(stderr, "Not enough arguments");
else
shell.Search_Text_Patterns(args[1], args[2]);
break;
case WC:
shell.Word_Count(text);
break;
default:
return INVALID;
}
return cmd_info;
}
/// @brief
/// @param c_args // command line args
/// @param argc
/// @param shell
/// @note exists to make running from command line easier
/// @return
CommandInfo TryExecute(char** c_args, const int argc, Shell& shell) {
vector<string> v_args = vector<string>(argc);
for (int i = 1; i < argc; ++i) v_args[i - 1] = string(c_args[i]);
return TryExecute(v_args, shell);
}
/// @brief trys to run a shell command
/// @param input string input
/// @param shell the shell to use
/// @return CommandInfo of the command executed
CommandInfo TryExecute(const string& input, Shell& shell) {
vector<string> args = SplitString(input, ' ');
DeleteStartingSpaces(args);
const CommandInfo& info = TryExecute(args, shell);
if (info.Type == INVALID) {
pid_t pid = shell.Execute(input);
if (pid == -1)
fprintf(stderr,
"'%s' is not an existing command, operable program or "
"batch file\n",
args[0].c_str());
else
printf("Finished Process '%s' with PID: %lld\n", args[0].c_str(),
pid);
}
return info;
}