#include #include #include #include #include #include #include #include "make_path.h" #include "get_stat.h" #include "recurse.h" #include "unused.h" char *f_flag = "rm"; char r_flag; char v_flag; int verbose(const char *path) { if (v_flag) { fprintf(stderr, "rm: remove %s? [y/n] ", path); fflush(stderr); int c = 0; int key = 0; while ((c = fgetc(stdin)) != EOF && c != '\n') { if (c == 'y') key = 1; } return key; } return 1; } void handle_error(const char *path) { if (f_flag) fprintf(stderr, "rm: %s: %s\n", path, strerror(errno)); } int rm(const char *path, void *p) { UNUSED(p); if (verbose(path) && remove(path) < 0) { handle_error(path); return 1; } return 0; } int rmd(const char *path, void *p) { UNUSED(p); if (verbose(path) && rmdir(path) < 0) { handle_error(path); return 1; } return 0; } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "frRi")) != -1) { switch (opt) { case 'f': f_flag = NULL; break; case 'r': r_flag = 1; break; case 'i': v_flag = 1; break; default: printf("rm [rif] [file1 file2...]\n\t-f Force\n\t-r Recursive\n\t-i Print prompt before remove\n"); return 0; } } argc -= optind; argv += optind; if (argc == 0) { fprintf(stderr, "rm: missing operand\n"); return 1; } 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 (r_flag) { if (mu_recurse(f_flag, 1, argv[i], NULL, rm, rmd)) ret = 1; } else if (rm(argv[i], NULL)) ret = 1; } return ret; }