Updated timestamps
[deliverable/titan.core.git] / mctr2 / mctr / main.cc
CommitLineData
d44e3c4f 1/******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Bene, Tamas
12 * Beres, Szabolcs
13 * Czimbalmos, Eduard
14 * Delic, Adam
15 * Lovassy, Arpad
16 * Raduly, Csaba
17 * Szabados, Kristof
18 * Szabo, Janos Zoltan – initial implementation
19 *
20 ******************************************************************************/
970ed795
EL
21//
22// Description: Implementation file for main
23// Author: Vilmos Varga
24// mail: ethvva@eth.ericsson.se
25//
3abe9331 26// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
27//
28//----------------------------------------------------------------------------
29
30#include <stdio.h>
31#include <string.h>
32#include <stdlib.h>
33#include <dirent.h>
34#include <time.h>
35#include <unistd.h>
36
37// STL include stuff
38#include <string>
39#include <vector>
40#include <map>
41#include <iostream>
42#include <fstream>
43
44#include "../../common/memory.h"
45#include "../../common/path.h"
46#include "../../common/version_internal.h"
47
48#ifdef LICENSE
49#include "../../common/license.h"
50#endif
51
52#include "MainController.h"
53
54#if defined CLI
55#include "../cli/Cli.h"
56#else
57#error "CLI must be defined"
58#endif
59
60extern int config_read_debug;
61
62/* ASCII ART STUFF */
63
64std::vector<std::string> split(const char separator, const std::string& source_str, bool drop_empty=true)
65{
66 std::vector<std::string> str_vec;
67 const char* begin_pos = source_str.data();
68 const char* end_pos = begin_pos + source_str.length(); // points behind the last char
69 for (const char* act_pos = begin_pos; act_pos<end_pos; act_pos++)
70 {
71 if ( *act_pos==separator )
72 {
73 if (!drop_empty || (act_pos>begin_pos))
74 str_vec.push_back(std::string(begin_pos, act_pos-begin_pos));
75 begin_pos = act_pos+1;
76 }
77 }
78 if (!drop_empty || (end_pos>begin_pos)) str_vec.push_back(std::string(begin_pos, end_pos-begin_pos));
79 return str_vec;
80}
81
82std::vector<std::string> get_directory_files(const std::string& directory)
83{
84 std::vector<std::string> file_list;
85 DIR *dir = opendir(directory.c_str());
86 if (dir==NULL) return file_list;
87 struct dirent *ent;
88 while ((ent=readdir(dir))!=NULL) {
89 std::string file_name = ent->d_name;
90 if (get_path_status((directory+"/"+file_name).c_str())==PS_FILE) file_list.push_back(file_name);
91 }
92 closedir(dir);
93 return file_list;
94}
95
96void print_ascii_art(const std::string& file_path)
97{
98 try {
99 std::ifstream ifs(file_path.c_str(), std::ifstream::in);
100 while (ifs.good()) {
101 int c = (char)ifs.get();
102 if (c<0) c = '\n';
103 std::cout << (char)c;
104 }
105 ifs.close();
106 }
107 catch (...) { /* stfu */ }
108}
109
110struct current_condition_data
111{
112 std::string user;
113 struct tm time;
114 current_condition_data();
115};
116current_condition_data::current_condition_data()
117{
118 const char* user_name = getlogin(); // TODO: use getpwuid(getuid())
119 user = user_name ? std::string(user_name) : "";
120 time_t rawtime;
121 ::time(&rawtime);
122 struct tm * curr_tm = localtime(&rawtime);
123 time = *curr_tm;
124}
125
126typedef bool (*condition_function)(const std::string& value, const current_condition_data& curr_data);
127typedef std::map<std::string,condition_function> condition_map;
128
129bool condition_user(const std::string& value, const current_condition_data& curr_data)
130{
131 return value==curr_data.user;
132}
133
134// sets the interval or returns false if invalid input
135bool get_interval(const std::string& value, int& a, int& b)
136{
137 std::vector<std::string> nums = split('_', value);
138 switch (nums.size()) {
139 case 1:
140 a = b = atoi(nums[0].c_str());
141 return true;
142 case 2:
143 a = atoi(nums[0].c_str());
144 b = atoi(nums[1].c_str());
145 return true;
146 default: ;
147 }
148 return false;
149}
150
151bool is_in_interval(const std::string& interval, int i)
152{
153 int a,b;
154 if (!get_interval(interval, a, b)) return false;
155 return a<=i && i<=b;
156}
157
158bool condition_weekday(const std::string& value, const current_condition_data& curr_data)
159{
160 return is_in_interval(value, curr_data.time.tm_wday ? curr_data.time.tm_wday : 7); // 1 - 7
161}
162
163bool condition_day(const std::string& value, const current_condition_data& curr_data)
164{
165 return is_in_interval(value, curr_data.time.tm_mday); // 1 - 31
166}
167
168bool condition_month(const std::string& value, const current_condition_data& curr_data)
169{
170 return is_in_interval(value, curr_data.time.tm_mon+1); // 1 - 12
171}
172
173bool condition_year(const std::string& value, const current_condition_data& curr_data)
174{
175 return is_in_interval(value, curr_data.time.tm_year+1900);
176}
177
178bool condition_hour(const std::string& value, const current_condition_data& curr_data)
179{
180 return is_in_interval(value, curr_data.time.tm_hour); // 0 - 23
181}
182
183bool condition_minute(const std::string& value, const current_condition_data& curr_data)
184{
185 return is_in_interval(value, curr_data.time.tm_min); // 0 - 59
186}
187
188bool condition_second(const std::string& value, const current_condition_data& curr_data)
189{
190 return is_in_interval(value, curr_data.time.tm_sec); // 0 - 61
191}
192
193condition_map create_condition_map()
194{
195 condition_map cond_map;
196 cond_map.insert(make_pair("user",condition_user));
197 cond_map.insert(make_pair("weekday",condition_weekday));
198 cond_map.insert(make_pair("day",condition_day));
199 cond_map.insert(make_pair("month",condition_month));
200 cond_map.insert(make_pair("year",condition_year));
201 cond_map.insert(make_pair("hour",condition_hour));
202 cond_map.insert(make_pair("minute",condition_minute));
203 cond_map.insert(make_pair("second",condition_second));
204 return cond_map;
205}
206
207// display random ascii art, if there was an error don't report it
208void display_ascii_art()
209{
210 std::string asciiart_dir;
211 const char* ttcn3_asciiart_dir = getenv("TTCN3_ASCIIART_DIR");
212 if (ttcn3_asciiart_dir!=NULL) {
213 if (strlen(ttcn3_asciiart_dir)==0) return;
214 asciiart_dir = ttcn3_asciiart_dir;
215 } else {
216 const char* ttcn3_dir = getenv("TTCN3_DIR");
217 asciiart_dir = ttcn3_dir ? ttcn3_dir : "";
218 asciiart_dir += (asciiart_dir.size()>0 && asciiart_dir[asciiart_dir.size()-1]=='/') ? "" : "/";
219 asciiart_dir += "etc/asciiart";
220 }
221 if (get_path_status(asciiart_dir.c_str())!=PS_DIRECTORY) return;
222 std::vector<std::string> asciiart_files = get_directory_files(asciiart_dir);
223 std::vector<std::string> normal_active_files; // files that don't have special filter
224 std::vector<std::string> special_active_files; // files that have special filter
225 condition_map cond_map = create_condition_map();
226 current_condition_data curr_data; // calculate current data for conditions only once, before entering loops
227 for (std::vector<std::string>::iterator file_name_i = asciiart_files.begin(); file_name_i<asciiart_files.end(); file_name_i++) {
228 std::vector<std::string> file_name_parts = split('.', *file_name_i);
229 bool is_special = false;
230 bool is_active = true;
231 for (std::vector<std::string>::iterator name_part_i = file_name_parts.begin(); name_part_i<file_name_parts.end(); name_part_i++) {
232 std::vector<std::string> condition = split('-', *name_part_i);
233 if (condition.size()==2) {
234 const std::string& cond_name = condition[0];
235 const std::string& cond_value = condition[1];
236 condition_map::iterator cond_iter = cond_map.find(cond_name);
237 if (cond_iter!=cond_map.end()) {
238 is_special = true;
239 is_active = is_active && (cond_iter->second)(cond_value, curr_data);
240 }
241 }
242 }
243 if (is_active) {
244 if (is_special) special_active_files.push_back(*file_name_i);
245 else normal_active_files.push_back(*file_name_i);
246 }
247 }
248 srand(time(NULL));
249 if (special_active_files.size()>0) {
250 print_ascii_art(asciiart_dir + "/" + special_active_files[rand()%special_active_files.size()]);
251 } else if (normal_active_files.size()>0) {
252 print_ascii_art(asciiart_dir + "/" + normal_active_files[rand()%normal_active_files.size()]);
253 }
254}
255
256/* Main function */
257
258using namespace mctr;
259
260int main(int argc, char *argv[])
261{
262#ifndef NDEBUG
263 config_read_debug = (getenv("DEBUG_CONFIG") != NULL);
264#endif
265
266 display_ascii_art();
267
268 if (argc == 2 && !strcmp(argv[1], "-v")) {
269 fputs("Main Controller "
270#if defined CLI
271 "(CLI)"
272#endif
273 " for the TTCN-3 Test Executor\n"
274 "Product number: " PRODUCT_NUMBER "\n"
275 "Build date: " __DATE__ " " __TIME__ "\n"
276 "Compiled with: " C_COMPILER_VERSION "\n\n"
277 COPYRIGHT_STRING "\n\n", stderr);
278#ifdef LICENSE
279 print_license_info();
280 fputs("\nUsing ", stderr);
281 fputs(openssl_version_str(), stderr);
282 fputs("\n\n", stderr);
283#endif
284 return 0;
285 }
286
287 int max_ptcs;
288#ifdef LICENSE
289 license_struct lstr;
290 init_openssl();
291 load_license(&lstr);
292 if (!verify_license(&lstr)) {
293 free_license(&lstr);
294 free_openssl();
295 exit(EXIT_FAILURE);
296 }
297 if (!check_feature(&lstr, FEATURE_MCTR)) {
298 fputs("The license key does not allow the starting of TTCN-3 "
299 "Main Controller.\n", stderr);
300 return 2;
301 }
302 max_ptcs = lstr.max_ptcs;
303 free_license(&lstr);
304 free_openssl();
305#else
306 max_ptcs = -1;
307#endif
308 int ret_val;
309 {
310#if defined CLI
311 cli::Cli
312#endif
313 userInterface;
314
315 userInterface.initialize();
316 MainController::initialize(userInterface, max_ptcs);
317
318 ret_val = userInterface.enterLoop(argc, argv);
319
320 MainController::terminate();
321 }
322 check_mem_leak(argv[0]);
323
324 return ret_val;
325}
326
327// Local Variables:
328// mode: C++
329// indent-tabs-mode: nil
330// c-basic-offset: 2
331// End:
This page took 0.035612 seconds and 5 git commands to generate.