#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define BUFFSIZE 131072 /* I/O block size: change with care */
#define PASSES 2 /* there are 3 write operations, so if this is set to 15 files will be overwritten 45 times */

#define INT_PASS_ONE 0   /* bytes to be written to the file */
#define INT_PASS_TWO 1

void writeout(off_t st_size, int fh, int o_data[BUFFSIZE]) {
  int bytecount = 0;
  do {
    if((st_size - bytecount) > BUFFSIZE) bytecount += write(fh, o_data, BUFFSIZE);
    else bytecount += write(fh, o_data, (st_size - bytecount));
  } while(bytecount < st_size);
  lseek(fh,0,SEEK_SET);
}

int main(int argc, char *argv[]) {

  int fh, o_data[BUFFSIZE], i, j;
  struct stat fh_stat;
  if(argc != 2) { fprintf(stderr,"Please specify a valid filename.\n"); return -1; }
  char temp0[strlen(argv[1])+1];
  /* open file descriptor and get file stats */
  if((fh = open(argv[1],O_WRONLY,0644)) < 0) { perror("Could not open file for writing"); return -1; }
  if(stat(argv[1],&fh_stat) < 0) { perror("Count not get file stats"); close(fh); return -1; }
  /* overwrite with bytes defined by INT_PASS_ONE */
  memset(o_data,INT_PASS_ONE,BUFFSIZE);
  for(i=0;i<PASSES;i++)
    writeout(fh_stat.st_size, fh, o_data);
  /* overwrite with bytes defined by INT_PASS_TWO */
  memset(o_data,INT_PASS_TWO,BUFFSIZE);
  for(i=0;i<PASSES;i++)
    writeout(fh_stat.st_size, fh, o_data);
  /* seed rand */
  srand(time(NULL));
  /* overwrite with random bytes */
  for(i=0;i<PASSES;i++) {
    for(j=0;j<BUFFSIZE;j++)
      o_data[j] = rand();
    writeout(fh_stat.st_size, fh, o_data);
  }
  fprintf(stderr,"Wiped %s (%i bytes)\n",argv[1], (int)fh_stat.st_size);
  /* rename file before deletion*/
  for(i=0;i<PASSES;i++) {
    strcpy(temp0,argv[1]);
    for(j=0;j<(int)strlen(argv[1]);j++)
      argv[1][j] = 97+(int)(25.0*rand()/(RAND_MAX+1.0));
    if(rename(temp0,argv[1]) < 0)
      perror("Rename failed");
  }
  /* delete overwritten file */
  if(unlink(argv[1]) < 0)
    perror("Unable to delete overwritten file");
  close(fh);
  return 0;
}
