|
MagickCore
6.7.5
|
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-2012 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 "MagickCore/studio.h" 00043 #include "MagickCore/property.h" 00044 #include "MagickCore/blob.h" 00045 #include "MagickCore/color.h" 00046 #include "MagickCore/exception.h" 00047 #include "MagickCore/exception-private.h" 00048 #include "MagickCore/geometry.h" 00049 #include "MagickCore/list.h" 00050 #include "MagickCore/log.h" 00051 #include "MagickCore/magick-private.h" 00052 #include "MagickCore/memory_.h" 00053 #include "MagickCore/nt-base-private.h" 00054 #include "MagickCore/option.h" 00055 #include "MagickCore/policy.h" 00056 #include "MagickCore/resource_.h" 00057 #include "MagickCore/semaphore.h" 00058 #include "MagickCore/signature-private.h" 00059 #include "MagickCore/statistic.h" 00060 #include "MagickCore/string_.h" 00061 #include "MagickCore/string-private.h" 00062 #include "MagickCore/token.h" 00063 #include "MagickCore/token-private.h" 00064 #include "MagickCore/utility.h" 00065 #include "MagickCore/utility-private.h" 00066 #if defined(MAGICKCORE_HAVE_PROCESS_H) 00067 #include <process.h> 00068 #endif 00069 #if defined(MAGICKCORE_HAVE_MACH_O_DYLD_H) 00070 #include <mach-o/dyld.h> 00071 #endif 00072 00073 /* 00074 Static declarations. 00075 */ 00076 static const char 00077 Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00078 00079 /* 00080 Forward declaration. 00081 */ 00082 static int 00083 IsPathDirectory(const char *); 00084 00085 /* 00086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00087 % % 00088 % % 00089 % % 00090 % A c q u i r e U n i q u e F i l e n a m e % 00091 % % 00092 % % 00093 % % 00094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00095 % 00096 % AcquireUniqueFilename() replaces the contents of path by a unique path name. 00097 % 00098 % The format of the AcquireUniqueFilename method is: 00099 % 00100 % MagickBooleanType AcquireUniqueFilename(char *path) 00101 % 00102 % A description of each parameter follows. 00103 % 00104 % o path: Specifies a pointer to an array of characters. The unique path 00105 % name is returned in this array. 00106 % 00107 */ 00108 MagickExport MagickBooleanType AcquireUniqueFilename(char *path) 00109 { 00110 int 00111 file; 00112 00113 file=AcquireUniqueFileResource(path); 00114 if (file == -1) 00115 return(MagickFalse); 00116 file=close(file)-1; 00117 return(MagickTrue); 00118 } 00119 00120 /* 00121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00122 % % 00123 % % 00124 % % 00125 % A c q u i r e U n i q u e S ym b o l i c L i n k % 00126 % % 00127 % % 00128 % % 00129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00130 % 00131 % AcquireUniqueSymbolicLink() creates a unique symbolic link to the specified 00132 % source path and returns MagickTrue on success otherwise MagickFalse. If the 00133 % symlink() method fails or is not available, a unique file name is generated 00134 % and the source file copied to it. When you are finished with the file, use 00135 % RelinquishUniqueFilename() to destroy it. 00136 % 00137 % The format of the AcquireUniqueSymbolicLink method is: 00138 % 00139 % MagickBooleanType AcquireUniqueSymbolicLink(const char *source, 00140 % char destination) 00141 % 00142 % A description of each parameter follows. 00143 % 00144 % o source: the source path. 00145 % 00146 % o destination: the destination path. 00147 % 00148 */ 00149 00150 static inline size_t MagickMin(const size_t x,const size_t y) 00151 { 00152 if (x < y) 00153 return(x); 00154 return(y); 00155 } 00156 00157 MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source, 00158 char *destination) 00159 { 00160 int 00161 destination_file, 00162 source_file; 00163 00164 size_t 00165 length, 00166 quantum; 00167 00168 ssize_t 00169 count; 00170 00171 struct stat 00172 attributes; 00173 00174 unsigned char 00175 *buffer; 00176 00177 assert(source != (const char *) NULL); 00178 assert(destination != (char *) NULL); 00179 #if defined(MAGICKCORE_HAVE_SYMLINK) 00180 (void) AcquireUniqueFilename(destination); 00181 (void) RelinquishUniqueFileResource(destination); 00182 if (*source == *DirectorySeparator) 00183 { 00184 if (symlink(source,destination) == 0) 00185 return(MagickTrue); 00186 } 00187 else 00188 { 00189 char 00190 path[MaxTextExtent]; 00191 00192 *path='\0'; 00193 if (getcwd(path,MaxTextExtent) == (char *) NULL) 00194 return(MagickFalse); 00195 (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent); 00196 (void) ConcatenateMagickString(path,source,MaxTextExtent); 00197 if (symlink(path,destination) == 0) 00198 return(MagickTrue); 00199 } 00200 #endif 00201 destination_file=AcquireUniqueFileResource(destination); 00202 if (destination_file == -1) 00203 return(MagickFalse); 00204 source_file=open_utf8(source,O_RDONLY | O_BINARY,0); 00205 if (source_file == -1) 00206 { 00207 (void) close(destination_file); 00208 (void) RelinquishUniqueFileResource(destination); 00209 return(MagickFalse); 00210 } 00211 quantum=(size_t) MagickMaxBufferExtent; 00212 if ((fstat(source_file,&attributes) == 0) && (attributes.st_size != 0)) 00213 quantum=MagickMin((size_t) attributes.st_size,MagickMaxBufferExtent); 00214 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); 00215 if (buffer == (unsigned char *) NULL) 00216 { 00217 (void) close(source_file); 00218 (void) close(destination_file); 00219 (void) RelinquishUniqueFileResource(destination); 00220 return(MagickFalse); 00221 } 00222 for (length=0; ; ) 00223 { 00224 count=(ssize_t) read(source_file,buffer,quantum); 00225 if (count <= 0) 00226 break; 00227 length=(size_t) count; 00228 count=(ssize_t) write(destination_file,buffer,length); 00229 if ((size_t) count != length) 00230 { 00231 (void) close(destination_file); 00232 (void) close(source_file); 00233 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 00234 (void) RelinquishUniqueFileResource(destination); 00235 return(MagickFalse); 00236 } 00237 } 00238 (void) close(destination_file); 00239 (void) close(source_file); 00240 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 00241 return(MagickTrue); 00242 } 00243 00244 /* 00245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00246 % % 00247 % % 00248 % % 00249 % A p p e n d I m a g e F o r m a t % 00250 % % 00251 % % 00252 % % 00253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00254 % 00255 % AppendImageFormat() appends the image format type to the filename. If an 00256 % extension to the file already exists, it is first removed. 00257 % 00258 % The format of the AppendImageFormat method is: 00259 % 00260 % void AppendImageFormat(const char *format,char *filename) 00261 % 00262 % A description of each parameter follows. 00263 % 00264 % o format: Specifies a pointer to an array of characters. This the 00265 % format of the image. 00266 % 00267 % o filename: Specifies a pointer to an array of characters. The unique 00268 % file name is returned in this array. 00269 % 00270 */ 00271 MagickExport void AppendImageFormat(const char *format,char *filename) 00272 { 00273 char 00274 extension[MaxTextExtent], 00275 root[MaxTextExtent]; 00276 00277 assert(format != (char *) NULL); 00278 assert(filename != (char *) NULL); 00279 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00280 if ((*format == '\0') || (*filename == '\0')) 00281 return; 00282 if (LocaleCompare(filename,"-") == 0) 00283 { 00284 char 00285 message[MaxTextExtent]; 00286 00287 (void) FormatLocaleString(message,MaxTextExtent,"%s:%s",format,filename); 00288 (void) CopyMagickString(filename,message,MaxTextExtent); 00289 return; 00290 } 00291 GetPathComponent(filename,ExtensionPath,extension); 00292 if ((LocaleCompare(extension,"Z") == 0) || 00293 (LocaleCompare(extension,"bz2") == 0) || 00294 (LocaleCompare(extension,"gz") == 0) || 00295 (LocaleCompare(extension,"wmz") == 0) || 00296 (LocaleCompare(extension,"svgz") == 0)) 00297 { 00298 GetPathComponent(filename,RootPath,root); 00299 (void) CopyMagickString(filename,root,MaxTextExtent); 00300 GetPathComponent(filename,RootPath,root); 00301 (void) FormatLocaleString(filename,MaxTextExtent,"%s.%s.%s",root,format, 00302 extension); 00303 return; 00304 } 00305 GetPathComponent(filename,RootPath,root); 00306 (void) FormatLocaleString(filename,MaxTextExtent,"%s.%s",root,format); 00307 } 00308 00309 /* 00310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00311 % % 00312 % % 00313 % % 00314 % B a s e 6 4 D e c o d e % 00315 % % 00316 % % 00317 % % 00318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00319 % 00320 % Base64Decode() decodes Base64-encoded text and returns its binary 00321 % equivalent. NULL is returned if the text is not valid Base64 data, or a 00322 % memory allocation failure occurs. 00323 % 00324 % The format of the Base64Decode method is: 00325 % 00326 % unsigned char *Base64Decode(const char *source,length_t *length) 00327 % 00328 % A description of each parameter follows: 00329 % 00330 % o source: A pointer to a Base64-encoded string. 00331 % 00332 % o length: the number of bytes decoded. 00333 % 00334 */ 00335 MagickExport unsigned char *Base64Decode(const char *source,size_t *length) 00336 { 00337 int 00338 state; 00339 00340 register const char 00341 *p, 00342 *q; 00343 00344 register size_t 00345 i; 00346 00347 unsigned char 00348 *decode; 00349 00350 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00351 assert(source != (char *) NULL); 00352 assert(length != (size_t *) NULL); 00353 *length=0; 00354 decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4, 00355 3*sizeof(*decode)); 00356 if (decode == (unsigned char *) NULL) 00357 return((unsigned char *) NULL); 00358 i=0; 00359 state=0; 00360 for (p=source; *p != '\0'; p++) 00361 { 00362 if (isspace((int) ((unsigned char) *p)) != 0) 00363 continue; 00364 if (*p == '=') 00365 break; 00366 q=strchr(Base64,*p); 00367 if (q == (char *) NULL) 00368 { 00369 decode=(unsigned char *) RelinquishMagickMemory(decode); 00370 return((unsigned char *) NULL); /* non-Base64 character */ 00371 } 00372 switch (state) 00373 { 00374 case 0: 00375 { 00376 decode[i]=(q-Base64) << 2; 00377 state++; 00378 break; 00379 } 00380 case 1: 00381 { 00382 decode[i++]|=(q-Base64) >> 4; 00383 decode[i]=((q-Base64) & 0x0f) << 4; 00384 state++; 00385 break; 00386 } 00387 case 2: 00388 { 00389 decode[i++]|=(q-Base64) >> 2; 00390 decode[i]=((q-Base64) & 0x03) << 6; 00391 state++; 00392 break; 00393 } 00394 case 3: 00395 { 00396 decode[i++]|=(q-Base64); 00397 state=0; 00398 break; 00399 } 00400 } 00401 } 00402 /* 00403 Verify Base-64 string has proper terminal characters. 00404 */ 00405 if (*p != '=') 00406 { 00407 if (state != 0) 00408 { 00409 decode=(unsigned char *) RelinquishMagickMemory(decode); 00410 return((unsigned char *) NULL); 00411 } 00412 } 00413 else 00414 { 00415 p++; 00416 switch (state) 00417 { 00418 case 0: 00419 case 1: 00420 { 00421 /* 00422 Unrecognized '=' character. 00423 */ 00424 decode=(unsigned char *) RelinquishMagickMemory(decode); 00425 return((unsigned char *) NULL); 00426 } 00427 case 2: 00428 { 00429 for ( ; *p != '\0'; p++) 00430 if (isspace((int) ((unsigned char) *p)) == 0) 00431 break; 00432 if (*p != '=') 00433 { 00434 decode=(unsigned char *) RelinquishMagickMemory(decode); 00435 return((unsigned char *) NULL); 00436 } 00437 p++; 00438 } 00439 case 3: 00440 { 00441 for ( ; *p != '\0'; p++) 00442 if (isspace((int) ((unsigned char) *p)) == 0) 00443 { 00444 decode=(unsigned char *) RelinquishMagickMemory(decode); 00445 return((unsigned char *) NULL); 00446 } 00447 if ((int) decode[i] != 0) 00448 { 00449 decode=(unsigned char *) RelinquishMagickMemory(decode); 00450 return((unsigned char *) NULL); 00451 } 00452 } 00453 } 00454 } 00455 *length=i; 00456 return(decode); 00457 } 00458 00459 /* 00460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00461 % % 00462 % % 00463 % % 00464 % B a s e 6 4 E n c o d e % 00465 % % 00466 % % 00467 % % 00468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00469 % 00470 % Base64Encode() encodes arbitrary binary data to Base64 encoded format as 00471 % described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and 00472 % returns the result as a null-terminated ASCII string. NULL is returned if 00473 % a memory allocation failure occurs. 00474 % 00475 % The format of the Base64Encode method is: 00476 % 00477 % char *Base64Encode(const unsigned char *blob,const size_t blob_length, 00478 % size_t *encode_length) 00479 % 00480 % A description of each parameter follows: 00481 % 00482 % o blob: A pointer to binary data to encode. 00483 % 00484 % o blob_length: the number of bytes to encode. 00485 % 00486 % o encode_length: The number of bytes encoded. 00487 % 00488 */ 00489 MagickExport char *Base64Encode(const unsigned char *blob, 00490 const size_t blob_length,size_t *encode_length) 00491 { 00492 char 00493 *encode; 00494 00495 register const unsigned char 00496 *p; 00497 00498 register size_t 00499 i; 00500 00501 size_t 00502 remainder; 00503 00504 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00505 assert(blob != (const unsigned char *) NULL); 00506 assert(blob_length != 0); 00507 assert(encode_length != (size_t *) NULL); 00508 *encode_length=0; 00509 encode=(char *) AcquireQuantumMemory(blob_length/3+4,4*sizeof(*encode)); 00510 if (encode == (char *) NULL) 00511 return((char *) NULL); 00512 i=0; 00513 for (p=blob; p < (blob+blob_length-2); p+=3) 00514 { 00515 encode[i++]=Base64[(int) (*p >> 2)]; 00516 encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))]; 00517 encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))]; 00518 encode[i++]=Base64[(int) (*(p+2) & 0x3f)]; 00519 } 00520 remainder=blob_length % 3; 00521 if (remainder != 0) 00522 { 00523 ssize_t 00524 j; 00525 00526 unsigned char 00527 code[3]; 00528 00529 code[0]='\0'; 00530 code[1]='\0'; 00531 code[2]='\0'; 00532 for (j=0; j < (ssize_t) remainder; j++) 00533 code[j]=(*p++); 00534 encode[i++]=Base64[(int) (code[0] >> 2)]; 00535 encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))]; 00536 if (remainder == 1) 00537 encode[i++]='='; 00538 else 00539 encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))]; 00540 encode[i++]='='; 00541 } 00542 *encode_length=i; 00543 encode[i++]='\0'; 00544 return(encode); 00545 } 00546 00547 /* 00548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00549 % % 00550 % % 00551 % % 00552 % C h o p P a t h C o m p o n e n t s % 00553 % % 00554 % % 00555 % % 00556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00557 % 00558 % ChopPathComponents() removes the number of specified file components from a 00559 % path. 00560 % 00561 % The format of the ChopPathComponents method is: 00562 % 00563 % ChopPathComponents(char *path,size_t components) 00564 % 00565 % A description of each parameter follows: 00566 % 00567 % o path: The path. 00568 % 00569 % o components: The number of components to chop. 00570 % 00571 */ 00572 MagickPrivate void ChopPathComponents(char *path,const size_t components) 00573 { 00574 register ssize_t 00575 i; 00576 00577 for (i=0; i < (ssize_t) components; i++) 00578 GetPathComponent(path,HeadPath,path); 00579 } 00580 00581 /* 00582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00583 % % 00584 % % 00585 % % 00586 % E x p a n d F i l e n a m e % 00587 % % 00588 % % 00589 % % 00590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00591 % 00592 % ExpandFilename() expands '~' in a path. 00593 % 00594 % The format of the ExpandFilename function is: 00595 % 00596 % ExpandFilename(char *path) 00597 % 00598 % A description of each parameter follows: 00599 % 00600 % o path: Specifies a pointer to a character array that contains the 00601 % path. 00602 % 00603 */ 00604 MagickPrivate void ExpandFilename(char *path) 00605 { 00606 char 00607 expand_path[MaxTextExtent]; 00608 00609 if (path == (char *) NULL) 00610 return; 00611 if (*path != '~') 00612 return; 00613 (void) CopyMagickString(expand_path,path,MaxTextExtent); 00614 if ((*(path+1) == *DirectorySeparator) || (*(path+1) == '\0')) 00615 { 00616 char 00617 *home; 00618 00619 /* 00620 Substitute ~ with $HOME. 00621 */ 00622 (void) CopyMagickString(expand_path,".",MaxTextExtent); 00623 (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent); 00624 home=GetEnvironmentValue("HOME"); 00625 if (home == (char *) NULL) 00626 home=GetEnvironmentValue("USERPROFILE"); 00627 if (home != (char *) NULL) 00628 { 00629 (void) CopyMagickString(expand_path,home,MaxTextExtent); 00630 (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent); 00631 home=DestroyString(home); 00632 } 00633 } 00634 else 00635 { 00636 #if defined(MAGICKCORE_POSIX_SUPPORT) && !defined(__OS2__) 00637 char 00638 username[MaxTextExtent]; 00639 00640 register char 00641 *p; 00642 00643 struct passwd 00644 *entry; 00645 00646 /* 00647 Substitute ~ with home directory from password file. 00648 */ 00649 (void) CopyMagickString(username,path+1,MaxTextExtent); 00650 p=strchr(username,'/'); 00651 if (p != (char *) NULL) 00652 *p='\0'; 00653 entry=getpwnam(username); 00654 if (entry == (struct passwd *) NULL) 00655 return; 00656 (void) CopyMagickString(expand_path,entry->pw_dir,MaxTextExtent); 00657 if (p != (char *) NULL) 00658 { 00659 (void) ConcatenateMagickString(expand_path,"/",MaxTextExtent); 00660 (void) ConcatenateMagickString(expand_path,p+1,MaxTextExtent); 00661 } 00662 #endif 00663 } 00664 (void) CopyMagickString(path,expand_path,MaxTextExtent); 00665 } 00666 00667 /* 00668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00669 % % 00670 % % 00671 % % 00672 % E x p a n d F i l e n a m e s % 00673 % % 00674 % % 00675 % % 00676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00677 % 00678 % ExpandFilenames() checks each argument of the command line vector and 00679 % expands it if they have a wildcard character. For example, *.jpg might 00680 % expand to: bird.jpg rose.jpg tiki.jpg. 00681 % 00682 % The format of the ExpandFilenames function is: 00683 % 00684 % status=ExpandFilenames(int *number_arguments,char ***arguments) 00685 % 00686 % A description of each parameter follows: 00687 % 00688 % o number_arguments: Specifies a pointer to an integer describing the 00689 % number of elements in the argument vector. 00690 % 00691 % o arguments: Specifies a pointer to a text array containing the command 00692 % line arguments. 00693 % 00694 */ 00695 MagickExport MagickBooleanType ExpandFilenames(int *number_arguments, 00696 char ***arguments) 00697 { 00698 char 00699 *directory, 00700 home_directory[MaxTextExtent], 00701 **vector; 00702 00703 register ssize_t 00704 i, 00705 j; 00706 00707 size_t 00708 number_files; 00709 00710 ssize_t 00711 count, 00712 parameters; 00713 00714 /* 00715 Allocate argument vector. 00716 */ 00717 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00718 assert(number_arguments != (int *) NULL); 00719 assert(arguments != (char ***) NULL); 00720 vector=(char **) AcquireQuantumMemory((size_t) (*number_arguments+1), 00721 sizeof(*vector)); 00722 if (vector == (char **) NULL) 00723 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 00724 /* 00725 Expand any wildcard filenames. 00726 */ 00727 *home_directory='\0'; 00728 count=0; 00729 for (i=0; i < (ssize_t) *number_arguments; i++) 00730 { 00731 char 00732 **filelist, 00733 filename[MaxTextExtent], 00734 magick[MaxTextExtent], 00735 *option, 00736 path[MaxTextExtent], 00737 subimage[MaxTextExtent]; 00738 00739 MagickBooleanType 00740 destroy; 00741 00742 option=(*arguments)[i]; 00743 *magick='\0'; 00744 *path='\0'; 00745 *filename='\0'; 00746 *subimage='\0'; 00747 vector[count++]=ConstantString(option); 00748 destroy=MagickTrue; 00749 parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option); 00750 if (parameters > 0) 00751 { 00752 /* 00753 Do not expand command option parameters. 00754 */ 00755 for (j=0; j < parameters; j++) 00756 { 00757 i++; 00758 if (i == (ssize_t) *number_arguments) 00759 break; 00760 option=(*arguments)[i]; 00761 vector[count++]=ConstantString(option); 00762 } 00763 continue; 00764 } 00765 if ((*option == '"') || (*option == '\'')) 00766 continue; 00767 GetPathComponent(option,TailPath,filename); 00768 GetPathComponent(option,MagickPath,magick); 00769 if ((LocaleCompare(magick,"CAPTION") == 0) || 00770 (LocaleCompare(magick,"LABEL") == 0) || 00771 (LocaleCompare(magick,"VID") == 0)) 00772 continue; 00773 if ((IsGlob(filename) == MagickFalse) && (*filename != '@')) 00774 continue; 00775 if (*filename != '@') 00776 { 00777 /* 00778 Generate file list from wildcard filename (e.g. *.jpg). 00779 */ 00780 GetPathComponent(option,HeadPath,path); 00781 GetPathComponent(option,SubimagePath,subimage); 00782 ExpandFilename(path); 00783 if (*home_directory == '\0') 00784 directory=getcwd(home_directory,MaxTextExtent-1); 00785 (void) directory; 00786 filelist=ListFiles(*path == '\0' ? home_directory : path,filename, 00787 &number_files); 00788 } 00789 else 00790 { 00791 char 00792 *files; 00793 00794 ExceptionInfo 00795 *exception; 00796 00797 int 00798 length; 00799 00800 /* 00801 Generate file list from file list (e.g. @filelist.txt). 00802 */ 00803 exception=AcquireExceptionInfo(); 00804 files=FileToString(filename+1,~0,exception); 00805 exception=DestroyExceptionInfo(exception); 00806 if (files == (char *) NULL) 00807 continue; 00808 filelist=StringToArgv(files,&length); 00809 if (filelist == (char **) NULL) 00810 continue; 00811 files=DestroyString(files); 00812 filelist[0]=DestroyString(filelist[0]); 00813 for (j=0; j < (ssize_t) (length-1); j++) 00814 filelist[j]=filelist[j+1]; 00815 number_files=(size_t) length-1; 00816 } 00817 if (filelist == (char **) NULL) 00818 continue; 00819 for (j=0; j < (ssize_t) number_files; j++) 00820 if (IsPathDirectory(filelist[j]) <= 0) 00821 break; 00822 if (j == (ssize_t) number_files) 00823 { 00824 for (j=0; j < (ssize_t) number_files; j++) 00825 filelist[j]=DestroyString(filelist[j]); 00826 filelist=(char **) RelinquishMagickMemory(filelist); 00827 continue; 00828 } 00829 /* 00830 Transfer file list to argument vector. 00831 */ 00832 vector=(char **) ResizeQuantumMemory(vector,(size_t) *number_arguments+ 00833 count+number_files+1,sizeof(*vector)); 00834 if (vector == (char **) NULL) 00835 return(MagickFalse); 00836 for (j=0; j < (ssize_t) number_files; j++) 00837 { 00838 option=filelist[j]; 00839 parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option); 00840 if (parameters > 0) 00841 { 00842 ssize_t 00843 k; 00844 00845 /* 00846 Do not expand command option parameters. 00847 */ 00848 vector[count++]=ConstantString(option); 00849 for (k=0; k < parameters; k++) 00850 { 00851 j++; 00852 if (j == (ssize_t) number_files) 00853 break; 00854 option=filelist[j]; 00855 vector[count++]=ConstantString(option); 00856 } 00857 continue; 00858 } 00859 (void) CopyMagickString(filename,path,MaxTextExtent); 00860 if (*path != '\0') 00861 (void) ConcatenateMagickString(filename,DirectorySeparator, 00862 MaxTextExtent); 00863 (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent); 00864 filelist[j]=DestroyString(filelist[j]); 00865 if (strlen(filename) >= (MaxTextExtent-1)) 00866 ThrowFatalException(OptionFatalError,"FilenameTruncated"); 00867 if (IsPathDirectory(filename) <= 0) 00868 { 00869 char 00870 path[MaxTextExtent]; 00871 00872 *path='\0'; 00873 if (*magick != '\0') 00874 { 00875 (void) ConcatenateMagickString(path,magick,MaxTextExtent); 00876 (void) ConcatenateMagickString(path,":",MaxTextExtent); 00877 } 00878 (void) ConcatenateMagickString(path,filename,MaxTextExtent); 00879 if (*subimage != '\0') 00880 { 00881 (void) ConcatenateMagickString(path,"[",MaxTextExtent); 00882 (void) ConcatenateMagickString(path,subimage,MaxTextExtent); 00883 (void) ConcatenateMagickString(path,"]",MaxTextExtent); 00884 } 00885 if (strlen(path) >= (MaxTextExtent-1)) 00886 ThrowFatalException(OptionFatalError,"FilenameTruncated"); 00887 if (destroy != MagickFalse) 00888 { 00889 count--; 00890 vector[count]=DestroyString(vector[count]); 00891 destroy=MagickFalse; 00892 } 00893 vector[count++]=ConstantString(path); 00894 } 00895 } 00896 filelist=(char **) RelinquishMagickMemory(filelist); 00897 } 00898 vector[count]=(char *) NULL; 00899 if (IsEventLogging() != MagickFalse) 00900 { 00901 char 00902 *command_line; 00903 00904 command_line=AcquireString(vector[0]); 00905 for (i=1; i < count; i++) 00906 { 00907 (void) ConcatenateString(&command_line," {"); 00908 (void) ConcatenateString(&command_line,vector[i]); 00909 (void) ConcatenateString(&command_line,"}"); 00910 } 00911 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 00912 "Command line: %s",command_line); 00913 command_line=DestroyString(command_line); 00914 } 00915 *number_arguments=(int) count; 00916 *arguments=vector; 00917 return(MagickTrue); 00918 } 00919 00920 /* 00921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00922 % % 00923 % % 00924 % % 00925 % G e t E x e c u t i o n P a t h % 00926 % % 00927 % % 00928 % % 00929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00930 % 00931 % GetExecutionPath() returns the pathname of the executable that started 00932 % the process. On success MagickTrue is returned, otherwise MagickFalse. 00933 % 00934 % The format of the GetExecutionPath method is: 00935 % 00936 % MagickBooleanType GetExecutionPath(char *path,const size_t extent) 00937 % 00938 % A description of each parameter follows: 00939 % 00940 % o path: the pathname of the executable that started the process. 00941 % 00942 % o extent: the maximum extent of the path. 00943 % 00944 */ 00945 MagickPrivate MagickBooleanType GetExecutionPath(char *path,const size_t extent) 00946 { 00947 char 00948 *directory; 00949 00950 *path='\0'; 00951 directory=getcwd(path,(unsigned long) extent); 00952 (void) directory; 00953 #if defined(MAGICKCORE_HAVE_GETPID) && defined(MAGICKCORE_HAVE_READLINK) && defined(PATH_MAX) 00954 { 00955 char 00956 link_path[MaxTextExtent], 00957 execution_path[PATH_MAX+1]; 00958 00959 ssize_t 00960 count; 00961 00962 (void) FormatLocaleString(link_path,MaxTextExtent,"/proc/%.20g/exe", 00963 (double) getpid()); 00964 count=readlink(link_path,execution_path,PATH_MAX); 00965 if (count == -1) 00966 { 00967 (void) FormatLocaleString(link_path,MaxTextExtent,"/proc/%.20g/file", 00968 (double) getpid()); 00969 count=readlink(link_path,execution_path,PATH_MAX); 00970 } 00971 if ((count > 0) && (count <= (ssize_t) PATH_MAX)) 00972 { 00973 execution_path[count]='\0'; 00974 (void) CopyMagickString(path,execution_path,extent); 00975 } 00976 } 00977 #endif 00978 #if defined(MAGICKCORE_HAVE__NSGETEXECUTABLEPATH) 00979 { 00980 char 00981 executable_path[PATH_MAX << 1], 00982 execution_path[PATH_MAX+1]; 00983 00984 uint32_t 00985 length; 00986 00987 length=sizeof(executable_path); 00988 if ((_NSGetExecutablePath(executable_path,&length) == 0) && 00989 (realpath(executable_path,execution_path) != (char *) NULL)) 00990 (void) CopyMagickString(path,execution_path,extent); 00991 } 00992 #endif 00993 #if defined(MAGICKCORE_HAVE_GETEXECNAME) 00994 { 00995 const char 00996 *execution_path; 00997 00998 execution_path=(const char *) getexecname(); 00999 if (execution_path != (const char *) NULL) 01000 { 01001 if (*execution_path != *DirectorySeparator) 01002 (void) ConcatenateMagickString(path,DirectorySeparator,extent); 01003 (void) ConcatenateMagickString(path,execution_path,extent); 01004 } 01005 } 01006 #endif 01007 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 01008 NTGetExecutionPath(path,extent); 01009 #endif 01010 #if defined(__GNU__) 01011 { 01012 char 01013 *program_name, 01014 *execution_path; 01015 01016 ssize_t 01017 count; 01018 01019 count=0; 01020 execution_path=(char *) NULL; 01021 program_name=program_invocation_name; 01022 if (*program_invocation_name != '/') 01023 { 01024 size_t 01025 extent; 01026 01027 extent=strlen(directory)+strlen(program_name)+2; 01028 program_name=AcquireQuantumMemory(extent,sizeof(*program_name)); 01029 if (program_name == (char *) NULL) 01030 program_name=program_invocation_name; 01031 else 01032 count=FormatLocaleString(program_name,extent,"%s/%s",directory, 01033 program_invocation_name); 01034 } 01035 if (count != -1) 01036 { 01037 execution_path=realpath(program_name,NULL); 01038 if (execution_path != (char *) NULL) 01039 (void) CopyMagickString(path,execution_path,extent); 01040 } 01041 if (program_name != program_invocation_name) 01042 program_name=(char *) RelinquishMagickMemory(program_name); 01043 execution_path=(char *) RelinquishMagickMemory(execution_path); 01044 } 01045 #endif 01046 return(IsPathAccessible(path)); 01047 } 01048 01049 /* 01050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01051 % % 01052 % % 01053 % % 01054 % G e t M a g i c k P a g e S i z e % 01055 % % 01056 % % 01057 % % 01058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01059 % 01060 % GetMagickPageSize() returns the memory page size. 01061 % 01062 % The format of the GetMagickPageSize method is: 01063 % 01064 % ssize_t GetMagickPageSize() 01065 % 01066 */ 01067 MagickPrivate ssize_t GetMagickPageSize(void) 01068 { 01069 static ssize_t 01070 page_size = -1; 01071 01072 if (page_size > 0) 01073 return(page_size); 01074 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) 01075 page_size=(ssize_t) sysconf(_SC_PAGE_SIZE); 01076 #else 01077 #if defined(MAGICKCORE_HAVE_GETPAGESIZE) 01078 page_size=(ssize_t) getpagesize(); 01079 #endif 01080 #endif 01081 if (page_size <= 0) 01082 page_size=16384; 01083 return(page_size); 01084 } 01085 01086 /* 01087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01088 % % 01089 % % 01090 % % 01091 % G e t P a t h A t t r i b u t e s % 01092 % % 01093 % % 01094 % % 01095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01096 % 01097 % GetPathAttributes() returns attributes (e.g. size of file) about a path. 01098 % 01099 % The path of the GetPathAttributes method is: 01100 % 01101 % MagickBooleanType GetPathAttributes(const char *path,void *attributes) 01102 % 01103 % A description of each parameter follows. 01104 % 01105 % o path: the file path. 01106 % 01107 % o attributes: the path attributes are returned here. 01108 % 01109 */ 01110 MagickExport MagickBooleanType GetPathAttributes(const char *path, 01111 void *attributes) 01112 { 01113 MagickBooleanType 01114 status; 01115 01116 if (path == (const char *) NULL) 01117 { 01118 errno=EINVAL; 01119 return(MagickFalse); 01120 } 01121 status=stat_utf8(path,(struct stat *) attributes) == 0 ? MagickTrue : 01122 MagickFalse; 01123 return(status); 01124 } 01125 01126 /* 01127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01128 % % 01129 % % 01130 % % 01131 % G e t P a t h C o m p o n e n t % 01132 % % 01133 % % 01134 % % 01135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01136 % 01137 % GetPathComponent() returns the parent directory name, filename, basename, or 01138 % extension of a file path. 01139 % 01140 % The format of the GetPathComponent function is: 01141 % 01142 % GetPathComponent(const char *path,PathType type,char *component) 01143 % 01144 % A description of each parameter follows: 01145 % 01146 % o path: Specifies a pointer to a character array that contains the 01147 % file path. 01148 % 01149 % o type: Specififies which file path component to return. 01150 % 01151 % o component: the selected file path component is returned here. 01152 % 01153 */ 01154 MagickExport void GetPathComponent(const char *path,PathType type, 01155 char *component) 01156 { 01157 char 01158 magick[MaxTextExtent], 01159 *q, 01160 subimage[MaxTextExtent]; 01161 01162 register char 01163 *p; 01164 01165 assert(path != (const char *) NULL); 01166 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",path); 01167 assert(component != (char *) NULL); 01168 if (*path == '\0') 01169 { 01170 *component='\0'; 01171 return; 01172 } 01173 (void) CopyMagickString(component,path,MaxTextExtent); 01174 *magick='\0'; 01175 #if defined(__OS2__) 01176 if (path[1] != ":") 01177 #endif 01178 for (p=component; *p != '\0'; p++) 01179 { 01180 if ((*p == '%') && (*(p+1) == '[')) 01181 { 01182 /* 01183 Skip over %[...]. 01184 */ 01185 for (p++; (*p != ']') && (*p != '\0'); p++) ; 01186 if (*p == '\0') 01187 break; 01188 } 01189 if ((*p == ':') && (IsPathDirectory(path) < 0) && 01190 (IsPathAccessible(path) == MagickFalse)) 01191 { 01192 /* 01193 Look for image format specification (e.g. ps3:image). 01194 */ 01195 (void) CopyMagickString(magick,component,(size_t) (p-component+1)); 01196 if (IsMagickConflict(magick) != MagickFalse) 01197 *magick='\0'; 01198 else 01199 for (q=component; *q != '\0'; q++) 01200 *q=(*++p); 01201 break; 01202 } 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 % size_t *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 MagickPrivate char **GetPathComponents(const char *path, 01328 size_t *number_components) 01329 { 01330 char 01331 **components; 01332 01333 register const char 01334 *p, 01335 *q; 01336 01337 register ssize_t 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 < (ssize_t) *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_utf8(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 % ssize_t *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 MagickPrivate char **ListFiles(const char *directory,const char *pattern, 01560 size_t *number_entries) 01561 { 01562 char 01563 **filelist; 01564 01565 DIR 01566 *current_directory; 01567 01568 struct dirent 01569 *buffer, 01570 *entry; 01571 01572 size_t 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 != (size_t *) 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)+ 01601 FILENAME_MAX+1); 01602 if (buffer == (struct dirent *) NULL) 01603 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 01604 while ((MagickReadDirectory(current_directory,buffer,&entry) == 0) && 01605 (entry != (struct dirent *) NULL)) 01606 { 01607 if (*entry->d_name == '.') 01608 continue; 01609 if ((IsPathDirectory(entry->d_name) > 0) || 01610 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 01611 (GlobExpression(entry->d_name,pattern,MagickTrue) != MagickFalse)) 01612 #else 01613 (GlobExpression(entry->d_name,pattern,MagickFalse) != MagickFalse)) 01614 #endif 01615 { 01616 if (*number_entries >= max_entries) 01617 { 01618 /* 01619 Extend the file list. 01620 */ 01621 max_entries<<=1; 01622 filelist=(char **) ResizeQuantumMemory(filelist,(size_t) 01623 max_entries,sizeof(*filelist)); 01624 if (filelist == (char **) NULL) 01625 break; 01626 } 01627 #if defined(vms) 01628 { 01629 register char 01630 *p; 01631 01632 p=strchr(entry->d_name,';'); 01633 if (p) 01634 *p='\0'; 01635 if (*number_entries > 0) 01636 if (LocaleCompare(entry->d_name,filelist[*number_entries-1]) == 0) 01637 continue; 01638 } 01639 #endif 01640 filelist[*number_entries]=(char *) AcquireString(entry->d_name); 01641 (*number_entries)++; 01642 } 01643 } 01644 buffer=(struct dirent *) RelinquishMagickMemory(buffer); 01645 (void) closedir(current_directory); 01646 if (filelist == (char **) NULL) 01647 return((char **) NULL); 01648 /* 01649 Sort filelist in ascending order. 01650 */ 01651 qsort((void *) filelist,(size_t) *number_entries,sizeof(*filelist), 01652 FileCompare); 01653 return(filelist); 01654 } 01655 01656 /* 01657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01658 % % 01659 % % 01660 % % 01661 % M a g i c k D e l a y % 01662 % % 01663 % % 01664 % % 01665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01666 % 01667 % MagickDelay() suspends program execution for the number of milliseconds 01668 % specified. 01669 % 01670 % The format of the Delay method is: 01671 % 01672 % void MagickDelay(const MagickSizeType milliseconds) 01673 % 01674 % A description of each parameter follows: 01675 % 01676 % o milliseconds: Specifies the number of milliseconds to delay before 01677 % returning. 01678 % 01679 */ 01680 MagickPrivate void MagickDelay(const MagickSizeType milliseconds) 01681 { 01682 if (milliseconds == 0) 01683 return; 01684 #if defined(MAGICKCORE_HAVE_NANOSLEEP) 01685 { 01686 struct timespec 01687 timer; 01688 01689 timer.tv_sec=(time_t) (milliseconds/1000); 01690 timer.tv_nsec=(milliseconds % 1000)*1000*1000; 01691 (void) nanosleep(&timer,(struct timespec *) NULL); 01692 } 01693 #elif defined(MAGICKCORE_HAVE_USLEEP) 01694 usleep(1000*milliseconds); 01695 #elif defined(MAGICKCORE_HAVE_SELECT) 01696 { 01697 struct timeval 01698 timer; 01699 01700 timer.tv_sec=(long) milliseconds/1000; 01701 timer.tv_usec=(long) (milliseconds % 1000)*1000; 01702 (void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer); 01703 } 01704 #elif defined(MAGICKCORE_HAVE_POLL) 01705 (void) poll((struct pollfd *) NULL,0,(int) milliseconds); 01706 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 01707 Sleep((long) milliseconds); 01708 #elif defined(vms) 01709 { 01710 float 01711 timer; 01712 01713 timer=milliseconds/1000.0; 01714 lib$wait(&timer); 01715 } 01716 #elif defined(__BEOS__) 01717 snooze(1000*milliseconds); 01718 #else 01719 # error "Time delay method not defined." 01720 #endif 01721 } 01722 01723 /* 01724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01725 % % 01726 % % 01727 % % 01728 % M u l t i l i n e C e n s u s % 01729 % % 01730 % % 01731 % % 01732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01733 % 01734 % MultilineCensus() returns the number of lines within a label. A line is 01735 % represented by a \n character. 01736 % 01737 % The format of the MultilineCenus method is: 01738 % 01739 % size_t MultilineCensus(const char *label) 01740 % 01741 % A description of each parameter follows. 01742 % 01743 % o label: This character string is the label. 01744 % 01745 */ 01746 MagickExport size_t MultilineCensus(const char *label) 01747 { 01748 size_t 01749 number_lines; 01750 01751 /* 01752 Determine the number of lines within this label. 01753 */ 01754 if (label == (char *) NULL) 01755 return(0); 01756 for (number_lines=1; *label != '\0'; label++) 01757 if (*label == '\n') 01758 number_lines++; 01759 return(number_lines); 01760 } 01761 01762 /* 01763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01764 % % 01765 % % 01766 % % 01767 % S y s t e m C o m m a n d % 01768 % % 01769 % % 01770 % % 01771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01772 % 01773 % SystemCommand() executes the specified command and waits until it 01774 % terminates. The returned value is the exit status of the command. 01775 % 01776 % The format of the SystemCommand method is: 01777 % 01778 % int SystemCommand(const MagickBooleanType asynchronous, 01779 % const MagickBooleanType verbose,const char *command, 01780 % ExceptionInfo *exception) 01781 % 01782 % A description of each parameter follows: 01783 % 01784 % o asynchronous: a value other than 0 executes the parent program 01785 % concurrently with the new child process. 01786 % 01787 % o verbose: a value other than 0 prints the executed command before it is 01788 % invoked. 01789 % 01790 % o command: this string is the command to execute. 01791 % 01792 % o exception: return any errors here. 01793 % 01794 */ 01795 MagickExport int SystemCommand(const MagickBooleanType asynchronous, 01796 const MagickBooleanType verbose,const char *command,ExceptionInfo *exception) 01797 { 01798 char 01799 **arguments, 01800 *shell_command; 01801 01802 int 01803 number_arguments, 01804 status; 01805 01806 PolicyDomain 01807 domain; 01808 01809 PolicyRights 01810 rights; 01811 01812 register ssize_t 01813 i; 01814 01815 status=(-1); 01816 arguments=StringToArgv(command,&number_arguments); 01817 if (arguments == (char **) NULL) 01818 return(status); 01819 rights=ExecutePolicyRights; 01820 domain=DelegatePolicyDomain; 01821 if (IsRightsAuthorized(domain,rights,arguments[1]) == MagickFalse) 01822 { 01823 errno=EPERM; 01824 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, 01825 "NotAuthorized","`%s'",arguments[1]); 01826 for (i=0; i < (ssize_t) number_arguments; i++) 01827 arguments[i]=DestroyString(arguments[i]); 01828 arguments=(char **) RelinquishMagickMemory(arguments); 01829 return(-1); 01830 } 01831 if (verbose != MagickFalse) 01832 { 01833 (void) FormatLocaleFile(stderr,"%s\n",command); 01834 (void) fflush(stderr); 01835 } 01836 shell_command=(char *) command; 01837 if (asynchronous != MagickFalse) 01838 { 01839 shell_command=AcquireString(command); 01840 (void) ConcatenateMagickString(shell_command,"&",MaxTextExtent); 01841 } 01842 #if defined(MAGICKCORE_POSIX_SUPPORT) 01843 #if !defined(MAGICKCORE_HAVE_EXECVP) 01844 status=system(shell_command); 01845 #else 01846 if ((asynchronous != MagickFalse) || 01847 (strpbrk(shell_command,"&;<>|") != (char *) NULL)) 01848 status=system(shell_command); 01849 else 01850 { 01851 pid_t 01852 child_pid; 01853 01854 /* 01855 Call application directly rather than from a shell. 01856 */ 01857 child_pid=fork(); 01858 if (child_pid == (pid_t) -1) 01859 status=system(command); 01860 else 01861 if (child_pid == 0) 01862 { 01863 status=execvp(arguments[1],arguments+1); 01864 _exit(1); 01865 } 01866 else 01867 { 01868 int 01869 child_status; 01870 01871 pid_t 01872 pid; 01873 01874 child_status=0; 01875 pid=waitpid(child_pid,&child_status,0); 01876 if (pid == -1) 01877 status=(-1); 01878 else 01879 { 01880 if (WIFEXITED(child_status) != 0) 01881 status=WEXITSTATUS(child_status); 01882 else 01883 if (WIFSIGNALED(child_status)) 01884 status=(-1); 01885 } 01886 } 01887 } 01888 #endif 01889 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 01890 status=NTSystemCommand(shell_command); 01891 #elif defined(macintosh) 01892 status=MACSystemCommand(shell_command); 01893 #elif defined(vms) 01894 status=system(shell_command); 01895 #else 01896 # error No suitable system() method. 01897 #endif 01898 if (status < 0) 01899 (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, 01900 "`%s' (%d)",command,status); 01901 if (shell_command != command) 01902 shell_command=DestroyString(shell_command); 01903 for (i=0; i < (ssize_t) number_arguments; i++) 01904 arguments[i]=DestroyString(arguments[i]); 01905 arguments=(char **) RelinquishMagickMemory(arguments); 01906 return(status); 01907 }