+/*
+ * rm_overwrite --
+ * Overwrite the file 3 times with varying bit patterns.
+ *
+ * XXX
+ * This is a cheap way to *really* delete files. Note that only regular
+ * files are deleted, directories (and therefore names) will remain.
+ * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
+ * System V file system). In a logging file system, you'll have to have
+ * kernel support.
+ */
+void
+rm_overwrite(file, sbp)
+ char *file;
+ struct stat *sbp;
+{
+ struct stat sb;
+ off_t len;
+ int fd, wlen;
+ char buf[8 * 1024];
+
+ fd = -1;
+ if (sbp == NULL) {
+ if (lstat(file, &sb))
+ goto err;
+ sbp = &sb;
+ }
+ if (!S_ISREG(sbp->st_mode))
+ return;
+ if ((fd = open(file, O_WRONLY, 0)) == -1)
+ goto err;
+
+#define PASS(byte) { \
+ memset(buf, byte, sizeof(buf)); \
+ for (len = sbp->st_size; len > 0; len -= wlen) { \
+ wlen = len < sizeof(buf) ? len : sizeof(buf); \
+ if (write(fd, buf, wlen) != wlen) \
+ goto err; \
+ } \
+}
+ PASS(0xff);
+ if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
+ goto err;
+ PASS(0x00);
+ if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
+ goto err;
+ PASS(0xff);
+ if (!fsync(fd) && !close(fd))
+ return;
+
+err: eval = 1;
+ warn("%s", file);
+}
+
+