diff --git a/src/rmdir/rmdir.c b/src/rmdir/rmdir.c index 6e6d777..e29bcb8 100644 --- a/src/rmdir/rmdir.c +++ b/src/rmdir/rmdir.c @@ -1,6 +1,98 @@ #include +#include +#include +#include +#include +#include +#include -int main(void) { - printf("Hello, World!\n"); +#define NAME "rmdir (canoutils)" +#define VERSION "1.0.0" +#define AUTHOR "tim-tm" + +#define print_version() \ + do { \ + printf("%s\nversion: %s\nby: %s\n", NAME, VERSION, AUTHOR); \ + } while (0) + +bool ignore_fail = false; +bool parents = false; +bool verbose = false; + +int rm_dir(char *dirname) { + if (dirname == NULL) { + fprintf(stderr, "Directory name must be specified.\n"); + return 1; + } + + struct stat stat_path; + stat(dirname, &stat_path); + if (S_ISDIR(stat_path.st_mode) == 0) { + fprintf(stderr, "'%s' is not a directory.\n", dirname); + return 1; + } + + DIR *dir = opendir(dirname); + if (dir == NULL) { + fprintf(stderr, "Failed to open '%s': %s\n", dirname, strerror(errno)); + return 1; + } + + int n = 0; + struct dirent *dent; + while ((dent = readdir(dir)) != NULL) { + if (++n > 2) break; + } + closedir(dir); + + if (n <= 2) { // Directory is empty (the two entries are '.' and '..') + if (remove(dirname) != 0) { + fprintf(stderr, "Failed to remove '%s': %s\n", dirname, strerror(errno)); + return 1; + } else if (verbose) { + printf("Removing '%s'\n", dirname); + } + } else if (!ignore_fail) { + fprintf(stderr, "'%s' must be empty.\n", dirname); + return 1; + } return 0; -} \ No newline at end of file +} + +int main(int argc, char **argv) { + if (argc <= 1) { + fprintf(stderr, "Not enough arguments.\nSee rmdir --help for more information.\n"); + return 1; + } + + if (strcmp(argv[1], "--version") == 0) { + print_version(); + return 0; + } + if (strcmp(argv[1], "--help") == 0) { + system("man rmdir"); + return 0; + } + + if (argc == 2) { + return rm_dir(argv[1]); + } + + for (int i = 1; i < argc-1; ++i) { + if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--parents") == 0) { + parents = true; + } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { + verbose = true; + } else if (strcmp(argv[i], "--ignore-fail-on-non-empty") == 0) { + ignore_fail = true; + } + } + + if (parents) { + // TODO: Implement -p|--parents flag + return 0; + } else { + return rm_dir(argv[argc-1]); + } +} +