1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
5 Copyright (C) 2011-2012 Planets Communications B.V.
6 Copyright (C) 2013-2020 Bareos GmbH & Co. KG
7
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
11 in the file LICENSE.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23
24 #include "lib/messages_resource.h"
25 #include "lib/message_destination_info.h"
26
27 #include <algorithm>
28 #include <iostream>
29
30 static pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
31
MessagesResource()32 MessagesResource::MessagesResource() : BareosResource(), send_msg_types_(3, 0)
33 {
34 return;
35 }
36
~MessagesResource()37 MessagesResource::~MessagesResource()
38 {
39 for (MessageDestinationInfo* d : dest_chain_) { delete d; }
40 }
41
Lock() const42 void MessagesResource::Lock() const { P(mutex_); }
43
Unlock() const44 void MessagesResource::Unlock() const { V(mutex_); }
45
WaitNotInUse() const46 void MessagesResource::WaitNotInUse() const
47 {
48 // leaves mutex_ locked
49 Lock();
50 while (in_use_ || closing_) {
51 Unlock();
52 Bmicrosleep(0, 200);
53 Lock();
54 }
55 }
56
ClearInUse()57 void MessagesResource::ClearInUse()
58 {
59 Lock();
60 in_use_ = false;
61 Unlock();
62 }
SetInUse()63 void MessagesResource::SetInUse()
64 {
65 WaitNotInUse();
66 in_use_ = true;
67 Unlock();
68 }
69
SetClosing()70 void MessagesResource::SetClosing() { closing_ = true; }
71
GetClosing() const72 bool MessagesResource::GetClosing() const { return closing_; }
73
ClearClosing()74 void MessagesResource::ClearClosing()
75 {
76 Lock();
77 closing_ = false;
78 Unlock();
79 }
80
IsClosing() const81 bool MessagesResource::IsClosing() const
82 {
83 Lock();
84 bool rtn = closing_;
85 Unlock();
86 return rtn;
87 }
88
DuplicateDestChain() const89 std::vector<MessageDestinationInfo*> MessagesResource::DuplicateDestChain()
90 const
91 {
92 std::vector<MessageDestinationInfo*> temp_chain;
93
94 for (MessageDestinationInfo* d : dest_chain_) {
95 MessageDestinationInfo* dnew = new MessageDestinationInfo(*d);
96 dnew->file_pointer_ = nullptr;
97 dnew->mail_filename_.clear();
98 temp_chain.push_back(dnew);
99 }
100
101 return temp_chain;
102 }
103
DuplicateResourceTo(MessagesResource & other) const104 void MessagesResource::DuplicateResourceTo(MessagesResource& other) const
105 {
106 other.dest_chain_ = DuplicateDestChain();
107 other.send_msg_types_ = send_msg_types_;
108 }
109
110 /*
111 * Called only during parsing of the config file.
112 *
113 * Note, where in the case of dest_code FILE is a filename,
114 * but in the case of MAIL is a space separated list of
115 * email addresses, ...
116 */
AddToExistingChain(MessageDestinationCode dest_code,int msg_type,const std::string & where)117 bool MessagesResource::AddToExistingChain(MessageDestinationCode dest_code,
118 int msg_type,
119 const std::string& where)
120 {
121 auto pos = std::find_if(dest_chain_.rbegin(), dest_chain_.rend(),
122 [&dest_code, where](MessageDestinationInfo* d) {
123 return ((d->dest_code_ == dest_code)
124 && ((where.empty() && d->where_.empty())
125 || (where == d->where_)));
126 });
127
128 if (pos != dest_chain_.rend()) {
129 MessageDestinationInfo* d = *pos;
130 Dmsg4(850, "add to existing d=%p msgtype=%d destcode=%d where=%s\n", d,
131 msg_type, dest_code, NSTDPRNT(where));
132 SetBit(msg_type, d->msg_types_);
133 SetBit(msg_type, send_msg_types_);
134 return true;
135 }
136 return false;
137 }
138
AddToNewChain(MessageDestinationCode dest_code,int msg_type,const std::string & where,const std::string & mail_cmd,const std::string & timestamp_format)139 void MessagesResource::AddToNewChain(MessageDestinationCode dest_code,
140 int msg_type,
141 const std::string& where,
142 const std::string& mail_cmd,
143 const std::string& timestamp_format)
144 {
145 MessageDestinationInfo* d;
146 d = new MessageDestinationInfo;
147 d->dest_code_ = dest_code;
148 SetBit(msg_type, d->msg_types_); /* Set type bit in structure */
149 SetBit(msg_type, send_msg_types_); /* Set type bit in our local */
150
151 d->where_ = where;
152 d->mail_cmd_ = mail_cmd;
153 d->timestamp_format_ = timestamp_format;
154
155 dest_chain_.push_back(d);
156
157 Dmsg6(850,
158 "add new d=%p msgtype=%d destcode=%d where=%s mailcmd=%s "
159 "timestampformat=%s\n",
160 d, msg_type, dest_code, NSTDPRNT(where), NSTDPRNT(d->mail_cmd_),
161 NSTDPRNT(d->timestamp_format_));
162 }
163
AddMessageDestination(MessageDestinationCode dest_code,int msg_type,const std::string & where,const std::string & mail_cmd,const std::string & timestamp_format)164 void MessagesResource::AddMessageDestination(
165 MessageDestinationCode dest_code,
166 int msg_type,
167 const std::string& where,
168 const std::string& mail_cmd,
169 const std::string& timestamp_format)
170 {
171 if (!AddToExistingChain(dest_code, msg_type, where)) {
172 AddToNewChain(dest_code, msg_type, where, mail_cmd, timestamp_format);
173 }
174 }
175
176 /*
177 * Called only during parsing of the config file.
178 */
RemoveMessageDestination(MessageDestinationCode dest_code,int msg_type,const std::string & where)179 void MessagesResource::RemoveMessageDestination(
180 MessageDestinationCode dest_code,
181 int msg_type,
182 const std::string& where)
183 {
184 for (MessageDestinationInfo* d : dest_chain_) {
185 Dmsg2(850, "Remove_msg_dest d=%p where=%s\n", d, NSTDPRNT(d->where_));
186 if (BitIsSet(msg_type, d->msg_types_) && (dest_code == d->dest_code_)
187 && ((where.empty() && d->where_.empty()) || (where == d->where_))) {
188 Dmsg3(850, "Found for remove d=%p msgtype=%d destcode=%d\n", d, msg_type,
189 dest_code);
190 ClearBit(msg_type, d->msg_types_);
191 Dmsg0(850, "Return RemoveMessageDestination\n");
192 return;
193 }
194 }
195 }
196