-
Notifications
You must be signed in to change notification settings - Fork 5
/
mlocate.cc
115 lines (100 loc) · 3.49 KB
/
mlocate.cc
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
// Copyright © 2015 Alexandre Detiste <[email protected]>
// SPDX-License-Identifier: GPL-2.0-or-later
#include <iostream>
#include <fstream>
#include <algorithm>
#include <limits>
#include "mlocate_db.h"
// original filename is 'db.h'
#include "locate.h"
#include "python.h"
#include <experimental/filesystem>
using namespace std::experimental;
namespace fs = std::experimental::filesystem;
int read_locate(vector<string>& fs, const string& ignore_path, const string& root_dir) // vector<string>& prunefs
{
bool debug=getenv("DEBUG") != NULL;
init_python();
string line;
ifstream mlocate("/var/lib/mlocate/mlocate.db");
if (not mlocate) {
cerr << "can not open mlocate database" << endl << "are you root ?" << endl;
// you can also "setgid mlocate" the cruft-ng binary
exit(1);
}
if (debug) cerr << "MLOCATE HEADER:\n";
//char * header = new char [sizeof(db_header)];
struct db_header header;
mlocate.read ((char *) &header,sizeof(db_header));
// TODO: assert this
for (int i=0;i<8;i++) {
if (debug) cerr << header.magic[i];
} if (debug) cerr << endl << endl;
if (debug) cerr << "MLOCATE ROOT:" << endl;
getline(mlocate,line, '\0');
if (debug) cerr << line << endl << endl;
if (debug) cerr << "MLOCATE PARAMETERS:" << endl;
int param_start = mlocate.tellg();
while (getline(mlocate,line,'\0'))
{
if (line.empty()) break;
string key=line;
if (debug) cerr << line << '=';
while (getline(mlocate,line,'\0'))
{
if (line.empty()) break;
//if (key=="prunefs") prunefs.push_back(line);
if (debug) cerr << line << ' ';
}
if (debug) cerr << endl;
}
// TODO "prunepaths="
// whitelist /tmp , /media
// ignore paths that doesn't even exist
// warn on other (e.g.: /var/spool)
if (debug) cerr << "theoretical length=" << header.conf_size << endl; // BAD !! UNSIGNED CHAR
if (debug) cerr << "actual length=" << ((int) mlocate.tellg() - param_start - 1) << endl << endl;
if (debug) cerr << "MLOCATE DATA\n";
char * dir = new char [sizeof(db_directory)];
string dirname;
string filename;
//fs.reserve(200000);
while ( mlocate.good() ) {
mlocate.read (dir,sizeof(db_directory));
getline(mlocate,dirname,'\0');
if (mlocate.eof()) break;
char filetype; // =sizeof(db_entry)
string toplevel = dirname.substr(0, dirname.find('/', 1));
if ( toplevel == "/dev"
/* have a peek into /home, but not deeper */
or (toplevel == "/home" and dirname != "/home")
or toplevel == "/mnt"
or toplevel == "/root"
or toplevel == "/tmp"
or dirname == "/var/lib/dpkg/info")
while ((mlocate.get()) != DBE_END) {
mlocate.ignore(std::numeric_limits<int>::max(), '\0');
} else while ((filetype = mlocate.get()) != DBE_END) {
getline(mlocate,filename,'\0');
string fullpath=dirname + '/' + filename;
if (!pyc_has_py(fullpath, debug))
fs.emplace_back(fullpath);
}
}
mlocate.close();
// default PRUNEPATH in /etc/updatedb.conf
fs.emplace_back("/var/spool");
try {
for (const auto& entry: filesystem::recursive_directory_iterator{"/var/spool", filesystem::directory_options::skip_permission_denied})
{
fs.emplace_back(entry.path());
}
} catch(const exception& e) {
cerr << "Failed to iterate directory /var/spool/: " << e.what() << endl;
}
sort(fs.begin(), fs.end());
fs.erase( unique( fs.begin(), fs.end() ), fs.end() );
//if (debug) cerr << prunefs.size() << " relevant records in PRUNEFS database" << endl;
if (debug) cerr << fs.size() << " relevant files in MLOCATE database" << endl << endl;
return 0;
}