-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfile_audit.cpp
More file actions
175 lines (166 loc) · 7.21 KB
/
file_audit.cpp
File metadata and controls
175 lines (166 loc) · 7.21 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Include the necessary libraries
#include <iostream>
#include <string>
#include <sstream>
#include <filesystem>
#include <fstream>
#include <chrono>
#include <iomanip>
#include <cmath>
#include "progress.h"
// Use the std namespace
using namespace std;
// Define a function to parse the command line arguments and return the values
void parse_args(int argc, char* argv[], string& dir, string& csvfile, string& type) {
// Loop through the arguments
for (int i = 1; i < argc; i++) {
if (string(argv[i]) == "-h") {
// Print the usage message and exit
cout << "Usage: " << argv[0] << " --dir <directory> --csvfile <csv file> --type <file type>\n";
cout << "Options:\n";
cout << " --dir <directory> Specify the directory to scan recursively\n";
cout << " --csvfile <csv file> Specify the output csv file name\n";
cout << " --type <file type> Specify the file extension type to filter - use .pdf not pdf - include \n";
cout << " -h Show this help message and exit\n";
exit(0);
}
// Check if the argument is --dir
if (string(argv[i]) == "--dir") {
// Check if the next argument exists and is not another option
if (i + 1 < argc && argv[i + 1][0] != '-') {
// Assign the next argument to dir
dir = argv[i + 1];
// Increment i to skip the next argument
i++;
}
else {
// Throw an exception if the argument is invalid
throw invalid_argument("Missing or invalid value for --dir");
}
}
// Check if the argument is --csvfile
else if (string(argv[i]) == "--csvfile") {
// Check if the next argument exists and is not another option
if (i + 1 < argc && argv[i + 1][0] != '-') {
// Assign the next argument to csvfile
csvfile = argv[i + 1];
// Increment i to skip the next argument
i++;
}
else {
// Throw an exception if the argument is invalid
throw invalid_argument("Missing or invalid value for --csvfile");
}
}
// Check if the argument is --type
else if (string(argv[i]) == "--type") {
// Check if the next argument exists and is not another option
if (i + 1 < argc && argv[i + 1][0] != '-') {
// Assign the next argument to type
type = argv[i + 1];
// Increment i to skip the next argument
i++;
}
else {
// Throw an exception if the argument is invalid
throw invalid_argument("Missing or invalid value for --type");
}
}
else {
// Throw an exception if the argument is unknown
throw invalid_argument("Unknown option: " + string(argv[i]));
}
}
}
// Define a function to format a file time point as YYYY/MM/DD HH:MM:SS
string format_time(filesystem::file_time_type file_time) {
// Convert the file time point to system clock time point
auto sys_time = chrono::time_point_cast<chrono::system_clock::duration>(file_time - filesystem::file_time_type::clock::now() + chrono::system_clock::now());
// Convert the system clock time point to time_t
time_t tt = chrono::system_clock::to_time_t(sys_time);
// Convert the time_t to tm structure
tm local_tm = *localtime(&tt);
// Create a string stream to format the output
stringstream ss;
// Write the year, month, day, hour, minute and second to the stream with leading zeros and separators
ss << setw(4) << setfill('0') << local_tm.tm_year + 1900 << "/";
ss << setw(2) << setfill('0') << local_tm.tm_mon + 1 << "/";
ss << setw(2) << setfill('0') << local_tm.tm_mday << " ";
ss << setw(2) << setfill('0') << local_tm.tm_hour << ":";
ss << setw(2) << setfill('0') << local_tm.tm_min << ":";
ss << setw(2) << setfill('0') << local_tm.tm_sec;
// Return the formatted string
return ss.str();
}
// Define a function to write the output to a csv file
void write_csv(const string& dir, const string& csvfile, const string& type) {
// Create an output file stream and open the csv file
ofstream ofs;
ofs.open(csvfile);
int num_found = 0;
int num_search = 0;
float percent = 0.0;
float amount = 0.0;
ProgressBar bar(100);
// Check if the file stream is open and ready
if (ofs.is_open()) {
// Write the header row to the csv file
ofs << "File Name,Directory,Size,Date\n";
// Loop through the directory entries in the given directory recursively
int file_count = std::distance(filesystem::recursive_directory_iterator(dir), filesystem::recursive_directory_iterator{});
cout << "Total number of files in directory: " << file_count << endl;
percent = file_count/100*1.0;
amount = percent * 100.0;
// cout << " amount " << amount << endl;
if ( file_count - int(amount) > 10 )
{
percent = percent + 1.0;
// cout << "upping\n";
}
// cout << "calcualted percent" << percent << endl;
for (const auto& entry : filesystem::recursive_directory_iterator(dir)) {
num_search++;
// Chck if the entry is a regular file and has the given extension type
// :cout << entry.path().filename().string() << " " << entry.path().extension() << endl;
if ( (num_search % (int)percent) == 0 )
{
bar.update(1);
// cout << num_found << endl;
}
if (entry.is_regular_file() && entry.path().extension() == type) {
num_found++;
// Write the file name, directory, size and date to the csv file with commas as separators and quotes as delimiters
ofs << "\"" << entry.path().filename().string() << "\",";
ofs << "\"" << entry.path().parent_path().string() << "\",";
ofs << "\"" << entry.file_size() << "\",";
ofs << "\"" << format_time(entry.last_write_time()) << "\"\n";
}
}
bar.close();
// Close the file stream
cout << "\nNumber of entires matched: " << num_found << endl;
ofs.close();
}
else {
// Throw an exception if the file stream is not open or ready
throw runtime_error("Failed to open or write to " + csvfile);
}
}
// Define the main function
int main(int argc, char* argv[]) {
try {
// Declare variables for directory, csv file and type arguments
string dir, csvfile, type;
// Parse the command line arguments and assign values to variables
parse_args(argc, argv, dir, csvfile, type);
// Write the output to a csv file with given arguments
write_csv(dir, csvfile, type);
// Print a success message to standard output
cout << "Output written to " << csvfile << "\n";
}
catch (const exception& e) {
// Print an error message to standard error with exception message
cerr << "Error: " << e.what() << "\n";
return 1;
}
}