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
00041
00042 #include "magick/studio.h"
00043 #include "magick/blob.h"
00044 #include "magick/client.h"
00045 #include "magick/configure.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/hashmap.h"
00049 #include "magick/log.h"
00050 #include "magick/memory_.h"
00051 #include "magick/option.h"
00052 #include "magick/semaphore.h"
00053 #include "magick/timer.h"
00054 #include "magick/string_.h"
00055 #include "magick/token.h"
00056 #include "magick/utility.h"
00057 #include "magick/version.h"
00058 #include "magick/xml-tree.h"
00059 #if defined(MAGICKCORE_HAVE_PTHREAD)
00060 #include <pthread.h>
00061 #endif
00062 #if defined(MAGICKCORE_HAVE_LINUX_UNISTD_H)
00063 #include <linux/unistd.h>
00064 #endif
00065 #if defined(__WINDOWS__)
00066 #include <windows.h>
00067 #endif
00068
00069
00070
00071
00072 #define LogFilename "log.xml"
00073
00074
00075
00076
00077 typedef enum
00078 {
00079 UndefinedHandler = 0x0000,
00080 NoHandler = 0x0000,
00081 ConsoleHandler = 0x0001,
00082 StdoutHandler = 0x0002,
00083 StderrHandler = 0x0004,
00084 FileHandler = 0x0008,
00085 DebugHandler = 0x0010,
00086 EventHandler = 0x0020
00087 } LogHandlerType;
00088
00089 typedef struct _EventInfo
00090 {
00091 char
00092 *name;
00093
00094 LogEventType
00095 event;
00096 } EventInfo;
00097
00098 typedef struct _HandlerInfo
00099 {
00100 const char
00101 *name;
00102
00103 LogHandlerType
00104 handler;
00105 } HandlerInfo;
00106
00107 struct _LogInfo
00108 {
00109 LogEventType
00110 event_mask;
00111
00112 LogHandlerType
00113 handler_mask;
00114
00115 char
00116 *path,
00117 *name,
00118 *filename,
00119 *format;
00120
00121 unsigned long
00122 generations,
00123 limit;
00124
00125 FILE
00126 *file;
00127
00128 unsigned long
00129 generation;
00130
00131 MagickBooleanType
00132 append,
00133 stealth;
00134
00135 TimerInfo
00136 timer;
00137
00138 unsigned long
00139 signature;
00140 };
00141
00142
00143
00144
00145 static const HandlerInfo
00146 LogHandlers[] =
00147 {
00148 { "console", ConsoleHandler },
00149 { "debug", DebugHandler },
00150 { "event", EventHandler },
00151 { "file", FileHandler },
00152 { "none", NoHandler },
00153 { "stderr", StderrHandler },
00154 { "stdout", StdoutHandler },
00155 { (char *) NULL, UndefinedHandler }
00156 };
00157
00158 static const char
00159 *LogMap = (const char *)
00160 "<?xml version=\"1.0\"?>"
00161 "<logmap>"
00162 " <log events=\"None\" />"
00163 " <log output=\"console\" />"
00164 " <log filename=\"Magick-%d.log\" />"
00165 " <log format=\"%t %r %u %v %d %c[%p]: %m/%f/%l/%d\n %e\" />"
00166 "</logmap>";
00167
00168
00169
00170
00171 static char
00172 log_name[MaxTextExtent] = "Magick";
00173
00174 static LinkedListInfo
00175 *log_list = (LinkedListInfo *) NULL;
00176
00177 static SemaphoreInfo
00178 *log_semaphore = (SemaphoreInfo *) NULL;
00179
00180 static volatile MagickBooleanType
00181 instantiate_log = MagickFalse;
00182
00183
00184
00185
00186 static LogHandlerType
00187 ParseLogHandlers(const char *);
00188
00189 static MagickBooleanType
00190 InitializeLogList(ExceptionInfo *),
00191 LoadLogLists(const char *,ExceptionInfo *);
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 MagickExport void CloseMagickLog(void)
00212 {
00213 ExceptionInfo
00214 *exception;
00215
00216 LogInfo
00217 *log_info;
00218
00219 if (IsEventLogging() == MagickFalse)
00220 return;
00221 exception=AcquireExceptionInfo();
00222 log_info=(LogInfo *) GetLogInfo("*",exception);
00223 exception=DestroyExceptionInfo(exception);
00224 AcquireSemaphoreInfo(&log_semaphore);
00225 if (log_info->file != (FILE *) NULL)
00226 {
00227 if (log_info->append == MagickFalse)
00228 (void) fprintf(log_info->file,"</log>\n");
00229 (void) fclose(log_info->file);
00230 log_info->file=(FILE *) NULL;
00231 }
00232 RelinquishSemaphoreInfo(log_semaphore);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 static void *DestroyLogElement(void *log_info)
00255 {
00256 register LogInfo
00257 *p;
00258
00259 p=(LogInfo *) log_info;
00260 if (p->file != (FILE *) NULL)
00261 {
00262 if (p->append == MagickFalse)
00263 (void) fprintf(p->file,"</log>\n");
00264 (void) fclose(p->file);
00265 p->file=(FILE *) NULL;
00266 }
00267 if (p->filename != (char *) NULL)
00268 p->filename=DestroyString(p->filename);
00269 if (p->path != (char *) NULL)
00270 p->path=DestroyString(p->path);
00271 if (p->format != (char *) NULL)
00272 p->format=DestroyString(p->format);
00273 p=(LogInfo *) RelinquishMagickMemory(p);
00274 return((void *) NULL);
00275 }
00276
00277 MagickExport void DestroyLogList(void)
00278 {
00279 AcquireSemaphoreInfo(&log_semaphore);
00280 if (log_list != (LinkedListInfo *) NULL)
00281 log_list=DestroyLinkedList(log_list,DestroyLogElement);
00282 instantiate_log=MagickFalse;
00283 RelinquishSemaphoreInfo(log_semaphore);
00284 DestroySemaphoreInfo(&log_semaphore);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 MagickExport const LogInfo *GetLogInfo(const char *name,
00313 ExceptionInfo *exception)
00314 {
00315 register const LogInfo
00316 *p;
00317
00318 assert(exception != (ExceptionInfo *) NULL);
00319 if ((log_list == (LinkedListInfo *) NULL) || (instantiate_log == MagickFalse))
00320 if (InitializeLogList(exception) == MagickFalse)
00321 return((const LogInfo *) NULL);
00322 if ((log_list == (LinkedListInfo *) NULL) ||
00323 (IsLinkedListEmpty(log_list) != MagickFalse))
00324 return((const LogInfo *) NULL);
00325 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00326 return((const LogInfo *) GetValueFromLinkedList(log_list,0));
00327
00328
00329
00330 AcquireSemaphoreInfo(&log_semaphore);
00331 ResetLinkedListIterator(log_list);
00332 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00333 while (p != (const LogInfo *) NULL)
00334 {
00335 if (LocaleCompare(name,p->name) == 0)
00336 break;
00337 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00338 }
00339 if (p != (LogInfo *) NULL)
00340 (void) InsertValueInLinkedList(log_list,0,
00341 RemoveElementByValueFromLinkedList(log_list,p));
00342 RelinquishSemaphoreInfo(log_semaphore);
00343 return(p);
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 #if defined(__cplusplus) || defined(c_plusplus)
00374 extern "C" {
00375 #endif
00376
00377 static int LogInfoCompare(const void *x,const void *y)
00378 {
00379 const LogInfo
00380 **p,
00381 **q;
00382
00383 p=(const LogInfo **) x,
00384 q=(const LogInfo **) y;
00385 if (LocaleCompare((*p)->path,(*q)->path) == 0)
00386 return(LocaleCompare((*p)->name,(*q)->name));
00387 return(LocaleCompare((*p)->path,(*q)->path));
00388 }
00389
00390 #if defined(__cplusplus) || defined(c_plusplus)
00391 }
00392 #endif
00393
00394 MagickExport const LogInfo **GetLogInfoList(const char *pattern,
00395 unsigned long *number_preferences,ExceptionInfo *exception)
00396 {
00397 const LogInfo
00398 **preferences;
00399
00400 register const LogInfo
00401 *p;
00402
00403 register long
00404 i;
00405
00406
00407
00408
00409 assert(pattern != (char *) NULL);
00410 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00411 assert(number_preferences != (unsigned long *) NULL);
00412 *number_preferences=0;
00413 p=GetLogInfo("*",exception);
00414 if (p == (const LogInfo *) NULL)
00415 return((const LogInfo **) NULL);
00416 preferences=(const LogInfo **) AcquireQuantumMemory((size_t)
00417 GetNumberOfElementsInLinkedList(log_list)+1UL,sizeof(*preferences));
00418 if (preferences == (const LogInfo **) NULL)
00419 return((const LogInfo **) NULL);
00420
00421
00422
00423 AcquireSemaphoreInfo(&log_semaphore);
00424 ResetLinkedListIterator(log_list);
00425 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00426 for (i=0; p != (const LogInfo *) NULL; )
00427 {
00428 if ((p->stealth == MagickFalse) &&
00429 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00430 preferences[i++]=p;
00431 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00432 }
00433 RelinquishSemaphoreInfo(log_semaphore);
00434 qsort((void *) preferences,(size_t) i,sizeof(*preferences),LogInfoCompare);
00435 preferences[i]=(LogInfo *) NULL;
00436 *number_preferences=(unsigned long) i;
00437 return(preferences);
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 #if defined(__cplusplus) || defined(c_plusplus)
00469 extern "C" {
00470 #endif
00471
00472 static int LogCompare(const void *x,const void *y)
00473 {
00474 register const char
00475 **p,
00476 **q;
00477
00478 p=(const char **) x;
00479 q=(const char **) y;
00480 return(LocaleCompare(*p,*q));
00481 }
00482
00483 #if defined(__cplusplus) || defined(c_plusplus)
00484 }
00485 #endif
00486
00487 MagickExport char **GetLogList(const char *pattern,
00488 unsigned long *number_preferences,ExceptionInfo *exception)
00489 {
00490 char
00491 **preferences;
00492
00493 register const LogInfo
00494 *p;
00495
00496 register long
00497 i;
00498
00499
00500
00501
00502 assert(pattern != (char *) NULL);
00503 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00504 assert(number_preferences != (unsigned long *) NULL);
00505 *number_preferences=0;
00506 p=GetLogInfo("*",exception);
00507 if (p == (const LogInfo *) NULL)
00508 return((char **) NULL);
00509 preferences=(char **) AcquireQuantumMemory((size_t)
00510 GetNumberOfElementsInLinkedList(log_list)+1UL,sizeof(*preferences));
00511 if (preferences == (char **) NULL)
00512 return((char **) NULL);
00513
00514
00515
00516 AcquireSemaphoreInfo(&log_semaphore);
00517 ResetLinkedListIterator(log_list);
00518 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00519 for (i=0; p != (const LogInfo *) NULL; )
00520 {
00521 if ((p->stealth == MagickFalse) &&
00522 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00523 preferences[i++]=ConstantString(p->name);
00524 p=(const LogInfo *) GetNextValueInLinkedList(log_list);
00525 }
00526 RelinquishSemaphoreInfo(log_semaphore);
00527 qsort((void *) preferences,(size_t) i,sizeof(*preferences),LogCompare);
00528 preferences[i]=(char *) NULL;
00529 *number_preferences=(unsigned long) i;
00530 return(preferences);
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 MagickExport const char *GetLogName(void)
00552 {
00553 return(log_name);
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 static MagickBooleanType InitializeLogList(ExceptionInfo *exception)
00579 {
00580 if ((log_list == (LinkedListInfo *) NULL) && (instantiate_log == MagickFalse))
00581 {
00582 AcquireSemaphoreInfo(&log_semaphore);
00583 if ((log_list == (LinkedListInfo *) NULL) &&
00584 (instantiate_log == MagickFalse))
00585 {
00586 (void) LoadLogLists(LogFilename,exception);
00587 instantiate_log=MagickTrue;
00588 }
00589 RelinquishSemaphoreInfo(log_semaphore);
00590 }
00591 return(log_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 MagickExport MagickBooleanType IsEventLogging(void)
00614 {
00615 const LogInfo
00616 *log_info;
00617
00618 ExceptionInfo
00619 *exception;
00620
00621 if ((log_list == (LinkedListInfo *) NULL) ||
00622 (IsLinkedListEmpty(log_list) != MagickFalse))
00623 return(MagickFalse);
00624 exception=AcquireExceptionInfo();
00625 log_info=GetLogInfo("*",exception);
00626 exception=DestroyExceptionInfo(exception);
00627 return(log_info->event_mask != NoEvents ? MagickTrue : MagickFalse);
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 MagickExport MagickBooleanType ListLogInfo(FILE *file,ExceptionInfo *exception)
00654 {
00655 #define MegabytesToBytes(value) ((MagickSizeType) (value)*1024*1024)
00656
00657 char
00658 limit[MaxTextExtent];
00659
00660 const char
00661 *path;
00662
00663 const LogInfo
00664 **log_info;
00665
00666 long
00667 j;
00668
00669 register long
00670 i;
00671
00672 unsigned long
00673 number_aliases;
00674
00675 if (file == (const FILE *) NULL)
00676 file=stdout;
00677 log_info=GetLogInfoList("*",&number_aliases,exception);
00678 if (log_info == (const LogInfo **) NULL)
00679 return(MagickFalse);
00680 j=0;
00681 path=(const char *) NULL;
00682 for (i=0; i < (long) number_aliases; i++)
00683 {
00684 if (log_info[i]->stealth != MagickFalse)
00685 continue;
00686 if ((path == (const char *) NULL) ||
00687 (LocaleCompare(path,log_info[i]->path) != 0))
00688 {
00689 if (log_info[i]->path != (char *) NULL)
00690 (void) fprintf(file,"\nPath: %s\n\n",log_info[i]->path);
00691 (void) fprintf(file,"Filename Generations Limit Format\n");
00692 (void) fprintf(file,"-------------------------------------------------"
00693 "------------------------------\n");
00694 }
00695 path=log_info[i]->path;
00696 if (log_info[i]->filename != (char *) NULL)
00697 {
00698 (void) fprintf(file,"%s",log_info[i]->filename);
00699 for (j=(long) strlen(log_info[i]->filename); j <= 16; j++)
00700 (void) fprintf(file," ");
00701 }
00702 (void) fprintf(file,"%9lu ",log_info[i]->generations);
00703 (void) FormatMagickSize(MegabytesToBytes(log_info[i]->limit),limit);
00704 (void) fprintf(file,"%8s ",limit);
00705 if (log_info[i]->format != (char *) NULL)
00706 (void) fprintf(file,"%s",log_info[i]->format);
00707 (void) fprintf(file,"\n");
00708 }
00709 (void) fflush(file);
00710 log_info=(const LogInfo **) RelinquishMagickMemory((void *) log_info);
00711 return(MagickTrue);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 static unsigned long GetLogThreadId(void)
00749 {
00750 #if defined(MAGICKCORE_HAVE_PTHREAD) && defined(MAGICKCORE_HAVE_LINUX_UNISTD_H)
00751 return((unsigned long) ((pid_t) syscall(__NR_gettid)));
00752 #endif
00753 #if defined(__WINDOWS__)
00754 return((unsigned long) GetCurrentThreadId());
00755 #endif
00756 return((unsigned long) getpid());
00757 }
00758
00759 static char *TranslateEvent(const LogEventType magick_unused(type),
00760 const char *module,const char *function,const unsigned long line,
00761 const char *domain,const char *event)
00762 {
00763 char
00764 *text;
00765
00766 double
00767 elapsed_time,
00768 user_time;
00769
00770 ExceptionInfo
00771 *exception;
00772
00773 LogInfo
00774 *log_info;
00775
00776 register char
00777 *q;
00778
00779 register const char
00780 *p;
00781
00782 size_t
00783 extent;
00784
00785 time_t
00786 seconds;
00787
00788 exception=AcquireExceptionInfo();
00789 log_info=(LogInfo *) GetLogInfo("*",exception);
00790 exception=DestroyExceptionInfo(exception);
00791 seconds=time((time_t *) NULL);
00792 elapsed_time=GetElapsedTime(&log_info->timer);
00793 user_time=GetUserTime(&log_info->timer);
00794 text=AcquireString(event);
00795 if (log_info->format == (char *) NULL)
00796 return(text);
00797 extent=strlen(event)+MaxTextExtent;
00798 if (LocaleCompare(log_info->format,"xml") == 0)
00799 {
00800 char
00801 timestamp[MaxTextExtent];
00802
00803
00804
00805
00806 (void) FormatMagickTime(seconds,extent,timestamp);
00807 (void) FormatMagickString(text,extent,
00808 "<entry>\n"
00809 " <timestamp>%s</timestamp>\n"
00810 " <elapsed-time>%ld:%02ld</elapsed-time>\n"
00811 " <user-time>%0.3f</user-time>\n"
00812 " <process-id>%ld</process-id>\n"
00813 " <thread-id>%lu</thread-id>\n"
00814 " <module>%s</module>\n"
00815 " <function>%s</function>\n"
00816 " <line>%lu</line>\n"
00817 " <domain>%s</domain>\n"
00818 " <event>%s</event>\n"
00819 "</entry>",timestamp,(long) (elapsed_time/60.0),
00820 (long) ceil(fmod(elapsed_time,60.0)),user_time,(long) getpid(),
00821 GetLogThreadId(),module,function,line,domain,event);
00822 return(text);
00823 }
00824
00825
00826
00827 q=text;
00828 for (p=log_info->format; *p != '\0'; p++)
00829 {
00830 *q='\0';
00831 if ((size_t) (q-text+MaxTextExtent) >= extent)
00832 {
00833 extent+=MaxTextExtent;
00834 text=(char *) ResizeQuantumMemory(text,extent+MaxTextExtent,
00835 sizeof(*text));
00836 if (text == (char *) NULL)
00837 return((char *) NULL);
00838 q=text+strlen(text);
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 if ((*p == '\\') && (*(p+1) == 'r'))
00861 {
00862 *q++='\r';
00863 p++;
00864 continue;
00865 }
00866 if ((*p == '\\') && (*(p+1) == 'n'))
00867 {
00868 *q++='\n';
00869 p++;
00870 continue;
00871 }
00872 if (*p != '%')
00873 {
00874 *q++=(*p);
00875 continue;
00876 }
00877 p++;
00878 switch (*p)
00879 {
00880 case 'c':
00881 {
00882 q+=CopyMagickString(q,GetClientName(),extent);
00883 break;
00884 }
00885 case 'd':
00886 {
00887 q+=CopyMagickString(q,domain,extent);
00888 break;
00889 }
00890 case 'e':
00891 {
00892 q+=CopyMagickString(q,event,extent);
00893 break;
00894 }
00895 case 'f':
00896 {
00897 q+=CopyMagickString(q,function,extent);
00898 break;
00899 }
00900 case 'g':
00901 {
00902 if (log_info->generations == 0)
00903 {
00904 (void) CopyMagickString(q,"0",extent);
00905 q++;
00906 break;
00907 }
00908 q+=FormatMagickString(q,extent,"%lu",log_info->generation %
00909 log_info->generations);
00910 break;
00911 }
00912 case 'l':
00913 {
00914 q+=FormatMagickString(q,extent,"%lu",line);
00915 break;
00916 }
00917 case 'm':
00918 {
00919 register const char
00920 *p;
00921
00922 for (p=module+strlen(module)-1; p > module; p--)
00923 if (*p == *DirectorySeparator)
00924 {
00925 p++;
00926 break;
00927 }
00928 q+=CopyMagickString(q,p,extent);
00929 break;
00930 }
00931 case 'n':
00932 {
00933 q+=CopyMagickString(q,GetLogName(),extent);
00934 break;
00935 }
00936 case 'p':
00937 {
00938 q+=FormatMagickString(q,extent,"%ld",(long) getpid());
00939 break;
00940 }
00941 case 'r':
00942 {
00943 q+=FormatMagickString(q,extent,"%ld:%02ld",(long)
00944 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)));
00945 break;
00946 }
00947 case 't':
00948 {
00949 q+=FormatMagickTime(seconds,extent,q);
00950 break;
00951 }
00952 case 'u':
00953 {
00954 q+=FormatMagickString(q,extent,"%0.3fu",user_time);
00955 break;
00956 }
00957 case 'v':
00958 {
00959 q+=CopyMagickString(q,MagickLibVersionText,extent);
00960 break;
00961 }
00962 case '%':
00963 {
00964 *q++=(*p);
00965 break;
00966 }
00967 default:
00968 {
00969 *q++='%';
00970 *q++=(*p);
00971 break;
00972 }
00973 }
00974 }
00975 *q='\0';
00976 return(text);
00977 }
00978
00979 static char *TranslateFilename(const LogInfo *log_info)
00980 {
00981 char
00982 *filename;
00983
00984 register char
00985 *q;
00986
00987 register const char
00988 *p;
00989
00990 size_t
00991 extent;
00992
00993
00994
00995
00996 assert(log_info != (LogInfo *) NULL);
00997 assert(log_info->filename != (char *) NULL);
00998 filename=AcquireString((char *) NULL);
00999 extent=MaxTextExtent;
01000 q=filename;
01001 for (p=log_info->filename; *p != '\0'; p++)
01002 {
01003 *q='\0';
01004 if ((size_t) (q-filename+MaxTextExtent) >= extent)
01005 {
01006 extent+=MaxTextExtent;
01007 filename=(char *) ResizeQuantumMemory(filename,extent+MaxTextExtent,
01008 sizeof(*filename));
01009 if (filename == (char *) NULL)
01010 return((char *) NULL);
01011 q=filename+strlen(filename);
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 if (*p != '%')
01024 {
01025 *q++=(*p);
01026 continue;
01027 }
01028 p++;
01029 switch (*p)
01030 {
01031 case 'c':
01032 {
01033 q+=CopyMagickString(q,GetClientName(),extent);
01034 break;
01035 }
01036 case 'g':
01037 {
01038 if (log_info->generations == 0)
01039 {
01040 (void) CopyMagickString(q,"0",extent);
01041 q++;
01042 break;
01043 }
01044 q+=FormatMagickString(q,extent,"%lu",log_info->generation %
01045 log_info->generations);
01046 break;
01047 }
01048 case 'n':
01049 {
01050 q+=CopyMagickString(q,GetLogName(),extent);
01051 break;
01052 }
01053 case 'p':
01054 {
01055 q+=FormatMagickString(q,extent,"%ld",(long) getpid());
01056 break;
01057 }
01058 case 'v':
01059 {
01060 q+=CopyMagickString(q,MagickLibVersionText,extent);
01061 break;
01062 }
01063 case '%':
01064 {
01065 *q++=(*p);
01066 break;
01067 }
01068 default:
01069 {
01070 *q++='%';
01071 *q++=(*p);
01072 break;
01073 }
01074 }
01075 }
01076 *q='\0';
01077 return(filename);
01078 }
01079
01080 MagickBooleanType LogMagickEventList(const LogEventType type,const char *module,
01081 const char *function,const unsigned long line,const char *format,
01082 va_list operands)
01083 {
01084 char
01085 event[MaxTextExtent],
01086 *text;
01087
01088 const char
01089 *domain;
01090
01091 ExceptionInfo
01092 *exception;
01093
01094 int
01095 n;
01096
01097 LogInfo
01098 *log_info;
01099
01100 if (IsEventLogging() == MagickFalse)
01101 return(MagickFalse);
01102 exception=AcquireExceptionInfo();
01103 log_info=(LogInfo *) GetLogInfo("*",exception);
01104 exception=DestroyExceptionInfo(exception);
01105 AcquireSemaphoreInfo(&log_semaphore);
01106 if ((log_info->event_mask & type) == 0)
01107 {
01108 RelinquishSemaphoreInfo(log_semaphore);
01109 return(MagickTrue);
01110 }
01111 domain=MagickOptionToMnemonic(MagickLogEventOptions,type);
01112 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
01113 n=vsnprintf(event,MaxTextExtent,format,operands);
01114 #else
01115 n=vsprintf(event,format,operands);
01116 #endif
01117 if (n < 0)
01118 event[MaxTextExtent-1]='\0';
01119 text=TranslateEvent(type,module,function,line,domain,event);
01120 if (text == (char *) NULL)
01121 {
01122 (void) ContinueTimer((TimerInfo *) &log_info->timer);
01123 RelinquishSemaphoreInfo(log_semaphore);
01124 return(MagickFalse);
01125 }
01126 if ((log_info->handler_mask & ConsoleHandler) != 0)
01127 {
01128 (void) fprintf(stderr,"%s\n",text);
01129 (void) fflush(stderr);
01130 }
01131 if ((log_info->handler_mask & DebugHandler) != 0)
01132 {
01133 #if defined(__WINDOWS__)
01134 OutputDebugString(text);
01135 #endif
01136 }
01137 if ((log_info->handler_mask & EventHandler) != 0)
01138 {
01139 #if defined(__WINDOWS__)
01140 (void)