~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to agent/helpers/table_container.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-05-10 22:20:23 UTC
  • mto: (1.4.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 11.
  • 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
1
/*
2
2
 * table_container.c
3
 
 * $Id: table_container.c,v 1.13.2.5 2006/01/27 09:05:31 tanders Exp $
 
3
 * $Id: table_container.c,v 1.21.2.2 2006/01/25 16:26:38 dts12 Exp $
4
4
 */
5
5
 
6
6
#include <net-snmp/net-snmp-config.h>
19
19
#include <net-snmp/library/container.h>
20
20
#include <net-snmp/library/snmp_assert.h>
21
21
 
22
 
#if HAVE_DMALLOC_H
23
 
#include <dmalloc.h>
24
 
#endif
25
 
 
26
22
/*
27
23
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN        -1 
28
24
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1     0 
142
138
                         netsnmp_agent_request_info *agtreq_info,
143
139
                         netsnmp_request_info *requests);
144
140
 
 
141
static void *
 
142
_find_next_row(netsnmp_container *c,
 
143
               netsnmp_table_request_info *tblreq,
 
144
               void * key);
 
145
 
145
146
/**********************************************************************
146
147
 **********************************************************************
147
148
 *                                                                    *
151
152
 *                                                                    *
152
153
 **********************************************************************
153
154
 **********************************************************************/
154
 
/** register specified callbacks for the specified table/oid.
155
 
*/
 
155
 
 
156
/* ==================================
 
157
 *
 
158
 * Container Table API: Table maintenance
 
159
 *
 
160
 * ================================== */
 
161
 
 
162
container_table_data *
 
163
netsnmp_tcontainer_create_table( const char *name,
 
164
                                 netsnmp_container *container, long flags )
 
165
{
 
166
    container_table_data *table;
 
167
 
 
168
    table = SNMP_MALLOC_TYPEDEF(container_table_data);
 
169
    if (!table)
 
170
        return NULL;
 
171
    if (container)
 
172
        table->table = container;
 
173
    else {
 
174
        table->table = netsnmp_container_find("table_container");
 
175
        if (!table->table) {
 
176
            SNMP_FREE(table);
 
177
            return NULL;
 
178
        }
 
179
    }
 
180
 
 
181
    if (flags)
 
182
        table->key_type = flags & 0x03;  /* Use lowest two bits */
 
183
    else
 
184
        table->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX;
 
185
 
 
186
    if (!table->table->compare)
 
187
         table->table->compare  = netsnmp_compare_netsnmp_index;
 
188
    if (!table->table->ncompare)
 
189
         table->table->ncompare = netsnmp_ncompare_netsnmp_index;
 
190
 
 
191
    return table;
 
192
}
 
193
 
 
194
void
 
195
netsnmp_tcontainer_delete_table( container_table_data *table )
 
196
{
 
197
    if (!table)
 
198
       return;
 
199
 
 
200
    if (table->table)
 
201
       CONTAINER_FREE(table->table);
 
202
    
 
203
    SNMP_FREE(table);
 
204
    return;
 
205
}
 
206
 
 
207
    /*
 
208
     * The various standalone row operation routines
 
209
     *    (create/clone/copy/delete)
 
210
     * will be specific to a particular table,
 
211
     *    so can't be implemented here.
 
212
     */
 
213
 
 
214
int
 
215
netsnmp_tcontainer_add_row( container_table_data *table, netsnmp_index *row )
 
216
{
 
217
    if (!table || !table->table || !row)
 
218
        return -1;
 
219
    CONTAINER_INSERT( table->table, row );
 
220
    return 0;
 
221
}
 
222
 
 
223
netsnmp_index *
 
224
netsnmp_tcontainer_remove_row( container_table_data *table, netsnmp_index *row )
 
225
{
 
226
    if (!table || !table->table || !row)
 
227
        return NULL;
 
228
    CONTAINER_REMOVE( table->table, row );
 
229
    return NULL;
 
230
}
 
231
 
 
232
int
 
233
netsnmp_tcontainer_replace_row( container_table_data *table,
 
234
                                netsnmp_index *old_row, netsnmp_index *new_row )
 
235
{
 
236
    if (!table || !table->table || !old_row || !new_row)
 
237
        return -1;
 
238
    netsnmp_tcontainer_remove_row( table, old_row );
 
239
    netsnmp_tcontainer_add_row(    table, new_row );
 
240
    return 0;
 
241
}
 
242
 
 
243
    /* netsnmp_tcontainer_remove_delete_row() will be table-specific too */
 
244
 
 
245
 
 
246
/* ==================================
 
247
 *
 
248
 * Container Table API: MIB maintenance
 
249
 *
 
250
 * ================================== */
 
251
 
 
252
/** returns a netsnmp_mib_handler object for the table_container helper */
156
253
netsnmp_mib_handler *
157
254
netsnmp_container_table_handler_get(netsnmp_table_registration_info *tabreg,
158
255
                                    netsnmp_container *container, char key_type)
218
315
    return netsnmp_register_table(reginfo, tabreg);
219
316
}
220
317
 
221
 
/** @} */
 
318
/** retrieve the container used by the table_container helper */
 
319
netsnmp_container*
 
320
netsnmp_container_table_container_extract(netsnmp_request_info *request)
 
321
{
 
322
    return (netsnmp_container *)
 
323
         netsnmp_request_get_list_data(request, TABLE_CONTAINER_CONTAINER);
 
324
}
 
325
 
 
326
#ifndef NETSNMP_USE_INLINE
 
327
/** find the context data used by the table_container helper */
 
328
void *
 
329
netsnmp_container_table_row_extract(netsnmp_request_info *request)
 
330
{
 
331
    /*
 
332
     * NOTE: this function must match in table_container.c and table_container.h.
 
333
     *       if you change one, change them both!
 
334
     */
 
335
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
 
336
}
 
337
/** find the context data used by the table_container helper */
 
338
void *
 
339
netsnmp_container_table_extract_context(netsnmp_request_info *request)
 
340
{
 
341
    /*
 
342
     * NOTE: this function must match in table_container.c and table_container.h.
 
343
     *       if you change one, change them both!
 
344
     */
 
345
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
 
346
}
 
347
#endif /* inline */
 
348
 
 
349
/** inserts a newly created table_container entry into a request list */
 
350
void
 
351
netsnmp_container_table_row_insert(netsnmp_request_info *request,
 
352
                                   netsnmp_index        *row)
 
353
{
 
354
    netsnmp_request_info       *req;
 
355
    netsnmp_table_request_info *table_info = NULL;
 
356
    netsnmp_variable_list      *this_index = NULL;
 
357
    netsnmp_variable_list      *that_index = NULL;
 
358
    oid      base_oid[] = {0, 0};       /* Make sure index OIDs are legal! */
 
359
    oid      this_oid[MAX_OID_LEN];
 
360
    oid      that_oid[MAX_OID_LEN];
 
361
    size_t   this_oid_len, that_oid_len;
 
362
 
 
363
    if (!request)
 
364
        return;
 
365
 
 
366
    /*
 
367
     * We'll add the new row information to any request
 
368
     * structure with the same index values as the request
 
369
     * passed in (which includes that one!).
 
370
     *
 
371
     * So construct an OID based on these index values.
 
372
     */
 
373
 
 
374
    table_info = netsnmp_extract_table_info(request);
 
375
    this_index = table_info->indexes;
 
376
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
 
377
                      base_oid, 2, this_index);
 
378
 
 
379
    /*
 
380
     * We need to look through the whole of the request list
 
381
     * (as received by the current handler), as there's no
 
382
     * guarantee that this routine will be called by the first
 
383
     * varbind that refers to this row.
 
384
     *   In particular, a RowStatus controlled row creation
 
385
     * may easily occur later in the variable list.
 
386
     *
 
387
     * So first, we rewind to the head of the list....
 
388
     */
 
389
    for (req=request; req->prev; req=req->prev)
 
390
        ;
 
391
 
 
392
    /*
 
393
     * ... and then start looking for matching indexes
 
394
     * (by constructing OIDs from these index values)
 
395
     */
 
396
    for (; req; req=req->next) {
 
397
        if (req->processed) 
 
398
            continue;
 
399
        
 
400
        table_info = netsnmp_extract_table_info(req);
 
401
        that_index = table_info->indexes;
 
402
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
 
403
                          base_oid, 2, that_index);
 
404
      
 
405
        /*
 
406
         * This request has the same index values,
 
407
         * so add the newly-created row information.
 
408
         */
 
409
        if (snmp_oid_compare(this_oid, this_oid_len,
 
410
                             that_oid, that_oid_len) == 0) {
 
411
            netsnmp_request_add_list_data(req,
 
412
                netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL));
 
413
        }
 
414
    }
 
415
}
222
416
 
223
417
/** @cond */
224
418
/**********************************************************************
252
446
        *key = NULL;
253
447
}
254
448
 
255
 
static void *
256
 
_find_next_row(netsnmp_container *c,
257
 
               netsnmp_table_request_info *tblreq,
258
 
               void * key)
259
 
{
260
 
    void *row = NULL;
261
 
 
262
 
    if (!c || !tblreq || !tblreq->reg_info ) {
263
 
        snmp_log(LOG_ERR,"_find_next_row param error\n");
264
 
        return NULL;
265
 
    }
266
 
 
267
 
    /*
268
 
     * table helper should have made sure we aren't below our minimum column
269
 
     */
270
 
    netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column);
271
 
 
272
 
    /*
273
 
     * if no indexes then use first row.
274
 
     */
275
 
    if(tblreq->number_indexes == 0) {
276
 
        row = CONTAINER_FIRST(c);
277
 
    } else {
278
 
 
279
 
        if(NULL == key) {
280
 
            netsnmp_index index;
281
 
            index.oids = tblreq->index_oid;
282
 
            index.len = tblreq->index_oid_len;
283
 
            row = CONTAINER_NEXT(c, &index);
284
 
        }
285
 
        else
286
 
            row = CONTAINER_NEXT(c, key);
287
 
 
288
 
        /*
289
 
         * we don't have a row, but we might be at the end of a
290
 
         * column, so try the next column.
291
 
         */
292
 
        if (NULL == row) {
293
 
            /*
294
 
             * don't set tblreq next_col unless we know there is one,
295
 
             * so we don't mess up table handler sparse table processing.
296
 
             */
297
 
            oid next_col = netsnmp_table_next_column(tblreq);
298
 
            if (0 != next_col) {
299
 
                tblreq->colnum = next_col;
300
 
                row = CONTAINER_FIRST(c);
301
 
            }
302
 
        }
303
 
    }
304
 
    
305
 
    return row;
306
 
}
307
 
 
308
 
/**
309
 
 * deprecated, backwards compatability only
310
 
 *
311
 
 * expected impact to remove: none
312
 
 *  - used between helpers, shouldn't have been used by end users
313
 
 *
314
 
 * replacement: none
315
 
 *  - never should have been a public method in the first place
316
 
 */
317
 
netsnmp_index *
318
 
netsnmp_table_index_find_next_row(netsnmp_container *c,
319
 
                                  netsnmp_table_request_info *tblreq)
320
 
{
321
 
    return _find_next_row(c, tblreq, NULL );
322
 
}
323
 
 
324
449
 
325
450
NETSNMP_STATIC_INLINE void
326
451
_data_lookup(netsnmp_handler_registration *reginfo,
370
495
                netsnmp_update_variable_list_from_index(tblreq_info);
371
496
            }
372
497
            else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {
 
498
                /** xxx-rks: shouldn't tblreq_info->indexes be updated
 
499
                    before we call this?? */
373
500
                netsnmp_update_indexes_from_variable_list(tblreq_info);
374
501
            }
375
502
 
408
535
    /*
409
536
     * save the data and table in the request.
410
537
     */
411
 
    if (SNMP_ENDOFMIBVIEW != request->status) {
 
538
    if (SNMP_ENDOFMIBVIEW != request->requestvb->type) {
412
539
        if (NULL != row)
413
540
            netsnmp_request_add_list_data(request,
414
541
                                          netsnmp_create_data_list
521
648
}
522
649
/** @endcond */
523
650
 
524
 
/** retrieve the container used by the table_container helper */
525
 
netsnmp_container*
526
 
netsnmp_container_table_container_extract(netsnmp_request_info *request)
527
 
{
528
 
    return (netsnmp_container *)
529
 
         netsnmp_request_get_list_data(request, TABLE_CONTAINER_CONTAINER);
530
 
}
531
 
 
532
 
/** inserts a newly created table_container entry into a request list */
533
 
void
534
 
netsnmp_container_table_row_insert(netsnmp_request_info *request,
535
 
                                   netsnmp_index        *row)
536
 
{
537
 
    netsnmp_request_info       *req;
538
 
    netsnmp_table_request_info *table_info = NULL;
539
 
    netsnmp_variable_list      *this_index = NULL;
540
 
    netsnmp_variable_list      *that_index = NULL;
541
 
    oid      base_oid[] = {0, 0};       /* Make sure index OIDs are legal! */
542
 
    oid      this_oid[MAX_OID_LEN];
543
 
    oid      that_oid[MAX_OID_LEN];
544
 
    size_t   this_oid_len, that_oid_len;
545
 
 
546
 
    if (!request)
547
 
        return;
548
 
 
549
 
    /*
550
 
     * We'll add the new row information to any request
551
 
     * structure with the same index values as the request
552
 
     * passed in (which includes that one!).
553
 
     *
554
 
     * So construct an OID based on these index values.
555
 
     */
556
 
 
557
 
    table_info = netsnmp_extract_table_info(request);
558
 
    this_index = table_info->indexes;
559
 
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
560
 
                      base_oid, 2, this_index);
561
 
 
562
 
    /*
563
 
     * We need to look through the whole of the request list
564
 
     * (as received by the current handler), as there's no
565
 
     * guarantee that this routine will be called by the first
566
 
     * varbind that refers to this row.
567
 
     *   In particular, a RowStatus controlled row creation
568
 
     * may easily occur later in the variable list.
569
 
     *
570
 
     * So first, we rewind to the head of the list....
571
 
     */
572
 
    for (req=request; req->prev; req=req->prev)
573
 
        ;
574
 
 
575
 
    /*
576
 
     * ... and then start looking for matching indexes
577
 
     * (by constructing OIDs from these index values)
578
 
     */
579
 
    for (; req; req=req->next) {
580
 
        if (req->processed)
581
 
            continue;
582
 
        table_info = netsnmp_extract_table_info(req);
583
 
        that_index = table_info->indexes;
584
 
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
585
 
                          base_oid, 2, that_index);
586
 
      
 
651
 
 
652
/* ==================================
 
653
 *
 
654
 * Container Table API: Row operations
 
655
 *
 
656
 * ================================== */
 
657
 
 
658
static void *
 
659
_find_next_row(netsnmp_container *c,
 
660
               netsnmp_table_request_info *tblreq,
 
661
               void * key)
 
662
{
 
663
    void *row = NULL;
 
664
 
 
665
    if (!c || !tblreq || !tblreq->reg_info ) {
 
666
        snmp_log(LOG_ERR,"_find_next_row param error\n");
 
667
        return NULL;
 
668
    }
 
669
 
 
670
    /*
 
671
     * table helper should have made sure we aren't below our minimum column
 
672
     */
 
673
    netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column);
 
674
 
 
675
    /*
 
676
     * if no indexes then use first row.
 
677
     */
 
678
    if(tblreq->number_indexes == 0) {
 
679
        row = CONTAINER_FIRST(c);
 
680
    } else {
 
681
 
 
682
        if(NULL == key) {
 
683
            netsnmp_index index;
 
684
            index.oids = tblreq->index_oid;
 
685
            index.len = tblreq->index_oid_len;
 
686
            row = CONTAINER_NEXT(c, &index);
 
687
        }
 
688
        else
 
689
            row = CONTAINER_NEXT(c, key);
 
690
 
587
691
        /*
588
 
         * This request has the same index values,
589
 
         * so add the newly-created row information.
 
692
         * we don't have a row, but we might be at the end of a
 
693
         * column, so try the next column.
590
694
         */
591
 
        if (snmp_oid_compare(this_oid, this_oid_len,
592
 
                             that_oid, that_oid_len) == 0) {
593
 
            netsnmp_request_add_list_data(req,
594
 
                netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL));
 
695
        if (NULL == row) {
 
696
            /*
 
697
             * don't set tblreq next_col unless we know there is one,
 
698
             * so we don't mess up table handler sparse table processing.
 
699
             */
 
700
            oid next_col = netsnmp_table_next_column(tblreq);
 
701
            if (0 != next_col) {
 
702
                tblreq->colnum = next_col;
 
703
                row = CONTAINER_FIRST(c);
 
704
            }
595
705
        }
596
706
    }
 
707
    
 
708
    return row;
597
709
}
598
710
 
599
 
#ifndef NETSNMP_USE_INLINE
600
 
/** find the context data used by the table_container helper */
601
 
void *
602
 
netsnmp_container_table_row_extract(netsnmp_request_info *request)
 
711
/**
 
712
 * deprecated, backwards compatability only
 
713
 *
 
714
 * expected impact to remove: none
 
715
 *  - used between helpers, shouldn't have been used by end users
 
716
 *
 
717
 * replacement: none
 
718
 *  - never should have been a public method in the first place
 
719
 */
 
720
netsnmp_index *
 
721
netsnmp_table_index_find_next_row(netsnmp_container *c,
 
722
                                  netsnmp_table_request_info *tblreq)
603
723
{
604
 
    /*
605
 
     * NOTE: this function must match in table_container.c and table_container.h.
606
 
     *       if you change one, change them both!
607
 
     */
608
 
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
 
724
    return _find_next_row(c, tblreq, NULL );
609
725
}
610
 
#endif /* inline */
 
726
 
 
727
/* ==================================
 
728
 *
 
729
 * Container Table API: Index operations
 
730
 *
 
731
 * ================================== */
 
732
 
 
733
/** @} */