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

Generated on Thu Jul 2 12:03:22 2009 for MagickCore by  doxygen 1.5.8