1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % M M OOO DDDD U U L EEEEE % 7 % MM MM O O D D U U L E % 8 % M M M O O D D U U L EEE % 9 % M M O O D D U U L E % 10 % M M OOO DDDD UUU LLLLL EEEEE % 11 % % 12 % % 13 % MagickCore Module Methods % 14 % % 15 % Software Design % 16 % Bob Friesenhahn % 17 % March 2000 % 18 % % 19 % % 20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % http://www.imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % 37 % 38 */ 39 40 /* 42 Include declarations. 43 */ 44 #include "MagickCore/studio.h" 45 #include "MagickCore/blob.h" 46 #include "MagickCore/coder.h" 47 #include "MagickCore/client.h" 48 #include "MagickCore/configure.h" 49 #include "MagickCore/exception.h" 50 #include "MagickCore/exception-private.h" 51 #include "MagickCore/log.h" 52 #include "MagickCore/linked-list.h" 53 #include "MagickCore/magic.h" 54 #include "MagickCore/magick.h" 55 #include "MagickCore/memory_.h" 56 #include "MagickCore/module.h" 57 #include "MagickCore/module-private.h" 58 #include "MagickCore/nt-base-private.h" 59 #include "MagickCore/policy.h" 60 #include "MagickCore/semaphore.h" 61 #include "MagickCore/splay-tree.h" 62 #include "MagickCore/static.h" 63 #include "MagickCore/string_.h" 64 #include "MagickCore/string-private.h" 65 #include "MagickCore/token.h" 66 #include "MagickCore/utility.h" 67 #include "MagickCore/utility-private.h" 68 #if defined(MAGICKCORE_MODULES_SUPPORT) 69 #if defined(MAGICKCORE_LTDL_DELEGATE) 70 #include "ltdl.h" 71 typedef lt_dlhandle ModuleHandle; 72 #else 73 typedef void *ModuleHandle; 74 #endif 75 76 /* 78 Define declarations. 79 */ 80 #if defined(MAGICKCORE_LTDL_DELEGATE) 81 # define ModuleGlobExpression "*.la" 82 #else 83 # if defined(_DEBUG) 84 # define ModuleGlobExpression "IM_MOD_DB_*.dll" 85 # else 86 # define ModuleGlobExpression "IM_MOD_RL_*.dll" 87 # endif 88 #endif 89 90 /* 92 Global declarations. 93 */ 94 static SemaphoreInfo 95 *module_semaphore = (SemaphoreInfo *) NULL; 96 97 static SplayTreeInfo 98 *module_list = (SplayTreeInfo *) NULL; 99 100 /* 102 Forward declarations. 103 */ 104 static const ModuleInfo 105 *RegisterModule(const ModuleInfo *,ExceptionInfo *); 106 107 static MagickBooleanType 108 GetMagickModulePath(const char *,MagickModuleType,char *,ExceptionInfo *), 109 IsModuleTreeInstantiated(), 110 UnregisterModule(const ModuleInfo *,ExceptionInfo *); 111 112 static void 113 TagToCoderModuleName(const char *,char *), 114 TagToFilterModuleName(const char *,char *), 115 TagToModuleName(const char *,const char *,char *); 116 117 /* 119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 120 % % 121 % % 122 % % 123 % A c q u i r e M o d u l e I n f o % 124 % % 125 % % 126 % % 127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 128 % 129 % AcquireModuleInfo() allocates the ModuleInfo structure. 130 % 131 % The format of the AcquireModuleInfo method is: 132 % 133 % ModuleInfo *AcquireModuleInfo(const char *path,const char *tag) 134 % 135 % A description of each parameter follows: 136 % 137 % o path: the path associated with the tag. 138 % 139 % o tag: a character string that represents the image format we are 140 % looking for. 141 % 142 */ 143 MagickExport ModuleInfo *AcquireModuleInfo(const char *path,const char *tag) 144 { 145 ModuleInfo 146 *module_info; 147 148 module_info=(ModuleInfo *) AcquireMagickMemory(sizeof(*module_info)); 149 if (module_info == (ModuleInfo *) NULL) 150 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 151 (void) ResetMagickMemory(module_info,0,sizeof(*module_info)); 152 if (path != (const char *) NULL) 153 module_info->path=ConstantString(path); 154 if (tag != (const char *) NULL) 155 module_info->tag=ConstantString(tag); 156 module_info->timestamp=time(0); 157 module_info->signature=MagickCoreSignature; 158 return(module_info); 159 } 160 161 /* 163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 164 % % 165 % % 166 % % 167 % D e s t r o y M o d u l e L i s t % 168 % % 169 % % 170 % % 171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 172 % 173 % DestroyModuleList() unregisters any previously loaded modules and exits 174 % the module loaded environment. 175 % 176 % The format of the DestroyModuleList module is: 177 % 178 % void DestroyModuleList(void) 179 % 180 */ 181 MagickExport void DestroyModuleList(void) 182 { 183 /* 184 Destroy magick modules. 185 */ 186 LockSemaphoreInfo(module_semaphore); 187 #if defined(MAGICKCORE_MODULES_SUPPORT) 188 if (module_list != (SplayTreeInfo *) NULL) 189 module_list=DestroySplayTree(module_list); 190 #endif 191 UnlockSemaphoreInfo(module_semaphore); 192 } 193 194 /* 196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 197 % % 198 % % 199 % % 200 % G e t M o d u l e I n f o % 201 % % 202 % % 203 % % 204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 205 % 206 % GetModuleInfo() returns a pointer to a ModuleInfo structure that matches the 207 % specified tag. If tag is NULL, the head of the module list is returned. If 208 % no modules are loaded, or the requested module is not found, NULL is 209 % returned. 210 % 211 % The format of the GetModuleInfo module is: 212 % 213 % ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception) 214 % 215 % A description of each parameter follows: 216 % 217 % o tag: a character string that represents the image format we are 218 % looking for. 219 % 220 % o exception: return any errors or warnings in this structure. 221 % 222 */ 223 MagickExport ModuleInfo *GetModuleInfo(const char *tag,ExceptionInfo *exception) 224 { 225 ModuleInfo 226 *module_info; 227 228 if (IsModuleTreeInstantiated() == MagickFalse) 229 return((ModuleInfo *) NULL); 230 LockSemaphoreInfo(module_semaphore); 231 ResetSplayTreeIterator(module_list); 232 if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0)) 233 { 234 #if defined(MAGICKCORE_MODULES_SUPPORT) 235 if (LocaleCompare(tag,"*") == 0) 236 (void) OpenModules(exception); 237 #endif 238 module_info=(ModuleInfo *) GetNextValueInSplayTree(module_list); 239 UnlockSemaphoreInfo(module_semaphore); 240 return(module_info); 241 } 242 module_info=(ModuleInfo *) GetValueFromSplayTree(module_list,tag); 243 UnlockSemaphoreInfo(module_semaphore); 244 return(module_info); 245 } 246 247 /* 249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 250 % % 251 % % 252 % % 253 % G e t M o d u l e I n f o L i s t % 254 % % 255 % % 256 % % 257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 258 % 259 % GetModuleInfoList() returns any modules that match the specified pattern. 260 % 261 % The format of the GetModuleInfoList function is: 262 % 263 % const ModuleInfo **GetModuleInfoList(const char *pattern, 264 % size_t *number_modules,ExceptionInfo *exception) 265 % 266 % A description of each parameter follows: 267 % 268 % o pattern: Specifies a pointer to a text string containing a pattern. 269 % 270 % o number_modules: This integer returns the number of modules in the list. 271 % 272 % o exception: return any errors or warnings in this structure. 273 % 274 */ 275 276 #if defined(__cplusplus) || defined(c_plusplus) 277 extern "C" { 278 #endif 279 280 static int ModuleInfoCompare(const void *x,const void *y) 281 { 282 const ModuleInfo 283 **p, 284 **q; 285 286 p=(const ModuleInfo **) x, 287 q=(const ModuleInfo **) y; 288 if (LocaleCompare((*p)->path,(*q)->path) == 0) 289 return(LocaleCompare((*p)->tag,(*q)->tag)); 290 return(LocaleCompare((*p)->path,(*q)->path)); 291 } 292 293 #if defined(__cplusplus) || defined(c_plusplus) 294 } 295 #endif 296 297 MagickExport const ModuleInfo **GetModuleInfoList(const char *pattern, 298 size_t *number_modules,ExceptionInfo *exception) 299 { 300 const ModuleInfo 301 **modules; 302 303 register const ModuleInfo 304 *p; 305 306 register ssize_t 307 i; 308 309 /* 310 Allocate module list. 311 */ 312 assert(pattern != (char *) NULL); 313 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 314 assert(number_modules != (size_t *) NULL); 315 *number_modules=0; 316 p=GetModuleInfo("*",exception); 317 if (p == (const ModuleInfo *) NULL) 318 return((const ModuleInfo **) NULL); 319 modules=(const ModuleInfo **) AcquireQuantumMemory((size_t) 320 GetNumberOfNodesInSplayTree(module_list)+1UL,sizeof(*modules)); 321 if (modules == (const ModuleInfo **) NULL) 322 return((const ModuleInfo **) NULL); 323 /* 324 Generate module list. 325 */ 326 LockSemaphoreInfo(module_semaphore); 327 ResetSplayTreeIterator(module_list); 328 p=(const ModuleInfo *) GetNextValueInSplayTree(module_list); 329 for (i=0; p != (const ModuleInfo *) NULL; ) 330 { 331 if ((p->stealth == MagickFalse) && 332 (GlobExpression(p->tag,pattern,MagickFalse) != MagickFalse)) 333 modules[i++]=p; 334 p=(const ModuleInfo *) GetNextValueInSplayTree(module_list); 335 } 336 UnlockSemaphoreInfo(module_semaphore); 337 qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleInfoCompare); 338 modules[i]=(ModuleInfo *) NULL; 339 *number_modules=(size_t) i; 340 return(modules); 341 } 342 343 /* 345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 346 % % 347 % % 348 % % 349 % G e t M o d u l e L i s t % 350 % % 351 % % 352 % % 353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 354 % 355 % GetModuleList() returns any image format modules that match the specified 356 % pattern. 357 % 358 % The format of the GetModuleList function is: 359 % 360 % char **GetModuleList(const char *pattern,const MagickModuleType type, 361 % size_t *number_modules,ExceptionInfo *exception) 362 % 363 % A description of each parameter follows: 364 % 365 % o pattern: Specifies a pointer to a text string containing a pattern. 366 % 367 % o type: choose from MagickImageCoderModule or MagickImageFilterModule. 368 % 369 % o number_modules: This integer returns the number of modules in the 370 % list. 371 % 372 % o exception: return any errors or warnings in this structure. 373 % 374 */ 375 376 #if defined(__cplusplus) || defined(c_plusplus) 377 extern "C" { 378 #endif 379 380 static int ModuleCompare(const void *x,const void *y) 381 { 382 register const char 383 **p, 384 **q; 385 386 p=(const char **) x; 387 q=(const char **) y; 388 return(LocaleCompare(*p,*q)); 389 } 390 391 #if defined(__cplusplus) || defined(c_plusplus) 392 } 393 #endif 394 395 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry, 396 struct dirent **result) 397 { 398 #if defined(MAGICKCORE_HAVE_READDIR_R) 399 return(readdir_r(directory,entry,result)); 400 #else 401 (void) entry; 402 errno=0; 403 *result=readdir(directory); 404 return(errno); 405 #endif 406 } 407 408 MagickExport char **GetModuleList(const char *pattern, 409 const MagickModuleType type,size_t *number_modules,ExceptionInfo *exception) 410 { 411 #define MaxModules 511 412 413 char 414 **modules, 415 filename[MagickPathExtent], 416 module_path[MagickPathExtent], 417 path[MagickPathExtent]; 418 419 DIR 420 *directory; 421 422 MagickBooleanType 423 status; 424 425 register ssize_t 426 i; 427 428 size_t 429 max_entries; 430 431 struct dirent 432 *buffer, 433 *entry; 434 435 /* 436 Locate all modules in the image coder or filter path. 437 */ 438 switch (type) 439 { 440 case MagickImageCoderModule: 441 default: 442 { 443 TagToCoderModuleName("magick",filename); 444 status=GetMagickModulePath(filename,MagickImageCoderModule,module_path, 445 exception); 446 break; 447 } 448 case MagickImageFilterModule: 449 { 450 TagToFilterModuleName("analyze",filename); 451 status=GetMagickModulePath(filename,MagickImageFilterModule,module_path, 452 exception); 453 break; 454 } 455 } 456 if (status == MagickFalse) 457 return((char **) NULL); 458 GetPathComponent(module_path,HeadPath,path); 459 max_entries=MaxModules; 460 modules=(char **) AcquireQuantumMemory((size_t) max_entries+1UL, 461 sizeof(*modules)); 462 if (modules == (char **) NULL) 463 return((char **) NULL); 464 *modules=(char *) NULL; 465 directory=opendir(path); 466 if (directory == (DIR *) NULL) 467 { 468 modules=(char **) RelinquishMagickMemory(modules); 469 return((char **) NULL); 470 } 471 buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1); 472 if (buffer == (struct dirent *) NULL) 473 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 474 i=0; 475 while ((MagickReadDirectory(directory,buffer,&entry) == 0) && 476 (entry != (struct dirent *) NULL)) 477 { 478 status=GlobExpression(entry->d_name,ModuleGlobExpression,MagickFalse); 479 if (status == MagickFalse) 480 continue; 481 if (GlobExpression(entry->d_name,pattern,MagickFalse) == MagickFalse) 482 continue; 483 if (i >= (ssize_t) max_entries) 484 { 485 modules=(char **) NULL; 486 if (~max_entries > max_entries) 487 modules=(char **) ResizeQuantumMemory(modules,(size_t) 488 (max_entries << 1),sizeof(*modules)); 489 max_entries<<=1; 490 if (modules == (char **) NULL) 491 break; 492 } 493 /* 494 Add new module name to list. 495 */ 496 modules[i]=AcquireString((char *) NULL); 497 GetPathComponent(entry->d_name,BasePath,modules[i]); 498 if (LocaleNCompare("IM_MOD_",modules[i],7) == 0) 499 { 500 (void) CopyMagickString(modules[i],modules[i]+10,MagickPathExtent); 501 modules[i][strlen(modules[i])-1]='\0'; 502 } 503 i++; 504 } 505 buffer=(struct dirent *) RelinquishMagickMemory(buffer); 506 (void) closedir(directory); 507 if (modules == (char **) NULL) 508 { 509 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureError, 510 "MemoryAllocationFailed","`%s'",pattern); 511 return((char **) NULL); 512 } 513 qsort((void *) modules,(size_t) i,sizeof(*modules),ModuleCompare); 514 modules[i]=(char *) NULL; 515 *number_modules=(size_t) i; 516 return(modules); 517 } 518 519 /* 521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 522 % % 523 % % 524 % % 525 % G e t M a g i c k M o d u l e P a t h % 526 % % 527 % % 528 % % 529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 530 % 531 % GetMagickModulePath() finds a module with the specified module type and 532 % filename. 533 % 534 % The format of the GetMagickModulePath module is: 535 % 536 % MagickBooleanType GetMagickModulePath(const char *filename, 537 % MagickModuleType module_type,char *path,ExceptionInfo *exception) 538 % 539 % A description of each parameter follows: 540 % 541 % o filename: the module file name. 542 % 543 % o module_type: the module type: MagickImageCoderModule or 544 % MagickImageFilterModule. 545 % 546 % o path: the path associated with the filename. 547 % 548 % o exception: return any errors or warnings in this structure. 549 % 550 */ 551 static MagickBooleanType GetMagickModulePath(const char *filename, 552 MagickModuleType module_type,char *path,ExceptionInfo *exception) 553 { 554 char 555 *module_path; 556 557 assert(filename != (const char *) NULL); 558 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 559 assert(path != (char *) NULL); 560 assert(exception != (ExceptionInfo *) NULL); 561 if (strchr(filename,'/') != (char *) NULL) 562 return(MagickFalse); 563 (void) CopyMagickString(path,filename,MagickPathExtent); 564 module_path=(char *) NULL; 565 switch (module_type) 566 { 567 case MagickImageCoderModule: 568 default: 569 { 570 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 571 "Searching for coder module file \"%s\" ...",filename); 572 module_path=GetEnvironmentValue("MAGICK_CODER_MODULE_PATH"); 573 #if defined(MAGICKCORE_CODER_PATH) 574 if (module_path == (char *) NULL) 575 module_path=AcquireString(MAGICKCORE_CODER_PATH); 576 #endif 577 break; 578 } 579 case MagickImageFilterModule: 580 { 581 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 582 "Searching for filter module file \"%s\" ...",filename); 583 module_path=GetEnvironmentValue("MAGICK_CODER_FILTER_PATH"); 584 #if defined(MAGICKCORE_FILTER_PATH) 585 if (module_path == (char *) NULL) 586 module_path=AcquireString(MAGICKCORE_FILTER_PATH); 587 #endif 588 break; 589 } 590 } 591 if (module_path != (char *) NULL) 592 { 593 register char 594 *p, 595 *q; 596 597 for (p=module_path-1; p != (char *) NULL; ) 598 { 599 (void) CopyMagickString(path,p+1,MagickPathExtent); 600 q=strchr(path,DirectoryListSeparator); 601 if (q != (char *) NULL) 602 *q='\0'; 603 q=path+strlen(path)-1; 604 if ((q >= path) && (*q != *DirectorySeparator)) 605 (void) ConcatenateMagickString(path,DirectorySeparator, 606 MagickPathExtent); 607 (void) ConcatenateMagickString(path,filename,MagickPathExtent); 608 if (IsPathAccessible(path) != MagickFalse) 609 { 610 module_path=DestroyString(module_path); 611 return(MagickTrue); 612 } 613 p=strchr(p+1,DirectoryListSeparator); 614 } 615 module_path=DestroyString(module_path); 616 } 617 #if defined(MAGICKCORE_INSTALLED_SUPPORT) 618 else 619 #if defined(MAGICKCORE_CODER_PATH) 620 { 621 const char 622 *directory; 623 624 /* 625 Search hard coded paths. 626 */ 627 switch (module_type) 628 { 629 case MagickImageCoderModule: 630 default: 631 { 632 directory=MAGICKCORE_CODER_PATH; 633 break; 634 } 635 case MagickImageFilterModule: 636 { 637 directory=MAGICKCORE_FILTER_PATH; 638 break; 639 } 640 } 641 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",directory, 642 filename); 643 if (IsPathAccessible(path) == MagickFalse) 644 { 645 ThrowFileException(exception,ConfigureWarning, 646 "UnableToOpenModuleFile",path); 647 return(MagickFalse); 648 } 649 return(MagickTrue); 650 } 651 #else 652 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 653 { 654 const char 655 *registery_key; 656 657 unsigned char 658 *key_value; 659 660 /* 661 Locate path via registry key. 662 */ 663 switch (module_type) 664 { 665 case MagickImageCoderModule: 666 default: 667 { 668 registery_key="CoderModulesPath"; 669 break; 670 } 671 case MagickImageFilterModule: 672 { 673 registery_key="FilterModulesPath"; 674 break; 675 } 676 } 677 key_value=NTRegistryKeyLookup(registery_key); 678 if (key_value == (unsigned char *) NULL) 679 { 680 ThrowMagickException(exception,GetMagickModule(),ConfigureError, 681 "RegistryKeyLookupFailed","`%s'",registery_key); 682 return(MagickFalse); 683 } 684 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",(char *) 685 key_value,DirectorySeparator,filename); 686 key_value=(unsigned char *) RelinquishMagickMemory(key_value); 687 if (IsPathAccessible(path) == MagickFalse) 688 { 689 ThrowFileException(exception,ConfigureWarning, 690 "UnableToOpenModuleFile",path); 691 return(MagickFalse); 692 } 693 return(MagickTrue); 694 } 695 #endif 696 #endif 697 #if !defined(MAGICKCORE_CODER_PATH) && !defined(MAGICKCORE_WINDOWS_SUPPORT) 698 # error MAGICKCORE_CODER_PATH or MAGICKCORE_WINDOWS_SUPPORT must be defined when MAGICKCORE_INSTALLED_SUPPORT is defined 699 #endif 700 #else 701 { 702 char 703 *home; 704 705 home=GetEnvironmentValue("MAGICK_HOME"); 706 if (home != (char *) NULL) 707 { 708 /* 709 Search MAGICK_HOME. 710 */ 711 #if !defined(MAGICKCORE_POSIX_SUPPORT) 712 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",home, 713 DirectorySeparator,filename); 714 #else 715 const char 716 *directory; 717 718 switch (module_type) 719 { 720 case MagickImageCoderModule: 721 default: 722 { 723 directory=MAGICKCORE_CODER_RELATIVE_PATH; 724 break; 725 } 726 case MagickImageFilterModule: 727 { 728 directory=MAGICKCORE_FILTER_RELATIVE_PATH; 729 break; 730 } 731 } 732 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s",home, 733 directory,filename); 734 #endif 735 home=DestroyString(home); 736 if (IsPathAccessible(path) != MagickFalse) 737 return(MagickTrue); 738 } 739 } 740 if (*GetClientPath() != '\0') 741 { 742 /* 743 Search based on executable directory. 744 */ 745 #if !defined(MAGICKCORE_POSIX_SUPPORT) 746 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",GetClientPath(), 747 DirectorySeparator,filename); 748 #else 749 char 750 prefix[MagickPathExtent]; 751 752 const char 753 *directory; 754 755 switch (module_type) 756 { 757 case MagickImageCoderModule: 758 default: 759 { 760 directory="coders"; 761 break; 762 } 763 case MagickImageFilterModule: 764 { 765 directory="filters"; 766 break; 767 } 768 } 769 (void) CopyMagickString(prefix,GetClientPath(),MagickPathExtent); 770 ChopPathComponents(prefix,1); 771 (void) FormatLocaleString(path,MagickPathExtent,"%s/lib/%s/%s/%s",prefix, 772 MAGICKCORE_MODULES_RELATIVE_PATH,directory,filename); 773 #endif 774 if (IsPathAccessible(path) != MagickFalse) 775 return(MagickTrue); 776 } 777 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 778 { 779 /* 780 Search module path. 781 */ 782 if ((NTGetModulePath("CORE_RL_MagickCore_.dll",path) != MagickFalse) || 783 (NTGetModulePath("CORE_DB_MagickCore_.dll",path) != MagickFalse)) 784 { 785 (void) ConcatenateMagickString(path,DirectorySeparator, 786 MagickPathExtent); 787 (void) ConcatenateMagickString(path,filename,MagickPathExtent); 788 if (IsPathAccessible(path) != MagickFalse) 789 return(MagickTrue); 790 } 791 } 792 #endif 793 { 794 char 795 *home; 796 797 home=GetEnvironmentValue("XDG_CONFIG_HOME"); 798 if (home == (char *) NULL) 799 home=GetEnvironmentValue("LOCALAPPDATA"); 800 if (home == (char *) NULL) 801 home=GetEnvironmentValue("APPDATA"); 802 if (home == (char *) NULL) 803 home=GetEnvironmentValue("USERPROFILE"); 804 if (home != (char *) NULL) 805 { 806 /* 807 Search $XDG_CONFIG_HOME/ImageMagick. 808 */ 809 (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s%s", 810 home,DirectorySeparator,DirectorySeparator,filename); 811 home=DestroyString(home); 812 if (IsPathAccessible(path) != MagickFalse) 813 return(MagickTrue); 814 } 815 home=GetEnvironmentValue("HOME"); 816 if (home != (char *) NULL) 817 { 818 /* 819 Search $HOME/.config/ImageMagick. 820 */ 821 (void) FormatLocaleString(path,MagickPathExtent, 822 "%s%s.config%sImageMagick%s%s",home,DirectorySeparator, 823 DirectorySeparator,DirectorySeparator,filename); 824 home=DestroyString(home); 825 if (IsPathAccessible(path) != MagickFalse) 826 return(MagickTrue); 827 } 828 } 829 /* 830 Search current directory. 831 */ 832 if (IsPathAccessible(path) != MagickFalse) 833 return(MagickTrue); 834 if (exception->severity < ConfigureError) 835 ThrowFileException(exception,ConfigureWarning,"UnableToOpenModuleFile", 836 path); 837 #endif 838 return(MagickFalse); 839 } 840 841 /* 843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 844 % % 845 % % 846 % % 847 % I s M o d u l e T r e e I n s t a n t i a t e d % 848 % % 849 % % 850 % % 851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 852 % 853 % IsModuleTreeInstantiated() determines if the module tree is instantiated. 854 % If not, it instantiates the tree and returns it. 855 % 856 % The format of the IsModuleTreeInstantiated() method is: 857 % 858 % IsModuleTreeInstantiated() 859 % 860 */ 861 862 static void *DestroyModuleNode(void *module_info) 863 { 864 ExceptionInfo 865 *exception; 866 867 register ModuleInfo 868 *p; 869 870 exception=AcquireExceptionInfo(); 871 p=(ModuleInfo *) module_info; 872 if (UnregisterModule(p,exception) == MagickFalse) 873 CatchException(exception); 874 if (p->tag != (char *) NULL) 875 p->tag=DestroyString(p->tag); 876 if (p->path != (char *) NULL) 877 p->path=DestroyString(p->path); 878 exception=DestroyExceptionInfo(exception); 879 return(RelinquishMagickMemory(p)); 880 } 881 882 static MagickBooleanType IsModuleTreeInstantiated() 883 { 884 if (module_list == (SplayTreeInfo *) NULL) 885 { 886 if (module_semaphore == (SemaphoreInfo *) NULL) 887 ActivateSemaphoreInfo(&module_semaphore); 888 LockSemaphoreInfo(module_semaphore); 889 if (module_list == (SplayTreeInfo *) NULL) 890 { 891 MagickBooleanType 892 status; 893 894 ModuleInfo 895 *module_info; 896 897 module_list=NewSplayTree(CompareSplayTreeString, 898 (void *(*)(void *)) NULL,DestroyModuleNode); 899 if (module_list == (SplayTreeInfo *) NULL) 900 ThrowFatalException(ResourceLimitFatalError, 901 "MemoryAllocationFailed"); 902 module_info=AcquireModuleInfo((const char *) NULL,"[boot-strap]"); 903 module_info->stealth=MagickTrue; 904 status=AddValueToSplayTree(module_list,module_info->tag,module_info); 905 if (status == MagickFalse) 906 ThrowFatalException(ResourceLimitFatalError, 907 "MemoryAllocationFailed"); 908 if (lt_dlinit() != 0) 909 ThrowFatalException(ModuleFatalError, 910 "UnableToInitializeModuleLoader"); 911 } 912 UnlockSemaphoreInfo(module_semaphore); 913 } 914 return(module_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse); 915 } 916 917 /* 919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 920 % % 921 % % 922 % % 923 % I n v o k e D y n a m i c I m a g e F i l t e r % 924 % % 925 % % 926 % % 927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 928 % 929 % InvokeDynamicImageFilter() invokes a dynamic image filter. 930 % 931 % The format of the InvokeDynamicImageFilter module is: 932 % 933 % MagickBooleanType InvokeDynamicImageFilter(const char *tag,Image **image, 934 % const int argc,const char **argv,ExceptionInfo *exception) 935 % 936 % A description of each parameter follows: 937 % 938 % o tag: a character string that represents the name of the particular 939 % module. 940 % 941 % o image: the image. 942 % 943 % o argc: a pointer to an integer describing the number of elements in the 944 % argument vector. 945 % 946 % o argv: a pointer to a text array containing the command line arguments. 947 % 948 % o exception: return any errors or warnings in this structure. 949 % 950 */ 951 MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag, 952 Image **images,const int argc,const char **argv,ExceptionInfo *exception) 953 { 954 char 955 name[MagickPathExtent], 956 path[MagickPathExtent]; 957 958 ImageFilterHandler 959 *image_filter; 960 961 MagickBooleanType 962 status; 963 964 ModuleHandle 965 handle; 966 967 PolicyRights 968 rights; 969 970 /* 971 Find the module. 972 */ 973 assert(images != (Image **) NULL); 974 assert((*images)->signature == MagickCoreSignature); 975 if ((*images)->debug != MagickFalse) 976 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 977 (*images)->filename); 978 #if !defined(MAGICKCORE_BUILD_MODULES) 979 { 980 MagickBooleanType 981 status; 982 983 status=InvokeStaticImageFilter(tag,images,argc,argv,exception); 984 if (status != MagickFalse) 985 return(status); 986 } 987 #endif 988 rights=ReadPolicyRights; 989 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse) 990 { 991 errno=EPERM; 992 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, 993 "NotAuthorized","`%s'",tag); 994 return(MagickFalse); 995 } 996 TagToFilterModuleName(tag,name); 997 status=GetMagickModulePath(name,MagickImageFilterModule,path,exception); 998 if (status == MagickFalse) 999 { 1000 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1001 "UnableToLoadModule","'%s': %s",name,path); 1002 return(MagickFalse); 1003 } 1004 /* 1005 Open the module. 1006 */ 1007 handle=(ModuleHandle) lt_dlopen(path); 1008 if (handle == (ModuleHandle) NULL) 1009 { 1010 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1011 "UnableToLoadModule","'%s': %s",name,lt_dlerror()); 1012 return(MagickFalse); 1013 } 1014 /* 1015 Locate the module. 1016 */ 1017 #if !defined(MAGICKCORE_NAMESPACE_PREFIX) 1018 (void) FormatLocaleString(name,MagickPathExtent,"%sImage",tag); 1019 #else 1020 (void) FormatLocaleString(name,MagickPathExtent,"%s%sImage", 1021 MAGICKCORE_NAMESPACE_PREFIX,tag); 1022 #endif 1023 /* 1024 Execute the module. 1025 */ 1026 ClearMagickException(exception); 1027 image_filter=(ImageFilterHandler *) lt_dlsym(handle,name); 1028 if (image_filter == (ImageFilterHandler *) NULL) 1029 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1030 "UnableToLoadModule","'%s': %s",name,lt_dlerror()); 1031 else 1032 { 1033 size_t 1034 signature; 1035 1036 if ((*images)->debug != MagickFalse) 1037 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 1038 "Invoking \"%s\" dynamic image filter",tag); 1039 signature=image_filter(images,argc,argv,exception); 1040 if ((*images)->debug != MagickFalse) 1041 (void) LogMagickEvent(ModuleEvent,GetMagickModule(),"\"%s\" completes", 1042 tag); 1043 if (signature != MagickImageFilterSignature) 1044 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1045 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag, 1046 (unsigned long) signature,(unsigned long) MagickImageFilterSignature); 1047 } 1048 /* 1049 Close the module. 1050 */ 1051 if (lt_dlclose(handle) != 0) 1052 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning, 1053 "UnableToCloseModule","'%s': %s",name,lt_dlerror()); 1054 return(exception->severity < ErrorException ? MagickTrue : MagickFalse); 1055 } 1056 1057 /* 1059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1060 % % 1061 % % 1062 % % 1063 % L i s t M o d u l e I n f o % 1064 % % 1065 % % 1066 % % 1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1068 % 1069 % ListModuleInfo() lists the module info to a file. 1070 % 1071 % The format of the ListModuleInfo module is: 1072 % 1073 % MagickBooleanType ListModuleInfo(FILE *file,ExceptionInfo *exception) 1074 % 1075 % A description of each parameter follows. 1076 % 1077 % o file: An pointer to a FILE. 1078 % 1079 % o exception: return any errors or warnings in this structure. 1080 % 1081 */ 1082 MagickExport MagickBooleanType ListModuleInfo(FILE *file, 1083 ExceptionInfo *exception) 1084 { 1085 char 1086 filename[MagickPathExtent], 1087 module_path[MagickPathExtent], 1088 **modules, 1089 path[MagickPathExtent]; 1090 1091 register ssize_t 1092 i; 1093 1094 size_t 1095 number_modules; 1096 1097 if (file == (const FILE *) NULL) 1098 file=stdout; 1099 /* 1100 List image coders. 1101 */ 1102 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception); 1103 if (modules == (char **) NULL) 1104 return(MagickFalse); 1105 TagToCoderModuleName("magick",filename); 1106 (void) GetMagickModulePath(filename,MagickImageCoderModule,module_path, 1107 exception); 1108 GetPathComponent(module_path,HeadPath,path); 1109 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path); 1110 (void) FormatLocaleFile(file,"Image Coder\n"); 1111 (void) FormatLocaleFile(file, 1112 "-------------------------------------------------" 1113 "------------------------------\n"); 1114 for (i=0; i < (ssize_t) number_modules; i++) 1115 { 1116 (void) FormatLocaleFile(file,"%s",modules[i]); 1117 (void) FormatLocaleFile(file,"\n"); 1118 } 1119 (void) fflush(file); 1120 /* 1121 Relinquish resources. 1122 */ 1123 for (i=0; i < (ssize_t) number_modules; i++) 1124 modules[i]=DestroyString(modules[i]); 1125 modules=(char **) RelinquishMagickMemory(modules); 1126 /* 1127 List image filters. 1128 */ 1129 modules=GetModuleList("*",MagickImageFilterModule,&number_modules,exception); 1130 if (modules == (char **) NULL) 1131 return(MagickFalse); 1132 TagToFilterModuleName("analyze",filename); 1133 (void) GetMagickModulePath(filename,MagickImageFilterModule,module_path, 1134 exception); 1135 GetPathComponent(module_path,HeadPath,path); 1136 (void) FormatLocaleFile(file,"\nPath: %s\n\n",path); 1137 (void) FormatLocaleFile(file,"Image Filter\n"); 1138 (void) FormatLocaleFile(file, 1139 "-------------------------------------------------" 1140 "------------------------------\n"); 1141 for (i=0; i < (ssize_t) number_modules; i++) 1142 { 1143 (void) FormatLocaleFile(file,"%s",modules[i]); 1144 (void) FormatLocaleFile(file,"\n"); 1145 } 1146 (void) fflush(file); 1147 /* 1148 Relinquish resources. 1149 */ 1150 for (i=0; i < (ssize_t) number_modules; i++) 1151 modules[i]=DestroyString(modules[i]); 1152 modules=(char **) RelinquishMagickMemory(modules); 1153 return(MagickTrue); 1154 } 1155 1156 /* 1158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1159 % % 1160 % % 1161 % % 1162 + M o d u l e C o m p o n e n t G e n e s i s % 1163 % % 1164 % % 1165 % % 1166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1167 % 1168 % ModuleComponentGenesis() instantiates the module component. 1169 % 1170 % The format of the ModuleComponentGenesis method is: 1171 % 1172 % MagickBooleanType ModuleComponentGenesis(void) 1173 % 1174 */ 1175 MagickPrivate MagickBooleanType ModuleComponentGenesis(void) 1176 { 1177 MagickBooleanType 1178 status; 1179 1180 if (module_semaphore == (SemaphoreInfo *) NULL) 1181 module_semaphore=AcquireSemaphoreInfo(); 1182 status=IsModuleTreeInstantiated(); 1183 return(status); 1184 } 1185 1186 /* 1188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1189 % % 1190 % % 1191 % % 1192 + M o d u l e C o m p o n e n t T e r m i n u s % 1193 % % 1194 % % 1195 % % 1196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1197 % 1198 % ModuleComponentTerminus() destroys the module component. 1199 % 1200 % The format of the ModuleComponentTerminus method is: 1201 % 1202 % ModuleComponentTerminus(void) 1203 % 1204 */ 1205 MagickPrivate void ModuleComponentTerminus(void) 1206 { 1207 if (module_semaphore == (SemaphoreInfo *) NULL) 1208 ActivateSemaphoreInfo(&module_semaphore); 1209 DestroyModuleList(); 1210 RelinquishSemaphoreInfo(&module_semaphore); 1211 } 1212 1213 /* 1215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1216 % % 1217 % % 1218 % % 1219 % O p e n M o d u l e % 1220 % % 1221 % % 1222 % % 1223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1224 % 1225 % OpenModule() loads a module, and invokes its registration module. It 1226 % returns MagickTrue on success, and MagickFalse if there is an error. 1227 % 1228 % The format of the OpenModule module is: 1229 % 1230 % MagickBooleanType OpenModule(const char *module,ExceptionInfo *exception) 1231 % 1232 % A description of each parameter follows: 1233 % 1234 % o module: a character string that indicates the module to load. 1235 % 1236 % o exception: return any errors or warnings in this structure. 1237 % 1238 */ 1239 MagickPrivate MagickBooleanType OpenModule(const char *module, 1240 ExceptionInfo *exception) 1241 { 1242 char 1243 filename[MagickPathExtent], 1244 module_name[MagickPathExtent], 1245 name[MagickPathExtent], 1246 path[MagickPathExtent]; 1247 1248 MagickBooleanType 1249 status; 1250 1251 ModuleHandle 1252 handle; 1253 1254 ModuleInfo 1255 *module_info; 1256 1257 register const CoderInfo 1258 *p; 1259 1260 size_t 1261 signature; 1262 1263 /* 1264 Assign module name from alias. 1265 */ 1266 assert(module != (const char *) NULL); 1267 module_info=(ModuleInfo *) GetModuleInfo(module,exception); 1268 if (module_info != (ModuleInfo *) NULL) 1269 return(MagickTrue); 1270 (void) CopyMagickString(module_name,module,MagickPathExtent); 1271 p=GetCoderInfo(module,exception); 1272 if (p != (CoderInfo *) NULL) 1273 (void) CopyMagickString(module_name,p->name,MagickPathExtent); 1274 if (GetValueFromSplayTree(module_list,module_name) != (void *) NULL) 1275 return(MagickTrue); /* module already opened, return */ 1276 /* 1277 Locate module. 1278 */ 1279 handle=(ModuleHandle) NULL; 1280 TagToCoderModuleName(module_name,filename); 1281 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 1282 "Searching for module \"%s\" using filename \"%s\"",module_name,filename); 1283 *path='\0'; 1284 status=GetMagickModulePath(filename,MagickImageCoderModule,path,exception); 1285 if (status == MagickFalse) 1286 return(MagickFalse); 1287 /* 1288 Load module 1289 */ 1290 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 1291 "Opening module at path \"%s\"",path); 1292 handle=(ModuleHandle) lt_dlopen(path); 1293 if (handle == (ModuleHandle) NULL) 1294 { 1295 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1296 "UnableToLoadModule","'%s': %s",path,lt_dlerror()); 1297 return(MagickFalse); 1298 } 1299 /* 1300 Register module. 1301 */ 1302 module_info=AcquireModuleInfo(path,module_name); 1303 module_info->handle=handle; 1304 if (RegisterModule(module_info,exception) == (ModuleInfo *) NULL) 1305 return(MagickFalse); 1306 /* 1307 Define RegisterFORMATImage method. 1308 */ 1309 TagToModuleName(module_name,"Register%sImage",name); 1310 module_info->register_module=(size_t (*)(void)) lt_dlsym(handle,name); 1311 if (module_info->register_module == (size_t (*)(void)) NULL) 1312 { 1313 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1314 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror()); 1315 return(MagickFalse); 1316 } 1317 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 1318 "Method \"%s\" in module \"%s\" at address %p",name,module_name, 1319 (void *) module_info->register_module); 1320 /* 1321 Define UnregisterFORMATImage method. 1322 */ 1323 TagToModuleName(module_name,"Unregister%sImage",name); 1324 module_info->unregister_module=(void (*)(void)) lt_dlsym(handle,name); 1325 if (module_info->unregister_module == (void (*)(void)) NULL) 1326 { 1327 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1328 "UnableToRegisterImageFormat","'%s': %s",module_name,lt_dlerror()); 1329 return(MagickFalse); 1330 } 1331 (void) LogMagickEvent(ModuleEvent,GetMagickModule(), 1332 "Method \"%s\" in module \"%s\" at address %p",name,module_name, 1333 (void *) module_info->unregister_module); 1334 signature=module_info->register_module(); 1335 if (signature != MagickImageCoderSignature) 1336 { 1337 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1338 "ImageCoderSignatureMismatch","'%s': %8lx != %8lx",module_name, 1339 (unsigned long) signature,(unsigned long) MagickImageCoderSignature); 1340 return(MagickFalse); 1341 } 1342 return(MagickTrue); 1343 } 1344 1345 /* 1347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1348 % % 1349 % % 1350 % % 1351 % O p e n M o d u l e s % 1352 % % 1353 % % 1354 % % 1355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1356 % 1357 % OpenModules() loads all available modules. 1358 % 1359 % The format of the OpenModules module is: 1360 % 1361 % MagickBooleanType OpenModules(ExceptionInfo *exception) 1362 % 1363 % A description of each parameter follows: 1364 % 1365 % o exception: return any errors or warnings in this structure. 1366 % 1367 */ 1368 MagickPrivate MagickBooleanType OpenModules(ExceptionInfo *exception) 1369 { 1370 char 1371 **modules; 1372 1373 register ssize_t 1374 i; 1375 1376 size_t 1377 number_modules; 1378 1379 /* 1380 Load all modules. 1381 */ 1382 (void) GetMagickInfo((char *) NULL,exception); 1383 number_modules=0; 1384 modules=GetModuleList("*",MagickImageCoderModule,&number_modules,exception); 1385 if ((modules == (char **) NULL) || (*modules == (char *) NULL)) 1386 { 1387 if (modules != (char **) NULL) 1388 modules=(char **) RelinquishMagickMemory(modules); 1389 return(MagickFalse); 1390 } 1391 for (i=0; i < (ssize_t) number_modules; i++) 1392 (void) OpenModule(modules[i],exception); 1393 /* 1394 Relinquish resources. 1395 */ 1396 for (i=0; i < (ssize_t) number_modules; i++) 1397 modules[i]=DestroyString(modules[i]); 1398 modules=(char **) RelinquishMagickMemory(modules); 1399 return(MagickTrue); 1400 } 1401 1402 /* 1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1405 % % 1406 % % 1407 % % 1408 % R e g i s t e r M o d u l e % 1409 % % 1410 % % 1411 % % 1412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1413 % 1414 % RegisterModule() adds an entry to the module list. It returns a pointer to 1415 % the registered entry on success. 1416 % 1417 % The format of the RegisterModule module is: 1418 % 1419 % ModuleInfo *RegisterModule(const ModuleInfo *module_info, 1420 % ExceptionInfo *exception) 1421 % 1422 % A description of each parameter follows: 1423 % 1424 % o info: a pointer to the registered entry is returned. 1425 % 1426 % o module_info: a pointer to the ModuleInfo structure to register. 1427 % 1428 % o exception: return any errors or warnings in this structure. 1429 % 1430 */ 1431 static const ModuleInfo *RegisterModule(const ModuleInfo *module_info, 1432 ExceptionInfo *exception) 1433 { 1434 MagickBooleanType 1435 status; 1436 1437 assert(module_info != (ModuleInfo *) NULL); 1438 assert(module_info->signature == MagickCoreSignature); 1439 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag); 1440 if (module_list == (SplayTreeInfo *) NULL) 1441 return((const ModuleInfo *) NULL); 1442 status=AddValueToSplayTree(module_list,module_info->tag,module_info); 1443 if (status == MagickFalse) 1444 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, 1445 "MemoryAllocationFailed","`%s'",module_info->tag); 1446 return(module_info); 1447 } 1448 1449 /* 1451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1452 % % 1453 % % 1454 % % 1455 % T a g T o C o d e r M o d u l e N a m e % 1456 % % 1457 % % 1458 % % 1459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1460 % 1461 % TagToCoderModuleName() munges a module tag and obtains the filename of the 1462 % corresponding module. 1463 % 1464 % The format of the TagToCoderModuleName module is: 1465 % 1466 % char *TagToCoderModuleName(const char *tag,char *name) 1467 % 1468 % A description of each parameter follows: 1469 % 1470 % o tag: a character string representing the module tag. 1471 % 1472 % o name: return the module name here. 1473 % 1474 */ 1475 static void TagToCoderModuleName(const char *tag,char *name) 1476 { 1477 assert(tag != (char *) NULL); 1478 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag); 1479 assert(name != (char *) NULL); 1480 #if defined(MAGICKCORE_LTDL_DELEGATE) 1481 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag); 1482 (void) LocaleLower(name); 1483 #else 1484 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 1485 if (LocaleNCompare("IM_MOD_",tag,7) == 0) 1486 (void) CopyMagickString(name,tag,MagickPathExtent); 1487 else 1488 { 1489 #if defined(_DEBUG) 1490 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_DB_%s_.dll",tag); 1491 #else 1492 (void) FormatLocaleString(name,MagickPathExtent,"IM_MOD_RL_%s_.dll",tag); 1493 #endif 1494 } 1495 #endif 1496 #endif 1497 } 1498 1499 /* 1501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1502 % % 1503 % % 1504 % % 1505 % T a g T o F i l t e r M o d u l e N a m e % 1506 % % 1507 % % 1508 % % 1509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1510 % 1511 % TagToFilterModuleName() munges a module tag and returns the filename of the 1512 % corresponding filter module. 1513 % 1514 % The format of the TagToFilterModuleName module is: 1515 % 1516 % void TagToFilterModuleName(const char *tag,char name) 1517 % 1518 % A description of each parameter follows: 1519 % 1520 % o tag: a character string representing the module tag. 1521 % 1522 % o name: return the filter name here. 1523 % 1524 */ 1525 static void TagToFilterModuleName(const char *tag,char *name) 1526 { 1527 assert(tag != (char *) NULL); 1528 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag); 1529 assert(name != (char *) NULL); 1530 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 1531 (void) FormatLocaleString(name,MagickPathExtent,"FILTER_%s_.dll",tag); 1532 #elif !defined(MAGICKCORE_LTDL_DELEGATE) 1533 (void) FormatLocaleString(name,MagickPathExtent,"%s.dll",tag); 1534 #else 1535 (void) FormatLocaleString(name,MagickPathExtent,"%s.la",tag); 1536 #endif 1537 } 1538 1539 /* 1541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1542 % % 1543 % % 1544 % % 1545 % T a g T o M o d u l e N a m e % 1546 % % 1547 % % 1548 % % 1549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1550 % 1551 % TagToModuleName() munges the module tag name and returns an upper-case tag 1552 % name as the input string, and a user-provided format. 1553 % 1554 % The format of the TagToModuleName module is: 1555 % 1556 % TagToModuleName(const char *tag,const char *format,char *module) 1557 % 1558 % A description of each parameter follows: 1559 % 1560 % o tag: the module tag. 1561 % 1562 % o format: a sprintf-compatible format string containing %s where the 1563 % upper-case tag name is to be inserted. 1564 % 1565 % o module: pointer to a destination buffer for the formatted result. 1566 % 1567 */ 1568 static void TagToModuleName(const char *tag,const char *format,char *module) 1569 { 1570 char 1571 name[MagickPathExtent]; 1572 1573 assert(tag != (const char *) NULL); 1574 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tag); 1575 assert(format != (const char *) NULL); 1576 assert(module != (char *) NULL); 1577 (void) CopyMagickString(name,tag,MagickPathExtent); 1578 LocaleUpper(name); 1579 #if !defined(MAGICKCORE_NAMESPACE_PREFIX) 1580 (void) FormatLocaleString(module,MagickPathExtent,format,name); 1581 #else 1582 { 1583 char 1584 prefix_format[MagickPathExtent]; 1585 1586 (void) FormatLocaleString(prefix_format,MagickPathExtent,"%s%s", 1587 MAGICKCORE_NAMESPACE_PREFIX,format); 1588 (void) FormatLocaleString(module,MagickPathExtent,prefix_format,name); 1589 } 1590 #endif 1591 } 1592 1593 /* 1595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1596 % % 1597 % % 1598 % % 1599 % U n r e g i s t e r M o d u l e % 1600 % % 1601 % % 1602 % % 1603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1604 % 1605 % UnregisterModule() unloads a module, and invokes its de-registration module. 1606 % Returns MagickTrue on success, and MagickFalse if there is an error. 1607 % 1608 % The format of the UnregisterModule module is: 1609 % 1610 % MagickBooleanType UnregisterModule(const ModuleInfo *module_info, 1611 % ExceptionInfo *exception) 1612 % 1613 % A description of each parameter follows: 1614 % 1615 % o module_info: the module info. 1616 % 1617 % o exception: return any errors or warnings in this structure. 1618 % 1619 */ 1620 static MagickBooleanType UnregisterModule(const ModuleInfo *module_info, 1621 ExceptionInfo *exception) 1622 { 1623 /* 1624 Locate and execute UnregisterFORMATImage module. 1625 */ 1626 assert(module_info != (const ModuleInfo *) NULL); 1627 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",module_info->tag); 1628 assert(exception != (ExceptionInfo *) NULL); 1629 if (module_info->unregister_module == NULL) 1630 return(MagickTrue); 1631 module_info->unregister_module(); 1632 if (lt_dlclose((ModuleHandle) module_info->handle) != 0) 1633 { 1634 (void) ThrowMagickException(exception,GetMagickModule(),ModuleWarning, 1635 "UnableToCloseModule","'%s': %s",module_info->tag,lt_dlerror()); 1636 return(MagickFalse); 1637 } 1638 return(MagickTrue); 1639 } 1640 #else 1641 1642 #if !defined(MAGICKCORE_BUILD_MODULES) 1643 extern size_t 1644 analyzeImage(Image **,const int,const char **,ExceptionInfo *); 1645 #endif 1646 1647 MagickExport MagickBooleanType ListModuleInfo(FILE *magick_unused(file), 1648 ExceptionInfo *magick_unused(exception)) 1649 { 1650 return(MagickTrue); 1651 } 1652 1653 MagickExport MagickBooleanType InvokeDynamicImageFilter(const char *tag, 1654 Image **image,const int argc,const char **argv,ExceptionInfo *exception) 1655 { 1656 PolicyRights 1657 rights; 1658 1659 assert(image != (Image **) NULL); 1660 assert((*image)->signature == MagickCoreSignature); 1661 if ((*image)->debug != MagickFalse) 1662 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename); 1663 rights=ReadPolicyRights; 1664 if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse) 1665 { 1666 errno=EPERM; 1667 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, 1668 "NotAuthorized","`%s'",tag); 1669 return(MagickFalse); 1670 } 1671 #if defined(MAGICKCORE_BUILD_MODULES) 1672 (void) tag; 1673 (void) argc; 1674 (void) argv; 1675 (void) exception; 1676 #else 1677 { 1678 ImageFilterHandler 1679 *image_filter; 1680 1681 image_filter=(ImageFilterHandler *) NULL; 1682 if (LocaleCompare("analyze",tag) == 0) 1683 image_filter=(ImageFilterHandler *) analyzeImage; 1684 if (image_filter == (ImageFilterHandler *) NULL) 1685 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1686 "UnableToLoadModule","`%s'",tag); 1687 else 1688 { 1689 size_t 1690 signature; 1691 1692 if ((*image)->debug != MagickFalse) 1693 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1694 "Invoking \"%s\" static image filter",tag); 1695 signature=image_filter(image,argc,argv,exception); 1696 if ((*image)->debug != MagickFalse) 1697 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"\"%s\" completes", 1698 tag); 1699 if (signature != MagickImageFilterSignature) 1700 { 1701 (void) ThrowMagickException(exception,GetMagickModule(),ModuleError, 1702 "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag, 1703 (unsigned long) signature,(unsigned long) 1704 MagickImageFilterSignature); 1705 return(MagickFalse); 1706 } 1707 } 1708 } 1709 #endif 1710 return(MagickTrue); 1711 } 1712 #endif 1713