|
WizardsToolkit
1.0.7
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % M M IIIII M M EEEEE % 00006 % MM MM I MM MM E % 00007 % M M M I M M M EEE % 00008 % M M I M M E % 00009 % M M IIIII M M EEEEE % 00010 % % 00011 % % 00012 % ImageMagick Mime Methods % 00013 % % 00014 % Software Design % 00015 % July 2000 % 00016 % % 00017 % % 00018 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % 00019 % dedicated to making software imaging solutions freely available. % 00020 % % 00021 % You may not use this file except in compliance with the License. You may % 00022 % obtain a copy of the License at % 00023 % % 00024 % http://www.wizards-toolkit.org/script/license.php % 00025 % % 00026 % Unless required by applicable law or agreed to in writing, software % 00027 % distributed under the License is distributed on an "AS IS" BASIS, % 00028 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00029 % See the License for the specific language governing permissions and % 00030 % limitations under the License. % 00031 % % 00032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00033 % 00034 % 00035 */ 00036 00037 /* 00038 Include declarations. 00039 */ 00040 #include "wizard/studio.h" 00041 #include "wizard/blob.h" 00042 #include "wizard/client.h" 00043 #include "wizard/configure.h" 00044 #include "wizard/exception.h" 00045 #include "wizard/exception-private.h" 00046 #include "wizard/hashmap.h" 00047 #include "wizard/memory_.h" 00048 #include "wizard/mime.h" 00049 #include "wizard/mime-private.h" 00050 #include "wizard/option.h" 00051 #include "wizard/semaphore.h" 00052 #include "wizard/string_.h" 00053 #include "wizard/token.h" 00054 #include "wizard/utility.h" 00055 #include "wizard/xml-tree.h" 00056 00057 /* 00058 Define declarations. 00059 */ 00060 #define MimeFilename "mime.xml" 00061 00062 /* 00063 Typedef declaration. 00064 */ 00065 struct _MimeInfo 00066 { 00067 char 00068 *path, 00069 *type, 00070 *description, 00071 *pattern; 00072 00073 ssize_t 00074 priority; 00075 00076 WizardOffsetType 00077 offset; 00078 00079 size_t 00080 extent; 00081 00082 DataType 00083 data_type; 00084 00085 ssize_t 00086 mask, 00087 value; 00088 00089 EndianType 00090 endian; 00091 00092 size_t 00093 length; 00094 00095 unsigned char 00096 *magic; 00097 00098 WizardBooleanType 00099 stealth; 00100 00101 size_t 00102 signature; 00103 }; 00104 00105 /* 00106 Static declarations. 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 WizardBooleanType 00121 instantiate_mime = WizardFalse; 00122 00123 /* 00124 Forward declarations. 00125 */ 00126 static WizardBooleanType 00127 InitializeMimeList(ExceptionInfo *); 00128 00129 /* 00130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00131 % % 00132 % % 00133 % % 00134 + G e t M i m e I n f o % 00135 % % 00136 % % 00137 % % 00138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00139 % 00140 % GetMimeInfo() attempts to classify the content to identify which mime type 00141 % is associated with the content, if any. 00142 % 00143 % The format of the GetMimeInfo method is: 00144 % 00145 % const MimeInfo *GetMimeInfo(const char *filename, 00146 % const unsigned char *magic,const size_t length, 00147 % ExceptionInfo *exception) 00148 % 00149 % A description of each parameter follows: 00150 % 00151 % o filename: If we cannot not classify the string, we attempt to classify 00152 % based on the filename (e.g. *.pdf returns application/pdf). 00153 % 00154 % o magic: A binary string generally representing the first few characters 00155 % of the image file or blob. 00156 % 00157 % o length: The length of the binary signature. 00158 % 00159 % o exception: Return any errors or warnings in this structure. 00160 % 00161 */ 00162 WizardExport 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 ssize_t 00172 value; 00173 00174 register const MimeInfo 00175 *p; 00176 00177 register const unsigned char 00178 *q; 00179 00180 register ssize_t 00181 i; 00182 00183 size_t 00184 lsb_first; 00185 00186 assert(exception != (ExceptionInfo *) NULL); 00187 if ((mime_list == (LinkedListInfo *) NULL) || 00188 (instantiate_mime == WizardFalse)) 00189 if (InitializeMimeList(exception) == WizardFalse) 00190 return((const MimeInfo *) NULL); 00191 if ((mime_list == (LinkedListInfo *) NULL) || 00192 (IsLinkedListEmpty(mime_list) != WizardFalse)) 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 Search for requested mime type. 00200 */ 00201 mime_info=(const MimeInfo *) NULL; 00202 lsb_first=1; 00203 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,WizardFalse) != WizardFalse) 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 <= (ssize_t) 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 UnlockSemaphoreInfo(mime_semaphore); 00328 return(mime_info); 00329 } 00330 00331 /* 00332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00333 % % 00334 % % 00335 % % 00336 % G e t M i m e I n f o L i s t % 00337 % % 00338 % % 00339 % % 00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00341 % 00342 % GetMimeInfoList() returns any image aliases that match the specified 00343 % pattern. 00344 % 00345 % The magic of the GetMimeInfoList function is: 00346 % 00347 % const MimeInfo **GetMimeInfoList(const char *pattern, 00348 % size_t *number_aliases,ExceptionInfo *exception) 00349 % 00350 % A description of each parameter follows: 00351 % 00352 % o pattern: Specifies a pointer to a text string containing a pattern. 00353 % 00354 % o number_aliases: This integer returns the number of magics in the 00355 % list. 00356 % 00357 % o exception: Return any errors or warnings in this structure. 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 WizardExport const MimeInfo **GetMimeInfoList(const char *pattern, 00383 size_t *number_aliases,ExceptionInfo *exception) 00384 { 00385 const MimeInfo 00386 **aliases; 00387 00388 register const MimeInfo 00389 *p; 00390 00391 register ssize_t 00392 i; 00393 00394 /* 00395 Allocate mime list. 00396 */ 00397 assert(pattern != (char *) NULL); 00398 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern); 00399 assert(number_aliases != (size_t *) 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 Generate mime list. 00410 */ 00411 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 == WizardFalse) && 00417 (GlobExpression(p->type,pattern,WizardFalse) != WizardFalse)) 00418 aliases[i++]=p; 00419 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list); 00420 } 00421 UnlockSemaphoreInfo(mime_semaphore); 00422 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare); 00423 aliases[i]=(MimeInfo *) NULL; 00424 *number_aliases=(size_t) i; 00425 return(aliases); 00426 } 00427 00428 /* 00429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00430 % % 00431 % % 00432 % % 00433 % G e t M i m e L i s t % 00434 % % 00435 % % 00436 % % 00437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00438 % 00439 % GetMimeList() returns any image format aliases that match the specified 00440 % pattern. 00441 % 00442 % The format of the GetMimeList function is: 00443 % 00444 % char **GetMimeList(const char *pattern,size_t *number_aliases, 00445 % ExceptionInfo *exception) 00446 % 00447 % A description of each parameter follows: 00448 % 00449 % o pattern: Specifies a pointer to a text string containing a pattern. 00450 % 00451 % o number_aliases: This integer returns the number of image format aliases 00452 % in the list. 00453 % 00454 % o exception: Return any errors or warnings in this structure. 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 WizardExport char **GetMimeList(const char *pattern, 00478 size_t *number_aliases,ExceptionInfo *exception) 00479 { 00480 char 00481 **aliases; 00482 00483 register const MimeInfo 00484 *p; 00485 00486 register ssize_t 00487 i; 00488 00489 /* 00490 Allocate configure list. 00491 */ 00492 assert(pattern != (char *) NULL); 00493 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern); 00494 assert(number_aliases != (size_t *) 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 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 == WizardFalse) && 00509 (GlobExpression(p->type,pattern,WizardFalse) != WizardFalse)) 00510 aliases[i++]=ConstantString(p->type); 00511 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list); 00512 } 00513 UnlockSemaphoreInfo(mime_semaphore); 00514 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare); 00515 aliases[i]=(char *) NULL; 00516 *number_aliases=(size_t) i; 00517 return(aliases); 00518 } 00519 00520 /* 00521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00522 % % 00523 % % 00524 % % 00525 % G e t M i m e D e s c r i p t i o n % 00526 % % 00527 % % 00528 % % 00529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00530 % 00531 % GetMimeDescription() returns the mime type description. 00532 % 00533 % The format of the GetMimeDescription method is: 00534 % 00535 % const char *GetMimeDescription(const MimeInfo *mime_info) 00536 % 00537 % A description of each parameter follows: 00538 % 00539 % o mime_info: The magic info. 00540 % 00541 */ 00542 WizardExport const char *GetMimeDescription(const MimeInfo *mime_info) 00543 { 00544 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00545 assert(mime_info != (MimeInfo *) NULL); 00546 assert(mime_info->signature == WizardSignature); 00547 return(mime_info->description); 00548 } 00549 00550 /* 00551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00552 % % 00553 % % 00554 % % 00555 % G e t M i m e T y p e % 00556 % % 00557 % % 00558 % % 00559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00560 % 00561 % GetMimeType() returns the mime type. 00562 % 00563 % The format of the GetMimeType method is: 00564 % 00565 % const char *GetMimeType(const MimeInfo *mime_info) 00566 % 00567 % A description of each parameter follows: 00568 % 00569 % o mime_info: The magic info. 00570 % 00571 */ 00572 WizardExport const char *GetMimeType(const MimeInfo *mime_info) 00573 { 00574 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00575 assert(mime_info != (MimeInfo *) NULL); 00576 assert(mime_info->signature == WizardSignature); 00577 return(mime_info->type); 00578 } 00579 00580 /* 00581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00582 % % 00583 % % 00584 % % 00585 + I n i t i a l i z e M i m e L i s t % 00586 % % 00587 % % 00588 % % 00589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00590 % 00591 % InitializeMimeList() initializes the mime list. 00592 % 00593 % The format of the InitializeMimeList method is: 00594 % 00595 % WizardBooleanType InitializeMimeList(ExceptionInfo *exception) 00596 % 00597 % A description of each parameter follows. 00598 % 00599 % o exception: Return any errors or warnings in this structure. 00600 % 00601 */ 00602 static WizardBooleanType InitializeMimeList(ExceptionInfo *exception) 00603 { 00604 if ((mime_list == (LinkedListInfo *) NULL) && 00605 (instantiate_mime == WizardFalse)) 00606 { 00607 if (mime_semaphore == (SemaphoreInfo *) NULL) 00608 AcquireSemaphoreInfo(&mime_semaphore); 00609 LockSemaphoreInfo(mime_semaphore); 00610 if ((mime_list == (LinkedListInfo *) NULL) && 00611 (instantiate_mime == WizardFalse)) 00612 { 00613 (void) LoadMimeLists(MimeFilename,exception); 00614 instantiate_mime=WizardTrue; 00615 } 00616 UnlockSemaphoreInfo(mime_semaphore); 00617 } 00618 return(mime_list != (LinkedListInfo *) NULL ? WizardTrue : WizardFalse); 00619 } 00620 00621 /* 00622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00623 % % 00624 % % 00625 % % 00626 % L i s t M i m e I n f o % 00627 % % 00628 % % 00629 % % 00630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00631 % 00632 % ListMimeInfo() lists the magic info to a file. 00633 % 00634 % The format of the ListMimeInfo method is: 00635 % 00636 % WizardBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception) 00637 % 00638 % A description of each parameter follows. 00639 % 00640 % o file: An pointer to a FILE. 00641 % 00642 % o exception: Return any errors or warnings in this structure. 00643 % 00644 */ 00645 WizardExport WizardBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception) 00646 { 00647 const char 00648 *path; 00649 00650 const MimeInfo 00651 **mime_info; 00652 00653 ssize_t 00654 j; 00655 00656 register ssize_t 00657 i; 00658 00659 size_t 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(WizardFalse); 00667 j=0; 00668 path=(const char *) NULL; 00669 for (i=0; i < (ssize_t) number_aliases; i++) 00670 { 00671 if (mime_info[i]->stealth != WizardFalse) 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=(ssize_t) 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 **) RelinquishWizardMemory((void *) mime_info); 00701 return(WizardTrue); 00702 } 00703 00704 /* 00705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00706 % % 00707 % % 00708 % % 00709 + L o a d M i m e L i s t % 00710 % % 00711 % % 00712 % % 00713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00714 % 00715 % LoadMimeList() loads the magic configuration file which provides a mapping 00716 % between magic attributes and a magic name. 00717 % 00718 % The format of the LoadMimeList method is: 00719 % 00720 % WizardBooleanType LoadMimeList(const char *xml,const char *filename, 00721 % const size_t depth,ExceptionInfo *exception) 00722 % 00723 % A description of each parameter follows: 00724 % 00725 % o xml: The mime list in XML format. 00726 % 00727 % o filename: The mime list filename. 00728 % 00729 % o depth: depth of <include /> statements. 00730 % 00731 % o exception: Return any errors or warnings in this structure. 00732 % 00733 */ 00734 static WizardBooleanType LoadMimeList(const char *xml,const char *filename, 00735 const size_t depth,ExceptionInfo *exception) 00736 { 00737 const char 00738 *attribute; 00739 00740 MimeInfo 00741 *mime_info = (MimeInfo *) NULL; 00742 00743 WizardBooleanType 00744 status; 00745 00746 XMLTreeInfo 00747 *mime, 00748 *mime_map, 00749 *include; 00750 00751 /* 00752 Load the mime map file. 00753 */ 00754 (void) LogWizardEvent(ConfigureEvent,GetWizardModule(), 00755 "Loading mime map \"%s\" ...",filename); 00756 if (xml == (const char *) NULL) 00757 return(WizardFalse); 00758 if (mime_list == (LinkedListInfo *) NULL) 00759 { 00760 mime_list=NewLinkedList(0); 00761 if (mime_list == (LinkedListInfo *) NULL) 00762 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'"); 00763 } 00764 mime_map=NewXMLTree(xml,exception); 00765 if (mime_map == (XMLTreeInfo *) NULL) 00766 return(WizardFalse); 00767 status=WizardTrue; 00768 include=GetXMLTreeChild(mime_map,"include"); 00769 while (include != (XMLTreeInfo *) NULL) 00770 { 00771 /* 00772 Process include element. 00773 */ 00774 attribute=GetXMLTreeAttribute(include,"file"); 00775 if (attribute != (const char *) NULL) 00776 { 00777 if (depth > 200) 00778 (void) ThrowWizardException(exception,GetWizardModule(), 00779 ConfigureError,"include element nested too deeply `%s'",filename); 00780 else 00781 { 00782 char 00783 path[MaxTextExtent], 00784 *xml; 00785 00786 GetPathComponent(filename,HeadPath,path); 00787 if (*path != '\0') 00788 (void) ConcatenateWizardString(path,DirectorySeparator, 00789 MaxTextExtent); 00790 if (*attribute == *DirectorySeparator) 00791 (void) CopyWizardString(path,attribute,MaxTextExtent); 00792 else 00793 (void) ConcatenateWizardString(path,attribute,MaxTextExtent); 00794 xml=FileToString(path,~0,exception); 00795 if (xml != (char *) NULL) 00796 { 00797 status=LoadMimeList(xml,path,depth+1,exception); 00798 xml=DestroyString(xml); 00799 } 00800 } 00801 } 00802 include=GetNextXMLTreeTag(include); 00803 } 00804 mime=GetXMLTreeChild(mime_map,"mime"); 00805 while (mime != (XMLTreeInfo *) NULL) 00806 { 00807 const char 00808 *attribute; 00809 00810 /* 00811 Process mime element. 00812 */ 00813 mime_info=(MimeInfo *) AcquireWizardMemory(sizeof(*mime_info)); 00814 if (mime_info == (MimeInfo *) NULL) 00815 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'"); 00816 (void) ResetWizardMemory(mime_info,0,sizeof(*mime_info)); 00817 mime_info->path=ConstantString(filename); 00818 mime_info->signature=WizardSignature; 00819 attribute=GetXMLTreeAttribute(mime,"data-type"); 00820 if (attribute != (const char *) NULL) 00821 mime_info->data_type=(DataType) ParseWizardOption(WizardDataTypeOptions, 00822 WizardTrue,attribute); 00823 attribute=GetXMLTreeAttribute(mime,"description"); 00824 if (attribute != (const char *) NULL) 00825 mime_info->description=ConstantString(attribute); 00826 attribute=GetXMLTreeAttribute(mime,"endian"); 00827 if (attribute != (const char *) NULL) 00828 mime_info->endian=(EndianType) ParseWizardOption(WizardEndianOptions, 00829 WizardTrue,attribute); 00830 attribute=GetXMLTreeAttribute(mime,"magic"); 00831 if (attribute != (const char *) NULL) 00832 { 00833 char 00834 *token; 00835 00836 const char 00837 *p; 00838 00839 register unsigned char 00840 *q; 00841 00842 token=AcquireString(attribute); 00843 (void) SubstituteString((char **) &token,"<","<"); 00844 (void) SubstituteString((char **) &token,"&","&"); 00845 (void) SubstituteString((char **) &token,""","\""); 00846 mime_info->magic=(unsigned char *) AcquireString(token); 00847 q=mime_info->magic; 00848 for (p=token; *p != '\0'; ) 00849 { 00850 if (*p == '\\') 00851 { 00852 p++; 00853 if (isdigit((int) ((unsigned char) *p)) != 0) 00854 { 00855 char 00856 *end; 00857 00858 *q++=(unsigned char) strtol(p,&end,8); 00859 p+=(end-p); 00860 mime_info->length++; 00861 continue; 00862 } 00863 switch (*p) 00864 { 00865 case 'b': *q='\b'; break; 00866 case 'f': *q='\f'; break; 00867 case 'n': *q='\n'; break; 00868 case 'r': *q='\r'; break; 00869 case 't': *q='\t'; break; 00870 case 'v': *q='\v'; break; 00871 case 'a': *q='a'; break; 00872 case '?': *q='\?'; break; 00873 default: *q=(unsigned char) (*p); break; 00874 } 00875 p++; 00876 q++; 00877 mime_info->length++; 00878 continue; 00879 } 00880 *q++=(unsigned char) (*p++); 00881 mime_info->length++; 00882 } 00883 token=DestroyString(token); 00884 if (mime_info->data_type != StringData) 00885 mime_info->value=strtol((char *) mime_info->magic,(char **) NULL,0); 00886 } 00887 attribute=GetXMLTreeAttribute(mime,"mask"); 00888 if (attribute != (const char *) NULL) 00889 mime_info->mask=strtol(attribute,(char **) NULL,0); 00890 attribute=GetXMLTreeAttribute(mime,"offset"); 00891 if (attribute != (const char *) NULL) 00892 { 00893 char 00894 *c; 00895 00896 mime_info->offset=(WizardOffsetType) strtol(attribute,&c,0); 00897 if (*c == ':') 00898 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0); 00899 } 00900 attribute=GetXMLTreeAttribute(mime,"pattern"); 00901 if (attribute != (const char *) NULL) 00902 mime_info->pattern=ConstantString(attribute); 00903 attribute=GetXMLTreeAttribute(mime,"priority"); 00904 if (attribute != (const char *) NULL) 00905 mime_info->priority=strtol(attribute,(char **) NULL,0); 00906 attribute=GetXMLTreeAttribute(mime,"stealth"); 00907 if (attribute != (const char *) NULL) 00908 mime_info->stealth=IsWizardTrue(attribute); 00909 attribute=GetXMLTreeAttribute(mime,"type"); 00910 if (attribute != (const char *) NULL) 00911 mime_info->type=ConstantString(attribute); 00912 status=AppendValueToLinkedList(mime_list,mime_info); 00913 if (status == WizardFalse) 00914 (void) ThrowWizardException(exception,GetWizardModule(),ResourceError, 00915 "memory allocation failed `%s'",filename); 00916 mime=GetNextXMLTreeTag(mime); 00917 } 00918 mime_map=DestroyXMLTree(mime_map); 00919 return(status); 00920 } 00921 00922 /* 00923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00924 % % 00925 % % 00926 % % 00927 % L o a d M i m e L i s t s % 00928 % % 00929 % % 00930 % % 00931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00932 % 00933 % LoadMimeList() loads one or more magic configuration file which provides a 00934 % mapping between magic attributes and a magic name. 00935 % 00936 % The format of the LoadMimeLists method is: 00937 % 00938 % WizardBooleanType LoadMimeLists(const char *filename, 00939 % ExceptionInfo *exception) 00940 % 00941 % A description of each parameter follows: 00942 % 00943 % o filename: The font file name. 00944 % 00945 % o exception: Return any errors or warnings in this structure. 00946 % 00947 */ 00948 WizardExport WizardBooleanType LoadMimeLists(const char *filename, 00949 ExceptionInfo *exception) 00950 { 00951 #if defined(WIZARDSTOOLKIT_EMBEDDABLE_SUPPORT) 00952 return(LoadMimeList(MimeMap,"built-in",0,exception)); 00953 #else 00954 const StringInfo 00955 *option; 00956 00957 LinkedListInfo 00958 *options; 00959 00960 WizardStatusType 00961 status; 00962 00963 status=WizardFalse; 00964 options=GetConfigureOptions(filename,exception); 00965 option=(const StringInfo *) GetNextValueInLinkedList(options); 00966 while (option != (const StringInfo *) NULL) 00967 { 00968 status|=LoadMimeList((const char *) GetStringInfoDatum(option), 00969 GetStringInfoPath(option),0,exception); 00970 option=(const StringInfo *) GetNextValueInLinkedList(options); 00971 } 00972 options=DestroyConfigureOptions(options); 00973 if ((mime_list == (LinkedListInfo *) NULL) || 00974 (IsLinkedListEmpty(mime_list) != WizardFalse)) 00975 status|=LoadMimeList(MimeMap,"built-in",0,exception); 00976 else 00977 ClearWizardException(exception); 00978 return(status != 0 ? WizardTrue : WizardFalse); 00979 #endif 00980 } 00981 00982 /* 00983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00984 % % 00985 % % 00986 % % 00987 + M i m e C o m p o n e n t G e n e s i s % 00988 % % 00989 % % 00990 % % 00991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00992 % 00993 % MimeComponentGenesis() instantiates the mime component. 00994 % 00995 % The format of the MimeComponentGenesis method is: 00996 % 00997 % WizardBooleanType MimeComponentGenesis(void) 00998 % 00999 */ 01000 WizardExport WizardBooleanType MimeComponentGenesis(void) 01001 { 01002 AcquireSemaphoreInfo(&mime_semaphore); 01003 return(WizardTrue); 01004 } 01005 01006 /* 01007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01008 % % 01009 % % 01010 % % 01011 + M i m e C o m p o n e n t T e r m i n u s % 01012 % % 01013 % % 01014 % % 01015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01016 % 01017 % MimeComponentTerminus() destroys the mime component. 01018 % 01019 % The format of the MimeComponentTerminus method is: 01020 % 01021 % MimeComponentTerminus(void) 01022 % 01023 */ 01024 01025 static void *DestroyMimeElement(void *mime_info) 01026 { 01027 register MimeInfo 01028 *p; 01029 01030 p=(MimeInfo *) mime_info; 01031 if (p->magic != (unsigned char *) NULL) 01032 p->magic=(unsigned char *) RelinquishWizardMemory(p->magic); 01033 if (p->pattern != (char *) NULL) 01034 p->pattern=DestroyString(p->pattern); 01035 if (p->description != (char *) NULL) 01036 p->description=DestroyString(p->description); 01037 if (p->type != (char *) NULL) 01038 p->type=DestroyString(p->type); 01039 if (p->path != (char *) NULL) 01040 p->path=DestroyString(p->path); 01041 p=(MimeInfo *) RelinquishWizardMemory(p); 01042 return((void *) NULL); 01043 } 01044 01045 WizardExport void MimeComponentTerminus(void) 01046 { 01047 if (mime_semaphore == (SemaphoreInfo *) NULL) 01048 AcquireSemaphoreInfo(&mime_semaphore); 01049 LockSemaphoreInfo(mime_semaphore); 01050 if (mime_list != (LinkedListInfo *) NULL) 01051 mime_list=DestroyLinkedList(mime_list,DestroyMimeElement); 01052 instantiate_mime=WizardFalse; 01053 UnlockSemaphoreInfo(mime_semaphore); 01054 DestroySemaphoreInfo(&mime_semaphore); 01055 } 01056 01057 /* 01058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01059 % % 01060 % % 01061 % % 01062 + W i z a r d T o M i m e % 01063 % % 01064 % % 01065 % % 01066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01067 % 01068 % WizardToMime() returns the officially registered (or de facto) MIME 01069 % media-type corresponding to a wizard string. If there is no registered 01070 % media-type, then the string "image/x-wizard" (all lower case) is returned. 01071 % The returned string must be deallocated by the user. 01072 % 01073 % The format of the WizardToMime method is: 01074 % 01075 % char *WizardToMime(const char *wizard) 01076 % 01077 % A description of each parameter follows. 01078 % 01079 % o wizard: ImageMagick format specification "wizard" tag. 01080 % 01081 */ 01082 WizardExport char *WizardToMime(const char *wizard) 01083 { 01084 char 01085 filename[MaxTextExtent], 01086 media[MaxTextExtent]; 01087 01088 const MimeInfo 01089 *mime_info; 01090 01091 ExceptionInfo 01092 *exception; 01093 01094 (void) FormatLocaleString(filename,MaxTextExtent,"file.%s",wizard); 01095 LocaleLower(filename); 01096 exception=AcquireExceptionInfo(); 01097 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception); 01098 exception=DestroyExceptionInfo(exception); 01099 if (mime_info != (const MimeInfo *) NULL) 01100 return(ConstantString(GetMimeType(mime_info))); 01101 (void) FormatLocaleString(media,MaxTextExtent,"image/x-%s",wizard); 01102 LocaleLower(media+8); 01103 return(ConstantString(media)); 01104 }