114 lines
2.0 KiB
C
114 lines
2.0 KiB
C
#define _SHRED_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>
|
|
#include "config.h"
|
|
|
|
char f_flag;
|
|
char u_flag;
|
|
char z_flag;
|
|
int n_loops = 3;
|
|
|
|
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 (char n = 0; n < n_loops; n++) {
|
|
if (read(rand_fd, buf, size) == 0)
|
|
fprintf(stderr, "shred: %s", strerror(errno));
|
|
|
|
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(int argc, char **argv) {
|
|
|
|
int opt;
|
|
while ((opt = getopt(argc, argv, "fuzn:")) != -1) {
|
|
switch (opt) {
|
|
case 'f':
|
|
f_flag = 1;
|
|
break;
|
|
|
|
case 'u':
|
|
u_flag = 1;
|
|
break;
|
|
|
|
case 'z':
|
|
z_flag = 1;
|
|
break;
|
|
|
|
case 'n':
|
|
n_loops = atoi(optarg);
|
|
break;
|
|
|
|
default:
|
|
puts("shred [fuzn] [file1 file2...]\n\t-n N Overwrite N times, default 3\n\t-z Final overwrite with zeros\n\t-u Remove file\n\t-f Chmod to ensure writability");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
argv += optind;
|
|
argc -= optind;
|
|
if (argc == 0) {
|
|
fprintf(stderr, "shred: missing operand\n");
|
|
return 1;
|
|
}
|
|
|
|
int rand_fd = open(RAND_SOURCE, O_RDONLY);
|
|
if (rand_fd < 0) {
|
|
fprintf(stderr, "shred: %s: %s\n", RAND_SOURCE, strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
for (int i = 0; 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);
|
|
fsync(fd);
|
|
close(fd);
|
|
|
|
if (f_flag) {
|
|
if (chmod(argv[i], 0) < 0)
|
|
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
|
|
}
|
|
|
|
if (u_flag) {
|
|
if (unlink(argv[i]) < 0)
|
|
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
|
|
}
|
|
}
|
|
|
|
close(rand_fd);
|
|
return 0;
|
|
}
|