static void clear_data_set(netsnmp_table_data_set *data_set)
{
	netsnmp_table_row *row, *nextrow;

	for (row = netsnmp_table_data_set_get_first_row(data_set); row; row = nextrow) {
		nextrow = netsnmp_table_data_set_get_next_row(data_set, row);
		netsnmp_table_dataset_remove_and_delete_row(data_set, row);
	}
}
示例#2
0
void netsnmp_delete_table_data_set(netsnmp_table_data_set *table_set)
{
    netsnmp_table_data_set_storage *ptr, *next;
    netsnmp_table_row *prow, *pnextrow;

    for (ptr = table_set->default_row; ptr; ptr = next) {
        next = ptr->next;
        free(ptr);
    }
    table_set->default_row = NULL;
    for (prow = table_set->table->first_row; prow; prow = pnextrow) {
        pnextrow = prow->next;
        netsnmp_table_dataset_remove_and_delete_row(table_set, prow);
    }
    table_set->table->first_row = NULL;
    netsnmp_table_data_delete_table(table_set->table);
    free(table_set);
}
示例#3
0
/** implements the table data helper.  This is the routine that takes
 *  care of all SNMP requests coming into the table. */
int
netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{

    netsnmp_table_data_set_storage *data = NULL;
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *row, *newrow = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    oid            *suffix;
    size_t          suffix_len;
    netsnmp_oid_stash_node **stashp = NULL;

    if (!handler)
        return SNMPERR_GENERR;
        
    DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n"));
    for (request = requests; request; request = request->next) {
        netsnmp_table_data_set *datatable =
            (netsnmp_table_data_set *) handler->myvoid;
        if (request->processed)
            continue;

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(request);
        table_info = netsnmp_extract_table_info(request);
        suffix = requests->requestvb->name + reginfo->rootoid_len + 2;
        suffix_len = requests->requestvb->name_length -
            (reginfo->rootoid_len + 2);

        if (MODE_IS_SET(reqinfo->mode)) {

            char buf[256]; /* is this reasonable size?? */
            int  rc;
            size_t len;

            /*
             * use a cached copy of the row for modification 
             */

            /*
             * cache location: may have been created already by other
             * SET requests in the same master request. 
             */
            rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:",
                          datatable->table->name);
            if ((-1 == rc) || (rc >= sizeof(buf))) {
                snmp_log(LOG_ERR,"%s handler name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            len = sizeof(buf) - rc;
            rc = snprint_objid(&buf[rc], len, table_info->index_oid,
                               table_info->index_oid_len);
            if (-1 == rc) {
                snmp_log(LOG_ERR,"%s oid or name too long\n",
                         datatable->table->name);
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_GENERR);
                continue;
            }
            stashp = (netsnmp_oid_stash_node **)
                netsnmp_table_get_or_create_row_stash(reqinfo, buf);

            newrowstash
                = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);

            if (!newrowstash) {
                if (!row) {
                    if (datatable->allow_creation) {
                        /*
                         * entirely new row.  Create the row from the template 
                         */
                        newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                        newrow = newrowstash->newrow;
                    } else if (datatable->rowstatus_column == 0) {
                        /*
                         * A RowStatus object may be used to control the
                         *  creation of a new row.  But if this object
                         *  isn't declared (and the table isn't marked as
                         *  'auto-create'), then we can't create a new row.
                         */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_NOCREATION);
                        continue;
                    }
                } else {
                    /*
                     * existing row that needs to be modified 
                     */
                    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);
                    newrow = netsnmp_table_data_set_clone_row(row);
                    newrowstash->newrow = newrow;
                }
                netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                           newrowstash);
            } else {
                newrow = newrowstash->newrow;
            }
            /*
             * all future SET data modification operations use this
             * temp pointer 
             */
            if (reqinfo->mode == MODE_SET_RESERVE1 ||
                reqinfo->mode == MODE_SET_RESERVE2)
                row = newrow;
        }

        if (row)
            data = (netsnmp_table_data_set_storage *) row->data;

        if (!row || !table_info || !data) {
            if (!MODE_IS_SET(reqinfo->mode)) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        }

        data =
            netsnmp_table_data_set_find_column(data, table_info->colnum);

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (data && data->data.voidp)
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                data->type,
                                                data->data.voidp,
                                                data->data_len);
            break;

        case MODE_SET_RESERVE1:
            if (data) {
                /*
                 * Can we modify the existing row?
                 */
                if (!data->writable) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                } else if (request->requestvb->type != data->type) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                }
            } else if (datatable->rowstatus_column == table_info->colnum) {
                /*
                 * Otherwise, this is where we create a new row using
                 * the RowStatus object (essentially duplicating the
                 * steps followed earlier in the 'allow_creation' case)
                 */
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                    newrow = newrowstash->newrow;
                    row    = newrow;
                    netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                               newrowstash);
                }
            }
            break;

        case MODE_SET_RESERVE2:
            /*
             * If the agent receives a SET request for an object in a non-existant
             *  row, then the RESERVE1 pass will create the row automatically.
             *
             * But since the row doesn't exist at that point, the test for whether
             *  the object is writable or not will be skipped.  So we need to check
             *  for this possibility again here.
             *
             * Similarly, if row creation is under the control of the RowStatus
             *  object (i.e. allow_creation == 0), but this particular request
             *  doesn't include such an object, then the row won't have been created,
             *  and the writable check will also have been skipped.  Again - check here.
             */
            if (data && data->writable == 0) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                continue;
            }
            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
                     * Can only operate on pre-existing rows.
                     */
                    if (!newrowstash || newrowstash->created) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Can only operate on newly created rows.
                     */
                    if (!(newrowstash && newrowstash->created)) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_DESTROY:
                    /*
                     * Can operate on new or pre-existing rows.
                     */
                    break;

                case RS_NOTREADY:
                default:
                    /*
                     * Not a valid value to Set 
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    continue;
                }
            }
            if (!data ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }

            /*
             * modify row and set new value 
             */
            SNMP_FREE(data->data.string);
            data->data.string =
                netsnmp_strdup_and_null(request->requestvb->val.string,
                                        request->requestvb->val_len);
            if (!data->data.string) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_RESOURCEUNAVAILABLE);
            }
            data->data_len = request->requestvb->val_len;

            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    newrowstash->deleted = 1;
                    break;
                }
            }
            break;

        case MODE_SET_ACTION:

            /*
             * Install the new row into the stored table.
	     * Do this only *once* per row ....
             */
            if (newrowstash->state != STATE_ACTION) {
                newrowstash->state = STATE_ACTION;
		if (newrowstash->created) {
                    netsnmp_table_dataset_add_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      row, newrow);
                }
            }
            /*
             * ... but every (relevant) varbind in the request will
	     * need to know about this new row, so update the
	     * per-request row information regardless
             */
            if (newrowstash->created) {
		netsnmp_request_add_list_data(request,
			netsnmp_create_data_list(TABLE_DATA_NAME,
						 newrow, NULL));
            }
            break;

        case MODE_SET_UNDO:
            /*
             * extract the new row, replace with the old or delete 
             */
            if (newrowstash->state != STATE_UNDO) {
                newrowstash->state = STATE_UNDO;
                if (newrowstash->created) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      newrow, row);
                    netsnmp_table_dataset_delete_row(newrow);
                }
            }
            break;

        case MODE_SET_COMMIT:
            if (newrowstash->state != STATE_COMMIT) {
                newrowstash->state = STATE_COMMIT;
                if (!newrowstash->created) {
                    netsnmp_table_dataset_delete_row(row);
                }
                if (newrowstash->deleted) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                }
            }
            break;

        case MODE_SET_FREE:
            if (newrowstash && newrowstash->state != STATE_FREE) {
                newrowstash->state = STATE_FREE;
                netsnmp_table_dataset_delete_row(newrow);
            }
            break;
        }
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}
示例#4
0
void cleanTableSet (netsnmp_table_data_set *table_set){
    netsnmp_table_row *row;
    while((row =  netsnmp_table_data_set_get_first_row(table_set)) != NULL){
        netsnmp_table_dataset_remove_and_delete_row(table_set, row);
    }
}
示例#5
0
void
check_log_size(unsigned int clientreg, void *clientarg)
{
    netsnmp_table_row *row, *deleterow, *tmprow, *deletevarrow;
    netsnmp_table_data_set_storage *data;
    u_long          count = 0;
    struct timeval  now;
    long            tmpl;

    gettimeofday(&now, NULL);
    tmpl = netsnmp_timeval_uptime(&now);

    for (row = nlmLogTable->table->first_row; row; row = row->next) {
        /*
         * check max allowed count 
         */
        count++;
        if (max_logged && count == max_logged)
            break;

        /*
         * check max age 
         */

        data = (netsnmp_table_data_set_storage *) row->data;
        data = netsnmp_table_data_set_find_column(data, COLUMN_NLMLOGTIME);

        if (max_age && tmpl > (*(data->data.integer) + max_age * 100 * 60))
            break;
    }

    if (!row)
        return;

    /*
     * we've reached the limit, so keep looping but start deleting
     * from the beginning 
     */
    for (deleterow = nlmLogTable->table->first_row, row = row->next; row;
         row = row->next) {
        DEBUGMSGTL(("notification_log", "deleting a log entry\n"));

        /*
         * delete contained varbinds 
         */
        for (deletevarrow = nlmLogVarTable->table->first_row;
             deletevarrow; deletevarrow = tmprow) {

            tmprow = deletevarrow->next;

            if (deleterow->index_oid_len ==
                deletevarrow->index_oid_len - 1 &&
                snmp_oid_compare(deleterow->index_oid,
                                 deleterow->index_oid_len,
                                 deletevarrow->index_oid,
                                 deleterow->index_oid_len) == 0) {
                netsnmp_table_dataset_remove_and_delete_row(nlmLogVarTable,
                                                            deletevarrow);
            }
        }

        /*
         * delete the master row 
         */
        tmprow = deleterow->next;
        netsnmp_table_dataset_remove_and_delete_row(nlmLogTable,
                                                    deleterow);
        deleterow = tmprow;
        num_deleted++;
        /*
         * XXX: delete vars from it's table 
         */
    }
}