📄 schedcore.c
字号:
}#endif/* * determine the time for the next scheduled action of a given entry */voidsched_nextTime( struct schedTable_entry *entry ){ time_t now; struct tm now_tm, next_tm; int rev_day, mon; time( &now ); if ( !entry ) { DEBUGMSGTL(("disman:schedule:time", "missing entry\n")); return; } if ( entry->schedCallbackID ) snmp_alarm_unregister( entry->schedCallbackID ); if (!(entry->flags & SCHEDULE_FLAG_ENABLED) || !(entry->flags & SCHEDULE_FLAG_ACTIVE)) { DEBUGMSGTL(("disman:schedule:time", "inactive entry\n")); return; } switch ( entry->schedType ) { case SCHED_TYPE_PERIODIC: if ( !entry->schedInterval ) { DEBUGMSGTL(("disman:schedule:time", "periodic: no interval\n")); return; } if ( entry->schedLastRun ) { entry->schedNextRun = entry->schedLastRun + entry->schedInterval; } else { entry->schedNextRun = now + entry->schedInterval; } DEBUGMSGTL(("disman:schedule:time", "periodic: (%d) %s", entry->schedNextRun, ctime(&entry->schedNextRun))); break; case SCHED_TYPE_ONESHOT: if ( entry->schedLastRun ) { DEBUGMSGTL(("disman:schedule:time", "one-shot: expired (%d) %s", entry->schedNextRun, ctime(&entry->schedNextRun))); return; } /* Fallthrough */ DEBUGMSGTL(("disman:schedule:time", "one-shot: fallthrough\n")); case SCHED_TYPE_CALENDAR: /* * Check for complete time specification * If any of the five fields have no bits set, * the entry can't possibly match any time. */ if ( _bit_allClear( entry->schedMinute, 8 ) || _bit_allClear( entry->schedHour, 3 ) || _bit_allClear( entry->schedDay, 4+4 ) || _bit_allClear( entry->schedMonth, 2 ) || _bit_allClear(&entry->schedWeekDay, 1 )) { DEBUGMSGTL(("disman:schedule:time", "calendar: incomplete spec\n")); return; } /* * Calculate the next run time: * * If the current Month, Day & Hour bits are set * calculate the next specified minute * If this fails (or the current Hour bit is not set) * use the first specified minute, * and calculate the next specified hour * If this fails (or the current Day bit is not set) * use the first specified minute and hour * and calculate the next specified day (in this month) * If this fails (or the current Month bit is not set) * use the first specified minute and hour * calculate the next specified month, and * the first specified day (in that month) */ localtime_r( &now, &now_tm ); localtime_r( &now, &next_tm ); next_tm.tm_mon=-1; next_tm.tm_mday=-1; next_tm.tm_hour=-1; next_tm.tm_min=-1; next_tm.tm_sec=0; if ( _bit_set( entry->schedMonth, now_tm.tm_mon )) { next_tm.tm_mon = now_tm.tm_mon; rev_day = _daysPerMonth[ now_tm.tm_mon ] - now_tm.tm_mday; if ( _bit_set( &entry->schedWeekDay, now_tm.tm_wday ) && (_bit_set( entry->schedDay, now_tm.tm_mday-1 ) || _bit_set( entry->schedDay, 31+rev_day ))) { next_tm.tm_mday = now_tm.tm_mday; if ( _bit_set( entry->schedHour, now_tm.tm_hour )) { next_tm.tm_hour = now_tm.tm_hour; /* XXX - Check Fall timechange */ next_tm.tm_min = _bit_next( entry->schedMinute, now_tm.tm_min, 8 ); } else { next_tm.tm_min = -1; } if ( next_tm.tm_min == -1 ) { next_tm.tm_min = _bit_next( entry->schedMinute, -1, 8 ); next_tm.tm_hour = _bit_next( entry->schedHour, now_tm.tm_hour, 3 ); } } else { next_tm.tm_hour = -1; } if ( next_tm.tm_hour == -1 ) { next_tm.tm_min = _bit_next( entry->schedMinute, -1, 8 ); next_tm.tm_hour = _bit_next( entry->schedHour, -1, 3 ); /* Handle leap years */ mon = now_tm.tm_mon; if ( mon == 1 && (now_tm.tm_year%4 == 0) ) mon = 12; next_tm.tm_mday = _bit_next_day( entry->schedDay, entry->schedWeekDay, now_tm.tm_mday, mon, now_tm.tm_year ); } } else { next_tm.tm_min = _bit_next( entry->schedMinute, -1, 2 ); next_tm.tm_hour = _bit_next( entry->schedHour, -1, 3 ); next_tm.tm_mday = -1; next_tm.tm_mon = now_tm.tm_mon; } while ( next_tm.tm_mday == -1 ) { next_tm.tm_mon = _bit_next( entry->schedMonth, next_tm.tm_mon, 2 ); if ( next_tm.tm_mon == -1 ) { next_tm.tm_year++; next_tm.tm_mon = _bit_next( entry->schedMonth, -1, 2 ); } /* Handle leap years */ mon = next_tm.tm_mon; if ( mon == 1 && (next_tm.tm_year%4 == 0) ) mon = 12; next_tm.tm_mday = _bit_next_day( entry->schedDay, entry->schedWeekDay, -1, mon, next_tm.tm_year ); /* XXX - catch infinite loop */ } /* XXX - Check for Spring timechange */ /* * 'next_tm' now contains the time for the next scheduled run */ entry->schedNextRun = mktime( &next_tm ); DEBUGMSGTL(("disman:schedule:time", "calendar: (%d) %s", entry->schedNextRun, ctime(&entry->schedNextRun))); return; default: DEBUGMSGTL(("disman:schedule:time", "unknown type (%d)\n", entry->schedType)); return; } entry->schedCallbackID = snmp_alarm_register( entry->schedNextRun - now, 0, _sched_callback, entry ); return;}voidsched_nextRowTime( netsnmp_tdata_row *row ){ sched_nextTime((struct schedTable_entry *) row->data );}/* * create a new row in the table */netsnmp_tdata_row *schedTable_createEntry(const char *schedOwner, const char *schedName){ struct schedTable_entry *entry; netsnmp_tdata_row *row; DEBUGMSGTL(("disman:schedule:entry", "creating entry (%s, %s)\n", schedOwner, schedName)); entry = SNMP_MALLOC_TYPEDEF(struct schedTable_entry); if (!entry) return NULL; row = netsnmp_tdata_create_row(); if (!row) { SNMP_FREE(entry); return NULL; } row->data = entry; /* * Set the indexing for this entry, both in the row * data structure, and in the table_data helper. */ if (schedOwner) { memcpy(entry->schedOwner, schedOwner, strlen(schedOwner)); } memcpy( entry->schedName, schedName, strlen(schedName)); netsnmp_tdata_row_add_index(row, ASN_OCTET_STR, (entry->schedOwner || ""), ((schedOwner) ? strlen(schedOwner) : 0)); netsnmp_tdata_row_add_index(row, ASN_OCTET_STR, entry->schedName, strlen(schedName)); /* * Set the (non-zero) default values in the row data structure. */ entry->schedType = SCHED_TYPE_PERIODIC; entry->schedVariable_len = 2; /* .0.0 */ netsnmp_tdata_add_row(schedule_table, row); return row;}/* * remove a row from the table */voidschedTable_removeEntry(netsnmp_tdata_row *row){ struct schedTable_entry *entry; if (!row || !row->data) { DEBUGMSGTL(("disman:schedule:entry", "remove: missing entry\n")); return; /* Nothing to remove */ } entry = (struct schedTable_entry *) netsnmp_tdata_remove_and_delete_row(schedule_table, row); if (entry) { DEBUGMSGTL(("disman:schedule:entry", "remove entry (%s, %s)\n", entry->schedOwner, entry->schedName)); SNMP_FREE(entry); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -