Disk ARchive 2.7.16
Full featured and portable backup and archiving tool
fichier_libcurl.hpp
Go to the documentation of this file.
1/*********************************************************************/
2// dar - disk archive - a backup/restoration program
3// Copyright (C) 2002-2024 Denis Corbin
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// to contact the author, see the AUTHOR file
20/*********************************************************************/
21
26
27#ifndef FICHIER_LIBCURL_HPP
28#define FICHIER_LIBCURL_HPP
29
30
31#include "../my_config.h"
32
33extern "C"
34{
35#if LIBCURL_AVAILABLE
36#if HAVE_CURL_CURL_H
37#include <curl/curl.h>
38#endif
39#endif
40} // end extern "C"
41
42#include <string>
43#ifdef LIBTHREADAR_AVAILABLE
44#include <libthreadar/libthreadar.hpp>
45#endif
46#include "integers.hpp"
47#include "user_interaction.hpp"
48#include "fichier_global.hpp"
49#include "mycurl_protocol.hpp"
51
52namespace libdar
53{
54
57
58#if defined ( LIBCURL_AVAILABLE ) && defined ( LIBTHREADAR_AVAILABLE )
59
61
62 class fichier_libcurl : public fichier_global, protected libthreadar::thread
63 {
64 public:
65
67 fichier_libcurl(const std::shared_ptr<user_interaction> & dialog, //< for user interaction requested by fichier_global
68 const std::string & chemin, //< full path of the file to open
69 mycurl_protocol proto, //< to workaround some libcurl strange behavior for some protocols
70 const std::shared_ptr<mycurl_easyhandle_node> & handle, //< the easy handle wrapper object
71 gf_mode m, //< open mode
72 U_I waiting, //< retry timeout in case of network error
73 bool force_permission, //< whether file permission should be modified
74 U_I permission, //< file permission to enforce if force_permission is set
75 bool erase); //< whether to erase the file before writing to it
76
78
80 fichier_libcurl(const fichier_libcurl & ref) = delete;
81
83 fichier_libcurl(fichier_libcurl && ref) = delete;
84
87 fichier_libcurl & operator = (const fichier_libcurl & ref) = delete;
88
90 fichier_libcurl & operator = (fichier_libcurl && ref) = delete;
91
93 ~fichier_libcurl() noexcept { kill(); join(); detruit(); };
94
96 virtual void change_permission(U_I perm) override;
97
99 virtual void change_ownership(const std::string & user, const std::string & group) override
100 { throw Efeature(gettext("user/group ownership not supported for this repository")); }; // not supported
101
103 virtual infinint get_size() const override;
104
106 virtual void fadvise(advise adv) const override {}; // not supported and ignored
107
108 // inherited from generic_file
109 virtual bool skippable(skippability direction, const infinint & amount) override;
110 virtual bool skip(const infinint & pos) override;
111 virtual bool skip_to_eof() override;
112 virtual bool skip_relative(S_I x) override;
113 virtual bool truncatable(const infinint & pos) const override { return pos == get_position(); };
114 virtual infinint get_position() const override { return current_offset; };
115
116 protected:
117 // inherited from generic_file grand-parent class
118 virtual void inherited_read_ahead(const infinint & amount) override;
119 virtual void inherited_truncate(const infinint & pos) override;
120 virtual void inherited_sync_write() override;
121 virtual void inherited_flush_read() override;
122 virtual void inherited_terminate() override;
123
124 // inherited from fichier_global parent class
125 virtual U_I fichier_global_inherited_write(const char *a, U_I size) override;
126 virtual bool fichier_global_inherited_read(char *a, U_I size, U_I & read, std::string & message) override;
127
128 // inherited from thread
129 virtual void inherited_run() override;
130
131 private:
132 static const U_I tampon_size = CURL_MAX_WRITE_SIZE;
133
135 //
136 // implementation internals
137 //
139 // the object has two modes:
140 // - meta data mode (skip, get_position() and other non read/write operations)
141 // - data mode (read or write operations)
142 //
143 // in metadata mode each method is a simple code execution (no subthread, no callback)
144 //
145 // in data mode, a subthread is used to interact with libcurl. It sends or receives
146 // data through the interthread pipe. A callback is occasionally run by libcurl in this
147 // subthread.
148 // in read mode, the subthread is run only if the interthread is empty. the subthread may
149 // survive the inherited_read call and may suspend on writing data to interthread being full
150 // - "subthread_net_offset" is updated by the callback and read by the subthread when
151 // libcurl has returned it keeps trace of the amount of data sent to interthread.
152 // - "network_block" is set by the main thread to define the amount of data to be fetched. It
153 // it used to setup libcurl and is read by the subthread for control/validation purposes
154
155 bool end_data_mode;
156 bool sub_is_dying;
157 bool sync_write_asked;
158 bool weof;
159 std::shared_ptr<mycurl_easyhandle_node> ehandle;
160 bool metadatamode;
161 infinint current_offset;
162 bool has_maxpos;
163 infinint maxpos;
164 bool append_write;
165 U_I meta_inbuf;
166 U_I wait_delay;
167 infinint network_block;
168 infinint subthread_net_offset;
169 infinint subthread_cur_offset;
170 libthreadar::fast_tampon<char> interthread;
171 libthreadar::barrier synchronize;
172 mycurl_protocol x_proto;
173
174 void set_range(const infinint & begin, const infinint & range_size);
175 void unset_range();
176 void switch_to_metadata(bool mode);
177 void detruit();
178 void run_thread();
179 void stop_thread();
180 void relaunch_thread(const infinint & block_size);
181 void initialize_subthread();
182 void finalize_subthread();
183 void set_subthread(U_I & needed_bytes);
184 bool still_data_to_write();
185
186 static size_t write_data_callback(char *buffer, size_t size, size_t nmemb, void *userp);
187 static size_t read_data_callback(char *bufptr, size_t size, size_t nitems, void *userp);
188 static size_t write_meta_callback(char *buffer, size_t size, size_t nmemb, void *userp);
189 static size_t read_meta_callback(char *bufptr, size_t size, size_t nitems, void *userp);
190 };
191
192
193#endif
195
196} // end of namespace
197
198#endif
class fichier_global definition. This class is a pure virtual class class fichier_global is an abstra...
mycurl_protocol
libcurl protocols supported by libdar
gf_mode
generic_file openning modes
Definition: gf_mode.hpp:44
are defined here basic integer types that tend to be portable
used to optimize session creation done by libcurl
datastructure defining the network protocols available for entrepot_libcurl class
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47
defines the interaction interface between libdar and users.