2023-10-15 11:29:56 +03:00
# include <stdio.h>
# include <errno.h>
# include <fcntl.h>
# include <unistd.h>
# include <stdlib.h>
# include <string.h>
2023-10-15 11:58:12 +03:00
# include <sys/mman.h>
2023-10-15 11:29:56 +03:00
# 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 ;
2023-10-15 11:58:12 +03:00
int shred ( int rand_fd , int fd ) {
/* Get size */
2023-10-15 11:29:56 +03:00
off_t size = lseek ( fd , 0 , SEEK_END ) ;
2023-10-15 11:58:12 +03:00
if ( size < = 0 )
2023-10-15 11:29:56 +03:00
return 1 ;
2023-10-15 11:58:12 +03:00
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 ;
}
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
for ( unsigned int n = 0 ; n < n_loops ; n + + ) {
read ( rand_fd , buf , size ) ;
fsync ( fd ) ;
}
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
if ( z_flag )
memset ( buf , 0 , size ) ;
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
if ( munmap ( buf , size ) ) {
fprintf ( stderr , " shred: munmap: %s \n " , strerror ( errno ) ) ;
return 1 ;
2023-10-15 11:29:56 +03:00
}
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 ;
2023-11-05 13:46:39 +03:00
else if ( ! strncmp ( argv [ i ] , " -n= " , 3 ) )
2023-11-04 22:19:51 +03:00
n_loops = atoi ( argv [ i ] + 3 ) ;
2023-10-15 11:29:56 +03:00
2023-10-21 15:05:49 +03:00
else if ( ! strcmp ( argv [ i ] , " --help " ) ) {
2023-10-30 18:09:33 +03:00
printf ( " shred [-n=N Overwrite N times (default 3)] [-z Final overwrite with zeros] [-u Remove file] [-f Chmod to ensure writability] [file file2...] \n " ) ;
2023-10-15 11:29:56 +03:00
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 + + ) {
2023-10-15 11:58:12 +03:00
int fd = open ( argv [ i ] , O_RDWR ) ;
2023-10-15 11:29:56 +03:00
if ( fd < 0 ) {
fprintf ( stderr , " shred: %s is %s \n " , argv [ i ] , strerror ( errno ) ) ;
2023-10-15 12:17:50 +03:00
continue ;
2023-10-15 11:29:56 +03:00
}
2023-10-15 11:58:12 +03:00
shred ( rand_fd , fd ) ;
2023-11-06 13:41:52 +03:00
fsync ( fd ) ;
2023-10-15 11:29:56 +03:00
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 ;
}