file.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                         FFFFF  IIIII  L      EEEEE                          %
00006 %                         F        I    L      E                              %
00007 %                         FFF      I    L      EEE                            %
00008 %                         F        I    L      E                              %
00009 %                         F      IIIII  LLLLL  EEEEE                          %
00010 %                                                                             %
00011 %                                                                             %
00012 %                         Wizard's Toolkit File Methods                       %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                               March 2003                                    %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.wizards-toolkit.org/script/license.php                        %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/blob.h"
00044 #include "wizard/exception.h"
00045 #include "wizard/exception-private.h"
00046 #include "wizard/file.h"
00047 #include "wizard/memory_.h"
00048 #include "wizard/semaphore.h"
00049 #include "wizard/string_.h"
00050 #include "wizard/utility.h"
00051 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD)
00052 #include <pthread.h>
00053 #endif
00054 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00055 #include <windows.h>
00056 #endif
00057 
00058 /*
00059   Forward declarations.
00060 */
00061 static WizardBooleanType
00062   RelinquishFileLock(FileInfo *,ExceptionInfo *);
00063 
00064 /*
00065   Typedef declarations.
00066 */
00067 struct _FileInfo
00068 {
00069   char
00070     *path;
00071 
00072   int
00073     file;
00074 
00075   struct stat
00076     properties;
00077 
00078   SemaphoreInfo
00079     *semaphore;
00080 
00081   time_t
00082     timestamp;
00083 
00084   size_t
00085     signature;
00086 };
00087 
00088 /*
00089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00090 %                                                                             %
00091 %                                                                             %
00092 %                                                                             %
00093 %   A c q u i r e F i l e L o c k                                             %
00094 %                                                                             %
00095 %                                                                             %
00096 %                                                                             %
00097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00098 %
00099 %  AcquireFileLock() acquires a lock for a file.
00100 %
00101 %  The format of the AcquireFileLock method is:
00102 %
00103 %      WizardBooleanType AcquireFileLock(FileInfo *file_info,
00104 %        ExceptionInfo *exception)
00105 %
00106 %  A description of each parameter follows:
00107 %
00108 %    o file_info: The file info.
00109 %
00110 %    o exception: Return any errors or warnings in this structure.
00111 %
00112 */
00113 
00114 static size_t GetWizardThreadId(void)
00115 {
00116 #if defined(WIZARDSTOOLKIT_HAVE_PTHREAD)
00117   return((size_t) pthread_self());
00118 #endif
00119 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00120   return((size_t) GetCurrentThreadId());
00121 #endif
00122   return((size_t) getpid());
00123 }
00124 
00125 static WizardBooleanType AcquireFileLock(FileInfo *file_info,
00126   ExceptionInfo *exception)
00127 {
00128   char
00129     *path;
00130 
00131   ssize_t
00132     pid;
00133 
00134   register ssize_t
00135     i;
00136 
00137   size_t
00138     tid;
00139 
00140   WizardStatusType
00141     status;
00142 
00143   /*
00144     Engage primitive atomic lock.
00145   */
00146   assert(file_info != (FileInfo *) NULL);
00147   assert(file_info->signature == WizardSignature);
00148   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",file_info->path);
00149   LockSemaphoreInfo(file_info->semaphore);
00150   path=AcquireString(file_info->path);
00151   AppendFileExtension("lck",path);
00152   for (i=0; i < 10; i++)
00153   {
00154     file_info->file=open(path,O_WRONLY | O_CREAT | O_EXCL,S_MODE);
00155     if (file_info->file == -1)
00156       {
00157         if (errno != EEXIST)
00158           break;
00159         file_info->file=open(path,O_RDONLY);
00160         if (file_info->file == -1)
00161           break;
00162         pid=(-1);
00163         tid=(~0UL);
00164         status=ReadFileChunk(file_info,&pid,sizeof(pid));
00165         status|=ReadFileChunk(file_info,&tid,sizeof(tid));
00166         if (close(file_info->file) == -1)
00167           (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00168             "unable to close file `%s': %s",path,strerror(errno));
00169         file_info->file=(-1);
00170         if (status != WizardFalse)
00171           {
00172             WizardBooleanType
00173               active_process;
00174 
00175             if ((pid == (ssize_t) getpid()) && (tid == GetWizardThreadId()))
00176               {
00177                 path=DestroyString(path);
00178                 UnlockSemaphoreInfo(file_info->semaphore);
00179                 return(WizardTrue);
00180               }
00181 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00182             {
00183               HANDLE
00184                 handle;
00185 
00186               handle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD) pid);
00187               active_process=handle == (HANDLE) NULL ? WizardFalse : WizardTrue;
00188               if (handle != (HANDLE) NULL)
00189                 CloseHandle(handle);
00190             }
00191 #else
00192             active_process=kill((pid_t) pid,0) == -1 ? WizardFalse : WizardTrue;
00193 #endif
00194             if (active_process == WizardFalse)
00195               {
00196                 if (errno != ESRCH)
00197                   break;
00198                 i--;
00199                 if (remove(path) == -1)
00200                   (void) ThrowWizardException(exception,GetWizardModule(),
00201                     FileError,"unable to remove file `%s': %s",path,
00202                     strerror(errno));
00203                 break;
00204               }
00205           }
00206         (void) sleep(1);
00207         continue;
00208       }
00209     pid=(ssize_t) getpid();
00210     status=WriteFileChunk(file_info,&pid,sizeof(pid));
00211     tid=GetWizardThreadId();
00212     status=WriteFileChunk(file_info,&tid,sizeof(tid));
00213     if (close(file_info->file) == -1)
00214       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00215         "unable to close file `%s': %s",path,strerror(errno));
00216     file_info->file=(-1);
00217     if (status == WizardFalse)
00218       break;
00219     i--;
00220   }
00221   path=DestroyString(path);
00222   UnlockSemaphoreInfo(file_info->semaphore);
00223   return(WizardFalse);
00224 }
00225 
00226 /*
00227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %                                                                             %
00228 %                                                                             %
00229 %                                                                             %
00230 %   A c q u i r e F i l e I n f o                                             %
00231 %                                                                             %
00232 %                                                                             %
00233 %                                                                             %
00234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00235 %
00236 %  AcquireFileInfo() opens the file for reading or writing and returns a
00237 %  FileInfo structure.
00238 %
00239 %  The format of the AcquireFileInfo method is:
00240 %
00241 %      FileInfo *AcquireFileInfo(const char *path,const char *relative_path,
00242 %        const FileMode mode,ExceptionInfo *exception)
00243 %
00244 %  A description of each parameter follows:
00245 %
00246 %    o path: The file path.
00247 %
00248 %    o relative_path: The path relative to the default path.
00249 %
00250 %    o mode: The file I/O mode.
00251 %
00252 %    o exception: Return any errors or warnings in this structure.
00253 %
00254 */
00255 WizardExport FileInfo *AcquireFileInfo(const char *path,
00256   const char *relative_path,const FileMode mode,ExceptionInfo *exception)
00257 {
00258   char
00259     *home;
00260 
00261   FileInfo
00262     *file_info;
00263 
00264   /*
00265     Acquire file info.
00266   */
00267   assert(relative_path != (char *) NULL);
00268   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",relative_path);
00269   assert(exception != (ExceptionInfo *) NULL);
00270   file_info=(FileInfo *) AcquireAlignedMemory(1,sizeof(*file_info));
00271   if (file_info == (FileInfo *) NULL)
00272     {
00273       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00274         "memory allocation failed `%s'",strerror(errno));
00275       return((FileInfo *) NULL);
00276     }
00277   (void) ResetWizardMemory(file_info,0,sizeof(*file_info));
00278   file_info->path=AcquireString((char *) NULL);
00279   file_info->file=(-1);
00280   file_info->semaphore=AllocateSemaphoreInfo();
00281   file_info->timestamp=time((time_t *) NULL);
00282   file_info->signature=WizardSignature;
00283   if (path != (char *) NULL)
00284     (void) CopyWizardString(file_info->path,path,MaxTextExtent);
00285   else
00286     {
00287       /*
00288         Default location for key ring, random state, etc.
00289       */
00290       *file_info->path='\0';
00291       home=GetEnvironmentValue("WIZARD_HOME");
00292       if (home != (char *) NULL)
00293         {
00294           (void) CopyWizardString(file_info->path,home,MaxTextExtent);
00295           (void) ConcatenateWizardString(file_info->path,DirectorySeparator,
00296             MaxTextExtent);
00297           home=(char *) RelinquishWizardMemory(home);
00298         }
00299       else
00300         {
00301           home=GetEnvironmentValue("HOME");
00302           if (home == (char *) NULL)
00303             home=GetEnvironmentValue("USERPROFILE");
00304           if (home != (char *) NULL)
00305             {
00306               (void) CopyWizardString(file_info->path,home,MaxTextExtent);
00307               (void) ConcatenateWizardString(file_info->path,
00308                 DirectorySeparator,MaxTextExtent);
00309               (void) ConcatenateWizardString(file_info->path,".wizard",
00310                 MaxTextExtent);
00311 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00312               (void) mkdir(file_info->path);
00313 #else
00314               (void) mkdir(file_info->path,0700);
00315 #endif
00316               (void) ConcatenateWizardString(file_info->path,
00317                 DirectorySeparator,MaxTextExtent);
00318               home=(char *) RelinquishWizardMemory(home);
00319             }
00320         }
00321       (void) ConcatenateWizardString(file_info->path,relative_path,
00322         MaxTextExtent);
00323     }
00324   if (AcquireFileLock(file_info,exception) == WizardFalse)
00325     {
00326       file_info=DestroyFileInfo(file_info,exception);
00327       return((FileInfo *) NULL);
00328     }
00329   /*
00330     Open file.
00331   */
00332   switch (mode)
00333   {
00334     case ReadFileMode:
00335     {
00336       file_info->file=open(file_info->path,O_RDONLY | O_BINARY);
00337       break;
00338     }
00339     case WriteFileMode:
00340     {
00341       file_info->file=open(file_info->path,O_RDWR | O_CREAT | O_BINARY,
00342         S_MODE);
00343       break;
00344     }
00345     default:
00346     {
00347       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00348         "Invalid file mode `%s'",path);
00349       file_info=DestroyFileInfo(file_info,exception);
00350       return((FileInfo *) NULL);
00351     }
00352   }
00353   if (file_info->file < 0)
00354     {
00355       file_info=DestroyFileInfo(file_info,exception);
00356       return((FileInfo *) NULL);
00357     }
00358   (void) fstat(file_info->file,&file_info->properties);
00359   return(file_info);
00360 }
00361 
00362 /*
00363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00364 %                                                                             %
00365 %                                                                             %
00366 %                                                                             %
00367 %   D e s t r o y F i l e                                                     %
00368 %                                                                             %
00369 %                                                                             %
00370 %                                                                             %
00371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00372 %
00373 %  DestroyFile() destroys the file on disk.
00374 %
00375 %  The format of the DestroyFile method is:
00376 %
00377 %      WizardBooleanType DestroyFile(FileInfo *file_info,
00378 %        Exceptioninfo *exception)
00379 %
00380 %  A description of each parameter follows:
00381 %
00382 %    o file_info: The file info.
00383 %
00384 %    o exception: Return any errors or warnings in this structure.
00385 %
00386 */
00387 WizardExport WizardBooleanType DestroyFile(FileInfo *file_info,
00388   ExceptionInfo *exception)
00389 {
00390   if (file_info->file >= 0)
00391     if (close(file_info->file) == -1)
00392       {
00393         (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00394           "unable to close file `%s': %s",file_info->path,strerror(errno));
00395         return(WizardFalse);
00396       }
00397   file_info->file=(-1);
00398   if (remove(file_info->path) == -1)
00399     {
00400       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00401         "unable to close file `%s': %s",file_info->path,strerror(errno));
00402       return(WizardFalse);
00403     }
00404   return(WizardTrue);
00405 }
00406 
00407 /*
00408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00409 %                                                                             %
00410 %                                                                             %
00411 %                                                                             %
00412 %   D e s t r o y F i l e I n f o                                             %
00413 %                                                                             %
00414 %                                                                             %
00415 %                                                                             %
00416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00417 %
00418 %  DestroyFileInfo() destroys the file info structure.
00419 %
00420 %  The format of the DestroyFileInfo method is:
00421 %
00422 %      FileInfo *DestroyFileInfo(FileInfo *file_info)
00423 %
00424 %  A description of each parameter follows:
00425 %
00426 %    o path: The file name.
00427 %
00428 */
00429 WizardExport FileInfo *DestroyFileInfo(FileInfo *file_info,
00430   ExceptionInfo *exception)
00431 {
00432   assert(file_info != (FileInfo *) NULL);
00433   assert(file_info->signature == WizardSignature);
00434   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",file_info->path);
00435   LockSemaphoreInfo(file_info->semaphore);
00436   if (file_info->file >= 0)
00437     if (close(file_info->file) == -1)
00438       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00439         "unable to close file `%s': %s",file_info->path,strerror(errno));
00440   file_info->file=(-1);
00441   (void) RelinquishFileLock(file_info,exception);
00442   if (file_info->path != (char *) NULL)
00443     file_info->path=DestroyString(file_info->path);
00444   file_info->signature=(~WizardSignature);
00445   UnlockSemaphoreInfo(file_info->semaphore);
00446   DestroySemaphoreInfo(&file_info->semaphore);
00447   file_info=(FileInfo *) RelinquishWizardMemory(file_info);
00448   return(file_info);
00449 }
00450 
00451 /*
00452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00453 %                                                                             %
00454 %                                                                             %
00455 %                                                                             %
00456 %   G e t F i l e D e s c r i p t o r                                         %
00457 %                                                                             %
00458 %                                                                             %
00459 %                                                                             %
00460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00461 %
00462 %  GetFileDescriptor() returns the file descriptor.
00463 %
00464 %  The format of the GetFileDescriptor method is:
00465 %
00466 %      int GetFileDescriptor(const FileInfo *file_info)
00467 %
00468 %  A description of each parameter follows:
00469 %
00470 %    o file_info: The file info.
00471 %
00472 */
00473 WizardExport int GetFileDescriptor(const FileInfo *file_info)
00474 {
00475   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00476   assert(file_info != (FileInfo *) NULL);
00477   assert(file_info->signature == WizardSignature);
00478   return(file_info->file);
00479 }
00480 
00481 /*
00482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00483 %                                                                             %
00484 %                                                                             %
00485 %                                                                             %
00486 %   G e t F i l e P a t h                                                     %
00487 %                                                                             %
00488 %                                                                             %
00489 %                                                                             %
00490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00491 %
00492 %  GetFilePath() returns the file path.
00493 %
00494 %  The format of the GetFilePath method is:
00495 %
00496 %      const const char *GetFilePath(const FileInfo *file_info)
00497 %
00498 %  A description of each parameter follows:
00499 %
00500 %    o file_info: The file info.
00501 %
00502 */
00503 WizardExport const char *GetFilePath(const FileInfo *file_info)
00504 {
00505   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00506   assert(file_info != (FileInfo *) NULL);
00507   assert(file_info->signature == WizardSignature);
00508   return(file_info->path);
00509 }
00510 
00511 /*
00512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00513 %                                                                             %
00514 %                                                                             %
00515 %                                                                             %
00516 %   G e t F i l e P r o p e r t i e s                                         %
00517 %                                                                             %
00518 %                                                                             %
00519 %                                                                             %
00520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00521 %
00522 %  GetFileproperties() returns the file properties.
00523 %
00524 %  The format of the GetFileProperties method is:
00525 %
00526 %      const struct stat *GetFileProperties(const FileInfo *file_info)
00527 %
00528 %  A description of each parameter follows:
00529 %
00530 %    o file_info: The file info.
00531 %
00532 */
00533 WizardExport const struct stat *GetFileProperties(const FileInfo *file_info)
00534 {
00535   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00536   assert(file_info != (FileInfo *) NULL);
00537   assert(file_info->signature == WizardSignature);
00538   return(&file_info->properties);
00539 }
00540 
00541 /*
00542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00543 %                                                                             %
00544 %                                                                             %
00545 %                                                                             %
00546 %  R e a d F i l e B y t e                                                    %
00547 %                                                                             %
00548 %                                                                             %
00549 %                                                                             %
00550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00551 %
00552 %  ReadFileByte() returns the character read as an unsigned char cast to an
00553 %  integer or EOF on end of file or error.
00554 %
00555 %  The format of the ReadFileByte method is:
00556 %
00557 %      int ReadFileByte(FileInfo *file_info)
00558 %
00559 %  A description of each parameter follows.
00560 %
00561 %    o file_info: the blob info.
00562 %
00563 */
00564 WizardExport int ReadFileByte(FileInfo *file_info)
00565 {
00566   unsigned char
00567     buffer[1];
00568 
00569   assert(file_info != (FileInfo *) NULL);
00570   assert(file_info->signature == WizardSignature);
00571   if (ReadFileChunk(file_info,buffer,1) == WizardFalse)
00572     return(EOF);
00573   return((int) (*buffer));
00574 }
00575 
00576 /*
00577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00578 %                                                                             %
00579 %                                                                             %
00580 %                                                                             %
00581 %   R e a d F i l e C h u n k                                                 %
00582 %                                                                             %
00583 %                                                                             %
00584 %                                                                             %
00585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00586 %
00587 %  ReadFileChunk() reliably reads a chunk of data from a file.  It returns
00588 %  WizardTrue if all the data requested is read otherwise WizardFalse.
00589 %
00590 %  The format of the ReadFileChunk method is:
00591 %
00592 %      WizardBooleanType ReadFileChunk(FileInfo *file_info,const void *data,
00593 %        const size_t length)
00594 %
00595 %  A description of each parameter follows:
00596 %
00597 %    o file_info: The file info.
00598 %
00599 %    o data: The data.
00600 %
00601 %    o length: The data length in bytes.
00602 %
00603 */
00604 WizardExport WizardBooleanType ReadFileChunk(FileInfo *file_info,void *data,
00605   const size_t length)
00606 {
00607   register ssize_t
00608     i;
00609 
00610   ssize_t
00611     count;
00612 
00613   assert(file_info != (FileInfo *) NULL);
00614   assert(file_info->signature == WizardSignature);
00615   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",file_info->path);
00616   for (i=0; i < (ssize_t) length; i+=count)
00617   {
00618     count=read(file_info->file,(unsigned char *) data+i,Min(length-i,(size_t)
00619       WizardMaxBufferExtent));
00620     if (count <= 0)
00621       {
00622         count=0;
00623         if (errno != EINTR)
00624           break;
00625       }
00626   }
00627   if (i < (ssize_t) length)
00628     return(WizardFalse);
00629   return(WizardTrue);
00630 }
00631 
00632 /*
00633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00634 %                                                                             %
00635 %                                                                             %
00636 %                                                                             %
00637 %  R e a d F i l e 1 6 B i t s                                                %
00638 %                                                                             %
00639 %                                                                             %
00640 %                                                                             %
00641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00642 %
00643 %  ReadFile16Bits() reads a 16-bit quantity in least-significant byte first
00644 %  order and returns it.
00645 %
00646 %  The format of the ReadFile16Bits method is:
00647 %
00648 %      WizardBooleanType ReadFile16Bits(FileInfo *file_info,
00649 %        unsigned short *value)
00650 %
00651 %  A description of each parameter follows.
00652 %
00653 %    o file_info: The image.
00654 %
00655 %    o value: The value.
00656 %
00657 */
00658 WizardExport WizardBooleanType ReadFile16Bits(FileInfo *file_info,
00659   unsigned short *value)
00660 {
00661   WizardBooleanType
00662     status;
00663 
00664   unsigned char
00665     buffer[2];
00666 
00667   assert(file_info != (FileInfo *) NULL);
00668   assert(file_info->signature == WizardSignature);
00669   *buffer=(unsigned char) '\0';
00670   status=ReadFileChunk(file_info,buffer,sizeof(buffer));
00671   if (status == WizardFalse)
00672     return(status);
00673   *value=(unsigned short) (buffer[1] << 8);
00674   *value|=(unsigned short) buffer[0];
00675   return(status);
00676 }
00677 
00678 /*
00679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00680 %                                                                             %
00681 %                                                                             %
00682 %                                                                             %
00683 %  R e a d F i l e 3 2 B i t s                                                %
00684 %                                                                             %
00685 %                                                                             %
00686 %                                                                             %
00687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00688 %
00689 %  ReadFile32Bits() reads a 32-bit quantity in least-significant byte first
00690 %  order and returns it.
00691 %
00692 %  The format of the ReadFile32Bits method is:
00693 %
00694 %      WizardBooleanType ReadFile32Bits(FileInfo *file_info,
00695 %        size_t *value)
00696 %
00697 %  A description of each parameter follows.
00698 %
00699 %    o file_info: The image.
00700 %
00701 %    o value: The value.
00702 %
00703 */
00704 WizardExport WizardBooleanType ReadFile32Bits(FileInfo *file_info,
00705   size_t *value)
00706 {
00707   WizardBooleanType
00708     status;
00709 
00710   unsigned char
00711     buffer[4];
00712 
00713   assert(file_info != (FileInfo *) NULL);
00714   assert(file_info->signature == WizardSignature);
00715   *buffer=(unsigned char) '\0';
00716   status=ReadFileChunk(file_info,buffer,sizeof(buffer));
00717   if (status == WizardFalse)
00718     return(status);
00719   *value=((size_t) buffer[3]) << 24;
00720   *value|=((size_t) buffer[2]) << 16;
00721   *value|=((size_t) buffer[1]) << 8;
00722   *value|=((size_t) buffer[0]);
00723   return(status);
00724 }
00725 
00726 /*
00727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00728 %                                                                             %
00729 %                                                                             %
00730 %                                                                             %
00731 %  R e a d F i l e 6 4 B i t s                                                %
00732 %                                                                             %
00733 %                                                                             %
00734 %                                                                             %
00735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00736 %
00737 %  ReadFile64Bits() reads a 64-bit quantity in least-significant byte first
00738 %  order and returns it.
00739 %
00740 %  The format of the ReadFile64Bits method is:
00741 %
00742 %      WizardBooleanType ReadFile64Bits(FileInfo *file_info,
00743 %        WizardSizeType *value)
00744 %
00745 %  A description of each parameter follows.
00746 %
00747 %    o file_info: The image.
00748 %
00749 %    o value: The value.
00750 %
00751 */
00752 WizardExport WizardBooleanType ReadFile64Bits(FileInfo *file_info,
00753   WizardSizeType *value)
00754 {
00755   WizardBooleanType
00756     status;
00757 
00758   unsigned char
00759     buffer[8];
00760 
00761   assert(file_info != (FileInfo *) NULL);
00762   assert(file_info->signature == WizardSignature);
00763   *buffer=(unsigned char) '\0';
00764   status=ReadFileChunk(file_info,buffer,sizeof(buffer));
00765   if (status == WizardFalse)
00766     return(status);
00767   *value=((WizardSizeType) buffer[7]) << 56;
00768   *value|=((WizardSizeType) buffer[6]) << 48;
00769   *value|=((WizardSizeType) buffer[5]) << 40;
00770   *value|=((WizardSizeType) buffer[4]) << 32;
00771   *value|=((WizardSizeType) buffer[3]) << 24;
00772   *value|=((WizardSizeType) buffer[2]) << 16;
00773   *value|=((WizardSizeType) buffer[1]) << 8;
00774   *value|=(WizardSizeType) buffer[0];
00775   return(status);
00776 }
00777 
00778 /*
00779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00780 %                                                                             %
00781 %                                                                             %
00782 %                                                                             %
00783 %   R e l i n q u i s h F i l e L o c k                                       %
00784 %                                                                             %
00785 %                                                                             %
00786 %                                                                             %
00787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00788 %
00789 %  RelinquishFileLock() relinquishes a file lock.
00790 %
00791 %  The format of the RelinquishFileLock method is:
00792 %
00793 %      WizardBooleanType RelinquishFileLock(FileInfo *file_info,
00794 %        ExceptionInfo *exception)
00795 %
00796 %  A description of each parameter follows:
00797 %
00798 %    o file_info: The file info.
00799 %
00800 %    o exception: Return any errors or warnings in this structure.
00801 %
00802 */
00803 static WizardBooleanType RelinquishFileLock(FileInfo *file_info,
00804   ExceptionInfo *exception)
00805 {
00806   char
00807     *path;
00808 
00809   path=AcquireString(file_info->path);
00810   AppendFileExtension("lck",path);
00811   if (remove(path) == -1)
00812     {
00813       (void) ThrowWizardException(exception,GetWizardModule(),FileError,
00814         "unable to remove file `%s': %s",path,strerror(errno));
00815       path=DestroyString(path);
00816       return(WizardFalse);
00817     }
00818   path=DestroyString(path);
00819   return(WizardTrue);
00820 }
00821 
00822 /*
00823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00824 %                                                                             %
00825 %                                                                             %
00826 %                                                                             %
00827 %   W r i t e F i l e C h u n k                                               %
00828 %                                                                             %
00829 %                                                                             %
00830 %                                                                             %
00831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00832 %
00833 %  WriteFileChunk() reliably writes data to a file.
00834 %
00835 %  The format of the WriteFileChunk method is:
00836 %
00837 %      WizardBooleanType WriteFileChunk(FileInfo *file_info,const void *data,
00838 %        const size_t length)
00839 %
00840 %  A description of each parameter follows:
00841 %
00842 %    o file_info: The file info.
00843 %
00844 %    o data: The data.
00845 %
00846 %    o lenth: The data length in bytes.
00847 %
00848 */
00849 WizardExport WizardBooleanType WriteFileChunk(FileInfo *file_info,
00850   const void *data,const size_t length)
00851 {
00852   register ssize_t
00853     i;
00854 
00855   ssize_t
00856     count;
00857 
00858   assert(file_info != (FileInfo *) NULL);
00859   assert(file_info->signature == WizardSignature);
00860   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",file_info->path);
00861   for (i=0; i < (ssize_t) length; i+=count)
00862   {
00863     count=write(file_info->file,(unsigned char *) data+i,length-i);
00864     if (count <= 0)
00865       {
00866         count=0;
00867         if (errno != EINTR)
00868           break;
00869       }
00870   }
00871   if (i < (ssize_t) length)
00872     return(WizardFalse);
00873   return(WizardTrue);
00874 }
00875 
00876 /*
00877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00878 %                                                                             %
00879 %                                                                             %
00880 %                                                                             %
00881 %  W r i t e F i l e 1 6 B i t s                                              %
00882 %                                                                             %
00883 %                                                                             %
00884 %                                                                             %
00885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00886 %
00887 %  WriteFile16Bits() writes a ssize_t value as a 16-bit quantity in
00888 %  least-significant byte first order.
00889 %
00890 %  The format of the WriteFile16Bits method is:
00891 %
00892 %      WizardBooleanType WriteFile16Bits(FileInfo *file_info,
00893 %        const unsigned short value)
00894 %
00895 %  A description of each parameter follows.
00896 %
00897 %    o value:  Specifies the value to write.
00898 %
00899 %    o file_info: The image.
00900 %
00901 */
00902 WizardExport WizardBooleanType WriteFile16Bits(FileInfo *file_info,
00903   const unsigned short value)
00904 {
00905   unsigned char
00906     buffer[2];
00907 
00908   assert(file_info != (FileInfo *) NULL);
00909   assert(file_info->signature == WizardSignature);
00910   buffer[0]=(unsigned char) value;
00911   buffer[1]=(unsigned char) (value >> 8);
00912   return(WriteFileChunk(file_info,buffer,sizeof(buffer)));
00913 }
00914 
00915 /*
00916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00917 %                                                                             %
00918 %                                                                             %
00919 %                                                                             %
00920 %  W r i t e F i l e 3 2 B i t s                                              %
00921 %                                                                             %
00922 %                                                                             %
00923 %                                                                             %
00924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00925 %
00926 %  WriteFile32Bits() writes a ssize_t value as a 32-bit quantity in
00927 %  least-significant byte first order.
00928 %
00929 %  The format of the WriteFile32Bits method is:
00930 %
00931 %      WizardBooleanType WriteFile32Bits(FileInfo *file_info,
00932 %        const size_t value)
00933 %
00934 %  A description of each parameter follows.
00935 %
00936 %    o value:  Specifies the value to write.
00937 %
00938 %    o file_info: The image.
00939 %
00940 */
00941 WizardExport WizardBooleanType WriteFile32Bits(FileInfo *file_info,
00942   const size_t value)
00943 {
00944   unsigned char
00945     buffer[4];
00946 
00947   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00948   assert(file_info != (FileInfo *) NULL);
00949   buffer[0]=(unsigned char) value;
00950   buffer[1]=(unsigned char) (value >> 8);
00951   buffer[2]=(unsigned char) (value >> 16);
00952   buffer[3]=(unsigned char) (value >> 24);
00953   return(WriteFileChunk(file_info,buffer,sizeof(buffer)));
00954 }
00955 
00956 /*
00957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00958 %                                                                             %
00959 %                                                                             %
00960 %                                                                             %
00961 %  W r i t e F i l e 6 4 B i t s                                              %
00962 %                                                                             %
00963 %                                                                             %
00964 %                                                                             %
00965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00966 %
00967 %  WriteFile64Bits() writes a ssize_t value as a 64-bit quantity in
00968 %  least-significant byte first order.
00969 %
00970 %  The format of the WriteFile64Bits method is:
00971 %
00972 %      WizardBooleanType WriteFile64Bits(FileInfo *file_info,
00973 %        const WizardSizeType value)
00974 %
00975 %  A description of each parameter follows.
00976 %
00977 %    o value:  Specifies the value to write.
00978 %
00979 %    o file_info: The image.
00980 %
00981 */
00982 WizardExport WizardBooleanType WriteFile64Bits(FileInfo *file_info,
00983   const WizardSizeType value)
00984 {
00985   unsigned char
00986     buffer[8];
00987 
00988   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00989   assert(file_info != (FileInfo *) NULL);
00990   buffer[0]=(unsigned char) value;
00991   buffer[1]=(unsigned char) (value >> 8);
00992   buffer[2]=(unsigned char) (value >> 16);
00993   buffer[3]=(unsigned char) (value >> 24);
00994   buffer[4]=(unsigned char) (value >> 32);
00995   buffer[5]=(unsigned char) (value >> 40);
00996   buffer[6]=(unsigned char) (value >> 48);
00997   buffer[7]=(unsigned char) (value >> 56);
00998   return(WriteFileChunk(file_info,buffer,sizeof(buffer)));
00999 }
Generated by  doxygen 1.6.2-20100208