📄 schedcore.c
字号:
/* * DisMan Schedule MIB: * Core implementation of the schedule handling behaviour */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "disman/schedule/schedCore.h"#include "utilities/iquery.h"netsnmp_tdata *schedule_table; /* * Initialize the container for the schedule table, * regardless of which initialisation routine is called first. */voidinit_schedule_container(void){ DEBUGMSGTL(("disman:schedule:init", "init schedule container\n")); if (!schedule_table) { schedule_table = netsnmp_tdata_create_table("schedTable", 0); DEBUGMSGTL(("disman:schedule:init", "create schedule container(%x)\n", schedule_table)); }}/** Initializes the schedCore module */voidinit_schedCore(void){ /* * Create a table structure for the schedule table * This will typically be registered by the schedTable module */ DEBUGMSGTL(("disman:schedule:init", "Initializing core module\n")); init_schedule_container();}/* * Callback to invoke a scheduled action */static void_sched_callback( unsigned int reg, void *magic ){ struct schedTable_entry *entry = (struct schedTable_entry *)magic; int ret; netsnmp_variable_list assign; if ( !entry ) { DEBUGMSGTL(("disman:schedule:callback", "missing entry\n")); return; } entry->schedLastRun = time(0); entry->schedTriggers++; DEBUGMSGTL(( "disman:schedule:callback", "assignment ")); DEBUGMSGOID(("disman:schedule:callback", entry->schedVariable, entry->schedVariable_len)); DEBUGMSG(( "disman:schedule:callback", " = %d\n", entry->schedValue)); memset(&assign, 0, sizeof(netsnmp_variable_list)); snmp_set_var_objid(&assign, entry->schedVariable, entry->schedVariable_len); snmp_set_var_typed_value(&assign, ASN_INTEGER, (u_char *)&entry->schedValue, sizeof(entry->schedValue)); ret = netsnmp_query_set( &assign, entry->session ); if ( ret != SNMP_ERR_NOERROR ) { DEBUGMSGTL(( "disman:schedule:callback", "assignment failed (%d)\n", ret)); entry->schedFailures++; entry->schedLastFailure = ret; time ( &entry->schedLastFailed ); } sched_nextTime( entry );} /* * Internal utility routines to help interpret * calendar-based schedule bit strings */static char _masks[] = { /* 0xff, */ 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };static char _bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };/* * Are any of the bits set? */static int_bit_allClear( char *pattern, int len ) { int i; for (i=0; i<len; i++) { if ( pattern[i] != 0 ) return 0; /* At least one bit set */ } return 1; /* All bits clear */ }/* * Is a particular bit set? */static int_bit_set( char *pattern, int bit ) { int major, minor; major = bit/8; minor = bit%8; if ( pattern[major] & _bits[minor] ) { return 1; /* Specified bit is set */ } return 0; /* Bit not set */}/* * What is the next bit set? * (after a specified point) */static int_bit_next( char *pattern, int current, size_t len ) { char buf[ 8 ]; int major, minor, i, j; /* Make a working copy of the bit pattern */ memset( buf, 0, 8 ); memcpy( buf, pattern, len ); /* * If we're looking for the first bit after some point, * then clear all earlier bits from the working copy. */ if ( current > -1 ) { major = current/8; minor = current%8; for ( i=0; i<major; i++ ) buf[i]=0; buf[major] &= _masks[minor]; } /* * Look for the first bit that's set */ for ( i=0; i<len; i++ ) { if ( buf[i] != 0 ) { major = i*8; for ( j=0; j<8; j++ ) { if ( buf[i] & _bits[j] ) { return major+j; } } } } return -1; /* No next bit */}static int _daysPerMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 29 };static char _truncate[] = { 0xfe, 0xf0, 0xfe, 0xfc, 0xfe, 0xfc, 0xfe, 0xfe, 0xfc, 0xfe, 0xfc, 0xfe, 0xf8 };/* * What is the next day with a relevant bit set? * * Merge the forward and reverse day bits into a single * pattern relevant for this particular month, * and apply the standard _bit_next() call. * Then check this result against the day of the week bits. */static int_bit_next_day( char *day_pattern, char weekday_pattern, int day, int month, int year ) { char buf[4]; union { char buf2[4]; int int_val; } rev; int next_day, i; struct tm tm_val; /* Make a working copy of the forward day bits ... */ memset( buf, 0, 4 ); memcpy( buf, day_pattern, 4 ); /* ... and another (right-aligned) of the reverse day bits */ memset( rev.buf2, 0, 4 ); memcpy( rev.buf2, day_pattern+4, 4 ); rev.int_val >>= 2; if ( buf[3] & 0x01 ) rev.buf2[0] |= 0x40; if ( month == 3 || month == 5 || month == 8 || month == 10 ) rev.int_val >>= 1; /* April, June, September, November */ if ( month == 1 ) rev.int_val >>= 3; /* February */ if ( month == 12 ) rev.int_val >>= 2; /* February (leap year) */ /* Combine the two bit patterns, and truncate to the month end */ for ( i=0; i<4; i++ ) { if ( rev.buf2[i] & 0x80 ) buf[3-i] |= 0x01; if ( rev.buf2[i] & 0x40 ) buf[3-i] |= 0x02; if ( rev.buf2[i] & 0x20 ) buf[3-i] |= 0x04; if ( rev.buf2[i] & 0x10 ) buf[3-i] |= 0x08; if ( rev.buf2[i] & 0x08 ) buf[3-i] |= 0x10; if ( rev.buf2[i] & 0x04 ) buf[3-i] |= 0x20; if ( rev.buf2[i] & 0x02 ) buf[3-i] |= 0x40; if ( rev.buf2[i] & 0x01 ) buf[3-i] |= 0x80; } buf[3] &= _truncate[ month ]; next_day = day-1; /* tm_day is 1-based, not 0-based */ do { next_day = _bit_next( buf, next_day, 4 ); if ( next_day < 0 ) return -1; /* * Calculate the day of the week, and * check this against the weekday pattern */ memset( &tm_val, 0, sizeof(struct tm)); tm_val.tm_mday = next_day+1; tm_val.tm_mon = month; tm_val.tm_year = year; mktime( &tm_val ); } while ( !_bit_set( &weekday_pattern, tm_val.tm_wday )); return next_day+1; /* Convert back to 1-based list */}#ifndef HAVE_LOCALTIME_Rstruct tm *localtime_r(const time_t *timep, struct tm *result) { struct tm *tmp; tmp = localtime( timep ); if ( tmp && result ) { memcpy( result, tmp, sizeof(struct tm)); } return (tmp ? result : NULL );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -