diff --git a/Userland/.gitignore b/Userland/.gitignore index 781e185b0e..e38b03c53a 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -6,3 +6,4 @@ *.o *.d +compile_commands.json diff --git a/Userland/rm.cpp b/Userland/rm.cpp index 606d92d7d9..2c62f4d628 100644 --- a/Userland/rm.cpp +++ b/Userland/rm.cpp @@ -1,18 +1,69 @@ +#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include -int main(int argc, char** argv) +int remove(bool recursive, const char* path) { - if (argc != 2) { - fprintf(stderr, "usage: rm \n"); + struct stat path_stat; + int s = stat(path, &path_stat); + if (s < 0) { + perror("stat"); return 1; } - int rc = unlink(argv[1]); - if (rc < 0) { - perror("unlink"); - return 1; + + if (S_ISDIR(path_stat.st_mode) && recursive) { + DIR* derp = opendir(path); + if (!derp) { + return 1; + } + + while (auto* de = readdir(derp)) { + if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { + StringBuilder builder; + builder.append(path); + builder.append('/'); + builder.append(de->d_name); + int s = remove(true, builder.to_string().characters()); + if (s < 0) + return s; + } + } + printf("Removing directory: %s\n", path); + int s = rmdir(path); + if (s < 0) { + perror("rmdir"); + return 1; + } + } else { + int rc = unlink(path); + if (rc < 0) { + perror("unlink"); + return 1; + } + printf("Removing file: %s\n", path); } return 0; } +int main(int argc, char** argv) +{ + CArgsParser args_parser("rm"); + args_parser.add_arg("r", "Delete directory recursively."); + args_parser.add_required_single_value("path"); + + CArgsParserResult args = args_parser.parse(argc, (const char**)argv); + Vector values = args.get_single_values(); + if (values.size() == 0) { + args_parser.print_usage(); + return 1; + } + + return remove(args.is_present("r"), values[0].characters()); +}