]> git.saurik.com Git - apple/file_cmds.git/blobdiff - rm/rm.c
file_cmds-264.50.1.tar.gz
[apple/file_cmds.git] / rm / rm.c
diff --git a/rm/rm.c b/rm/rm.c
index c5c4da57ba28eb3e2ec516867f195686c636ca76..ec13b2a4f50f05ac787ddcb42cf655b00b00743a 100644 (file)
--- a/rm/rm.c
+++ b/rm/rm.c
@@ -31,8 +31,9 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
 #ifndef lint
-static const char copyright[] =
+__used static const char copyright[] =
 "@(#) Copyright (c) 1990, 1993, 1994\n\
        The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
@@ -41,7 +42,7 @@ static const char copyright[] =
 #if 0
 static char sccsid[] = "@(#)rm.c       8.5 (Berkeley) 4/18/94";
 #else
-static const char rcsid[] =
+__used static const char rcsid[] =
   "$FreeBSD: src/bin/rm/rm.c,v 1.33 2001/06/13 15:01:25 ru Exp $";
 #endif
 #endif /* not lint */
@@ -61,6 +62,9 @@ static const char rcsid[] =
 #include <unistd.h>
 
 #ifdef __APPLE__
+#include <removefile.h>
+#include <pwd.h>
+#include <grp.h>
 #include "get_compat.h"
 #else
 #define COMPAT_MODE(func, mode) 1
@@ -93,6 +97,9 @@ main(argc, argv)
        int ch, rflag;
        char *p;
 
+       if (argc < 1)
+               usage();
+
        /*
         * Test for the special case where the utility is called as
         * "unlink", for which the functionality provided is greatly
@@ -102,6 +109,7 @@ main(argc, argv)
                p = argv[0];
        else
                ++p;
+       uid = geteuid();
        if (strcmp(p, "unlink") == 0) {
                if (argc == 2) {
                        rm_file(&argv[1]);
@@ -150,7 +158,6 @@ main(argc, argv)
        }
 
        checkdot(argv);
-       uid = geteuid();
 
        if (*argv) {
                stdin_ok = isatty(STDIN_FILENO);
@@ -293,9 +300,17 @@ rm_tree(argv)
                                break;
 
                        default:
+#ifdef __APPLE__
+                               if (Pflag) {
+                                       if (removefile(p->fts_accpath, NULL, REMOVEFILE_SECURE_7_PASS)) /* overwrites and unlinks */
+                                               eval = rval = 1;
+                               } else
+                                       rval = unlink(p->fts_accpath);
+#else  /* !__APPLE_ */
                                if (Pflag)
                                        rm_overwrite(p->fts_accpath, NULL);
                                rval = unlink(p->fts_accpath);
+#endif /* __APPLE__ */
                                if (rval == 0 || (fflag && errno == ENOENT)) {
                                        if (rval == 0 && vflag)
                                                (void)printf("%s\n",
@@ -310,6 +325,7 @@ err:
        }
        if (errno)
                err(1, "fts_read");
+       fts_close(fts);
 }
 
 void
@@ -360,9 +376,17 @@ rm_file(argv)
                        else if (S_ISDIR(sb.st_mode))
                                rval = rmdir(f);
                        else {
+#ifdef __APPLE__
+                               if (Pflag) {
+                                       if (removefile(f, NULL, REMOVEFILE_SECURE_7_PASS)) /* overwrites and unlinks */
+                                               eval = rval = 1;
+                               } else
+                                       rval = unlink(f);
+#else  /* !__APPLE__ */
                                if (Pflag)
                                        rm_overwrite(f, &sb);
                                rval = unlink(f);
+#endif /* __APPLE__ */
                        }
                }
                if (rval && (!fflag || errno != ENOENT)) {
@@ -396,7 +420,6 @@ rm_overwrite(file, sbp)
        int bsize, fd, wlen;
        char *buf = NULL;
 
-       fd = -1;
        if (sbp == NULL) {
                if (lstat(file, &sb))
                        goto err;
@@ -415,7 +438,7 @@ rm_overwrite(file, sbp)
 #define        PASS(byte) {                                                    \
        memset(buf, byte, bsize);                                       \
        for (len = sbp->st_size; len > 0; len -= wlen) {                \
-               wlen = len < bsize ? len : bsize;                       \
+               wlen = len < bsize ? (int)len : bsize;                  \
                if (write(fd, buf, wlen) != wlen)                       \
                        goto err;                                       \
        }                                                               \
@@ -507,10 +530,24 @@ checkdot(argv)
 
        complained = 0;
        for (t = argv; *t;) {
-               if ((p = strrchr(*t, '/')) != NULL)
-                       ++p;
-               else
+               size_t len = strlen(*t);
+               char truncated[len];
+
+               if ((p = strrchr(*t, '/')) != NULL) {
+                       if (p[1] == '\0') { // trailing / -- treat as if not present
+                               strlcpy(truncated, *t, len);
+                               p = strrchr(truncated, '/');
+                               if (p) {
+                                       ++p;
+                               } else {
+                                       p = truncated;
+                               }
+                       } else {
+                               ++p;
+                       }
+               } else {
                        p = *t;
+               }
                if (ISDOT(p)) {
                        if (!complained++)
                                warnx("\".\" and \"..\" may not be removed");