/************************************************************ * Assuming that the RESERVE phases were successful, the next * stage is indicated by the action value ACTION. This is used * to actually implement the set operation. However, this must * either be done into temporary (persistent) storage, or the * previous value stored similarly, in case any of the subsequent * ACTION calls fail. * * In your case, changes should be made to row_ctx. A copy of * the original row is in undo_ctx. */ void saHpiEventLogTable_set_action( netsnmp_request_group *rg ) { netsnmp_variable_list *var; saHpiEventLogTable_context *row_ctx = (saHpiEventLogTable_context *)rg->existing_row; saHpiEventLogTable_context *undo_ctx = (saHpiEventLogTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* * TODO: loop through columns, copy varbind values * to context structure for the row. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } #if 0 /* * done with all the columns. Could check row related * requirements here. */ #ifndef saHpiEventLogTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->saHpiDomainAlarmRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->saHpiDomainAlarmRowStatus) ) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->saHpiDomainAlarmRowStatus : NULL, undo_ctx ? &undo_ctx->saHpiDomainAlarmRowStatus : NULL); #endif if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } /* * TODO: if you have dependencies on other tables, this would be * a good place to check those, too. */ }
int netsnmp_table_array_check_row_status (netsnmp_table_array_callbacks * cb, netsnmp_request_group * ag, long *rs_new, long *rs_old) { netsnmp_index *row_ctx; netsnmp_index *undo_ctx; if (!ag || !cb) return SNMPERR_GENERR; row_ctx = ag->existing_row; undo_ctx = ag->undo_info; /* * xxx-rks: revisit row delete scenario */ if (row_ctx) { /* * either a new row, or change to old row */ /* * is it set to active? */ if (RS_IS_GOING_ACTIVE (*rs_new)) { /* * is it ready to be active? */ if ((NULL == cb->can_activate) || cb->can_activate (undo_ctx, row_ctx, ag)) *rs_new = RS_ACTIVE; else return SNMP_ERR_INCONSISTENTVALUE; } else { /* * not going active */ if (undo_ctx) { /* * change */ if (RS_IS_ACTIVE (*rs_old)) { /* * check pre-reqs for deactivation */ if (cb->can_deactivate && !cb->can_deactivate (undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; } } } else { /* * new row */ } if (*rs_new != RS_DESTROY) { if ((NULL == cb->can_activate) || cb->can_activate (undo_ctx, row_ctx, ag)) *rs_new = RS_NOTINSERVICE; else *rs_new = RS_NOTREADY; } else { if (cb->can_delete && !cb->can_delete (undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; } ag->row_deleted = 1; } } } else { /* * check pre-reqs for delete row */ if (cb->can_delete && !cb->can_delete (undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; } } return SNMP_ERR_NOERROR; }
/** handles requests for the tlstmCertToTSNTable table */ static int tlstmCertToTSNTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { oid tsnm[] = { SNMP_TLS_TM_BASE, 1, 1, 0 }; static const int tsnm_pos = OID_LENGTH(tsnm) - 1; netsnmp_request_info *request = NULL; netsnmp_table_request_info *info; netsnmp_tdata *table; netsnmp_tdata_row *row; certToTSN_entry *entry; int ret = SNMP_ERR_NOERROR; DEBUGMSGTL(("tlstmCertToSN:handler", "Processing request (mode %s (%d))\n", se_find_label_in_slist("agent_mode", reqinfo->mode), reqinfo->mode)); switch (reqinfo->mode) { /** ######################################################### GET ##### * * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); netsnmp_assert(entry && info); switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: { /* * build SnmpTLSFingerprint */ u_char bin[42], *ptr = bin; size_t len = sizeof(bin); int rc; rc = netsnmp_tls_fingerprint_build(entry->hashType, entry->fingerprint, &ptr, &len, 0); if (SNMPERR_SUCCESS != rc) netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); else snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, bin, len); } break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: tsnm[tsnm_pos] = entry->mapType; snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, tsnm, sizeof(tsnm)); break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, entry->data, entry->data_len); break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->storageType); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->rowStatus); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } /* switch colnum */ } /* for requests */ break; /* case MODE_GET */ /* * Write-support */ /** #################################################### RESERVE1 ##### * * In RESERVE1 we are just checking basic ASN.1 size/type restrictions. * You probably don't need to change any of this code. Don't change any * of the column values here. Save that for the ACTION phase. * * The next phase is RESERVE2 or FREE. */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { netsnmp_assert(request->processed == 0); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); if ((NULL != entry) && (ST_READONLY == entry->storageType)) { ret = SNMP_ERR_NOTWRITABLE; break; } switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, sizeof(entry->fingerprint)); /** check len/algorithm MIB requirements */ if (ret == SNMP_ERR_NOERROR) ret = netsnmp_cert_check_vb_fingerprint(request->requestvb); break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OBJECT_ID, SNMPTLSTMCERTTOTSN_MAPTYPE_MAX_SIZE); if (ret == SNMP_ERR_NOERROR) { if (_oid2type(request->requestvb->val.objid, request->requestvb->val_len) > TSNM_tlstmCert_MAX) ret = SNMP_ERR_WRONGVALUE; } break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: ret = netsnmp_check_vb_type_and_max_size (request->requestvb, ASN_OCTET_STR, sizeof(entry->data)); break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: ret = netsnmp_check_vb_storagetype (request->requestvb,(entry ? entry->storageType : ST_NONE)); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: ret = netsnmp_check_vb_rowstatus_with_storagetype (request->requestvb, (entry ? entry->rowStatus :RS_NONEXISTENT), (entry ? entry->storageType :ST_NONE)); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ default: ret = SNMP_ERR_NOTWRITABLE; } /* switch colnum */ if (ret != SNMP_ERR_NOERROR) break; } /* for requests */ break; /* case MODE_SET_RESERVE1 */ /** #################################################### RESERVE2 ##### * * RESERVE2 is for checking additional restrictions from the MIB. * Since these restrictions are often in the description of the object, * mib2c can't generate code. It's possible that you need to add * additional checks here. However, don't change any of the column * values here. Save that for the ACTION phase. * * The next phase is ACTION or FREE. */ case MODE_SET_RESERVE2: for (request = requests; request; request = request->next) { netsnmp_assert(request->processed == 0); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); table = netsnmp_tdata_extract_table(request); info = netsnmp_extract_table_info(request); /* * if no row, create one */ if (!entry) { row = tlstmCertToTSNTable_createEntry (table,*info->indexes->val.integer); if (!row) { ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } entry = row->data; _allocUndo(entry); if (!entry->undo) { tlstmCertToTSNTable_removeEntry(table, row); row = NULL; ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } entry->undo->fate = FATE_NEWLY_CREATED; /** associate row with requests */ netsnmp_insert_tdata_row(request, row); } /** allocate undo structure, if needed */ if (!entry->undo) { _allocUndo(entry); if (!entry->undo) { ret = SNMP_ERR_RESOURCEUNAVAILABLE; break; } } /* * save request ptr for column. if we already * have a value, bail. */ if (entry->undo->req[info->colnum]) { DEBUGMSGT(("tlstmCertToSN:reserve2", "multiple sets to col %d in request\n", info->colnum)); if (FATE_NEWLY_CREATED == entry->undo->fate) ret = SNMP_ERR_INCONSISTENTNAME; else ret = SNMP_ERR_INCONSISTENTVALUE; break; } entry->undo->req[info->colnum] = request; if (ret != SNMP_ERR_NOERROR) break; } /* for requests */ if (ret == SNMP_ERR_NOERROR) { /** make sure rowstatus is used to create rows */ for (request = requests; request; request = request->next) { if (request->processed) continue; entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if ((entry->undo->fate != FATE_NEWLY_CREATED) || (entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS])) continue; ret = SNMP_ERR_INCONSISTENTNAME; break; } /* creation for requests */ } /* no error */ break; /* case MODE_SET_RESERVE2 */ /** ######################################################## FREE ##### * * FREE is for cleaning up after a failed request (during either * RESERVE1 or RESERVE2). So any allocated resources need to be * released. * * This the final phase for this path in the state machine. */ case MODE_SET_FREE: /* * release undo resources * remove any newly created rows */ for (request = requests; request; request = request->next) { table = netsnmp_tdata_extract_table(request); row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if (!entry || !entry->undo) continue; /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); if (FATE_NEWLY_CREATED == entry->undo->fate) tlstmCertToTSNTable_removeEntry(table, row); else _freeUndo(entry); } break; /* case MODE_SET_FREE */ /** ###################################################### ACTION ##### * * In the ACTION phase, we perform any sets that can be undone. * (Save anything that can't be undone for the COMMIT phase.) * * After individual columns have been done, you should check that the * row as a whole is consistent. * * The next phase is UNDO or COMMIT. */ case MODE_SET_ACTION: for (request = requests; request; request = request->next) { entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); /** reserve2 should enforce this */ netsnmp_assert(request == entry->undo->req[info->colnum]); /* * for each col, save old value and the set new value */ switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: { u_char *tmp = (u_char*)entry->fingerprint; u_int size = sizeof(entry->fingerprint); netsnmp_variable_list *vb = request->requestvb; memcpy(entry->undo->fingerprint, entry->fingerprint, sizeof(entry->fingerprint)); entry->undo->fingerprint_len = entry->fingerprint_len; entry->undo->hashType = entry->hashType; memset(entry->fingerprint, 0, sizeof(entry->fingerprint)); (void)netsnmp_tls_fingerprint_parse(vb->val.string, vb->val_len, (char**)&tmp, &size, 0, &entry->hashType); entry->fingerprint_len = size; if (0 == entry->fingerprint_len) ret = SNMP_ERR_GENERR; } break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: entry->undo->mapType = entry->mapType; entry->mapType = _oid2type(request->requestvb->val.objid, request->requestvb->val_len); break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: memcpy(entry->undo->data, entry->data, sizeof(entry->data)); entry->undo->data_len = entry->data_len; memset(entry->data, 0, sizeof(entry->data)); memcpy(entry->data, request->requestvb->val.string, request->requestvb->val_len); entry->data_len = request->requestvb->val_len; break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: entry->undo->storageType = entry->storageType; entry->storageType = *request->requestvb->val.integer; break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: entry->undo->rowStatus = entry->rowStatus; entry->rowStatus = *request->requestvb->val.integer; break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ } /* switch colnum */ } /* set values for requests */ if (ret != SNMP_ERR_NOERROR) break; /* skip consistency if we've already got error */ /* * All columns now have their final values set. check the * internal consistency of each row. */ for (request = requests; request; request = request->next) { entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); if (entry->undo->is_consistent != -1) continue; /* already checked */ /** assume consistency */ entry->undo->is_consistent = 1; /* * per mib, can't have empty fingerprint and must * have data if indicated by map type. */ if (0 == entry->fingerprint_len) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "fingerprint must not be empty\n")); entry->undo->is_consistent = 0; } else if ((TSNM_tlstmCertSpecified == entry->mapType) && (0 == entry->data_len)) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "must specify Data for CertSpecified identity\n")); entry->undo->is_consistent = 0; } if ((RS_IS_ACTIVE(entry->rowStatus)) && ((!entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) || (RS_IS_ACTIVE(entry->undo->rowStatus)))) { /* * per mib, can't modify these while row active */ char _cols[3] = { COL_SNMPTLSTMCERTTOTSN_FINGERPRINT, COL_SNMPTLSTMCERTTOTSN_MAPTYPE, COL_SNMPTLSTMCERTTOTSN_DATA }; int i; for (i=0; i < 3; ++i ) { if (!entry->undo->req[i]) continue; DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "can't modify row %d while active\n", _cols[i])); entry->undo->is_consistent = 0; ret = SNMP_ERR_NOTWRITABLE; request= entry->undo->req[i]; break; } } else if (RS_IS_GOING_ACTIVE(entry->rowStatus)) { /* * if going active, inconsistency is fatal */ if (!entry->undo->is_consistent) { netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]); if (FATE_NEWLY_CREATED == entry->undo->fate) ret = SNMP_ERR_INCONSISTENTNAME; else ret = SNMP_ERR_INCONSISTENTVALUE; request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]; } } else if (RS_DESTROY == entry->rowStatus) { /* * can't destroy active row */ if (RS_IS_ACTIVE(entry->undo->rowStatus)) { DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent", "can't destroy active row\n")); netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]); ret = SNMP_ERR_INCONSISTENTVALUE; request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]; } } if (ret != SNMP_ERR_NOERROR) break; } /* consistency for requests */ break; /* case MODE_SET_ACTION */ /** ######################################################## UNDO ##### * * UNDO is for cleaning up any failed requests that went through the * ACTION phase. * * This the final phase for this path in the state machine. */ case MODE_SET_UNDO: for (request = requests; request; request = request->next) { row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); info = netsnmp_extract_table_info(request); /* * skip newly created rows, as we're going to delete * them below anyways */ if (FATE_NEWLY_CREATED == entry->undo->fate) continue; /* * restore values */ switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: memcpy(entry->fingerprint, entry->undo->fingerprint, sizeof(entry->fingerprint)); entry->fingerprint_len = entry->undo->fingerprint_len; entry->hashType = entry->undo->hashType; break; /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */ case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: entry->mapType = entry->undo->mapType; break; /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */ case COL_SNMPTLSTMCERTTOTSN_DATA: memcpy(entry->data, entry->undo->data, sizeof(entry->data)); entry->data_len = entry->undo->data_len; break; /* case COL_SNMPTLSTMCERTTOTSN_DATA */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: entry->storageType = entry->undo->storageType; break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: entry->rowStatus = entry->undo->rowStatus; break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ } /* switch colnum */ } /* for requests */ /* * release undo data * or remove any newly created rows */ for (request = requests; request; request = request->next) { table = netsnmp_tdata_extract_table(request); row = netsnmp_tdata_extract_row(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if (!entry || !entry->undo) continue; /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); if (FATE_NEWLY_CREATED == entry->undo->fate) tlstmCertToTSNTable_removeEntry(table, row); else _freeUndo(entry); } /* for requests */ break; /* case MODE_SET_UNDO */ /** ###################################################### COMMIT ##### * * COMMIT is the final success state, when all changes are finalized. * There is not recovery state should something faile here. * * This the final phase for this path in the state machine. */ case MODE_SET_COMMIT: for (request = requests; request; request = request->next) { row = netsnmp_tdata_extract_row(request); table = netsnmp_tdata_extract_table(request); info = netsnmp_extract_table_info(request); entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request); if ((RS_NOTREADY == entry->rowStatus) && entry->undo->is_consistent) entry->rowStatus = RS_NOTINSERVICE; else if ((RS_NOTINSERVICE == entry->rowStatus) && (0 == entry->undo->is_consistent)) entry->rowStatus = RS_NOTREADY; /** release undo data for requests with no rowstatus */ if (entry->undo && !entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) { _freeUndo(entry); if ((0 == entry->map_flags) && (entry->rowStatus == RS_ACTIVE)) _cert_map_add(entry); else if ((0 != entry->map_flags) && (entry->rowStatus == RS_DESTROY)) _cert_map_remove(entry); } switch (info->colnum) { case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS: switch (entry->rowStatus) { case RS_CREATEANDGO: /** Fall-through */ case RS_ACTIVE: netsnmp_assert(entry->undo->is_consistent); entry->rowStatus = RS_ACTIVE; if (0 == entry->map_flags) _cert_map_add(entry); break; case RS_CREATEANDWAIT: /** Fall-through */ case RS_NOTINSERVICE: /** simply set status based on consistency */ if (entry->undo->is_consistent) entry->rowStatus = RS_NOTINSERVICE; else entry->rowStatus = RS_NOTREADY; if (0 != entry->map_flags) _cert_map_remove(entry); break; case RS_DESTROY: /** remove from cert map */ if (0 != entry->map_flags) _cert_map_remove(entry); /** disassociate row with requests */ netsnmp_remove_tdata_row(request, row); tlstmCertToTSNTable_removeEntry(table, row); row = NULL; entry = NULL; } /** release undo data */ _freeUndo(entry); break; /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */ case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE: if (RS_ACTIVE == entry->rowStatus) _cert_map_tweak_storage(entry); break; /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */ case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT: case COL_SNMPTLSTMCERTTOTSN_MAPTYPE: case COL_SNMPTLSTMCERTTOTSN_DATA: break; } /* switch colnum */ } /* for requests */ /** update last changed */ _last_changed = netsnmp_get_agent_uptime(); /** set up to save persistent store */ snmp_store_needed(NULL); break; /* case MODE_SET_COMMIT */ } /* switch (reqinfo->mode) */ if (ret != SNMP_ERR_NOERROR) netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; }
/************************************************************ * Assuming that the RESERVE phases were successful, the next * stage is indicated by the action value ACTION. This is used * to actually implement the set operation. However, this must * either be done into temporary (persistent) storage, or the * previous value stored similarly, in case any of the subsequent * ACTION calls fail. * * In your case, changes should be made to row_ctx. A copy of * the original row is in undo_ctx. */ void saHpiHotSwapTable_set_action( netsnmp_request_group *rg ) { netsnmp_variable_list *var; saHpiHotSwapTable_context *row_ctx = (saHpiHotSwapTable_context *)rg->existing_row; saHpiHotSwapTable_context *undo_ctx = (saHpiHotSwapTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* * TODO: loop through columns, copy varbind values * to context structure for the row. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { case COLUMN_SAHPIHOTSWAPINDICATOR: /** INTEGER = ASN_INTEGER */ row_ctx->saHpiHotSwapIndicator = *var->val.integer; break; case COLUMN_SAHPIHOTSWAPSTATE: /** SaHpiHotSwapState = ASN_INTEGER */ row_ctx->saHpiHotSwapState = *var->val.integer; break; case COLUMN_SAHPIHOTSWAPEXTRACTTIMEOUT: /** SaHpiTime = ASN_COUNTER64 */ row_ctx->saHpiHotSwapExtractTimeout = *var->val.integer; break; case COLUMN_SAHPIHOTSWAPACTIONREQUEST: /** INTEGER = ASN_INTEGER */ row_ctx->saHpiHotSwapActionRequest = *var->val.integer; break; case COLUMN_SAHPIHOTSWAPPOLICYCANCEL: /** INTEGER = ASN_INTEGER */ row_ctx->saHpiHotSwapPolicyCancel = *var->val.integer; break; case COLUMN_SAHPIHOTSWAPRESOURCEREQUEST: /** INTEGER = ASN_INTEGER */ row_ctx->saHpiHotSwapResourceRequest = *var->val.integer; break; default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } /* * done with all the columns. Could check row related * requirements here. */ #ifndef saHpiHotSwapTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->saHpiDomainAlarmRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->saHpiDomainAlarmRowStatus) ) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->saHpiDomainAlarmRowStatus : NULL, undo_ctx ? &undo_ctx->saHpiDomainAlarmRowStatus : NULL); if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } /* * TODO: if you have dependencies on other tables, this would be * a good place to check those, too. */ }
/* * This function is called only when all the *_reserve[1|2] functions were * succeful. Its purpose is to make any changes to the row before it is * inserted into the table. * * In our case, we don't require any changes. So we leave the original * auto-generated code as is. */ void openserSIPStatusCodesTable_set_action( netsnmp_request_group *rg ) { netsnmp_variable_list *var; openserSIPStatusCodesTable_context *row_ctx = (openserSIPStatusCodesTable_context *)rg->existing_row; openserSIPStatusCodesTable_context *undo_ctx = (openserSIPStatusCodesTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* Depending on what the snmpset was, set the row to be created or * deleted. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { case COLUMN_OPENSERSIPSTATUSCODEROWSTATUS: /** RowStatus = ASN_INTEGER */ row_ctx->openserSIPStatusCodeRowStatus = *var->val.integer; if (*var->val.integer == TC_ROWSTATUS_CREATEANDGO) { rg->row_created = 1; } else if (*var->val.integer == TC_ROWSTATUS_DESTROY) { rg->row_deleted = 1; } else { /* We should never be here, because the RESERVE * functions should have taken care of all other * values. */ LM_ERR("Invalid RowStatus in openserSIPStatusCodesTable\n"); } break; default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } /* * done with all the columns. Could check row related * requirements here. */ #ifndef openserSIPStatusCodesTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->openserSIPStatusCodeRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->openserSIPStatusCodeRowStatus)) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->openserSIPStatusCodeRowStatus : NULL, undo_ctx ? &undo_ctx->openserSIPStatusCodeRowStatus : NULL); if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } }
/* * This function is called only when all the *_reserve[1|2] functions were * succeful. Its purpose is to make any changes to the row before it is * inserted into the table. * * In the case of this table, this involves looking up the index of the * requested user in the URI to userIndex mapping hash table. If the result is * found, the index will be copied to the row, and the rowStatus set to * 'active'. Otherwise, the row status will be set to 'notInService' * * All other handling is auto-generated. */ void openserSIPRegUserLookupTable_set_action( netsnmp_request_group *rg ) { /* First things first, we need to consume the interprocess buffer, in * case something has changed. We want to return the freshest data. */ consumeInterprocessBuffer(); aorToIndexStruct_t *hashRecord; netsnmp_variable_list *var; openserSIPRegUserLookupTable_context *row_ctx = (openserSIPRegUserLookupTable_context *)rg->existing_row; openserSIPRegUserLookupTable_context *undo_ctx = (openserSIPRegUserLookupTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* Copy the actual data to the row. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { case COLUMN_OPENSERSIPREGUSERLOOKUPURI: row_ctx->openserSIPRegUserLookupURI = pkg_malloc(sizeof(char)*(var->val_len + 1)); memcpy(row_ctx->openserSIPRegUserLookupURI, var->val.string, var->val_len); /* Usually NetSNMP won't terminate strings with '\0'. * The hash function expect them to be terminated * though, so we have to add this on to the end. The +1 * in the malloc makes sure of the extra space for us. */ row_ctx->openserSIPRegUserLookupURI[var->val_len] = '\0'; row_ctx->openserSIPRegUserLookupURI_len = var->val_len; /* Do the lookup. If we could find the record, then set * the index and the row status to active. Otherwise, * set the row to notInService */ hashRecord = findHashRecord(hashTable, (char *) row_ctx->openserSIPRegUserLookupURI, HASH_SIZE); if (hashRecord == NULL) { row_ctx->openserSIPRegUserIndex = 0; row_ctx->openserSIPRegUserLookupRowStatus = TC_ROWSTATUS_NOTINSERVICE; } else { row_ctx->openserSIPRegUserIndex = hashRecord->userIndex; row_ctx->openserSIPRegUserLookupRowStatus = TC_ROWSTATUS_ACTIVE; } break; case COLUMN_OPENSERSIPREGUSERLOOKUPROWSTATUS: row_ctx->openserSIPRegUserLookupRowStatus = *var->val.integer; if (*var->val.integer == TC_ROWSTATUS_CREATEANDGO) { rg->row_created = 1; /* Set to NOT READY until the lookup URI has * been supplied. */ row_ctx->openserSIPRegUserLookupRowStatus = TC_ROWSTATUS_NOTREADY; } else if (*var->val.integer == TC_ROWSTATUS_DESTROY) { rg->row_deleted = 1; } else { /* We should never be here, because the RESERVE * functions should have taken care of all other * values. */ LM_ERR("invalid RowStatus in openserSIPStatusCodesTable\n"); } break; default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } /* * done with all the columns. Could check row related * requirements here. */ #ifndef openserSIPRegUserLookupTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->openserSIPRegUserLookupRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->openserSIPRegUserLookupRowStatus) ) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->openserSIPRegUserLookupRowStatus : NULL, undo_ctx ? &undo_ctx->openserSIPRegUserLookupRowStatus : NULL); if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } }
/************************************************************ * Assuming that the RESERVE phases were successful, the next * stage is indicated by the action value ACTION. This is used * to actually implement the set operation. However, this must * either be done into temporary (persistent) storage, or the * previous value stored similarly, in case any of the subsequent * ACTION calls fail. * * In your case, changes should be made to row_ctx. A copy of * the original row is in undo_ctx. */ void saHpiUserEventTable_set_action( netsnmp_request_group *rg ) { netsnmp_variable_list *var; saHpiUserEventTable_context *row_ctx = (saHpiUserEventTable_context *)rg->existing_row; saHpiUserEventTable_context *undo_ctx = (saHpiUserEventTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* * TODO: loop through columns, copy varbind values * to context structure for the row. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { case COLUMN_SAHPIUSEREVENTTIMESTAMP: /** SaHpiTime = ASN_COUNTER64 */ row_ctx->saHpiUserEventTimestamp = *var->val.integer; break; case COLUMN_SAHPIUSEREVENTTEXTTYPE: /** SaHpiTextType = ASN_INTEGER */ row_ctx->saHpiUserEventTextType = *var->val.integer; break; case COLUMN_SAHPIUSEREVENTTEXTLANGUAGE: /** SaHpiTextLanguage = ASN_INTEGER */ row_ctx->saHpiUserEventTextLanguage = *var->val.integer; break; case COLUMN_SAHPIUSEREVENTTEXT: /** SaHpiText = ASN_OCTET_STR */ memcpy(row_ctx->saHpiUserEventText,var->val.string,var->val_len); row_ctx->saHpiUserEventText_len = var->val_len; break; case COLUMN_SAHPIUSEREVENTROWSTATUS: /** RowStatus = ASN_INTEGER */ row_ctx->saHpiUserEventRowStatus = *var->val.integer; break; default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } /* * done with all the columns. Could check row related * requirements here. */ #ifndef saHpiUserEventTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->saHpiDomainAlarmRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->saHpiDomainAlarmRowStatus) ) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->saHpiDomainAlarmRowStatus : NULL, undo_ctx ? &undo_ctx->saHpiDomainAlarmRowStatus : NULL); if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } /* * TODO: if you have dependencies on other tables, this would be * a good place to check those, too. */ }
/************************************************************ * Assuming that the RESERVE phases were successful, the next * stage is indicated by the action value ACTION. This is used * to actually implement the set operation. However, this must * either be done into temporary (persistent) storage, or the * previous value stored similarly, in case any of the subsequent * ACTION calls fail. * * In your case, changes should be made to row_ctx. A copy of * the original row is in undo_ctx. */ void saHpiWatchdogTable_set_action( netsnmp_request_group *rg ) { netsnmp_variable_list *var; saHpiWatchdogTable_context *row_ctx = (saHpiWatchdogTable_context *)rg->existing_row; saHpiWatchdogTable_context *undo_ctx = (saHpiWatchdogTable_context *)rg->undo_info; netsnmp_request_group_item *current; int row_err = 0; /* * TODO: loop through columns, copy varbind values * to context structure for the row. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; switch(current->tri->colnum) { case COLUMN_SAHPIWATCHDOGLOG: /** TruthValue = ASN_INTEGER */ row_ctx->saHpiWatchdogLog = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGRUNNING: /** TruthValue = ASN_INTEGER */ row_ctx->saHpiWatchdogRunning = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGTIMERUSE: /** SaHpiWatchdogTimerUse = ASN_INTEGER */ row_ctx->saHpiWatchdogTimerUse = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGTIMERACTION: /** INTEGER = ASN_INTEGER */ row_ctx->saHpiWatchdogTimerAction = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGPRETIMERINTERRUPT: /** SaHpiWatchdogPreTimerAction = ASN_INTEGER */ row_ctx->saHpiWatchdogPretimerInterrupt = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGPRETIMEOUTINTERVAL: /** UNSIGNED32 = ASN_UNSIGNED */ row_ctx->saHpiWatchdogPreTimeoutInterval = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGTIMERUSEEXPFLAGS: /** OCTETSTR = ASN_OCTET_STR */ memcpy(row_ctx->saHpiWatchdogTimerUseExpFlags,var->val.string,var->val_len); row_ctx->saHpiWatchdogTimerUseExpFlags_len = var->val_len; break; case COLUMN_SAHPIWATCHDOGTIMERINITIALCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ row_ctx->saHpiWatchdogTimerInitialCount = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGTIMERPRESENTCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ row_ctx->saHpiWatchdogTimerPresentCount = *var->val.integer; break; case COLUMN_SAHPIWATCHDOGTIMERRESET: /** TruthValue = ASN_INTEGER */ row_ctx->saHpiWatchdogTimerReset = *var->val.integer; break; default: /** We shouldn't get here */ netsnmp_assert(0); /** why wasn't this caught in reserve1? */ } } /* * done with all the columns. Could check row related * requirements here. */ #ifndef saHpiWatchdogTable_CAN_MODIFY_ACTIVE_ROW if( undo_ctx && RS_IS_ACTIVE(undo_ctx->saHpiDomainAlarmRowStatus) && row_ctx && RS_IS_ACTIVE(row_ctx->saHpiDomainAlarmRowStatus) ) { row_err = 1; } #endif /* * check activation/deactivation */ row_err = netsnmp_table_array_check_row_status(&cb, rg, row_ctx ? &row_ctx->saHpiDomainAlarmRowStatus : NULL, undo_ctx ? &undo_ctx->saHpiDomainAlarmRowStatus : NULL); if(row_err) { netsnmp_set_mode_request_error(MODE_SET_BEGIN, (netsnmp_request_info*)rg->rg_void, row_err); return; } /* * TODO: if you have dependencies on other tables, this would be * a good place to check those, too. */ }