]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Thu, 18 Apr 2013 12:49:11 +0000 (12:49 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Thu, 18 Apr 2013 12:49:11 +0000 (12:49 +0000)
MagickCore/utility.c

index 50155e4718bd142a0be5fed596d3840da32dc6f4..6dedc601341675ea934f6809b37eea16cf533508 100644 (file)
@@ -53,6 +53,8 @@
 #include "MagickCore/nt-base-private.h"
 #include "MagickCore/option.h"
 #include "MagickCore/policy.h"
+#include "MagickCore/random_.h"
+#include "MagickCore/registry.h"
 #include "MagickCore/resource_.h"
 #include "MagickCore/semaphore.h"
 #include "MagickCore/signature-private.h"
@@ -1761,9 +1763,10 @@ MagickExport size_t MultilineCensus(const char *label)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  ShredFile() first overwrites the specified file with random data and then
-%  removed it.  The overwrite is optional and is only required to help keep
-%  the contents of the file private.
+%  ShredFile() overwrites the specified file with zeros or random data and then
+%  removes it.  The overwrite is optional and is only required to help keep
+%  the contents of the file private.  The first, the file is zeroed.  For
+%  other passes, random data is written.
 %
 %  The format of the ShredFile method is:
 %
@@ -1776,15 +1779,98 @@ MagickExport size_t MultilineCensus(const char *label)
 */
 MagickPrivate MagickBooleanType ShredFile(const char *path)
 {
+  char
+    *iterations;
+
+  ExceptionInfo
+    *exception;
+
   int
+    file,
     status;
 
+  MagickSizeType
+    length;
+
+  register ssize_t
+    i;
+
+  size_t
+    quantum;
+
+  struct stat
+    file_stats;
+
   if ((path == (const char *) NULL) || (*path == '\0'))
     return(MagickFalse);
+  exception=AcquireExceptionInfo();
+  iterations=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
+    exception);
+  exception=DestroyExceptionInfo(exception);
+  if (iterations == (char *) NULL)
+    iterations=GetEnvironmentValue("MAGICK_SHRED_FILE");
+  if (iterations == (char *) NULL)
+    {
+      /*
+        Don't shred the file, just remove it.
+      */
+      status=remove_utf8(path);
+      if (status == -1)
+        return(MagickFalse);
+      return(MagickTrue);
+    }
+  file=open_utf8(path,O_WRONLY | O_EXCL | O_BINARY,S_MODE);
+  if (file == -1)
+    return(MagickFalse);
+  /*
+    Shred the file.
+  */
+  quantum=(size_t) MagickMaxBufferExtent;
+  if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+    quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
+      MagickMaxBufferExtent);
+  length=(MagickSizeType) file_stats.st_size;
+  for (i=0; i < StringToInteger(iterations); i++)
+  {
+    RandomInfo
+      *random_info;
+
+    register ssize_t
+      j;
+
+    ssize_t
+      count;
+
+    if (lseek(file,0,SEEK_SET) < 0)
+      break;
+    random_info=AcquireRandomInfo();
+    for (j=0; j < length; j+=count)
+    {
+      StringInfo
+        *key;
+
+      key=GetRandomKey(random_info,quantum);
+      if (j == 0)
+        ResetStringInfo(key);  /* zero on first pass */
+      count=write(file,GetStringInfoDatum(key),(size_t)
+        MagickMin(quantum,length-j));
+      key=DestroyStringInfo(key);
+      if (count <= 0)
+        {
+          count=0;
+          if (errno != EINTR)
+            break;
+        }
+    }
+    random_info=DestroyRandomInfo(random_info);
+    if (j < length)
+      break;
+  }
+  status=close(file);
   status=remove_utf8(path);
   if (status == -1)
     return(MagickFalse);
-  return(MagickTrue);
+  return(i < StringToInteger(iterations) ? MagickFalse : MagickTrue);
 }
 \f
 /*