0b9d788019bb313c58f32a30d8900b581ea3cdf8
[platform/core/system/libdbuspolicy.git] / src / dbuspolicy_serializer.cpp
1 #include <unistd.h>
2 #include <getopt.h>
3
4 #include <algorithm>
5 #include <iomanip>
6 #include <iostream>
7 #include <fstream>
8 #include <sstream>
9 #include "internal/serializer.hpp"
10 #include "dbuspolicy1/libdbuspolicy1.h"
11 #include "libdbuspolicy1-private.h"
12
13 #include <openssl/sha.h>
14
15 using namespace std;
16
17 static const struct option options[] = {
18         {"system", no_argument, 0, 0 },
19         {"session", no_argument, 0, 0},
20         {0, 0, 0, 0}
21 };
22
23 static void print_help(const char *name) {
24         cout << endl;
25         cout << "usage: " << name << " [-j] [-o output_filename] <input_filename>" << endl;
26         cout << "       " << name << " {--system|--session} [-j] [-o output_filename]" << endl;
27         cout << endl;
28         cout << "If not specified, output_filename is input_filename.serialized" << endl;
29         cout << " -j - don't write anything, just check if the output file is valid and up to date" << endl;
30         cout << endl;
31 }
32
33 static int check(const char *input_filename, const std::string &output_filename) {
34         bool ok = false;
35
36         cout << "Read from: " << input_filename << ", checking " << output_filename << "..." << endl;
37         ldp_xml_parser::Serializer serializer;
38         ostringstream output;
39         serializer.serialize(input_filename, output);
40
41         ifstream serialized(output_filename, ifstream::binary|ifstream::ate);
42
43         if (serialized && output.tellp() == serialized.tellg()) {
44                 serialized.seekg(0, ifstream::beg);
45
46                 ok = equal(istreambuf_iterator<char>(serialized),
47                                    istreambuf_iterator<char>(),
48                                    output.str().begin());
49         }
50         cout << output_filename << " is " << (ok ? "valid and up to date" : "not updated or invalid") << endl;
51         return ok ? EXIT_SUCCESS : EXIT_FAILURE;
52 }
53
54 int main(int argc, char *argv[])
55 {
56         bool need_input_filename = true;
57         bool just_check = false;
58         std::string output_filename;
59         const char *input_filename = system_bus_conf_file_primary();
60         int c;
61
62         while (1) {
63                 int option_index;
64                 c = getopt_long(argc, argv, "o:j", options, &option_index);
65                 if (c == -1)
66                         break;
67
68                 switch(c) {
69                 case 0:
70                         if (option_index == 1)
71                                 input_filename = session_bus_conf_file_primary();
72                         need_input_filename = false;
73                         break;
74                 case 'o':
75                         output_filename = optarg;
76                         break;
77                 case 'j':
78                         just_check = true;
79                         break;
80                 }
81         }
82
83         if (need_input_filename) {
84                 if (optind < argc) {
85                         input_filename = argv[optind];
86                 } else {
87                         print_help(argv[0]);
88                         return EXIT_FAILURE;
89                 }
90         }
91
92         if (output_filename.empty())
93                 output_filename = std::string(input_filename) + ".serialized";
94
95         if (just_check)
96                 return check(input_filename, output_filename);
97
98         cout << "Read from: " << input_filename << " write to: " << output_filename << endl;
99         ldp_xml_parser::Serializer serializer;
100         ofstream output(output_filename, ofstream::binary);
101
102         uint8_t *data = serializer.serialize(input_filename, output);
103
104         if (output.fail()) {
105                 cout << "Write FAILED." << endl;
106                 return EXIT_FAILURE;
107         }
108
109         cout << "Write " << output.tellp() << " bytes" << endl;
110
111         array<unsigned char, SHA_DIGEST_LENGTH> digest;
112         string sha1_filename = output_filename + ".sha1";
113         ofstream output_sha1(sha1_filename);
114
115         SHA1(data, output.tellp(), digest.data());
116
117         output_sha1 << hex;
118         for_each(digest.begin(), digest.end(), [&](uint16_t c) { output_sha1 << setw(2) << setfill('0') << c; });
119         output_sha1 << " *" << output_filename << endl;
120
121         cout << "SHA1 written to " << sha1_filename << endl;
122
123         return EXIT_SUCCESS;
124 }