113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci/* <DESC> 2513498266Sopenharmony_ci * Upload to SFTP, resuming a previously aborted transfer. 2613498266Sopenharmony_ci * </DESC> 2713498266Sopenharmony_ci */ 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include <stdlib.h> 3013498266Sopenharmony_ci#include <stdio.h> 3113498266Sopenharmony_ci#include <curl/curl.h> 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci/* read data to upload */ 3413498266Sopenharmony_cistatic size_t readfunc(char *ptr, size_t size, size_t nmemb, void *stream) 3513498266Sopenharmony_ci{ 3613498266Sopenharmony_ci FILE *f = (FILE *)stream; 3713498266Sopenharmony_ci size_t n; 3813498266Sopenharmony_ci 3913498266Sopenharmony_ci if(ferror(f)) 4013498266Sopenharmony_ci return CURL_READFUNC_ABORT; 4113498266Sopenharmony_ci 4213498266Sopenharmony_ci n = fread(ptr, size, nmemb, f) * size; 4313498266Sopenharmony_ci 4413498266Sopenharmony_ci return n; 4513498266Sopenharmony_ci} 4613498266Sopenharmony_ci 4713498266Sopenharmony_ci/* 4813498266Sopenharmony_ci * sftpGetRemoteFileSize returns the remote file size in byte; -1 on error 4913498266Sopenharmony_ci */ 5013498266Sopenharmony_cistatic curl_off_t sftpGetRemoteFileSize(const char *i_remoteFile) 5113498266Sopenharmony_ci{ 5213498266Sopenharmony_ci CURLcode result = CURLE_GOT_NOTHING; 5313498266Sopenharmony_ci curl_off_t remoteFileSizeByte = -1; 5413498266Sopenharmony_ci CURL *curlHandlePtr = curl_easy_init(); 5513498266Sopenharmony_ci 5613498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_VERBOSE, 1L); 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_URL, i_remoteFile); 5913498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_NOPROGRESS, 1); 6013498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_NOBODY, 1); 6113498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_HEADER, 1); 6213498266Sopenharmony_ci curl_easy_setopt(curlHandlePtr, CURLOPT_FILETIME, 1); 6313498266Sopenharmony_ci 6413498266Sopenharmony_ci result = curl_easy_perform(curlHandlePtr); 6513498266Sopenharmony_ci if(CURLE_OK == result) { 6613498266Sopenharmony_ci result = curl_easy_getinfo(curlHandlePtr, 6713498266Sopenharmony_ci CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, 6813498266Sopenharmony_ci &remoteFileSizeByte); 6913498266Sopenharmony_ci if(result) 7013498266Sopenharmony_ci return -1; 7113498266Sopenharmony_ci printf("filesize: %lu\n", (unsigned long)remoteFileSizeByte); 7213498266Sopenharmony_ci } 7313498266Sopenharmony_ci curl_easy_cleanup(curlHandlePtr); 7413498266Sopenharmony_ci 7513498266Sopenharmony_ci return remoteFileSizeByte; 7613498266Sopenharmony_ci} 7713498266Sopenharmony_ci 7813498266Sopenharmony_ci 7913498266Sopenharmony_cistatic int sftpResumeUpload(CURL *curlhandle, const char *remotepath, 8013498266Sopenharmony_ci const char *localpath) 8113498266Sopenharmony_ci{ 8213498266Sopenharmony_ci FILE *f = NULL; 8313498266Sopenharmony_ci CURLcode result = CURLE_GOT_NOTHING; 8413498266Sopenharmony_ci 8513498266Sopenharmony_ci curl_off_t remoteFileSizeByte = sftpGetRemoteFileSize(remotepath); 8613498266Sopenharmony_ci if(-1 == remoteFileSizeByte) { 8713498266Sopenharmony_ci printf("Error reading the remote file size: unable to resume upload\n"); 8813498266Sopenharmony_ci return -1; 8913498266Sopenharmony_ci } 9013498266Sopenharmony_ci 9113498266Sopenharmony_ci f = fopen(localpath, "rb"); 9213498266Sopenharmony_ci if(!f) { 9313498266Sopenharmony_ci perror(NULL); 9413498266Sopenharmony_ci return 0; 9513498266Sopenharmony_ci } 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L); 9813498266Sopenharmony_ci curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath); 9913498266Sopenharmony_ci curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc); 10013498266Sopenharmony_ci curl_easy_setopt(curlhandle, CURLOPT_READDATA, f); 10113498266Sopenharmony_ci 10213498266Sopenharmony_ci#ifdef _WIN32 10313498266Sopenharmony_ci _fseeki64(f, remoteFileSizeByte, SEEK_SET); 10413498266Sopenharmony_ci#else 10513498266Sopenharmony_ci fseek(f, (long)remoteFileSizeByte, SEEK_SET); 10613498266Sopenharmony_ci#endif 10713498266Sopenharmony_ci curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L); 10813498266Sopenharmony_ci result = curl_easy_perform(curlhandle); 10913498266Sopenharmony_ci 11013498266Sopenharmony_ci fclose(f); 11113498266Sopenharmony_ci 11213498266Sopenharmony_ci if(result == CURLE_OK) 11313498266Sopenharmony_ci return 1; 11413498266Sopenharmony_ci else { 11513498266Sopenharmony_ci fprintf(stderr, "%s\n", curl_easy_strerror(result)); 11613498266Sopenharmony_ci return 0; 11713498266Sopenharmony_ci } 11813498266Sopenharmony_ci} 11913498266Sopenharmony_ci 12013498266Sopenharmony_ciint main(void) 12113498266Sopenharmony_ci{ 12213498266Sopenharmony_ci const char *remote = "sftp://user:pass@example.com/path/filename"; 12313498266Sopenharmony_ci const char *filename = "filename"; 12413498266Sopenharmony_ci CURL *curlhandle = NULL; 12513498266Sopenharmony_ci 12613498266Sopenharmony_ci curl_global_init(CURL_GLOBAL_ALL); 12713498266Sopenharmony_ci curlhandle = curl_easy_init(); 12813498266Sopenharmony_ci 12913498266Sopenharmony_ci if(!sftpResumeUpload(curlhandle, remote, filename)) { 13013498266Sopenharmony_ci printf("resumed upload using curl %s failed\n", curl_version()); 13113498266Sopenharmony_ci } 13213498266Sopenharmony_ci 13313498266Sopenharmony_ci curl_easy_cleanup(curlhandle); 13413498266Sopenharmony_ci curl_global_cleanup(); 13513498266Sopenharmony_ci 13613498266Sopenharmony_ci return 0; 13713498266Sopenharmony_ci} 138