File: semaphore.hpp

package info (click to toggle)
dar 2.6.13-2
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 10,364 kB
  • sloc: cpp: 77,385; sh: 6,192; ansic: 776; makefile: 435; python: 242; csh: 95; perl: 43; sed: 16
file content (133 lines) | stat: -rw-r--r-- 5,812 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*********************************************************************/
// dar - disk archive - a backup/restoration program
// Copyright (C) 2002-2020 Denis Corbin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// to contact the author : http://dar.linux.free.fr/email.html
/*********************************************************************/

    /// \file semaphore.hpp
    /// \brief definition of class semaphore, used to manage invocation of backup hook for files
    /// \ingroup Private

#ifndef SEMAPHORE_HPP
#define SEMAPHORE_HPP

#include "../my_config.h"

#include "mem_ui.hpp"
#include "mask.hpp"

namespace libdar
{

	/// \addtogroup Private
	/// @{

	/// class semaphore

	/// Its action is to invoke the execute hook for each file that match the given mask
	/// Each file to backup has to be "raised()", which, if it matches the mask, leads
	/// to the execution of the execute hook with the proper substitution for that file
	/// in the "start" context.
	/// Then the backup can take place.
	/// When the backup is finished, the lower() method has to be called to trigger the
	/// execution of the hook with the proper substitution but in the "end" context.
	/// but, things are a bit complicated due to the handle of directories:
	/// If a directory is "raised()" and matches the mask, next calls to raise() do not trigger any
	/// hook execution even if the file match the mask, while saving into the directory
	/// that matched first. Instead, each new call to raise() increments an internal counter when
	/// a new directory is met, which is decremented when an "eod" is given to raised().
	/// So it is important to feed raise() with any entry may it has to be saved or not.
	/// while lower() has only to be called when a file has been saved.
	/// This is only when this internal counters reaches zero, that the lower() call will
	/// trigger the execution for this first matched directory, of the hook in the "end" context.
	///
	/// So the expected use is to give each file to be saved (including eod) to the raise()
	/// method, before eventually saving the file, and call the lower() method only for files that had to
	/// be saved once the backup is completed, may it be normally or due to an exception being thrown.

    class semaphore : public mem_ui
    {
    public:

	    /// constructor

	    /// \param[in] dialog for user interaction
	    /// \param[in] backup_hook_file_execute is the string to execute, it can contains macros
	    /// to be substitued, %f by filename, %p by path, %u by uid, %g by gid, and %c by the context,
	    /// which is either "start" or "end".
	    /// \param[in] backup_hook_file_mask defines the path+filename of entry that need to have
	    /// the hook executed before and after their backup
	semaphore(const std::shared_ptr<user_interaction> & dialog,
		  const std::string & backup_hook_file_execute,
		  const mask & backup_hook_file_mask);

	    /// copy constructor
	semaphore(const semaphore & ref) : mem_ui(ref) { copy_from(ref); };

	    /// move constructor
	semaphore(semaphore && ref) noexcept: mem_ui(std::move(ref)) { nullifyptr(); move_from(std::move(ref)); };

	    /// assignment operator
	semaphore & operator = (const semaphore & ref) { detruit(); copy_from(ref); return *this; };

	    /// move operator
	semaphore & operator = (semaphore && ref) noexcept { move_from(std::move(ref)); return *this; };

	    /// destructor
	~semaphore() { detruit(); };

	    /// to prepare a file for backup

	    /// all file has to be given to this call, even the eod objects
	    /// \param[in] path is the full path to the object
	    /// \param[in] object is the object about to be saved
	    /// \param[in] data_to_save tells whether this entry will have to
	    /// be saved or just recursed into (directory for example)
	    /// \note, if data_to_save is true, the lower() method is expected to be used
	    /// before a next call to raise. For a directory this is only the call to lower()
	    /// of the matching EOD that will trigger the hook execution in the "end" context.
	    /// If instead data_to_save if false, no lower() call has to be done.
	void raise(const std::string & path,
		   const cat_entree *object,
		   bool data_to_save);

	    /// to tell that the backup is completed for the last "raised" entry.
	void lower();

    private:
	infinint count;       ///< is the number of subdirectories currently saved in the last directory that matched the mask
	std::string chem;     ///< path of the file that has to be call in the "end" context when count will drop to zero
	std::string filename; ///< filename of that same file
	infinint uid;         ///< UID of that same file
	infinint gid;         ///< GID of that same file
	unsigned char sig;    ///< object type
	std::string execute;  ///< command to execute
	const mask *match;    ///< for which file to run the execute command

	void nullifyptr() noexcept { match = nullptr; };
	std::string build_string(const std::string & context);
	void copy_from(const semaphore & ref);
	void move_from(semaphore && ref) noexcept;
	void detruit();
    };

	/// @}

} // end of namespace

#endif