26 #include <relpipe/writer/Factory.h> |
26 #include <relpipe/writer/Factory.h> |
27 #include <relpipe/writer/TypeId.h> |
27 #include <relpipe/writer/TypeId.h> |
28 |
28 |
29 #include <relpipe/cli/CLI.h> |
29 #include <relpipe/cli/CLI.h> |
30 |
30 |
|
31 #include "CLIParser.h" |
|
32 #include "Configuration.h" |
|
33 #include "FstabCommand.h" |
|
34 |
31 using namespace relpipe::cli; |
35 using namespace relpipe::cli; |
32 using namespace relpipe::writer; |
36 using namespace relpipe::writer; |
33 |
37 using namespace relpipe::in::fstab; |
34 /** |
|
35 * see https://hg.frantovo.cz/sql-api/file/tip/prototyp/prototyp.sql#l49 |
|
36 */ |
|
37 void processDataStream(ostream &output, istream* input) { |
|
38 wregex devicePattern = wregex(L"(LABEL|UUID)=(.*)"); |
|
39 wregex linePattern = wregex(L"^([^\\s#]+)\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s*$"); |
|
40 wstring_convert < codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings. |
|
41 |
|
42 std::shared_ptr<RelationalWriter> writer(Factory::create(output)); |
|
43 |
|
44 writer->startRelation(L"fstab",{ |
|
45 {L"scheme", TypeId::STRING}, |
|
46 {L"device", TypeId::STRING}, |
|
47 {L"mount_point", TypeId::STRING}, |
|
48 {L"type", TypeId::STRING}, |
|
49 // {L"types", TypeId::STRING}, // TODO: array |
|
50 {L"options", TypeId::STRING}, // TODO: array |
|
51 {L"dump", TypeId::INTEGER}, |
|
52 {L"pass", TypeId::INTEGER} |
|
53 }, true); |
|
54 |
|
55 string lineBytes; |
|
56 while (getline(*input, lineBytes)) { |
|
57 |
|
58 wstring line = convertor.from_bytes(lineBytes); |
|
59 wsmatch lineMatch; |
|
60 if (regex_search(line, lineMatch, linePattern) && lineMatch.size() > 0) { |
|
61 int g = 1; |
|
62 wstring device = lineMatch[g++]; |
|
63 wstring mountPoint = lineMatch[g++]; |
|
64 wstring type = lineMatch[g++]; |
|
65 wstring options = lineMatch[g++]; |
|
66 wstring dump = lineMatch[g++]; |
|
67 wstring pass = lineMatch[g++]; |
|
68 |
|
69 wsmatch deviceMatch; |
|
70 if (regex_search(device, deviceMatch, devicePattern)) { |
|
71 writer->writeAttribute(deviceMatch[1]); |
|
72 writer->writeAttribute(deviceMatch[2]); |
|
73 } else { |
|
74 writer->writeAttribute(L""); // TODO: null (requires bitmap) |
|
75 writer->writeAttribute(device); |
|
76 } |
|
77 |
|
78 if (mountPoint == L"none") mountPoint = L""; // TODO: null (requires bitmap) |
|
79 writer->writeAttribute(mountPoint); |
|
80 writer->writeAttribute(type); |
|
81 writer->writeAttribute(options); |
|
82 writer->writeAttribute(dump); |
|
83 writer->writeAttribute(pass); |
|
84 } |
|
85 } |
|
86 |
|
87 } |
|
88 |
38 |
89 int main(int argc, char** argv) { |
39 int main(int argc, char** argv) { |
90 setlocale(LC_ALL, ""); |
40 setlocale(LC_ALL, ""); |
91 CLI::untieStdIO(); |
41 CLI::untieStdIO(); |
92 //CLI cli(argc, argv); |
42 CLI cli(argc, argv); |
93 |
43 |
94 int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR; |
44 int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR; |
95 |
45 |
96 try { |
46 try { |
|
47 CLIParser cliParser; |
|
48 Configuration configuration = cliParser.parse(cli.arguments()); |
|
49 FstabCommand command; |
|
50 std::shared_ptr<RelationalWriter> writer(Factory::create(std::cout)); |
|
51 |
97 if (isatty(fileno(stdin))) { |
52 if (isatty(fileno(stdin))) { |
98 /** |
53 /** |
99 * Our program is executed on TTY without input stream redirection → read from default file location. |
54 * Our program is executed on TTY without input stream redirection → read from default file location. |
100 * e.g. $ relpipe-in-fstab | … |
55 * e.g. $ relpipe-in-fstab | … |
101 * (we don't expect that user is writing the content of fstab by hand on the terminal) |
56 * (we don't expect that user is writing the content of fstab by hand on the terminal) |
102 */ |
57 */ |
103 ifstream s("/etc/fstab"); |
58 ifstream s("/etc/fstab"); |
104 processDataStream(cout, &s); |
59 command.process(s, writer, configuration); |
105 } else { |
60 } else { |
106 /** |
61 /** |
107 * Input stream comes from a file or is piped from other command → read it instead of default file. |
62 * Input stream comes from a file or is piped from other command → read it instead of default file. |
108 * e.g. $ cat /etc/fstab | grep '/mnt/' | relpipe-in-fstab | … |
63 * e.g. $ cat /etc/fstab | grep '/mnt/' | relpipe-in-fstab | … |
109 * or $ relpipe-in-fstab < /etc/fstab | … # without UUoC |
64 * or $ relpipe-in-fstab < /etc/fstab | … # without UUoC |
110 * or $ ssh example.com cat /etc/fstab | relpipe-in-fstab | … |
65 * or $ ssh example.com cat /etc/fstab | relpipe-in-fstab | … |
111 * or $ cat | relpipe-in-fstab | … # user writes the fstab content by hand |
66 * or $ cat | relpipe-in-fstab | … # user writes the fstab content by hand |
|
67 * or $ cat /etc/mtab | relpipe-in-fstab | relpipe-out-tabular | less -RSi # currently mounted filesystems |
112 */ |
68 */ |
113 processDataStream(cout, &cin); |
69 command.process(std::cin, writer, configuration); |
114 } |
70 } |
|
71 |
115 resultCode = CLI::EXIT_CODE_SUCCESS; |
72 resultCode = CLI::EXIT_CODE_SUCCESS; |
116 |
73 } catch (RelpipeCLIException e) { |
|
74 fwprintf(stderr, L"Caught CLI exception: %ls\n", e.getMessge().c_str()); |
|
75 fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); |
|
76 resultCode = e.getExitCode(); |
117 } catch (RelpipeWriterException e) { |
77 } catch (RelpipeWriterException e) { |
118 fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str()); |
78 fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str()); |
119 fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); |
79 fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); |
120 resultCode = CLI::EXIT_CODE_DATA_ERROR; |
80 resultCode = CLI::EXIT_CODE_DATA_ERROR; |
121 } |
81 } |