#include #include #include #include #include #include #include "make_path.h" #include "get_stat.h" unsigned int f_flag; int rmtree(const char *path) { struct stat stat_path; if (mu_get_lstat("rm", path, &stat_path)) return 1; if (!S_ISDIR(stat_path.st_mode) || S_ISLNK(stat_path.st_mode)) { if (unlink(path) < 0) { if (!f_flag) fprintf(stderr, "rm: %s: is not directory\n", path); return 1; } return 0; } DIR *dir = opendir(path); if (dir == NULL) { if (!f_flag) fprintf(stderr, "rm: %s: Can`t open directory\n", path); return 1; } int ret = 0; struct dirent *ep; while ((ep = readdir(dir)) != NULL) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) continue; char *full_path = mu_make_path("rm", path, ep->d_name); if (full_path == NULL) continue; if (rmtree(full_path)) ret = 1; free(full_path); } closedir(dir); if (rmdir(path) < 0) if (!f_flag) fprintf(stderr, "rm: %s: can`t remove a directory\n", path); return ret; } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "frR")) != -1) { switch (opt) { case 'f': f_flag = 1; break; case 'r': case 'R': break; default: printf("rm [file1 file2...]\n\t[-f Force]\n"); return 0; } } if (argv[optind] == NULL) { fprintf(stderr, "rm: missing operand\n"); return 1; } argv += optind; argc -= optind; int ret = 0; for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], ".") || !strcmp(argv[i], "..")){ printf("rm: refusing to remove '.' or '..' directory\n"); break; } if (rmtree(argv[i])) ret = 1; } return ret; }