`rm`: add `--follow-symlinks`.

now i have a feature that gnu doesn't even have!
admittedly a pointless one... but still a substantial feature none-the-less.
master
Drake 3 years ago
parent e16bee31d5
commit 84ca84611f

@ -42,7 +42,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
int removeFileOrDirectory(char *path, bool recursive, bool force) { int removeFileOrDirectory(char *path, bool recursive, bool force,
bool followSymlink) {
if (isDirectory(path)) { if (isDirectory(path)) {
if (recursive == true) { if (recursive == true) {
DIR *dirp; DIR *dirp;
@ -55,10 +56,16 @@ int removeFileOrDirectory(char *path, bool recursive, bool force) {
fullname = malloc(strlen(dp->d_name) + strlen(path) + 2); fullname = malloc(strlen(dp->d_name) + strlen(path) + 2);
sprintf(fullname, "%s/%s", path, dp->d_name); sprintf(fullname, "%s/%s", path, dp->d_name);
// printf("%s\n", dp->d_name); // printf("%s\n", dp->d_name);
if (!isDirectory(fullname)) { if (isSymlink(fullname) && followSymlink == true) {
char *buf = malloc(1024);
readlink(path, buf, sizeof(buf));
removeFileOrDirectory(buf, recursive, force, followSymlink);
unlink(path);
} else if (isRegularFile(fullname) ||
(followSymlink == false && isSymlink(fullname))) {
unlink(fullname); unlink(fullname);
} else { } else if (isDirectory(fullname) && recursive) {
removeFileOrDirectory(fullname, recursive, force); removeFileOrDirectory(fullname, recursive, force, followSymlink);
} }
free(fullname); free(fullname);
if (errno != 0) { if (errno != 0) {
@ -91,7 +98,14 @@ int removeFileOrDirectory(char *path, bool recursive, bool force) {
return errno; return errno;
} }
} else { } else {
unlink(path); if (isRegularFile(path) || followSymlink == false) {
unlink(path);
} else if (isSymlink(path) && followSymlink == true) {
char *buf = malloc(1024);
readlink(path, buf, sizeof(buf));
removeFileOrDirectory(buf, recursive, force, followSymlink);
unlink(path);
}
if (errno == 0) { if (errno == 0) {
return 0; return 0;
} else if (errno == EACCES || errno == EPERM) { } else if (errno == EACCES || errno == EPERM) {
@ -107,6 +121,7 @@ int removeFileOrDirectory(char *path, bool recursive, bool force) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
bool recursive = false; bool recursive = false;
bool force = false; bool force = false;
bool followSymlink = false;
char *path; char *path;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
char *arg = argv[i]; char *arg = argv[i];
@ -117,11 +132,14 @@ int main(int argc, char **argv) {
"Drake's Epic Coreutils (working title) " DRAKECU_VERSION "\n" "Drake's Epic Coreutils (working title) " DRAKECU_VERSION "\n"
"rm - removes files and directories.\n" "rm - removes files and directories.\n"
"available arguments:\n" "available arguments:\n"
" --help: show this help message\n" " --help: show this help message\n"
" --version: show the version of the program\n" " --version: show the version of the program\n"
" --recursive, -r: recursively delete files inside directories.\n" " --recursive, -r: recursively delete files inside "
"directories.\n"
" --follow-symlink, -s: follow symlinks and delete the files "
"inside of them.\n"
"usage:\n" "usage:\n"
" rm -{r} [long options] [file/directory]"; " rm -{r,s} [long options] [file/directory]";
printf("%s\n", help); printf("%s\n", help);
return 0; return 0;
} else if (!strcmp(arg, "--version")) { } else if (!strcmp(arg, "--version")) {
@ -134,16 +152,20 @@ int main(int argc, char **argv) {
// why not use `rm -r` // why not use `rm -r`
// this might just be a placebo/compatibility thing atm, lol // this might just be a placebo/compatibility thing atm, lol
force = true; force = true;
} else if (!strcmp(arg, "--follow-symlink")) {
followSymlink = true;
} else if (startsWithChar(arg, '-')) { } else if (startsWithChar(arg, '-')) {
for (int i = 1; i < (int)strlen(arg); i++) { for (int i = 1; i < (int)strlen(arg); i++) {
if (arg[i] == 'r') { if (arg[i] == 'r') {
recursive = true; recursive = true;
} else if (arg[i] == 'f') { } else if (arg[i] == 'f') {
force = true; force = true;
} else if (arg[i] == 's') {
followSymlink = true;
} }
} }
} else { } else {
removeFileOrDirectory(arg, recursive, force); removeFileOrDirectory(arg, recursive, force, followSymlink);
} }
} }
} }

Loading…
Cancel
Save