Home | History | Annotate | Download | only in src
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 #include "tool_setup.h"
     23 
     24 #define ENABLE_CURLX_PRINTF
     25 /* use our own printf() functions */
     26 #include "curlx.h"
     27 
     28 #include "tool_cfgable.h"
     29 #include "tool_cb_see.h"
     30 
     31 #include "memdebug.h" /* keep this as LAST include */
     32 
     33 /* OUR_MAX_SEEK_L has 'long' data type, OUR_MAX_SEEK_O has 'curl_off_t,
     34    both represent the same value. Maximum offset used here when we lseek
     35    using a 'long' data type offset */
     36 
     37 #define OUR_MAX_SEEK_L  2147483647L - 1L
     38 #define OUR_MAX_SEEK_O  CURL_OFF_T_C(0x7FFFFFFF) - CURL_OFF_T_C(0x1)
     39 
     40 /*
     41 ** callback for CURLOPT_SEEKFUNCTION
     42 **
     43 ** Notice that this is not supposed to return the resulting offset. This
     44 ** shall only return CURL_SEEKFUNC_* return codes.
     45 */
     46 
     47 int tool_seek_cb(void *userdata, curl_off_t offset, int whence)
     48 {
     49   struct InStruct *in = userdata;
     50 
     51 #if(CURL_SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)
     52 
     53   /* The offset check following here is only interesting if curl_off_t is
     54      larger than off_t and we are not using the WIN32 large file support
     55      macros that provide the support to do 64bit seeks correctly */
     56 
     57   if(offset > OUR_MAX_SEEK_O) {
     58     /* Some precaution code to work around problems with different data sizes
     59        to allow seeking >32bit even if off_t is 32bit. Should be very rare and
     60        is really valid on weirdo-systems. */
     61     curl_off_t left = offset;
     62 
     63     if(whence != SEEK_SET)
     64       /* this code path doesn't support other types */
     65       return CURL_SEEKFUNC_FAIL;
     66 
     67     if(LSEEK_ERROR == lseek(in->fd, 0, SEEK_SET))
     68       /* couldn't rewind to beginning */
     69       return CURL_SEEKFUNC_FAIL;
     70 
     71     while(left) {
     72       long step = (left > OUR_MAX_SEEK_O) ? OUR_MAX_SEEK_L : (long)left;
     73       if(LSEEK_ERROR == lseek(in->fd, step, SEEK_CUR))
     74         /* couldn't seek forwards the desired amount */
     75         return CURL_SEEKFUNC_FAIL;
     76       left -= step;
     77     }
     78     return CURL_SEEKFUNC_OK;
     79   }
     80 #endif
     81 
     82   if(LSEEK_ERROR == lseek(in->fd, offset, whence))
     83     /* couldn't rewind, the reason is in errno but errno is just not portable
     84        enough and we don't actually care that much why we failed. We'll let
     85        libcurl know that it may try other means if it wants to. */
     86     return CURL_SEEKFUNC_CANTSEEK;
     87 
     88   return CURL_SEEKFUNC_OK;
     89 }
     90 
     91 #if defined(WIN32) && !defined(__MINGW64__)
     92 
     93 #ifdef __BORLANDC__
     94 /* 64-bit lseek-like function unavailable */
     95 #  define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
     96 #endif
     97 
     98 #ifdef __POCC__
     99 #  if(__POCC__ < 450)
    100 /* 64-bit lseek-like function unavailable */
    101 #    define _lseeki64(hnd,ofs,whence) _lseek(hnd,ofs,whence)
    102 #  else
    103 #    define _lseeki64(hnd,ofs,whence) _lseek64(hnd,ofs,whence)
    104 #  endif
    105 #endif
    106 
    107 #ifdef _WIN32_WCE
    108 /* 64-bit lseek-like function unavailable */
    109 #  undef _lseeki64
    110 #  define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
    111 #  undef _get_osfhandle
    112 #  define _get_osfhandle(fd) (fd)
    113 #endif
    114 
    115 /*
    116  * Truncate a file handle at a 64-bit position 'where'.
    117  */
    118 
    119 int tool_ftruncate64(int fd, curl_off_t where)
    120 {
    121   if(_lseeki64(fd, where, SEEK_SET) < 0)
    122     return -1;
    123 
    124   if(!SetEndOfFile((HANDLE)_get_osfhandle(fd)))
    125     return -1;
    126 
    127   return 0;
    128 }
    129 
    130 #endif /* WIN32  && ! __MINGW64__ */
    131 
    132