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(JobControlRecord *jcr, uint32_t number_of_files)
41 {
42    jcr_= jcr;
43    filenr_ = 0;
44    number_of_previous_files_ = number_of_files;
45 
46    CurFile *elt = NULL;
47    file_list_ = (htable *)malloc(sizeof(htable));
48    file_list_->init(elt, &elt->link, number_of_previous_files_);
49    seen_bitmap_ = (char *)malloc(NbytesForBits(number_of_previous_files_));
50    ClearAllBits(number_of_previous_files_, seen_bitmap_);
51 }
52 
AddFile(char * fname,int fname_length,char * lstat,int lstat_length,char * chksum,int chksum_length,int32_t delta_seq)53 bool BareosAccurateFilelistHtable::AddFile( char *fname,
54                                              int fname_length,
55                                              char *lstat,
56                                              int lstat_length,
57                                              char *chksum,
58                                              int chksum_length,
59                                              int32_t delta_seq)
60 {
61    CurFile *item;
62    int total_length;
63    bool retval = true;
64 
65    total_length = sizeof(CurFile) + fname_length + lstat_length + chksum_length + 3;
66    item = (CurFile *)file_list_->hash_malloc(total_length);
67 
68    item->fname = (char *)item + sizeof(CurFile);
69    memcpy(item->fname, fname, fname_length);
70    item->fname[fname_length] = '\0';
71 
72    item->payload.lstat = item->fname + fname_length + 1;
73    memcpy(item->payload.lstat, lstat, lstat_length);
74    item->payload.lstat[lstat_length] = '\0';
75 
76    item->payload.chksum = item->payload.lstat + lstat_length + 1;
77    if (chksum_length) {
78       memcpy(item->payload.chksum, chksum, chksum_length);
79    }
80    item->payload.chksum[chksum_length] = '\0';
81 
82    item->payload.delta_seq = delta_seq;
83    item->payload.filenr = filenr_++;
84    file_list_->insert(item->fname, item);
85 
86    if (chksum) {
87       Dmsg4(debuglevel, "add fname=<%s> lstat=%s delta_seq=%i chksum=%s\n", fname, lstat, delta_seq, chksum);
88    } else {
89       Dmsg2(debuglevel, "add fname=<%s> lstat=%s\n", fname, lstat);
90    }
91 
92    return retval;
93 }
94 
EndLoad()95 bool BareosAccurateFilelistHtable::EndLoad()
96 {
97    /*
98     * Nothing to do.
99     */
100    return true;
101 }
102 
lookup_payload(char * fname)103 accurate_payload *BareosAccurateFilelistHtable::lookup_payload(char *fname)
104 {
105    CurFile *temp;
106 
107    temp = (CurFile *)file_list_->lookup(fname);
108    return (temp) ? &temp->payload : NULL;
109 }
110 
UpdatePayload(char * fname,accurate_payload * payload)111 bool BareosAccurateFilelistHtable::UpdatePayload(char *fname, accurate_payload *payload)
112 {
113    /*
114     * Nothing to do.
115     */
116    return true;
117 }
118 
SendBaseFileList()119 bool BareosAccurateFilelistHtable::SendBaseFileList()
120 {
121    CurFile *elt;
122    FindFilesPacket *ff_pkt;
123    int32_t LinkFIc;
124    struct stat statp;
125    int stream = STREAM_UNIX_ATTRIBUTES;
126 
127    if (!jcr_->accurate || jcr_->getJobLevel() != L_FULL) {
128       return true;
129    }
130 
131    if (file_list_ == NULL) {
132       return true;
133    }
134 
135    ff_pkt = init_find_files();
136    ff_pkt->type = FT_BASE;
137 
138    foreach_htable(elt, file_list_) {
139       if (BitIsSet(elt->payload.filenr, seen_bitmap_)) {
140          Dmsg1(debuglevel, "base file fname=%s\n", elt->fname);
141          DecodeStat(elt->payload.lstat, &statp, sizeof(statp), &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) {
161       return true;
162    }
163 
164    ff_pkt = init_find_files();
165    ff_pkt->type = FT_DELETED;
166 
167    foreach_htable(elt, file_list_) {
168       if (BitIsSet(elt->payload.filenr, seen_bitmap_) ||
169           PluginCheckFile(jcr_, elt->fname)) {
170          continue;
171       }
172       Dmsg1(debuglevel, "deleted fname=%s\n", elt->fname);
173       ff_pkt->fname = elt->fname;
174       DecodeStat(elt->payload.lstat, &statp, sizeof(statp), &LinkFIc); /* decode catalog stat */
175       ff_pkt->statp.st_mtime = statp.st_mtime;
176       ff_pkt->statp.st_ctime = statp.st_ctime;
177       EncodeAndSendAttributes(jcr_, ff_pkt, stream);
178    }
179 
180    TermFindFiles(ff_pkt);
181    return true;
182 }
183 
destroy()184 void BareosAccurateFilelistHtable::destroy()
185 {
186    if (file_list_) {
187       file_list_->destroy();
188       free(file_list_);
189       file_list_ = NULL;
190    }
191 
192    if (seen_bitmap_) {
193       free(seen_bitmap_);
194       seen_bitmap_ = NULL;
195    }
196 
197    filenr_ = 0;
198 }
199 
200 } /* namespace filedaemon */
201