82 lines
3.1 KiB
C
82 lines
3.1 KiB
C
|
#define _POSIX_C_SOURCE 200809L
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <libgen.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
int remove_up(char * path);
|
||
|
|
||
|
int main(int argc, char * argv[]) {
|
||
|
int do_remove_up = 0, error = 0; char c;
|
||
|
|
||
|
while((c = getopt(argc, argv, "p")) != -1) {
|
||
|
do_remove_up = c == 'p' ? 1 : do_remove_up;
|
||
|
}
|
||
|
|
||
|
for(; optind < argc; optind++) {
|
||
|
if(remove_up) {
|
||
|
int status = remove_up(argv[optind]);
|
||
|
if(status == -1) {
|
||
|
switch(errno) {
|
||
|
case EACCES: fprintf(stderr, "%s: %s: write permission denied\n",
|
||
|
argv[0], argv[optind]); error = 1; break;
|
||
|
case EBUSY: fprintf(stderr, "%s: %s: file in use\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case ENOTEMPTY:
|
||
|
case EEXIST: fprintf(stderr, "%s: %s: directory not empty\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case EINVAL: error = 1; break;
|
||
|
case EIO: fprintf(stderr, "%s: %s: IO error\n", argv[0], argv[optind]);
|
||
|
error = 1; break;
|
||
|
case ELOOP: error = 1; break;
|
||
|
case ENAMETOOLONG: error = 1; break;
|
||
|
case ENOENT: fprintf(stderr, "%s: %s: file not found\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case ENOTDIR: fprintf(stderr, "%s: %s: not a directory\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case EPERM: error = 1; break;
|
||
|
case EROFS: fprintf(stderr, "%s: %s: contained on read-only filesystem",
|
||
|
argv[0], argv[optind]); error = 1; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
int status = rmdir(argv[optind]);
|
||
|
if(status == -1) {
|
||
|
switch(errno) {
|
||
|
case EACCES: fprintf(stderr, "%s: %s: write permission denied\n",
|
||
|
argv[0], argv[optind]); error = 1; break;
|
||
|
case EBUSY: fprintf(stderr, "%s: %s: file in use\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case ENOTEMPTY:
|
||
|
case EEXIST: fprintf(stderr, "%s: %s: directory not empty\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case EINVAL: error = 1; break;
|
||
|
case EIO: fprintf(stderr, "%s: %s: IO error\n", argv[0], argv[optind]);
|
||
|
error = 1; break;
|
||
|
case ELOOP: error = 1; break;
|
||
|
case ENAMETOOLONG: error = 1; break;
|
||
|
case ENOENT: fprintf(stderr, "%s: %s: file not found\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case ENOTDIR: fprintf(stderr, "%s: %s: not a directory\n", argv[0],
|
||
|
argv[optind]); error = 1; break;
|
||
|
case EPERM: error = 1; break;
|
||
|
case EROFS: fprintf(stderr, "%s: %s: contained on read-only filesystem",
|
||
|
argv[0], argv[optind]); error = 1; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int remove_up(char * path) {
|
||
|
if(path[0] == '.' && path[1] == '\0') {
|
||
|
return 0;
|
||
|
}
|
||
|
else {
|
||
|
return rmdir(path) == -1 ? -1 : remove_up(dirname(path));
|
||
|
}
|
||
|
}
|