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 ;
}
2023-11-07 16:56:14 +03:00
int main ( int argc , char * * argv ) {
2023-10-15 11:29:56 +03:00
n_loops = 3 ;
2023-11-07 16:56:14 +03:00
int opt ;
while ( ( opt = getopt ( argc , argv , " fuzn: " ) ) ! = - 1 ) {
switch ( opt ) {
case ' f ' :
f_flag = 1 ;
break ;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case ' u ' :
u_flag = 1 ;
break ;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case ' z ' :
z_flag = 1 ;
break ;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case ' n ' :
n_loops = atoi ( optarg ) ;
break ;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
default :
printf ( " shred [file1 file2...] \n \t [-n N Overwrite N times, default 3] \n \t [-z Final overwrite with zeros] \n \t [-u Remove file] [-f Chmod to ensure writability] \n " ) ;
return 0 ;
2023-10-15 11:29:56 +03:00
}
}
2023-11-07 16:56:14 +03:00
argv + = optind ;
argc - = optind ;
if ( argc = = 0 ) {
fprintf ( stderr , " shred: missing operand \n " ) ;
return 1 ;
}
2023-10-15 11:29:56 +03:00
int rand_fd = open ( RAND_SOURCE , O_RDONLY ) ;
if ( rand_fd < 0 ) {
2023-11-07 16:56:14 +03:00
fprintf ( stderr , " shred: %s: %s \n " , RAND_SOURCE , strerror ( errno ) ) ;
2023-10-15 11:29:56 +03:00
return 1 ;
}
2023-11-07 16:56:14 +03:00
for ( int i = 0 ; 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 ) ;
2023-11-07 16:56:14 +03:00
if ( f_flag ) {
if ( chmod ( argv [ i ] , 0 ) < 0 )
2023-10-15 11:29:56 +03:00
fprintf ( stderr , " shred: %s is %s \n " , argv [ i ] , strerror ( errno ) ) ;
2023-11-07 16:56:14 +03:00
}
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
if ( u_flag ) {
if ( unlink ( argv [ i ] ) < 0 )
2023-10-15 11:29:56 +03:00
fprintf ( stderr , " shred: %s is %s \n " , argv [ i ] , strerror ( errno ) ) ;
2023-11-07 16:56:14 +03:00
}
2023-10-15 11:29:56 +03:00
}
close ( rand_fd ) ;
return 0 ;
}