2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % PPPP OOO L IIIII CCCC Y Y %
9 % P OOO LLLLL IIIII CCCC Y %
12 % MagickCore Policy Methods %
19 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % http://www.imagemagick.org/script/license.php %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 % We use linked-lists because splay-trees do not currently support duplicate
36 % key / value pairs (.e.g X11 green compliance and SVG green compliance).
43 #include "magick/studio.h"
44 #include "magick/client.h"
45 #include "magick/configure.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/memory_.h"
49 #include "magick/monitor.h"
50 #include "magick/monitor-private.h"
51 #include "magick/option.h"
52 #include "magick/policy.h"
53 #include "magick/semaphore.h"
54 #include "magick/string_.h"
55 #include "magick/token.h"
56 #include "magick/utility.h"
57 #include "magick/xml-tree.h"
62 #define PolicyFilename "policy.xml"
68 *PolicyMap = (const char *)
69 "<?xml version=\"1.0\"?>"
74 Domaindef declarations.
106 static LinkedListInfo
107 *policy_list = (LinkedListInfo *) NULL;
110 *policy_semaphore = (SemaphoreInfo *) NULL;
112 static volatile MagickBooleanType
113 instantiate_policy = MagickFalse;
116 Forward declarations.
118 static MagickBooleanType
119 InitializePolicyList(ExceptionInfo *),
120 LoadPolicyLists(const char *,ExceptionInfo *);
123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 + D e s t r o y P o l i c y L i s t %
131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133 % DestroyPolicyList() deallocates memory associated with the policy list.
135 % The format of the DestroyPolicyList method is:
137 % DestroyPolicyList(void)
141 static void *DestroyPolicyElement(void *policy_info)
146 p=(PolicyInfo *) policy_info;
147 if (p->value != (char *) NULL)
148 p->value=DestroyString(p->value);
149 if (p->pattern != (char *) NULL)
150 p->pattern=DestroyString(p->pattern);
151 if (p->name != (char *) NULL)
152 p->name=DestroyString(p->name);
153 if (p->path != (char *) NULL)
154 p->path=DestroyString(p->path);
155 p=(PolicyInfo *) RelinquishMagickMemory(p);
156 return((void *) NULL);
159 MagickExport void DestroyPolicyList(void)
161 AcquireSemaphoreInfo(&policy_semaphore);
162 if (policy_list != (LinkedListInfo *) NULL)
163 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement);
164 instantiate_policy=MagickFalse;
165 RelinquishSemaphoreInfo(policy_semaphore);
166 DestroySemaphoreInfo(&policy_semaphore);
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 + G e t P o l i c y I n f o %
178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 % GetPolicyInfo() searches the policy list for the specified name and if found
181 % returns attributes for that policy.
183 % The format of the GetPolicyInfo method is:
185 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
187 % A description of each parameter follows:
189 % o name: the policy name.
191 % o exception: return any errors or warnings in this structure.
194 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
197 policyname[MaxTextExtent];
205 assert(exception != (ExceptionInfo *) NULL);
206 if ((policy_list == (LinkedListInfo *) NULL) ||
207 (instantiate_policy == MagickFalse))
208 if (InitializePolicyList(exception) == MagickFalse)
209 return((PolicyInfo *) NULL);
210 if ((policy_list == (LinkedListInfo *) NULL) ||
211 (IsLinkedListEmpty(policy_list) != MagickFalse))
212 return((PolicyInfo *) NULL);
213 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
214 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0));
216 Strip names of whitespace.
218 (void) CopyMagickString(policyname,name,MaxTextExtent);
219 for (q=policyname; *q != '\0'; q++)
221 if (isspace((int) ((unsigned char) *q)) == 0)
223 (void) CopyMagickString(q,q+1,MaxTextExtent);
227 Search for policy tag.
229 AcquireSemaphoreInfo(&policy_semaphore);
230 ResetLinkedListIterator(policy_list);
231 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
232 while (p != (PolicyInfo *) NULL)
234 if (LocaleCompare(policyname,p->name) == 0)
236 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
238 if (p == (PolicyInfo *) NULL)
239 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
240 "UnrecognizedPolicy","`%s'",name);
242 (void) InsertValueInLinkedList(policy_list,0,
243 RemoveElementByValueFromLinkedList(policy_list,p));
244 RelinquishSemaphoreInfo(policy_semaphore);
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 % G e t P o l i c y I n f o L i s t %
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 % GetPolicyInfoList() returns any policies that match the specified pattern.
261 % The format of the GetPolicyInfoList function is:
263 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
264 % unsigned long *number_policies,ExceptionInfo *exception)
266 % A description of each parameter follows:
268 % o pattern: Specifies a pointer to a text string containing a pattern.
270 % o number_policies: returns the number of policies in the list.
272 % o exception: return any errors or warnings in this structure.
275 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
276 unsigned long *number_policies,ExceptionInfo *exception)
281 register const PolicyInfo
288 Allocate policy list.
290 assert(pattern != (char *) NULL);
291 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
292 assert(number_policies != (unsigned long *) NULL);
294 p=GetPolicyInfo("*",exception);
295 if (p == (const PolicyInfo *) NULL)
296 return((const PolicyInfo **) NULL);
297 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
298 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
299 if (policies == (const PolicyInfo **) NULL)
300 return((const PolicyInfo **) NULL);
302 Generate policy list.
304 AcquireSemaphoreInfo(&policy_semaphore);
305 ResetLinkedListIterator(policy_list);
306 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
307 for (i=0; p != (const PolicyInfo *) NULL; )
309 if ((p->stealth == MagickFalse) &&
310 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
312 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
314 RelinquishSemaphoreInfo(policy_semaphore);
315 policies[i]=(PolicyInfo *) NULL;
316 *number_policies=(unsigned long) i;
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325 % G e t P o l i c y L i s t %
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331 % GetPolicyList() returns any policies that match the specified pattern.
333 % The format of the GetPolicyList function is:
335 % char **GetPolicyList(const char *pattern,unsigned long *number_policies,
336 % ExceptionInfo *exception)
338 % A description of each parameter follows:
340 % o pattern: a pointer to a text string containing a pattern.
342 % o number_policies: returns the number of policies in the list.
344 % o exception: return any errors or warnings in this structure.
347 MagickExport char **GetPolicyList(const char *pattern,
348 unsigned long *number_policies,ExceptionInfo *exception)
353 register const PolicyInfo
360 Allocate policy list.
362 assert(pattern != (char *) NULL);
363 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
364 assert(number_policies != (unsigned long *) NULL);
366 p=GetPolicyInfo("*",exception);
367 if (p == (const PolicyInfo *) NULL)
368 return((char **) NULL);
369 policies=(char **) AcquireQuantumMemory((size_t)
370 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
371 if (policies == (char **) NULL)
372 return((char **) NULL);
374 Generate policy list.
376 AcquireSemaphoreInfo(&policy_semaphore);
377 ResetLinkedListIterator(policy_list);
378 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
379 for (i=0; p != (const PolicyInfo *) NULL; )
381 if ((p->stealth == MagickFalse) &&
382 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
383 policies[i++]=ConstantString(p->name);
384 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
386 RelinquishSemaphoreInfo(policy_semaphore);
387 policies[i]=(char *) NULL;
388 *number_policies=(unsigned long) i;
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 % G e t P o l i c y V a l u e %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % GetPolicyValue() returns the value associated with the named policy.
405 % The format of the GetPolicyValue method is:
407 % char *GetPolicyValue(const char *name)
409 % A description of each parameter follows:
411 % o policy_info: The policy info.
414 MagickExport char *GetPolicyValue(const char *name)
425 assert(name != (const char *) NULL);
426 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
427 exception=AcquireExceptionInfo();
428 policy_info=GetPolicyInfo(name,exception);
429 exception=DestroyExceptionInfo(exception);
430 if (policy_info == (PolicyInfo *) NULL)
431 return((char *) NULL);
432 value=policy_info->value;
433 if ((value == (const char *) NULL) || (*value == '\0'))
434 return((char *) NULL);
435 return(ConstantString(value));
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443 + I n i t i a l i z e P o l i c y L i s t %
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 % InitializePolicyList() initializes the policy list.
451 % The format of the InitializePolicyList method is:
453 % MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
455 % A description of each parameter follows.
457 % o exception: return any errors or warnings in this structure.
460 static MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
462 if ((policy_list == (LinkedListInfo *) NULL) &&
463 (instantiate_policy == MagickFalse))
465 AcquireSemaphoreInfo(&policy_semaphore);
466 if ((policy_list == (LinkedListInfo *) NULL) &&
467 (instantiate_policy == MagickFalse))
469 (void) LoadPolicyLists(PolicyFilename,exception);
470 instantiate_policy=MagickTrue;
472 RelinquishSemaphoreInfo(policy_semaphore);
474 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 % I s R i g h t s A u t h o r i z e d %
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
489 % requested rights for the specified domain.
491 % The format of the IsRightsAuthorized method is:
493 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
494 % const PolicyRights rights,const char *pattern)
496 % A description of each parameter follows:
498 % o domain: the policy domain.
500 % o rights: the policy rights.
502 % o pattern: the coder, delegate, filter, or path pattern.
505 MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
506 const PolicyRights rights,const char *pattern)
520 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
521 "Domain: %s; rights=%s; pattern=\"%s\" ...",
522 MagickOptionToMnemonic(MagickPolicyDomainOptions,domain),
523 MagickOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
524 exception=AcquireExceptionInfo();
525 policy_info=GetPolicyInfo("*",exception);
526 exception=DestroyExceptionInfo(exception);
527 if (policy_info == (PolicyInfo *) NULL)
529 authorized=MagickTrue;
530 AcquireSemaphoreInfo(&policy_semaphore);
531 ResetLinkedListIterator(policy_list);
532 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
533 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
535 if ((p->domain == domain) &&
536 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
538 if (((rights & ReadPolicyRights) != 0) &&
539 ((p->rights & ReadPolicyRights) == 0))
540 authorized=MagickFalse;
541 if (((rights & WritePolicyRights) != 0) &&
542 ((p->rights & WritePolicyRights) == 0))
543 authorized=MagickFalse;
544 if (((rights & ExecutePolicyRights) != 0) &&
545 ((p->rights & ExecutePolicyRights) == 0))
546 authorized=MagickFalse;
548 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
550 RelinquishSemaphoreInfo(policy_semaphore);
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559 % L i s t P o l i c y I n f o %
563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
565 % ListPolicyInfo() lists policies to the specified file.
567 % The format of the ListPolicyInfo method is:
569 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
571 % A description of each parameter follows.
573 % o file: List policy names to this file handle.
575 % o exception: return any errors or warnings in this structure.
578 MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
579 ExceptionInfo *exception)
595 List name and attributes of each policy in the list.
597 if (file == (const FILE *) NULL)
599 policy_info=GetPolicyInfoList("*",&number_policies,exception);
600 if (policy_info == (const PolicyInfo **) NULL)
602 path=(const char *) NULL;
603 for (i=0; i < (long) number_policies; i++)
605 if (policy_info[i]->stealth != MagickFalse)
607 if (((path == (const char *) NULL) ||
608 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
609 (policy_info[i]->path != (char *) NULL))
610 (void) fprintf(file,"\nPath: %s\n",policy_info[i]->path);
611 path=policy_info[i]->path;
612 domain=MagickOptionToMnemonic(MagickPolicyDomainOptions,
613 policy_info[i]->domain);
614 (void) fprintf(file," Policy: %s\n",domain);
615 if (policy_info[i]->domain == ResourcePolicyDomain)
617 if (policy_info[i]->name != (char *) NULL)
618 (void) fprintf(file," name: %s\n",policy_info[i]->name);
619 if (policy_info[i]->value != (char *) NULL)
620 (void) fprintf(file," value: %s\n",policy_info[i]->value);
624 (void) fprintf(file," rights: ");
625 if (policy_info[i]->rights == NoPolicyRights)
626 (void) fprintf(file,"None ");
627 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
628 (void) fprintf(file,"Read ");
629 if ((policy_info[i]->rights & WritePolicyRights) != 0)
630 (void) fprintf(file,"Write ");
631 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
632 (void) fprintf(file,"Execute ");
633 (void) fprintf(file,"\n");
634 if (policy_info[i]->pattern != (char *) NULL)
635 (void) fprintf(file," pattern: %s\n",policy_info[i]->pattern);
638 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649 + L o a d P o l i c y L i s t %
653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655 % LoadPolicyList() loads the policy configuration file which provides a mapping
656 % between policy attributes and a policy domain.
658 % The format of the LoadPolicyList method is:
660 % MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
661 % const unsigned long depth,ExceptionInfo *exception)
663 % A description of each parameter follows:
665 % o xml: The policy list in XML format.
667 % o filename: The policy list filename.
669 % o depth: depth of <include /> statements.
671 % o exception: return any errors or warnings in this structure.
674 static MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
675 const unsigned long depth,ExceptionInfo *exception)
678 keyword[MaxTextExtent],
691 Load the policy map file.
693 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
694 "Loading policy file \"%s\" ...",filename);
695 if (xml == (char *) NULL)
697 if (policy_list == (LinkedListInfo *) NULL)
699 policy_list=NewLinkedList(0);
700 if (policy_list == (LinkedListInfo *) NULL)
702 ThrowFileException(exception,ResourceLimitError,
703 "MemoryAllocationFailed",filename);
708 policy_info=(PolicyInfo *) NULL;
709 token=AcquireString(xml);
710 for (q=(const char *) xml; *q != '\0'; )
715 GetMagickToken(q,&q,token);
718 (void) CopyMagickString(keyword,token,MaxTextExtent);
719 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
724 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
725 GetMagickToken(q,&q,token);
728 if (LocaleNCompare(keyword,"<!--",4) == 0)
733 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
734 GetMagickToken(q,&q,token);
737 if (LocaleCompare(keyword,"<include") == 0)
742 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
744 (void) CopyMagickString(keyword,token,MaxTextExtent);
745 GetMagickToken(q,&q,token);
748 GetMagickToken(q,&q,token);
749 if (LocaleCompare(keyword,"file") == 0)
752 (void) ThrowMagickException(exception,GetMagickModule(),
753 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
760 GetPathComponent(filename,HeadPath,path);
762 (void) ConcatenateMagickString(path,DirectorySeparator,
764 if (*token == *DirectorySeparator)
765 (void) CopyMagickString(path,token,MaxTextExtent);
767 (void) ConcatenateMagickString(path,token,MaxTextExtent);
768 xml=FileToString(path,~0,exception);
769 if (xml != (char *) NULL)
771 status=LoadPolicyList(xml,path,depth+1,exception);
772 xml=(char *) RelinquishMagickMemory(xml);
779 if (LocaleCompare(keyword,"<policy") == 0)
784 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
785 if (policy_info == (PolicyInfo *) NULL)
786 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
787 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
788 policy_info->path=ConstantString(filename);
789 policy_info->signature=MagickSignature;
792 if (policy_info == (PolicyInfo *) NULL)
794 if (LocaleCompare(keyword,"/>") == 0)
796 status=AppendValueToLinkedList(policy_list,policy_info);
797 if (status == MagickFalse)
798 (void) ThrowMagickException(exception,GetMagickModule(),
799 ResourceLimitError,"MemoryAllocationFailed","`%s'",
801 policy_info=(PolicyInfo *) NULL;
803 GetMagickToken(q,(const char **) NULL,token);
806 GetMagickToken(q,&q,token);
807 GetMagickToken(q,&q,token);
813 if (LocaleCompare((char *) keyword,"domain") == 0)
815 policy_info->domain=(PolicyDomain) ParseMagickOption(
816 MagickPolicyDomainOptions,MagickTrue,token);
824 if (LocaleCompare((char *) keyword,"name") == 0)
826 policy_info->name=ConstantString(token);
834 if (LocaleCompare((char *) keyword,"pattern") == 0)
836 policy_info->pattern=ConstantString(token);
844 if (LocaleCompare((char *) keyword,"rights") == 0)
846 policy_info->rights=(PolicyRights) ParseMagickOption(
847 MagickPolicyRightsOptions,MagickTrue,token);
855 if (LocaleCompare((char *) keyword,"stealth") == 0)
857 policy_info->stealth=IsMagickTrue(token);
865 if (LocaleCompare((char *) keyword,"value") == 0)
867 policy_info->value=ConstantString(token);
876 token=(char *) RelinquishMagickMemory(token);
881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 % L o a d P o l i c y L i s t s %
889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
891 % LoadPolicyList() loads one or more policy configuration file which provides a
892 % mapping between policy attributes and a policy name.
894 % The format of the LoadPolicyLists method is:
896 % MagickBooleanType LoadPolicyLists(const char *filename,
897 % ExceptionInfo *exception)
899 % A description of each parameter follows:
901 % o filename: the font file name.
903 % o exception: return any errors or warnings in this structure.
906 static MagickBooleanType LoadPolicyLists(const char *filename,
907 ExceptionInfo *exception)
909 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
910 return(LoadPolicyList(PolicyMap,"built-in",0,exception));
922 options=GetConfigureOptions(filename,exception);
923 option=(const StringInfo *) GetNextValueInLinkedList(options);
924 while (option != (const StringInfo *) NULL)
926 status|=LoadPolicyList((const char *) GetStringInfoDatum(option),
927 GetStringInfoPath(option),0,exception);
928 option=(const StringInfo *) GetNextValueInLinkedList(options);
930 options=DestroyConfigureOptions(options);
931 if ((policy_list == (LinkedListInfo *) NULL) ||
932 (IsLinkedListEmpty(policy_list) != MagickFalse))
933 status|=LoadPolicyList(PolicyMap,"built-in",0,exception);
934 return(status != 0 ? MagickTrue : MagickFalse);