Disk ARchive  2.7.15
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 
33 extern "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 
52 namespace 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.