micro-utils/coreutils/shred.c

106 lines
2.0 KiB
C

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define RAND_SOURCE "/dev/urandom"
unsigned int f_flag;
unsigned int u_flag;
unsigned int z_flag;
unsigned int n_loops;
int shred(int rand_fd, int fd) {
/* Get size */
off_t size = lseek(fd, 0, SEEK_END);
if (size <= 0)
return 1;
void *buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
fprintf(stderr, "shred: mmap: %s\n", strerror(errno));
return 1;
}
for (unsigned int n = 0; n < n_loops; n++) {
read(rand_fd, buf, size);
fsync(fd);
}
if (z_flag)
memset(buf, 0, size);
if (munmap(buf, size)) {
fprintf(stderr, "shred: munmap: %s\n", strerror(errno));
return 1;
}
return 0;
}
int main(const int argc, const char **argv) {
n_loops = 3;
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
else if (!strcmp(argv[i], "-f"))
f_flag = 1;
else if (!strcmp(argv[i], "-u"))
u_flag = 1;
else if (!strcmp(argv[i], "-z"))
z_flag = 1;
else if (!strncmp(argv[i], "-n=", 3)) {
char *val = strchr(argv[i], '=');
if (!val)
break;
val[0] = '\0';
n_loops = atoi(val + 1);
}
else if (!strcmp(argv[i], "-h")) {
printf("shred [-n=N (Overwrite N times (default 3))] [-z (Final overwrite with zeros)] [-u (Remove file)] [-f (Chmod to ensure writability)] [FILE...]\n");
return 1;
}
}
int rand_fd = open(RAND_SOURCE, O_RDONLY);
if (rand_fd < 0) {
fprintf(stderr, "shred: %s is %s\n", RAND_SOURCE, strerror(errno));
return 1;
}
for (; i < argc; i++) {
int fd = open(argv[i], O_RDWR);
if (fd < 0) {
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
continue;
}
shred(rand_fd, fd);
close(fd);
if (u_flag)
if (unlink(argv[i]) < 0)
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
if (f_flag)
if (chmod(argv[i], 0) < 0)
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
}
close(rand_fd);
return 0;
}