diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..40316d2 --- /dev/null +++ b/src/log.h @@ -0,0 +1,72 @@ +#include +#include +/** + * 0: LOG_TRACE + * 1: LOG_DEBUG + * 2: LOG_INFO + * 3: LOG_WARN + * 4: LOG_ERROR + * 5: LOG_CRITICAL + * 6: LOG_NONE + */ +#define DEBUG 0 + +#define timeStrRollSize 5 +char timeStr[timeStrRollSize][20]; +unsigned char timeStrI = 0; +char *timeToStr(time_t t){ + unsigned char i = timeStrI; + timeStrI++; + if(timeStrI == timeStrRollSize) + timeStrI = 0; + if(t == 0) + t = time(NULL); + struct tm T = *localtime(&t); + sprintf(&timeStr[i][0], "%04d-%02d-%02d %2d:%02d:%02d", + T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec); + return &timeStr[i][0]; +} +char *timeToStr2(struct tm T){ + unsigned char i = timeStrI; + timeStrI++; + if(timeStrI == timeStrRollSize) + timeStrI = 0; + sprintf(&timeStr[i][0], "%04d-%02d-%02d %2d:%02d:%02d", + T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec); + return &timeStr[i][0]; +} + +#define Log(ll, msg, ...) printf("%s - " ll ": " msg "\n", timeToStr(0), __VA_ARGS__) + +#if DEBUG <= 0 +#define logTrace(...) Log("TRACE", __VA_ARGS__) +#else +#define logTrace(...) +#endif +#if DEBUG <= 1 +#define logDebug(...) Log("DEBUG", __VA_ARGS__) +#else +#define logDebug(...) +#endif +#if DEBUG <= 2 +#define logInfo(...) Log("INFO", __VA_ARGS__) +#else +#define logInfo(...) +#endif +#if DEBUG <= 3 +#define logWarn(...) Log("WARN", __VA_ARGS__) +#else +#define logWarn(...) +#endif +#if DEBUG <= 4 +#define logError(...) Log("ERROR", __VA_ARGS__) +#else +#define logError(...) +#endif +#if DEBUG <= 5 +#define logCritical(...) Log("CRITICAL", __VA_ARGS__) +#else +#define logCritical(...) +#endif + + diff --git a/src/main.c b/src/main.c index d4e46a9..cb8fdbe 100644 --- a/src/main.c +++ b/src/main.c @@ -4,124 +4,141 @@ #include #include #include +#include -#define DEBUG +#include "log.h" + +#define MAX_NUMBER_OF_SCRIPTS 128 typedef struct { uint32_t scheduler[5]; uint32_t next; char filename[128]; } Script_t; -Script_t *Scripts[128]; +Script_t Scripts[MAX_NUMBER_OF_SCRIPTS]; -#ifdef DEBUG -char timestr[19]; -char *timeToStr(time_t t){ - struct tm T = *localtime(&t); - sprintf(×tr[0], "%04d-%02d-%02d %d:%02d:%02d", T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec); - return ×tr[0]; -} -char *timeToStr2(struct tm T){ - sprintf(×tr[0], "%04d-%02d-%02d %d:%02d:%02d", T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec); - return ×tr[0]; -} -#endif - -uint32_t getNextTrigger(Script_t *script){ - uint8_t daysInMouth[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - time_t ti = time(NULL); +uint8_t DaysInMouth[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +struct tm getNextTriggerDay(Script_t *script, time_t ti){ struct tm t = *localtime(&ti); while(1){ - printf("mounth: %d (%s), mask: 0x%x\n", t.tm_mon, timeToStr2(t), script->scheduler[3]); + logTrace("mounth: %2d (%s), mask: 0x%08x", t.tm_mon, timeToStr2(t), script->scheduler[3]); if(1 << (t.tm_mon) & script->scheduler[3]){ while(1){ - printf("day: %d (%s), mask: 0x%x\n", t.tm_mday, timeToStr2(t), script->scheduler[2]); + logTrace("day : %2d (%s), mask: 0x%08x", t.tm_mday, timeToStr2(t), script->scheduler[2]); if(1 << (t.tm_mday) & script->scheduler[2]){ - while(1){ - printf("hour: %d (%s), mask: 0x%x\n", t.tm_hour, timeToStr2(t), script->scheduler[1]); - if(1 << (t.tm_hour) & script->scheduler[1]){ - while(1){ - printf("minute: %d (%s), mask: 0x%x\n", t.tm_min, timeToStr2(t), script->scheduler[1]); - if(1 << (t.tm_hour) & script->scheduler[1]){ - return mktime(&t); - } - t.tm_min++; - if(t.tm_min > 60){ - t.tm_min = 0; - t.tm_sec = 0; - break; - } - } - } - t.tm_hour++; - if(t.tm_hour > 23){ - t.tm_hour = 0; - t.tm_min = 0; - t.tm_sec = 0; - break; - } + time_t ti = mktime(&t); + t = *localtime(&ti); // get the weekday of the date + logTrace("wekday: %2d (%s), mask: 0x%08x", t.tm_wday, timeToStr2(t), script->scheduler[4]); + if(1 << (t.tm_wday) & script->scheduler[4]){ + return t; } } t.tm_mday++; - if(t.tm_mday > daysInMouth[t.tm_mon]){ + t.tm_hour = 0; + t.tm_min = 0; + if(t.tm_mday > DaysInMouth[t.tm_mon]){ t.tm_mday = 1; - t.tm_hour = 0; - t.tm_min = 0; - t.tm_sec = 0; break; } } } t.tm_mon++; + t.tm_mday = 1; + t.tm_hour = 0; + t.tm_min = 0; if(t.tm_mon >= 12){ t.tm_year++; + if(t.tm_year-1 > localtime(&ti)->tm_year){ + time_t zero = 0; + return *localtime(&zero); // no posible time this and next year (t.tm_min is just 0, it needs a pointer) + } t.tm_mon = 0; - t.tm_mday = 1; - t.tm_hour = 0; + } + } +} + +time_t getNextTrigger(Script_t *script, time_t startTime){ + logTrace("Search time of next trigger for '%s'", script->filename); + struct tm t = getNextTriggerDay(script, (startTime == 0) ? time(NULL) : startTime); + if(t.tm_year == 70){ + logError("no time found to run this or next year for '%s'", script->filename); + return 0; + } + if(t.tm_sec != 0){ + t.tm_sec = 0; + if(t.tm_min = 59){ t.tm_min = 0; - t.tm_sec = 0; + t.tm_hour++; + }else{ + t.tm_min++; + } + } + while(1){ + logTrace("hour : %2d (%s), mask: 0x%08x", t.tm_hour, timeToStr2(t), script->scheduler[1]); + if(1 << (t.tm_hour) & script->scheduler[1]){ + while(1){ + if(t.tm_min%1 == 0) + t.tm_min + 1; // make minut even + logTrace("minute: %2d (%s), mask: 0x%08x", t.tm_min, timeToStr2(t), script->scheduler[0]); + if(1 << (t.tm_min/2) & script->scheduler[0]){ + logTrace("next trigger found for '%s': %s", script->filename, timeToStr2(t)); + return mktime(&t); + } + t.tm_min+=2; + if(t.tm_min >= 60){ + t.tm_min = 0; + break; + } + } + } + t.tm_hour++; + t.tm_min = 0; + if(t.tm_hour > 23){ + if(startTime != 0){ + logError("something went wrong when getting next trigger time for '%s'", script->filename); + return 0; + }else{ + logError("trigger was today. rerun to get the real next.%s", ""); + // set time the the start of the next day + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 0; + if(t.tm_mday == DaysInMouth[t.tm_mon]){ + t.tm_mday = 1; + if(t.tm_mon == 11){ + t.tm_mon = 0; + t.tm_year++; + }else + t.tm_mon++; + }else + t.tm_mday++; + // get the date agen bedouse today is no next run anymore + return getNextTrigger(script, mktime(&t)); + } } } } //TODO: add devide option //TOOD: add full file name instad of only extention -Script_t *getSchedule(char *str){ +void getSchedule(Script_t *script, char *str){ uint8_t is = 0; - Script_t scit; - scit.scheduler[0] = - scit.scheduler[1] = - scit.scheduler[2] = - scit.scheduler[3] = - scit.scheduler[4] = 0; + script->scheduler[0] = + script->scheduler[1] = + script->scheduler[2] = + script->scheduler[3] = + script->scheduler[4] = 0; int8_t cmd[3]; cmd[0] = cmd[1] = cmd[2] = 0; + logTrace("get the scheduler for '%s'", str); + // read the filename uint8_t ic; for(ic=0; iccmd[1]; i--){ - scit.scheduler[is] |= 1<scheduler[is] = ~0; break; case '0' ... '9': // read a number if(cmd[0] == '-'){ // the second numer of a range should not be overritten @@ -134,7 +151,7 @@ Script_t *getSchedule(char *str){ break; case ',': // list of times cmd[0] = ','; - scit.scheduler[is] |= (is == 0) ? 1<<(cmd[1]/2) : 1<scheduler[is] |= (is == 0) ? 1<<(cmd[1]/2) : 1<cmd[1]; i--){ + script->scheduler[is] |= 1<scheduler[is] |= (is == 0) ? 1<<(cmd[1]/2) : 1<filename, str, strlen(str)+1); + + logInfo("scheduler: [0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x]", + script->scheduler[0], + script->scheduler[1], + script->scheduler[2], + script->scheduler[3], + script->scheduler[4] + ); // get next time to trigger - scit.next = getNextTrigger(&scit); + script->next = getNextTrigger(script, 0); -#ifdef DEBUG - printf("scheduler: [\n 0x%08x\n 0x%08x\n 0x%08x\n 0x%08x\n 0x%08x\n]\nnext trigger: %s\nfilename: %s\n", - scit.scheduler[0], - scit.scheduler[1], - scit.scheduler[2], - scit.scheduler[3], - scit.scheduler[4], - timeToStr(scit.next), - scit.filename + logInfo("add script '%s' (next trigger: %s)", + script->filename, + (script->next == 0) ? "(none)" : timeToStr(script->next) ); -#endif } void getScripts(){ + logTrace("open script directory%s", ""); DIR *ScriptDir = opendir("./scripts"); uint8_t i=0; while(i < 128){ @@ -181,12 +219,34 @@ void getScripts(){ //TODO: add simbolic link suport if(script->d_type != DT_REG) continue; - - Scripts[i] = getSchedule(script->d_name); + #if DEBUG == 0 + printf("\n"); + logTrace("found file '%s'", script->d_name); + #endif + getSchedule(&Scripts[i], script->d_name); i++; } } void main(){ + for(uint8_t i=MAX_NUMBER_OF_SCRIPTS; i > 0; i--){ + Scripts[i].next = 0; + } getScripts(); -} \ No newline at end of file + time_t nextScriptTrigger = time(NULL) + 30 * 24 * 60 * 60; + Script_t *scriptToTrigger = NULL; + for(uint8_t i=MAX_NUMBER_OF_SCRIPTS; i > 0; i--){ + if(Scripts[i].next == 0) + continue; + if(Scripts[i].next < nextScriptTrigger){ + nextScriptTrigger = Scripts[i].next; + scriptToTrigger = &Scripts[i]; + } + } + uint32_t timeToSleep = nextScriptTrigger - time(NULL); + logInfo("sleep for %d (%d:%2d:%2d) seconds to %s%s%s", + timeToSleep, timeToSleep/3600, (timeToSleep/60) % 60, timeToSleep % 60, + (scriptToTrigger == NULL) ? "refrash scripts" : " run script '", + (scriptToTrigger == NULL) ? "" : scriptToTrigger->filename, + (scriptToTrigger == NULL) ? "" : "'"); +}