/***************************************************************************1* _ _ ____ _2* Project ___| | | | _ \| |3* / __| | | | |_) | |4* | (__| |_| | _ <| |___5* \___|\___/|_| \_\_____|6*7* Copyright (C) Daniel Stenberg, <[email protected]>, et al.8*9* This software is licensed as described in the file COPYING, which10* you should have received as part of this distribution. The terms11* are also available at https://curl.se/docs/copyright.html.12*13* You may opt to use, copy, modify, merge, publish, distribute and/or sell14* copies of the Software, and permit persons to whom the Software is15* furnished to do so, under the terms of the COPYING file.16*17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY18* KIND, either express or implied.19*20* SPDX-License-Identifier: curl21*22***************************************************************************/23#include "tool_setup.h"2425#include <curlx.h>2627#include "tool_cfgable.h"28#include "tool_operate.h"29#include "tool_cb_see.h"3031#include <memdebug.h> /* keep this as LAST include */3233/*34** callback for CURLOPT_SEEKFUNCTION35**36** Notice that this is not supposed to return the resulting offset. This37** shall only return CURL_SEEKFUNC_* return codes.38*/3940int tool_seek_cb(void *userdata, curl_off_t offset, int whence)41{42struct per_transfer *per = userdata;4344#if (SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)4546/* OUR_MAX_SEEK_L has 'long' data type, OUR_MAX_SEEK_O has 'curl_off_t,47both represent the same value. Maximum offset used here when we lseek48using a 'long' data type offset */4950#define OUR_MAX_SEEK_L 2147483647L - 1L51#define OUR_MAX_SEEK_O CURL_OFF_T_C(0x7FFFFFFF) - CURL_OFF_T_C(0x1)5253/* The offset check following here is only interesting if curl_off_t is54larger than off_t and we are not using the Win32 large file support55macros that provide the support to do 64-bit seeks correctly */5657if(offset > OUR_MAX_SEEK_O) {58/* Some precaution code to work around problems with different data sizes59to allow seeking >32-bit even if off_t is 32-bit. Should be very rare60and is really valid on weirdo-systems. */61curl_off_t left = offset;6263if(whence != SEEK_SET)64/* this code path does not support other types */65return CURL_SEEKFUNC_FAIL;6667if(LSEEK_ERROR == lseek(per->infd, 0, SEEK_SET))68/* could not rewind to beginning */69return CURL_SEEKFUNC_FAIL;7071while(left) {72long step = (left > OUR_MAX_SEEK_O) ? OUR_MAX_SEEK_L : (long)left;73if(LSEEK_ERROR == lseek(per->infd, step, SEEK_CUR))74/* could not seek forwards the desired amount */75return CURL_SEEKFUNC_FAIL;76left -= step;77}78return CURL_SEEKFUNC_OK;79}80#endif8182#if defined(__AMIGA__) || defined(__MINGW32CE__)83if(LSEEK_ERROR == lseek(per->infd, (off_t)offset, whence))84#else85if(LSEEK_ERROR == lseek(per->infd, offset, whence))86#endif87/* could not rewind, the reason is in errno but errno is just not portable88enough and we do not actually care that much why we failed. We will let89libcurl know that it may try other means if it wants to. */90return CURL_SEEKFUNC_CANTSEEK;9192return CURL_SEEKFUNC_OK;93}949596