~ubuntu-branches/debian/lenny/net-snmp/lenny

« back to all changes in this revision

Viewing changes to agent/mibgroup/disman/schedule/schedConf.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-05-10 22:20:23 UTC
  • Revision ID: james.westby@ubuntu.com-20070510222023-3fr07xb9i17xvq32
Tags: upstream-5.3.1
ImportĀ upstreamĀ versionĀ 5.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DisMan Schedule MIB:
 
3
 *     Implementation of the schedule MIB config handling
 
4
 */
 
5
 
 
6
#include <net-snmp/net-snmp-config.h>
 
7
#include <net-snmp/net-snmp-includes.h>
 
8
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
9
#include <ctype.h>
 
10
#include "disman/schedule/schedCore.h"
 
11
#include "disman/schedule/schedConf.h"
 
12
 
 
13
static int schedEntries;
 
14
 
 
15
/** Initializes the schedConf module */
 
16
void
 
17
init_schedConf(void)
 
18
{
 
19
    DEBUGMSGTL(("disman:schedule:init", "Initializing config module\n"));
 
20
    init_schedule_container();
 
21
 
 
22
    /*
 
23
     * Register public configuration directives
 
24
     */
 
25
    snmpd_register_config_handler("repeat", parse_sched_periodic, NULL,
 
26
                                  "repeat period  OID = value");
 
27
    snmpd_register_config_handler("cron",   parse_sched_timed,    NULL,
 
28
                                  "cron * * * * * OID = value");
 
29
    snmpd_register_config_handler("at",     parse_sched_timed,    NULL,
 
30
                                  "at   * * * * * OID = value");
 
31
 
 
32
    /*
 
33
     * Register internal configuration directive,
 
34
     *   and arrange for dynamically configured entries to be saved
 
35
     */
 
36
    snmpd_register_config_handler("_schedTable", parse_schedTable, NULL, NULL);
 
37
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
 
38
                                     store_schedTable, NULL);
 
39
    schedEntries = 0;
 
40
}
 
41
 
 
42
 
 
43
/* =======================================================
 
44
 *
 
45
 * Handlers for user-configured (static) scheduled actions
 
46
 *
 
47
 * ======================================================= */
 
48
 
 
49
void
 
50
parse_sched_periodic( const char *token, char *line )
 
51
{
 
52
    netsnmp_tdata_row       *row;
 
53
    struct schedTable_entry *entry;
 
54
    char   buf[24];
 
55
    long   frequency;
 
56
    long   value;
 
57
    size_t tmpint;
 
58
    oid    variable[ MAX_OID_LEN], *var_ptr = variable;
 
59
    size_t var_len = MAX_OID_LEN;
 
60
    
 
61
    schedEntries++;
 
62
    sprintf(buf, "_conf%03d", schedEntries);
 
63
 
 
64
    DEBUGMSGTL(( "disman:schedule:conf", "periodic: %s %s\n", token, line));
 
65
    /*
 
66
     *  Parse the configure directive line
 
67
     */
 
68
    line = read_config_read_data(ASN_INTEGER,   line, &frequency, &tmpint);
 
69
    line = read_config_read_data(ASN_OBJECT_ID, line, &var_ptr,   &var_len);
 
70
    if (var_len == 0) {
 
71
        config_perror("invalid specification for schedVariable");
 
72
        return;
 
73
    }
 
74
    /*
 
75
     * Skip over optional assignment in "var = value"
 
76
     */
 
77
    while (line && isspace(*line))
 
78
        line++;
 
79
    if (line && *line == '=' ) {
 
80
        line++;
 
81
        while (line && isspace(*line)) {
 
82
            line++;
 
83
        }
 
84
    }
 
85
    line = read_config_read_data(ASN_INTEGER,   line, &value, &tmpint);
 
86
    
 
87
    /*
 
88
     * Create an entry in the schedTable
 
89
     */
 
90
    row   = schedTable_createEntry( "snmpd.conf", buf );
 
91
    if (!row || !row->data) {
 
92
        config_perror("create schedule entry failure");
 
93
        return;
 
94
    }
 
95
    entry = (struct schedTable_entry *)row->data;
 
96
 
 
97
    entry->schedInterval     = frequency;
 
98
    entry->schedValue        = value;
 
99
    entry->schedVariable_len = var_len;
 
100
    memcpy(entry->schedVariable, variable, var_len*sizeof(oid));
 
101
 
 
102
    entry->schedType         = SCHED_TYPE_PERIODIC;
 
103
    entry->schedStorageType  = ST_READONLY;  /* or PERMANENT */
 
104
    entry->flags             = SCHEDULE_FLAG_ENABLED |
 
105
                               SCHEDULE_FLAG_ACTIVE  |
 
106
                               SCHEDULE_FLAG_VALID;
 
107
    entry->session           = netsnmp_query_get_default_session();
 
108
    sched_nextTime( entry );
 
109
}
 
110
 
 
111
 
 
112
/*
 
113
 * Timed-schedule utility:
 
114
 *     Convert from a cron-style specification to the equivalent set
 
115
 *     of bits. Note that minute, hour and weekday crontab fields are
 
116
 *     0-based, while day and month more naturally start from 1.
 
117
 */
 
118
void
 
119
_sched_convert_bits( char *cron_spec, char *bit_buf,
 
120
                     int  bit_buf_len, int max_val, int startAt1 ) {
 
121
    char *cp = cron_spec;
 
122
    char b[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
 
123
    int val, major, minor;
 
124
    int overshoot;
 
125
 
 
126
    if (!cron_spec || !bit_buf)
 
127
        return;
 
128
 
 
129
    /*
 
130
     * Wildcard field - set all bits
 
131
     */
 
132
    if ( *cp == '*' ) {
 
133
        memset( bit_buf, 0xff, bit_buf_len );
 
134
 
 
135
        /*
 
136
         * An "all-bits" specification may not be an exact multiple of 8.
 
137
         * Work out how far we've overshot things, and tidy up the excess.
 
138
         */
 
139
        overshoot = 8*bit_buf_len-max_val;
 
140
        while ( overshoot > 0 ) {
 
141
            bit_buf[ bit_buf_len-1 ] ^= b[8-overshoot];
 
142
            overshoot--;
 
143
        }
 
144
        return;
 
145
    }
 
146
 
 
147
    /*
 
148
     * Otherwise, clear the bit string buffer,
 
149
     * and start calculating which bits to set
 
150
     */
 
151
    memset( bit_buf, 0, bit_buf_len );
 
152
 
 
153
    while (1) {
 
154
        sscanf( cp, "%d", &val);
 
155
        /* Handle negative day specification */
 
156
        if ( val < 0 ) {
 
157
            val = max_val - val; 
 
158
        }
 
159
        if ( startAt1 )
 
160
            val--;
 
161
        major = val/8;
 
162
        minor = val%8;
 
163
        bit_buf[ major ] |= b[minor];
 
164
 
 
165
        /* XXX - ideally we should handle "X-Y" syntax as well */
 
166
        while (*cp && *cp!=',')
 
167
            cp++;
 
168
        if (!*cp)
 
169
            break;
 
170
        cp++;
 
171
    }
 
172
}
 
173
 
 
174
void
 
175
parse_sched_timed( const char *token, char *line )
 
176
{
 
177
    netsnmp_tdata_row       *row;
 
178
    struct schedTable_entry *entry;
 
179
    char   buf[24], *cp;
 
180
 
 
181
    char  minConf[512];  size_t  min_len = sizeof(minConf);  char  minVal[8];
 
182
    char hourConf[512];  size_t hour_len = sizeof(hourConf); char hourVal[3];
 
183
    char dateConf[512];  size_t date_len = sizeof(dateConf); char dateVal[8];
 
184
    char  monConf[512];  size_t  mon_len = sizeof(monConf);  char  monVal[2];
 
185
    char  dayConf[512];  size_t  day_len = sizeof(dayConf);  char  dayVal;
 
186
 
 
187
    long   value;
 
188
    size_t tmpint;
 
189
    oid    variable[ MAX_OID_LEN], *var_ptr = variable;
 
190
    size_t var_len = MAX_OID_LEN;
 
191
    
 
192
    schedEntries++;
 
193
    sprintf(buf, "_conf%03d", schedEntries);
 
194
 
 
195
    DEBUGMSGTL(( "sched", "config: %s %s\n", token, line));
 
196
    /*
 
197
     *  Parse the configure directive line
 
198
     */
 
199
    cp       = minConf;
 
200
    line = read_config_read_data(ASN_OCTET_STR, line, &cp,   &min_len);
 
201
    cp       = hourConf;
 
202
    line = read_config_read_data(ASN_OCTET_STR, line, &cp,  &hour_len);
 
203
    cp       = dateConf;
 
204
    line = read_config_read_data(ASN_OCTET_STR, line, &cp,  &date_len);
 
205
    cp       = monConf;
 
206
    line = read_config_read_data(ASN_OCTET_STR, line, &cp,   &mon_len);
 
207
    cp       = dayConf;
 
208
    line = read_config_read_data(ASN_OCTET_STR, line, &cp,   &day_len);
 
209
    if (!line) {
 
210
        config_perror("invalid schedule time specification");
 
211
        return;
 
212
    }
 
213
 
 
214
    line = read_config_read_data(ASN_OBJECT_ID, line, &var_ptr,   &var_len);
 
215
    if (var_len == 0) {
 
216
        config_perror("invalid specification for schedVariable");
 
217
        return;
 
218
    }
 
219
    /*
 
220
     * Skip over optional assignment in "var = value"
 
221
     */
 
222
    while (line && isspace(*line))
 
223
        line++;
 
224
    if ( *line == '=' ) {
 
225
        line++;
 
226
        while (line && isspace(*line)) {
 
227
            line++;
 
228
        }
 
229
    }
 
230
    line = read_config_read_data(ASN_INTEGER,   line, &value, &tmpint);
 
231
 
 
232
    /*
 
233
     * Convert from cron-style specifications into bits
 
234
     */
 
235
    _sched_convert_bits( minConf,  minVal,  8, 60, 0 );
 
236
    _sched_convert_bits( hourConf, hourVal, 3, 24, 0 );
 
237
    memset(dateVal+4, 0, 4); /* Clear the reverse day bits */
 
238
    _sched_convert_bits( dateConf, dateVal, 4, 31, 1 );
 
239
    _sched_convert_bits( monConf,  monVal,  2, 12, 1 );
 
240
    _sched_convert_bits( dayConf, &dayVal,  1,  8, 0 );
 
241
    if ( dayVal & 0x01 ) {  /* sunday(7) = sunday(0) */
 
242
         dayVal |= 0x80;
 
243
         dayVal &= 0xfe;
 
244
    }
 
245
    
 
246
    /*
 
247
     * Create an entry in the schedTable
 
248
     */
 
249
    row   = schedTable_createEntry("snmpd.conf", buf);
 
250
    if (!row || !row->data) {
 
251
        config_perror("create schedule entry failure");
 
252
        return;
 
253
    }
 
254
    entry = (struct schedTable_entry *)row->data;
 
255
 
 
256
    entry->schedWeekDay = dayVal;
 
257
    memcpy(entry->schedMonth,  monVal,  2);
 
258
    memcpy(entry->schedDay,    dateVal, 4+4);
 
259
    memcpy(entry->schedHour,   hourVal, 3);
 
260
    memcpy(entry->schedMinute, minVal,  8);
 
261
    
 
262
    memcpy(entry->schedVariable, variable, var_len*sizeof(oid));
 
263
    entry->schedVariable_len = var_len;
 
264
    entry->schedValue        = value;
 
265
 
 
266
    if ( !strcmp( token, "at" ))
 
267
        entry->schedType     = SCHED_TYPE_ONESHOT;
 
268
    else
 
269
        entry->schedType     = SCHED_TYPE_CALENDAR;
 
270
    entry->schedStorageType  = ST_READONLY;  /* or PERMANENT */
 
271
    entry->flags             = SCHEDULE_FLAG_ENABLED |
 
272
                               SCHEDULE_FLAG_ACTIVE  |
 
273
                               SCHEDULE_FLAG_VALID;
 
274
    entry->session           = netsnmp_query_get_default_session();
 
275
    sched_nextTime( entry );
 
276
}
 
277
 
 
278
 
 
279
/* ========================================
 
280
 *
 
281
 * Handlers for persistent schedule entries
 
282
 *
 
283
 * ======================================== */
 
284
 
 
285
void
 
286
parse_schedTable( const char *token, char *line )
 
287
{
 
288
    char   owner[SCHED_STR1_LEN+1];
 
289
    char   name[ SCHED_STR1_LEN+1];
 
290
    char   time_bits[22];  /* schedWeekDay..schedMinute */
 
291
    void  *vp;
 
292
    size_t len;
 
293
    netsnmp_tdata_row       *row;
 
294
    struct schedTable_entry *entry;
 
295
 
 
296
    DEBUGMSGTL(("disman:schedule:conf", "Parsing schedTable config...  "));
 
297
 
 
298
    /*
 
299
     * Read in the index information for this entry
 
300
     *  and create a (non-fixed) data structure for it.
 
301
     */
 
302
    memset( owner, 0, sizeof(owner));
 
303
    memset( name,  0, sizeof(name));
 
304
    len  = SCHED_STR1_LEN; vp = owner;
 
305
    line = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
 
306
    len  = SCHED_STR1_LEN; vp = name;
 
307
    line = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
 
308
    row  = schedTable_createEntry(owner, name);
 
309
    if (!row || !row->data) {
 
310
        config_perror("create schedule entry failure");
 
311
        return;
 
312
    }
 
313
    entry = (struct schedTable_entry *)row->data;
 
314
    DEBUGMSG(("disman:schedule:conf", "(%s, %s) ", owner, name));
 
315
    
 
316
    /*
 
317
     * Read in the column values.
 
318
     */
 
319
    len  = SCHED_STR2_LEN; vp = entry->schedDescr;
 
320
    line = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
 
321
    line = read_config_read_data(ASN_UNSIGNED,  line,
 
322
                                     &entry->schedInterval, NULL);
 
323
        /* Unpick the various timed bits */
 
324
    len  = 22; vp = time_bits;
 
325
    line = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
 
326
    entry->schedWeekDay  = time_bits[0];
 
327
    entry->schedMonth[0] = time_bits[1];
 
328
    entry->schedMonth[1] = time_bits[2];
 
329
    entry->schedHour[0]  = time_bits[11];
 
330
    entry->schedHour[1]  = time_bits[12];
 
331
    entry->schedHour[2]  = time_bits[13];
 
332
    memcpy(entry->schedDay,    time_bits+3,  8);
 
333
    memcpy(entry->schedMinute, time_bits+14, 8);
 
334
 
 
335
    len  = SCHED_STR1_LEN; vp = entry->schedContextName;
 
336
    line = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
 
337
    len  = MAX_OID_LEN;    vp = entry->schedVariable;
 
338
    line = read_config_read_data(ASN_OBJECT_ID, line, &vp,  &len);
 
339
    entry->schedVariable_len = len;
 
340
    line = read_config_read_data(ASN_INTEGER,  line,
 
341
                                     &entry->schedValue, NULL);
 
342
    line = read_config_read_data(ASN_UNSIGNED, line,
 
343
                                     &entry->schedType,  NULL);
 
344
    line = read_config_read_data(ASN_UNSIGNED, line, &len, NULL);
 
345
    entry->flags |= (len /* & WHAT ?? */);
 
346
    /* XXX - Will need to read in the 'iquery' access information */
 
347
    entry->flags |= SCHEDULE_FLAG_VALID;
 
348
 
 
349
    DEBUGMSG(("disman:schedule:conf", "\n"));
 
350
}
 
351
 
 
352
/*
 
353
 * Save dynamically-configured schedTable entries into persistent storage
 
354
 */
 
355
int
 
356
store_schedTable(int majorID, int minorID, void *serverarg, void *clientarg)
 
357
{
 
358
    char              line[SNMP_MAXBUF];
 
359
    char              time_bits[22];  /* schedWeekDay..schedMinute */
 
360
    char             *cptr;
 
361
    void             *vp;
 
362
    size_t            tint;
 
363
    netsnmp_tdata_row *row;
 
364
    struct schedTable_entry *entry;
 
365
 
 
366
 
 
367
    DEBUGMSGTL(( "disman:schedule:conf", "Storing schedTable:\n"));
 
368
 
 
369
    for (row = netsnmp_tdata_row_first( schedule_table );
 
370
         row;
 
371
         row = netsnmp_tdata_row_next(  schedule_table, row )) {
 
372
 
 
373
        if (!row->data)
 
374
            continue;
 
375
        entry = (struct schedTable_entry *)row->data;
 
376
 
 
377
        /*
 
378
         * Only save (dynamically-created) 'nonVolatile' entries
 
379
         *    (XXX - what about dynamic 'permanent' entries ??)
 
380
         */
 
381
        if (entry->schedStorageType != ST_NONVOLATILE )
 
382
            continue;
 
383
        DEBUGMSGTL(( "disman:schedule:conf", "  Storing (%s, %s)\n",
 
384
                             entry->schedOwner, entry->schedName));
 
385
 
 
386
        memset(line, 0, sizeof(line));
 
387
        strcpy(line, "_schedTable ");
 
388
        cptr = line + strlen(line);
 
389
 
 
390
        vp   = entry->schedOwner;     tint = strlen( vp );
 
391
        cptr = read_config_store_data(ASN_OCTET_STR, cptr, &vp,  &tint );
 
392
        vp   = entry->schedName;      tint = strlen( vp );
 
393
        cptr = read_config_store_data(ASN_OCTET_STR, cptr, &vp,  &tint );
 
394
        vp   = entry->schedDescr;     tint = strlen( vp );
 
395
        cptr = read_config_store_data(ASN_OCTET_STR, cptr, &vp,  &tint );
 
396
        tint = entry->schedInterval;
 
397
        cptr = read_config_store_data(ASN_UNSIGNED,  cptr, &tint, NULL );
 
398
 
 
399
        /* Combine all the timed bits into a single field */
 
400
        time_bits[0]  = entry->schedWeekDay;
 
401
        time_bits[1]  = entry->schedMonth[0];
 
402
        time_bits[2]  = entry->schedMonth[1];
 
403
        time_bits[11] = entry->schedHour[0];
 
404
        time_bits[12] = entry->schedHour[1];
 
405
        time_bits[13] = entry->schedHour[2];
 
406
        memcpy(time_bits+3,  entry->schedDay,    8);
 
407
        memcpy(time_bits+14, entry->schedMinute, 8);
 
408
        vp   = time_bits;    tint = 22;
 
409
        cptr = read_config_store_data(ASN_OCTET_STR, cptr, &vp, &tint );
 
410
 
 
411
        vp   = entry->schedContextName; tint = strlen( vp );
 
412
        cptr = read_config_store_data(ASN_OCTET_STR, cptr, &vp,  &tint );
 
413
        vp   = entry->schedVariable;
 
414
        tint = entry->schedVariable_len;
 
415
        cptr = read_config_store_data(ASN_OBJECT_ID, cptr, &vp,  &tint );
 
416
        tint = entry->schedValue;
 
417
        cptr = read_config_store_data(ASN_INTEGER,   cptr, &tint, NULL );
 
418
        tint = entry->schedType;
 
419
        cptr = read_config_store_data(ASN_UNSIGNED,  cptr, &tint, NULL );
 
420
        tint = entry->flags /* & WHAT ?? */;
 
421
        cptr = read_config_store_data(ASN_UNSIGNED,  cptr, &tint, NULL );
 
422
        /* XXX - Need to store the 'iquery' access information */
 
423
        snmpd_store_config(line);
 
424
    }
 
425
    DEBUGMSGTL(( "disman:schedule:conf", "  done.\n"));
 
426
    return SNMPERR_SUCCESS;
 
427
}