WizardsToolkit  1.0.7
utility.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %             U   U  TTTTT  IIIII  L      IIIII  TTTTT  Y   Y                 %
00007 %             U   U    T      I    L        I      T     Y Y                  %
00008 %             U   U    T      I    L        I      T      Y                   %
00009 %             U   U    T      I    L        I      T      Y                   %
00010 %              UUU     T    IIIII  LLLLL  IIIII    T      Y                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                     Wizard's Toolkit Utility Methods                        %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                               March 2003                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.wizards-toolkit.org/script/license.php                        %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/locale_.h"
00046 #include "wizard/memory_.h"
00047 #include "wizard/resource_.h"
00048 #include "wizard/string-private.h"
00049 #include "wizard/utility.h"
00050 #include "wizard/utility-private.h"
00051 #if defined(WIZARDSTOOLKIT_HAVE_MACH_O_DYLD_H)
00052 #include <mach-o/dyld.h>
00053 #endif
00054 
00055 /*
00056   Static declarations.
00057 */
00058 static const char
00059   Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00060 
00061 /*
00062   Forward declaration.
00063 */
00064 static int
00065   IsDirectory(const char *);
00066 
00067 /*
00068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00069 %                                                                             %
00070 %                                                                             %
00071 %                                                                             %
00072 %  A p p e n d F i l e E x t e n s i o n                                      %
00073 %                                                                             %
00074 %                                                                             %
00075 %                                                                             %
00076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00077 %
00078 %  AppendFileExtension() appends a file extension type to the filename.  If an
00079 %  extension to the file already exists, it is first removed.
00080 %
00081 %  The extension of the AppendFileExtension method is:
00082 %
00083 %      void AppendFileExtension(const char *extension,char *filename)
00084 %
00085 %  A description of each parameter follows.
00086 %
00087 %   o  extension:  Specifies a pointer to an array of characters.  This is the
00088 %      extension of the image.
00089 %
00090 %   o  filename:  Specifies a pointer to an array of characters.  The unique
00091 %      file name is returned in this array.
00092 %
00093 */
00094 WizardExport void AppendFileExtension(const char *extension,char *filename)
00095 {
00096   char
00097     root[MaxTextExtent];
00098 
00099   assert(extension != (char *) NULL);
00100   assert(filename != (char *) NULL);
00101   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
00102   if ((*extension == '\0') || (*filename == '\0'))
00103     return;
00104   GetPathComponent(filename,RootPath,root);
00105   (void) CopyWizardString(filename,root,MaxTextExtent);
00106   (void) ConcatenateWizardString(filename,".",MaxTextExtent);
00107   (void) ConcatenateWizardString(filename,extension,MaxTextExtent);
00108 }
00109 
00110 /*
00111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00112 %                                                                             %
00113 %                                                                             %
00114 %                                                                             %
00115 %   B a s e 6 4 D e c o d e                                                   %
00116 %                                                                             %
00117 %                                                                             %
00118 %                                                                             %
00119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00120 %
00121 %  Base64Decode() decodes Base64-encoded text and returns its binary
00122 %  equivalent.  NULL is returned if the text is not valid Base64 data, or a
00123 %  memory allocation failure occurs.
00124 %
00125 %  The format of the Base64Decode method is:
00126 %
00127 %      unsigned char *Base64Decode(const char *source,length_t *length)
00128 %
00129 %  A description of each parameter follows:
00130 %
00131 %    o source:  A pointer to a Base64-encoded string.
00132 %
00133 %    o length: The number of bytes decoded.
00134 %
00135 */
00136 WizardExport unsigned char *Base64Decode(const char *source,size_t *length)
00137 {
00138   int
00139     state;
00140 
00141   register const char
00142     *p,
00143     *q;
00144 
00145   register size_t
00146     i;
00147 
00148   unsigned char
00149     *decode;
00150 
00151   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00152   assert(source != (char *) NULL);
00153   assert(length != (size_t *) NULL);
00154   *length=0;
00155   decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4,
00156     3*sizeof(*decode));
00157   if (decode == (unsigned char *) NULL)
00158     return((unsigned char *) NULL);
00159   i=0;
00160   state=0;
00161   for (p=source; *p != '\0'; p++)
00162   {
00163     if (isspace((int) ((unsigned char) *p)) != 0)
00164       continue;
00165     if (*p == '=')
00166       break;
00167     q=strchr(Base64,*p);
00168     if (q == (char *) NULL)
00169       {
00170         decode=(unsigned char *) RelinquishWizardMemory(decode);
00171         return((unsigned char *) NULL);  /* non-Base64 character */
00172       }
00173     switch (state)
00174     {
00175       case 0:
00176       {
00177         decode[i]=(q-Base64) << 2;
00178         state++;
00179         break;
00180       }
00181       case 1:
00182       {
00183         decode[i++]|=(q-Base64) >> 4;
00184         decode[i]=((q-Base64) & 0x0f) << 4;
00185         state++;
00186         break;
00187       }
00188       case 2:
00189       {
00190         decode[i++]|=(q-Base64) >> 2;
00191         decode[i]=((q-Base64) & 0x03) << 6;
00192         state++;
00193         break;
00194       }
00195       case 3:
00196       {
00197         decode[i++]|=(q-Base64);
00198         state=0;
00199         break;
00200       }
00201     }
00202   }
00203   /*
00204     Verify Base-64 string has proper terminal characters.
00205   */
00206   if (*p != '=')
00207     {
00208       if (state != 0)
00209         {
00210           decode=(unsigned char *) RelinquishWizardMemory(decode);
00211           return((unsigned char *) NULL);
00212         }
00213     }
00214   else
00215     {
00216       p++;
00217       switch (state)
00218       {
00219         case 0:
00220         case 1:
00221         {
00222           /*
00223             Unrecognized '=' character.
00224           */
00225           decode=(unsigned char *) RelinquishWizardMemory(decode);
00226           return((unsigned char *) NULL);
00227         }
00228         case 2:
00229         {
00230           for ( ; *p != '\0'; p++)
00231             if (isspace((int) ((unsigned char) *p)) == 0)
00232               break;
00233           if (*p != '=')
00234             {
00235               decode=(unsigned char *) RelinquishWizardMemory(decode);
00236               return((unsigned char *) NULL);
00237             }
00238           p++;
00239         }
00240         case 3:
00241         {
00242           for ( ; *p != '\0'; p++)
00243             if (isspace((int) ((unsigned char) *p)) == 0)
00244               {
00245                 decode=(unsigned char *) RelinquishWizardMemory(decode);
00246                 return((unsigned char *) NULL);
00247               }
00248           if ((int) decode[i] != 0)
00249             {
00250               decode=(unsigned char *) RelinquishWizardMemory(decode);
00251               return((unsigned char *) NULL);
00252             }
00253         }
00254       }
00255     }
00256   *length=i;
00257   return(decode);
00258 }
00259 
00260 /*
00261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00262 %                                                                             %
00263 %                                                                             %
00264 %                                                                             %
00265 %   B a s e 6 4 E n c o d e                                                   %
00266 %                                                                             %
00267 %                                                                             %
00268 %                                                                             %
00269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00270 %
00271 %  Base64Encode() encodes arbitrary binary data to Base64 encoded format as
00272 %  described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
00273 %  returns the result as a null-terminated ASCII string.  NULL is returned if
00274 %  a memory allocation failure occurs.
00275 %
00276 %  The format of the Base64Encode method is:
00277 %
00278 %      char *Base64Encode(const unsigned char *blob,const size_t blob_length,
00279 %        size_t *encode_length)
00280 %
00281 %  A description of each parameter follows:
00282 %
00283 %    o blob:  A pointer to binary data to encode.
00284 %
00285 %    o blob_length: The number of bytes to encode.
00286 %
00287 %    o encode_length:  The number of bytes encoded.
00288 %
00289 */
00290 WizardExport char *Base64Encode(const unsigned char *blob,
00291   const size_t blob_length,size_t *encode_length)
00292 {
00293   char
00294     *encode;
00295 
00296   register const unsigned char
00297     *p;
00298 
00299   register size_t
00300     i;
00301 
00302   size_t
00303     quantum,
00304     remainder;
00305 
00306   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00307   assert(blob != (const unsigned char *) NULL);
00308   assert(blob_length != 0);
00309   assert(encode_length != (size_t *) NULL);
00310   *encode_length=0;
00311   quantum=4*blob_length/3+4;
00312   encode=(char *) AcquireQuantumMemory(quantum,sizeof(*encode));
00313   if (encode == (char *) NULL)
00314     return((char *) NULL);
00315   i=0;
00316   for (p=blob; p < (blob+blob_length-2); p+=3)
00317   {
00318     encode[i++]=Base64[(int) (*p >> 2)];
00319     encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
00320     encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
00321     encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
00322   }
00323   remainder=blob_length % 3;
00324   if (remainder != 0)
00325     {
00326       ssize_t
00327         j;
00328 
00329       unsigned char
00330         code[3];
00331 
00332       code[0]='\0';
00333       code[1]='\0';
00334       code[2]='\0';
00335       for (j=0; j < (ssize_t) remainder; j++)
00336         code[j]=(*p++);
00337       encode[i++]=Base64[(int) (code[0] >> 2)];
00338       encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
00339       if (remainder == 1)
00340         encode[i++]='=';
00341       else
00342         encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
00343       encode[i++]='=';
00344     }
00345   *encode_length=i;
00346   encode[i++]='\0';
00347   assert(i <= quantum);
00348   return(encode);
00349 }
00350 
00351 /*
00352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00353 %                                                                             %
00354 %                                                                             %
00355 %                                                                             %
00356 %   C h o p P a t h C o m p o n e n t s                                       %
00357 %                                                                             %
00358 %                                                                             %
00359 %                                                                             %
00360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00361 %
00362 %  ChopPathComponents() removes the number of specified file components from a
00363 %  path.
00364 %
00365 %  The format of the ChopPathComponents method is:
00366 %
00367 %      ChopPathComponents(char *path,size_t components)
00368 %
00369 %  A description of each parameter follows:
00370 %
00371 %    o path:  The path.
00372 %
00373 %    o components:  The number of components to chop.
00374 %
00375 */
00376 WizardExport void ChopPathComponents(char *path,const size_t components)
00377 {
00378   register ssize_t
00379     i;
00380 
00381   for (i=0; i < (ssize_t) components; i++)
00382     GetPathComponent(path,HeadPath,path);
00383 }
00384 
00385 /*
00386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00387 %                                                                             %
00388 %                                                                             %
00389 %                                                                             %
00390 +   G e t P a t h C o m p o n e n t                                           %
00391 %                                                                             %
00392 %                                                                             %
00393 %                                                                             %
00394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00395 %
00396 %  GetPathComponent() returns the parent directory name, filename, basename,
00397 %  or extension of a file path.
00398 %
00399 %  The format of the GetPathComponent function is:
00400 %
00401 %      GetPathComponent(const char *path,PathType type,char *component)
00402 %
00403 %  A description of each parameter follows:
00404 %
00405 %    o path: Specifies a pointer to a character array that contains the
00406 %      file path.
00407 %
00408 %    o type: Specififies which file path component to return.
00409 %
00410 %    o component: The selected file path component is returned here.
00411 %
00412 */
00413 WizardExport void GetPathComponent(const char *path,PathType type,
00414   char *component)
00415 {
00416   char
00417     filesystem[MaxTextExtent],
00418     subnode[MaxTextExtent],
00419     *q;
00420 
00421   register char
00422     *p;
00423 
00424   /*
00425     Get basename of client.
00426   */
00427   assert(path != (const char *) NULL);
00428   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",path);
00429   assert(component != (const char *) NULL);
00430   if (*path == '\0')
00431     {
00432       *component='\0';
00433       return;
00434     }
00435   (void) CopyWizardString(component,path,MaxTextExtent);
00436   *filesystem='\0';
00437   for (p=component; *p != '\0'; p++)
00438     if ((*p == ':') && (IsDirectory(path) < 0) &&
00439         (IsAccessible(path) == WizardFalse))
00440       {     
00441         /*
00442           Look for filesystem specification (e.g. c:/documents).
00443         */
00444         (void) CopyWizardString(filesystem,component,(size_t)
00445           (p-component+1));
00446         if (IsDirectory(filesystem) < 0)
00447           *filesystem='\0';
00448         else         
00449           for (q=component; *q != '\0'; q++)
00450             *q=(*++p);
00451         break;
00452       }
00453   *subnode='\0';
00454   p=component;
00455   if (*p != '\0')
00456     p=component+strlen(component)-1;
00457   if ((*p == ']') && (strchr(component,'[') != (char *) NULL))
00458     {
00459       /*
00460         Look for subnode specification (e.g. book[2]).
00461       */
00462       for (q=p-1; q > component; q--)
00463         if (*q == '[')
00464           break;
00465       if (*q == '[')
00466         {
00467           (void) CopyWizardString(subnode,q+1,MaxTextExtent);
00468           subnode[p-q-1]='\0';
00469           *q='\0';
00470         }
00471     }
00472   p=component;
00473   if (*p != '\0')
00474     for (p=component+(strlen(component)-1); p > component; p--)
00475       if (IsBasenameSeparator(*p))
00476         break;
00477   switch (type)
00478   {
00479     case FilesystemPath:
00480     {
00481       (void) CopyWizardString(component,filesystem,MaxTextExtent);
00482       break;
00483     }
00484     case RootPath:
00485     {
00486       for (p=component+(strlen(component)-1); p > component; p--)
00487       {
00488         if (IsBasenameSeparator(*p) != WizardFalse)
00489           break;
00490         if (*p == '.')
00491           break;
00492       }
00493       if (*p == '.')
00494         *p='\0';
00495       break;
00496     }
00497     case HeadPath:
00498     {
00499       *p='\0';
00500       break;
00501     }
00502     case TailPath:
00503     {
00504       if (IsBasenameSeparator(*p) != WizardFalse)
00505         (void) CopyWizardMemory((unsigned char *) component,
00506           (const unsigned char *) (p+1),strlen(p+1)+1);
00507       break;
00508     }
00509     case BasePath:
00510     {
00511       if (IsBasenameSeparator(*p) != WizardFalse)
00512         (void) CopyWizardString(component,p+1,MaxTextExtent);
00513       for (p=component+(strlen(component)-1); p > component; p--)
00514         if (*p == '.')
00515           {
00516             *p='\0';
00517             break;
00518           }
00519       break;
00520     }
00521     case ExtensionPath:
00522     {
00523       if (IsBasenameSeparator(*p) != WizardFalse)
00524         (void) CopyWizardString(component,p+1,MaxTextExtent);
00525       p=component;
00526       if (*p != '\0')
00527         for (p=component+strlen(component)-1; p > component; p--)
00528           if (*p == '.')
00529             break;
00530       *component='\0';
00531       if (*p == '.')
00532         (void) CopyWizardString(component,p+1,MaxTextExtent);
00533       p=strchr(component,'?');
00534       if (p != (char *) NULL)
00535         *p='\0';
00536       break;
00537     }
00538     case SubnodePath:
00539     {
00540       (void) CopyWizardString(component,subnode,MaxTextExtent);
00541       break;
00542     }
00543     case CanonicalPath:
00544     case UndefinedPath:
00545       break;
00546   }
00547 }
00548 
00549 /*
00550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00551 %                                                                             %
00552 %                                                                             %
00553 %                                                                             %
00554 %  G e t P a t h C o m p o n e n t s                                          %
00555 %                                                                             %
00556 %                                                                             %
00557 %                                                                             %
00558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00559 %
00560 %  GetPathComponents() returns a list of path components.
00561 %
00562 %  The format of the GetPathComponents method is:
00563 %
00564 %      char **GetPathComponents(const char *path,
00565 %        size_t *number_componenets)
00566 %
00567 %  A description of each parameter follows:
00568 %
00569 %    o path:  Specifies the string to segment into a list.
00570 %
00571 %    o number_components:  return the number of components in the list
00572 %
00573 */
00574 WizardExport char **GetPathComponents(const char *path,
00575   size_t *number_components)
00576 {
00577   char
00578     **components;
00579 
00580   register char
00581     *q;
00582 
00583   register const char
00584     *p;
00585 
00586   register ssize_t
00587     i;
00588 
00589   if (path == (char *) NULL)
00590     return((char **) NULL);
00591   *number_components=1;
00592   for (p=path; *p != '\0'; p++)
00593     if (IsBasenameSeparator(*p))
00594       (*number_components)++;
00595   components=(char **) AcquireQuantumMemory((size_t) (*number_components+1),
00596     sizeof(*components));
00597   if (components == (char **) NULL)
00598     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00599   p=path;
00600   for (i=0; i < (ssize_t) *number_components; i++)
00601   {
00602     for (q=(char *) p; *q != '\0'; q++)
00603       if (IsBasenameSeparator(*q))
00604         break;
00605     components[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
00606       sizeof(**components));
00607     if (components[i] == (char *) NULL)
00608       ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00609     (void) CopyWizardString(components[i],p,(size_t) (q-p+1));
00610     p=q+1;
00611   }
00612   components[i]=(char *) NULL;
00613   return(components);
00614 }
00615 
00616 /*
00617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00618 %                                                                             %
00619 %                                                                             %
00620 %                                                                             %
00621 %   G e t E x e c u t i o n P a t h                                           %
00622 %                                                                             %
00623 %                                                                             %
00624 %                                                                             %
00625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00626 %
00627 %  GetExecutionPath() returns the pathname of the executable that started
00628 %  the process.  On success WizardTrue is returned, otherwise WizardFalse.
00629 %
00630 %  The format of the GetExecutionPath method is:
00631 %
00632 %      WizardBooleanType GetExecutionPath(char *path,const size_t extent)
00633 %
00634 %  A description of each parameter follows:
00635 %
00636 %    o path: The pathname of the executable that started the process.
00637 %
00638 %    o extent: the maximum extent of the path.
00639 %
00640 */
00641 WizardExport WizardBooleanType GetExecutionPath(char *path,const size_t extent)
00642 {
00643   char
00644     *directory;
00645 
00646   *path='\0';
00647   directory=getcwd(path,(unsigned long) extent);
00648   (void) directory;
00649 #if defined(WIZARDSTOOLKIT_HAVE_GETPID) && defined(WIZARDSTOOLKIT_HAVE_READLINK) && defined(PATH_MAX)
00650   {
00651     char
00652       link_path[MaxTextExtent],
00653       real_path[PATH_MAX+1];
00654 
00655     int
00656       length;
00657 
00658     (void) FormatLocaleString(link_path,MaxTextExtent,"/proc/%.20g/exe",
00659       (double) getpid());
00660     length=readlink(link_path,real_path,PATH_MAX);
00661     if (length == -1)
00662       {
00663         (void) FormatLocaleString(link_path,MaxTextExtent,"/proc/%.20g/file",
00664           (double) getpid());
00665         length=readlink(link_path,real_path,PATH_MAX);
00666       }
00667     if ((length > 0) && ((size_t) length <= PATH_MAX))
00668       {
00669         real_path[length]='\0';
00670         (void) CopyWizardString(path,real_path,extent);
00671       }
00672   }
00673 #endif
00674 #if defined(WIZARDSTOOLKIT_HAVE__NSGETEXECUTABLEPATH)
00675   {
00676 
00677     char
00678       executable_path[PATH_MAX << 1],
00679       real_path[PATH_MAX+1];
00680    
00681     size_t
00682       length;
00683 
00684     length=sizeof(executable_path);
00685     if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
00686         (realpath(executable_path,real_path) != (char *) NULL))
00687       (void) CopyWizardString(path,real_path,extent);
00688   }
00689 #endif
00690 #if defined(WIZARDSTOOLKIT_HAVE_GETEXECNAME)
00691   {
00692     const char
00693       *execution_path;
00694 
00695     execution_path=(const char *) getexecname();
00696     if (execution_path != (const char *) NULL)
00697       {
00698         if (*execution_path != *DirectorySeparator)
00699           (void) ConcatenateWizardString(path,DirectorySeparator,extent);
00700         (void) ConcatenateWizardString(path,execution_path,extent);
00701       }
00702   }
00703 #endif
00704 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00705   NTGetExecutionPath(path,extent);
00706 #endif
00707 #if defined(__GNU__)
00708   {
00709     char
00710       *program_name,
00711       *execution_path;
00712 
00713     ssize_t
00714       count;
00715 
00716     count=0;
00717     execution_path=(char *) NULL;
00718     program_name=program_invocation_name;
00719     if (*program_invocation_name != '/')
00720       {
00721         size_t
00722           extent;
00723 
00724         extent=strlen(directory)+strlen(program_name)+2;
00725         program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
00726         if (program_name == (char *) NULL)
00727           program_name=program_invocation_name;
00728         else
00729           count=FormatLocaleString(program_name,extent,"%s/%s",directory,
00730             program_invocation_name);
00731       }
00732     if (count != -1)
00733       {
00734         execution_path=realpath(program_name,NULL);
00735         if (execution_path != (char *) NULL)
00736           (void) CopyWizardString(path,execution_path,extent);
00737       }
00738     if (program_name != program_invocation_name)
00739       program_name=(char *) RelinquishWizardMemory(program_name);
00740     execution_path=(char *) RelinquishWizardMemory(execution_path);
00741   }
00742 #endif
00743   return(IsAccessible(path));
00744 }
00745 
00746 /*
00747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00748 %                                                                             %
00749 %                                                                             %
00750 %                                                                             %
00751 %  I s A c c e s s i b l e                                                    %
00752 %                                                                             %
00753 %                                                                             %
00754 %                                                                             %
00755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00756 %
00757 %  IsAccessible() returns WizardTrue if the file as defined by the path is
00758 %  accessible.
00759 %
00760 %  The format of the IsAccessible method is:
00761 %
00762 %      WizardBooleanType IsAccessible(const char *filename)
00763 %
00764 %  A description of each parameter follows.
00765 %
00766 %    o path:  Specifies a path to a file.
00767 %
00768 */
00769 WizardExport WizardBooleanType IsAccessible(const char *path)
00770 {
00771   int
00772     status;
00773 
00774   struct stat
00775     file_info;
00776 
00777   if ((path == (const char *) NULL) || (*path == '\0'))
00778     return(WizardFalse);
00779   status=stat_utf8(path,&file_info);
00780   if (status != 0)
00781     return(WizardFalse);
00782   if (S_ISREG(file_info.st_mode) == 0)
00783     return(WizardFalse);
00784   if (access(path,F_OK) != 0)
00785     return(WizardFalse);
00786   return(WizardTrue);
00787 }
00788 
00789 /*
00790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00791 %                                                                             %
00792 %                                                                             %
00793 %                                                                             %
00794 +  I s D i r e c t o r y                                                      %
00795 %                                                                             %
00796 %                                                                             %
00797 %                                                                             %
00798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00799 %
00800 %  IsDirectory() returns -1 if the directory does not exist,  1 is returned
00801 %  if the path represents a directory otherwise 0.
00802 %
00803 %  The format of the IsAccessible method is:
00804 %
00805 %      int IsDirectory(const char *path)
00806 %
00807 %  A description of each parameter follows.
00808 %
00809 %   o  path:  The directory path.
00810 %
00811 %
00812 */
00813 static int IsDirectory(const char *path)
00814 {
00815 #if !defined(X_OK)
00816 #define X_OK  1
00817 #endif
00818 
00819   int
00820     status;
00821 
00822   struct stat
00823     file_info;
00824 
00825   if ((path == (const char *) NULL) || (*path == '\0'))
00826     return(WizardFalse);
00827   status=stat_utf8(path,&file_info);
00828   if (status != 0)
00829     return(-1);
00830   if (S_ISDIR(file_info.st_mode) == 0)
00831     return(0);
00832   if (access(path,X_OK) != 0)
00833     return(0);
00834   return(1);
00835 }
00836 
00837 /*
00838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00839 %                                                                             %
00840 %                                                                             %
00841 %                                                                             %
00842 %   I s W i z a r d T r u e                                                   %
00843 %                                                                             %
00844 %                                                                             %
00845 %                                                                             %
00846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00847 %
00848 %  IsWizardTrue() returns WizardTrue if the value is "true", "on", "yes" or
00849 %  "1".
00850 %
00851 %  The format of the IsWizardTrue method is:
00852 %
00853 %      WizardBooleanType IsWizardTrue(const char *value)
00854 %
00855 %  A description of each parameter follows:
00856 %
00857 %    o option: either WizardTrue or WizardFalse depending on the value
00858 %      parameter.
00859 %
00860 %    o value: Specifies a pointer to a character array.
00861 %
00862 */
00863 WizardExport WizardBooleanType IsWizardTrue(const char *value)
00864 {
00865   if (value == (char *) NULL)
00866     return(WizardFalse);
00867   if (LocaleCompare(value,"true") == 0)
00868     return(WizardTrue);
00869   if (LocaleCompare(value,"on") == 0)
00870     return(WizardTrue);
00871   if (LocaleCompare(value,"yes") == 0)
00872     return(WizardTrue);
00873   if (LocaleCompare(value,"1") == 0)
00874     return(WizardTrue);
00875   return(WizardFalse);
00876 }
00877 
00878 /*
00879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00880 %                                                                             %
00881 %                                                                             %
00882 %                                                                             %
00883 %  P a r s e W i z a r d T i m e                                              %
00884 %                                                                             %
00885 %                                                                             %
00886 %                                                                             %
00887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00888 %
00889 %  ParseWizardTime() parses the specified time in the Internet date/time
00890 %  format and the returns the results.
00891 %
00892 %  The format of the ParseWizardTime method is:
00893 %
00894 %      const char *ParseWizardTime(const char *timestamp,time_t *target)
00895 %
00896 %  A description of each parameter follows.
00897 %
00898 %   o timestamp:  the Internet date/time here.
00899 %
00900 %   o target:  return the time since the Epoch (00:00:00 UTC, January 1, 1970),
00901 %     measured in seconds.
00902 %
00903 */
00904 WizardExport const char *ParseWizardTime(const char *timestamp,time_t *target)
00905 {
00906   char
00907     *q;
00908 
00909   double
00910     value;
00911 
00912   ssize_t
00913     timezone;
00914 
00915   register const char
00916     *p;
00917 
00918   register ssize_t
00919     i;
00920 
00921   static char
00922     separators[] = "--T::-:";
00923 
00924   struct tm
00925     gm_time,
00926     local_time,
00927     target_time;
00928 
00929   *target=time((time_t *) NULL);
00930 #if defined(WIZARDSTOOLKIT_HAVE_LOCALTIME_R)
00931   (void) localtime_r(target,&local_time);
00932 #else
00933   (void) memcpy(&local_time,localtime(target),sizeof(local_time));
00934 #endif
00935 #if defined(WIZARDSTOOLKIT_HAVE_GMTIME_R)
00936   (void) gmtime_r(target,&gm_time);
00937 #else
00938   (void) memcpy(&gm_time,gmtime(target),sizeof(gm_time));
00939 #endif
00940   timezone=(ssize_t) ((local_time.tm_min-gm_time.tm_min)/60+local_time.tm_hour-
00941     gm_time.tm_hour+24*((local_time.tm_year-gm_time.tm_year) != 0 ?
00942     (local_time.tm_year-gm_time.tm_year) : (local_time.tm_yday-
00943     gm_time.tm_yday)));
00944   (void) ResetWizardMemory(&target_time,0,sizeof(target_time));
00945   p=timestamp;
00946   for (i=0; ; i++)
00947   {
00948     value=StringToDouble(p,&q);
00949     if (*q != separators[i])
00950       break;
00951     switch (i)
00952     {
00953       case 0: target_time.tm_year=(int) (value+0.5)-1900; break;
00954       case 1: target_time.tm_mon=(int) (value+0.5)-1; break;
00955       case 2: target_time.tm_mday=(int) (value+0.5); break;
00956       case 3: target_time.tm_hour=(int) (value+0.5); break;
00957       case 4: target_time.tm_min=(int) (value+0.5); break;
00958       case 5: target_time.tm_sec=(int) (value+0.5); break;
00959       case 6: timezone+=(int) (value+0.5); break;
00960       default: break;
00961     }
00962     p=q;
00963     if (*q == '\0')
00964       break;
00965     p++;
00966   }
00967   *target=mktime(&target_time)-3600*timezone;
00968   return(p);
00969 }