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/property.h"
00044 #include "magick/blob.h"
00045 #include "magick/color.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/geometry.h"
00049 #include "magick/list.h"
00050 #include "magick/log.h"
00051 #include "magick/memory_.h"
00052 #include "magick/option.h"
00053 #include "magick/resource_.h"
00054 #include "magick/semaphore.h"
00055 #include "magick/signature-private.h"
00056 #include "magick/statistic.h"
00057 #include "magick/string_.h"
00058 #include "magick/token.h"
00059 #include "magick/utility.h"
00060 #if defined(MAGICKCORE_HAVE_MACH_O_DYLD_H)
00061 #include <mach-o/dyld.h>
00062 #endif
00063
00064
00065
00066
00067 static const char
00068 Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00069
00070
00071
00072
00073 static int
00074 IsPathDirectory(const char *);
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
00100 {
00101 int
00102 file;
00103
00104 file=AcquireUniqueFileResource(path);
00105 if (file == -1)
00106 return(MagickFalse);
00107 file=close(file)-1;
00108 return(MagickTrue);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 static inline size_t MagickMin(const size_t x,const size_t y)
00142 {
00143 if (x < y)
00144 return(x);
00145 return(y);
00146 }
00147
00148 MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
00149 char *destination)
00150 {
00151 int
00152 destination_file,
00153 source_file;
00154
00155 size_t
00156 length,
00157 quantum;
00158
00159 ssize_t
00160 count;
00161
00162 struct stat
00163 attributes;
00164
00165 unsigned char
00166 *buffer;
00167
00168 assert(source != (const char *) NULL);
00169 assert(destination != (char *) NULL);
00170 #if defined(MAGICKCORE_HAVE_SYMLINK)
00171 (void) AcquireUniqueFilename(destination);
00172 (void) RelinquishUniqueFileResource(destination);
00173 if (*source == *DirectorySeparator)
00174 {
00175 if (symlink(source,destination) == 0)
00176 return(MagickTrue);
00177 }
00178 else
00179 {
00180 char
00181 path[MaxTextExtent];
00182
00183 *path='\0';
00184 if (getcwd(path,MaxTextExtent) == (char *) NULL)
00185 return(MagickFalse);
00186 (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
00187 (void) ConcatenateMagickString(path,source,MaxTextExtent);
00188 if (symlink(path,destination) == 0)
00189 return(MagickTrue);
00190 }
00191 #endif
00192 destination_file=AcquireUniqueFileResource(destination);
00193 if (destination_file == -1)
00194 return(MagickFalse);
00195 source_file=open(source,O_RDONLY | O_BINARY);
00196 if (source_file == -1)
00197 {
00198 (void) close(destination_file);
00199 (void) RelinquishUniqueFileResource(destination);
00200 return(MagickFalse);
00201 }
00202 quantum=(size_t) MagickMaxBufferExtent;
00203 if ((fstat(source_file,&attributes) == 0) && (attributes.st_size != 0))
00204 quantum=MagickMin((size_t) attributes.st_size,MagickMaxBufferExtent);
00205 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
00206 if (buffer == (unsigned char *) NULL)
00207 {
00208 (void) close(source_file);
00209 (void) close(destination_file);
00210 (void) RelinquishUniqueFileResource(destination);
00211 return(MagickFalse);
00212 }
00213 for (length=0; ; )
00214 {
00215 count=(ssize_t) read(source_file,buffer,quantum);
00216 if (count <= 0)
00217 break;
00218 length=(size_t) count;
00219 count=(ssize_t) write(destination_file,buffer,length);
00220 if ((size_t) count != length)
00221 {
00222 (void) close(destination_file);
00223 (void) close(source_file);
00224 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
00225 (void) RelinquishUniqueFileResource(destination);
00226 return(MagickFalse);
00227 }
00228 }
00229 (void) close(destination_file);
00230 (void) close(source_file);
00231 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
00232 return(MagickTrue);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 MagickExport void AppendImageFormat(const char *format,char *filename)
00263 {
00264 char
00265 root[MaxTextExtent];
00266
00267 assert(format != (char *) NULL);
00268 assert(filename != (char *) NULL);
00269 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00270 if ((*format == '\0') || (*filename == '\0'))
00271 return;
00272 if (LocaleCompare(filename,"-") == 0)
00273 {
00274 char
00275 message[MaxTextExtent];
00276
00277 (void) FormatMagickString(message,MaxTextExtent,"%s:%s",format,filename);
00278 (void) CopyMagickString(filename,message,MaxTextExtent);
00279 return;
00280 }
00281 GetPathComponent(filename,RootPath,root);
00282 (void) FormatMagickString(filename,MaxTextExtent,"%s.%s",root,format);
00283 }
00284
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 MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
00312 {
00313 int
00314 state;
00315
00316 register const char
00317 *p,
00318 *q;
00319
00320 register size_t
00321 i;
00322
00323 unsigned char
00324 *decode;
00325
00326 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00327 assert(source != (char *) NULL);
00328 assert(length != (size_t *) NULL);
00329 *length=0;
00330 decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4,
00331 3*sizeof(*decode));
00332 if (decode == (unsigned char *) NULL)
00333 return((unsigned char *) NULL);
00334 i=0;
00335 state=0;
00336 for (p=source; *p != '\0'; p++)
00337 {
00338 if (isspace((int) ((unsigned char) *p)) != 0)
00339 continue;
00340 if (*p == '=')
00341 break;
00342 q=strchr(Base64,*p);
00343 if (q == (char *) NULL)
00344 {
00345 decode=(unsigned char *) RelinquishMagickMemory(decode);
00346 return((unsigned char *) NULL);
00347 }
00348 switch (state)
00349 {
00350 case 0:
00351 {
00352 decode[i]=(q-Base64) << 2;
00353 state++;
00354 break;
00355 }
00356 case 1:
00357 {
00358 decode[i++]|=(q-Base64) >> 4;
00359 decode[i]=((q-Base64) & 0x0f) << 4;
00360 state++;
00361 break;
00362 }
00363 case 2:
00364 {
00365 decode[i++]|=(q-Base64) >> 2;
00366 decode[i]=((q-Base64) & 0x03) << 6;
00367 state++;
00368 break;
00369 }
00370 case 3:
00371 {
00372 decode[i++]|=(q-Base64);
00373 state=0;
00374 break;
00375 }
00376 }
00377 }
00378
00379
00380
00381 if (*p != '=')
00382 {
00383 if (state != 0)
00384 {
00385 decode=(unsigned char *) RelinquishMagickMemory(decode);
00386 return((unsigned char *) NULL);
00387 }
00388 }
00389 else
00390 {
00391 p++;
00392 switch (state)
00393 {
00394 case 0:
00395 case 1:
00396 {
00397
00398
00399
00400 decode=(unsigned char *) RelinquishMagickMemory(decode);
00401 return((unsigned char *) NULL);
00402 }
00403 case 2:
00404 {
00405 for ( ; *p != '\0'; p++)
00406 if (isspace((int) ((unsigned char) *p)) == 0)
00407 break;
00408 if (*p != '=')
00409 {
00410 decode=(unsigned char *) RelinquishMagickMemory(decode);
00411 return((unsigned char *) NULL);
00412 }
00413 p++;
00414 }
00415 case 3:
00416 {
00417 for ( ; *p != '\0'; p++)
00418 if (isspace((int) ((unsigned char) *p)) == 0)
00419 {
00420 decode=(unsigned char *) RelinquishMagickMemory(decode);
00421 return((unsigned char *) NULL);
00422 }
00423 if ((int) decode[i] != 0)
00424 {
00425 decode=(unsigned char *) RelinquishMagickMemory(decode);
00426 return((unsigned char *) NULL);
00427 }
00428 }
00429 }
00430 }
00431 *length=i;
00432 return(decode);
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
00459
00460
00461
00462
00463
00464
00465 MagickExport char *Base64Encode(const unsigned char *blob,
00466 const size_t blob_length,size_t *encode_length)
00467 {
00468 char
00469 *encode;
00470
00471 register const unsigned char
00472 *p;
00473
00474 register size_t
00475 i;
00476
00477 size_t
00478 remainder;
00479
00480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00481 assert(blob != (const unsigned char *) NULL);
00482 assert(blob_length != 0);
00483 assert(encode_length != (size_t *) NULL);
00484 *encode_length=0;
00485 encode=(char *) AcquireQuantumMemory(blob_length/3+4,4*sizeof(*encode));
00486 if (encode == (char *) NULL)
00487 return((char *) NULL);
00488 i=0;
00489 for (p=blob; p < (blob+blob_length-2); p+=3)
00490 {
00491 encode[i++]=Base64[(int) (*p >> 2)];
00492 encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
00493 encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
00494 encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
00495 }
00496 remainder=blob_length % 3;
00497 if (remainder != 0)
00498 {
00499 long
00500 j;
00501
00502 unsigned char
00503 code[3];
00504
00505 code[0]='\0';
00506 code[1]='\0';
00507 code[2]='\0';
00508 for (j=0; j < (long) remainder; j++)
00509 code[j]=(*p++);
00510 encode[i++]=Base64[(int) (code[0] >> 2)];
00511 encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
00512 if (remainder == 1)
00513 encode[i++]='=';
00514 else
00515 encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
00516 encode[i++]='=';
00517 }
00518 *encode_length=i;
00519 encode[i++]='\0';
00520 return(encode);
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 MagickExport void ChopPathComponents(char *path,const unsigned long components)
00549 {
00550 register long
00551 i;
00552
00553 for (i=0; i < (long) components; i++)
00554 GetPathComponent(path,HeadPath,path);
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 MagickExport void ExpandFilename(char *path)
00581 {
00582 char
00583 expand_path[MaxTextExtent];
00584
00585 if (path == (char *) NULL)
00586 return;
00587 if (*path != '~')
00588 return;
00589 (void) CopyMagickString(expand_path,path,MaxTextExtent);
00590 if ((*(path+1) == *DirectorySeparator) || (*(path+1) == '\0'))
00591 {
00592 char
00593 *home;
00594
00595
00596
00597
00598 (void) CopyMagickString(expand_path,".",MaxTextExtent);
00599 (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent);
00600 home=GetEnvironmentValue("HOME");
00601 if (home == (char *) NULL)
00602 home=GetEnvironmentValue("USERPROFILE");
00603 if (home != (char *) NULL)
00604 {
00605 (void) CopyMagickString(expand_path,home,MaxTextExtent);
00606 (void) ConcatenateMagickString(expand_path,path+1,MaxTextExtent);
00607 home=DestroyString(home);
00608 }
00609 }
00610 else
00611 {
00612 #if defined(MAGICKCORE_POSIX_SUPPORT)
00613 char
00614 username[MaxTextExtent];
00615
00616 register char
00617 *p;
00618
00619 struct passwd
00620 *entry;
00621
00622
00623
00624
00625 (void) CopyMagickString(username,path+1,MaxTextExtent);
00626 p=strchr(username,'/');
00627 if (p != (char *) NULL)
00628 *p='\0';
00629 entry=getpwnam(username);
00630 if (entry == (struct passwd *) NULL)
00631 return;
00632 (void) CopyMagickString(expand_path,entry->pw_dir,MaxTextExtent);
00633 if (p != (char *) NULL)
00634 {
00635 (void) ConcatenateMagickString(expand_path,"/",MaxTextExtent);
00636 (void) ConcatenateMagickString(expand_path,p+1,MaxTextExtent);
00637 }
00638 #endif
00639 }
00640 (void) CopyMagickString(path,expand_path,MaxTextExtent);
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
00672 char ***arguments)
00673 {
00674 char
00675 home_directory[MaxTextExtent],
00676 **vector;
00677
00678 long
00679 count,
00680 parameters;
00681
00682 register long
00683 i,
00684 j;
00685
00686 unsigned long
00687 number_files;
00688
00689
00690
00691
00692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00693 assert(number_arguments != (int *) NULL);
00694 assert(arguments != (char ***) NULL);
00695 vector=(char **) AcquireQuantumMemory(*number_arguments+1UL,sizeof(*vector));
00696 if (vector == (char **) NULL)
00697 return(MagickFalse);
00698
00699
00700
00701 if (getcwd(home_directory,MaxTextExtent) == (char *) NULL)
00702 return(MagickFalse);
00703 count=0;
00704 for (i=0; i < (long) *number_arguments; i++)
00705 {
00706 char
00707 **filelist,
00708 filename[MaxTextExtent],
00709 magick[MaxTextExtent],
00710 *option,
00711 path[MaxTextExtent],
00712 subimage[MaxTextExtent];
00713
00714 MagickBooleanType
00715 destroy;
00716
00717 option=(*arguments)[i];
00718 vector[count++]=ConstantString(option);
00719 destroy=MagickTrue;
00720 parameters=ParseMagickOption(MagickCommandOptions,MagickFalse,option);
00721 if (parameters > 0)
00722 {
00723
00724
00725
00726 for (j=0; j < parameters; j++)
00727 {
00728 i++;
00729 if (i == (long) *number_arguments)
00730 break;
00731 option=(*arguments)[i];
00732 vector[count++]=ConstantString(option);
00733 }
00734 continue;
00735 }
00736 if ((*option == '"') || (*option == '\''))
00737 continue;
00738 GetPathComponent(option,TailPath,filename);
00739 if (IsGlob(filename) == MagickFalse)
00740 continue;
00741 GetPathComponent(option,MagickPath,magick);
00742 if ((LocaleCompare(magick,"CAPTION") == 0) ||
00743 (LocaleCompare(magick,"LABEL") == 0) ||
00744 (LocaleCompare(magick,"VID") == 0))
00745 continue;
00746 GetPathComponent(option,HeadPath,path);
00747 GetPathComponent(option,SubimagePath,subimage);
00748 ExpandFilename(path);
00749 filelist=ListFiles(*path == '\0' ? home_directory : path,filename,
00750 &number_files);
00751 if (filelist == (char **) NULL)
00752 continue;
00753 for (j=0; j < (long) number_files; j++)
00754 if (IsPathDirectory(filelist[j]) <= 0)
00755 break;
00756 if (j == (long) number_files)
00757 {
00758 for (j=0; j < (long) number_files; j++)
00759 filelist[j]=DestroyString(filelist[j]);
00760 filelist=(char **) RelinquishMagickMemory(filelist);
00761 continue;
00762 }
00763
00764
00765
00766 vector=(char **) ResizeQuantumMemory(vector,(size_t) *number_arguments+
00767 count+number_files+1,sizeof(*vector));
00768 if (vector == (char **) NULL)
00769 return(MagickFalse);
00770 for (j=0; j < (long) number_files; j++)
00771 {
00772 (void) CopyMagickString(filename,path,MaxTextExtent);
00773 if (*path != '\0')
00774 (void) ConcatenateMagickString(filename,DirectorySeparator,
00775 MaxTextExtent);
00776 (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
00777 filelist[j]=DestroyString(filelist[j]);
00778 if (strlen(filename) >= MaxTextExtent)
00779 ThrowFatalException(OptionFatalError,"FilenameTruncated");
00780 if (IsPathAccessible(filename) != MagickFalse)
00781 {
00782 char
00783 path[MaxTextExtent];
00784
00785 *path='\0';
00786 if (*magick != '\0')
00787 {
00788 (void) ConcatenateMagickString(path,magick,MaxTextExtent);
00789 (void) ConcatenateMagickString(path,":",MaxTextExtent);
00790 }
00791 (void) ConcatenateMagickString(path,filename,MaxTextExtent);
00792 if (*subimage != '\0')
00793 {
00794 (void) ConcatenateMagickString(path,"[",MaxTextExtent);
00795 (void) ConcatenateMagickString(path,subimage,MaxTextExtent);
00796 (void) ConcatenateMagickString(path,"]",MaxTextExtent);
00797 }
00798 if (strlen(path) >= MaxTextExtent)
00799 ThrowFatalException(OptionFatalError,"FilenameTruncated");
00800 if (destroy != MagickFalse)
00801 {
00802 count--;
00803 vector[count]=DestroyString(vector[count]);
00804 destroy=MagickFalse;
00805 }
00806 vector[count++]=ConstantString(path);
00807 }
00808 }
00809 filelist=(char **) RelinquishMagickMemory(filelist);
00810 }
00811 vector[count]=(char *) NULL;
00812 if (IsEventLogging() != MagickFalse)
00813 {
00814 char
00815 *command_line;
00816
00817 command_line=AcquireString(vector[0]);
00818 for (i=1; i < count; i++)
00819 {
00820 (void) ConcatenateString(&command_line," {");
00821 (void) ConcatenateString(&command_line,vector[i]);
00822 (void) ConcatenateString(&command_line,"}");
00823 }
00824 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00825 "Command line: %s",command_line);
00826 command_line=DestroyString(command_line);
00827 }
00828 *number_arguments=(int) count;
00829 *arguments=vector;
00830 return(MagickTrue);
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
00859 {
00860 char
00861 *cwd;
00862
00863 *path='\0';
00864 cwd=getcwd(path,(unsigned long) extent);
00865 #if defined(MAGICKCORE_HAVE_GETPID) && defined(MAGICKCORE_HAVE_READLINK)
00866 {
00867 char
00868 link_path[MaxTextExtent],
00869 real_path[PATH_MAX+1];
00870
00871 ssize_t
00872 count;
00873
00874 (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/exe",
00875 (long) getpid());
00876 count=readlink(link_path,real_path,PATH_MAX);
00877 if (count == -1)
00878 {
00879 (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/file",
00880 (long) getpid());
00881 count=readlink(link_path,real_path,PATH_MAX);
00882 }
00883 if ((count > 0) && (count <= (ssize_t) PATH_MAX))
00884 {
00885 real_path[count]='\0';
00886 (void) CopyMagickString(path,real_path,extent);
00887 }
00888 }
00889 #endif
00890 #if defined(MAGICKCORE_HAVE__NSGETEXECUTABLEPATH)
00891 {
00892 char
00893 executable_path[PATH_MAX << 1],
00894 real_path[PATH_MAX+1];
00895
00896 uint32_t
00897 length;
00898
00899 length=sizeof(executable_path);
00900 if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
00901 (realpath(executable_path,real_path) != (char *) NULL))
00902 (void) CopyMagickString(path,real_path,extent);
00903 }
00904 #endif
00905 #if defined(MAGICKCORE_HAVE_GETEXECNAME)
00906 {
00907 const char
00908 *execution_path;
00909
00910 execution_path=(const char *) getexecname();
00911 if (execution_path != (const char *) NULL)
00912 {
00913 if (*execution_path != *DirectorySeparator)
00914 (void) ConcatenateMagickString(path,DirectorySeparator,extent);
00915 (void) ConcatenateMagickString(path,execution_path,extent);
00916 }
00917 }
00918 #endif
00919 #if defined(__WINDOWS__)
00920 NTGetExecutionPath(path,extent);
00921 #endif
00922 return(IsPathAccessible(path));
00923 }
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 #if defined(MAGICKCORE_HAVE__WFOPEN)
00951 static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
00952 {
00953 register const unsigned char
00954 *p;
00955
00956 if (utf16 != (wchar_t *) NULL)
00957 {
00958 register wchar_t
00959 *q;
00960
00961 wchar_t
00962 c;
00963
00964
00965
00966
00967 q=utf16;
00968 for (p=utf8; *p != '\0'; p++)
00969 {
00970 if ((*p & 0x80) == 0)
00971 *q=(*p);
00972 else
00973 if ((*p & 0xE0) == 0xC0)
00974 {
00975 c=(*p);
00976 *q=(c & 0x1F) << 6;
00977 p++;
00978 if ((*p & 0xC0) != 0x80)
00979 return(0);
00980 *q|=(*p & 0x3F);
00981 }
00982 else
00983 if ((*p & 0xF0) == 0xE0)
00984 {
00985 c=(*p);
00986 *q=c << 12;
00987 p++;
00988 if ((*p & 0xC0) != 0x80)
00989 return(0);
00990 c=(*p);
00991 *q|=(c & 0x3F) << 6;
00992 p++;
00993 if ((*p & 0xC0) != 0x80)
00994 return(0);
00995 *q|=(*p & 0x3F);
00996 }
00997 else
00998 return(0);
00999 q++;
01000 }
01001 *q++='\0';
01002 return(q-utf16);
01003 }
01004
01005
01006
01007 for (p=utf8; *p != '\0'; p++)
01008 {
01009 if ((*p & 0x80) == 0)
01010 ;
01011 else
01012 if ((*p & 0xE0) == 0xC0)
01013 {
01014 p++;
01015 if ((*p & 0xC0) != 0x80)
01016 return(0);
01017 }
01018 else
01019 if ((*p & 0xF0) == 0xE0)
01020 {
01021 p++;
01022 if ((*p & 0xC0) != 0x80)
01023 return(0);
01024 p++;
01025 if ((*p & 0xC0) != 0x80)
01026 return(0);
01027 }
01028 else
01029 return(0);
01030 }
01031 return(p-utf8);
01032 }
01033
01034 static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
01035 {
01036 size_t
01037 length;
01038
01039 wchar_t
01040 *utf16;
01041
01042 length=UTF8ToUTF16(source,(wchar_t *) NULL);
01043 if (length == 0)
01044 {
01045 register long
01046 i;
01047
01048
01049
01050
01051 length=strlen(source);
01052 utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01053 if (utf16 == (wchar_t *) NULL)
01054 return((wchar_t *) NULL);
01055 for (i=0; i <= (long) length; i++)
01056 utf16[i]=source[i];
01057 return(utf16);
01058 }
01059 utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01060 if (utf16 == (wchar_t *) NULL)
01061 return((wchar_t *) NULL);
01062 length=UTF8ToUTF16(source,utf16);
01063 return(utf16);
01064 }
01065 #endif
01066
01067 MagickExport MagickBooleanType GetPathAttributes(const char *path,
01068 void *attributes)
01069 {
01070 MagickBooleanType
01071 status;
01072
01073 if (path == (const char *) NULL)
01074 {
01075 errno=EINVAL;
01076 return(MagickFalse);
01077 }
01078 #if !defined(MAGICKCORE_HAVE__WFOPEN)
01079 status=stat(path,(struct stat *) attributes) == 0 ? MagickTrue : MagickFalse;
01080 #else
01081 {
01082 wchar_t
01083 *unicode_path;
01084
01085 unicode_path=ConvertUTF8ToUTF16(path);
01086 if (unicode_path == (wchar_t *) NULL)
01087 return(MagickFalse);
01088 status=_wstat(unicode_path,(struct _stat *) attributes) == 0 ? MagickTrue :
01089 MagickFalse;
01090 unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
01091 }
01092 #endif
01093 return(status);
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 MagickExport void GetPathComponent(const char *path,PathType type,
01125 char *component)
01126 {
01127 char
01128 magick[MaxTextExtent],
01129 *q,
01130 subimage[MaxTextExtent];
01131
01132 register char
01133 *p;
01134
01135 assert(path != (const char *) NULL);
01136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",path);
01137 assert(component != (char *) NULL);
01138 if (*path == '\0')
01139 {
01140 *component='\0';
01141 return;
01142 }
01143 (void) CopyMagickString(component,path,MaxTextExtent);
01144 *magick='\0';
01145 for (p=component; *p != '\0'; p++)
01146 if ((*p == ':') && (IsPathDirectory(path) < 0) &&
01147 (IsPathAccessible(path) == MagickFalse))
01148 {
01149
01150
01151
01152 (void) CopyMagickString(magick,component,(size_t) (p-component+1));
01153 if (IsMagickConflict(magick) != MagickFalse)
01154 *magick='\0';
01155 else
01156 for (q=component; *q != '\0'; q++)
01157 *q=(*++p);
01158 break;
01159 }
01160 *subimage='\0';
01161 p=component;
01162 if (*p != '\0')
01163 p=component+strlen(component)-1;
01164 if ((*p == ']') && (strchr(component,'[') != (char *) NULL) &&
01165 (IsPathAccessible(path) == MagickFalse))
01166 {
01167
01168
01169
01170 for (q=p-1; q > component; q--)
01171 if (*q == '[')
01172 break;
01173 if (*q == '[')
01174 {
01175 (void) CopyMagickString(subimage,q+1,MaxTextExtent);
01176 subimage[p-q-1]='\0';
01177 if ((IsSceneGeometry(subimage,MagickFalse) == MagickFalse) &&
01178 (IsGeometry(subimage) == MagickFalse))
01179 *subimage='\0';
01180 else
01181 *q='\0';
01182 }
01183 }
01184 p=component;
01185 if (*p != '\0')
01186 for (p=component+strlen(component)-1; p > component; p--)
01187 if (IsBasenameSeparator(*p) != MagickFalse)
01188 break;
01189 switch (type)
01190 {
01191 case MagickPath:
01192 {
01193 (void) CopyMagickString(component,magick,MaxTextExtent);
01194 break;
01195 }
01196 case RootPath:
01197 {
01198 for (p=component+(strlen(component)-1); p > component; p--)
01199 {
01200 if (IsBasenameSeparator(*p) != MagickFalse)
01201 break;
01202 if (*p == '.')
01203 break;
01204 }
01205 if (*p == '.')
01206 *p='\0';
01207 break;
01208 }
01209 case HeadPath:
01210 {
01211 *p='\0';
01212 break;
01213 }
01214 case TailPath:
01215 {
01216 if (IsBasenameSeparator(*p) != MagickFalse)
01217 (void) CopyMagickMemory((unsigned char *) component,
01218 (const unsigned char *) (p+1),strlen(p+1)+1);
01219 break;
01220 }
01221 case BasePath:
01222 {
01223 if (IsBasenameSeparator(*p) != MagickFalse)
01224 (void) CopyMagickString(component,p+1,MaxTextExtent);
01225 for (p=component+(strlen(component)-1); p