home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / utilslib / c / Frename < prev    next >
Encoding:
Text File  |  1991-04-21  |  2.5 KB  |  108 lines

  1. /* C.Frename: safe file rename which works across file systems */
  2.  
  3. #include <stdio.h>
  4. #include "kernel.h"
  5.  
  6. #include "utils.h"
  7.  
  8. /* Rename a file. If a simple OS rename fails, the file is copied.
  9.  * This allows renames across filing system boundaries.
  10.  * If the destination filename exists, the function deletes it (even
  11.  * if locked) first.
  12.  * This function does its best to be totally paranoid about errors, and
  13.  * returns failure if the rename does not work.
  14.  * Returns 0 on success, 1 on failure.
  15.  */
  16. int frename(const char *old, const char *new)
  17. {
  18.     register int result;
  19.     register int n;
  20.     FILE *in, *out;
  21.     _kernel_osfile_block blk;
  22.     char buf[BUFSIZ];
  23.  
  24.     /* Check the new file. If it exists, and is not a directory,
  25.      * unlock it (if necessary) and delete it.
  26.      */
  27.     result = _kernel_osfile (17, new, &blk);
  28.  
  29.     /* If the file is a directory, or an error occurred, return failure */
  30.     if (result == 2 || result == _kernel_ERROR)
  31.         return 1;
  32.  
  33.     /* If the file exists and is locked, unlock it */
  34.     if (result == 1 && (blk.end & 0x0008) != 0)
  35.     {
  36.         blk.end &= ~0x0008;
  37.         if (_kernel_osfile(4, new, &blk) == _kernel_ERROR)
  38.             return 1;
  39.     }
  40.  
  41.     /* If the file exists, delete it */
  42.     if (result == 1 && _kernel_osfile(6, new, &blk) == _kernel_ERROR)
  43.         return 1;
  44.  
  45.     /* Now try a simple OS rename */
  46.     if (rename(old, new) == 0)
  47.         return 0;
  48.  
  49.     /* No luck. Get the old file attributes (to ensure that it exists,
  50.      * and is not locked, and for later copying to the new file).
  51.      */
  52.     result = _kernel_osfile (17, old, &blk);
  53.  
  54.     /* If the file is not a simple file, or an error occurred,
  55.      * or the file is locked, return failure.
  56.      */
  57.     if (result != 1 || (blk.end & 0x0008) != 0)
  58.         return 1;
  59.     
  60.     /* Now prepare to copy the file */
  61.     if ((in = fopen(old, "rb")) == NULL)
  62.         return 1;
  63.  
  64.     if ((out = fopen(new, "wb")) == NULL)
  65.     {
  66.         fclose(in);
  67.         return 1;
  68.     }
  69.  
  70.     /* Copy the file */
  71.     while (!feof(in))
  72.     {
  73.         n = fread(buf, 1, BUFSIZ, in);
  74.         if (ferror(in) || fwrite(buf, 1, n, out) != n)
  75.         {
  76.             fclose(in);
  77.             fclose(out);
  78.             remove(new);
  79.             return 1;
  80.         }
  81.     }
  82.  
  83.     if (ferror(in) || fclose(in) == EOF || ferror(out) || fclose(out) == EOF)
  84.     {
  85.         remove(new);
  86.         return 1;
  87.     }
  88.  
  89.     /* Copy the file attributes across */
  90.     if (_kernel_osfile(1, new, &blk) == _kernel_ERROR)
  91.     {
  92.         remove(new);
  93.         return 1;
  94.     }
  95.  
  96.     /* Delete the old file. The most likely case of error here
  97.      * is renaming an open file. We left it a bit late to catch
  98.      * this one, but we can't find out any earlier...
  99.      */
  100.     if (_kernel_osfile(6, old, &blk) == _kernel_ERROR)
  101.     {
  102.         remove(new);
  103.         return 1;
  104.     }
  105.  
  106.     return 0;
  107. }
  108.