00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "magick/studio.h"
00041 #include "magick/blob.h"
00042 #include "magick/client.h"
00043 #include "magick/configure.h"
00044 #include "magick/exception.h"
00045 #include "magick/exception-private.h"
00046 #include "magick/hashmap.h"
00047 #include "magick/memory_.h"
00048 #include "magick/mime.h"
00049 #include "magick/mime-private.h"
00050 #include "magick/option.h"
00051 #include "magick/semaphore.h"
00052 #include "magick/string_.h"
00053 #include "magick/token.h"
00054 #include "magick/utility.h"
00055 #include "magick/xml-tree.h"
00056
00057
00058
00059
00060 #define MimeFilename "mime.xml"
00061
00062
00063
00064
00065 struct _MimeInfo
00066 {
00067 char
00068 *path,
00069 *type,
00070 *description,
00071 *pattern;
00072
00073 long
00074 priority;
00075
00076 MagickOffsetType
00077 offset;
00078
00079 size_t
00080 extent;
00081
00082 DataType
00083 data_type;
00084
00085 long
00086 mask,
00087 value;
00088
00089 EndianType
00090 endian;
00091
00092 size_t
00093 length;
00094
00095 unsigned char
00096 *magic;
00097
00098 MagickBooleanType
00099 stealth;
00100
00101 unsigned long
00102 signature;
00103 };
00104
00105
00106
00107
00108 static const char
00109 *MimeMap = (char *)
00110 "<?xml version=\"1.0\"?>"
00111 "<mimemap>"
00112 "</mimemap>";
00113
00114 static LinkedListInfo
00115 *mime_list = (LinkedListInfo *) NULL;
00116
00117 static SemaphoreInfo
00118 *mime_semaphore = (SemaphoreInfo *) NULL;
00119
00120 static volatile MagickBooleanType
00121 instantiate_mime = MagickFalse;
00122
00123
00124
00125
00126 static MagickBooleanType
00127 InitializeMimeList(ExceptionInfo *);
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 MagickExport const MimeInfo *GetMimeInfo(const char *filename,
00163 const unsigned char *magic,const size_t length,ExceptionInfo *exception)
00164 {
00165 const MimeInfo
00166 *mime_info;
00167
00168 EndianType
00169 endian;
00170
00171 long
00172 value;
00173
00174 register const MimeInfo
00175 *p;
00176
00177 register const unsigned char
00178 *q;
00179
00180 register long
00181 i;
00182
00183 unsigned long
00184 lsb_first;
00185
00186 assert(exception != (ExceptionInfo *) NULL);
00187 if ((mime_list == (LinkedListInfo *) NULL) ||
00188 (instantiate_mime == MagickFalse))
00189 if (InitializeMimeList(exception) == MagickFalse)
00190 return((const MimeInfo *) NULL);
00191 if ((mime_list == (LinkedListInfo *) NULL) ||
00192 (IsLinkedListEmpty(mime_list) != MagickFalse))
00193 return((const MimeInfo *) NULL);
00194 if ((magic == (const unsigned char *) NULL) || (length == 0))
00195 return((const MimeInfo *) GetValueFromLinkedList(mime_list,0));
00196 if (length == 0)
00197 return((const MimeInfo *) NULL);
00198
00199
00200
00201 mime_info=(const MimeInfo *) NULL;
00202 lsb_first=1;
00203 (void) LockSemaphoreInfo(mime_semaphore);
00204 ResetLinkedListIterator(mime_list);
00205 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00206 while (p != (const MimeInfo *) NULL)
00207 {
00208 assert(p->offset >= 0);
00209 if (mime_info != (const MimeInfo *) NULL)
00210 if (p->priority > mime_info->priority)
00211 {
00212 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00213 continue;
00214 }
00215 if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
00216 {
00217 if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse)
00218 mime_info=p;
00219 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00220 continue;
00221 }
00222 switch (p->data_type)
00223 {
00224 case ByteData:
00225 {
00226 if ((size_t) (p->offset+4) > length)
00227 break;
00228 q=magic+p->offset;
00229 value=(*q++);
00230 if (p->mask == 0)
00231 {
00232 if (p->value == value)
00233 mime_info=p;
00234 }
00235 else
00236 {
00237 if ((p->value & p->mask) == value)
00238 mime_info=p;
00239 }
00240 break;
00241 }
00242 case ShortData:
00243 {
00244 if ((size_t) (p->offset+4) > length)
00245 break;
00246 q=magic+p->offset;
00247 endian=p->endian;
00248 if (p->endian == UndefinedEndian)
00249 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
00250 if (endian == LSBEndian)
00251 {
00252 value=(*q++);
00253 value|=(*q++) << 8;
00254 }
00255 else
00256 {
00257 value=(*q++) << 8;
00258 value|=(*q++);
00259 }
00260 if (p->mask == 0)
00261 {
00262 if (p->value == value)
00263 mime_info=p;
00264 }
00265 else
00266 {
00267 if ((p->value & p->mask) == value)
00268 mime_info=p;
00269 }
00270 break;
00271 }
00272 case LongData:
00273 {
00274 if ((size_t) (p->offset+4) > length)
00275 break;
00276 q=magic+p->offset;
00277 endian=p->endian;
00278 if (p->endian == UndefinedEndian)
00279 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
00280 if (endian == LSBEndian)
00281 {
00282 value=(*q++);
00283 value|=(*q++) << 8;
00284 value|=(*q++) << 16;
00285 value|=(*q++) << 24;
00286 }
00287 else
00288 {
00289 value=(*q++) << 24;
00290 value|=(*q++) << 16;
00291 value|=(*q++) << 8;
00292 value|=(*q++);
00293 }
00294 if (p->mask == 0)
00295 {
00296 if (p->value == value)
00297 mime_info=p;
00298 }
00299 else
00300 {
00301 if ((p->value & p->mask) == value)
00302 mime_info=p;
00303 }
00304 break;
00305 }
00306 case StringData:
00307 default:
00308 {
00309 for (i=0; i <= (long) p->extent; i++)
00310 {
00311 if ((size_t) (p->offset+i+p->length) > length)
00312 break;
00313 if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
00314 {
00315 mime_info=p;
00316 break;
00317 }
00318 }
00319 break;
00320 }
00321 }
00322 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00323 }
00324 if (p != (const MimeInfo *) NULL)
00325 (void) InsertValueInLinkedList(mime_list,0,
00326 RemoveElementByValueFromLinkedList(mime_list,p));
00327 (void) UnlockSemaphoreInfo(mime_semaphore);
00328 return(mime_info);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 #if defined(__cplusplus) || defined(c_plusplus)
00362 extern "C" {
00363 #endif
00364
00365 static int MimeInfoCompare(const void *x,const void *y)
00366 {
00367 const MimeInfo
00368 **p,
00369 **q;
00370
00371 p=(const MimeInfo **) x,
00372 q=(const MimeInfo **) y;
00373 if (strcasecmp((*p)->path,(*q)->path) == 0)
00374 return(strcasecmp((*p)->type,(*q)->type));
00375 return(strcasecmp((*p)->path,(*q)->path));
00376 }
00377
00378 #if defined(__cplusplus) || defined(c_plusplus)
00379 }
00380 #endif
00381
00382 MagickExport const MimeInfo **GetMimeInfoList(const char *pattern,
00383 unsigned long *number_aliases,ExceptionInfo *exception)
00384 {
00385 const MimeInfo
00386 **aliases;
00387
00388 register const MimeInfo
00389 *p;
00390
00391 register long
00392 i;
00393
00394
00395
00396
00397 assert(pattern != (char *) NULL);
00398 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00399 assert(number_aliases != (unsigned long *) NULL);
00400 *number_aliases=0;
00401 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
00402 if (p == (const MimeInfo *) NULL)
00403 return((const MimeInfo **) NULL);
00404 aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
00405 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
00406 if (aliases == (const MimeInfo **) NULL)
00407 return((const MimeInfo **) NULL);
00408
00409
00410
00411 (void) LockSemaphoreInfo(mime_semaphore);
00412 ResetLinkedListIterator(mime_list);
00413 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00414 for (i=0; p != (const MimeInfo *) NULL; )
00415 {
00416 if ((p->stealth == MagickFalse) &&
00417 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
00418 aliases[i++]=p;
00419 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00420 }
00421 (void) UnlockSemaphoreInfo(mime_semaphore);
00422 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
00423 aliases[i]=(MimeInfo *) NULL;
00424 *number_aliases=(unsigned long) i;
00425 return(aliases);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 #if defined(__cplusplus) || defined(c_plusplus)
00459 extern "C" {
00460 #endif
00461
00462 static int MimeCompare(const void *x,const void *y)
00463 {
00464 register char
00465 *p,
00466 *q;
00467
00468 p=(char *) x;
00469 q=(char *) y;
00470 return(strcasecmp(p,q));
00471 }
00472
00473 #if defined(__cplusplus) || defined(c_plusplus)
00474 }
00475 #endif
00476
00477 MagickExport char **GetMimeList(const char *pattern,
00478 unsigned long *number_aliases,ExceptionInfo *exception)
00479 {
00480 char
00481 **aliases;
00482
00483 register const MimeInfo
00484 *p;
00485
00486 register long
00487 i;
00488
00489
00490
00491
00492 assert(pattern != (char *) NULL);
00493 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00494 assert(number_aliases != (unsigned long *) NULL);
00495 *number_aliases=0;
00496 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
00497 if (p == (const MimeInfo *) NULL)
00498 return((char **) NULL);
00499 aliases=(char **) AcquireQuantumMemory((size_t)
00500 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
00501 if (aliases == (char **) NULL)
00502 return((char **) NULL);
00503 (void) LockSemaphoreInfo(mime_semaphore);
00504 ResetLinkedListIterator(mime_list);
00505 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00506 for (i=0; p != (const MimeInfo *) NULL; )
00507 {
00508 if ((p->stealth == MagickFalse) &&
00509 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
00510 aliases[i++]=ConstantString(p->type);
00511 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00512 }
00513 (void) UnlockSemaphoreInfo(mime_semaphore);
00514 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
00515 aliases[i]=(char *) NULL;
00516 *number_aliases=(unsigned long) i;
00517 return(aliases);
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 MagickExport const char *GetMimeDescription(const MimeInfo *mime_info)
00543 {
00544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00545 assert(mime_info != (MimeInfo *) NULL);
00546 assert(mime_info->signature == MagickSignature);
00547 return(mime_info->description);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 MagickExport const char *GetMimeType(const MimeInfo *mime_info)
00573 {
00574 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00575 assert(mime_info != (MimeInfo *) NULL);
00576 assert(mime_info->signature == MagickSignature);
00577 return(mime_info->type);
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 static MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
00603 {
00604 if ((mime_list == (LinkedListInfo *) NULL) &&
00605 (instantiate_mime == MagickFalse))
00606 {
00607 if (mime_semaphore == (SemaphoreInfo *) NULL)
00608 AcquireSemaphoreInfo(&mime_semaphore);
00609 (void) LockSemaphoreInfo(mime_semaphore);
00610 if ((mime_list == (LinkedListInfo *) NULL) &&
00611 (instantiate_mime == MagickFalse))
00612 {
00613 (void) LoadMimeLists(MimeFilename,exception);
00614 instantiate_mime=MagickTrue;
00615 }
00616 (void) UnlockSemaphoreInfo(mime_semaphore);
00617 }
00618 return(mime_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 MagickExport MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
00646 {
00647 const char
00648 *path;
00649
00650 const MimeInfo
00651 **mime_info;
00652
00653 long
00654 j;
00655
00656 register long
00657 i;
00658
00659 unsigned long
00660 number_aliases;
00661
00662 if (file == (const FILE *) NULL)
00663 file=stdout;
00664 mime_info=GetMimeInfoList("*",&number_aliases,exception);
00665 if (mime_info == (const MimeInfo **) NULL)
00666 return(MagickFalse);
00667 j=0;
00668 path=(const char *) NULL;
00669 for (i=0; i < (long) number_aliases; i++)
00670 {
00671 if (mime_info[i]->stealth != MagickFalse)
00672 continue;
00673 if ((path == (const char *) NULL) ||
00674 (strcasecmp(path,mime_info[i]->path) != 0))
00675 {
00676 if (mime_info[i]->path != (char *) NULL)
00677 (void) fprintf(file,"\nPath: %s\n\n",mime_info[i]->path);
00678 (void) fprintf(file,"Type Description\n");
00679 (void) fprintf(file,"-------------------------------------------------"
00680 "------------------------------\n");
00681 }
00682 path=mime_info[i]->path;
00683 (void) fprintf(file,"%s",mime_info[i]->type);
00684 if (strlen(mime_info[i]->type) <= 25)
00685 {
00686 for (j=(long) strlen(mime_info[i]->type); j <= 27; j++)
00687 (void) fprintf(file," ");
00688 }
00689 else
00690 {
00691 (void) fprintf(file,"\n");
00692 for (j=0; j <= 27; j++)
00693 (void) fprintf(file," ");
00694 }
00695 if (mime_info[i]->description != (char *) NULL)
00696 (void) fprintf(file,"%s",mime_info[i]->description);
00697 (void) fprintf(file,"\n");
00698 }
00699 (void) fflush(file);
00700 mime_info=(const MimeInfo **) RelinquishMagickMemory((void *) mime_info);
00701 return(MagickTrue);
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 static MagickBooleanType LoadMimeList(const char *xml,const char *filename,
00735 const unsigned long depth,ExceptionInfo *exception)
00736 {
00737 const char
00738 *attribute;
00739
00740 MimeInfo
00741 *mime_info = (MimeInfo *) NULL;
00742
00743 MagickBooleanType
00744 status;
00745
00746 XMLTreeInfo
00747 *mime,
00748 *mime_map,
00749 *include;
00750
00751
00752
00753
00754 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00755 "Loading mime map \"%s\" ...",filename);
00756 if (xml == (const char *) NULL)
00757 return(MagickFalse);
00758 if (mime_list == (LinkedListInfo *) NULL)
00759 {
00760 mime_list=NewLinkedList(0);
00761 if (mime_list == (LinkedListInfo *) NULL)
00762 {
00763 ThrowFileException(exception,ResourceLimitError,
00764 "MemoryAllocationFailed",filename);
00765 return(MagickFalse);
00766 }
00767 }
00768 mime_map=NewXMLTree(xml,exception);
00769 if (mime_map == (XMLTreeInfo *) NULL)
00770 return(MagickFalse);
00771 status=MagickTrue;
00772 include=GetXMLTreeChild(mime_map,"include");
00773 while (include != (XMLTreeInfo *) NULL)
00774 {
00775
00776
00777
00778 attribute=GetXMLTreeAttribute(include,"file");
00779 if (attribute != (const char *) NULL)
00780 {
00781 if (depth > 200)
00782 (void) ThrowMagickException(exception,GetMagickModule(),
00783 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename);
00784 else
00785 {
00786 char
00787 path[MaxTextExtent],
00788 *xml;
00789
00790 GetPathComponent(filename,HeadPath,path);
00791 if (*path != '\0')
00792 (void) ConcatenateMagickString(path,DirectorySeparator,
00793 MaxTextExtent);
00794 if (*attribute == *DirectorySeparator)
00795 (void) CopyMagickString(path,attribute,MaxTextExtent);
00796 else
00797 (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
00798 xml=FileToString(path,~0,exception);
00799 if (xml != (char *) NULL)
00800 {
00801 status=LoadMimeList(xml,path,depth+1,exception);
00802 xml=DestroyString(xml);
00803 }
00804 }
00805 }
00806 include=GetNextXMLTreeTag(include);
00807 }
00808 mime=GetXMLTreeChild(mime_map,"mime");
00809 while (mime != (XMLTreeInfo *) NULL)
00810 {
00811 const char
00812 *attribute;
00813
00814
00815
00816
00817 mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info));
00818 if (mime_info == (MimeInfo *) NULL)
00819 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00820 (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info));
00821 mime_info->path=ConstantString(filename);
00822 mime_info->signature=MagickSignature;
00823 attribute=GetXMLTreeAttribute(mime,"data-type");
00824 if (attribute != (const char *) NULL)
00825 mime_info->data_type=(DataType) ParseMagickOption(MagickDataTypeOptions,
00826 MagickTrue,attribute);
00827 attribute=GetXMLTreeAttribute(mime,"description");
00828 if (attribute != (const char *) NULL)
00829 mime_info->description=ConstantString(attribute);
00830 attribute=GetXMLTreeAttribute(mime,"endian");
00831 if (attribute != (const char *) NULL)
00832 mime_info->endian=(EndianType) ParseMagickOption(MagickEndianOptions,
00833 MagickTrue,attribute);
00834 attribute=GetXMLTreeAttribute(mime,"magic");
00835 if (attribute != (const char *) NULL)
00836 {
00837 char
00838 *token;
00839
00840 const char
00841 *p;
00842
00843 register unsigned char
00844 *q;
00845
00846 token=AcquireString(attribute);
00847 (void) SubstituteString((char **) &token,"<","<");
00848 (void) SubstituteString((char **) &token,"&","&");
00849 (void) SubstituteString((char **) &token,""","\"");
00850 mime_info->magic=(unsigned char *) AcquireString(token);
00851 q=mime_info->magic;
00852 for (p=token; *p != '\0'; )
00853 {
00854 if (*p == '\\')
00855 {
00856 p++;
00857 if (isdigit((int) ((unsigned char) *p)) != 0)
00858 {
00859 char
00860 *end;
00861
00862 *q++=(unsigned char) strtol(p,&end,8);
00863 p+=(end-p);
00864 mime_info->length++;
00865 continue;
00866 }
00867 switch (*p)
00868 {
00869 case 'b': *q='\b'; break;
00870 case 'f': *q='\f'; break;
00871 case 'n': *q='\n'; break;
00872 case 'r': *q='\r'; break;
00873 case 't': *q='\t'; break;
00874 case 'v': *q='\v'; break;
00875 case 'a': *q='a'; break;
00876 case '?': *q='\?'; break;
00877 default: *q=(unsigned char) (*p); break;
00878 }
00879 p++;
00880 q++;
00881 mime_info->length++;
00882 continue;
00883 }
00884 *q++=(unsigned char) (*p++);
00885 mime_info->length++;
00886 }
00887 token=DestroyString(token);
00888 if (mime_info->data_type != StringData)
00889 mime_info->value=strtol((char *) mime_info->magic,(char **) NULL,0);
00890 }
00891 attribute=GetXMLTreeAttribute(mime,"mask");
00892 if (attribute != (const char *) NULL)
00893 mime_info->mask=strtol(attribute,(char **) NULL,0);
00894 attribute=GetXMLTreeAttribute(mime,"offset");
00895 if (attribute != (const char *) NULL)
00896 {
00897 char
00898 *c;
00899
00900 mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0);
00901 if (*c == ':')
00902 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
00903 }
00904 attribute=GetXMLTreeAttribute(mime,"pattern");
00905 if (attribute != (const char *) NULL)
00906 mime_info->pattern=ConstantString(attribute);
00907 attribute=GetXMLTreeAttribute(mime,"priority");
00908 if (attribute != (const char *) NULL)
00909 mime_info->priority=strtol(attribute,(char **) NULL,0);
00910 attribute=GetXMLTreeAttribute(mime,"stealth");
00911 if (attribute != (const char *) NULL)
00912 mime_info->stealth=IsMagickTrue(attribute);
00913 attribute=GetXMLTreeAttribute(mime,"type");
00914 if (attribute != (const char *) NULL)
00915 mime_info->type=ConstantString(attribute);
00916 status=AppendValueToLinkedList(mime_list,mime_info);
00917 if (status == MagickFalse)
00918 (void) ThrowMagickException(exception,GetMagickModule(),
00919 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
00920 mime=GetNextXMLTreeTag(mime);
00921 }
00922 mime_map=DestroyXMLTree(mime_map);
00923 return(status);
00924 }
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 MagickExport MagickBooleanType LoadMimeLists(const char *filename,
00953 ExceptionInfo *exception)
00954 {
00955 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
00956 return(LoadMimeList(MimeMap,"built-in",0,exception));
00957 #else
00958 const StringInfo
00959 *option;
00960
00961 LinkedListInfo
00962 *options;
00963
00964 MagickStatusType
00965 status;
00966
00967 status=MagickFalse;
00968 options=GetConfigureOptions(filename,exception);
00969 option=(const StringInfo *) GetNextValueInLinkedList(options);
00970 while (option != (const StringInfo *) NULL)
00971 {
00972 status|=LoadMimeList((const char *) GetStringInfoDatum(option),
00973 GetStringInfoPath(option),0,exception);
00974 option=(const StringInfo *) GetNextValueInLinkedList(options);
00975 }
00976 options=DestroyConfigureOptions(options);
00977 if ((mime_list == (LinkedListInfo *) NULL) ||
00978 (IsLinkedListEmpty(mime_list) != MagickFalse))
00979 status|=LoadMimeList(MimeMap,"built-in",0,exception);
00980 else
00981 ClearMagickException(exception);
00982 return(status != 0 ? MagickTrue : MagickFalse);
00983 #endif
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 MagickExport char *MagickToMime(const char *magick)
01012 {
01013 char
01014 filename[MaxTextExtent],
01015 media[MaxTextExtent];
01016
01017 const MimeInfo
01018 *mime_info;
01019
01020 ExceptionInfo
01021 *exception;
01022
01023 (void) FormatMagickString(filename,MaxTextExtent,"file.%s",magick);
01024 LocaleLower(filename);
01025 exception=AcquireExceptionInfo();
01026 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
01027 exception=DestroyExceptionInfo(exception);
01028 if (mime_info != (const MimeInfo *) NULL)
01029 return(ConstantString(GetMimeType(mime_info)));
01030 (void) FormatMagickString(media,MaxTextExtent,"image/x-%s",magick);
01031 LocaleLower(media+8);
01032 return(ConstantString(media));
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 MagickExport MagickBooleanType MimeComponentGenesis(void)
01054 {
01055 AcquireSemaphoreInfo(&mime_semaphore);
01056 return(MagickTrue);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 static void *DestroyMimeElement(void *mime_info)
01079 {
01080 register MimeInfo
01081 *p;
01082
01083 p=(MimeInfo *) mime_info;
01084 if (p->magic != (unsigned char *) NULL)
01085 p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
01086 if (p->pattern != (char *) NULL)
01087 p->pattern=DestroyString(p->pattern);
01088 if (p->description != (char *) NULL)
01089 p->description=DestroyString(p->description);
01090 if (p->type != (char *) NULL)
01091 p->type=DestroyString(p->type);
01092 if (p->path != (char *) NULL)
01093 p->path=DestroyString(p->path);
01094 p=(MimeInfo *) RelinquishMagickMemory(p);
01095 return((void *) NULL);
01096 }
01097
01098 MagickExport void MimeComponentTerminus(void)
01099 {
01100 if (mime_semaphore == (SemaphoreInfo *) NULL)
01101 AcquireSemaphoreInfo(&mime_semaphore);
01102 (void) LockSemaphoreInfo(mime_semaphore);
01103 if (mime_list != (LinkedListInfo *) NULL)
01104 mime_list=DestroyLinkedList(mime_list,DestroyMimeElement);
01105 instantiate_mime=MagickFalse;
01106 (void) UnlockSemaphoreInfo(mime_semaphore);
01107 DestroySemaphoreInfo(&mime_semaphore);
01108 }