home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_07 / 1007086a < prev    next >
Text File  |  1992-05-05  |  3KB  |  124 lines

  1.  
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6.  
  7. static int copy_files ();
  8. static long file_len ();
  9. static int do_copy ();
  10. long atol ();
  11.  
  12. #define SIZE_BUFFER 1024
  13. #define OK 0
  14. #define NOT_OK -1
  15. #define min(a,b)  ((a)<(b)?a:b)
  16. #define IFTESTING
  17. #ifdef IFTESTING
  18. /*
  19.  * To test the code compile with parameter -DTESTING and execute
  20.  * a.out filename newlength
  21.  */
  22.  
  23. main (int argc, char **argv)
  24.    {
  25.      printf ("%2d", truncate_file (argv[1], atol (argv[2])));
  26.    }
  27. #endif
  28.  
  29. truncate_file(char *path, long len)
  30.    {
  31.      int infile, tmp_file;    /* input file */
  32.      int ret = 0;
  33.      char tf_name[L_tmpnam];
  34.        if (len < 0)
  35.            ret = -10;
  36.        else if (len == 0)
  37.            ret = truncate_to_zero (path);
  38.        else if ((infile = open(path, O_RDONLY, 0)) < 0)
  39.            ret = -1;
  40.        else if (file_len (infile) <= len)
  41.            {
  42.            close (infile);
  43.            ret = -3;
  44.            }
  45.        else
  46.            {
  47.            tmpnam (tf_name);
  48.            tmp_file = open (tf_name, O_RDWR | O_CREAT, 0666);
  49.            ret = copy_file (infile, tmp_file, path, len);
  50.            unlink (tf_name);
  51.            }
  52.        return ret;
  53.    }
  54. /*
  55.  * file_len () returns the length of file, in bytes
  56.  */
  57.  
  58. static long file_len (infile)
  59.    {
  60.    struct stat file_status;
  61.  
  62.    fstat (infile, &file_status);
  63.    return file_status.st_size;
  64.    }
  65.  
  66.  /*
  67.  * copy_file () copies in_file to tmp_file then back to 
  68.  * in_file, truncating to len bytes in the process
  69.  */
  70.  
  71. copy_file (int infile, int tmp_file, char *path, long len)
  72.     {
  73.      int ret = 0;
  74.      if ((ret = do_copy (infile, tmp_file, len)) == 0)
  75.           {
  76.           close (infile);
  77.           lseek (tmp_file, 0L, SEEK_SET);
  78.           if (( infile = open (path, O_WRONLY | O_TRUNC, 0666)) < 0)
  79.                ret = -12;
  80.           else
  81.                ret = do_copy (tmp_file, infile, len);
  82.           }
  83.      return ret;
  84.    }
  85. /*
  86.  * do_copy () copies len bytes from infile to tmp_file
  87.  */
  88. static int do_copy (int infile, int tmp_file, long len)
  89.    {
  90.      int to_read, to_write, ret = 0;
  91.      char buffer [SIZE_BUFFER];
  92.  
  93.      do
  94.           {
  95.           to_read = (int) (min ((long) SIZE_BUFFER, len)); 
  96.           if ((to_write = read (infile, buffer, to_read)) < to_read)
  97.                {
  98.                ret = -4;
  99.                break;
  100.                }
  101.           if (write (tmp_file, buffer, to_write) < to_write) 
  102.                {
  103.                ret = -5;
  104.                break;
  105.                }
  106.          } while (len -= to_write);
  107.      return ret;
  108.    }
  109. /*
  110.  * truncate_to_zero () opens the file *path with the 
  111.  * option O_Trunc.
  112.  */
  113. truncate_to_zero (char *path)
  114.    {
  115.      int ret = OK;
  116.      int fd = open (path, O_WRONLY | O_TRUNC, 0666);
  117.  
  118.      if (fd < 0)
  119.           ret = NOT_OK;
  120.      close (fd);
  121.      return ret;
  122.    }
  123.  
  124.