Branch data Line data Source code
1 : : /**
2 : : *
3 : : * @file precizer.c
4 : : * @brief Main file
5 : : *
6 : : */
7 : : #include "precizer.h"
8 : :
9 : : /**
10 : : * Global definitions
11 : : *
12 : : */
13 : :
14 : : // Global variable controls signals to interrupt execution
15 : : // Atomic variable is very fast and will be called very often
16 : : _Atomic bool global_interrupt_flag = false;
17 : :
18 : : // The global structure Config where all runtime settings will be stored
19 : : Config _config;
20 : : Config *config = &_config;
21 : :
22 : : /**
23 : : * @mainpage
24 : : * @brief precizer is a CLI application designed to verify the integrity of files after synchronization.
25 : : * The program recursively traverses directories and creates a database
26 : : * of files and their checksums, followed by a quick comparison.
27 : : *
28 : : * @author Dennis Razumovsky
29 : : * @details precizer specializes in managing vast file systems.
30 : : * The program identifies synchronization errors by cross-referencing
31 : : * data and checksums from various sources. Alternatively, it can be
32 : : * used to crawl historical changes by comparing databases from the
33 : : * same sources over different times
34 : : */
35 : : #ifndef TESTITALL // Unit testing library
36 : 190 : int main(
37 : : int argc,
38 : : char **argv)
39 : : #else
40 : 187 : int test_main(
41 : : int argc,
42 : : char **argv)
43 : : #endif // TESTITALL
44 : : {
45 : : /* Status returned by this function through provide()
46 : : Default value assumes successful completion */
47 : 377 : Return status = SUCCESS;
48 : :
49 : : // Stack storage for traversal stats, zero-initialized.
50 : 377 : TraversalSummary _summary = {0};
51 : : // Use pointer form for consistency.
52 : 377 : TraversalSummary *summary = &_summary;
53 : :
54 : : // Initialize configuration with values
55 : 377 : init_config();
56 : :
57 : : // Fill Config structure
58 : : // parsing command line arguments
59 [ + - + + ]: 377 : run(parse_arguments(argc,argv));
60 : :
61 : : // Print program identity only when argument parsing is not in info mode
62 [ + + ]: 377 : if((status & INFO) == false)
63 : : {
64 : 347 : about();
65 : : }
66 : :
67 : : // Verify that the provided paths exist and
68 : : // are directories
69 [ + + - + ]: 377 : run(paths_detect());
70 : :
71 : : // Initialize signals interception like Ctrl+C
72 [ + + - + ]: 377 : run(init_signals());
73 : :
74 : : // The current directory where app being executed
75 [ + + - + ]: 377 : run(determine_running_dir());
76 : :
77 : : // Generate DB file name if
78 : : // not passed as an argument
79 [ + + - + ]: 377 : run(db_determine_name());
80 : :
81 : : // Validate database file existence and set up existence flag
82 [ + + + + ]: 377 : run(db_primary_file_validate_existence());
83 : :
84 : : // Define the database operation mode
85 [ + + + + ]: 377 : run(db_determine_mode());
86 : :
87 : : // Primary database file integrity check
88 [ + + + + ]: 377 : run(db_primary_file_test());
89 : :
90 : : // Initialize SQLite database
91 [ + + + + ]: 377 : run(db_init());
92 : :
93 : : // Compare databases
94 [ + + + + ]: 377 : run(db_compare());
95 : :
96 : : // Check whether the database already exists or not yet
97 [ + + + + ]: 377 : run(db_contains_data());
98 : :
99 : : // Verify that the provided path arguments match
100 : : // the paths stored in the database
101 [ + + + + ]: 377 : run(db_validate_paths());
102 : :
103 : : // Save new prefixes that has been passed as
104 : : // arguments
105 [ + + - + ]: 377 : run(db_save_prefixes());
106 : :
107 : : // Just get a statistic
108 : 377 : summary->stats_only_pass = true;
109 [ + + - + ]: 377 : run(file_list(summary));
110 : :
111 : : // Get file list and their checksums
112 : 377 : summary->stats_only_pass = false;
113 [ + + + + ]: 377 : run(file_list(summary));
114 : :
115 : : // Update the database. Remove files that
116 : : // no longer exist.
117 [ + + - + ]: 377 : run(db_delete_missing_metadata());
118 : :
119 : : // Print remembered warning and error lines if --progress is enabled.
120 [ - + + + ]: 377 : call(show_remembered_messages());
121 : :
122 : : // Print final totals and runtime metrics after delayed warnings/errors.
123 : : // This runs only for successful execution flow.
124 [ + + ]: 377 : if((SUCCESS|WARNING) & status)
125 : : {
126 : 343 : show_statistics(summary);
127 : 343 : show_elapsed(summary);
128 : : }
129 : :
130 : : // Disable journaling, flush the journal to the main database,
131 : : // clear the cache, and close the database
132 [ - + + + ]: 377 : call(db_close(config->db,&config->db_primary_file_modified));
133 : :
134 : : // Optimizing the space occupied by a database file.
135 [ + + - + ]: 377 : run(db_primary_consider_vacuum());
136 : :
137 : : // Print out whether there have been changes to
138 : : // the file system and accordingly against the database
139 : : // since the last research
140 [ + + + + ]: 377 : run(status_of_changes());
141 : :
142 : : // Free allocated memory
143 : : // for arrays and variables
144 : 377 : free_config();
145 : :
146 : 377 : return(exit_status(status,argv));
147 : : }
|