-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfoosh.cpp
More file actions
137 lines (117 loc) · 4.04 KB
/
Copy pathfoosh.cpp
File metadata and controls
137 lines (117 loc) · 4.04 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
#include "diskutils.hpp"
#include <iostream>
#include <sstream>
#include <vector>
int main() {
joindisk();
std::cout << "+++ Number of blocks = " << NBLOCKS << "\n";
std::cout << "+++ Number of free blocks = " << NFREEBLOCKS << "\n";
std::cout << "+++ First block of the root directory = " << RBN << "\n";
unsigned int CBN = RBN;
std::string CWD = "/";
std::string line;
while (true) {
std::cout << "[foosh] VD:" << (CWD == "/" ? "" : CWD) << "> ";
if (!std::getline(std::cin, line))
break;
std::stringstream ss(line);
std::string cmd, arg1, arg2;
ss >> cmd;
if (cmd.empty()) continue;
// exit / quit
if (cmd == "exit" || cmd == "quit") {
break;
}
// cd / chdir
else if (cmd == "cd" || cmd == "chdir") {
ss >> arg1;
if (arg1.empty() || arg1 == "/") {
CBN = RBN;
CWD = "/";
continue;
}
// Strip optional trailing slash
if (arg1.size() > 1 && arg1.back() == '/')
arg1.pop_back();
unsigned int search_block = (arg1[0] == '/') ? RBN : CBN;
std::string temp_cwd = (arg1[0] == '/') ? "/" : CWD;
auto path_parts = split_path(arg1);
bool success = true;
for (const std::string& part : path_parts) {
metadata entry;
if (find_dir_entry(search_block, part, entry)) {
if (entry.type == 'd') {
search_block = entry.firstblock;
if (part == ".") {
// no change
} else if (part == "..") {
if (temp_cwd != "/") {
size_t last_slash = temp_cwd.find_last_of('/');
temp_cwd = (last_slash == 0) ? "/" : temp_cwd.substr(0, last_slash);
}
} else {
if (temp_cwd != "/") temp_cwd += "/";
temp_cwd += part;
}
} else {
std::cout << "***Error: " << part << " is a file, not a directory.\n";
success = false;
break;
}
} else {
std::cout << "***Error: unable to change to directory " << arg1 << "\n";
success = false;
break;
}
}
if (success) {
CBN = search_block;
CWD = temp_cwd;
}
}
// md / mkdir
else if (cmd == "md" || cmd == "mkdir") {
ss >> arg1;
if (arg1.empty()) {
std::cout << "Usage: md <path>\n";
continue;
}
fs_mkdir(arg1, CBN, CWD);
}
// ls
else if (cmd == "ls") {
ss >> arg1; // may be empty
fs_ls(arg1, CBN, CWD);
}
// dir
else if (cmd == "dir") {
fs_dir(CBN, CWD);
}
// cp / copy
else if (cmd == "cp" || cmd == "copy") {
// We must NOT use >> because the back-tick and path have no space
// between them; but we need to read two whitespace-separated tokens.
ss >> arg1 >> arg2;
if (arg1.empty() || arg2.empty()) {
std::cout << "Usage: cp <src> <dst>\n";
continue;
}
fs_cp(arg1, arg2, CBN, CWD);
}
// prn / type
else if (cmd == "prn" || cmd == "type") {
ss >> arg1;
if (arg1.empty()) {
std::cout << "Usage: prn <file>\n";
continue;
}
fs_prn(arg1, CBN, CWD);
}
// unknown
else {
std::cout << "***Error: Unknown command: " << cmd << "\n";
}
}
leavedisk();
return 0;
}