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