]> granicus.if.org Git - imagemagick/blob - MagickCore/configure.c
(no commit message)
[imagemagick] / MagickCore / configure.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %          CCCC   OOO   N   N  FFFFF  IIIII   GGGG  U   U  RRRR   EEEEE       %
7 %         C      O   O  NN  N  F        I    G      U   U  R   R  E           %
8 %         C      O   O  N N N  FFF      I    G GG   U   U  RRRR   EEE         %
9 %         C      O   O  N  NN  F        I    G   G  U   U  R R    E           %
10 %          CCCC   OOO   N   N  F      IIIII   GGG    UUU   R  R   EEEEE       %
11 %                                                                             %
12 %                                                                             %
13 %                      MagickCore Image Configure Methods                     %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                                 July 2003                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2012 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 \f
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/hashmap.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/semaphore.h"
53 #include "MagickCore/string_.h"
54 #include "MagickCore/string-private.h"
55 #include "MagickCore/token.h"
56 #include "MagickCore/utility.h"
57 #include "MagickCore/utility-private.h"
58 #include "MagickCore/xml-tree.h"
59 \f
60 /*
61   Define declarations.
62 */
63 #define ConfigureFilename  "configure.xml"
64 \f
65 /*
66   Typedef declarations.
67 */
68 typedef struct _ConfigureMapInfo
69 {
70   const char
71     *name,
72     *value;
73 } ConfigureMapInfo;
74 \f
75 /*
76   Static declarations.
77 */
78 static const ConfigureMapInfo
79   ConfigureMap[] =
80   {
81     { "NAME", "ImageMagick" }
82   };
83
84 static LinkedListInfo
85   *configure_list = (LinkedListInfo *) NULL;
86
87 static SemaphoreInfo
88   *configure_semaphore = (SemaphoreInfo *) NULL;
89
90 static volatile MagickBooleanType
91   instantiate_configure = MagickFalse;
92 \f
93 /*
94   Forward declarations.
95 */
96 static MagickBooleanType
97   InitializeConfigureList(ExceptionInfo *),
98   LoadConfigureLists(const char *,ExceptionInfo *);
99 \f
100 /*
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %                                                                             %
103 %                                                                             %
104 %                                                                             %
105 +   C o n f i g u r e C o m p o n e n t G e n e s i s                         %
106 %                                                                             %
107 %                                                                             %
108 %                                                                             %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 %
111 %  ConfigureComponentGenesis() instantiates the configure component.
112 %
113 %  The format of the ConfigureComponentGenesis method is:
114 %
115 %      MagickBooleanType ConfigureComponentGenesis(void)
116 %
117 */
118 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
119 {
120   AcquireSemaphoreInfo(&configure_semaphore);
121   return(MagickTrue);
122 }
123 \f
124 /*
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 %                                                                             %
127 %                                                                             %
128 %                                                                             %
129 +   C o n f i g u r e C o m p o n e n t T e r m i n u s                       %
130 %                                                                             %
131 %                                                                             %
132 %                                                                             %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 %
135 %  ConfigureComponentTerminus() destroys the configure component.
136 %
137 %  The format of the ConfigureComponentTerminus method is:
138 %
139 %      ConfigureComponentTerminus(void)
140 %
141 */
142
143 static void *DestroyConfigureElement(void *configure_info)
144 {
145   register ConfigureInfo
146     *p;
147
148   p=(ConfigureInfo *) configure_info;
149   if (p->exempt == MagickFalse)
150     {
151       if (p->value != (char *) NULL)
152         p->value=DestroyString(p->value);
153       if (p->name != (char *) NULL)
154         p->name=DestroyString(p->name);
155       if (p->path != (char *) NULL)
156         p->path=DestroyString(p->path);
157     }
158   p=(ConfigureInfo *) RelinquishMagickMemory(p);
159   return((void *) NULL);
160 }
161
162 MagickPrivate void ConfigureComponentTerminus(void)
163 {
164   if (configure_semaphore == (SemaphoreInfo *) NULL)
165     AcquireSemaphoreInfo(&configure_semaphore);
166   LockSemaphoreInfo(configure_semaphore);
167   if (configure_list != (LinkedListInfo *) NULL)
168     configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
169   configure_list=(LinkedListInfo *) NULL;
170   instantiate_configure=MagickFalse;
171   UnlockSemaphoreInfo(configure_semaphore);
172   DestroySemaphoreInfo(&configure_semaphore);
173 }
174 \f
175 /*
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 %                                                                             %
178 %                                                                             %
179 %                                                                             %
180 %   D e s t r o y C o n f i g u r e O p t i o n s                             %
181 %                                                                             %
182 %                                                                             %
183 %                                                                             %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 %
186 %  DestroyConfigureOptions() releases memory associated with an configure
187 %  options.
188 %
189 %  The format of the DestroyProfiles method is:
190 %
191 %      LinkedListInfo *DestroyConfigureOptions(Image *image)
192 %
193 %  A description of each parameter follows:
194 %
195 %    o image: the image.
196 %
197 */
198
199 static void *DestroyOptions(void *option)
200 {
201   return(DestroyStringInfo((StringInfo *) option));
202 }
203
204 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
205 {
206   assert(options != (LinkedListInfo *) NULL);
207   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
208   return(DestroyLinkedList(options,DestroyOptions));
209 }
210 \f
211 /*
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 %                                                                             %
214 %                                                                             %
215 %                                                                             %
216 +   G e t C o n f i g u r e I n f o                                           %
217 %                                                                             %
218 %                                                                             %
219 %                                                                             %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %
222 %  GetConfigureInfo() searches the configure list for the specified name and if
223 %  found returns attributes for that element.
224 %
225 %  The format of the GetConfigureInfo method is:
226 %
227 %      const ConfigureInfo *GetConfigureInfo(const char *name,
228 %        ExceptionInfo *exception)
229 %
230 %  A description of each parameter follows:
231 %
232 %    o configure_info: GetConfigureInfo() searches the configure list for the
233 %      specified name and if found returns attributes for that element.
234 %
235 %    o name: the configure name.
236 %
237 %    o exception: return any errors or warnings in this structure.
238 %
239 */
240 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
241   ExceptionInfo *exception)
242 {
243   register const ConfigureInfo
244     *p;
245
246   assert(exception != (ExceptionInfo *) NULL);
247   if ((configure_list == (LinkedListInfo *) NULL) ||
248       (instantiate_configure == MagickFalse))
249     if (InitializeConfigureList(exception) == MagickFalse)
250       return((const ConfigureInfo *) NULL);
251   if ((configure_list == (LinkedListInfo *) NULL) ||
252       (IsLinkedListEmpty(configure_list) != MagickFalse))
253     return((const ConfigureInfo *) NULL);
254   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
255     return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
256   /*
257     Search for configure tag.
258   */
259   LockSemaphoreInfo(configure_semaphore);
260   ResetLinkedListIterator(configure_list);
261   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
262   while (p != (const ConfigureInfo *) NULL)
263   {
264     if (LocaleCompare(name,p->name) == 0)
265       break;
266     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
267   }
268   if (p != (ConfigureInfo *) NULL)
269     (void) InsertValueInLinkedList(configure_list,0,
270       RemoveElementByValueFromLinkedList(configure_list,p));
271   UnlockSemaphoreInfo(configure_semaphore);
272   return(p);
273 }
274 \f
275 /*
276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 %                                                                             %
278 %                                                                             %
279 %                                                                             %
280 %   G e t C o n f i g u r e I n f o L i s t                                   %
281 %                                                                             %
282 %                                                                             %
283 %                                                                             %
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 %
286 %  GetConfigureInfoList() returns any configure options that match the
287 %  specified pattern.
288 %
289 %  The format of the GetConfigureInfoList function is:
290 %
291 %      const ConfigureInfo **GetConfigureInfoList(const char *pattern,
292 %        size_t *number_options,ExceptionInfo *exception)
293 %
294 %  A description of each parameter follows:
295 %
296 %    o pattern: Specifies a pointer to a text string containing a pattern.
297 %
298 %    o number_options:  This integer returns the number of configure options in
299 %    the list.
300 %
301 %    o exception: return any errors or warnings in this structure.
302 %
303 */
304
305 #if defined(__cplusplus) || defined(c_plusplus)
306 extern "C" {
307 #endif
308
309 static int ConfigureInfoCompare(const void *x,const void *y)
310 {
311   const ConfigureInfo
312     **p,
313     **q;
314
315   p=(const ConfigureInfo **) x,
316   q=(const ConfigureInfo **) y;
317   if (LocaleCompare((*p)->path,(*q)->path) == 0)
318     return(LocaleCompare((*p)->name,(*q)->name));
319   return(LocaleCompare((*p)->path,(*q)->path));
320 }
321
322 #if defined(__cplusplus) || defined(c_plusplus)
323 }
324 #endif
325
326 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
327   size_t *number_options,ExceptionInfo *exception)
328 {
329   const ConfigureInfo
330     **options;
331
332   register const ConfigureInfo
333     *p;
334
335   register ssize_t
336     i;
337
338   /*
339     Allocate configure list.
340   */
341   assert(pattern != (char *) NULL);
342   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
343   assert(number_options != (size_t *) NULL);
344   *number_options=0;
345   p=GetConfigureInfo("*",exception);
346   if (p == (const ConfigureInfo *) NULL)
347     return((const ConfigureInfo **) NULL);
348   options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
349     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
350   if (options == (const ConfigureInfo **) NULL)
351     return((const ConfigureInfo **) NULL);
352   /*
353     Generate configure list.
354   */
355   LockSemaphoreInfo(configure_semaphore);
356   ResetLinkedListIterator(configure_list);
357   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
358   for (i=0; p != (const ConfigureInfo *) NULL; )
359   {
360     if ((p->stealth == MagickFalse) &&
361         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
362       options[i++]=p;
363     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
364   }
365   UnlockSemaphoreInfo(configure_semaphore);
366   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
367   options[i]=(ConfigureInfo *) NULL;
368   *number_options=(size_t) i;
369   return(options);
370 }
371 \f
372 /*
373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 %                                                                             %
375 %                                                                             %
376 %                                                                             %
377 %   G e t C o n f i g u r e L i s t                                           %
378 %                                                                             %
379 %                                                                             %
380 %                                                                             %
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 %
383 %  GetConfigureList() returns any configure options that match the specified
384 %  pattern.
385 %
386 %  The format of the GetConfigureList function is:
387 %
388 %      char **GetConfigureList(const char *pattern,
389 %        size_t *number_options,ExceptionInfo *exception)
390 %
391 %  A description of each parameter follows:
392 %
393 %    o pattern: Specifies a pointer to a text string containing a pattern.
394 %
395 %    o number_options:  This integer returns the number of options in the list.
396 %
397 %    o exception: return any errors or warnings in this structure.
398 %
399 */
400
401 #if defined(__cplusplus) || defined(c_plusplus)
402 extern "C" {
403 #endif
404
405 static int ConfigureCompare(const void *x,const void *y)
406 {
407   register char
408     **p,
409     **q;
410
411   p=(char **) x;
412   q=(char **) y;
413   return(LocaleCompare(*p,*q));
414 }
415
416 #if defined(__cplusplus) || defined(c_plusplus)
417 }
418 #endif
419
420 MagickExport char **GetConfigureList(const char *pattern,
421   size_t *number_options,ExceptionInfo *exception)
422 {
423   char
424     **options;
425
426   register const ConfigureInfo
427     *p;
428
429   register ssize_t
430     i;
431
432   /*
433     Allocate configure list.
434   */
435   assert(pattern != (char *) NULL);
436   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
437   assert(number_options != (size_t *) NULL);
438   *number_options=0;
439   p=GetConfigureInfo("*",exception);
440   if (p == (const ConfigureInfo *) NULL)
441     return((char **) NULL);
442   options=(char **) AcquireQuantumMemory((size_t)
443     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
444   if (options == (char **) NULL)
445     return((char **) NULL);
446   LockSemaphoreInfo(configure_semaphore);
447   ResetLinkedListIterator(configure_list);
448   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
449   for (i=0; p != (const ConfigureInfo *) NULL; )
450   {
451     if ((p->stealth == MagickFalse) &&
452         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
453       options[i++]=ConstantString(p->name);
454     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
455   }
456   UnlockSemaphoreInfo(configure_semaphore);
457   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
458   options[i]=(char *) NULL;
459   *number_options=(size_t) i;
460   return(options);
461 }
462 \f
463 /*
464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 %                                                                             %
466 %                                                                             %
467 %                                                                             %
468 %   G e t C o n f i g u r e O p t i o n                                       %
469 %                                                                             %
470 %                                                                             %
471 %                                                                             %
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 %
474 %  GetConfigureOption() returns the value associated with the configure option.
475 %
476 %  The format of the GetConfigureOption method is:
477 %
478 %      char *GetConfigureOption(const char *option)
479 %
480 %  A description of each parameter follows:
481 %
482 %    o configure_info:  The configure info.
483 %
484 */
485 MagickExport char *GetConfigureOption(const char *option)
486 {
487   const char
488     *value;
489
490   const ConfigureInfo
491     *configure_info;
492
493   ExceptionInfo
494     *exception;
495
496   assert(option != (const char *) NULL);
497   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
498   exception=AcquireExceptionInfo();
499   configure_info=GetConfigureInfo(option,exception);
500   exception=DestroyExceptionInfo(exception);
501   if (configure_info == (ConfigureInfo *) NULL)
502     return((char *) NULL);
503   value=GetConfigureValue(configure_info);
504   if ((value == (const char *) NULL) || (*value == '\0'))
505     return((char *) NULL);
506   return(ConstantString(value));
507 }
508 \f
509 /*
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 %                                                                             %
512 %                                                                             %
513 %                                                                             %
514 %  G e t C o n f i g u r e O p t i o n s                                      %
515 %                                                                             %
516 %                                                                             %
517 %                                                                             %
518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519 %
520 %  GetConfigureOptions() returns any Magick configuration options associated
521 %  with the specified filename.
522 %
523 %  The format of the GetConfigureOptions method is:
524 %
525 %      LinkedListInfo *GetConfigureOptions(const char *filename,
526 %        ExceptionInfo *exception)
527 %
528 %  A description of each parameter follows:
529 %
530 %    o filename: the configure file name.
531 %
532 %    o exception: return any errors or warnings in this structure.
533 %
534 */
535 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
536   ExceptionInfo *exception)
537 {
538   char
539     path[MaxTextExtent];
540
541   const char
542     *element;
543
544   LinkedListInfo
545     *options,
546     *paths;
547
548   StringInfo
549     *xml;
550
551   assert(filename != (const char *) NULL);
552   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
553   assert(exception != (ExceptionInfo *) NULL);
554   (void) CopyMagickString(path,filename,MaxTextExtent);
555   /*
556     Load XML from configuration files to linked-list.
557   */
558   options=NewLinkedList(0);
559   paths=GetConfigurePaths(filename,exception);
560   if (paths != (LinkedListInfo *) NULL)
561     {
562       ResetLinkedListIterator(paths);
563       element=(const char *) GetNextValueInLinkedList(paths);
564       while (element != (const char *) NULL)
565       {
566         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
567         (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
568           "Searching for configure file: \"%s\"",path);
569         xml=ConfigureFileToStringInfo(path);
570         if (xml != (StringInfo *) NULL)
571           (void) AppendValueToLinkedList(options,xml);
572         element=(const char *) GetNextValueInLinkedList(paths);
573       }
574       paths=DestroyLinkedList(paths,RelinquishMagickMemory);
575     }
576 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
577   if (GetNumberOfElementsInLinkedList(options) == 0)
578     {
579       char
580         *blob;
581
582       blob=(char *) NTResourceToBlob(filename);
583       if (blob != (char *) NULL)
584         {
585           xml=AcquireStringInfo(0);
586           SetStringInfoLength(xml,strlen(blob)+1);
587           SetStringInfoDatum(xml,(unsigned char *) blob);
588           SetStringInfoPath(xml,filename);
589           (void) AppendValueToLinkedList(options,xml);
590         }
591     }
592 #endif
593   if (GetNumberOfElementsInLinkedList(options) == 0)
594     (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
595       "UnableToOpenConfigureFile","'%s'",filename);
596   ResetLinkedListIterator(options);
597   return(options);
598 }
599 \f
600 /*
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 %                                                                             %
603 %                                                                             %
604 %                                                                             %
605 %  G e t C o n f i g u r e P a t h s                                          %
606 %                                                                             %
607 %                                                                             %
608 %                                                                             %
609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 %
611 %  GetConfigurePaths() returns any Magick configuration paths associated
612 %  with the specified filename.
613 %
614 %  The format of the GetConfigurePaths method is:
615 %
616 %      LinkedListInfo *GetConfigurePaths(const char *filename,
617 %        ExceptionInfo *exception)
618 %
619 %  A description of each parameter follows:
620 %
621 %    o filename: the configure file name.
622 %
623 %    o exception: return any errors or warnings in this structure.
624 %
625 */
626 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
627   ExceptionInfo *exception)
628 {
629 #define RegistryKey  "ConfigurePath"
630 #define MagickCoreDLL  "CORE_RL_MagickCore_.dll"
631 #define MagickCoreDebugDLL  "CORE_DB_MagickCore_.dll"
632
633   char
634     path[MaxTextExtent];
635
636   LinkedListInfo
637     *paths;
638
639   assert(filename != (const char *) NULL);
640   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
641   assert(exception != (ExceptionInfo *) NULL);
642   (void) CopyMagickString(path,filename,MaxTextExtent);
643   paths=NewLinkedList(0);
644   {
645     char
646       *configure_path;
647
648     /*
649       Search $MAGICK_CONFIGURE_PATH.
650     */
651     configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
652     if (configure_path != (char *) NULL)
653       {
654         register char
655           *p,
656           *q;
657
658         for (p=configure_path-1; p != (char *) NULL; )
659         {
660           (void) CopyMagickString(path,p+1,MaxTextExtent);
661           q=strchr(path,DirectoryListSeparator);
662           if (q != (char *) NULL)
663             *q='\0';
664           q=path+strlen(path)-1;
665           if ((q >= path) && (*q != *DirectorySeparator))
666             (void) ConcatenateMagickString(path,DirectorySeparator,
667               MaxTextExtent);
668           (void) AppendValueToLinkedList(paths,ConstantString(path));
669           p=strchr(p+1,DirectoryListSeparator);
670         }
671         configure_path=DestroyString(configure_path);
672       }
673   }
674 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
675 #if defined(MAGICKCORE_SHARE_PATH)
676   (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
677 #endif
678 #if defined(MAGICKCORE_SHAREARCH_PATH)
679   (void) AppendValueToLinkedList(paths,ConstantString(
680     MAGICKCORE_SHAREARCH_PATH));
681 #endif
682 #if defined(MAGICKCORE_CONFIGURE_PATH)
683   (void) AppendValueToLinkedList(paths,ConstantString(
684     MAGICKCORE_CONFIGURE_PATH));
685 #endif
686 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
687   (void) AppendValueToLinkedList(paths,ConstantString(
688     MAGICKCORE_DOCUMENTATION_PATH));
689 #endif
690 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
691   {
692     unsigned char
693       *key_value;
694
695     /*
696       Locate file via registry key.
697     */
698     key_value=NTRegistryKeyLookup(RegistryKey);
699     if (key_value != (unsigned char *) NULL)
700       {
701         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
702           DirectorySeparator);
703         (void) AppendValueToLinkedList(paths,ConstantString(path));
704         key_value=(unsigned char *) RelinquishMagickMemory(key_value);
705       }
706   }
707 #endif
708 #else
709   {
710     char
711       *home;
712
713     /*
714       Search under MAGICK_HOME.
715     */
716     home=GetEnvironmentValue("MAGICK_HOME");
717     if (home != (char *) NULL)
718       {
719 #if !defined(MAGICKCORE_POSIX_SUPPORT)
720         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
721           DirectorySeparator);
722         (void) AppendValueToLinkedList(paths,ConstantString(path));
723 #else
724         (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
725           MAGICKCORE_CONFIGURE_RELATIVE_PATH);
726         (void) AppendValueToLinkedList(paths,ConstantString(path));
727         (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
728           MAGICKCORE_SHARE_RELATIVE_PATH);
729         (void) AppendValueToLinkedList(paths,ConstantString(path));
730 #endif
731         home=DestroyString(home);
732       }
733     }
734   if (*GetClientPath() != '\0')
735     {
736 #if !defined(MAGICKCORE_POSIX_SUPPORT)
737       (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
738         DirectorySeparator);
739       (void) AppendValueToLinkedList(paths,ConstantString(path));
740 #else
741       char
742         prefix[MaxTextExtent];
743
744       /*
745         Search based on executable directory if directory is known.
746       */
747       (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
748       ChopPathComponents(prefix,1);
749       (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
750         MAGICKCORE_CONFIGURE_RELATIVE_PATH);
751       (void) AppendValueToLinkedList(paths,ConstantString(path));
752       (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
753         MAGICKCORE_SHARE_RELATIVE_PATH);
754       (void) AppendValueToLinkedList(paths,ConstantString(path));
755 #endif
756     }
757   /*
758     Search current directory.
759   */
760   (void) AppendValueToLinkedList(paths,ConstantString(""));
761 #endif
762   {
763     char
764       *home;
765
766     home=GetEnvironmentValue("HOME");
767     if (home == (char *) NULL)
768       home=GetEnvironmentValue("USERPROFILE");
769     if (home != (char *) NULL)
770       {
771         /*
772           Search $HOME/.magick.
773         */
774         (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
775           DirectorySeparator,DirectorySeparator);
776         (void) AppendValueToLinkedList(paths,ConstantString(path));
777         home=DestroyString(home);
778       }
779   }
780 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
781   {
782     char
783       module_path[MaxTextExtent];
784
785     if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
786         (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
787       {
788         unsigned char
789           *key_value;
790
791         /*
792           Search module path.
793         */
794         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
795           DirectorySeparator);
796         key_value=NTRegistryKeyLookup(RegistryKey);
797         if (key_value == (unsigned char *) NULL)
798           (void) AppendValueToLinkedList(paths,ConstantString(path));
799         else
800           key_value=(unsigned char *) RelinquishMagickMemory(key_value);
801       }
802     if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
803       {
804         /*
805           Search PerlMagick module path.
806         */
807         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
808           DirectorySeparator);
809         (void) AppendValueToLinkedList(paths,ConstantString(path));
810         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
811           "\\inc\\lib\\auto\\Image\\Magick\\");
812         (void) AppendValueToLinkedList(paths,ConstantString(path));
813       }
814   }
815 #endif
816   return(paths);
817 }
818 \f
819 /*
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821 %                                                                             %
822 %                                                                             %
823 %                                                                             %
824 %   G e t C o n f i g u r e V a l u e                                         %
825 %                                                                             %
826 %                                                                             %
827 %                                                                             %
828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829 %
830 %  GetConfigureValue() returns the value associated with the configure info.
831 %
832 %  The format of the GetConfigureValue method is:
833 %
834 %      const char *GetConfigureValue(const ConfigureInfo *configure_info)
835 %
836 %  A description of each parameter follows:
837 %
838 %    o configure_info:  The configure info.
839 %
840 */
841 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
842 {
843   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
844   assert(configure_info != (ConfigureInfo *) NULL);
845   assert(configure_info->signature == MagickSignature);
846   return(configure_info->value);
847 }
848 \f
849 /*
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 %                                                                             %
852 %                                                                             %
853 %                                                                             %
854 +   I n i t i a l i z e C o n f i g u r e L i s t                             %
855 %                                                                             %
856 %                                                                             %
857 %                                                                             %
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 %
860 %  InitializeConfigureList() initializes the configure list.
861 %
862 %  The format of the InitializeConfigureList method is:
863 %
864 %      MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
865 %
866 %  A description of each parameter follows.
867 %
868 %    o exception: return any errors or warnings in this structure.
869 %
870 */
871 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
872 {
873   if ((configure_list == (LinkedListInfo *) NULL) &&
874       (instantiate_configure == MagickFalse))
875     {
876       if (configure_semaphore == (SemaphoreInfo *) NULL)
877         AcquireSemaphoreInfo(&configure_semaphore);
878       LockSemaphoreInfo(configure_semaphore);
879       if ((configure_list == (LinkedListInfo *) NULL) &&
880           (instantiate_configure == MagickFalse))
881         {
882           (void) LoadConfigureLists(ConfigureFilename,exception);
883           instantiate_configure=MagickTrue;
884         }
885       UnlockSemaphoreInfo(configure_semaphore);
886     }
887   return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
888 }
889 \f
890 /*
891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 %                                                                             %
893 %                                                                             %
894 %                                                                             %
895 %  L i s t C o n f i g u r e I n f o                                          %
896 %                                                                             %
897 %                                                                             %
898 %                                                                             %
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900 %
901 %  ListConfigureInfo() lists the configure info to a file.
902 %
903 %  The format of the ListConfigureInfo method is:
904 %
905 %      MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
906 %
907 %  A description of each parameter follows.
908 %
909 %    o file:  An pointer to a FILE.
910 %
911 %    o exception: return any errors or warnings in this structure.
912 %
913 */
914 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
915   ExceptionInfo *exception)
916 {
917   const char
918     *name,
919     *path,
920     *value;
921
922   const ConfigureInfo
923     **configure_info;
924
925   register ssize_t
926     i;
927
928   size_t
929     number_options;
930
931   ssize_t
932     j;
933
934   if (file == (const FILE *) NULL)
935     file=stdout;
936   configure_info=GetConfigureInfoList("*",&number_options,exception);
937   if (configure_info == (const ConfigureInfo **) NULL)
938     return(MagickFalse);
939   path=(const char *) NULL;
940   for (i=0; i < (ssize_t) number_options; i++)
941   {
942     if (configure_info[i]->stealth != MagickFalse)
943       continue;
944     if ((path == (const char *) NULL) ||
945         (LocaleCompare(path,configure_info[i]->path) != 0))
946       {
947         if (configure_info[i]->path != (char *) NULL)
948           (void) FormatLocaleFile(file,"\nPath: %s\n\n",
949             configure_info[i]->path);
950         (void) FormatLocaleFile(file,"Name          Value\n");
951         (void) FormatLocaleFile(file,
952           "-------------------------------------------------"
953           "------------------------------\n");
954       }
955     path=configure_info[i]->path;
956     name="unknown";
957     if (configure_info[i]->name != (char *) NULL)
958       name=configure_info[i]->name;
959     (void) FormatLocaleFile(file,"%s",name);
960     for (j=(ssize_t) strlen(name); j <= 12; j++)
961       (void) FormatLocaleFile(file," ");
962     (void) FormatLocaleFile(file," ");
963     value="unknown";
964     if (configure_info[i]->value != (char *) NULL)
965       value=configure_info[i]->value;
966     (void) FormatLocaleFile(file,"%s",value);
967     (void) FormatLocaleFile(file,"\n");
968   }
969   (void) fflush(file);
970   configure_info=(const ConfigureInfo **)
971     RelinquishMagickMemory((void *) configure_info);
972   return(MagickTrue);
973 }
974 \f
975 /*
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 %                                                                             %
978 %                                                                             %
979 %                                                                             %
980 +   L o a d C o n f i g u r e L i s t                                         %
981 %                                                                             %
982 %                                                                             %
983 %                                                                             %
984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985 %
986 %  LoadConfigureList() loads the configure configuration file which provides a
987 %  mapping between configure attributes and a configure name.
988 %
989 %  The format of the LoadConfigureList method is:
990 %
991 %      MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
992 %        const size_t depth,ExceptionInfo *exception)
993 %
994 %  A description of each parameter follows:
995 %
996 %    o xml:  The configure list in XML format.
997 %
998 %    o filename:  The configure list filename.
999 %
1000 %    o depth: depth of <include /> statements.
1001 %
1002 %    o exception: return any errors or warnings in this structure.
1003 %
1004 */
1005 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1006   const size_t depth,ExceptionInfo *exception)
1007 {
1008   char
1009     keyword[MaxTextExtent],
1010     *token;
1011
1012   ConfigureInfo
1013     *configure_info;
1014
1015   const char
1016     *q;
1017
1018   MagickBooleanType
1019     status;
1020
1021   /*
1022     Load the configure map file.
1023   */
1024   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1025     "Loading configure file \"%s\" ...",filename);
1026   if (configure_list == (LinkedListInfo *) NULL)
1027     {
1028       configure_list=NewLinkedList(0);
1029       if (configure_list == (LinkedListInfo *) NULL)
1030         {
1031           ThrowFileException(exception,ResourceLimitError,
1032             "MemoryAllocationFailed",filename);
1033           return(MagickFalse);
1034         }
1035     }
1036   status=MagickTrue;
1037   configure_info=(ConfigureInfo *) NULL;
1038   token=AcquireString((char *) xml);
1039   for (q=(char *) xml; *q != '\0'; )
1040   {
1041     /*
1042       Interpret XML.
1043     */
1044     GetMagickToken(q,&q,token);
1045     if (*token == '\0')
1046       break;
1047     (void) CopyMagickString(keyword,token,MaxTextExtent);
1048     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1049       {
1050         /*
1051           Doctype element.
1052         */
1053         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1054           GetMagickToken(q,&q,token);
1055         continue;
1056       }
1057     if (LocaleNCompare(keyword,"<!--",4) == 0)
1058       {
1059         /*
1060           Comment element.
1061         */
1062         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1063           GetMagickToken(q,&q,token);
1064         continue;
1065       }
1066     if (LocaleCompare(keyword,"<include") == 0)
1067       {
1068         /*
1069           Include element.
1070         */
1071         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1072         {
1073           (void) CopyMagickString(keyword,token,MaxTextExtent);
1074           GetMagickToken(q,&q,token);
1075           if (*token != '=')
1076             continue;
1077           GetMagickToken(q,&q,token);
1078           if (LocaleCompare(keyword,"file") == 0)
1079             {
1080               if (depth > 200)
1081                 (void) ThrowMagickException(exception,GetMagickModule(),
1082                   ConfigureError,"IncludeElementNestedTooDeeply","'%s'",token);
1083               else
1084                 {
1085                   char
1086                     path[MaxTextExtent],
1087                     *xml;
1088
1089                   GetPathComponent(filename,HeadPath,path);
1090                   if (*path != '\0')
1091                     (void) ConcatenateMagickString(path,DirectorySeparator,
1092                       MaxTextExtent);
1093                   if (*token == *DirectorySeparator)
1094                     (void) CopyMagickString(path,token,MaxTextExtent);
1095                   else
1096                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
1097                   xml=FileToString(path,~0,exception);
1098                   if (xml != (char *) NULL)
1099                     {
1100                       status=LoadConfigureList(xml,path,depth+1,exception);
1101                       xml=(char *) RelinquishMagickMemory(xml);
1102                     }
1103                 }
1104             }
1105         }
1106         continue;
1107       }
1108     if (LocaleCompare(keyword,"<configure") == 0)
1109       {
1110         /*
1111           Configure element.
1112         */
1113         configure_info=(ConfigureInfo *) AcquireMagickMemory(
1114           sizeof(*configure_info));
1115         if (configure_info == (ConfigureInfo *) NULL)
1116           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1117         (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1118         configure_info->path=ConstantString(filename);
1119         configure_info->exempt=MagickFalse;
1120         configure_info->signature=MagickSignature;
1121         continue;
1122       }
1123     if (configure_info == (ConfigureInfo *) NULL)
1124       continue;
1125     if (LocaleCompare(keyword,"/>") == 0)
1126       {
1127         status=AppendValueToLinkedList(configure_list,configure_info);
1128         if (status == MagickFalse)
1129           (void) ThrowMagickException(exception,GetMagickModule(),
1130             ResourceLimitError,"MemoryAllocationFailed","'%s'",
1131             configure_info->name);
1132         configure_info=(ConfigureInfo *) NULL;
1133       }
1134     /*
1135       Parse configure element.
1136     */
1137     GetMagickToken(q,(const char **) NULL,token);
1138     if (*token != '=')
1139       continue;
1140     GetMagickToken(q,&q,token);
1141     GetMagickToken(q,&q,token);
1142     switch (*keyword)
1143     {
1144       case 'N':
1145       case 'n':
1146       {
1147         if (LocaleCompare((char *) keyword,"name") == 0)
1148           {
1149             configure_info->name=ConstantString(token);
1150             break;
1151           }
1152         break;
1153       }
1154       case 'S':
1155       case 's':
1156       {
1157         if (LocaleCompare((char *) keyword,"stealth") == 0)
1158           {
1159             configure_info->stealth=IsStringTrue(token);
1160             break;
1161           }
1162         break;
1163       }
1164       case 'V':
1165       case 'v':
1166       {
1167         if (LocaleCompare((char *) keyword,"value") == 0)
1168           {
1169             configure_info->value=ConstantString(token);
1170             break;
1171           }
1172         break;
1173       }
1174       default:
1175         break;
1176     }
1177   }
1178   token=(char *) RelinquishMagickMemory(token);
1179   return(status);
1180 }
1181 \f
1182 /*
1183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1184 %                                                                             %
1185 %                                                                             %
1186 %                                                                             %
1187 %  L o a d C o n f i g u r e L i s t s                                        %
1188 %                                                                             %
1189 %                                                                             %
1190 %                                                                             %
1191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192 %
1193 %  LoadConfigureList() loads one or more configure configuration files which
1194 %  provides a mapping between configure attributes and a configure name.
1195 %
1196 %  The format of the LoadConfigureLists method is:
1197 %
1198 %      MagickBooleanType LoadConfigureLists(const char *filename,
1199 %        ExceptionInfo *exception)
1200 %
1201 %  A description of each parameter follows:
1202 %
1203 %    o filename: the font file name.
1204 %
1205 %    o exception: return any errors or warnings in this structure.
1206 %
1207 */
1208 static MagickBooleanType LoadConfigureLists(const char *filename,
1209   ExceptionInfo *exception)
1210 {
1211   const StringInfo
1212     *option;
1213
1214   LinkedListInfo
1215     *options;
1216
1217   MagickStatusType
1218     status;
1219
1220   register ssize_t
1221     i;
1222
1223   /*
1224     Load built-in configure map.
1225   */
1226   status=MagickFalse;
1227   if (configure_list == (LinkedListInfo *) NULL)
1228     {
1229       configure_list=NewLinkedList(0);
1230       if (configure_list == (LinkedListInfo *) NULL)
1231         {
1232           ThrowFileException(exception,ResourceLimitError,
1233             "MemoryAllocationFailed",filename);
1234           return(MagickFalse);
1235         }
1236     }
1237   for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1238   {
1239     ConfigureInfo
1240       *configure_info;
1241
1242     register const ConfigureMapInfo
1243       *p;
1244
1245     p=ConfigureMap+i;
1246     configure_info=(ConfigureInfo *) AcquireMagickMemory(
1247       sizeof(*configure_info));
1248     if (configure_info == (ConfigureInfo *) NULL)
1249       {
1250         (void) ThrowMagickException(exception,GetMagickModule(),
1251           ResourceLimitError,"MemoryAllocationFailed","'%s'",
1252           configure_info->name);
1253         continue;
1254       }
1255     (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1256     configure_info->path=(char *) "[built-in]";
1257     configure_info->name=(char *) p->name;
1258     configure_info->value=(char *) p->value;
1259     configure_info->exempt=MagickTrue;
1260     configure_info->signature=MagickSignature;
1261     status=AppendValueToLinkedList(configure_list,configure_info);
1262     if (status == MagickFalse)
1263       (void) ThrowMagickException(exception,GetMagickModule(),
1264         ResourceLimitError,"MemoryAllocationFailed","'%s'",
1265         configure_info->name);
1266   }
1267   /*
1268     Load external configure map.
1269   */
1270   options=GetConfigureOptions(filename,exception);
1271   option=(const StringInfo *) GetNextValueInLinkedList(options);
1272   while (option != (const StringInfo *) NULL)
1273   {
1274     status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1275       GetStringInfoPath(option),0,exception);
1276     option=(const StringInfo *) GetNextValueInLinkedList(options);
1277   }
1278   options=DestroyConfigureOptions(options);
1279   return(status != 0 ? MagickTrue : MagickFalse);
1280 }