"Fossies" - the Fresh Open Source Software Archive

Member "ftwin-master/src/ft_file.c" (15 Feb 2015, 7550 Bytes) of package /linux/privat/ftwin-master.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  *
    3  * Copyright (C) 2007 Fran├žois Pesce : francois.pesce (at) gmail (dot) com
    4  *
    5  * Licensed under the Apache License, Version 2.0 (the "License");
    6  * you may not use this file except in compliance with the License.
    7  * You may obtain a copy of the License at
    8  * 
    9  *  http://www.apache.org/licenses/LICENSE-2.0
   10  * 
   11  * Unless required by applicable law or agreed to in writing, software
   12  * distributed under the License is distributed on an "AS IS" BASIS,
   13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14  * See the License for the specific language governing permissions and
   15  * limitations under the License.
   16  */
   17 
   18 #include <apr_file_io.h>
   19 #include <apr_mmap.h>
   20 
   21 #include "checksum.h"
   22 #include "debug.h"
   23 #include "ft_file.h"
   24 
   25 static apr_status_t checksum_big_file(const char *filename, apr_off_t size, apr_uint32_t *state, apr_pool_t *gc_pool);
   26 static apr_status_t big_filecmp(apr_pool_t *pool, const char *fname1, const char *fname2, apr_off_t size, int *i);
   27 
   28 /*#define HUGE_LEN 8192*/
   29 #define HUGE_LEN 4096
   30 
   31 static apr_status_t checksum_small_file(const char *filename, apr_off_t size, apr_uint32_t *state, apr_pool_t *gc_pool)
   32 {
   33     char errbuf[128];
   34     apr_file_t *fd = NULL;
   35     apr_mmap_t *mm;
   36     apr_status_t status;
   37     apr_uint32_t i;
   38     apr_off_t rbytes;
   39 
   40     status = apr_file_open(&fd, filename, APR_READ | APR_BINARY, APR_OS_DEFAULT, gc_pool);
   41     if (APR_SUCCESS != status) {
   42     return status;
   43     }
   44 
   45     status = apr_mmap_create(&mm, fd, 0, (apr_size_t) size, APR_MMAP_READ, gc_pool);
   46     if (APR_SUCCESS != status) {
   47     apr_file_close(fd);
   48     return checksum_big_file(filename, size, state, gc_pool);
   49     }
   50 
   51     for (i = 0; i < HASHSTATE; ++i)
   52     state[i] = 1;
   53 
   54     rbytes = 0;
   55     do {
   56     hash(mm->mm + rbytes, FTWIN_MIN(HUGE_LEN, size), state);
   57     rbytes += FTWIN_MIN(HUGE_LEN, size);
   58     size -= HUGE_LEN;
   59     } while (size > 0);
   60 
   61     if (APR_SUCCESS != (status = apr_mmap_delete(mm))) {
   62     DEBUG_ERR("error calling apr_mmap_delete: %s", apr_strerror(status, errbuf, 128));
   63     apr_file_close(fd);
   64     return status;
   65     }
   66     if (APR_SUCCESS != (status = apr_file_close(fd))) {
   67     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status, errbuf, 128));
   68     return status;
   69     }
   70 
   71     return APR_SUCCESS;
   72 }
   73 
   74 static apr_status_t checksum_big_file(const char *filename, apr_off_t size, apr_uint32_t *state, apr_pool_t *gc_pool)
   75 {
   76     unsigned char data_chunk[HUGE_LEN];
   77     char errbuf[128];
   78     apr_size_t rbytes;
   79     apr_file_t *fd = NULL;
   80     apr_status_t status;
   81     apr_uint32_t i;
   82 
   83     status = apr_file_open(&fd, filename, APR_READ | APR_BINARY, APR_OS_DEFAULT, gc_pool);
   84     if (APR_SUCCESS != status) {
   85     return status;
   86     }
   87 
   88     for (i = 0; i < HASHSTATE; ++i)
   89     state[i] = 1;
   90 
   91     do {
   92     rbytes = HUGE_LEN;
   93     status = apr_file_read(fd, data_chunk, &rbytes);
   94     if (APR_SUCCESS == status) {
   95         hash(data_chunk, rbytes, state);
   96     }
   97     } while (APR_SUCCESS == status);
   98     if (APR_EOF != status) {
   99     DEBUG_ERR("unable to read(%s, O_RDONLY), skipping: %s", filename, apr_strerror(status, errbuf, 128));
  100     apr_file_close(fd);
  101     return status;
  102     }
  103 
  104     if (APR_SUCCESS != (status = apr_file_close(fd))) {
  105     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status, errbuf, 128));
  106     return status;
  107     }
  108 
  109     return APR_SUCCESS;
  110 }
  111 
  112 extern apr_status_t checksum_file(const char *filename, apr_off_t size, apr_off_t excess_size, apr_uint32_t *state,
  113                   apr_pool_t *gc_pool)
  114 {
  115     if (size < excess_size)
  116     return checksum_small_file(filename, size, state, gc_pool);
  117 
  118     return checksum_big_file(filename, size, state, gc_pool);
  119 }
  120 
  121 static apr_status_t small_filecmp(apr_pool_t *pool, const char *fname1, const char *fname2, apr_off_t size, int *i)
  122 {
  123     char errbuf[128];
  124     apr_file_t *fd1 = NULL, *fd2 = NULL;
  125     apr_mmap_t *mm1, *mm2;
  126     apr_status_t status;
  127 
  128     if (0 == size) {
  129     *i = 0;
  130     return APR_SUCCESS;
  131     }
  132 
  133     status = apr_file_open(&fd1, fname1, APR_READ | APR_BINARY, APR_OS_DEFAULT, pool);
  134     if (APR_SUCCESS != status) {
  135     return status;
  136     }
  137 
  138     status = apr_mmap_create(&mm1, fd1, 0, (apr_size_t) size, APR_MMAP_READ, pool);
  139     if (APR_SUCCESS != status) {
  140     apr_file_close(fd1);
  141     return big_filecmp(pool, fname1, fname2, size, i);
  142     }
  143 
  144     status = apr_file_open(&fd2, fname2, APR_READ | APR_BINARY, APR_OS_DEFAULT, pool);
  145     if (APR_SUCCESS != status) {
  146     apr_mmap_delete(mm1);
  147     apr_file_close(fd1);
  148     return status;
  149     }
  150 
  151     status = apr_mmap_create(&mm2, fd2, 0, size, APR_MMAP_READ, pool);
  152     if (APR_SUCCESS != status) {
  153     apr_file_close(fd2);
  154     apr_mmap_delete(mm1);
  155     apr_file_close(fd1);
  156     return big_filecmp(pool, fname1, fname2, size, i);
  157     }
  158 
  159     *i = memcmp(mm1->mm, mm2->mm, size);
  160 
  161     if (APR_SUCCESS != (status = apr_mmap_delete(mm2))) {
  162     DEBUG_ERR("error calling apr_mmap_delete: %s", apr_strerror(status, errbuf, 128));
  163     apr_file_close(fd2);
  164     apr_mmap_delete(mm1);
  165     apr_file_close(fd1);
  166     return status;
  167     }
  168     if (APR_SUCCESS != (status = apr_file_close(fd2))) {
  169     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status, errbuf, 128));
  170     apr_mmap_delete(mm1);
  171     apr_file_close(fd1);
  172     return status;
  173     }
  174 
  175     if (APR_SUCCESS != (status = apr_mmap_delete(mm1))) {
  176     DEBUG_ERR("error calling apr_mmap_delete: %s", apr_strerror(status, errbuf, 128));
  177     apr_file_close(fd1);
  178     return status;
  179     }
  180     if (APR_SUCCESS != (status = apr_file_close(fd1))) {
  181     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status, errbuf, 128));
  182     return status;
  183     }
  184 
  185     return APR_SUCCESS;
  186 }
  187 
  188 static apr_status_t big_filecmp(apr_pool_t *pool, const char *fname1, const char *fname2, apr_off_t size, int *i)
  189 {
  190     unsigned char data_chunk1[HUGE_LEN], data_chunk2[HUGE_LEN];
  191     char errbuf[128];
  192     apr_size_t rbytes1, rbytes2;
  193     apr_file_t *fd1 = NULL, *fd2 = NULL;
  194     apr_status_t status1, status2;
  195 
  196     if (0 == size) {
  197     *i = 0;
  198     return APR_SUCCESS;
  199     }
  200 
  201     status1 = apr_file_open(&fd1, fname1, APR_READ | APR_BINARY, APR_OS_DEFAULT, pool);
  202     if (APR_SUCCESS != status1) {
  203     return status1;
  204     }
  205 
  206     status1 = apr_file_open(&fd2, fname2, APR_READ | APR_BINARY, APR_OS_DEFAULT, pool);
  207     if (APR_SUCCESS != status1) {
  208     apr_file_close(fd1);
  209     return status1;
  210     }
  211 
  212     do {
  213     rbytes1 = HUGE_LEN;
  214     status1 = apr_file_read(fd1, data_chunk1, &rbytes1);
  215     rbytes2 = rbytes1;
  216     status2 = apr_file_read(fd2, data_chunk2, &rbytes2);
  217     if ((APR_SUCCESS == status1) && (APR_SUCCESS == status2) && (rbytes2 == rbytes1)) {
  218         *i = memcmp(data_chunk1, data_chunk2, rbytes1);
  219     }
  220     } while ((APR_SUCCESS == status1) && (APR_SUCCESS == status2) && (0 == *i) && (rbytes2 == rbytes1));
  221 
  222     if ((APR_EOF != status1) && (APR_EOF != status2) && (0 == *i)) {
  223     DEBUG_ERR("1:unable to read %s (%" APR_SIZE_T_FMT "): %s", fname1, rbytes1, apr_strerror(status1, errbuf, 128));
  224     DEBUG_ERR("2:unable to read %s (%" APR_SIZE_T_FMT "): %s", fname2, rbytes2, apr_strerror(status2, errbuf, 128));
  225     return status1;
  226     }
  227 
  228     if (APR_SUCCESS != (status1 = apr_file_close(fd2))) {
  229     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status1, errbuf, 128));
  230     apr_file_close(fd1);
  231     return status1;
  232     }
  233 
  234     if (APR_SUCCESS != (status1 = apr_file_close(fd1))) {
  235     DEBUG_ERR("error calling apr_file_close: %s", apr_strerror(status1, errbuf, 128));
  236     return status1;
  237     }
  238 
  239     return APR_SUCCESS;
  240 }
  241 
  242 extern apr_status_t filecmp(apr_pool_t *pool, const char *fname1, const char *fname2, apr_off_t size, apr_off_t excess_size,
  243                 int *i)
  244 {
  245     if (size < excess_size)
  246     return small_filecmp(pool, fname1, fname2, size, i);
  247 
  248     return big_filecmp(pool, fname1, fname2, size, i);
  249 }