1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2004-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20-module(snmpa_mib_lib). 21 22-export([table_cre_row/3, table_del_row/2]). 23-export([get_table/2]). 24-export([print_variables/1, print_table/3, print_table/4, print_tables/1]). 25-export([gc_tab/3, gc_tab/5]). 26 27-include("SNMPv2-TC.hrl"). 28-include("snmp_types.hrl"). 29 30-define(VMODULE,"MIB-LIB"). 31-include("snmp_verbosity.hrl"). 32 33-ifndef(default_verbosity). 34-define(default_verbosity,silence). 35-endif. 36 37 38%%%----------------------------------------------------------------- 39%%%----------------------------------------------------------------- 40 41%% returns: bool() 42table_cre_row({Tab, mnesia}, Key, _Row) -> 43 ?vtrace("create mnesia table ~w row with Key: ~w",[Tab, Key]), 44 {error, mnesia_not_supported}; 45table_cre_row({Tab, Db} = TabDb, Key, Row) -> 46 ?vtrace("create ~w table ~w row with Key: ~w",[Db, Tab, Key]), 47 snmpa_local_db:table_create_row(TabDb, Key, Row). 48 49%% returns: bool() 50table_del_row({Tab, mnesia}, Key) -> 51 ?vtrace("delete mnesia table ~w row with Key: ~w",[Tab, Key]), 52 {error, mnesia_not_supported}; 53table_del_row({Tab, Db} = TabDb, Key) -> 54 ?vtrace("delete ~w table ~w row with Key: ~w", [Db, Tab, Key]), 55 snmpa_local_db:table_delete_row(TabDb, Key). 56 57 58%%%----------------------------------------------------------------- 59%%% Retreives the entire table. Used for debugging 60%%%----------------------------------------------------------------- 61 62get_table(NameDb, FOI) -> 63 (catch get_table(NameDb, FOI, [], [])). 64 65get_table(NameDb, FOI, Key, Acc) -> 66 case table_next(NameDb, Key) of 67 endOfTable -> 68 ?vdebug("end of table",[]), 69 {ok, lists:reverse(Acc)}; 70 Key -> 71 %% Crap, circular ref 72 ?vinfo("cyclic reference: ~w -> ~w", [Key, Key]), 73 throw({error, {cyclic_db_reference, Key, Acc}}); 74 NextKey -> 75 ?vtrace("get row for key ~w", [NextKey]), 76 case table_get_row(NameDb, NextKey, FOI) of 77 undefined -> 78 throw({error, {invalid_rowindex, NextKey, Acc}}); 79 Row -> 80 ?vtrace("row: ~w", [Row]), 81 get_table(NameDb, FOI, NextKey, [{NextKey, Row}|Acc]) 82 end 83 end. 84 85 86print_variables(Variables) when is_list(Variables) -> 87 Variables2 = print_variables_prefixify(Variables), 88 lists:foreach(fun({Variable, ValueResult, Prefix}) -> 89 print_variable(Variable, ValueResult, Prefix) 90 end, Variables2), 91 ok. 92 93print_variable(Variable, {value, Val}, Prefix) when is_atom(Variable) -> 94 io:format("~w~s=> ~p~n", [Variable, Prefix, Val]); 95print_variable(Variable, Error, Prefix) when is_atom(Variable) -> 96 io:format("~w~s=> [e] ~p~n", [Variable, Prefix, Error]). 97 98print_variables_prefixify(Variables) -> 99 MaxVarLength = print_variables_maxlength(Variables), 100 print_variables_prefixify(Variables, MaxVarLength, []). 101 102print_variables_prefixify([], _MaxVarLength, Acc) -> 103 lists:reverse(Acc); 104print_variables_prefixify([{Var, Res}|Variables], MaxVarLength, Acc) -> 105 Prefix = make_variable_print_prefix(Var, MaxVarLength), 106 print_variables_prefixify(Variables, MaxVarLength, 107 [{Var, Res, Prefix}|Acc]). 108 109make_variable_print_prefix(Var, MaxVarLength) -> 110 lists:duplicate(MaxVarLength - length(atom_to_list(Var)) + 1, $ ). 111 112print_variables_maxlength(Variables) -> 113 print_variables_maxlength(Variables, 0). 114 115print_variables_maxlength([], MaxLength) -> 116 MaxLength; 117print_variables_maxlength([{Var, _}|Variables], MaxLength) when is_atom(Var) -> 118 VarLen = length(atom_to_list(Var)), 119 if 120 VarLen > MaxLength -> 121 print_variables_maxlength(Variables, VarLen); 122 true -> 123 print_variables_maxlength(Variables, MaxLength) 124 end. 125 126 127print_tables(Tables) when is_list(Tables) -> 128 lists:foreach(fun({Table, DB, FOI, PrintRow}) -> 129 print_table(Table, DB, FOI, PrintRow) 130 end, Tables), 131 ok. 132 133print_table(Table, DB, FOI, PrintRow) -> 134 TableInfo = get_table(DB, FOI), 135 print_table(Table, TableInfo, PrintRow). 136 137print_table(Table, TableInfo, PrintRow) when is_function(PrintRow, 2) -> 138 io:format("~w =>", [Table]), 139 do_print_table(TableInfo, PrintRow). 140 141do_print_table({ok, [] = _TableInfo}, _PrintRow) -> 142 io:format(" -~n", []); 143do_print_table({ok, TableInfo}, PrintRow) when is_function(PrintRow, 2) -> 144 io:format("~n", []), 145 lists:foreach(fun({RowIdx, Row}) -> 146 io:format(" ~w => ~n~s~n", 147 [RowIdx, PrintRow(" ", Row)]) 148 end, TableInfo); 149do_print_table({error, {invalid_rowindex, BadRowIndex, []}}, _PrintRow) -> 150 io:format("Error: Bad rowindex ~w~n", [BadRowIndex]); 151do_print_table({error, {invalid_rowindex, BadRowIndex, TableInfo}}, PrintRow) -> 152 io:format("Error: Bad rowindex ~w", [BadRowIndex]), 153 do_print_table(TableInfo, PrintRow); 154do_print_table(Error, _PrintRow) -> 155 io:format("Error: ~p~n", [Error]). 156 157 158%%%----------------------------------------------------------------- 159%%% 160%%%----------------------------------------------------------------- 161 162table_next({Name, mnesia}, RestOid) -> 163 snmp_generic_mnesia:table_next(Name, RestOid); 164table_next(NameDb, RestOid) -> 165 snmpa_local_db:table_next(NameDb, RestOid). 166 167 168table_get_row({Name, mnesia}, RowIndex) -> 169 snmp_generic_mnesia:table_get_row(Name, RowIndex); 170table_get_row(NameDb, RowIndex) -> 171 snmpa_local_db:table_get_row(NameDb, RowIndex). 172 173table_get_row(NameDb, RowIndex, undefined) -> 174 table_get_row(NameDb, RowIndex); 175table_get_row({Name, mnesia}, RowIndex, FOI) -> 176 snmp_generic_mnesia:table_get_row(Name, RowIndex, FOI); 177table_get_row(NameDb, RowIndex, _FOI) -> 178 snmpa_local_db:table_get_row(NameDb, RowIndex). 179 180 181%%%----------------------------------------------------------------- 182%%% Utility module for the mib-implementation modules (such as 183%%% snmp_target_mib). 184%%%----------------------------------------------------------------- 185 186gc_tab(TabDb, STC, FOI) -> 187 InvalidateRow = fun(_) -> ok end, 188 UpdateRow = fun(_) -> ok end, 189 gc_tab(TabDb, STC, FOI, InvalidateRow, UpdateRow). 190 191gc_tab({Tab,mnesia} = TabDb, STC, FOI, InvalidateRow, UpdateRow) -> 192 F = fun(RowIndex, Row) -> 193 case element(STC, Row) of 194 ?'StorageType_volatile' -> 195 snmp_generic_mnesia:table_delete_row(Tab, RowIndex), 196 InvalidateRow(RowIndex); 197 _ -> 198 UpdateRow(RowIndex) 199 end 200 end, 201 gc_tab1(F, TabDb, FOI); 202 203gc_tab(TabDb, STC, FOI, InvalidateRow, UpdateRow) -> 204 F = fun(RowIndex, Row) -> 205 case element(STC, Row) of 206 ?'StorageType_volatile' -> 207 snmpa_local_db:table_delete_row(TabDb, RowIndex), 208 InvalidateRow(RowIndex); 209 _ -> 210 UpdateRow(RowIndex), 211 ok 212 end 213 end, 214 gc_tab1(F, TabDb, FOI). 215 216 217gc_tab1(F, {Tab,_} = TabDb, FOI) -> 218 case (catch snmp_generic:table_foreach(TabDb, F, FOI)) of 219 {'EXIT',{cyclic_db_reference,Oid}} -> 220 %% Remove the row regardless of storage type since this 221 %% is a major error. This row must be removed. 222 case table_delete_row(TabDb, Oid) of 223 true -> 224 ?vlog("deleted cyclic ref row for: ~w;~w", 225 [Tab, Oid]), 226 config_err("cyclic reference in table ~w: " 227 "~w -> ~w. Row deleted", 228 [Tab, Oid, Oid]), 229 gc_tab1(F, TabDb, FOI); 230 false -> 231 ?vlog("unable to remove faulty row from table ~w", 232 [Tab]), 233 config_err("failed removing faulty row. " 234 "Giving up on table ~w cleanup", [Tab]) 235 end; 236 _ -> 237 ok 238 end. 239 240table_delete_row({Tab, mnesia}, Oid) -> 241 snmp_generic_mnesia:table_delete_row(Tab, Oid), 242 true; 243table_delete_row(TabDb, Oid) -> 244 snmpa_local_db:table_delete_row(TabDb, Oid). 245 246config_err(F, A) -> 247 snmpa_error:config_err(F, A). 248