root/source3/lib/util_transfer_file.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. transfer_file_internal
  2. sys_read_fn
  3. sys_write_fn
  4. transfer_file

   1 /*
   2  * Unix SMB/CIFS implementation.
   3  * Utility functions to transfer files.
   4  *
   5  * Copyright (C) Jeremy Allison 2001-2002
   6  * Copyright (C) Michael Adam 2008
   7  *
   8  * This program is free software; you can redistribute it and/or modify
   9  * it under the terms of the GNU General Public License as published by
  10  * the Free Software Foundation; either version 3 of the License, or
  11  * (at your option) any later version.
  12  *
  13  * This program is distributed in the hope that it will be useful,
  14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  * GNU General Public License for more details.
  17  *
  18  * You should have received a copy of the GNU General Public License
  19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20  */
  21 
  22 
  23 #include <includes.h>
  24 
  25 /****************************************************************************
  26  Transfer some data between two fd's.
  27 ****************************************************************************/
  28 
  29 #ifndef TRANSFER_BUF_SIZE
  30 #define TRANSFER_BUF_SIZE 65536
  31 #endif
  32 
  33 
  34 ssize_t transfer_file_internal(void *in_file,
     /* [<][>][^][v][top][bottom][index][help] */
  35                                void *out_file,
  36                                size_t n,
  37                                ssize_t (*read_fn)(void *, void *, size_t),
  38                                ssize_t (*write_fn)(void *, const void *, size_t))
  39 {
  40         char *buf;
  41         size_t total = 0;
  42         ssize_t read_ret;
  43         ssize_t write_ret;
  44         size_t num_to_read_thistime;
  45         size_t num_written = 0;
  46 
  47         if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) {
  48                 return -1;
  49         }
  50 
  51         while (total < n) {
  52                 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
  53 
  54                 read_ret = (*read_fn)(in_file, buf, num_to_read_thistime);
  55                 if (read_ret == -1) {
  56                         DEBUG(0,("transfer_file_internal: read failure. "
  57                                  "Error = %s\n", strerror(errno) ));
  58                         SAFE_FREE(buf);
  59                         return -1;
  60                 }
  61                 if (read_ret == 0) {
  62                         break;
  63                 }
  64 
  65                 num_written = 0;
  66 
  67                 while (num_written < read_ret) {
  68                         write_ret = (*write_fn)(out_file, buf + num_written,
  69                                                 read_ret - num_written);
  70 
  71                         if (write_ret == -1) {
  72                                 DEBUG(0,("transfer_file_internal: "
  73                                          "write failure. Error = %s\n",
  74                                          strerror(errno) ));
  75                                 SAFE_FREE(buf);
  76                                 return -1;
  77                         }
  78                         if (write_ret == 0) {
  79                                 return (ssize_t)total;
  80                         }
  81 
  82                         num_written += (size_t)write_ret;
  83                 }
  84 
  85                 total += (size_t)read_ret;
  86         }
  87 
  88         SAFE_FREE(buf);
  89         return (ssize_t)total;
  90 }
  91 
  92 static ssize_t sys_read_fn(void *file, void *buf, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
  93 {
  94         int *fd = (int *)file;
  95 
  96         return sys_read(*fd, buf, len);
  97 }
  98 
  99 static ssize_t sys_write_fn(void *file, const void *buf, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101         int *fd = (int *)file;
 102 
 103         return sys_write(*fd, buf, len);
 104 }
 105 
 106 SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n)
     /* [<][>][^][v][top][bottom][index][help] */
 107 {
 108         return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n,
 109                                                  sys_read_fn, sys_write_fn);
 110 }

/* [<][>][^][v][top][bottom][index][help] */