Index: trunk/pol-core/pol/pol.cpp =================================================================== --- trunk/pol-core/pol/pol.cpp (revision 535) +++ trunk/pol-core/pol/pol.cpp (working copy) @@ -75,6 +75,8 @@ #include #include "dtrace.h" +#include "../clib/cfgelem.h" +#include "../clib/cfgfile.h" #include "../clib/dualbuf.h" #include "../clib/endian.h" #include "../clib/esignal.h" @@ -1685,6 +1687,7 @@ void catch_signals_thread( void ); void check_console_commands(); void reload_configuration(); +void ScriptScheduleThread ( void ); void console_thread( void ) { @@ -1706,6 +1709,8 @@ } } + + void start_threads() { threadmap.Register( thread_pid(), "Main" ); @@ -1760,12 +1765,320 @@ checkpoint( "start clienttransmit thread" ); start_thread( ClientTransmitThread, "ClientTransmit" ); + checkpoint( "start scriptschedule thread" ); + start_thread( ScriptScheduleThread, "ScriptSchedule" ); + #ifndef _WIN32 //checkpoint( "start catch_signals thread" ); //start_thread( catch_signals_thread, "CatchSignals" ); #endif } + +void ScriptScheduleThread ( void ) //aqui +{ + + //todo: put this on another file! + //todo: split this in functions. + //todo: load schedule.cfg in all packpages. + + ConfigFile cf; + + if (FileExists( "config/schedule.cfg" )) + { + cf.open( "config/schedule.cfg" ); + } + else + { + //if not exists, just quit + return; + } + + ConfigElem elem; + + //schedule prototype + struct schedeled_script { + string name; + string script; + unsigned short day; + unsigned short month; + unsigned short hour; + unsigned short minute; + bool repeat; + bool critical; + bool startup; + vector week; + }; + + //vector tasks will store schedule information + vector tasks; + vector ::iterator this_task; + + unsigned short int startscript = 0; + + while (cf.read( elem )) + { + if (!elem.type_is( "Schedule" )) + continue; + + schedeled_script this_task; + this_task.name = elem.remove_string( "NAME", "no label" ); + this_task.script = elem.remove_string( "SCRIPT", "" ); + this_task.hour = elem.remove_int( "HOUR", 24 ); //default 24 cuz need to declare this + this_task.day = elem.remove_int( "DAY", 0 ); //0 = every day + this_task.month = elem.remove_int( "MONTH", 0 ); //0 = every month + this_task.minute = elem.remove_int( "MIN", 0 ); //0 means o'clock + this_task.repeat = elem.remove_bool ( "REPEAT", true ); //if false this task will be deleted after first launch + this_task.critical = elem.remove_bool ( "CRITIC", false ); //if true this task will run in critical mode + this_task.startup = elem.remove_bool ( "STARTUP", false ); //if true this task will run only one time after startup, like a 'start.ecl' + + string day_of_week = elem.remove_string ( "WEEK", "" ); //days of the week to run this task + + if (this_task.script == "") //no script + { + cout << "Warning! invalid script entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + //script exists? + ScriptDef this_script; + if (!this_script.config_nodie( this_task.script, 0, 0 )) + { + cout << "Warning! invalid script entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + if ( !this_script.exists() ) + { + cout << "Warning! invalid script entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + if (this_task.startup == false) //is a normal shedule task, check if attributes are all okey before + { + if (day_of_week != "") + { + vector days; + ISTRINGSTREAM is (day_of_week); + string temp; + + //TODO: no case sensitive. + while (is >> temp) + { + const char *today = temp.c_str(); + if (!strcmp (today, "all")) + { + for (int n = 1; n <= 7; n++) + days.push_back(n); + } + if (!strcmp (today, "weekday")) + { + for (int n = 1; n <= 5; n++) + days.push_back(n); + } + if (!strcmp (today, "weekend")) + { + for (int n = 6; n <= 7; n++) + days.push_back(n); + } + else if (!strcmp (today, "sun")) + days.push_back(7); + else if (!strcmp (today, "mon")) + days.push_back(1); + else if (!strcmp (today, "tue")) + days.push_back(2); + else if (!strcmp (today, "wed")) + days.push_back(3); + else if (!strcmp (today, "thu")) + days.push_back(4); + else if (!strcmp (today, "fri")) + days.push_back(5); + else if (!strcmp (today, "sat")) + days.push_back(6); + } + + if (!days.empty()) + this_task.week = days; + else + { + cout << "Warning! invalid week entry. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + } + + if (this_task.hour > 23) //hours goes from 0 to 23 + { + cout << "Warning! invalid hour entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + if (this_task.month > 12) //month goes from 0 to 12 + { + cout << "Warning! invalid month entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + if (this_task.day > 31) //days goes from 0 to 31 + { + cout << "Warning! invalid day entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + + if (this_task.minute > 59) //minutes goes from 0 to 59 + { + cout << "Warning! invalid day entry in script schedule. See " << this_task.name << " in schedule.cfg\n" << endl; + continue; + } + } + + else // this is a startup task, launch now. + { + // TODO: launch routines and script valid checks should be inside a function. + if (this_task.critical == true) + { + //critical script + if (! run_script_to_completion ( this_script )) + { + cout << "Could not start startup script for task " << this_task.name << "." << endl; + } + else + { + cout << "Startup -> initiating " << this_task.name << "." << endl; + startscript++; + } + } + else + { + //normal script + if (! start_script ( this_script, 0 ) ) + { + cout << "Could not start startup script for task " << this_task.name << "." << endl; + } + else + { + cout << "Startup -> initiating " << this_task.name << "." << endl; + startscript++; + } + } + continue; // no need store. + } + + tasks.push_back (this_task); + } + + cout << startscript << " scripts launched during startup schedule." << endl; + + while (!exit_signalled) + { + + time_t now = time(0); + tm *ltm = localtime (&now); + + //DEBUG: show schedule cicles + //cout << "schedule time: " << ltm->tm_hour << ":" << ltm->tm_min << ":" << ltm->tm_sec << endl; + + for (this_task = tasks.begin(); this_task != tasks.end();) + + { + //check mouth + if ( this_task->month != 0 ) + { + if ( this_task->month != (ltm->tm_mon + 1) ) + { + this_task++; + continue; + } + } + + //check day + if (this_task->day != 0) + { + if ( this_task->day != ltm->tm_mday ) + { + this_task++; + continue; + } + } + + //check week day + if (!this_task->week.empty()) + { + bool resultado = find (this_task->week.begin(), this_task->week.end(), ltm->tm_wday) != this_task->week.end(); + if (!resultado) + { + this_task++; + continue; + } + } + + //check hour + if (this_task->hour == ltm->tm_hour) + { + //if hour okey, need to check minutes + if (this_task->minute == ltm->tm_min) + { + //Hour and Minutes okey, time to check script again before start it + ScriptDef sd; + if (sd.config_nodie( this_task->script, 0, 0 )) + { + if (sd.exists()) + { + //its all okey, time to launch the script + if (this_task->critical == true) + { + //critical script + if (!run_script_to_completion ( sd )) + { + cout << "Could not start script " << this_task->script << " for scheduled task " << this_task->name << "." << endl; + } + } + else + { + //normal script + if (! start_script ( sd, 0 ) ) + { + cout << "Could not start script " << this_task->script << " for scheduled task " << this_task->name << "." << endl; + } + } + + //check if this is a repetible task: + if (this_task->repeat == false) + { + //remove this task + tasks.erase (this_task); + continue; + } + } + else + { + cout << "Script for task scheduled " << this_task->name << " does not exists any more." << endl; + } + } + else + { + cout << "Script for task scheduled " << this_task->name << " got some problem to initialize." << endl; + } + } + } + + this_task++; + + } //forloop end + + //Check every 1min + for (unsigned short int n = 1; n <= 60; n++) + { + if (exit_signalled) + { + return; + } + pol_sleep_ms (1000); + } + + } //whileloop end + +}//void end + void check_incoming_data(void) { unsigned cli;