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