#include #include #include #include #include #include #include int get_stat(const char *path, struct stat *stat_path) { if (lstat(path, stat_path)) { fprintf(stderr, "rm: unable to stat %s: %s\n", path, strerror(errno)); return 1; } return 0; } char *make_path(const char *src, const char *dst) { size_t len = strlen(src) + strlen(dst) + 2; char *full_path = malloc(len + 1); if (full_path == NULL) { fprintf(stderr, "rm: malloc() returned NULL\n"); return NULL; } snprintf(full_path, len, "%s/%s", src, dst); return full_path; } int rmtree(const char *path) { struct stat stat_path; if (get_stat(path, &stat_path)) return 1; if (!S_ISDIR(stat_path.st_mode) || S_ISLNK(stat_path.st_mode)) { if (unlink(path) < 0) { fprintf(stderr, "rm: %s: is not directory\n", path); return 1; } return 0; } DIR *dir = opendir(path); if (dir == NULL) { fprintf(stderr, "rm: %s: Can`t open directory\n", path); return 1; } struct dirent *ep; while ((ep = readdir(dir)) != NULL) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) continue; char *full_path = make_path(path, ep->d_name); if (full_path == NULL) continue; rmtree(full_path); free(full_path); } closedir(dir); if (rmdir(path) < 0) fprintf(stderr, "rm: %s: can`t remove a directory\n", path); return 0; } int main(const int argc, char **argv) { if (argc == 1 || !strcmp(argv[argc - 1], "--help")) { printf("rm [src1 src2...]\n"); return 0; } int status = 0; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') continue; int status = rmtree(argv[i]); if (status != 0) status = 1; } return status; }