utility.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %             U   U  TTTTT  IIIII  L      IIIII  TTTTT  Y   Y                 %
00007 %             U   U    T      I    L        I      T     Y Y                  %
00008 %             U   U    T      I    L        I      T      Y                   %
00009 %             U   U    T      I    L        I      T      Y                   %
00010 %              UUU     T    IIIII  LLLLL  IIIII    T      Y                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                       MagickCore Utility Methods                            %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                              January 1993                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "magick/studio.h"
00043 #include "magick/property.h"
00044 #include "magick/blob.h"
00045 #include "magick/color.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/geometry.h"
00049 #include "magick/list.h"
00050 #include "magick/log.h"
00051 #include "magick/memory_.h"
00052 #include "magick/option.h"
00053 #include "magick/policy.h"
00054 #include "magick/resource_.h"
00055 #include "magick/semaphore.h"
00056 #include "magick/signature-private.h"
00057 #include "magick/statistic.h"
00058 #include "magick/string_.h"
00059 #include "magick/token.h"
00060 #include "magick/utility.h"
00061 #if defined(MAGICKCORE_HAVE_MACH_O_DYLD_H)
00062 #include <mach-o/dyld.h>
00063 #endif
00064 
00065 /*
00066   Static declarations.
00067 */
00068 static const char
00069   Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00070 
00071 /*
00072   Forward declaration.
00073 */
00074 static int
00075   IsPathDirectory(const char *);
00076 
00077 /*
00078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00079 %                                                                             %
00080 %                                                                             %
00081 %                                                                             %
00082 %   A c q u i r e U n i q u e F i l e n a m e                                 %
00083 %                                                                             %
00084 %                                                                             %
00085 %                                                                             %
00086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00087 %
00088 %  AcquireUniqueFilename() replaces the contents of path by a unique path name.
00089 %
00090 %  The format of the AcquireUniqueFilename method is:
00091 %
00092 %      MagickBooleanType AcquireUniqueFilename(char *path)
00093 %
00094 %  A description of each parameter follows.
00095 %
00096 %   o  path:  Specifies a pointer to an array of characters.  The unique path
00097 %      name is returned in this array.
00098 %
00099 */
00100 MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
00101 {
00102   int
00103     file;
00104 
00105   file=AcquireUniqueFileResource(path);
00106   if (file == -1)
00107     return(MagickFalse);
00108   file=close(file)-1;
00109   return(MagickTrue);
00110 }
00111 
00112 /*
00113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00114 %                                                                             %
00115 %                                                                             %
00116 %                                                                             %
00117 %   A c q u i r e U n i q u e S ym b o l i c L i n k                          %
00118 %                                                                             %
00119 %                                                                             %
00120 %                                                                             %
00121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00122 %
00123 %  AcquireUniqueSymbolicLink() creates a unique symbolic link to the specified
00124 %  source path and returns MagickTrue on success otherwise MagickFalse.  If the
00125 %  symlink() method fails or is not available, a unique file name is generated
00126 %  and the source file copied to it.  When you are finished with the file, use
00127 %  RelinquishUniqueFilename() to destroy it.
00128 %
00129 %  The format of the AcquireUniqueSymbolicLink method is:
00130 %
00131 %      MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
00132 %        char destination)
00133 %
00134 %  A description of each parameter follows.
00135 %
00136 %   o  source:  the source path.
00137 %
00138 %   o  destination:  the destination path.
00139 %
00140 */
00141 
00142 static inline size_t MagickMin(const size_t x,const size_t y)
00143 {
00144   if (x < y)
00145     return(x);
00146   return(y);
00147 }
00148 
00149 MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
00150   char *destination)
00151 {
00152   int
00153     destination_file,
00154     source_file;
00155 
00156   size_t
00157     length,
00158     quantum;
00159 
00160   ssize_t
00161     count;
00162 
00163   struct stat
00164     attributes;
00165 
00166   unsigned char
00167     *buffer;
00168 
00169   assert(source != (const char *) NULL);
00170   assert(destination != (char *) NULL);
00171 #if defined(MAGICKCORE_HAVE_SYMLINK)
00172   (void) AcquireUniqueFilename(destination);
00173   (void) RelinquishUniqueFileResource(destination);
00174   if (*source == *DirectorySeparator)
00175     {
00176       if (symlink(source,destination) == 0)
00177         return(MagickTrue);
00178     }
00179   else
00180     {
00181       char
00182         path[MaxTextExtent];
00183 
00184       *path='\0';
00185       if (getcwd(path,MaxTextExtent) == (char *) NULL)
00186         return(MagickFalse);
00187       (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
00188       (void) ConcatenateMagickString(path,source,MaxTextExtent);
00189       if (symlink(path,destination) == 0)
00190         return(MagickTrue);
00191     }
00192 #endif
00193   destination_file=AcquireUniqueFileResource(destination);
00194   if (destination_file == -1)
00195     return(MagickFalse);
00196   source_file=open(source,O_RDONLY | O_BINARY);
00197   if (source_file == -1)
00198     {
00199       (void) close(destination_file);
00200       (void) RelinquishUniqueFileResource(destination);
00201       return(MagickFalse);
00202     }
00203   quantum=(size_t) MagickMaxBufferExtent;
00204   if ((fstat(source_file,&attributes) == 0) && (attributes.st_size != 0))
00205     quantum=MagickMin((size_t) attributes.st_size,MagickMaxBufferExtent);
00206   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
00207   if (buffer == (unsigned char *) NULL)
00208     {
00209       (void) close(source_file);
00210       (void) close(destination_file);
00211       (void) RelinquishUniqueFileResource(destination);
00212       return(MagickFalse);
00213     }
00214   for (length=0; ; )
00215   {
00216     count=(ssize_t) read(source_file,buffer,quantum);
00217     if (count <= 0)
00218       break;
00219     length=(size_t) count;
00220     count=(ssize_t) write(destination_file,buffer,length);
00221     if ((size_t) count != length)
00222       {
00223         (void) close(destination_file);
00224         (void) close(source_file);
00225         buffer=(unsigned char *) RelinquishMagickMemory(buffer);
00226         (void) RelinquishUniqueFileResource(destination);
00227         return(MagickFalse);
00228       }
00229   }
00230   (void) close(destination_file);
00231   (void) close(source_file);
00232   buffer=(unsigned char *) RelinquishMagickMemory(buffer);
00233   return(MagickTrue);
00234 }
00235 
00236 /*
00237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00238 %                                                                             %
00239 %                                                                             %
00240 %                                                                             %
00241 %  A p p e n d I m a g e F o r m a t                                          %
00242 %                                                                             %
00243 %                                                                             %
00244 %                                                                             %
00245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00246 %
00247 %  AppendImageFormat() appends the image format type to the filename.  If an
00248 %  extension to the file already exists, it is first removed.
00249 %
00250 %  The format of the AppendImageFormat method is:
00251 %
00252 %      void AppendImageFormat(const char *format,char *filename)
00253 %
00254 %  A description of each parameter follows.
00255 %
00256 %   o  format:  Specifies a pointer to an array of characters.  This the
00257 %      format of the image.
00258 %
00259 %   o  filename:  Specifies a pointer to an array of characters.  The unique
00260 %      file name is returned in this array.
00261 %
00262 */
00263 MagickExport void AppendImageFormat(const char *format,char *filename)
00264 {
00265   char
00266     root[MaxTextExtent];
00267 
00268   assert(format != (char *) NULL);
00269   assert(filename != (char *) NULL);
00270   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00271   if ((*format == '\0') || (*filename == '\0'))
00272     return;
00273   if (LocaleCompare(filename,"-") == 0)
00274     {
00275       char
00276         message[MaxTextExtent];
00277 
00278       (void) FormatMagickString(message,MaxTextExtent,"%s:%s",format,filename);
00279       (void) CopyMagickString(filename,message,MaxTextExtent);
00280       return;
00281     }
00282   GetPathComponent(filename,RootPath,root);
00283   (void) FormatMagickString(filename,MaxTextExtent,"%s.%s",root,format);
00284 }
00285 
00286 /*
00287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00288 %                                                                             %
00289 %                                                                             %
00290 %                                                                             %
00291 %   B a s e 6 4 D e c o d e                                                   %
00292 %                                                                             %
00293 %                                                                             %
00294 %                                                                             %
00295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00296 %
00297 %  Base64Decode() decodes Base64-encoded text and returns its binary
00298 %  equivalent.  NULL is returned if the text is not valid Base64 data, or a
00299 %  memory allocation failure occurs.
00300 %
00301 %  The format of the Base64Decode method is:
00302 %
00303 %      unsigned char *Base64Decode(const char *source,length_t *length)
00304 %
00305 %  A description of each parameter follows:
00306 %
00307 %    o source:  A pointer to a Base64-encoded string.
00308 %
00309 %    o length: the number of bytes decoded.
00310 %
00311 */
00312 MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
00313 {
00314   int
00315     state;
00316 
00317   register const char
00318     *p,
00319     *q;
00320 
00321   register size_t
00322     i;
00323 
00324   unsigned char
00325     *decode;
00326 
00327   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00328   assert(source != (char *) NULL);
00329   assert(length != (size_t *) NULL);
00330   *length=0;
00331   decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4,
00332     3*sizeof(*decode));
00333   if (decode == (unsigned char *) NULL)
00334     return((unsigned char *) NULL);
00335   i=0;
00336   state=0;
00337   for (p=source; *p != '\0'; p++)
00338   {
00339     if (isspace((int) ((unsigned char) *p)) != 0)
00340       continue;
00341     if (*p == '=')
00342       break;
00343     q=strchr(Base64,*p);
00344     if (q == (char *) NULL)
00345       {
00346         decode=(unsigned char *) RelinquishMagickMemory(decode);
00347         return((unsigned char *) NULL);  /* non-Base64 character */
00348       }
00349     switch (state)
00350     {
00351       case 0:
00352       {
00353         decode[i]=(q-Base64) << 2;
00354         state++;
00355         break;
00356       }
00357       case 1:
00358       {
00359         decode[i++]|=(q-Base64) >> 4;
00360         decode[i]=((q-Base64) & 0x0f) << 4;
00361         state++;
00362         break;
00363       }
00364       case 2:
00365       {
00366         decode[i++]|=(q-Base64) >> 2;
00367         decode[i]=((q-Base64) & 0x03) << 6;
00368         state++;
00369         break;
00370       }
00371       case 3:
00372       {
00373         decode[i++]|=(q-Base64);
00374         state=0;
00375         break;
00376       }
00377     }
00378   }
00379   /*
00380     Verify Base-64 string has proper terminal characters.
00381   */
00382   if (*p != '=')
00383     {
00384       if (state != 0)
00385         {
00386           decode=(unsigned char *) RelinquishMagickMemory(decode);
00387           return((unsigned char *) NULL);
00388         }
00389     }
00390   else
00391     {
00392       p++;
00393       switch (state)
00394       {
00395         case 0:
00396         case 1:
00397         {
00398           /*
00399             Unrecognized '=' character.
00400           */
00401           decode=(unsigned char *) RelinquishMagickMemory(decode);
00402           return((unsigned char *) NULL);
00403         }
00404         case 2:
00405         {
00406           for ( ; *p != '\0'; p++)
00407             if (isspace((int) ((unsigned char) *p)) == 0)
00408               break;
00409           if (*p != '=')
00410             {
00411               decode=(unsigned char *) RelinquishMagickMemory(decode);
00412               return((unsigned char *) NULL);
00413             }
00414           p++;
00415         }
00416         case 3:
00417         {
00418           for ( ; *p != '\0'; p++)
00419             if (isspace((int) ((unsigned char) *p)) == 0)
00420               {
00421                 decode=(unsigned char *) RelinquishMagickMemory(decode);
00422                 return((unsigned char *) NULL);
00423               }
00424           if ((int) decode[i] != 0)
00425             {
00426               decode=(unsigned char *) RelinquishMagickMemory(decode);
00427               return((unsigned char *) NULL);
00428             }
00429         }
00430       }
00431     }
00432   *length=i;
00433   return(decode);
00434 }
00435 
00436 /*
00437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00438 %                                                                             %
00439 %                                                                             %
00440 %                                                                             %
00441 %   B a s e 6 4 E n c o d e                                                   %
00442 %                                                                             %
00443 %                                                                             %
00444 %                                                                             %
00445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00446 %
00447 %  Base64Encode() encodes arbitrary binary data to Base64 encoded format as
00448 %  described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
00449 %  returns the result as a null-terminated ASCII string.  NULL is returned if
00450 %  a memory allocation failure occurs.
00451 %
00452 %  The format of the Base64Encode method is:
00453 %
00454 %      char *Base64Encode(const unsigned char *blob,const size_t blob_length,
00455 %        size_t *encode_length)
00456 %
00457 %  A description of each parameter follows:
00458 %
00459 %    o blob:  A pointer to binary data to encode.
00460 %
00461 %    o blob_length: the number of bytes to encode.
00462 %
00463 %    o encode_length:  The number of bytes encoded.
00464 %
00465 */
00466 MagickExport char *Base64Encode(const unsigned char *blob,
00467   const size_t blob_length,size_t *encode_length)
00468 {
00469   char
00470     *encode;
00471 
00472   register const unsigned char
00473     *p;
00474 
00475   register size_t
00476     i;
00477 
00478   size_t
00479     remainder;
00480 
00481   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00482   assert(blob != (const unsigned char *) NULL);
00483   assert(blob_length != 0);
00484   assert(encode_length != (size_t *) NULL);
00485   *encode_length=0;
00486   encode=(char *) AcquireQuantumMemory(blob_length/3+4,4*sizeof(*encode));
00487   if (encode == (char *) NULL)
00488     return((char *) NULL);
00489   i=0;
00490   for (p=blob; p < (blob+blob_length-2); p+=3)
00491   {
00492     encode[i++]=Base64[(int) (*p >> 2)];
00493     encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
00494     encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
00495     encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
00496   }
00497   remainder=blob_length % 3;
00498   if (remainder != 0)
00499     {
00500       long
00501         j;
00502 
00503       unsigned char
00504         code[3];
00505 
00506       code[0]='\0';
00507       code[1]='\0';
00508       code[2]='\0';
00509       for (j=0; j < (long) remainder; j++)
00510         code[j]=(*p++);
00511       encode[i++]=Base64[(int) (code[0] >> 2)];
00512       encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
00513       if (remainder == 1)
00514         encode[i++]='=';
00515       else
00516         encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
00517       encode[i++]='=';
00518     }
00519   *encode_length=i;
00520   encode[i++]='\0';
00521   return(encode);
00522 }
00523 
00524 /*
00525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00526 %                                                                             %
00527 %                                                                             %
00528 %                                                                             %
00529 %   C h o p P a t h C o m p o n e n t s                                       %
00530 %                                                                             %
00531 %                                                                             %
00532 %                                                                             %
00533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00534 %
00535 %  ChopPathComponents() removes the number of specified file components from a
00536 %  path.
00537 %
00538 %  The format of the ChopPathComponents method is:
00539 %
00540 %      ChopPathComponents(char *path,unsigned long components)
00541 %
00542 %  A description of each parameter follows:
00543 %
00544 %    o path:  The path.
00545 %
00546 %    o components:  The number of components to chop.
00547 %
00548 */
00549 MagickExport void ChopPathComponents(char *path,const unsigned long components)
00550 {
00551   register long
00552     i;
00553 
00554   for (i=0; i < (long) components; i++)
00555     GetPathComponent(path,HeadPath,path);
00556 }
00557 
00558 /*
00559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00560 %                                                                             %
00561 %                                                                             %
00562 %                                                                             %
00563 %   E x p a n d F i l e n a m e                                               %
00564 %                                                                             %
00565 %                                                                             %
00566 %                                                                             %
00567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00568 %
00569 %  ExpandFilename() expands '~' in a path.
00570 %
00571 %  The format of the ExpandFilename function is:
00572 %
00573 %      ExpandFilename(char *path)
00574 %
00575 %  A description of each parameter follows:
00576 %
00577 %    o path: Specifies a pointer to a character array that contains the
00578 %      path.
00579 %
00580 */
00581 MagickExport void ExpandFilename(char *path)
00582 {
00583   char
00584     expand_path[MaxTextExtent];
00585 
00586   if (path == (char *) NULL)
00587     return;
00588   if (*path != '~')
00589     return;
00590   (void) CopyMagickString(expand_path,path,MaxTextExtent);
00591   if ((*(path+1) == *DirectorySeparator) || (*(path+1) == '\0'))
00592     {
00593       char
00594         *home;
00595 
00596       /*
00597         Substitute ~ with $HOME.
00598       */
00599       (void) CopyMagickString(expand_path,".",MaxTextExtent);
00600       (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent);
00601       home=GetEnvironmentValue("HOME");
00602       if (home == (char *) NULL)
00603         home=GetEnvironmentValue("USERPROFILE");
00604       if (home != (char *) NULL)
00605         {
00606           (void) CopyMagickString(expand_path,home,MaxTextExtent);
00607           (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent);
00608           home=DestroyString(home);
00609         }
00610     }
00611   else
00612     {
00613 #if defined(MAGICKCORE_POSIX_SUPPORT) && !defined(__OS2__)
00614       char
00615         username[MaxTextExtent];
00616 
00617       register char
00618         *p;
00619 
00620       struct passwd
00621         *entry;
00622 
00623       /*
00624         Substitute ~ with home directory from password file.
00625       */
00626       (void) CopyMagickString(username,path+1,MaxTextExtent);
00627       p=strchr(username,'/');
00628       if (p != (char *) NULL)
00629         *p='\0';
00630       entry=getpwnam(username);
00631       if (entry == (struct passwd *) NULL)
00632         return;
00633       (void) CopyMagickString(expand_path,entry->pw_dir,MaxTextExtent);
00634       if (p != (char *) NULL)
00635         {
00636           (void) ConcatenateMagickString(expand_path,"/",MaxTextExtent);
00637           (void) ConcatenateMagickString(expand_path,p+1,MaxTextExtent);
00638         }
00639 #endif
00640     }
00641   (void) CopyMagickString(path,expand_path,MaxTextExtent);
00642 }
00643 
00644 /*
00645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00646 %                                                                             %
00647 %                                                                             %
00648 %                                                                             %
00649 %   E x p a n d F i l e n a m e s                                             %
00650 %                                                                             %
00651 %                                                                             %
00652 %                                                                             %
00653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00654 %
00655 %  ExpandFilenames() checks each argument of the command line vector and
00656 %  expands it if they have a wildcard character.  For example, *.jpg might
00657 %  expand to:  bird.jpg rose.jpg tiki.jpg.
00658 %
00659 %  The format of the ExpandFilenames function is:
00660 %
00661 %      status=ExpandFilenames(int *number_arguments,char ***arguments)
00662 %
00663 %  A description of each parameter follows:
00664 %
00665 %    o number_arguments: Specifies a pointer to an integer describing the
00666 %      number of elements in the argument vector.
00667 %
00668 %    o arguments: Specifies a pointer to a text array containing the command
00669 %      line arguments.
00670 %
00671 */
00672 MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
00673   char ***arguments)
00674 {
00675   char
00676     *cwd,
00677     home_directory[MaxTextExtent],
00678     **vector;
00679 
00680   long
00681     count,
00682     parameters;
00683 
00684   register long
00685     i,
00686     j;
00687 
00688   unsigned long
00689     number_files;
00690 
00691   /*
00692     Allocate argument vector.
00693   */
00694   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00695   assert(number_arguments != (int *) NULL);
00696   assert(arguments != (char ***) NULL);
00697   vector=(char **) AcquireQuantumMemory((size_t) (*number_arguments+1),
00698     sizeof(*vector));
00699   if (vector == (char **) NULL)
00700     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00701   /*
00702     Expand any wildcard filenames.
00703   */
00704   *home_directory='\0';
00705   count=0;
00706   for (i=0; i < (long) *number_arguments; i++)
00707   {
00708     char
00709       **filelist,
00710       filename[MaxTextExtent],
00711       magick[MaxTextExtent],
00712       *option,
00713       path[MaxTextExtent],
00714       subimage[MaxTextExtent];
00715 
00716     MagickBooleanType
00717       destroy;
00718 
00719     option=(*arguments)[i];
00720     *magick='\0';
00721     *path='\0';
00722     *filename='\0';
00723     *subimage='\0';
00724     vector[count++]=ConstantString(option);
00725     destroy=MagickTrue;
00726     parameters=ParseMagickOption(MagickCommandOptions,MagickFalse,option);
00727     if (parameters > 0)
00728       {
00729         /*
00730           Do not expand command option parameters.
00731         */
00732         for (j=0; j < parameters; j++)
00733         {
00734           i++;
00735           if (i == (long) *number_arguments)
00736             break;
00737           option=(*arguments)[i];
00738           vector[count++]=ConstantString(option);
00739         }
00740         continue;
00741       }
00742     if ((*option == '"') || (*option == '\''))
00743       continue;
00744     GetPathComponent(option,TailPath,filename);
00745     GetPathComponent(option,MagickPath,magick);
00746     if ((LocaleCompare(magick,"CAPTION") == 0) ||
00747         (LocaleCompare(magick,"LABEL") == 0) ||
00748         (LocaleCompare(magick,"VID") == 0))
00749       continue;
00750     if ((IsGlob(filename) == MagickFalse) && (*filename != '@'))
00751       continue;
00752     if (*filename != '@')
00753       {
00754         /*
00755           Generate file list from wildcard filename (e.g. *.jpg).
00756         */
00757         GetPathComponent(option,HeadPath,path);
00758         GetPathComponent(option,SubimagePath,subimage);
00759         ExpandFilename(path);
00760         if (*home_directory == '\0')
00761           cwd=getcwd(home_directory,MaxTextExtent-1);
00762         filelist=ListFiles(*path == '\0' ? home_directory : path,filename,
00763           &number_files);
00764       }
00765     else
00766       {
00767         char
00768           *files;
00769 
00770         ExceptionInfo
00771           *exception;
00772 
00773         int
00774           number_images;
00775 
00776         /*
00777           Generate file list from file list (e.g. @filelist.txt).
00778         */
00779         exception=AcquireExceptionInfo();
00780         files=FileToString(filename+1,~0,exception);
00781         exception=DestroyExceptionInfo(exception);
00782         if (files == (char *) NULL)
00783           continue;
00784         StripString(files);
00785         filelist=StringToArgv(files,&number_images);
00786         files=DestroyString(files);
00787         number_files=(unsigned long) number_images;
00788         if (filelist != (char **) NULL)
00789           {
00790             number_files--;
00791             for (j=0; j < (long) number_files; j++)
00792               filelist[j]=filelist[j+1];
00793           }
00794       }
00795     if (filelist == (char **) NULL)
00796       continue;
00797     for (j=0; j < (long) number_files; j++)
00798       if (IsPathDirectory(filelist[j]) <= 0)
00799         break;
00800     if (j == (long) number_files)
00801       {
00802         for (j=0; j < (long) number_files; j++)
00803           filelist[j]=DestroyString(filelist[j]);
00804         filelist=(char **) RelinquishMagickMemory(filelist);
00805         continue;
00806       }
00807     /*
00808       Transfer file list to argument vector.
00809     */
00810     vector=(char **) ResizeQuantumMemory(vector,(size_t) *number_arguments+
00811       count+number_files+1,sizeof(*vector));
00812     if (vector == (char **) NULL)
00813       return(MagickFalse);
00814     for (j=0; j < (long) number_files; j++)
00815     {
00816       (void) CopyMagickString(filename,path,MaxTextExtent);
00817       if (*path != '\0')
00818         (void) ConcatenateMagickString(filename,DirectorySeparator,
00819           MaxTextExtent);
00820       (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
00821       filelist[j]=DestroyString(filelist[j]);
00822       if (strlen(filename) >= MaxTextExtent)
00823         ThrowFatalException(OptionFatalError,"FilenameTruncated");
00824       if (IsPathDirectory(filename) == 0)
00825         {
00826           char
00827             path[MaxTextExtent];
00828 
00829           *path='\0';
00830           if (*magick != '\0')
00831             {
00832               (void) ConcatenateMagickString(path,magick,MaxTextExtent);
00833               (void) ConcatenateMagickString(path,":",MaxTextExtent);
00834             }
00835           (void) ConcatenateMagickString(path,filename,MaxTextExtent);
00836           if (*subimage != '\0')
00837             {
00838               (void) ConcatenateMagickString(path,"[",MaxTextExtent);
00839               (void) ConcatenateMagickString(path,subimage,MaxTextExtent);
00840               (void) ConcatenateMagickString(path,"]",MaxTextExtent);
00841             }
00842           if (strlen(path) >= MaxTextExtent)
00843             ThrowFatalException(OptionFatalError,"FilenameTruncated");
00844           if (destroy != MagickFalse)
00845             {
00846               count--;
00847               vector[count]=DestroyString(vector[count]);
00848               destroy=MagickFalse;
00849             }
00850           vector[count++]=ConstantString(path);
00851         }
00852     }
00853     filelist=(char **) RelinquishMagickMemory(filelist);
00854   }
00855   vector[count]=(char *) NULL;
00856   if (IsEventLogging() != MagickFalse)
00857     {
00858       char
00859         *command_line;
00860 
00861       command_line=AcquireString(vector[0]);
00862       for (i=1; i < count; i++)
00863       {
00864         (void) ConcatenateString(&command_line," {");
00865         (void) ConcatenateString(&command_line,vector[i]);
00866         (void) ConcatenateString(&command_line,"}");
00867       }
00868       (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00869         "Command line: %s",command_line);
00870       command_line=DestroyString(command_line);
00871     }
00872   *number_arguments=(int) count;
00873   *arguments=vector;
00874   return(MagickTrue);
00875 }
00876 
00877 /*
00878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00879 %                                                                             %
00880 %                                                                             %
00881 %                                                                             %
00882 %   G e t E x e c u t i o n P a t h                                           %
00883 %                                                                             %
00884 %                                                                             %
00885 %                                                                             %
00886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00887 %
00888 %  GetExecutionPath() returns the pathname of the executable that started
00889 %  the process.  On success MagickTrue is returned, otherwise MagickFalse.
00890 %
00891 %  The format of the GetExecutionPath method is:
00892 %
00893 %      MagickBooleanType GetExecutionPath(char *path,const size_t extent)
00894 %
00895 %  A description of each parameter follows:
00896 %
00897 %    o path: the pathname of the executable that started the process.
00898 %
00899 %    o extent: the maximum extent of the path.
00900 %
00901 */
00902 MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
00903 {
00904   char
00905     *cwd;
00906 
00907   *path='\0';
00908   cwd=getcwd(path,(unsigned long) extent);
00909 #if defined(MAGICKCORE_HAVE_GETPID) && defined(MAGICKCORE_HAVE_READLINK) && defined(PATH_MAX)
00910   {
00911     char
00912       link_path[MaxTextExtent],
00913       execution_path[PATH_MAX+1];
00914 
00915     ssize_t
00916       count;
00917 
00918     (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/exe",
00919       (long) getpid());
00920     count=readlink(link_path,execution_path,PATH_MAX);
00921     if (count == -1)
00922       {
00923         (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/file",
00924           (long) getpid());
00925         count=readlink(link_path,execution_path,PATH_MAX);
00926       }
00927     if ((count > 0) && (count <= (ssize_t) PATH_MAX))
00928       {
00929         execution_path[count]='\0';
00930         (void) CopyMagickString(path,execution_path,extent);
00931       }
00932   }
00933 #endif
00934 #if defined(MAGICKCORE_HAVE__NSGETEXECUTABLEPATH)
00935   {
00936     char
00937       executable_path[PATH_MAX << 1],
00938       execution_path[PATH_MAX+1];
00939 
00940     uint32_t
00941       length;
00942 
00943     length=sizeof(executable_path);
00944     if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
00945         (realpath(executable_path,execution_path) != (char *) NULL))
00946       (void) CopyMagickString(path,execution_path,extent);
00947   }
00948 #endif
00949 #if defined(MAGICKCORE_HAVE_GETEXECNAME)
00950   {
00951     const char
00952       *execution_path;
00953 
00954     execution_path=(const char *) getexecname();
00955     if (execution_path != (const char *) NULL)
00956       {
00957         if (*execution_path != *DirectorySeparator)
00958           (void) ConcatenateMagickString(path,DirectorySeparator,extent);
00959         (void) ConcatenateMagickString(path,execution_path,extent);
00960       }
00961   }
00962 #endif
00963 #if defined(__WINDOWS__)
00964   NTGetExecutionPath(path,extent);
00965 #endif
00966 #if defined(__GNU__)
00967   {
00968     char
00969       *program_name,
00970       *execution_path;
00971 
00972     long
00973       count;
00974 
00975     count=0;
00976     execution_path=(char *) NULL;
00977     program_name=program_invocation_name;
00978     if (*program_invocation_name != '/')
00979       {
00980         size_t
00981           extent;
00982 
00983         extent=strlen(cwd)+strlen(program_name)+1;
00984         program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
00985         if (program_name == (char *) NULL)
00986           program_name=program_invocation_name;
00987         else
00988           count=FormatMagickString(program_name,extent,"%s/%s",cwd,
00989             program_invocation_name);
00990       }
00991     if (count != -1)
00992       {
00993         execution_path=realpath(program_name,NULL);
00994         if (execution_path != (char *) NULL)
00995           (void) CopyMagickString(path,execution_path,extent);
00996       }
00997     if (program_name != program_invocation_name)
00998       program_name=(char *) RelinquishMagickMemory(program_name);
00999     execution_path=(char *) RelinquishMagickMemory(execution_path);
01000   }
01001 #endif
01002   return(IsPathAccessible(path));
01003 }
01004 
01005 /*
01006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01007 %                                                                             %
01008 %                                                                             %
01009 %                                                                             %
01010 %   G e t M a g i c k P a g e S i z e                                         %
01011 %                                                                             %
01012 %                                                                             %
01013 %                                                                             %
01014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01015 %
01016 %  GetMagickPageSize() returns the memory page size.
01017 %
01018 %  The format of the GetMagickPageSize method is:
01019 %
01020 %      long GetMagickPageSize()
01021 %
01022 */
01023 MagickExport long GetMagickPageSize(void)
01024 {
01025   static long
01026     page_size = -1;
01027 
01028   if (page_size > 0)
01029     return(page_size);
01030 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
01031   page_size=sysconf(_SC_PAGE_SIZE);
01032 #endif
01033 #if defined(MAGICKCORE_HAVE_GETPAGESIZE)
01034   if (page_size <= 0)
01035     page_size=getpagesize();
01036 #endif
01037   if (page_size <= 0)
01038     page_size=16384;
01039   return(page_size);
01040 }
01041 
01042 /*
01043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01044 %                                                                             %
01045 %                                                                             %
01046 %                                                                             %
01047 %   G e t P a t h A t t r i b u t e s                                         %
01048 %                                                                             %
01049 %                                                                             %
01050 %                                                                             %
01051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01052 %
01053 %  GetPathAttributes() returns attributes (e.g. size of file) about a path.
01054 %
01055 %  The path of the GetPathAttributes method is:
01056 %
01057 %      MagickBooleanType GetPathAttributes(const char *path,void *attributes)
01058 %
01059 %  A description of each parameter follows.
01060 %
01061 %   o  path: the file path.
01062 %
01063 %   o  attributes: the path attributes are returned here.
01064 %
01065 */
01066 
01067 #if defined(MAGICKCORE_HAVE__WFOPEN)
01068 static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
01069 {
01070   register const unsigned char
01071     *p;
01072 
01073   if (utf16 != (wchar_t *) NULL)
01074     {
01075       register wchar_t
01076         *q;
01077 
01078       wchar_t
01079         c;
01080 
01081       /*
01082         Convert UTF-8 to UTF-16.
01083       */
01084       q=utf16;
01085       for (p=utf8; *p != '\0'; p++)
01086       {
01087         if ((*p & 0x80) == 0)
01088           *q=(*p);
01089         else
01090           if ((*p & 0xE0) == 0xC0)
01091             {
01092               c=(*p);
01093               *q=(c & 0x1F) << 6;
01094               p++;
01095               if ((*p & 0xC0) != 0x80)
01096                 return(0);
01097               *q|=(*p & 0x3F);
01098             }
01099           else
01100             if ((*p & 0xF0) == 0xE0)
01101               {
01102                 c=(*p);
01103                 *q=c << 12;
01104                 p++;
01105                 if ((*p & 0xC0) != 0x80)
01106                   return(0);
01107                 c=(*p);
01108                 *q|=(c & 0x3F) << 6;
01109                 p++;
01110                 if ((*p & 0xC0) != 0x80)
01111                   return(0);
01112                 *q|=(*p & 0x3F);
01113               }
01114             else
01115               return(0);
01116         q++;
01117       }
01118       *q++='\0';
01119       return(q-utf16);
01120     }
01121   /*
01122     Compute UTF-16 string length.
01123   */
01124   for (p=utf8; *p != '\0'; p++)
01125   {
01126     if ((*p & 0x80) == 0)
01127       ;
01128     else
01129       if ((*p & 0xE0) == 0xC0)
01130         {
01131           p++;
01132           if ((*p & 0xC0) != 0x80)
01133             return(0);
01134         }
01135       else
01136         if ((*p & 0xF0) == 0xE0)
01137           {
01138             p++;
01139             if ((*p & 0xC0) != 0x80)
01140               return(0);
01141             p++;
01142             if ((*p & 0xC0) != 0x80)
01143               return(0);
01144          }
01145        else
01146          return(0);
01147   }
01148   return(p-utf8);
01149 }
01150 
01151 static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
01152 {
01153   size_t
01154     length;
01155 
01156   wchar_t
01157     *utf16;
01158 
01159   length=UTF8ToUTF16(source,(wchar_t *) NULL);
01160   if (length == 0)
01161     {
01162       register long
01163         i;
01164 
01165       /*
01166         Not UTF-8, just copy.
01167       */
01168       length=strlen(source);
01169       utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01170       if (utf16 == (wchar_t *) NULL)
01171         return((wchar_t *) NULL);
01172       for (i=0; i <= (long) length; i++)
01173         utf16[i]=source[i];
01174       return(utf16);
01175     }
01176   utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01177   if (utf16 == (wchar_t *) NULL)
01178     return((wchar_t *) NULL);
01179   length=UTF8ToUTF16(source,utf16);
01180   return(utf16);
01181 }
01182 #endif
01183 
01184 MagickExport MagickBooleanType GetPathAttributes(const char *path,
01185   void *attributes)
01186 {
01187   MagickBooleanType
01188     status;
01189 
01190   if (path == (const char *) NULL)
01191     {
01192       errno=EINVAL;
01193       return(MagickFalse);
01194     }
01195 #if !defined(MAGICKCORE_HAVE__WSTAT)
01196   status=stat(path,(struct stat *) attributes) == 0 ? MagickTrue : MagickFalse;
01197 #else
01198   {
01199     wchar_t
01200       *unicode_path;
01201 
01202     unicode_path=ConvertUTF8ToUTF16(path);
01203     if (unicode_path == (wchar_t *) NULL)
01204       return(MagickFalse);
01205     status=wstat(unicode_path,(struct stat *) attributes) == 0 ? MagickTrue :
01206       MagickFalse;
01207     unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
01208   }
01209 #endif
01210   return(status);
01211 }
01212 
01213 /*
01214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01215 %                                                                             %
01216 %                                                                             %
01217 %                                                                             %
01218 %   G e t P a t h C o m p o n e n t                                           %
01219 %                                                                             %
01220 %                                                                             %
01221 %                                                                             %
01222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01223 %
01224 %  GetPathComponent() returns the parent directory name, filename, basename, or
01225 %  extension of a file path.
01226 %
01227 %  The format of the GetPathComponent function is:
01228 %
01229 %      GetPathComponent(const char *path,PathType type,char *component)
01230 %
01231 %  A description of each parameter follows:
01232 %
01233 %    o path: Specifies a pointer to a character array that contains the
01234 %      file path.
01235 %
01236 %    o type: Specififies which file path component to return.
01237 %
01238 %    o component: the selected file path component is returned here.
01239 %
01240 */
01241 MagickExport void GetPathComponent(const char *path,PathType type,
01242   char *component)
01243 {
01244   char
01245     magick[MaxTextExtent],
01246     *q,
01247     subimage[MaxTextExtent];
01248 
01249   register char
01250     *p;
01251 
01252   assert(path != (const char *) NULL);
01253   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",path);
01254   assert(component != (char *) NULL);
01255   if (*path == '\0')
01256     {
01257       *component='\0';
01258       return;
01259     }
01260   (void) CopyMagickString(component,path,MaxTextExtent);
01261   *magick='\0';
01262 #if defined(__OS2__)
01263   if (path[1] != ":")
01264 #endif
01265   for (p=component; *p != '\0'; p++)
01266     if ((*p == ':') && (IsPathDirectory(path) < 0) &&
01267         (IsPathAccessible(path) == MagickFalse))
01268       {
01269         /*
01270           Look for image format specification (e.g. ps3:image).
01271         */
01272         (void) CopyMagickString(magick,component,(size_t) (p-component+1));
01273         if (IsMagickConflict(magick) != MagickFalse)
01274           *magick='\0';
01275         else
01276           for (q=component; *q != '\0'; q++)
01277             *q=(*++p);
01278         break;
01279       }
01280   *subimage='\0';
01281   p=component;
01282   if (*p != '\0')
01283     p=component+strlen(component)-1;
01284   if ((*p == ']') && (strchr(component,'[') != (char *) NULL) &&
01285       (IsPathAccessible(path) == MagickFalse))
01286     {
01287       /*
01288         Look for scene specification (e.g. img0001.pcd[4]).
01289       */
01290       for (q=p-1; q > component; q--)
01291         if (*q == '[')
01292           break;
01293       if (*q == '[')
01294         {
01295           (void) CopyMagickString(subimage,q+1,MaxTextExtent);
01296           subimage[p-q-1]='\0';
01297           if ((IsSceneGeometry(subimage,MagickFalse) == MagickFalse) &&
01298               (IsGeometry(subimage) == MagickFalse))
01299             *subimage='\0';
01300           else
01301             *q='\0';
01302         }
01303     }
01304   p=component;
01305   if (*p != '\0')
01306     for (p=component+strlen(component)-1; p > component; p--)
01307       if (IsBasenameSeparator(*p) != MagickFalse)
01308         break;
01309   switch (type)
01310   {
01311     case MagickPath:
01312     {
01313       (void) CopyMagickString(component,magick,MaxTextExtent);
01314       break;
01315     }
01316     case RootPath:
01317     {
01318       for (p=component+(strlen(component)-1); p > component; p--)
01319       {
01320         if (IsBasenameSeparator(*p) != MagickFalse)
01321           break;
01322         if (*p == '.')
01323           break;
01324       }
01325       if (*p == '.')
01326         *p='\0';
01327       break;
01328     }
01329     case HeadPath:
01330     {
01331       *p='\0';
01332       break;
01333     }
01334     case TailPath:
01335     {
01336       if (IsBasenameSeparator(*p) != MagickFalse)
01337         (void) CopyMagickMemory((unsigned char *) component,
01338           (const unsigned char *) (p+1),strlen(p+1)+1);
01339       break;
01340     }
01341     case BasePath:
01342     {
01343       if (IsBasenameSeparator(*p) != MagickFalse)
01344         (void) CopyMagickString(component,p+1,MaxTextExtent);
01345       for (p=component+(strlen(component)-1); p > component; p--)
01346         if (*p == '.')
01347           {
01348             *p='\0';
01349             break;
01350           }
01351       break;
01352     }
01353     case ExtensionPath:
01354     {
01355       if (IsBasenameSeparator(*p) != MagickFalse)
01356         (void) CopyMagickString(component,p+1,MaxTextExtent);
01357       p=component;
01358       if (*p != '\0')
01359         for (p=component+strlen(component)-1; p > component; p--)
01360           if (*p == '.')
01361             break;
01362       *component='\0';
01363       if (*p == '.')
01364         (void) CopyMagickString(component,p+1,MaxTextExtent);
01365       break;
01366     }
01367     case SubimagePath:
01368     {
01369       (void) CopyMagickString(component,subimage,MaxTextExtent);
01370       break;
01371     }
01372     case CanonicalPath:
01373     case UndefinedPath:
01374       break;
01375   }
01376 }
01377 
01378 /*
01379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01380 %                                                                             %
01381 %                                                                             %
01382 %                                                                             %
01383 %  G e t P a t h C o m p o n e n t s                                          %
01384 %                                                                             %
01385 %                                                                             %
01386 %                                                                             %
01387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01388 %
01389 %  GetPathComponents() returns a list of path components.
01390 %
01391 %  The format of the GetPathComponents method is:
01392 %
01393 %      char **GetPathComponents(const char *path,
01394 %        unsigned long *number_componenets)
01395 %
01396 %  A description of each parameter follows:
01397 %
01398 %    o path:  Specifies the string to segment into a list.
01399 %
01400 %    o number_components:  return the number of components in the list
01401 %
01402 */
01403 MagickExport char **GetPathComponents(const char *path,
01404   unsigned long *number_components)
01405 {
01406   char
01407     **components;
01408 
01409   register const char
01410     *p,
01411     *q;
01412 
01413   register long
01414     i;
01415 
01416   if (path == (char *) NULL)
01417     return((char **) NULL);
01418   *number_components=1;
01419   for (p=path; *p != '\0'; p++)
01420     if (IsBasenameSeparator(*p))
01421       (*number_components)++;
01422   components=(char **) AcquireQuantumMemory((size_t) *number_components+1UL,
01423     sizeof(*components));
01424   if (components == (char **) NULL)
01425     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01426   p=path;
01427   for (i=0; i < (long) *number_components; i++)
01428   {
01429     for (q=p; *q != '\0'; q++)
01430       if (IsBasenameSeparator(*q))
01431         break;
01432     components[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
01433       sizeof(*components));
01434     if (components[i] == (char *) NULL)
01435       ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01436     (void) CopyMagickString(components[i],p,(size_t) (q-p+1));
01437     p=q+1;
01438   }
01439   components[i]=(char *) NULL;
01440   return(components);
01441 }
01442 
01443 /*
01444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01445 %                                                                             %
01446 %                                                                             %
01447 %                                                                             %
01448 %  I s P a t h A c c e s s i b l e                                            %
01449 %                                                                             %
01450 %                                                                             %
01451 %                                                                             %
01452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01453 %
01454 %  IsPathAccessible() returns MagickTrue if the file as defined by the path is
01455 %  accessible.
01456 %
01457 %  The format of the IsPathAccessible method is:
01458 %
01459 %      MagickBooleanType IsPathAccessible(const char *filename)
01460 %
01461 %  A description of each parameter follows.
01462 %
01463 %    o path:  Specifies a path to a file.
01464 %
01465 */
01466 MagickExport MagickBooleanType IsPathAccessible(const char *path)
01467 {
01468   MagickBooleanType
01469     status;
01470 
01471   struct stat
01472     attributes;
01473 
01474   if ((path == (const char *) NULL) || (*path == '\0'))
01475     return(MagickFalse);
01476   status=GetPathAttributes(path,&attributes);
01477   if (status == MagickFalse)
01478     return(status);
01479   if (S_ISREG(attributes.st_mode) == 0)
01480     return(MagickFalse);
01481   if (access(path,F_OK) != 0)
01482     return(MagickFalse);
01483   return(MagickTrue);
01484 }
01485 
01486 /*
01487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01488 %                                                                             %
01489 %                                                                             %
01490 %                                                                             %
01491 +  I s P a t h D i r e c t o r y                                              %
01492 %                                                                             %
01493 %                                                                             %
01494 %                                                                             %
01495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01496 %
01497 %  IsPathDirectory() returns -1 if the directory does not exist,  1 is returned
01498 %  if the path represents a directory otherwise 0.
01499 %
01500 %  The format of the IsPathDirectory method is:
01501 %
01502 %      int IsPathDirectory(const char *path)
01503 %
01504 %  A description of each parameter follows.
01505 %
01506 %   o  path:  The directory path.
01507 %
01508 */
01509 static int IsPathDirectory(const char *path)
01510 {
01511   MagickBooleanType
01512     status;
01513 
01514   struct stat
01515     attributes;
01516 
01517   if ((path == (const char *) NULL) || (*path == '\0'))
01518     return(MagickFalse);
01519   status=GetPathAttributes(path,&attributes);
01520   if (status == MagickFalse)
01521     return(-1);
01522   if (S_ISDIR(attributes.st_mode) == 0)
01523     return(0);
01524   return(1);
01525 }
01526 
01527 /*
01528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01529 %                                                                             %
01530 %                                                                             %
01531 %                                                                             %
01532 %   I s M a g i c k T r u e                                                   %
01533 %                                                                             %
01534 %                                                                             %
01535 %                                                                             %
01536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01537 %
01538 %  IsMagickTrue() returns MagickTrue if the value is "true", "on", "yes" or
01539 %  "1".
01540 %
01541 %  The format of the IsMagickTrue method is:
01542 %
01543 %      MagickBooleanType IsMagickTrue(const char *value)
01544 %
01545 %  A description of each parameter follows:
01546 %
01547 %    o option: either MagickTrue or MagickFalse depending on the value
01548 %      parameter.
01549 %
01550 %    o value: Specifies a pointer to a character array.
01551 %
01552 */
01553 MagickExport MagickBooleanType IsMagickTrue(const char *value)
01554 {
01555   if (value == (const char *) NULL)
01556     return(MagickFalse);
01557   if (LocaleCompare(value,"true") == 0)
01558     return(MagickTrue);
01559   if (LocaleCompare(value,"on") == 0)
01560     return(MagickTrue);
01561   if (LocaleCompare(value,"yes") == 0)
01562     return(MagickTrue);
01563   if (LocaleCompare(value,"1") == 0)
01564     return(MagickTrue);
01565   return(MagickFalse);
01566 }
01567 
01568 /*
01569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01570 %                                                                             %
01571 %                                                                             %
01572 %                                                                             %
01573 %   L i s t F i l e s                                                         %
01574 %                                                                             %
01575 %                                                                             %
01576 %                                                                             %
01577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01578 %
01579 %  ListFiles() reads the directory specified and returns a list of filenames
01580 %  contained in the directory sorted in ascending alphabetic order.
01581 %
01582 %  The format of the ListFiles function is:
01583 %
01584 %      char **ListFiles(const char *directory,const char *pattern,
01585 %        long *number_entries)
01586 %
01587 %  A description of each parameter follows:
01588 %
01589 %    o filelist: Method ListFiles returns a list of filenames contained
01590 %      in the directory.  If the directory specified cannot be read or it is
01591 %      a file a NULL list is returned.
01592 %
01593 %    o directory: Specifies a pointer to a text string containing a directory
01594 %      name.
01595 %
01596 %    o pattern: Specifies a pointer to a text string containing a pattern.
01597 %
01598 %    o number_entries:  This integer returns the number of filenames in the
01599 %      list.
01600 %
01601 */
01602 
01603 #if defined(__cplusplus) || defined(c_plusplus)
01604 extern "C" {
01605 #endif
01606 
01607 static int FileCompare(const void *x,const void *y)
01608 {
01609   register const char
01610     **p,
01611     **q;
01612 
01613   p=(const char **) x;
01614   q=(const char **) y;
01615   return(LocaleCompare(*p,*q));
01616 }
01617 
01618 #if defined(__cplusplus) || defined(c_plusplus)
01619 }
01620 #endif
01621 
01622 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
01623   struct dirent **result)
01624 {
01625 #if defined(MAGICKCORE_HAVE_READDIR_R)
01626   return(readdir_r(directory,entry,result));
01627 #else
01628   (void) entry;
01629   errno=0;
01630   *result=readdir(directory);
01631   return(errno);
01632 #endif
01633 }
01634 
01635 MagickExport char **ListFiles(const char *directory,const char *pattern,
01636   unsigned long *number_entries)
01637 {
01638   char
01639     **filelist;
01640 
01641   DIR
01642     *current_directory;
01643 
01644   struct dirent
01645     *buffer,
01646     *entry;
01647 
01648   unsigned long
01649     max_entries;
01650 
01651   /*
01652     Open directory.
01653   */
01654   assert(directory != (const char *) NULL);
01655   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",directory);
01656   assert(pattern != (const char *) NULL);
01657   assert(number_entries != (unsigned long *) NULL);
01658   *number_entries=0;
01659   current_directory=opendir(directory);
01660   if (current_directory == (DIR *) NULL)
01661     return((char **) NULL);
01662   /*
01663     Allocate filelist.
01664   */
01665   max_entries=2048;
01666   filelist=(char **) AcquireQuantumMemory((size_t) max_entries,
01667     sizeof(*filelist));
01668   if (filelist == (char **) NULL)
01669     {
01670       (void) closedir(current_directory);
01671       return((char **) NULL);
01672     }
01673   /*
01674     Save the current and change to the new directory.
01675   */
01676   buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1);
01677   if (buffer == (struct dirent *) NULL)
01678     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01679   while ((MagickReadDirectory(current_directory,buffer,&entry) == 0) &&
01680          (entry != (struct dirent *) NULL))
01681   {
01682     if (*entry->d_name == '.')
01683       continue;
01684     if ((IsPathDirectory(entry->d_name) > 0) ||
01685 #if defined(__WINDOWS__)
01686         (GlobExpression(entry->d_name,pattern,MagickTrue) != MagickFalse))
01687 #else
01688         (GlobExpression(entry->d_name,pattern,MagickFalse) != MagickFalse))
01689 #endif
01690       {
01691         if (*number_entries >= max_entries)
01692           {
01693             /*
01694               Extend the file list.
01695             */
01696             max_entries<<=1;
01697             filelist=(char **) ResizeQuantumMemory(filelist,(size_t)
01698               max_entries,sizeof(*filelist));
01699             if (filelist == (char **) NULL)
01700               break;
01701           }
01702 #if defined(vms)
01703         {
01704           register char
01705             *p;
01706 
01707           p=strchr(entry->d_name,';');
01708           if (p)
01709             *p='\0';
01710           if (*number_entries > 0)
01711             if (LocaleCompare(entry->d_name,filelist[*number_entries-1]) == 0)
01712               continue;
01713         }
01714 #endif
01715         filelist[*number_entries]=(char *) AcquireString(entry->d_name);
01716         if (IsPathDirectory(entry->d_name) > 0)
01717           (void) ConcatenateMagickString(filelist[*number_entries],
01718             DirectorySeparator,MaxTextExtent);
01719         (*number_entries)++;
01720       }
01721   }
01722   buffer=(struct dirent *) RelinquishMagickMemory(buffer);
01723   (void) closedir(current_directory);
01724   if (filelist == (char **) NULL)
01725     return((char **) NULL);
01726   /*
01727     Sort filelist in ascending order.
01728   */
01729   qsort((void *) filelist,(size_t) *number_entries,sizeof(*filelist),
01730     FileCompare);
01731   return(filelist);
01732 }
01733 
01734 /*
01735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01736 %                                                                             %
01737 %                                                                             %
01738 %                                                                             %
01739 %  M u l t i l i n e C e n s u s                                              %
01740 %                                                                             %
01741 %                                                                             %
01742 %                                                                             %
01743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01744 %
01745 %  MultilineCensus() returns the number of lines within a label.  A line is
01746 %  represented by a \n character.
01747 %
01748 %  The format of the MultilineCenus method is:
01749 %
01750 %      unsigned long MultilineCensus(const char *label)
01751 %
01752 %  A description of each parameter follows.
01753 %
01754 %   o  label:  This character string is the label.
01755 %
01756 %
01757 */
01758 MagickExport unsigned long MultilineCensus(const char *label)
01759 {
01760   unsigned long
01761     number_lines;
01762 
01763   /*
01764     Determine the number of lines within this label.
01765   */
01766   if (label == (char *) NULL)
01767     return(0);
01768   for (number_lines=1; *label != '\0'; label++)
01769     if (*label == '\n')
01770       number_lines++;
01771   return(number_lines);
01772 }
01773 
01774 /*
01775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01776 %                                                                             %
01777 %                                                                             %
01778 %                                                                             %
01779 %   O p e n M a g i c k S t r e a m                                           %
01780 %                                                                             %
01781 %                                                                             %
01782 %                                                                             %
01783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01784 %
01785 %  OpenMagickStream() opens the file at the specified path and return the
01786 %  associated stream.
01787 %
01788 %  The path of the OpenMagickStream method is:
01789 %
01790 %      FILE *OpenMagickStream(const char *path,const char *mode)
01791 %
01792 %  A description of each parameter follows.
01793 %
01794 %   o  path: the file path.
01795 %
01796 %   o  mode: the file mode.
01797 %
01798 */
01799 MagickExport FILE *OpenMagickStream(const char *path,const char *mode)
01800 {
01801   FILE
01802     *file;
01803 
01804   if ((path == (const char *) NULL) || (mode == (const char *) NULL))
01805     {
01806       errno=EINVAL;
01807       return((FILE *) NULL);
01808     }
01809   file=(FILE *) NULL;
01810 #if defined(MAGICKCORE_HAVE__WFOPEN)
01811   {
01812     wchar_t
01813       *unicode_mode,
01814       *unicode_path;
01815 
01816     unicode_path=ConvertUTF8ToUTF16(path);
01817     if (unicode_path == (wchar_t *) NULL)
01818       return((FILE *) NULL);
01819     unicode_mode=ConvertUTF8ToUTF16(mode);
01820     if (unicode_mode == (wchar_t *) NULL)
01821       {
01822         unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
01823         return((FILE *) NULL);
01824       }
01825     file=_wfopen(unicode_path,unicode_mode);
01826     unicode_mode=(wchar_t *) RelinquishMagickMemory(unicode_mode);
01827     unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
01828   }
01829 #endif
01830   if (file == (FILE *) NULL)
01831     file=fopen(path,mode);
01832   return(file);
01833 }
01834 
01835 /*
01836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01837 %                                                                             %
01838 %                                                                             %
01839 %                                                                             %
01840 %   S y s t e m C o m m a n d                                                 %
01841 %                                                                             %
01842 %                                                                             %
01843 %                                                                             %
01844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01845 %
01846 %  SystemCommand() executes the specified command and waits until it
01847 %  terminates.  The returned value is the exit status of the command.
01848 %
01849 %  The format of the SystemCommand method is:
01850 %
01851 %      int SystemCommand(const MagickBooleanType verbose,const char *command,
01852 %        ExceptionInfo *exception)
01853 %
01854 %  A description of each parameter follows:
01855 %
01856 %    o verbose: a value other than 0 prints the executed command before it is
01857 %      invoked.
01858 %
01859 %    o command: this string is the command to execute.
01860 %
01861 %    o exception: return any errors here.
01862 %
01863 */
01864 MagickExport int SystemCommand(const MagickBooleanType verbose,
01865   const char *command,ExceptionInfo *exception)
01866 {
01867   char
01868     **arguments;
01869 
01870   int
01871     number_arguments,
01872     status;
01873 
01874   PolicyDomain
01875     domain;
01876 
01877   PolicyRights
01878     rights;
01879 
01880   register long
01881     i;
01882 
01883   status=(-1);
01884   arguments=StringToArgv(command,&number_arguments);
01885   if (arguments == (char **) NULL)
01886     return(status);
01887   domain=DelegatePolicyDomain;
01888   rights=ExecutePolicyRights;
01889   if (IsRightsAuthorized(domain,rights,arguments[1]) == MagickFalse)
01890     {
01891       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
01892         "NotAuthorized","`%s'",arguments[1]);
01893       for (i=0; i < number_arguments; i++)
01894         arguments[i]=DestroyString(arguments[i]);
01895       arguments=(char **) RelinquishMagickMemory(arguments);
01896       return(-1);
01897     }
01898   if (verbose != MagickFalse)
01899     {
01900       (void) fprintf(stderr,"%s\n",command);
01901       (void) fflush(stderr);
01902     }
01903 #if defined(MAGICKCORE_POSIX_SUPPORT)
01904 #if !defined(MAGICKCORE_HAVE_EXECVP)
01905   status=system(command);
01906 #else
01907   if (strspn(command,"&;<>|") == 0)
01908     status=system(command);
01909   else
01910     {
01911       pid_t
01912         child_pid;
01913 
01914       /*
01915         Call application directly rather than from a shell.
01916       */
01917       child_pid=fork();
01918       if (child_pid == (pid_t) -1)
01919         status=system(command);
01920       else
01921         if (child_pid == 0)
01922           {
01923             status=execvp(arguments[1],arguments+1);
01924             _exit(1);
01925           }
01926         else
01927           {
01928             int
01929               child_status;
01930 
01931             pid_t
01932               pid;
01933 
01934             child_status=0;
01935             pid=waitpid(child_pid,&child_status,0);
01936             if (pid == -1)
01937               status=(-1);
01938             else
01939               {
01940                 if (WIFEXITED(child_status) != 0)
01941                   status=WEXITSTATUS(child_status);
01942                 else
01943                   if (WIFSIGNALED(child_status))
01944                     status=(-1);
01945               }
01946           }
01947     }
01948 #endif
01949 #elif defined(__WINDOWS__)
01950   status=NTSystemCommand(command);
01951 #elif defined(macintosh)
01952   status=MACSystemCommand(command);
01953 #elif defined(vms)
01954   status=system(command);
01955 #else
01956 #  error No suitable system() method.
01957 #endif
01958   if (status < 0)
01959     {
01960       char
01961         *message;
01962 
01963       message=GetExceptionMessage(errno);
01964       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
01965         "`%s': %s",command,message);
01966       message=DestroyString(message);
01967     }
01968   for (i=0; i < number_arguments; i++)
01969     arguments[i]=DestroyString(arguments[i]);
01970   arguments=(char **) RelinquishMagickMemory(arguments);
01971   return(status);
01972 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1