-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from tim-tm/rmdir
partially implement rmdir
- Loading branch information
Showing
1 changed file
with
95 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,98 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
#include <dirent.h> | ||
#include <sys/stat.h> | ||
#include <errno.h> | ||
|
||
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; | ||
} | ||
} | ||
|
||
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]); | ||
} | ||
} | ||
|