]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/utility.c
(no commit message)
[imagemagick] / MagickCore / utility.c
index a8e4e90039056e8b350fc2fc74a7101dfb6f8811..9faa024ed04833a42c7dba4e5d4144f9396789ea 100644 (file)
 %                       MagickCore Utility Methods                            %
 %                                                                             %
 %                             Software Design                                 %
-%                               John Cristy                                   %
+%                                  Cristy                                     %
 %                              January 1993                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -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"
@@ -147,7 +149,8 @@ MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
 %
 */
 
-static inline size_t MagickMin(const size_t x,const size_t y)
+static inline MagickSizeType MagickMin(const MagickSizeType x,
+  const MagickSizeType y)
 {
   if (x < y)
     return(x);
@@ -210,7 +213,8 @@ MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
     }
   quantum=(size_t) MagickMaxBufferExtent;
   if ((fstat(source_file,&attributes) == 0) && (attributes.st_size != 0))
-    quantum=MagickMin((size_t) attributes.st_size,MagickMaxBufferExtent);
+    quantum=(size_t) MagickMin((size_t) attributes.st_size,
+      MagickMaxBufferExtent);
   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
   if (buffer == (unsigned char *) NULL)
     {
@@ -675,9 +679,37 @@ MagickPrivate void ExpandFilename(char *path)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  ExpandFilenames() checks each argument of the command line vector and
-%  expands it if they have a wildcard character.  For example, *.jpg might
-%  expand to:  bird.jpg rose.jpg tiki.jpg.
+%  ExpandFilenames() checks each argument of the given argument array, and
+%  expands it if they have a wildcard character.
+%
+%  Any coder prefix (EG: 'coder:filename') or read modifier postfix (EG:
+%  'filename[...]') are ignored during the file the expansion, but will be
+%  included in the final argument.  If no filename matching the meta-character
+%  'glob' is found the original argument is returned.
+%
+%  For example, an argument of '*.gif[20x20]' will be replaced by the list
+%    'abc.gif[20x20]',  'foobar.gif[20x20]',  'xyzzy.gif[20x20]'
+%  if such filenames exist, (in the current directory in this case).
+%
+%  Meta-characters handled...
+%     @    read a list of filenames (no further expansion performed)
+%     ~    At start of filename expands to HOME environemtn variable
+%     *    matches any string including an empty string
+%     ?    matches by any single character
+%
+%  WARNING: filenames starting with '.' (hidden files in a UNIX file system)
+%  will never be expanded.  Attempting to epand '.*' will produce no change.
+%
+%  Expansion is ignored for coders "label:" "caption:" "pango:" and "vid:".
+%  Which provide their own '@' meta-character handling.
+%
+%  You can see the results of the expansion using "Configure" log events.
+%
+%  The returned list should be freed using  DestroyStringList().
+%
+%  However the strings in the original pointed to argv are not
+%  freed  (TO BE CHECKED).  So a copy of the original pointer (and count)
+%  should be kept separate if they need to be freed later.
 %
 %  The format of the ExpandFilenames function is:
 %
@@ -744,6 +776,7 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
     *path='\0';
     *filename='\0';
     *subimage='\0';
+    number_files=0;
     vector[count++]=ConstantString(option);
     destroy=MagickTrue;
     parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
@@ -768,11 +801,12 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
     GetPathComponent(option,MagickPath,magick);
     if ((LocaleCompare(magick,"CAPTION") == 0) ||
         (LocaleCompare(magick,"LABEL") == 0) ||
+        (LocaleCompare(magick,"PANGO") == 0) ||
         (LocaleCompare(magick,"VID") == 0))
       continue;
-    if ((IsGlob(filename) == MagickFalse) && (*filename != '@'))
+    if ((IsGlob(filename) == MagickFalse) && (*option != '@'))
       continue;
-    if (*filename != '@')
+    if (*option != '@')
       {
         /*
           Generate file list from wildcard filename (e.g. *.jpg).
@@ -801,7 +835,7 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
           Generate file list from file list (e.g. @filelist.txt).
         */
         exception=AcquireExceptionInfo();
-        files=FileToString(filename+1,~0,exception);
+        files=FileToString(option+1,~0UL,exception);
         exception=DestroyExceptionInfo(exception);
         if (files == (char *) NULL)
           continue;
@@ -860,7 +894,8 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
       if (*path != '\0')
         (void) ConcatenateMagickString(filename,DirectorySeparator,
           MaxTextExtent);
-      (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
+      if (filelist[j] != (char *) NULL)
+        (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
       filelist[j]=DestroyString(filelist[j]);
       if (strlen(filename) >= (MaxTextExtent-1))
         ThrowFatalException(OptionFatalError,"FilenameTruncated");
@@ -1042,6 +1077,14 @@ MagickPrivate MagickBooleanType GetExecutionPath(char *path,const size_t extent)
       program_name=(char *) RelinquishMagickMemory(program_name);
     execution_path=(char *) RelinquishMagickMemory(execution_path);
   }
+#endif
+#if defined(__OpenBSD__)
+  {
+    extern char
+      *__progname;
+
+    (void) CopyMagickString(path,__progname,extent);
+  }
 #endif
   return(IsPathAccessible(path));
 }
@@ -1137,6 +1180,9 @@ MagickExport MagickBooleanType GetPathAttributes(const char *path,
 %  GetPathComponent() returns the parent directory name, filename, basename, or
 %  extension of a file path.
 %
+%  The component string pointed to must have at least MaxTextExtent space
+%  for the results to be stored.
+%
 %  The format of the GetPathComponent function is:
 %
 %      GetPathComponent(const char *path,PathType type,char *component)
@@ -1380,7 +1426,7 @@ MagickPrivate char **GetPathComponents(const char *path,
 %
 %  The format of the IsPathAccessible method is:
 %
-%      MagickBooleanType IsPathAccessible(const char *filename)
+%      MagickBooleanType IsPathAccessible(const char *path)
 %
 %  A description of each parameter follows.
 %
@@ -1453,47 +1499,6 @@ static int IsPathDirectory(const char *path)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   I s M a g i c k T r u e                                                   %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  IsMagickTrue() returns MagickTrue if the value is "true", "on", "yes" or
-%  "1".
-%
-%  The format of the IsMagickTrue method is:
-%
-%      MagickBooleanType IsMagickTrue(const char *value)
-%
-%  A description of each parameter follows:
-%
-%    o option: either MagickTrue or MagickFalse depending on the value
-%      parameter.
-%
-%    o value: Specifies a pointer to a character array.
-%
-*/
-MagickExport MagickBooleanType IsMagickTrue(const char *value)
-{
-  if (value == (const char *) NULL)
-    return(MagickFalse);
-  if (LocaleCompare(value,"true") == 0)
-    return(MagickTrue);
-  if (LocaleCompare(value,"on") == 0)
-    return(MagickTrue);
-  if (LocaleCompare(value,"yes") == 0)
-    return(MagickTrue);
-  if (LocaleCompare(value,"1") == 0)
-    return(MagickTrue);
-  return(MagickFalse);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 %   L i s t F i l e s                                                         %
 %                                                                             %
 %                                                                             %
@@ -1764,6 +1769,125 @@ MagickExport size_t MultilineCensus(const char *label)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   S h r e a d F i l e                                                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  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.  On the first pass, the file is zeroed.
+%  For subsequent passes, random data is written.
+%
+%  The format of the ShredFile method is:
+%
+%      MagickBooleanType ShredFile(const char *path)
+%
+%  A description of each parameter follows.
+%
+%    o path:  Specifies a path to a file.
+%
+*/
+MagickPrivate MagickBooleanType ShredFile(const char *path)
+{
+  char
+    *passes;
+
+  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);
+  passes=GetEnvironmentValue("MAGICK_SHRED_PASSES");
+  if (passes == (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)
+    {
+      /*
+        Don't shred the file, just remove it.
+      */
+      status=remove_utf8(path);
+      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 < (ssize_t) StringToInteger(passes); i++)
+  {
+    RandomInfo
+      *random_info;
+
+    register MagickOffsetType
+      j;
+
+    ssize_t
+      count;
+
+    if (lseek(file,0,SEEK_SET) < 0)
+      break;
+    random_info=AcquireRandomInfo();
+    for (j=0; j < (MagickOffsetType) length; j+=count)
+    {
+      StringInfo
+        *key;
+
+      key=GetRandomKey(random_info,quantum);
+      if (i == 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 < (MagickOffsetType) length)
+      break;
+  }
+  status=close(file);
+  status=remove_utf8(path);
+  if (status == -1)
+    return(MagickFalse);
+  return(i < (ssize_t) StringToInteger(passes) ? MagickFalse : MagickTrue);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   S y s t e m C o m m a n d                                                 %
 %                                                                             %
 %                                                                             %
@@ -1816,6 +1940,13 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
   arguments=StringToArgv(command,&number_arguments);
   if (arguments == (char **) NULL)
     return(status);
+  if (*arguments[1] == '\0')
+    {
+      for (i=0; i < (ssize_t) number_arguments; i++)
+        arguments[i]=DestroyString(arguments[i]);
+      arguments=(char **) RelinquishMagickMemory(arguments);
+      return(-1);
+    }
   rights=ExecutePolicyRights;
   domain=DelegatePolicyDomain;
   if (IsRightsAuthorized(domain,rights,arguments[1]) == MagickFalse)
@@ -1844,7 +1975,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
   status=system(shell_command);
 #else
   if ((asynchronous != MagickFalse) ||
-      (strpbrk(shell_command,"&;<>|") == (char *) NULL))
+      (strpbrk(shell_command,"&;<>|") != (char *) NULL))
     status=system(shell_command);
   else
     {
@@ -1854,7 +1985,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
       /*
         Call application directly rather than from a shell.
       */
-      child_pid=fork();
+      child_pid=(pid_t) fork();
       if (child_pid == (pid_t) -1)
         status=system(command);
       else
@@ -1872,7 +2003,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
               pid;
 
             child_status=0;
-            pid=waitpid(child_pid,&child_status,0);
+            pid=(pid_t) waitpid(child_pid,&child_status,0);
             if (pid == -1)
               status=(-1);
             else
@@ -1897,7 +2028,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
 #endif
   if (status < 0)
     (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
-      "`%s' (%d)",command,status);
+      "FailedToExecuteCommand","`%s' (%d)",command,status);
   if (shell_command != command)
     shell_command=DestroyString(shell_command);
   for (i=0; i < (ssize_t) number_arguments; i++)