1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2013-2014 Planets Communications B.V.
6    Copyright (C) 2013-2018 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  * Marco van Wieringen, December 2013
25  */
26 /**
27  * @file
28  * This file contains the HTABLE abstraction of the accurate payload storage.
29  */
30 
31 #include "include/bareos.h"
32 #include "filed/filed.h"
33 #include "accurate.h"
34 #include "lib/attribs.h"
35 
36 namespace filedaemon {
37 
38 static int debuglevel = 100;
39 
BareosAccurateFilelistHtable(JobControlRecord * jcr,uint32_t number_of_files)40 BareosAccurateFilelistHtable::BareosAccurateFilelistHtable(
41     JobControlRecord* jcr,
42     uint32_t number_of_files)
43 {
44   jcr_ = jcr;
45   filenr_ = 0;
46   number_of_previous_files_ = number_of_files;
47 
48   CurFile* elt = NULL;
49   file_list_ = (htable*)malloc(sizeof(htable));
50   file_list_->init(elt, &elt->link, number_of_previous_files_);
51   seen_bitmap_ = (char*)malloc(NbytesForBits(number_of_previous_files_));
52   ClearAllBits(number_of_previous_files_, seen_bitmap_);
53 }
54 
AddFile(char * fname,int fname_length,char * lstat,int lstat_length,char * chksum,int chksum_length,int32_t delta_seq)55 bool BareosAccurateFilelistHtable::AddFile(char* fname,
56                                            int fname_length,
57                                            char* lstat,
58                                            int lstat_length,
59                                            char* chksum,
60                                            int chksum_length,
61                                            int32_t delta_seq)
62 {
63   CurFile* item;
64   int total_length;
65   bool retval = true;
66 
67   total_length
68       = sizeof(CurFile) + fname_length + lstat_length + chksum_length + 3;
69   item = (CurFile*)file_list_->hash_malloc(total_length);
70 
71   item->fname = (char*)item + sizeof(CurFile);
72   memcpy(item->fname, fname, fname_length);
73   item->fname[fname_length] = '\0';
74 
75   item->payload.lstat = item->fname + fname_length + 1;
76   memcpy(item->payload.lstat, lstat, lstat_length);
77   item->payload.lstat[lstat_length] = '\0';
78 
79   item->payload.chksum = item->payload.lstat + lstat_length + 1;
80   if (chksum_length) { memcpy(item->payload.chksum, chksum, chksum_length); }
81   item->payload.chksum[chksum_length] = '\0';
82 
83   item->payload.delta_seq = delta_seq;
84   item->payload.filenr = filenr_++;
85   file_list_->insert(item->fname, item);
86 
87   if (chksum) {
88     Dmsg4(debuglevel, "add fname=<%s> lstat=%s delta_seq=%i chksum=%s\n", fname,
89           lstat, delta_seq, chksum);
90   } else {
91     Dmsg2(debuglevel, "add fname=<%s> lstat=%s\n", fname, lstat);
92   }
93 
94   return retval;
95 }
96 
EndLoad()97 bool BareosAccurateFilelistHtable::EndLoad()
98 {
99   /*
100    * Nothing to do.
101    */
102   return true;
103 }
104 
lookup_payload(char * fname)105 accurate_payload* BareosAccurateFilelistHtable::lookup_payload(char* fname)
106 {
107   CurFile* temp;
108 
109   temp = (CurFile*)file_list_->lookup(fname);
110   return (temp) ? &temp->payload : NULL;
111 }
112 
UpdatePayload(char * fname,accurate_payload * payload)113 bool BareosAccurateFilelistHtable::UpdatePayload(char* fname,
114                                                  accurate_payload* payload)
115 {
116   /*
117    * Nothing to do.
118    */
119   return true;
120 }
121 
SendBaseFileList()122 bool BareosAccurateFilelistHtable::SendBaseFileList()
123 {
124   CurFile* elt;
125   FindFilesPacket* ff_pkt;
126   int32_t LinkFIc;
127   struct stat statp;
128   int stream = STREAM_UNIX_ATTRIBUTES;
129 
130   if (!jcr_->accurate || jcr_->getJobLevel() != L_FULL) { return true; }
131 
132   if (file_list_ == NULL) { return true; }
133 
134   ff_pkt = init_find_files();
135   ff_pkt->type = FT_BASE;
136 
137   foreach_htable (elt, file_list_) {
138     if (BitIsSet(elt->payload.filenr, seen_bitmap_)) {
139       Dmsg1(debuglevel, "base file fname=%s\n", elt->fname);
140       DecodeStat(elt->payload.lstat, &statp, sizeof(statp),
141                  &LinkFIc); /* decode catalog stat */
142       ff_pkt->fname = elt->fname;
143       ff_pkt->statp = statp;
144       EncodeAndSendAttributes(jcr_, ff_pkt, stream);
145     }
146   }
147 
148   TermFindFiles(ff_pkt);
149   return true;
150 }
151 
SendDeletedList()152 bool BareosAccurateFilelistHtable::SendDeletedList()
153 {
154   CurFile* elt;
155   FindFilesPacket* ff_pkt;
156   int32_t LinkFIc;
157   struct stat statp;
158   int stream = STREAM_UNIX_ATTRIBUTES;
159 
160   if (!jcr_->accurate) { return true; }
161 
162   ff_pkt = init_find_files();
163   ff_pkt->type = FT_DELETED;
164 
165   foreach_htable (elt, file_list_) {
166     if (BitIsSet(elt->payload.filenr, seen_bitmap_)
167         || PluginCheckFile(jcr_, elt->fname)) {
168       continue;
169     }
170     Dmsg1(debuglevel, "deleted fname=%s\n", elt->fname);
171     ff_pkt->fname = elt->fname;
172     DecodeStat(elt->payload.lstat, &statp, sizeof(statp),
173                &LinkFIc); /* decode catalog stat */
174     ff_pkt->statp.st_mtime = statp.st_mtime;
175     ff_pkt->statp.st_ctime = statp.st_ctime;
176     EncodeAndSendAttributes(jcr_, ff_pkt, stream);
177   }
178 
179   TermFindFiles(ff_pkt);
180   return true;
181 }
182 
destroy()183 void BareosAccurateFilelistHtable::destroy()
184 {
185   if (file_list_) {
186     file_list_->destroy();
187     free(file_list_);
188     file_list_ = NULL;
189   }
190 
191   if (seen_bitmap_) {
192     free(seen_bitmap_);
193     seen_bitmap_ = NULL;
194   }
195 
196   filenr_ = 0;
197 }
198 
199 } /* namespace filedaemon */
200