13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%             U   U  TTTTT  IIIII  L      IIIII  TTTTT  Y   Y                 %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%             U   U    T      I    L        I      T     Y Y                  %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%             U   U    T      I    L        I      T      Y                   %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%             U   U    T      I    L        I      T      Y                   %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              UUU     T    IIIII  LLLLL  IIIII    T      Y                   %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                       MagickCore Utility Methods                            %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             Software Design                                 %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                  Cristy                                     %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              January 1993                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h"
49007e925e29fea767305ade6e1d635e5e517a13b3dirk#include "MagickCore/image-private.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h"
527832dc2d904c471770087cce18a9a2d76c2216a3cristy#include "MagickCore/magick-private.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
542c5fc27ae5b613b7fb9fd69c12a47b99c7d4d471cristy#include "MagickCore/nt-base-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/policy.h"
57403ae7b98805d29da82152f8874d2d0936ba0fe0cristy#include "MagickCore/random_.h"
58403ae7b98805d29da82152f8874d2d0936ba0fe0cristy#include "MagickCore/registry.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/signature-private.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
647832dc2d904c471770087cce18a9a2d76c2216a3cristy#include "MagickCore/string-private.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token.h"
667832dc2d904c471770087cce18a9a2d76c2216a3cristy#include "MagickCore/token-private.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
68d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h"
6998e91bd2c61748ce20b8e2a0b6d689ada75237c4cristy#if defined(MAGICKCORE_HAVE_PROCESS_H)
7098e91bd2c61748ce20b8e2a0b6d689ada75237c4cristy#include <process.h>
7198e91bd2c61748ce20b8e2a0b6d689ada75237c4cristy#endif
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_MACH_O_DYLD_H)
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <mach-o/dyld.h>
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Static declarations.
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const char
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declaration.
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IsPathDirectory(const char *);
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   A c q u i r e U n i q u e F i l e n a m e                                 %
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  AcquireUniqueFilename() replaces the contents of path by a unique path name.
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the AcquireUniqueFilename method is:
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType AcquireUniqueFilename(char *path)
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  path:  Specifies a pointer to an array of characters.  The unique path
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      name is returned in this array.
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType AcquireUniqueFilename(char *path)
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    file;
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  file=AcquireUniqueFileResource(path);
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (file == -1)
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  file=close(file)-1;
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   A c q u i r e U n i q u e S ym b o l i c L i n k                          %
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  AcquireUniqueSymbolicLink() creates a unique symbolic link to the specified
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  source path and returns MagickTrue on success otherwise MagickFalse.  If the
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  symlink() method fails or is not available, a unique file name is generated
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  and the source file copied to it.  When you are finished with the file, use
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RelinquishUniqueFilename() to destroy it.
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the AcquireUniqueSymbolicLink method is:
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char destination)
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  source:  the source path.
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  destination:  the destination path.
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char *destination)
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    destination_file,
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    source_file;
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quantum;
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  struct stat
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes;
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *buffer;
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(source != (const char *) NULL);
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(destination != (char *) NULL);
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_SYMLINK)
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(destination);
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(destination);
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*source == *DirectorySeparator)
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (symlink(source,destination) == 0)
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickTrue);
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
186151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        path[MagickPathExtent];
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *path='\0';
189151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      if (getcwd(path,MagickPathExtent) == (char *) NULL)
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
191151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(path,DirectorySeparator,MagickPathExtent);
192151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(path,source,MagickPathExtent);
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (symlink(path,destination) == 0)
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickTrue);
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_file=AcquireUniqueFileResource(destination);
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (destination_file == -1)
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
20018c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy  source_file=open_utf8(source,O_RDONLY | O_BINARY,0);
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (source_file == -1)
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) close(destination_file);
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(destination);
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum=(size_t) MagickMaxBufferExtent;
208f201ba6ae86e22ff3a61ec2e92a62f0799821314cristy  if ((fstat(source_file,&attributes) == 0) && (attributes.st_size > 0))
209f201ba6ae86e22ff3a61ec2e92a62f0799821314cristy    quantum=(size_t) MagickMin(attributes.st_size,MagickMaxBufferExtent);
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (buffer == (unsigned char *) NULL)
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) close(source_file);
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) close(destination_file);
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(destination);
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (length=0; ; )
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(ssize_t) read(source_file,buffer,quantum);
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (count <= 0)
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=(size_t) count;
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(ssize_t) write(destination_file,buffer,length);
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((size_t) count != length)
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) close(destination_file);
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) close(source_file);
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) RelinquishUniqueFileResource(destination);
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) close(destination_file);
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) close(source_file);
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A p p e n d I m a g e F o r m a t                                          %
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  AppendImageFormat() appends the image format type to the filename.  If an
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  extension to the file already exists, it is first removed.
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the AppendImageFormat method is:
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      void AppendImageFormat(const char *format,char *filename)
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  format:  Specifies a pointer to an array of characters.  This the
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      format of the image.
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  filename:  Specifies a pointer to an array of characters.  The unique
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      file name is returned in this array.
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void AppendImageFormat(const char *format,char *filename)
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
270151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    extension[MagickPathExtent],
271151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    root[MagickPathExtent];
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(format != (char *) NULL);
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(filename != (char *) NULL);
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*format == '\0') || (*filename == '\0'))
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(filename,"-") == 0)
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
281151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        message[MagickPathExtent];
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28358a33836a139776aab5f22c0fa3377a9b2b1b582cristy      (void) FormatLocaleString(message,MagickPathExtent,"%s:%s",format,
28458a33836a139776aab5f22c0fa3377a9b2b1b582cristy        filename);
285151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(filename,message,MagickPathExtent);
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
288212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy  GetPathComponent(filename,ExtensionPath,extension);
289212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy  if ((LocaleCompare(extension,"Z") == 0) ||
290212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      (LocaleCompare(extension,"bz2") == 0) ||
291212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      (LocaleCompare(extension,"gz") == 0) ||
292212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      (LocaleCompare(extension,"wmz") == 0) ||
293212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      (LocaleCompare(extension,"svgz") == 0))
294212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy    {
295212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      GetPathComponent(filename,RootPath,root);
296151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(filename,root,MagickPathExtent);
297212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      GetPathComponent(filename,RootPath,root);
29858a33836a139776aab5f22c0fa3377a9b2b1b582cristy      (void) FormatLocaleString(filename,MagickPathExtent,"%s.%s.%s",root,
29958a33836a139776aab5f22c0fa3377a9b2b1b582cristy        format,extension);
300212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy      return;
301212e262c842c16f5e9d1f2176b5d5b30a3f59e39cristy    }
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  GetPathComponent(filename,RootPath,root);
303151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(filename,MagickPathExtent,"%s.%s",root,format);
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   B a s e 6 4 D e c o d e                                                   %
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Base64Decode() decodes Base64-encoded text and returns its binary
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  equivalent.  NULL is returned if the text is not valid Base64 data, or a
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  memory allocation failure occurs.
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the Base64Decode method is:
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned char *Base64Decode(const char *source,length_t *length)
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o source:  A pointer to a Base64-encoded string.
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: the number of bytes decoded.
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport unsigned char *Base64Decode(const char *source,size_t *length)
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    state;
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register size_t
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *decode;
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(source != (char *) NULL);
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(length != (size_t *) NULL);
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *length=0;
3512ceb4f825fc96d60da9475b00c2d8a7c30de1dc2cristy  decode=(unsigned char *) AcquireQuantumMemory((strlen(source)+3)/4,
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    3*sizeof(*decode));
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (decode == (unsigned char *) NULL)
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((unsigned char *) NULL);
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  state=0;
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (p=source; *p != '\0'; p++)
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (isspace((int) ((unsigned char) *p)) != 0)
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*p == '=')
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=strchr(Base64,*p);
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (q == (char *) NULL)
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode=(unsigned char *) RelinquishMagickMemory(decode);
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((unsigned char *) NULL);  /* non-Base64 character */
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    switch (state)
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 0:
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i]=(q-Base64) << 2;
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        state++;
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 1:
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i++]|=(q-Base64) >> 4;
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i]=((q-Base64) & 0x0f) << 4;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        state++;
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 2:
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i++]|=(q-Base64) >> 2;
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i]=((q-Base64) & 0x03) << 6;
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        state++;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 3:
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        decode[i++]|=(q-Base64);
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        state=0;
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify Base-64 string has proper terminal characters.
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*p != '=')
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (state != 0)
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          decode=(unsigned char *) RelinquishMagickMemory(decode);
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((unsigned char *) NULL);
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      switch (state)
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case 0:
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case 1:
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Unrecognized '=' character.
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          decode=(unsigned char *) RelinquishMagickMemory(decode);
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((unsigned char *) NULL);
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case 2:
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for ( ; *p != '\0'; p++)
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (isspace((int) ((unsigned char) *p)) == 0)
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*p != '=')
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              decode=(unsigned char *) RelinquishMagickMemory(decode);
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((unsigned char *) NULL);
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case 3:
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for ( ; *p != '\0'; p++)
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (isspace((int) ((unsigned char) *p)) == 0)
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                decode=(unsigned char *) RelinquishMagickMemory(decode);
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((unsigned char *) NULL);
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((int) decode[i] != 0)
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              decode=(unsigned char *) RelinquishMagickMemory(decode);
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((unsigned char *) NULL);
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4496f008fdcea6389206e36baf0f05c8999c7366f7bcristy          break;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *length=i;
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(decode);
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   B a s e 6 4 E n c o d e                                                   %
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Base64Encode() encodes arbitrary binary data to Base64 encoded format as
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  returns the result as a null-terminated ASCII string.  NULL is returned if
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a memory allocation failure occurs.
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the Base64Encode method is:
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      char *Base64Encode(const unsigned char *blob,const size_t blob_length,
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        size_t *encode_length)
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o blob:  A pointer to binary data to encode.
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o blob_length: the number of bytes to encode.
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o encode_length:  The number of bytes encoded.
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport char *Base64Encode(const unsigned char *blob,
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const size_t blob_length,size_t *encode_length)
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *encode;
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const unsigned char
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register size_t
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remainder;
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(blob != (const unsigned char *) NULL);
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(blob_length != 0);
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(encode_length != (size_t *) NULL);
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *encode_length=0;
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  encode=(char *) AcquireQuantumMemory(blob_length/3+4,4*sizeof(*encode));
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (encode == (char *) NULL)
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char *) NULL);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (p=blob; p < (blob+blob_length-2); p+=3)
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    encode[i++]=Base64[(int) (*p >> 2)];
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remainder=blob_length % 3;
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remainder != 0)
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ssize_t
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned char
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        code[3];
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      code[0]='\0';
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      code[1]='\0';
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      code[2]='\0';
530bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (j=0; j < (ssize_t) remainder; j++)
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        code[j]=(*p++);
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      encode[i++]=Base64[(int) (code[0] >> 2)];
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (remainder == 1)
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        encode[i++]='=';
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      encode[i++]='=';
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *encode_length=i;
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  encode[i++]='\0';
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(encode);
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C h o p P a t h C o m p o n e n t s                                       %
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ChopPathComponents() removes the number of specified file components from a
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  path.
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ChopPathComponents method is:
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      ChopPathComponents(char *path,size_t components)
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path:  The path.
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o components:  The number of components to chop.
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
570d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate void ChopPathComponents(char *path,const size_t components)
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
572bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) components; i++)
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    GetPathComponent(path,HeadPath,path);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x p a n d F i l e n a m e                                               %
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExpandFilename() expands '~' in a path.
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExpandFilename function is:
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      ExpandFilename(char *path)
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path: Specifies a pointer to a character array that contains the
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      path.
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
602d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate void ExpandFilename(char *path)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
605151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    expand_path[MagickPathExtent];
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (path == (char *) NULL)
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*path != '~')
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
611151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(expand_path,path,MagickPathExtent);
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*(path+1) == *DirectorySeparator) || (*(path+1) == '\0'))
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *home;
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Substitute ~ with $HOME.
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
620151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(expand_path,".",MagickPathExtent);
621151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) ConcatenateMagickString(expand_path,path+1,MagickPathExtent);
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      home=GetEnvironmentValue("HOME");
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (home == (char *) NULL)
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        home=GetEnvironmentValue("USERPROFILE");
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (home != (char *) NULL)
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
627151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) CopyMagickString(expand_path,home,MagickPathExtent);
628151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) ConcatenateMagickString(expand_path,path+1,MagickPathExtent);
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          home=DestroyString(home);
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_POSIX_SUPPORT) && !defined(__OS2__)
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
636151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        username[MagickPathExtent];
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register char
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      struct passwd
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *entry;
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Substitute ~ with home directory from password file.
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
647151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(username,path+1,MagickPathExtent);
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=strchr(username,'/');
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p != (char *) NULL)
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p='\0';
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      entry=getpwnam(username);
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (entry == (struct passwd *) NULL)
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return;
654151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(expand_path,entry->pw_dir,MagickPathExtent);
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p != (char *) NULL)
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
657151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) ConcatenateMagickString(expand_path,"/",MagickPathExtent);
658151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) ConcatenateMagickString(expand_path,p+1,MagickPathExtent);
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
662151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(path,expand_path,MagickPathExtent);
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x p a n d F i l e n a m e s                                             %
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
676de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  ExpandFilenames() checks each argument of the given argument array, and
677de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  expands it if they have a wildcard character.
678de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
679de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  Any coder prefix (EG: 'coder:filename') or read modifier postfix (EG:
680de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  'filename[...]') are ignored during the file the expansion, but will be
681de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  included in the final argument.  If no filename matching the meta-character
682de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  'glob' is found the original argument is returned.
683de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
684de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  For example, an argument of '*.gif[20x20]' will be replaced by the list
685de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%    'abc.gif[20x20]',  'foobar.gif[20x20]',  'xyzzy.gif[20x20]'
686de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  if such filenames exist, (in the current directory in this case).
687de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
688de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  Meta-characters handled...
689de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%     @    read a list of filenames (no further expansion performed)
690de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%     ~    At start of filename expands to HOME environemtn variable
691de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%     *    matches any string including an empty string
692de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%     ?    matches by any single character
693de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
694de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  WARNING: filenames starting with '.' (hidden files in a UNIX file system)
695de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  will never be expanded.  Attempting to epand '.*' will produce no change.
696de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
697de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  Expansion is ignored for coders "label:" "caption:" "pango:" and "vid:".
698de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%  Which provide their own '@' meta-character handling.
699de897b7fc8288eab3bbbd53d9aeeec549bf1dd61anthony%
7008a5d7f45b2ba420c8ea1e51bec48d3172814def3cristy%  You can see the results of the expansion using "Configure" log events.
701451f909cf486b03805c10c8075a4bdb8330a1dddanthony%
702451f909cf486b03805c10c8075a4bdb8330a1dddanthony%  The returned list should be freed using  DestroyStringList().
703451f909cf486b03805c10c8075a4bdb8330a1dddanthony%
704451f909cf486b03805c10c8075a4bdb8330a1dddanthony%  However the strings in the original pointed to argv are not
705451f909cf486b03805c10c8075a4bdb8330a1dddanthony%  freed  (TO BE CHECKED).  So a copy of the original pointer (and count)
706451f909cf486b03805c10c8075a4bdb8330a1dddanthony%  should be kept separate if they need to be freed later.
707451f909cf486b03805c10c8075a4bdb8330a1dddanthony%
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExpandFilenames function is:
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      status=ExpandFilenames(int *number_arguments,char ***arguments)
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o number_arguments: Specifies a pointer to an integer describing the
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      number of elements in the argument vector.
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o arguments: Specifies a pointer to a text array containing the command
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      line arguments.
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char ***arguments)
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
725151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    home_directory[MagickPathExtent],
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **vector;
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j;
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_files;
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73500976d8abcff7a3bc7b986b8105dde8d091dee61cristy  ssize_t
73600976d8abcff7a3bc7b986b8105dde8d091dee61cristy    count,
73700976d8abcff7a3bc7b986b8105dde8d091dee61cristy    parameters;
73800976d8abcff7a3bc7b986b8105dde8d091dee61cristy
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate argument vector.
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(number_arguments != (int *) NULL);
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(arguments != (char ***) NULL);
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  vector=(char **) AcquireQuantumMemory((size_t) (*number_arguments+1),
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*vector));
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (vector == (char **) NULL)
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Expand any wildcard filenames.
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *home_directory='\0';
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=0;
754bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) *number_arguments; i++)
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      **filelist,
758151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      filename[MagickPathExtent],
759151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      magick[MagickPathExtent],
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *option,
761151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      path[MagickPathExtent],
762151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      subimage[MagickPathExtent];
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      destroy;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    option=(*arguments)[i];
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *magick='\0';
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *path='\0';
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *filename='\0';
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *subimage='\0';
77254ebd8d7629c2faa0c8fb0dc97967f31c759d2d2cristy    number_files=0;
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    vector[count++]=ConstantString(option);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    destroy=MagickTrue;
775042ee78fa9004bf1ac6a95f09d9d1faca631dda1cristy    parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (parameters > 0)
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Do not expand command option parameters.
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=0; j < parameters; j++)
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          i++;
784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if (i == (ssize_t) *number_arguments)
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          option=(*arguments)[i];
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          vector[count++]=ConstantString(option);
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((*option == '"') || (*option == '\''))
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
7934b06482cd46511ecd60d280e4bbcc7ad7ce5127ecristy    GetPathComponent(option,TailPath,filename);
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    GetPathComponent(option,MagickPath,magick);
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((LocaleCompare(magick,"CAPTION") == 0) ||
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (LocaleCompare(magick,"LABEL") == 0) ||
797c0732c4dfb1cfe8d208d041a4e0ffb9ebf946593cristy        (LocaleCompare(magick,"PANGO") == 0) ||
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (LocaleCompare(magick,"VID") == 0))
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
800127425f9e916a7b731feaf585e41a03745ad401bcristy    if ((IsGlob(filename) == MagickFalse) && (*option != '@'))
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
802127425f9e916a7b731feaf585e41a03745ad401bcristy    if (*option != '@')
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Generate file list from wildcard filename (e.g. *.jpg).
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetPathComponent(option,HeadPath,path);
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetPathComponent(option,SubimagePath,subimage);
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ExpandFilename(path);
810f5ee5be3d0b257d863eed42e42e8dfd601fc3a74cristy        if (*home_directory == '\0')
811151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          getcwd_utf8(home_directory,MagickPathExtent-1);
8124b06482cd46511ecd60d280e4bbcc7ad7ce5127ecristy        filelist=ListFiles(*path == '\0' ? home_directory : path,filename,
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          &number_files);
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        char
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *files;
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ExceptionInfo
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *exception;
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
824f9218a733290c84d9838e09c7921f2f342f4f468cristy          length;
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Generate file list from file list (e.g. @filelist.txt).
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        exception=AcquireExceptionInfo();
8303a5987c75c361dde2b38579f05ca961927d842fecristy        files=FileToString(option+1,~0UL,exception);
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        exception=DestroyExceptionInfo(exception);
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (files == (char *) NULL)
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          continue;
834f9218a733290c84d9838e09c7921f2f342f4f468cristy        filelist=StringToArgv(files,&length);
835f9218a733290c84d9838e09c7921f2f342f4f468cristy        if (filelist == (char **) NULL)
836f9218a733290c84d9838e09c7921f2f342f4f468cristy          continue;
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        files=DestroyString(files);
838f9218a733290c84d9838e09c7921f2f342f4f468cristy        filelist[0]=DestroyString(filelist[0]);
839f9218a733290c84d9838e09c7921f2f342f4f468cristy        for (j=0; j < (ssize_t) (length-1); j++)
840f9218a733290c84d9838e09c7921f2f342f4f468cristy          filelist[j]=filelist[j+1];
841f9218a733290c84d9838e09c7921f2f342f4f468cristy        number_files=(size_t) length-1;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (filelist == (char **) NULL)
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
845bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (j=0; j < (ssize_t) number_files; j++)
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsPathDirectory(filelist[j]) <= 0)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
848bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    if (j == (ssize_t) number_files)
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
850bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (j=0; j < (ssize_t) number_files; j++)
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          filelist[j]=DestroyString(filelist[j]);
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        filelist=(char **) RelinquishMagickMemory(filelist);
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer file list to argument vector.
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    vector=(char **) ResizeQuantumMemory(vector,(size_t) *number_arguments+
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count+number_files+1,sizeof(*vector));
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (vector == (char **) NULL)
86162813b59088717ba4b483d62ba5682f31cdb6002dirk      {
86262813b59088717ba4b483d62ba5682f31cdb6002dirk        for (j=0; j < (ssize_t) number_files; j++)
86362813b59088717ba4b483d62ba5682f31cdb6002dirk          filelist[j]=DestroyString(filelist[j]);
86462813b59088717ba4b483d62ba5682f31cdb6002dirk        filelist=(char **) RelinquishMagickMemory(filelist);
86562813b59088717ba4b483d62ba5682f31cdb6002dirk        return(MagickFalse);
86662813b59088717ba4b483d62ba5682f31cdb6002dirk      }
867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (j=0; j < (ssize_t) number_files; j++)
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8690e526225a3ff4d4f070f3d47600134669a00c72bcristy      option=filelist[j];
870042ee78fa9004bf1ac6a95f09d9d1faca631dda1cristy      parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
8710e526225a3ff4d4f070f3d47600134669a00c72bcristy      if (parameters > 0)
8720e526225a3ff4d4f070f3d47600134669a00c72bcristy        {
873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
8740e526225a3ff4d4f070f3d47600134669a00c72bcristy            k;
8750e526225a3ff4d4f070f3d47600134669a00c72bcristy
8760e526225a3ff4d4f070f3d47600134669a00c72bcristy          /*
8770e526225a3ff4d4f070f3d47600134669a00c72bcristy            Do not expand command option parameters.
8780e526225a3ff4d4f070f3d47600134669a00c72bcristy          */
8790e526225a3ff4d4f070f3d47600134669a00c72bcristy          vector[count++]=ConstantString(option);
8800e526225a3ff4d4f070f3d47600134669a00c72bcristy          for (k=0; k < parameters; k++)
8810e526225a3ff4d4f070f3d47600134669a00c72bcristy          {
8820e526225a3ff4d4f070f3d47600134669a00c72bcristy            j++;
883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            if (j == (ssize_t) number_files)
8840e526225a3ff4d4f070f3d47600134669a00c72bcristy              break;
8850e526225a3ff4d4f070f3d47600134669a00c72bcristy            option=filelist[j];
8860e526225a3ff4d4f070f3d47600134669a00c72bcristy            vector[count++]=ConstantString(option);
8870e526225a3ff4d4f070f3d47600134669a00c72bcristy          }
8880e526225a3ff4d4f070f3d47600134669a00c72bcristy          continue;
8890e526225a3ff4d4f070f3d47600134669a00c72bcristy        }
890151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(filename,path,MagickPathExtent);
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*path != '\0')
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(filename,DirectorySeparator,
893151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          MagickPathExtent);
894aa4db030d50b21f98104b3e245dd54b7f3f53d39cristy      if (filelist[j] != (char *) NULL)
895151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) ConcatenateMagickString(filename,filelist[j],MagickPathExtent);
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      filelist[j]=DestroyString(filelist[j]);
897151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      if (strlen(filename) >= (MagickPathExtent-1))
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowFatalException(OptionFatalError,"FilenameTruncated");
89947dc34d86f6c7062924bac9ee8097b264c18ccb1cristy      if (IsPathDirectory(filename) <= 0)
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
902151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            path[MagickPathExtent];
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *path='\0';
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*magick != '\0')
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
907151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) ConcatenateMagickString(path,magick,MagickPathExtent);
908151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) ConcatenateMagickString(path,":",MagickPathExtent);
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
910151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) ConcatenateMagickString(path,filename,MagickPathExtent);
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*subimage != '\0')
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
913151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) ConcatenateMagickString(path,"[",MagickPathExtent);
914151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) ConcatenateMagickString(path,subimage,MagickPathExtent);
915151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) ConcatenateMagickString(path,"]",MagickPathExtent);
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
917151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          if (strlen(path) >= (MagickPathExtent-1))
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowFatalException(OptionFatalError,"FilenameTruncated");
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (destroy != MagickFalse)
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              count--;
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              vector[count]=DestroyString(vector[count]);
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              destroy=MagickFalse;
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          vector[count++]=ConstantString(path);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filelist=(char **) RelinquishMagickMemory(filelist);
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  vector[count]=(char *) NULL;
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (IsEventLogging() != MagickFalse)
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *command_line;
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      command_line=AcquireString(vector[0]);
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < count; i++)
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateString(&command_line," {");
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateString(&command_line,vector[i]);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateString(&command_line,"}");
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Command line: %s",command_line);
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      command_line=DestroyString(command_line);
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *number_arguments=(int) count;
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *arguments=vector;
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t E x e c u t i o n P a t h                                           %
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetExecutionPath() returns the pathname of the executable that started
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the process.  On success MagickTrue is returned, otherwise MagickFalse.
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetExecutionPath method is:
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType GetExecutionPath(char *path,const size_t extent)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path: the pathname of the executable that started the process.
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o extent: the maximum extent of the path.
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
977d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate MagickBooleanType GetExecutionPath(char *path,const size_t extent)
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
979fbe485afe671dae03d2c70e25872e5507c29dbe7cristy  char
980fbe485afe671dae03d2c70e25872e5507c29dbe7cristy    *directory;
981fbe485afe671dae03d2c70e25872e5507c29dbe7cristy
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *path='\0';
983fbe485afe671dae03d2c70e25872e5507c29dbe7cristy  directory=getcwd(path,(unsigned long) extent);
984fbe485afe671dae03d2c70e25872e5507c29dbe7cristy  (void) directory;
985fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy#if defined(MAGICKCORE_HAVE_GETPID) && defined(MAGICKCORE_HAVE_READLINK) && defined(PATH_MAX)
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
98858a33836a139776aab5f22c0fa3377a9b2b1b582cristy      execution_path[PATH_MAX+1],
98958a33836a139776aab5f22c0fa3377a9b2b1b582cristy      link_path[MagickPathExtent];
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ssize_t
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
994151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(link_path,MagickPathExtent,"/proc/%.20g/exe",
995e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) getpid());
996fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    count=readlink(link_path,execution_path,PATH_MAX);
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (count == -1)
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
999151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) FormatLocaleString(link_path,MagickPathExtent,"/proc/%.20g/file",
1000e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) getpid());
1001fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        count=readlink(link_path,execution_path,PATH_MAX);
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((count > 0) && (count <= (ssize_t) PATH_MAX))
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1005fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        execution_path[count]='\0';
1006fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        (void) CopyMagickString(path,execution_path,extent);
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE__NSGETEXECUTABLEPATH)
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      executable_path[PATH_MAX << 1],
1014fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      execution_path[PATH_MAX+1];
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    uint32_t
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length;
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=sizeof(executable_path);
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
1021fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        (realpath(executable_path,execution_path) != (char *) NULL))
1022fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      (void) CopyMagickString(path,execution_path,extent);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_GETEXECNAME)
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const char
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *execution_path;
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    execution_path=(const char *) getexecname();
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (execution_path != (const char *) NULL)
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*execution_path != *DirectorySeparator)
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(path,DirectorySeparator,extent);
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(path,execution_path,extent);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10390157aeadef2fce908277168097a160a8f15a6952cristy#if defined(MAGICKCORE_WINDOWS_SUPPORT)
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  NTGetExecutionPath(path,extent);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1042fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy#if defined(__GNU__)
1043fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy  {
1044fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    char
1045fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      *program_name,
1046fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      *execution_path;
1047fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy
1048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
1049fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      count;
1050fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy
1051fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    count=0;
1052fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    execution_path=(char *) NULL;
1053fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    program_name=program_invocation_name;
1054fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    if (*program_invocation_name != '/')
1055fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      {
1056fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        size_t
1057fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy          extent;
1058fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy
1059b29bea545c794e1cb840d87d1472f3f68580f045cristy        extent=strlen(directory)+strlen(program_name)+2;
1060fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
1061fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        if (program_name == (char *) NULL)
1062fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy          program_name=program_invocation_name;
1063fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        else
1064b29bea545c794e1cb840d87d1472f3f68580f045cristy          count=FormatLocaleString(program_name,extent,"%s/%s",directory,
1065fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy            program_invocation_name);
1066fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      }
1067fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    if (count != -1)
1068fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      {
1069fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        execution_path=realpath(program_name,NULL);
1070fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy        if (execution_path != (char *) NULL)
1071fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy          (void) CopyMagickString(path,execution_path,extent);
1072fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      }
1073fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    if (program_name != program_invocation_name)
1074fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy      program_name=(char *) RelinquishMagickMemory(program_name);
1075fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy    execution_path=(char *) RelinquishMagickMemory(execution_path);
1076fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy  }
1077fa09d14e6d511fa88c3b230e31e50fb8409c2adfcristy#endif
10788a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy#if defined(__OpenBSD__)
10798a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy  {
10808a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy    extern char
10818a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy      *__progname;
10828a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy
10838a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy    (void) CopyMagickString(path,__progname,extent);
10848a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy  }
10858a7ca3c458c39f6bdc4f038d6693fda2325d69a6cristy#endif
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(IsPathAccessible(path));
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1094688f07b92c207046de0cdfb2235becdea77ef9e3cristy%   G e t M a g i c k P a g e S i z e                                         %
1095688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
1096688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
1097688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
1098688f07b92c207046de0cdfb2235becdea77ef9e3cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099688f07b92c207046de0cdfb2235becdea77ef9e3cristy%
1100688f07b92c207046de0cdfb2235becdea77ef9e3cristy%  GetMagickPageSize() returns the memory page size.
1101688f07b92c207046de0cdfb2235becdea77ef9e3cristy%
1102688f07b92c207046de0cdfb2235becdea77ef9e3cristy%  The format of the GetMagickPageSize method is:
1103688f07b92c207046de0cdfb2235becdea77ef9e3cristy%
1104bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      ssize_t GetMagickPageSize()
1105688f07b92c207046de0cdfb2235becdea77ef9e3cristy%
1106688f07b92c207046de0cdfb2235becdea77ef9e3cristy*/
1107d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate ssize_t GetMagickPageSize(void)
1108688f07b92c207046de0cdfb2235becdea77ef9e3cristy{
1109bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  static ssize_t
1110688f07b92c207046de0cdfb2235becdea77ef9e3cristy    page_size = -1;
1111688f07b92c207046de0cdfb2235becdea77ef9e3cristy
1112688f07b92c207046de0cdfb2235becdea77ef9e3cristy  if (page_size > 0)
1113688f07b92c207046de0cdfb2235becdea77ef9e3cristy    return(page_size);
1114688f07b92c207046de0cdfb2235becdea77ef9e3cristy#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
1115ecd0ab5350482e4a2ea003705e3e0b2120b66384cristy  page_size=(ssize_t) sysconf(_SC_PAGE_SIZE);
111609449f733819b0213c4c888761289b778e51809acristy#else
1117688f07b92c207046de0cdfb2235becdea77ef9e3cristy#if defined(MAGICKCORE_HAVE_GETPAGESIZE)
1118ecd0ab5350482e4a2ea003705e3e0b2120b66384cristy  page_size=(ssize_t) getpagesize();
111909449f733819b0213c4c888761289b778e51809acristy#endif
1120688f07b92c207046de0cdfb2235becdea77ef9e3cristy#endif
1121688f07b92c207046de0cdfb2235becdea77ef9e3cristy  if (page_size <= 0)
1122688f07b92c207046de0cdfb2235becdea77ef9e3cristy    page_size=16384;
1123688f07b92c207046de0cdfb2235becdea77ef9e3cristy  return(page_size);
1124688f07b92c207046de0cdfb2235becdea77ef9e3cristy}
1125688f07b92c207046de0cdfb2235becdea77ef9e3cristy
1126688f07b92c207046de0cdfb2235becdea77ef9e3cristy/*
1127688f07b92c207046de0cdfb2235becdea77ef9e3cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
1129688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
1130688f07b92c207046de0cdfb2235becdea77ef9e3cristy%                                                                             %
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t P a t h A t t r i b u t e s                                         %
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetPathAttributes() returns attributes (e.g. size of file) about a path.
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The path of the GetPathAttributes method is:
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
114121ef17b65dbe7001236b74866985fa88257645b1cristy%      MagickBooleanType GetPathAttributes(const char *path,void *attributes)
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  path: the file path.
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  attributes: the path attributes are returned here.
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetPathAttributes(const char *path,
1151626a27b7ba3ae0d975e27a546855e3302756ce87dirk  void *attributes)
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
115321ef17b65dbe7001236b74866985fa88257645b1cristy  MagickBooleanType
115421ef17b65dbe7001236b74866985fa88257645b1cristy    status;
115521ef17b65dbe7001236b74866985fa88257645b1cristy
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (path == (const char *) NULL)
115721ef17b65dbe7001236b74866985fa88257645b1cristy    {
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      errno=EINVAL;
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1161626a27b7ba3ae0d975e27a546855e3302756ce87dirk  (void) ResetMagickMemory(attributes,0,sizeof(struct stat));
1162626a27b7ba3ae0d975e27a546855e3302756ce87dirk  status=stat_utf8(path,(struct stat *) attributes) == 0 ? MagickTrue :
1163626a27b7ba3ae0d975e27a546855e3302756ce87dirk    MagickFalse;
116421ef17b65dbe7001236b74866985fa88257645b1cristy  return(status);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t P a t h C o m p o n e n t                                           %
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetPathComponent() returns the parent directory name, filename, basename, or
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  extension of a file path.
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1181151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy%  The component string pointed to must have at least MagickPathExtent space
1182104f8932a48379d3355160642b3de6f0611a7d19anthony%  for the results to be stored.
1183104f8932a48379d3355160642b3de6f0611a7d19anthony%
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetPathComponent function is:
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      GetPathComponent(const char *path,PathType type,char *component)
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path: Specifies a pointer to a character array that contains the
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      file path.
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o type: Specififies which file path component to return.
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o component: the selected file path component is returned here.
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void GetPathComponent(const char *path,PathType type,
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char *component)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
1202f8aac35468201fc1071bcd1a54faaf11dbc96329dirk    *q;
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1207f8aac35468201fc1071bcd1a54faaf11dbc96329dirk  size_t
1208f8aac35468201fc1071bcd1a54faaf11dbc96329dirk    magick_length,
1209f8aac35468201fc1071bcd1a54faaf11dbc96329dirk    subimage_offset,
1210f8aac35468201fc1071bcd1a54faaf11dbc96329dirk    subimage_length;
1211f8aac35468201fc1071bcd1a54faaf11dbc96329dirk
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(path != (const char *) NULL);
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",path);
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(component != (char *) NULL);
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*path == '\0')
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *component='\0';
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1220151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(component,path,MagickPathExtent);
1221f8aac35468201fc1071bcd1a54faaf11dbc96329dirk  magick_length=0;
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__OS2__)
12231224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy  if (path[1] != ":")
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (p=component; *p != '\0'; p++)
12262261ef5d3357ed9869714c3313b0c657f2409e80cristy  {
12272261ef5d3357ed9869714c3313b0c657f2409e80cristy    if ((*p == '%') && (*(p+1) == '['))
12282261ef5d3357ed9869714c3313b0c657f2409e80cristy      {
122920843eaf833d31fdb6940fa95b54663f939c31edcristy        /*
123020843eaf833d31fdb6940fa95b54663f939c31edcristy          Skip over %[...].
123120843eaf833d31fdb6940fa95b54663f939c31edcristy        */
12322261ef5d3357ed9869714c3313b0c657f2409e80cristy        for (p++; (*p != ']') && (*p != '\0'); p++) ;
12332261ef5d3357ed9869714c3313b0c657f2409e80cristy        if (*p == '\0')
12342261ef5d3357ed9869714c3313b0c657f2409e80cristy          break;
12352261ef5d3357ed9869714c3313b0c657f2409e80cristy      }
12361224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy    if ((*p == ':') && (IsPathDirectory(path) < 0) &&
12371224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy        (IsPathAccessible(path) == MagickFalse))
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Look for image format specification (e.g. ps3:image).
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
1242f8aac35468201fc1071bcd1a54faaf11dbc96329dirk        *p='\0';
1243f8aac35468201fc1071bcd1a54faaf11dbc96329dirk        if (IsMagickConflict(component) != MagickFalse)
1244f8aac35468201fc1071bcd1a54faaf11dbc96329dirk          *p=':';
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
1246f8aac35468201fc1071bcd1a54faaf11dbc96329dirk          {
1247f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            magick_length=(size_t) (p-component+1);
1248f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            for (q=component; *(++p) != '\0'; q++)
12490093cffaf900a8a5708be6810fda6caf4df49099Cristy              *q=(*p);
1250f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            *q='\0';
1251f8aac35468201fc1071bcd1a54faaf11dbc96329dirk          }
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12542261ef5d3357ed9869714c3313b0c657f2409e80cristy  }
1255f8aac35468201fc1071bcd1a54faaf11dbc96329dirk  subimage_length=0;
1256f8aac35468201fc1071bcd1a54faaf11dbc96329dirk  subimage_offset=0;
12571224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy  p=component;
12581224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy  if (*p != '\0')
12591224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy    p=component+strlen(component)-1;
12601224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy  if ((*p == ']') && (strchr(component,'[') != (char *) NULL) &&
12611224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy      (IsPathAccessible(path) == MagickFalse))
12621224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy    {
12631224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy      /*
12641224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy        Look for scene specification (e.g. img0001.pcd[4]).
12651224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy      */
12661224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy      for (q=p-1; q > component; q--)
12671224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy        if (*q == '[')
12681224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy          break;
12691224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy      if (*q == '[')
12701224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy        {
1271f8aac35468201fc1071bcd1a54faaf11dbc96329dirk          *p='\0';
1272f8aac35468201fc1071bcd1a54faaf11dbc96329dirk          if ((IsSceneGeometry(q+1,MagickFalse) == MagickFalse) &&
1273f8aac35468201fc1071bcd1a54faaf11dbc96329dirk              (IsGeometry(q+1) == MagickFalse))
1274f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            *p=']';
12751224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy          else
1276f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            {
1277f8aac35468201fc1071bcd1a54faaf11dbc96329dirk              subimage_length=(size_t) (p-q);
1278f8aac35468201fc1071bcd1a54faaf11dbc96329dirk              subimage_offset=magick_length+1+(size_t) (q-component);
1279f8aac35468201fc1071bcd1a54faaf11dbc96329dirk              *q='\0';
1280f8aac35468201fc1071bcd1a54faaf11dbc96329dirk            }
12811224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy        }
12821224a9941fcdddc1c36cbc74e34c81b7fb67ce28cristy    }
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=component;
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*p != '\0')
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=component+strlen(component)-1; p > component; p--)
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsBasenameSeparator(*p) != MagickFalse)
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (type)
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case MagickPath:
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1292f8aac35468201fc1071bcd1a54faaf11dbc96329dirk      if (magick_length != 0)
1293f8aac35468201fc1071bcd1a54faaf11dbc96329dirk        (void) CopyMagickString(component,path,magick_length);
1294f8aac35468201fc1071bcd1a54faaf11dbc96329dirk      else
12950093cffaf900a8a5708be6810fda6caf4df49099Cristy        *component='\0';
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case RootPath:
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=component+(strlen(component)-1); p > component; p--)
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsBasenameSeparator(*p) != MagickFalse)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*p == '.')
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*p == '.')
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p='\0';
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case HeadPath:
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p='\0';
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case TailPath:
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsBasenameSeparator(*p) != MagickFalse)
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CopyMagickMemory((unsigned char *) component,
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (const unsigned char *) (p+1),strlen(p+1)+1);
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case BasePath:
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsBasenameSeparator(*p) != MagickFalse)
1326151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) CopyMagickString(component,p+1,MagickPathExtent);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=component+(strlen(component)-1); p > component; p--)
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*p == '.')
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p='\0';
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case ExtensionPath:
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsBasenameSeparator(*p) != MagickFalse)
1338151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) CopyMagickString(component,p+1,MagickPathExtent);
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=component;
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*p != '\0')
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (p=component+strlen(component)-1; p > component; p--)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*p == '.')
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *component='\0';
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*p == '.')
1346151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) CopyMagickString(component,p+1,MagickPathExtent);
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SubimagePath:
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1351f8aac35468201fc1071bcd1a54faaf11dbc96329dirk      if (subimage_length != 0)
1352f8aac35468201fc1071bcd1a54faaf11dbc96329dirk        (void) CopyMagickString(component,path+subimage_offset,subimage_length);
1353f8aac35468201fc1071bcd1a54faaf11dbc96329dirk      else
1354f8aac35468201fc1071bcd1a54faaf11dbc96329dirk        *component = '\0';
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case CanonicalPath:
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedPath:
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  G e t P a t h C o m p o n e n t s                                          %
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetPathComponents() returns a list of path components.
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetPathComponents method is:
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      char **GetPathComponents(const char *path,
1379bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        size_t *number_componenets)
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path:  Specifies the string to segment into a list.
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o number_components:  return the number of components in the list
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1388d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate char **GetPathComponents(const char *path,
1389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t *number_components)
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **components;
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p,
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1398bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (path == (char *) NULL)
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char **) NULL);
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *number_components=1;
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (p=path; *p != '\0'; p++)
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (IsBasenameSeparator(*p))
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*number_components)++;
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  components=(char **) AcquireQuantumMemory((size_t) *number_components+1UL,
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*components));
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (components == (char **) NULL)
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=path;
1412bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) *number_components; i++)
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (q=p; *q != '\0'; q++)
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsBasenameSeparator(*q))
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
1417151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    components[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
1418c92c1e12b1181536317d08edb3b30dd3da33eae5cristy      sizeof(**components));
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (components[i] == (char *) NULL)
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickString(components[i],p,(size_t) (q-p+1));
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=q+1;
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  components[i]=(char *) NULL;
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(components);
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  I s P a t h A c c e s s i b l e                                            %
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPathAccessible() returns MagickTrue if the file as defined by the path is
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  accessible.
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPathAccessible method is:
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
144459864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%      MagickBooleanType IsPathAccessible(const char *path)
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path:  Specifies a path to a file.
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType IsPathAccessible(const char *path)
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  struct stat
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes;
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((path == (const char *) NULL) || (*path == '\0'))
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14615a20e691a69f150368d9471a72c4378f655ad9cfCristy  if (LocaleCompare(path,"-") == 0)
14622588ecc44bc3f9367fa55ffaa10dbbce150851efCristy    return(MagickTrue);
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=GetPathAttributes(path,&attributes);
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (S_ISREG(attributes.st_mode) == 0)
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
146818c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy  if (access_utf8(path,F_OK) != 0)
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+  I s P a t h D i r e c t o r y                                              %
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPathDirectory() returns -1 if the directory does not exist,  1 is returned
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  if the path represents a directory otherwise 0.
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPathDirectory method is:
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      int IsPathDirectory(const char *path)
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  path:  The directory path.
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int IsPathDirectory(const char *path)
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  struct stat
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes;
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((path == (const char *) NULL) || (*path == '\0'))
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=GetPathAttributes(path,&attributes);
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1);
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (S_ISDIR(attributes.st_mode) == 0)
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   L i s t F i l e s                                                         %
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ListFiles() reads the directory specified and returns a list of filenames
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  contained in the directory sorted in ascending alphabetic order.
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ListFiles function is:
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      char **ListFiles(const char *directory,const char *pattern,
1531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        ssize_t *number_entries)
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o filelist: Method ListFiles returns a list of filenames contained
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      in the directory.  If the directory specified cannot be read or it is
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      a file a NULL list is returned.
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o directory: Specifies a pointer to a text string containing a directory
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      name.
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pattern: Specifies a pointer to a text string containing a pattern.
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o number_entries:  This integer returns the number of filenames in the
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      list.
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int FileCompare(const void *x,const void *y)
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **p,
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **q;
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=(const char **) x;
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=(const char **) y;
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(LocaleCompare(*p,*q));
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  struct dirent **result)
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_READDIR_R)
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(readdir_r(directory,entry,result));
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) entry;
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  errno=0;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *result=readdir(directory);
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(errno);
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1581d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristyMagickPrivate char **ListFiles(const char *directory,const char *pattern,
1582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t *number_entries)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **filelist;
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DIR
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *current_directory;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  struct dirent
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *buffer,
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    max_entries;
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open directory.
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(directory != (const char *) NULL);
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",directory);
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pattern != (const char *) NULL);
1603bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  assert(number_entries != (size_t *) NULL);
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *number_entries=0;
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  current_directory=opendir(directory);
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (current_directory == (DIR *) NULL)
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char **) NULL);
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate filelist.
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  max_entries=2048;
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  filelist=(char **) AcquireQuantumMemory((size_t) max_entries,
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*filelist));
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (filelist == (char **) NULL)
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) closedir(current_directory);
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((char **) NULL);
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Save the current and change to the new directory.
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16226e6c822ecb3c8122ca7cbf105a08b959049bce15cristy  buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1);
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (buffer == (struct dirent *) NULL)
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while ((MagickReadDirectory(current_directory,buffer,&entry) == 0) &&
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (entry != (struct dirent *) NULL))
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*entry->d_name == '.')
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((IsPathDirectory(entry->d_name) > 0) ||
16310157aeadef2fce908277168097a160a8f15a6952cristy#if defined(MAGICKCORE_WINDOWS_SUPPORT)
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (GlobExpression(entry->d_name,pattern,MagickTrue) != MagickFalse))
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (GlobExpression(entry->d_name,pattern,MagickFalse) != MagickFalse))
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*number_entries >= max_entries)
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extend the file list.
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            max_entries<<=1;
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            filelist=(char **) ResizeQuantumMemory(filelist,(size_t)
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              max_entries,sizeof(*filelist));
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (filelist == (char **) NULL)
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(vms)
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          register char
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p;
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=strchr(entry->d_name,';');
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p='\0';
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*number_entries > 0)
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (LocaleCompare(entry->d_name,filelist[*number_entries-1]) == 0)
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              continue;
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        filelist[*number_entries]=(char *) AcquireString(entry->d_name);
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (*number_entries)++;
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(struct dirent *) RelinquishMagickMemory(buffer);
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) closedir(current_directory);
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (filelist == (char **) NULL)
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char **) NULL);
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sort filelist in ascending order.
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  qsort((void *) filelist,(size_t) *number_entries,sizeof(*filelist),
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    FileCompare);
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(filelist);
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1682a21afdefe277667f7821fa90decc1f15a167eacfcristy%   M a g i c k D e l a y                                                     %
1683a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
1684a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
1685a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
1686a21afdefe277667f7821fa90decc1f15a167eacfcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1687a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1688a21afdefe277667f7821fa90decc1f15a167eacfcristy%  MagickDelay() suspends program execution for the number of milliseconds
1689a21afdefe277667f7821fa90decc1f15a167eacfcristy%  specified.
1690a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1691a21afdefe277667f7821fa90decc1f15a167eacfcristy%  The format of the Delay method is:
1692a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1693a21afdefe277667f7821fa90decc1f15a167eacfcristy%      void MagickDelay(const MagickSizeType milliseconds)
1694a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1695a21afdefe277667f7821fa90decc1f15a167eacfcristy%  A description of each parameter follows:
1696a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1697a21afdefe277667f7821fa90decc1f15a167eacfcristy%    o milliseconds: Specifies the number of milliseconds to delay before
1698a21afdefe277667f7821fa90decc1f15a167eacfcristy%      returning.
1699a21afdefe277667f7821fa90decc1f15a167eacfcristy%
1700a21afdefe277667f7821fa90decc1f15a167eacfcristy*/
170161cfa7509650b2406943f462698bd8fa093c667eCristyMagickExport void MagickDelay(const MagickSizeType milliseconds)
1702a21afdefe277667f7821fa90decc1f15a167eacfcristy{
1703a21afdefe277667f7821fa90decc1f15a167eacfcristy  if (milliseconds == 0)
1704a21afdefe277667f7821fa90decc1f15a167eacfcristy    return;
1705a21afdefe277667f7821fa90decc1f15a167eacfcristy#if defined(MAGICKCORE_HAVE_NANOSLEEP)
1706a21afdefe277667f7821fa90decc1f15a167eacfcristy  {
1707a21afdefe277667f7821fa90decc1f15a167eacfcristy    struct timespec
1708a21afdefe277667f7821fa90decc1f15a167eacfcristy      timer;
1709a21afdefe277667f7821fa90decc1f15a167eacfcristy
1710a21afdefe277667f7821fa90decc1f15a167eacfcristy    timer.tv_sec=(time_t) (milliseconds/1000);
1711a21afdefe277667f7821fa90decc1f15a167eacfcristy    timer.tv_nsec=(milliseconds % 1000)*1000*1000;
1712a21afdefe277667f7821fa90decc1f15a167eacfcristy    (void) nanosleep(&timer,(struct timespec *) NULL);
1713a21afdefe277667f7821fa90decc1f15a167eacfcristy  }
1714a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(MAGICKCORE_HAVE_USLEEP)
1715a21afdefe277667f7821fa90decc1f15a167eacfcristy  usleep(1000*milliseconds);
1716a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(MAGICKCORE_HAVE_SELECT)
1717a21afdefe277667f7821fa90decc1f15a167eacfcristy  {
1718a21afdefe277667f7821fa90decc1f15a167eacfcristy    struct timeval
1719a21afdefe277667f7821fa90decc1f15a167eacfcristy      timer;
1720a21afdefe277667f7821fa90decc1f15a167eacfcristy
1721a21afdefe277667f7821fa90decc1f15a167eacfcristy    timer.tv_sec=(long) milliseconds/1000;
1722a21afdefe277667f7821fa90decc1f15a167eacfcristy    timer.tv_usec=(long) (milliseconds % 1000)*1000;
1723a21afdefe277667f7821fa90decc1f15a167eacfcristy    (void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer);
1724a21afdefe277667f7821fa90decc1f15a167eacfcristy  }
1725a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(MAGICKCORE_HAVE_POLL)
1726a21afdefe277667f7821fa90decc1f15a167eacfcristy  (void) poll((struct pollfd *) NULL,0,(int) milliseconds);
1727a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1728a21afdefe277667f7821fa90decc1f15a167eacfcristy  Sleep((long) milliseconds);
1729a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(vms)
1730a21afdefe277667f7821fa90decc1f15a167eacfcristy  {
1731a21afdefe277667f7821fa90decc1f15a167eacfcristy    float
1732a21afdefe277667f7821fa90decc1f15a167eacfcristy      timer;
1733a21afdefe277667f7821fa90decc1f15a167eacfcristy
1734a21afdefe277667f7821fa90decc1f15a167eacfcristy    timer=milliseconds/1000.0;
1735a21afdefe277667f7821fa90decc1f15a167eacfcristy    lib$wait(&timer);
1736a21afdefe277667f7821fa90decc1f15a167eacfcristy  }
1737a21afdefe277667f7821fa90decc1f15a167eacfcristy#elif defined(__BEOS__)
1738a21afdefe277667f7821fa90decc1f15a167eacfcristy  snooze(1000*milliseconds);
1739a21afdefe277667f7821fa90decc1f15a167eacfcristy#else
1740a21afdefe277667f7821fa90decc1f15a167eacfcristy# error "Time delay method not defined."
1741a21afdefe277667f7821fa90decc1f15a167eacfcristy#endif
1742a21afdefe277667f7821fa90decc1f15a167eacfcristy}
1743a21afdefe277667f7821fa90decc1f15a167eacfcristy
1744a21afdefe277667f7821fa90decc1f15a167eacfcristy/*
1745a21afdefe277667f7821fa90decc1f15a167eacfcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1746a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
1747a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
1748a21afdefe277667f7821fa90decc1f15a167eacfcristy%                                                                             %
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  M u l t i l i n e C e n s u s                                              %
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MultilineCensus() returns the number of lines within a label.  A line is
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  represented by a \n character.
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the MultilineCenus method is:
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t MultilineCensus(const char *label)
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   o  label:  This character string is the label.
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport size_t MultilineCensus(const char *label)
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1769bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_lines;
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine the number of lines within this label.
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (label == (char *) NULL)
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (number_lines=1; *label != '\0'; label++)
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*label == '\n')
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      number_lines++;
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(number_lines);
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
17887fb986b2b49cd759838497e5f66ccdfe624d74b4dirk%   S h r e d F i l e                                                         %
178959864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%                                                                             %
179059864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%                                                                             %
179159864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%                                                                             %
179259864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179359864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
1794403ae7b98805d29da82152f8874d2d0936ba0fe0cristy%  ShredFile() overwrites the specified file with zeros or random data and then
1795403ae7b98805d29da82152f8874d2d0936ba0fe0cristy%  removes it.  The overwrite is optional and is only required to help keep
17963c91e2db88187a992c9770fd4e5b4d64555fc457cristy%  the contents of the file private.  On the first pass, the file is zeroed.
17973c91e2db88187a992c9770fd4e5b4d64555fc457cristy%  For subsequent passes, random data is written.
179859864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
179959864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%  The format of the ShredFile method is:
180059864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
180159864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%      MagickBooleanType ShredFile(const char *path)
180259864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
180359864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%  A description of each parameter follows.
180459864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
180559864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%    o path:  Specifies a path to a file.
180659864563ee5f8d9589af5b2ef45a3c098a1081d5cristy%
180759864563ee5f8d9589af5b2ef45a3c098a1081d5cristy*/
180859864563ee5f8d9589af5b2ef45a3c098a1081d5cristyMagickPrivate MagickBooleanType ShredFile(const char *path)
180959864563ee5f8d9589af5b2ef45a3c098a1081d5cristy{
1810403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  char
18113c91e2db88187a992c9770fd4e5b4d64555fc457cristy    *passes;
1812403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
181359864563ee5f8d9589af5b2ef45a3c098a1081d5cristy  int
1814403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    file,
181559864563ee5f8d9589af5b2ef45a3c098a1081d5cristy    status;
181659864563ee5f8d9589af5b2ef45a3c098a1081d5cristy
1817403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  MagickSizeType
1818403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    length;
1819403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1820403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  register ssize_t
1821403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    i;
1822403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1823403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  size_t
1824403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    quantum;
1825403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1826403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  struct stat
1827403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    file_stats;
1828403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
182959864563ee5f8d9589af5b2ef45a3c098a1081d5cristy  if ((path == (const char *) NULL) || (*path == '\0'))
183059864563ee5f8d9589af5b2ef45a3c098a1081d5cristy    return(MagickFalse);
18318a23f66e2fa9503367f7b85f73d984a5e7b6d384cristy  passes=GetEnvironmentValue("MAGICK_SHRED_PASSES");
18323c91e2db88187a992c9770fd4e5b4d64555fc457cristy  if (passes == (char *) NULL)
1833403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    {
1834403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      /*
1835403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        Don't shred the file, just remove it.
1836403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      */
1837403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      status=remove_utf8(path);
1838403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      if (status == -1)
18397fb986b2b49cd759838497e5f66ccdfe624d74b4dirk        {
18407fb986b2b49cd759838497e5f66ccdfe624d74b4dirk          (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
18417fb986b2b49cd759838497e5f66ccdfe624d74b4dirk            "Failed to remove: %s",path);
18427fb986b2b49cd759838497e5f66ccdfe624d74b4dirk          return(MagickFalse);
18437fb986b2b49cd759838497e5f66ccdfe624d74b4dirk        }
1844403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      return(MagickTrue);
1845403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    }
1846403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  file=open_utf8(path,O_WRONLY | O_EXCL | O_BINARY,S_MODE);
1847403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  if (file == -1)
1848d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy    {
1849d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy      /*
1850d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy        Don't shred the file, just remove it.
1851d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy      */
1852c56b56a57ca7159568e8d60b987dee51f5b6f438dirk      passes=DestroyString(passes);
1853d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy      status=remove_utf8(path);
18547fb986b2b49cd759838497e5f66ccdfe624d74b4dirk      if (status == -1)
18557fb986b2b49cd759838497e5f66ccdfe624d74b4dirk        (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
18567fb986b2b49cd759838497e5f66ccdfe624d74b4dirk          "Failed to remove: %s",path);
1857d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy      return(MagickFalse);
1858d2ce3601d1805fa4da0524fdfa728aed9c1d05eccristy    }
1859403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  /*
1860403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    Shred the file.
1861403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  */
1862403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  quantum=(size_t) MagickMaxBufferExtent;
1863f201ba6ae86e22ff3a61ec2e92a62f0799821314cristy  if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1864f201ba6ae86e22ff3a61ec2e92a62f0799821314cristy    quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1865403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  length=(MagickSizeType) file_stats.st_size;
186694cc10eea67454cf3630feb2c7e1c2581b65ddfbcristy  for (i=0; i < (ssize_t) StringToInteger(passes); i++)
1867403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  {
1868403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    RandomInfo
1869403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      *random_info;
1870403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
18716e31dc7107e03d618d2399f7b43fda985ab55036cristy    register MagickOffsetType
1872403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      j;
1873403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1874403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    ssize_t
1875403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      count;
1876403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1877403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    if (lseek(file,0,SEEK_SET) < 0)
1878403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      break;
1879403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    random_info=AcquireRandomInfo();
18806e31dc7107e03d618d2399f7b43fda985ab55036cristy    for (j=0; j < (MagickOffsetType) length; j+=count)
1881403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    {
1882403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      StringInfo
1883403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        *key;
1884403ae7b98805d29da82152f8874d2d0936ba0fe0cristy
1885403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      key=GetRandomKey(random_info,quantum);
1886689d9855419aa8be797e93a171cfd54666172137cristy      if (i == 0)
1887403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        ResetStringInfo(key);  /* zero on first pass */
1888403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      count=write(file,GetStringInfoDatum(key),(size_t)
1889403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        MagickMin(quantum,length-j));
1890403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      key=DestroyStringInfo(key);
1891403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      if (count <= 0)
1892403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        {
1893403ae7b98805d29da82152f8874d2d0936ba0fe0cristy          count=0;
1894403ae7b98805d29da82152f8874d2d0936ba0fe0cristy          if (errno != EINTR)
1895403ae7b98805d29da82152f8874d2d0936ba0fe0cristy            break;
1896403ae7b98805d29da82152f8874d2d0936ba0fe0cristy        }
1897403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    }
1898403ae7b98805d29da82152f8874d2d0936ba0fe0cristy    random_info=DestroyRandomInfo(random_info);
18992a927fa5e4e90dd7e59a8526269bb41094de7cb4cristy    if (j < (MagickOffsetType) length)
1900403ae7b98805d29da82152f8874d2d0936ba0fe0cristy      break;
1901403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  }
1902403ae7b98805d29da82152f8874d2d0936ba0fe0cristy  status=close(file);
190359864563ee5f8d9589af5b2ef45a3c098a1081d5cristy  status=remove_utf8(path);
1904c56b56a57ca7159568e8d60b987dee51f5b6f438dirk  if (status != -1)
1905c56b56a57ca7159568e8d60b987dee51f5b6f438dirk    status=StringToInteger(passes);
1906c56b56a57ca7159568e8d60b987dee51f5b6f438dirk  passes=DestroyString(passes);
1907c56b56a57ca7159568e8d60b987dee51f5b6f438dirk  return((status == -1 || i < (ssize_t) status) ? MagickFalse : MagickTrue);
190859864563ee5f8d9589af5b2ef45a3c098a1081d5cristy}
1909