Code Search for Developers
 
 
  

agent__registry_8c-source.html from net-snmp at Krugle


Show agent__registry_8c-source.html syntax highlighted

<!--#set var="section" value="development" -->
<!--#include virtual="/page-top.html" -->
<!-- CONTENT START -->
  <!-- Generated by Doxygen 1.3.9.1 -->

  <div class="qindex">
    <a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class=
    "qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class=
    "qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a> | <a class=
    "qindex" href="examples.html">Examples</a>
  </div>

  <div class="nav">
    <a class="el" href="dir_000003.html">agent</a>
  </div>

  <h1>agent_registry.c</h1>

  <div class="fragment">
    <pre class="fragment">
00001 <span class="comment">/*</span>
00002 <span class="comment"> * agent_registry.c</span>
00003 <span class="comment"> */</span>
00004 <span class="comment">/* Portions of this file are subject to the following copyright(s).  See</span>
00005 <span class="comment"> * the Net-SNMP's COPYING file for more details and other copyrights</span>
00006 <span class="comment"> * that may apply:</span>
00007 <span class="comment"> */</span>
00008 <span class="comment">/*</span>
00009 <span class="comment"> * Portions of this file are copyrighted by:</span>
00010 <span class="comment"> * Copyright &copy; 2003 Sun Microsystems, Inc. All rights reserved.</span>
00011 <span class="comment"> * Use is subject to license terms specified in the COPYING file</span>
00012 <span class="comment"> * distributed with the Net-SNMP package.</span>
00013 <span class="comment"> */</span>
00020 <span class="preprocessor">#define IN_SNMP_VARS_C</span>
00021 
00022 <span class="preprocessor">#include &lt;net-snmp/net-snmp-config.h&gt;</span>
00023 <span class="preprocessor">#include &lt;signal.h&gt;</span>
00024 <span class="preprocessor">#if HAVE_STRING_H</span>
00025 <span class="preprocessor">#include &lt;string.h&gt;</span>
00026 <span class="preprocessor">#endif</span>
00027 <span class="preprocessor">#if HAVE_STDLIB_H</span>
00028 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
00029 <span class="preprocessor">#endif</span>
00030 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
00031 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
00032 <span class="preprocessor">#include &lt;fcntl.h&gt;</span>
00033 <span class="preprocessor">#if HAVE_WINSOCK_H</span>
00034 <span class="preprocessor">#include &lt;winsock.h&gt;</span>
00035 <span class="preprocessor">#endif</span>
00036 <span class="preprocessor">#if TIME_WITH_SYS_TIME</span>
00037 <span class="preprocessor"># ifdef WIN32</span>
00038 <span class="preprocessor">#  include &lt;sys/timeb.h&gt;</span>
00039 <span class="preprocessor"># else</span>
00040 <span class="preprocessor">#  include &lt;sys/time.h&gt;</span>
00041 <span class="preprocessor"># endif</span>
00042 <span class="preprocessor"># include &lt;time.h&gt;</span>
00043 <span class="preprocessor">#else</span>
00044 <span class="preprocessor"># if HAVE_SYS_TIME_H</span>
00045 <span class="preprocessor">#  include &lt;sys/time.h&gt;</span>
00046 <span class="preprocessor"># else</span>
00047 <span class="preprocessor">#  include &lt;time.h&gt;</span>
00048 <span class="preprocessor"># endif</span>
00049 <span class="preprocessor">#endif</span>
00050 <span class="preprocessor">#if HAVE_NETINET_IN_H</span>
00051 <span class="preprocessor">#include &lt;netinet/in.h&gt;</span>
00052 <span class="preprocessor">#endif</span>
00053 
00054 <span class="preprocessor">#include &lt;net-snmp/net-snmp-includes.h&gt;</span>
00055 <span class="preprocessor">#include &lt;net-snmp/agent/net-snmp-agent-includes.h&gt;</span>
00056 <span class="preprocessor">#include &lt;net-snmp/agent/agent_callbacks.h&gt;</span>
00057 
00058 <span class="preprocessor">#include "snmpd.h"</span>
00059 <span class="preprocessor">#include "mibgroup/struct.h"</span>
00060 <span class="preprocessor">#include &lt;net-snmp/agent/old_api.h&gt;</span>
00061 <span class="preprocessor">#include &lt;net-snmp/agent/null.h&gt;</span>
00062 <span class="preprocessor">#include &lt;net-snmp/agent/table.h&gt;</span>
00063 <span class="preprocessor">#include &lt;net-snmp/agent/table_iterator.h&gt;</span>
00064 <span class="preprocessor">#include &lt;net-snmp/agent/agent_registry.h&gt;</span>
00065 <span class="preprocessor">#include "mib_module_includes.h"</span>
00066 
00067 <span class="preprocessor">#ifdef USING_AGENTX_SUBAGENT_MODULE</span>
00068 <span class="preprocessor">#include "agentx/subagent.h"</span>
00069 <span class="preprocessor">#include "agentx/client.h"</span>
00070 <span class="preprocessor">#endif</span>
00071 
00072 <span class="keyword">static</span> <span class="keywordtype">void</span> register_mib_detach_node(netsnmp_subtree *s);
00073 NETSNMP_STATIC_INLINE <span class="keywordtype">void</span> invalidate_lookup_cache(<span class=
"keyword">const</span> <span class="keywordtype">char</span> *context);
00074 <span class="keywordtype">void</span> <a class="code" href=
"group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(<span class="keywordtype">int</span> newsize);
00075 <span class="keywordtype">int</span> <a class="code" href=
"group__agent__registry.html#ga10">netsnmp_get_lookup_cache_size</a>(<span class="keywordtype">void</span>);
00076 
00077 subtree_context_cache *context_subtrees = NULL;
00078 
00079 <span class="keywordtype">void</span>
00080 netsnmp_subtree_free(netsnmp_subtree *a)
00081 {
00082   <span class="keywordflow">if</span> (a != NULL) {
00083     <span class="keywordflow">if</span> (a-&gt;variables != NULL &amp;&amp; <a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(a-&gt;name_a, a-&gt;namelen, 
00084                                              a-&gt;start_a, a-&gt;start_len) == 0) {
00085       <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a-&gt;variables);
00086     }
00087     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a-&gt;name_a);
00088     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a-&gt;start_a);
00089     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a-&gt;end_a);
00090     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a-&gt;label_a);
00091     <a class="code" href="group__handler.html#ga21">netsnmp_handler_registration_free</a>(a-&gt;reginfo);
00092     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(a);
00093   }
00094 }
00095 
00096 netsnmp_subtree *
00097 netsnmp_subtree_deepcopy(netsnmp_subtree *a)
00098 {
00099   netsnmp_subtree *b = (netsnmp_subtree *)calloc(1, <span class="keyword">sizeof</span>(netsnmp_subtree));
00100 
00101   <span class="keywordflow">if</span> (b != NULL) {
00102     memcpy(b, a, <span class="keyword">sizeof</span>(netsnmp_subtree));
00103     b-&gt;name_a  = snmp_duplicate_objid(a-&gt;name_a,  a-&gt;namelen);
00104     b-&gt;start_a = snmp_duplicate_objid(a-&gt;start_a, a-&gt;start_len);
00105     b-&gt;end_a   = snmp_duplicate_objid(a-&gt;end_a,   a-&gt;end_len);
00106     b-&gt;label_a = strdup(a-&gt;label_a);
00107     
00108     <span class="keywordflow">if</span> (b-&gt;name_a == NULL || b-&gt;start_a == NULL || 
00109         b-&gt;end_a  == NULL || b-&gt;label_a == NULL) {
00110       netsnmp_subtree_free(b);
00111       <span class="keywordflow">return</span> NULL;
00112     }
00113 
00114     <span class="keywordflow">if</span> (a-&gt;variables != NULL) {
00115       b-&gt;variables = (<span class="keyword">struct </span>variable *)malloc(a-&gt;variables_len * 
00116                                                a-&gt;variables_width);
00117       <span class="keywordflow">if</span> (b-&gt;variables != NULL) {
00118         memcpy(b-&gt;variables, a-&gt;variables,a-&gt;variables_len*a-&gt;variables_width);
00119       } <span class="keywordflow">else</span> {
00120         netsnmp_subtree_free(b);
00121         <span class="keywordflow">return</span> NULL;
00122       }
00123     }
00124 
00125     <span class="keywordflow">if</span> (a-&gt;reginfo != NULL) {
00126       b-&gt;reginfo = <a class="code" href="group__handler.html#ga22">netsnmp_handler_registration_dup</a>(a-&gt;reginfo);
00127       <span class="keywordflow">if</span> (b-&gt;reginfo == NULL) {
00128         netsnmp_subtree_free(b);
00129         <span class="keywordflow">return</span> NULL;
00130       }
00131     }
00132   }
00133   <span class="keywordflow">return</span> b;
00134 }
00135 
00136 subtree_context_cache *
00137 get_top_context_cache(<span class="keywordtype">void</span>)
00138 {
00139     <span class="keywordflow">return</span> context_subtrees;
00140 }
00141 
00142 netsnmp_subtree *
00143 netsnmp_subtree_find_first(<span class="keyword">const</span> <span class="keywordtype">char</span> *context_name)
00144 {
00145     subtree_context_cache *ptr;
00146 
00147     <span class="keywordflow">if</span> (!context_name) {
00148         context_name = <span class="stringliteral">""</span>;
00149     }
00150 
00151     DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class=
"stringliteral">"looking for subtree for context: \"%s\"\n"</span>, 
00152                 context_name));
00153     <span class="keywordflow">for</span> (ptr = context_subtrees; ptr != NULL; ptr = ptr-&gt;next) {
00154         <span class="keywordflow">if</span> (ptr-&gt;context_name != NULL &amp;&amp; 
00155             strcmp(ptr-&gt;context_name, context_name) == 0) {
00156             DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class=
"stringliteral">"found one for: \"%s\"\n"</span>, context_name));
00157             <span class="keywordflow">return</span> ptr-&gt;first_subtree;
00158         }
00159     }
00160     DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class=
"stringliteral">"didn't find a subtree for context: \"%s\"\n"</span>, 
00161                 context_name));
00162     <span class="keywordflow">return</span> NULL;
00163 }
00164 
00165 netsnmp_subtree *
00166 add_subtree(netsnmp_subtree *new_tree, <span class="keyword">const</span> <span class=
"keywordtype">char</span> *context_name)
00167 {
00168     subtree_context_cache *ptr = <a class="code" href=
"group__util.html#ga39">SNMP_MALLOC_TYPEDEF</a>(subtree_context_cache);
00169     
00170     <span class="keywordflow">if</span> (!context_name) {
00171         context_name = <span class="stringliteral">""</span>;
00172     }
00173 
00174     <span class="keywordflow">if</span> (!ptr) {
00175         <span class="keywordflow">return</span> NULL;
00176     }
00177     
00178     DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class=
"stringliteral">"adding subtree for context: \"%s\"\n"</span>,      
00179                 context_name));
00180 
00181     ptr-&gt;next = context_subtrees;
00182     ptr-&gt;first_subtree = new_tree;
00183     ptr-&gt;context_name = strdup(context_name);
00184     context_subtrees = ptr;
00185 
00186     <span class="keywordflow">return</span> ptr-&gt;first_subtree;
00187 }
00188 
00189 netsnmp_subtree *
00190 netsnmp_subtree_replace_first(netsnmp_subtree *new_tree, 
00191                               <span class="keyword">const</span> <span class="keywordtype">char</span> *context_name)
00192 {
00193     subtree_context_cache *ptr;
00194     <span class="keywordflow">if</span> (!context_name) {
00195         context_name = <span class="stringliteral">""</span>;
00196     }
00197     <span class="keywordflow">for</span> (ptr = context_subtrees; ptr != NULL; ptr = ptr-&gt;next) {
00198         <span class="keywordflow">if</span> (ptr-&gt;context_name != NULL &amp;&amp;
00199             strcmp(ptr-&gt;context_name, context_name) == 0) {
00200             ptr-&gt;first_subtree = new_tree;
00201             <span class="keywordflow">return</span> ptr-&gt;first_subtree;
00202         }
00203     }
00204     <span class="keywordflow">return</span> add_subtree(new_tree, context_name);
00205 }
00206 
00207 NETSNMP_INLINE <span class="keywordtype">void</span>
00208 netsnmp_subtree_change_next(netsnmp_subtree *ptr, netsnmp_subtree *thenext)
00209 {
00210     ptr-&gt;next = thenext;
00211     <span class="keywordflow">if</span> (thenext)
00212         <a class="code" href="group__library.html#ga104">netsnmp_oid_compare_ll</a>(ptr-&gt;start_a,
00213                                ptr-&gt;start_len,
00214                                thenext-&gt;start_a,
00215                                thenext-&gt;start_len,
00216                                &amp;thenext-&gt;oid_off);
00217 }
00218 
00219 NETSNMP_INLINE <span class="keywordtype">void</span>
00220 netsnmp_subtree_change_prev(netsnmp_subtree *ptr, netsnmp_subtree *theprev)
00221 {
00222     ptr-&gt;prev = theprev;
00223     <span class="keywordflow">if</span> (theprev)
00224         <a class="code" href="group__library.html#ga104">netsnmp_oid_compare_ll</a>(theprev-&gt;start_a,
00225                                theprev-&gt;start_len,
00226                                ptr-&gt;start_a,
00227                                ptr-&gt;start_len,
00228                                &amp;ptr-&gt;oid_off);
00229 }
00230 
00231 <span class="keywordtype">int</span>
00232 netsnmp_subtree_compare(<span class="keyword">const</span> netsnmp_subtree *ap, <span class=
"keyword">const</span> netsnmp_subtree *bp)
00233 {
00234     <span class="keywordflow">return</span> <a class="code" href=
"group__library.html#ga103">snmp_oid_compare</a>(ap-&gt;name_a, ap-&gt;namelen, bp-&gt;name_a, bp-&gt;namelen);
00235 }
00236 
00237 <span class="keywordtype">void</span>
00238 netsnmp_subtree_join(netsnmp_subtree *root)
00239 {
00240     netsnmp_subtree *s, *tmp, *c, *d;
00241 
00242     <span class="keywordflow">while</span> (root != NULL) {
00243         s = root-&gt;next;
00244         <span class="keywordflow">while</span> (s != NULL &amp;&amp; root-&gt;reginfo == s-&gt;reginfo) {
00245             tmp = s-&gt;next;
00246             DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">"root start "</span>));
00247             DEBUGMSGOID((<span class="stringliteral">"subtree"</span>, root-&gt;start_a, root-&gt;start_len));
00248             DEBUGMSG((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">" (original end "</span>));
00249             DEBUGMSGOID((<span class="stringliteral">"subtree"</span>, root-&gt;end_a, root-&gt;end_len));
00250             DEBUGMSG((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">")\n"</span>));
00251             DEBUGMSGTL((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">"  JOINING to "</span>));
00252             DEBUGMSGOID((<span class="stringliteral">"subtree"</span>, s-&gt;start_a, s-&gt;start_len));
00253 
00254             <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(root-&gt;end_a);
00255             root-&gt;end_a   = s-&gt;end_a;
00256             root-&gt;end_len = s-&gt;end_len;
00257             s-&gt;end_a      = NULL;
00258 
00259             <span class="keywordflow">for</span> (c = root; c != NULL; c = c-&gt;children) {
00260                 netsnmp_subtree_change_next(c, s-&gt;next);
00261             }
00262             <span class="keywordflow">for</span> (c = s; c != NULL; c = c-&gt;children) {
00263                 netsnmp_subtree_change_prev(c, root);
00264             }
00265             DEBUGMSG((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">" so new end "</span>));
00266             DEBUGMSGOID((<span class="stringliteral">"subtree"</span>, root-&gt;end_a, root-&gt;end_len));
00267             DEBUGMSG((<span class="stringliteral">"subtree"</span>, <span class="stringliteral">"\n"</span>));
00268             <span class="comment">/*</span>
00269 <span class="comment">             * Probably need to free children too?  </span>
00270 <span class="comment">             */</span>
00271             <span class="keywordflow">for</span> (c = s-&gt;children; c != NULL; c = d) {
00272                 d = c-&gt;children;
00273                 netsnmp_subtree_free(c);
00274             }
00275             netsnmp_subtree_free(s);
00276             s = tmp;
00277         }
00278         root = root-&gt;next;
00279     }
00280 }
00281 
00282 
00283         <span class="comment">/*</span>
00284 <span class="comment">         *  Split the subtree into two at the specified point,</span>
00285 <span class="comment">         *    returning the new (second) subtree</span>
00286 <span class="comment">         */</span>
00287 netsnmp_subtree *
00288 netsnmp_subtree_split(netsnmp_subtree *current, oid name[], <span class="keywordtype">int</span> name_len)
00289 {
00290     <span class="keyword">struct </span>variable *vp = NULL;
00291     netsnmp_subtree *new_sub, *ptr;
00292     <span class="keywordtype">int</span> i = 0, rc = 0, rc2 = 0;
00293     size_t common_len = 0;
00294     <span class="keywordtype">char</span> *cp;
00295     oid *tmp_a, *tmp_b;
00296 
00297     <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga103">snmp_oid_compare</a>(name, name_len, current-&gt;end_a, current-&gt;end_len)&gt;0) {
00298         <span class="comment">/* Split comes after the end of this subtree */</span>
00299         <span class="keywordflow">return</span> NULL;
00300     }
00301 
00302     new_sub = netsnmp_subtree_deepcopy(current);
00303     <span class="keywordflow">if</span> (new_sub == NULL) {
00304         <span class="keywordflow">return</span> NULL;
00305     }
00306 
00307     <span class="comment">/*  Set up the point of division.  */</span>
00308     tmp_a = snmp_duplicate_objid(name, name_len);
00309     <span class="keywordflow">if</span> (tmp_a == NULL) {
00310         netsnmp_subtree_free(new_sub);
00311         <span class="keywordflow">return</span> NULL;
00312     }
00313     tmp_b = snmp_duplicate_objid(name, name_len);
00314     <span class="keywordflow">if</span> (tmp_b == NULL) {
00315         netsnmp_subtree_free(new_sub);
00316         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(tmp_a);
00317         <span class="keywordflow">return</span> NULL;
00318     }
00319 
00320     <span class="keywordflow">if</span> (current-&gt;end_a != NULL) {
00321         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(current-&gt;end_a);
00322     }
00323     current-&gt;end_a = tmp_a;
00324     current-&gt;end_len = name_len;
00325     <span class="keywordflow">if</span> (new_sub-&gt;start_a != NULL) {
00326         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(new_sub-&gt;start_a);
00327     }
00328     new_sub-&gt;start_a = tmp_b;
00329     new_sub-&gt;start_len = name_len;
00330 
00331     <span class="comment">/*  Split the variables between the two new subtrees.  */</span>
00332     i = current-&gt;variables_len;
00333     current-&gt;variables_len = 0;
00334 
00335     <span class="keywordflow">for</span> (vp = current-&gt;variables; i &gt; 0; i--) {
00336         <span class="comment">/*  Note that the variable "name" field omits the prefix common to the</span>
00337 <span class="comment">            whole registration, hence the strange comparison here.  */</span>
00338 
00339         rc = <a class="code" href="group__library.html#ga103">snmp_oid_compare</a>(vp-&gt;name, vp-&gt;namelen,
00340                               name     + current-&gt;namelen, 
00341                               name_len - current-&gt;namelen);
00342 
00343         <span class="keywordflow">if</span> (name_len - current-&gt;namelen &gt; vp-&gt;namelen) {
00344             common_len = vp-&gt;namelen;
00345         } <span class="keywordflow">else</span> {
00346             common_len = name_len - current-&gt;namelen;
00347         }
00348 
00349         rc2 = <a class="code" href="group__library.html#ga103">snmp_oid_compare</a>(vp-&gt;name, common_len,
00350                                name + current-&gt;namelen, common_len);
00351 
00352         <span class="keywordflow">if</span> (rc &gt;= 0) {
00353             <span class="keywordflow">break</span>;  <span class=
"comment">/* All following variables belong to the second subtree */</span>
00354         }
00355 
00356         current-&gt;variables_len++;
00357         <span class="keywordflow">if</span> (rc2 &lt; 0) {
00358             new_sub-&gt;variables_len--;
00359             cp = (<span class="keywordtype">char</span> *) new_sub-&gt;variables;
00360             new_sub-&gt;variables = (<span class="keyword">struct </span>variable *)(cp + 
00361                                                      new_sub-&gt;variables_width);
00362         }
00363         vp = (<span class="keyword">struct </span>variable *) ((<span class=
"keywordtype">char</span> *) vp + current-&gt;variables_width);
00364     }
00365 
00366     <span class="comment">/* Delegated trees should retain their variables regardless */</span>
00367     <span class="keywordflow">if</span> (current-&gt;variables_len &gt; 0 &amp;&amp;
00368         IS_DELEGATED((u_char) current-&gt;variables[0].type)) {
00369         new_sub-&gt;variables_len = 1;
00370         new_sub-&gt;variables = current-&gt;variables;
00371     }
00372 
00373     <span class="comment">/* Propogate this split down through any children */</span>
00374     <span class="keywordflow">if</span> (current-&gt;children) {
00375         new_sub-&gt;children = netsnmp_subtree_split(current-&gt;children, 
00376                                                   name, name_len);
00377     }
00378 
00379     <span class="comment">/* Retain the correct linking of the list */</span>
00380     <span class="keywordflow">for</span> (ptr = current; ptr != NULL; ptr = ptr-&gt;children) {
00381         netsnmp_subtree_change_next(ptr, new_sub);
00382     }
00383     <span class="keywordflow">for</span> (ptr = new_sub; ptr != NULL; ptr = ptr-&gt;children) {
00384         netsnmp_subtree_change_prev(ptr, current);
00385     }
00386     <span class="keywordflow">for</span> (ptr = new_sub-&gt;next; ptr != NULL; ptr=ptr-&gt;children) {
00387         netsnmp_subtree_change_prev(ptr, new_sub);
00388     }
00389 
00390     <span class="keywordflow">return</span> new_sub;
00391 }
00392 
00393 <span class="keywordtype">int</span>
00394 netsnmp_subtree_load(netsnmp_subtree *new_sub, <span class="keyword">const</span> <span class=
"keywordtype">char</span> *context_name)
00395 {
00396     netsnmp_subtree *tree1, *tree2, *new2;
00397     netsnmp_subtree *prev, *next;
00398     <span class="keywordtype">int</span>             res, rc = 0;
00399 
00400     <span class="keywordflow">if</span> (new_sub == NULL) {
00401         <span class="keywordflow">return</span> MIB_REGISTERED_OK;       <span class="comment">/* Degenerate case */</span>
00402     }
00403 
00404     <span class="keywordflow">if</span> (!netsnmp_subtree_find_first(context_name)) {
00405         <span class="keyword">static</span> <span class="keywordtype">int</span> inloop = 0;
00406         <span class="keywordflow">if</span> (!inloop) {
00407             oid ccitt[1]           = { 0 };
00408             oid iso[1]             = { 1 };
00409             oid joint_ccitt_iso[1] = { 2 };
00410             inloop = 1;
00411             netsnmp_register_null_context(snmp_duplicate_objid(ccitt, 1), 1,
00412                                           context_name);
00413             netsnmp_register_null_context(snmp_duplicate_objid(iso, 1), 1,
00414                                           context_name);
00415             netsnmp_register_null_context(snmp_duplicate_objid(joint_ccitt_iso, 1),
00416                                           1, context_name);
00417             inloop = 0;
00418         }
00419     }
00420 
00421     <span class="comment">/*  Find the subtree that contains the start of the new subtree (if</span>
00422 <span class="comment">        any)...*/</span>
00423 
00424     tree1 = netsnmp_subtree_find(new_sub-&gt;start_a, new_sub-&gt;start_len, 
00425                                  NULL, context_name);
00426 
00427     <span class="comment">/*  ... and the subtree that follows the new one (NULL implies this is the</span>
00428 <span class="comment">        final region covered).  */</span>
00429 
00430     <span class="keywordflow">if</span> (tree1 == NULL) {
00431         tree2 = netsnmp_subtree_find_next(new_sub-&gt;start_a, new_sub-&gt;start_len,
00432                                           NULL, context_name);
00433     } <span class="keywordflow">else</span> {
00434         tree2 = tree1-&gt;next;
00435     }
00436 
00437     <span class="comment">/*  Handle new subtrees that start in virgin territory.  */</span>
00438 
00439     <span class="keywordflow">if</span> (tree1 == NULL) {
00440         new2 = NULL;
00441         <span class="comment">/*  Is there any overlap with later subtrees?  */</span>
00442         <span class="keywordflow">if</span> (tree2 &amp;&amp; <a class="code" href=
"group__library.html#ga103">snmp_oid_compare</a>(new_sub-&gt;end_a, new_sub-&gt;end_len,
00443                                       tree2-&gt;start_a, tree2-&gt;start_len) &gt; 0) {
00444             new2 = netsnmp_subtree_split(new_sub, 
00445                                          tree2-&gt;start_a, tree2-&gt;start_len);
00446         }
00447 
00448         <span class="comment">/*  Link the new subtree (less any overlapping region) with the list of</span>
00449 <span class="comment">            existing registrations.  */</span>
00450 
00451         <span class="keywordflow">if</span> (tree2) {
00452             netsnmp_subtree_change_prev(new_sub, tree2-&gt;prev);
00453             netsnmp_subtree_change_prev(tree2, new_sub);
00454         } <span class="keywordflow">else</span> {
00455             netsnmp_subtree_change_prev(new_sub,
00456                                         netsnmp_subtree_find_prev(new_sub-&gt;start_a,
00457                                                                   new_sub-&gt;start_len, NULL, context_name));
00458 
00459             <span class="keywordflow">if</span> (new_sub-&gt;prev) {
00460                 netsnmp_subtree_change_next(new_sub-&gt;prev, new_sub);
00461             } <span class="keywordflow">else</span> {
00462                 netsnmp_subtree_replace_first(new_sub, context_name);
00463             }
00464 
00465             netsnmp_subtree_change_next(new_sub, tree2);
00466 
00467             <span class="comment">/* If there was any overlap, recurse to merge in the overlapping</span>
00468 <span class="comment">               region (including anything that may follow the overlap).  */</span>
00469             <span class="keywordflow">if</span> (new2) {
00470                 <span class="keywordflow">return</span> netsnmp_subtree_load(new2, context_name);
00471             }
00472         }
00473     } <span class="keywordflow">else</span> {
00474         <span class="comment">/*  If the new subtree starts *within* an existing registration</span>
00475 <span class="comment">            (rather than at the same point as it), then split the existing</span>
00476 <span class="comment">            subtree at this point.  */</span>
00477 
00478         <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(new_sub-&gt;start_a, new_sub-&gt;start_len, 
00479                              tree1-&gt;start_a,   tree1-&gt;start_len) != 0) {
00480             tree1 = netsnmp_subtree_split(tree1, new_sub-&gt;start_a, 
00481                                           new_sub-&gt;start_len);
00482         }
00483 
00484         <span class="keywordflow">if</span> (tree1 == NULL) {
00485             <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00486         }
00487 
00488         <span class="comment">/*  Now consider the end of this existing subtree:</span>
00489 <span class="comment">            </span>
00490 <span class="comment">            If it matches the new subtree precisely,</span>
00491 <span class="comment">                    simply merge the new one into the list of children</span>
00492 
00493 <span class="comment">            If it includes the whole of the new subtree,</span>
00494 <span class="comment">                    split it at the appropriate point, and merge again</span>
00495 <span class="comment">     </span>
00496 <span class="comment">            If the new subtree extends beyond this existing region,</span>
00497 <span class="comment">                    split it, and recurse to merge the two parts.  */</span>
00498 
00499         rc = <a class="code" href="group__library.html#ga103">snmp_oid_compare</a>(new_sub-&gt;end_a, new_sub-&gt;end_len, 
00500                               tree1-&gt;end_a, tree1-&gt;end_len);
00501 
00502         <span class="keywordflow">switch</span> (rc) {
00503 
00504         <span class="keywordflow">case</span> -1:
00505             <span class="comment">/*  Existing subtree contains new one.  */</span>
00506             netsnmp_subtree_split(tree1, new_sub-&gt;end_a, new_sub-&gt;end_len);
00507             <span class="comment">/* Fall Through */</span>
00508 
00509         <span class="keywordflow">case</span>  0:
00510             <span class="comment">/*  The two trees match precisely.  */</span>
00511 
00512             <span class="comment">/*  Note: This is the only point where the original registration</span>
00513 <span class="comment">                OID ("name") is used.  */</span>
00514 
00515             prev = NULL;
00516             next = tree1;
00517         
00518             <span class="keywordflow">while</span> (next &amp;&amp; next-&gt;namelen &gt; new_sub-&gt;namelen) {
00519                 prev = next;
00520                 next = next-&gt;children;
00521             }
00522 
00523             <span class="keywordflow">while</span> (next &amp;&amp; next-&gt;namelen == new_sub-&gt;namelen &amp;&amp;
00524                    next-&gt;priority &lt; new_sub-&gt;priority ) {
00525                 prev = next;
00526                 next = next-&gt;children;
00527             }
00528         
00529             <span class="keywordflow">if</span> (next &amp;&amp; (next-&gt;namelen  == new_sub-&gt;namelen) &amp;&amp;
00530                 (next-&gt;priority == new_sub-&gt;priority)) {
00531                 netsnmp_assert(<span class="stringliteral">"registration"</span> != <span class=
"stringliteral">"duplicate"</span>);
00532                 <span class="keywordflow">return</span> MIB_DUPLICATE_REGISTRATION;
00533             }
00534 
00535             <span class="keywordflow">if</span> (prev) {
00536                 prev-&gt;children    = new_sub;
00537                 new_sub-&gt;children = next;
00538                 netsnmp_subtree_change_prev(new_sub, prev-&gt;prev);
00539                 netsnmp_subtree_change_next(new_sub, prev-&gt;next);
00540             } <span class="keywordflow">else</span> {
00541                 new_sub-&gt;children = next;
00542                 netsnmp_subtree_change_prev(new_sub, next-&gt;prev);
00543                 netsnmp_subtree_change_next(new_sub, next-&gt;next);
00544         
00545                 <span class="keywordflow">for</span> (next = new_sub-&gt;next; next != NULL;next = next-&gt;children){
00546                     netsnmp_subtree_change_prev(next, new_sub);
00547                 }
00548 
00549                 <span class="keywordflow">for</span> (prev = new_sub-&gt;prev; prev != NULL;prev = prev-&gt;children){
00550                     netsnmp_subtree_change_next(prev, new_sub);
00551                 }
00552             }
00553             <span class="keywordflow">break</span>;
00554 
00555         <span class="keywordflow">case</span>  1:
00556             <span class="comment">/*  New subtree contains the existing one.  */</span>
00557             new2 = netsnmp_subtree_split(new_sub, tree1-&gt;end_a,tree1-&gt;end_len);
00558             res = netsnmp_subtree_load(new_sub, context_name);
00559             <span class="keywordflow">if</span> (res != MIB_REGISTERED_OK) {
00560                 netsnmp_subtree_free(new2);
00561                 <span class="keywordflow">return</span> res;
00562             }
00563             <span class="keywordflow">return</span> netsnmp_subtree_load(new2, context_name);
00564         }
00565     }
00566     <span class="keywordflow">return</span> 0;
00567 }
00568 
00569 <span class="comment">/*</span>
00570 <span class="comment"> * Note: reginfo will be freed on failures</span>
00571 <span class="comment"> */</span>
00572 <span class="keywordtype">int</span>
00573 netsnmp_register_mib(<span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName,
00574                      <span class="keyword">struct</span> variable *var,
00575                      size_t varsize,
00576                      size_t numvars,
00577                      oid * mibloc,
00578                      size_t mibloclen,
00579                      <span class="keywordtype">int</span> priority,
00580                      <span class="keywordtype">int</span> range_subid,
00581                      oid range_ubound,
00582                      <a class="code" href="structsnmp__session.html">netsnmp_session</a> * ss,
00583                      <span class="keyword">const</span> <span class="keywordtype">char</span> *context,
00584                      <span class="keywordtype">int</span> timeout,
00585                      <span class="keywordtype">int</span> flags,
00586                      <a class="code" href=
"structnetsnmp__handler__registration__s.html">netsnmp_handler_registration</a> *reginfo,
00587                      <span class="keywordtype">int</span> perform_callback)
00588 {
00589     netsnmp_subtree *subtree, *sub2;
00590     <span class="keywordtype">int</span>             res, i;
00591     <span class="keyword">struct </span>register_parameters reg_parms;
00592     <span class="keywordtype">int</span> old_lookup_cache_val = <a class="code" href=
"group__agent__registry.html#ga10">netsnmp_get_lookup_cache_size</a>();
00593 
00594     <span class="keywordflow">if</span> (moduleName == NULL ||
00595         mibloc     == NULL) {
00596         <span class="comment">/* Shouldn't happen ??? */</span>
00597         <a class="code" href="group__handler.html#ga21">netsnmp_handler_registration_free</a>(reginfo);
00598         <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00599     }
00600     subtree = (netsnmp_subtree *)calloc(1, <span class="keyword">sizeof</span>(netsnmp_subtree));
00601     <span class="keywordflow">if</span> (subtree == NULL) {
00602         <a class="code" href="group__handler.html#ga21">netsnmp_handler_registration_free</a>(reginfo);
00603         <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00604     }
00605 
00606     DEBUGMSGTL((<span class="stringliteral">"register_mib"</span>, <span class=
"stringliteral">"registering \"%s\" at "</span>, moduleName));
00607     DEBUGMSGOIDRANGE((<span class="stringliteral">"register_mib"</span>, mibloc, mibloclen, range_subid,
00608                       range_ubound));
00609     DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class=
"stringliteral">" with context \"%s\"\n"</span>, context));
00610 
00611     <span class="comment">/*</span>
00612 <span class="comment">     * verify that the passed context is equal to the context</span>
00613 <span class="comment">     * in the reginfo.</span>
00614 <span class="comment">     * (which begs the question, why do we have both? It appears that the</span>
00615 <span class="comment">     *  reginfo item didn't appear til 5.2)</span>
00616 <span class="comment">     */</span>
00617     <span class="keywordflow">if</span>( ((NULL == context) &amp;&amp; (NULL != reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>)) ||
00618         ((NULL != context) &amp;&amp; (NULL == reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>)) ||
00619         ( ((NULL != context) &amp;&amp; (NULL != reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>)) &amp;&amp;
00620           (0 != strcmp(context, reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>))) ) {
00621         <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_WARNING,<span class=
"stringliteral">"context passed during registration does not "</span>
00622                  <span class="stringliteral">"equal the reginfo contextName! ('%s' != '%s')\n"</span>,
00623                  context, reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>);
00624         netsnmp_assert(<span class="stringliteral">"register context"</span> == <span class=
"stringliteral">"reginfo-&gt;contextName"</span>);
00625     }
00626 
00627     <span class="comment">/*  Create the new subtree node being registered.  */</span>
00628 
00629     subtree-&gt;reginfo = reginfo;
00630     subtree-&gt;name_a  = snmp_duplicate_objid(mibloc, mibloclen);
00631     subtree-&gt;start_a = snmp_duplicate_objid(mibloc, mibloclen);
00632     subtree-&gt;end_a   = snmp_duplicate_objid(mibloc, mibloclen);
00633     subtree-&gt;label_a = strdup(moduleName);
00634     <span class="keywordflow">if</span> (subtree-&gt;name_a == NULL || subtree-&gt;start_a == NULL || 
00635         subtree-&gt;end_a  == NULL || subtree-&gt;label_a == NULL) {
00636         netsnmp_subtree_free(subtree); <span class="comment">/* also frees reginfo */</span>
00637         <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00638     }
00639     subtree-&gt;namelen   = (u_char)mibloclen;
00640     subtree-&gt;start_len = (u_char)mibloclen;
00641     subtree-&gt;end_len   = (u_char)mibloclen;
00642     subtree-&gt;end_a[mibloclen - 1]++;
00643 
00644     <span class="keywordflow">if</span> (var != NULL) {
00645         subtree-&gt;variables = (<span class="keyword">struct </span>variable *)malloc(varsize*numvars);
00646         <span class="keywordflow">if</span> (subtree-&gt;variables == NULL) {
00647             netsnmp_subtree_free(subtree); <span class="comment">/* also frees reginfo */</span>
00648             <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00649         }
00650         memcpy(subtree-&gt;variables, var, numvars*varsize);
00651         subtree-&gt;variables_len = numvars;
00652         subtree-&gt;variables_width = varsize;
00653     }
00654     subtree-&gt;<a class="code" href="structnetsnmp__handler__registration__s.html#o6">priority</a> = priority;
00655     subtree-&gt;<a class="code" href="structnetsnmp__handler__registration__s.html#o9">timeout</a> = timeout;
00656     subtree-&gt;<a class="code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a> = range_subid;
00657     subtree-&gt;<a class="code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = range_ubound;
00658     subtree-&gt;session = ss;
00659     subtree-&gt;<a class="code" href="structsnmp__session.html#o3">flags</a> = (u_char)flags;    <span class=
"comment">/*  used to identify instance oids  */</span>
00660     subtree-&gt;<a class="code" href="structsnmp__session.html#o3">flags</a> |= SUBTREE_ATTACHED;
00661     subtree-&gt;global_cacheid = reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o10">global_cacheid</a>;
00662 
00663     <a class="code" href="group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(0);
00664     res = netsnmp_subtree_load(subtree, context);
00665 
00666     <span class="comment">/*  If registering a range, use the first subtree as a template for the</span>
00667 <span class="comment">        rest of the range.  */</span>
00668 
00669     <span class="keywordflow">if</span> (res == MIB_REGISTERED_OK &amp;&amp; range_subid != 0) {
00670         <span class="keywordflow">for</span> (i = mibloc[range_subid - 1] + 1; i &lt;= (int)range_ubound; i++) {
00671             sub2 = netsnmp_subtree_deepcopy(subtree);
00672 
00673             <span class="keywordflow">if</span> (sub2 == NULL) {
00674                 <a class="code" href=
"group__agent__registry.html#ga32">unregister_mib_context</a>(mibloc, mibloclen, priority,
00675                                        range_subid, range_ubound, context);
00676                 <a class="code" href=
"group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(old_lookup_cache_val);
00677                 invalidate_lookup_cache(context);
00678                 <span class="keywordflow">return</span> MIB_REGISTRATION_FAILED;
00679             }
00680 
00681             sub2-&gt;name_a[range_subid - 1]  = i;
00682             sub2-&gt;start_a[range_subid - 1] = i;
00683             sub2-&gt;end_a[range_subid - 1]   = i;     <span class="comment">/* XXX - ???? */</span>
00684             <span class="keywordflow">if</span> (range_subid == (int)mibloclen)
00685                 ++sub2-&gt;end_a[range_subid - 1];
00686             res = netsnmp_subtree_load(sub2, context);
00687             sub2-&gt;flags |= SUBTREE_ATTACHED;
00688             <span class="keywordflow">if</span> (res != MIB_REGISTERED_OK) {
00689                 <a class="code" href=
"group__agent__registry.html#ga32">unregister_mib_context</a>(mibloc, mibloclen, priority,
00690                                        range_subid, range_ubound, context);
00691                 netsnmp_subtree_free(sub2);
00692                 <a class="code" href=
"group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(old_lookup_cache_val);
00693                 invalidate_lookup_cache(context);
00694                 <span class="keywordflow">return</span> res;
00695             }
00696         }
00697     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (res == MIB_DUPLICATE_REGISTRATION ||
00698                res == MIB_REGISTRATION_FAILED) {
00699         <a class="code" href="group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(old_lookup_cache_val);
00700         invalidate_lookup_cache(context);
00701         netsnmp_subtree_free(subtree);
00702         <span class="keywordflow">return</span> res;
00703     }
00704 
00705     <span class="comment">/*</span>
00706 <span class="comment">     * mark the MIB as detached, if there's no master agent present as of now </span>
00707 <span class="comment">     */</span>
00708     <span class="keywordflow">if</span> (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00709                                NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT) {
00710         <span class="keyword">extern</span> <span class="keyword">struct </span><a class="code" href=
"structsnmp__session.html">snmp_session</a> *main_session;
00711         <span class="keywordflow">if</span> (main_session == NULL) {
00712             register_mib_detach_node(subtree);
00713         }
00714     }
00715 
00716     <span class="keywordflow">if</span> (res == MIB_REGISTERED_OK &amp;&amp; perform_callback) {
00717         memset(&amp;reg_parms, 0x0, <span class="keyword">sizeof</span>(reg_parms));
00718         reg_parms.name = mibloc;
00719         reg_parms.namelen = mibloclen;
00720         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o6">priority</a> = priority;
00721         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a> = range_subid;
00722         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = range_ubound;
00723         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o9">timeout</a> = timeout;
00724         reg_parms.flags = (u_char) flags;
00725         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o1">contextName</a> = context;
00726         <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
00727                             SNMPD_CALLBACK_REGISTER_OID, &amp;reg_parms);
00728     }
00729 
00730     <a class="code" href="group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(old_lookup_cache_val);
00731     invalidate_lookup_cache(context);
00732     <span class="keywordflow">return</span> res;
00733 }
00734 
00735 <span class="comment">/*</span>
00736 <span class="comment"> * Reattach a particular node.  </span>
00737 <span class="comment"> */</span>
00738 
00739 <span class="keyword">static</span> <span class="keywordtype">void</span>
00740 register_mib_reattach_node(netsnmp_subtree *s)
00741 {
00742     <span class=
"keywordflow">if</span> ((s != NULL) &amp;&amp; (s-&gt;namelen &gt; 1) &amp;&amp; !(s-&gt;flags &amp; SUBTREE_ATTACHED)) {
00743         <span class="keyword">struct </span>register_parameters reg_parms;
00744         <span class="comment">/*</span>
00745 <span class="comment">         * only do registrations that are not the top level nodes </span>
00746 <span class="comment">         */</span>
00747         memset(&amp;reg_parms, 0x0, <span class="keyword">sizeof</span>(reg_parms));
00748 
00749         <span class="comment">/*</span>
00750 <span class="comment">         * XXX: do this better </span>
00751 <span class="comment">         */</span>
00752         reg_parms.name = s-&gt;name_a;
00753         reg_parms.namelen = s-&gt;namelen;
00754         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o6">priority</a> = s-&gt;<a class=
"code" href="structnetsnmp__handler__registration__s.html#o6">priority</a>;
00755         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a> = s-&gt;<a class=
"code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a>;
00756         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = s-&gt;<a class=
"code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a>;
00757         reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o9">timeout</a> = s-&gt;<a class=
"code" href="structnetsnmp__handler__registration__s.html#o9">timeout</a>;
00758         reg_parms.flags = s-&gt;flags;
00759         <span class="keywordflow">if</span> ((NULL != s-&gt;reginfo) &amp;&amp; (NULL != s-&gt;reginfo-&gt;contextName))
00760             reg_parms.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a> = s-&gt;reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>;
00761         <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
00762                             SNMPD_CALLBACK_REGISTER_OID, &amp;reg_parms);
00763         s-&gt;flags |= SUBTREE_ATTACHED;
00764     }
00765 }
00766 
00767 <span class="comment">/*</span>
00768 <span class="comment"> * Call callbacks to reattach all our nodes.  </span>
00769 <span class="comment"> */</span>
00770 
00771 <span class="keywordtype">void</span>
00772 register_mib_reattach(<span class="keywordtype">void</span>)
00773 {
00774     netsnmp_subtree *s, *t;
00775     subtree_context_cache *ptr;
00776 
00777     <span class="keywordflow">for</span> (ptr = context_subtrees; ptr; ptr = ptr-&gt;next) {
00778         <span class="keywordflow">for</span> (s = ptr-&gt;first_subtree; s != NULL; s = s-&gt;next) {
00779             register_mib_reattach_node(s);
00780             <span class="keywordflow">for</span> (t = s-&gt;children; t != NULL; t = t-&gt;children) {
00781                 register_mib_reattach_node(t);
00782             }
00783         }
00784     }
00785 }
00786 
00787 <span class="comment">/*</span>
00788 <span class="comment"> * Mark a node as detached.  </span>
00789 <span class="comment"> */</span>
00790 
00791 <span class="keyword">static</span> <span class="keywordtype">void</span>
00792 register_mib_detach_node(netsnmp_subtree *s)
00793 {
00794     <span class="keywordflow">if</span> (s != NULL) {
00795         s-&gt;flags = s-&gt;flags &amp; ~SUBTREE_ATTACHED;
00796     }
00797 }
00798 
00799 <span class="comment">/*</span>
00800 <span class="comment"> * Mark all our registered OIDs as detached.  This is only really</span>
00801 <span class="comment"> * useful for subagent protocols, when a connection is lost or</span>
00802 <span class="comment"> * something.  </span>
00803 <span class="comment"> */</span>
00804 
00805 <span class="keywordtype">void</span>
00806 register_mib_detach(<span class="keywordtype">void</span>)
00807 {
00808     netsnmp_subtree *s, *t;
00809     subtree_context_cache *ptr;
00810     <span class="keywordflow">for</span> (ptr = context_subtrees; ptr; ptr = ptr-&gt;next) {
00811         <span class="keywordflow">for</span> (s = ptr-&gt;first_subtree; s != NULL; s = s-&gt;next) {
00812             register_mib_detach_node(s);
00813             <span class="keywordflow">for</span> (t = s-&gt;children; t != NULL; t = t-&gt;children) {
00814                 register_mib_detach_node(t);
00815             }
00816         }
00817     }
00818 }
00819 
00820 <span class="keywordtype">int</span>
00821 register_mib_context(<span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName,
00822                      <span class="keyword">struct</span> variable *var,
00823                      size_t varsize,
00824                      size_t numvars,
00825                      oid * mibloc,
00826                      size_t mibloclen,
00827                      <span class="keywordtype">int</span> priority,
00828                      <span class="keywordtype">int</span> range_subid,
00829                      oid range_ubound,
00830                      <a class="code" href="structsnmp__session.html">netsnmp_session</a> * ss,
00831                      <span class="keyword">const</span> <span class="keywordtype">char</span> *context, <span class=
"keywordtype">int</span> timeout, <span class="keywordtype">int</span> flags)
00832 {
00833     <span class="keywordflow">return</span> <a class="code" href=
"group__old__api.html#ga1">netsnmp_register_old_api</a>(moduleName, var, varsize, numvars,
00834                                     mibloc, mibloclen, priority,
00835                                     range_subid, range_ubound, ss, context,
00836                                     timeout, flags);
00837 }
00838 
00839 <span class="keywordtype">int</span>
00840 register_mib_range(<span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName,
00841                    <span class="keyword">struct</span> variable *var,
00842                    size_t varsize,
00843                    size_t numvars,
00844                    oid * mibloc,
00845                    size_t mibloclen,
00846                    <span class="keywordtype">int</span> priority,
00847                    <span class="keywordtype">int</span> range_subid, oid range_ubound, <a class="code" href=
"structsnmp__session.html">netsnmp_session</a> * ss)
00848 {
00849     <span class="keywordflow">return</span> register_mib_context(moduleName, var, varsize, numvars,
00850                                 mibloc, mibloclen, priority,
00851                                 range_subid, range_ubound, ss, <span class="stringliteral">""</span>, -1, 0);
00852 }
00853 
00854 <span class="keywordtype">int</span>
00855 register_mib_priority(<span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName,
00856                       <span class="keyword">struct</span> variable *var,
00857                       size_t varsize,
00858                       size_t numvars,
00859                       oid * mibloc, size_t mibloclen, <span class="keywordtype">int</span> priority)
00860 {
00861     <span class="keywordflow">return</span> register_mib_range(moduleName, var, varsize, numvars,
00862                               mibloc, mibloclen, priority, 0, 0, NULL);
00863 }
00864 
00865 <span class="keywordtype">int</span>
00866 register_mib(<span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName,
00867              <span class="keyword">struct</span> variable *var,
00868              size_t varsize,
00869              size_t numvars, oid * mibloc, size_t mibloclen)
00870 {
00871     <span class="keywordflow">return</span> register_mib_priority(moduleName, var, varsize, numvars,
00872                                  mibloc, mibloclen, DEFAULT_MIB_PRIORITY);
00873 }
00874 
00875 <span class="keywordtype">void</span>
00876 netsnmp_subtree_unload(netsnmp_subtree *sub, netsnmp_subtree *prev, <span class="keyword">const</span> <span class=
"keywordtype">char</span> *context)
00877 {
00878     netsnmp_subtree *ptr;
00879 
00880     DEBUGMSGTL((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"unload("</span>));
00881     <span class="keywordflow">if</span> (sub != NULL) {
00882         DEBUGMSGOID((<span class="stringliteral">"register_mib"</span>, sub-&gt;start_a, sub-&gt;start_len));
00883     } <span class="keywordflow">else</span> {
00884         DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"[NIL]"</span>));
00885     }
00886     DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">", "</span>));
00887     <span class="keywordflow">if</span> (prev != NULL) {
00888         DEBUGMSGOID((<span class="stringliteral">"register_mib"</span>, prev-&gt;start_a, prev-&gt;start_len));
00889     } <span class="keywordflow">else</span> {
00890         DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"[NIL]"</span>));
00891     }
00892     DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">")\n"</span>));
00893 
00894     <span class="keywordflow">if</span> (prev != NULL) {         <span class=
"comment">/* non-leading entries are easy */</span>
00895         prev-&gt;children = sub-&gt;children;
00896         invalidate_lookup_cache(context);
00897         <span class="keywordflow">return</span>;
00898     }
00899     <span class="comment">/*</span>
00900 <span class="comment">     * otherwise, we need to amend our neighbours as well </span>
00901 <span class="comment">     */</span>
00902 
00903     <span class="keywordflow">if</span> (sub-&gt;children == NULL) {        <span class=
"comment">/* just remove this node completely */</span>
00904         <span class="keywordflow">for</span> (ptr = sub-&gt;prev; ptr; ptr = ptr-&gt;children) {
00905             netsnmp_subtree_change_next(ptr, sub-&gt;next);
00906         }
00907         <span class="keywordflow">for</span> (ptr = sub-&gt;next; ptr; ptr = ptr-&gt;children) {
00908             netsnmp_subtree_change_prev(ptr, sub-&gt;prev);
00909         }
00910 
00911         <span class="keywordflow">if</span> (sub-&gt;prev == NULL) {
00912             netsnmp_subtree_replace_first(sub-&gt;next, context);
00913         }
00914 
00915     } <span class="keywordflow">else</span> {
00916         <span class="keywordflow">for</span> (ptr = sub-&gt;prev; ptr; ptr = ptr-&gt;children)
00917             netsnmp_subtree_change_next(ptr, sub-&gt;children);
00918         <span class="keywordflow">for</span> (ptr = sub-&gt;next; ptr; ptr = ptr-&gt;children)
00919             netsnmp_subtree_change_prev(ptr, sub-&gt;children);
00920 
00921         <span class="keywordflow">if</span> (sub-&gt;prev == NULL) {
00922             netsnmp_subtree_replace_first(sub-&gt;children, context);
00923         }
00924     }
00925     invalidate_lookup_cache(context);
00926 }
00927 
00957 <span class="keywordtype">int</span>
<a name="l00958" id="l00958"></a><a class="code" href="group__agent__registry.html#ga32">00958</a> <a class="code" href=
"group__agent__registry.html#ga32">unregister_mib_context</a>(oid * name, size_t len, <span class=
"keywordtype">int</span> priority,
00959                        <span class="keywordtype">int</span> range_subid, oid range_ubound,
00960                        <span class="keyword">const</span> <span class="keywordtype">char</span> *context)
00961 {
00962     netsnmp_subtree *list, *myptr;
00963     netsnmp_subtree *prev, *child, *next; <span class="comment">/* loop through children */</span>
00964     <span class="keyword">struct </span>register_parameters reg_parms;
00965     <span class="keywordtype">int</span> old_lookup_cache_val = <a class="code" href=
"group__agent__registry.html#ga10">netsnmp_get_lookup_cache_size</a>();
00966     <a class="code" href="group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(0);
00967 
00968     DEBUGMSGTL((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"unregistering "</span>));
00969     DEBUGMSGOIDRANGE((<span class="stringliteral">"register_mib"</span>, name, len, range_subid, range_ubound));
00970     DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"\n"</span>));
00971 
00972     list = netsnmp_subtree_find(name, len, netsnmp_subtree_find_first(context),
00973                                 context);
00974     <span class="keywordflow">if</span> (list == NULL) {
00975         <span class="keywordflow">return</span> MIB_NO_SUCH_REGISTRATION;
00976     }
00977 
00978     <span class="keywordflow">for</span> (child = list, prev = NULL; child != NULL;
00979          prev = child, child = child-&gt;children) {
00980         <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(child-&gt;name_a, child-&gt;namelen, name, len) == 0 &amp;&amp;
00981             child-&gt;priority == priority) {
00982             <span class="keywordflow">break</span>;              <span class="comment">/* found it */</span>
00983         }
00984     }
00985 
00986     <span class="keywordflow">if</span> (child == NULL) {
00987         <span class="keywordflow">return</span> MIB_NO_SUCH_REGISTRATION;
00988     }
00989 
00990     netsnmp_subtree_unload(child, prev, context);
00991     myptr = child;              <span class="comment">/* remember this for later */</span>
00992 
00993     <span class="comment">/*</span>
00994 <span class="comment">     *  Now handle any occurances in the following subtrees,</span>
00995 <span class="comment">     *      as a result of splitting this range.  Due to the</span>
00996 <span class="comment">     *      nature of the way such splits work, the first</span>
00997 <span class="comment">     *      subtree 'slice' that doesn't refer to the given</span>
00998 <span class="comment">     *      name marks the end of the original region.</span>
00999 <span class="comment">     *</span>
01000 <span class="comment">     *  This should also serve to register ranges.</span>
01001 <span class="comment">     */</span>
01002 
01003     <span class="keywordflow">for</span> (list = myptr-&gt;next; list != NULL; list = next) {
01004         next = list-&gt;next; <span class="comment">/* list gets freed sometimes; cache next */</span>
01005         <span class="keywordflow">for</span> (child = list, prev = NULL; child != NULL;
01006              prev = child, child = child-&gt;children) {
01007             <span class="keywordflow">if</span> ((<a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(child-&gt;name_a, child-&gt;namelen,
01008                                   name, len) == 0) &amp;&amp;
01009                 (child-&gt;priority == priority)) {
01010                 netsnmp_subtree_unload(child, prev, context);
01011                 netsnmp_subtree_free(child);
01012                 <span class="keywordflow">break</span>;
01013             }
01014         }
01015         <span class="keywordflow">if</span> (child == NULL)      <span class=
"comment">/* Didn't find the given name */</span>
01016             <span class="keywordflow">break</span>;
01017     }
01018     netsnmp_subtree_free(myptr);
01019 
01020     memset(&amp;reg_parms, 0x0, <span class="keyword">sizeof</span>(reg_parms));
01021     reg_parms.name = name;
01022     reg_parms.namelen = len;
01023     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o6">priority</a> = priority;
01024     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a> = range_subid;
01025     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = range_ubound;
01026     reg_parms.flags = 0x00;     <span class="comment">/*  this is okay I think  */</span>
01027     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o1">contextName</a> = context;
01028     <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01029                         SNMPD_CALLBACK_UNREGISTER_OID, &amp;reg_parms);
01030 
01031     <a class="code" href="group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(old_lookup_cache_val);
01032     invalidate_lookup_cache(context);
01033     <span class="keywordflow">return</span> MIB_UNREGISTERED_OK;
01034 }
01035 
01036 <span class="keywordtype">int</span>
01037 netsnmp_unregister_mib_table_row(oid * name, size_t len, <span class="keywordtype">int</span> priority,
01038                                  <span class="keywordtype">int</span> var_subid, oid range_ubound,
01039                                  <span class="keyword">const</span> <span class="keywordtype">char</span> *context)
01040 {
01041     netsnmp_subtree *list, *myptr;
01042     netsnmp_subtree *prev, *child;       <span class="comment">/* loop through children */</span>
01043     <span class="keyword">struct </span>register_parameters reg_parms;
01044     oid             range_lbound = name[var_subid - 1];
01045 
01046     DEBUGMSGTL((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"unregistering "</span>));
01047     DEBUGMSGOIDRANGE((<span class="stringliteral">"register_mib"</span>, name, len, var_subid, range_ubound));
01048     DEBUGMSG((<span class="stringliteral">"register_mib"</span>, <span class="stringliteral">"\n"</span>));
01049 
01050     <span class="keywordflow">for</span> (; name[var_subid - 1] &lt;= range_ubound; name[var_subid - 1]++) {
01051         list = netsnmp_subtree_find(name, len, 
01052                                 netsnmp_subtree_find_first(context), context);
01053 
01054         <span class="keywordflow">if</span> (list == NULL) {
01055             <span class="keywordflow">continue</span>;
01056         }
01057 
01058         <span class="keywordflow">for</span> (child = list, prev = NULL; child != NULL;
01059              prev = child, child = child-&gt;children) {
01060 
01061             <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(child-&gt;name_a, child-&gt;namelen, 
01062                                  name, len) == 0 &amp;&amp; 
01063                 (child-&gt;priority == priority)) {
01064                 <span class="keywordflow">break</span>;          <span class="comment">/* found it */</span>
01065             }
01066         }
01067 
01068         <span class="keywordflow">if</span> (child == NULL) {
01069             <span class="keywordflow">continue</span>;
01070         }
01071 
01072         netsnmp_subtree_unload(child, prev, context);
01073         myptr = child;          <span class="comment">/* remember this for later */</span>
01074 
01075         <span class="keywordflow">for</span> (list = myptr-&gt;next; list != NULL; list = list-&gt;next) {
01076             <span class="keywordflow">for</span> (child = list, prev = NULL; child != NULL;
01077                  prev = child, child = child-&gt;children) {
01078 
01079                 <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(child-&gt;name_a, child-&gt;namelen, 
01080                                       name, len) == 0 &amp;&amp;
01081                     (child-&gt;priority == priority)) {
01082                     netsnmp_subtree_unload(child, prev, context);
01083                     netsnmp_subtree_free(child);
01084                     <span class="keywordflow">break</span>;
01085                 }
01086             }
01087             <span class="keywordflow">if</span> (child == NULL) {        <span class=
"comment">/* Didn't find the given name */</span>
01088                 <span class="keywordflow">break</span>;
01089             }
01090         }
01091         netsnmp_subtree_free(myptr);
01092     }
01093 
01094     name[var_subid - 1] = range_lbound;
01095     memset(&amp;reg_parms, 0x0, <span class="keyword">sizeof</span>(reg_parms));
01096     reg_parms.name = name;
01097     reg_parms.namelen = len;
01098     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o6">priority</a> = priority;
01099     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o7">range_subid</a> = var_subid;
01100     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = range_ubound;
01101     reg_parms.flags = 0x00;     <span class="comment">/*  this is okay I think  */</span>
01102     reg_parms.<a class="code" href="structnetsnmp__handler__registration__s.html#o1">contextName</a> = context;
01103     <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01104                         SNMPD_CALLBACK_UNREGISTER_OID, &amp;reg_parms);
01105 
01106     <span class="keywordflow">return</span> 0;
01107 }
01108 
01109 <span class="keywordtype">int</span>
01110 unregister_mib_range(oid * name, size_t len, <span class="keywordtype">int</span> priority,
01111                      <span class="keywordtype">int</span> range_subid, oid range_ubound)
01112 {
01113     <span class="keywordflow">return</span> <a class="code" href=
"group__agent__registry.html#ga32">unregister_mib_context</a>(name, len, priority, range_subid,
01114                                   range_ubound, <span class="stringliteral">""</span>);
01115 }
01116 
01117 <span class="keywordtype">int</span>
01118 unregister_mib_priority(oid * name, size_t len, <span class="keywordtype">int</span> priority)
01119 {
01120     <span class="keywordflow">return</span> unregister_mib_range(name, len, priority, 0, 0);
01121 }
01122 
01123 <span class="keywordtype">int</span>
01124 unregister_mib(oid * name, size_t len)
01125 {
01126     <span class="keywordflow">return</span> unregister_mib_priority(name, len, DEFAULT_MIB_PRIORITY);
01127 }
01128 
01129 <span class="keywordtype">void</span>
01130 unregister_mibs_by_session(<a class="code" href="structsnmp__session.html">netsnmp_session</a> * ss)
01131 {
01132     netsnmp_subtree *list, *list2;
01133     netsnmp_subtree *child, *prev, *next_child;
01134     <span class="keyword">struct </span>register_parameters rp;
01135     subtree_context_cache *contextptr;
01136 
01137     DEBUGMSGTL((<span class="stringliteral">"register_mib"</span>, <span class=
"stringliteral">"unregister_mibs_by_session(%p) ctxt \"%s\"\n"</span>,
01138                 ss, (ss &amp;&amp; ss-&gt;<a class="code" href=
"structsnmp__session.html#o25">contextName</a>) ? ss-&gt;<a class="code" href=
"structsnmp__session.html#o25">contextName</a> : <span class="stringliteral">"[NIL]"</span>));
01139 
01140     <span class="keywordflow">for</span> (contextptr = get_top_context_cache(); contextptr != NULL;
01141          contextptr = contextptr-&gt;next) {
01142         <span class="keywordflow">for</span> (list = contextptr-&gt;first_subtree; list != NULL; list = list2) {
01143             list2 = list-&gt;next;
01144 
01145             <span class="keywordflow">for</span> (child = list, prev = NULL; child != NULL; child = next_child){
01146                 next_child = child-&gt;children;
01147 
01148                 <span class="keywordflow">if</span> (((!ss || ss-&gt;<a class="code" href=
"structsnmp__session.html#o3">flags</a> &amp; SNMP_FLAGS_SUBSESSION) &amp;&amp;
01149                      child-&gt;session == ss) ||
01150                     (!(!ss || ss-&gt;<a class="code" href=
"structsnmp__session.html#o3">flags</a> &amp; SNMP_FLAGS_SUBSESSION) &amp;&amp; child-&gt;session &amp;&amp;
01151                      child-&gt;session-&gt;subsession == ss)) {
01152 
01153                     memset(&amp;rp,0x0,<span class="keyword">sizeof</span>(rp));
01154                     rp.name = child-&gt;name_a;
01155                     child-&gt;name_a = NULL;
01156                     rp.namelen = child-&gt;namelen;
01157                     rp.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o6">priority</a> = child-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o6">priority</a>;
01158                     rp.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o7">range_subid</a> = child-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o7">range_subid</a>;
01159                     rp.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o8">range_ubound</a> = child-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o8">range_ubound</a>;
01160                     rp.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o9">timeout</a> = child-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o9">timeout</a>;
01161                     rp.flags = child-&gt;flags;
01162                     <span class="keywordflow">if</span> ((NULL != child-&gt;reginfo) &amp;&amp;
01163                         (NULL != child-&gt;reginfo-&gt;contextName))
01164                         rp.<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a> = child-&gt;reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o1">contextName</a>;
01165 
01166                     <span class="keywordflow">if</span> (child-&gt;reginfo != NULL) {
01167                         <span class="comment">/*</span>
01168 <span class="comment">                         * Don't let's free the session pointer just yet!  </span>
01169 <span class="comment">                         */</span>
01170                         child-&gt;reginfo-&gt;<a class="code" href=
"structnetsnmp__handler__registration__s.html#o4">handler</a>-&gt;<a class="code" href=
"structnetsnmp__mib__handler__s.html#o1">myvoid</a> = NULL;
01171                         <a class="code" href=
"group__handler.html#ga21">netsnmp_handler_registration_free</a>(child-&gt;reginfo);
01172                         child-&gt;reginfo = NULL;
01173                     }
01174 
01175                     netsnmp_subtree_unload(child, prev, contextptr-&gt;context_name);
01176                     netsnmp_subtree_free(child);
01177 
01178                     <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01179                                         SNMPD_CALLBACK_UNREGISTER_OID, &amp;rp);
01180                     <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(rp.name);
01181                 } <span class="keywordflow">else</span> {
01182                     prev = child;
01183                 }
01184             }
01185         }
01186         netsnmp_subtree_join(contextptr-&gt;first_subtree);
01187     }
01188 }
01189 
01190 <span class="comment">/*</span>
01191 <span class="comment"> * in_a_view: determines if a given snmp_pdu is allowed to see a</span>
01192 <span class="comment"> * given name/namelen OID pointer</span>
01193 <span class="comment"> * name         IN - name of var, OUT - name matched</span>
01194 <span class="comment"> * nameLen      IN -number of sub-ids in name, OUT - subid-is in matched name</span>
01195 <span class="comment"> * pi           IN - relevant auth info re PDU </span>
01196 <span class="comment"> * cvp          IN - relevant auth info re mib module</span>
01197 <span class="comment"> */</span>
01198 
01199 <span class="keywordtype">int</span>
01200 in_a_view(oid *name, size_t *namelen, <a class="code" href="structsnmp__pdu.html">netsnmp_pdu</a> *pdu, <span class=
"keywordtype">int</span> type)
01201 {
01202     <span class="keyword">struct </span>view_parameters view_parms;
01203 
01204     <span class="keywordflow">if</span> (pdu-&gt;<a class="code" href=
"structsnmp__pdu.html#o9">flags</a> &amp; UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01205         <span class="comment">/* Enable bypassing of view-based access control */</span>
01206         <span class="keywordflow">return</span> VACM_SUCCESS;
01207     }
01208 
01209     <span class="comment">/*</span>
01210 <span class="comment">     * check for v1 and counter64s, since snmpv1 doesn't support it </span>
01211 <span class="comment">     */</span>
01212 <span class="preprocessor">#ifndef DISABLE_SNMPV1</span>
01213     <span class="keywordflow">if</span> (pdu-&gt;<a class="code" href=
"structsnmp__pdu.html#o0">version</a> == SNMP_VERSION_1 &amp;&amp; type == ASN_COUNTER64) {
01214         <span class="keywordflow">return</span> VACM_NOTINVIEW;
01215     }
01216 <span class="preprocessor">#endif</span>
01217 
01218     view_parms.pdu = pdu;
01219     view_parms.name = name;
01220     <span class="keywordflow">if</span> (namelen != NULL) {
01221         view_parms.namelen = *namelen;
01222     } <span class="keywordflow">else</span> {
01223         view_parms.namelen = 0;
01224     }
01225     view_parms.errorcode = 0;
01226     view_parms.check_subtree = 0;
01227 
01228     <span class="keywordflow">switch</span> (pdu-&gt;<a class="code" href="structsnmp__pdu.html#o0">version</a>) {
01229 <span class="preprocessor">#ifndef DISABLE_SNMPV1</span>
01230     <span class="keywordflow">case</span> SNMP_VERSION_1:
01231 <span class="preprocessor">#endif</span>
01232 <span class="preprocessor">#ifndef DISABLE_SNMPV2C</span>
01233     <span class="keywordflow">case</span> SNMP_VERSION_2c:
01234 <span class="preprocessor">#endif</span>
01235     <span class="keywordflow">case</span> SNMP_VERSION_3:
01236         <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01237                             SNMPD_CALLBACK_ACM_CHECK, &amp;view_parms);
01238         <span class="keywordflow">return</span> view_parms.errorcode;
01239     }
01240     <span class="keywordflow">return</span> VACM_NOSECNAME;
01241 }
01242 
01243 <span class="comment">/*</span>
01244 <span class="comment"> * check_acces: determines if a given snmp_pdu is ever going to be</span>
01245 <span class="comment"> * allowed to do anynthing or if it's not going to ever be</span>
01246 <span class="comment"> * authenticated.</span>
01247 <span class="comment"> */</span>
01248 <span class="keywordtype">int</span>
01249 check_access(<a class="code" href="structsnmp__pdu.html">netsnmp_pdu</a> *pdu)
01250 {                               <span class="comment">/* IN - pdu being checked */</span>
01251     <span class="keyword">struct </span>view_parameters view_parms;
01252     view_parms.pdu = pdu;
01253     view_parms.name = 0;
01254     view_parms.namelen = 0;
01255     view_parms.errorcode = 0;
01256     view_parms.check_subtree = 0;
01257 
01258     <span class="keywordflow">if</span> (pdu-&gt;<a class="code" href=
"structsnmp__pdu.html#o9">flags</a> &amp; UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01259         <span class="comment">/* Enable bypassing of view-based access control */</span>
01260         <span class="keywordflow">return</span> 0;
01261     }
01262 
01263     <span class="keywordflow">switch</span> (pdu-&gt;<a class="code" href="structsnmp__pdu.html#o0">version</a>) {
01264 <span class="preprocessor">#ifndef DISABLE_SNMPV1</span>
01265     <span class="keywordflow">case</span> SNMP_VERSION_1:
01266 <span class="preprocessor">#endif</span>
01267 <span class="preprocessor">#ifndef DISABLE_SNMPV2C</span>
01268     <span class="keywordflow">case</span> SNMP_VERSION_2c:
01269 <span class="preprocessor">#endif</span>
01270     <span class="keywordflow">case</span> SNMP_VERSION_3:
01271         <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01272                             SNMPD_CALLBACK_ACM_CHECK_INITIAL, &amp;view_parms);
01273         <span class="keywordflow">return</span> view_parms.errorcode;
01274     }
01275     <span class="keywordflow">return</span> 1;
01276 }
01277 
01285 <span class="keywordtype">int</span>
<a name="l01286" id="l01286"></a><a class="code" href="group__agent__registry.html#ga40">01286</a> <a class="code" href=
"group__agent__registry.html#ga40">netsnmp_acm_check_subtree</a>(<a class="code" href=
"structsnmp__pdu.html">netsnmp_pdu</a> *pdu, oid *name, size_t namelen)
01287 {                               <span class="comment">/* IN - pdu being checked */</span>
01288     <span class="keyword">struct </span>view_parameters view_parms;
01289     view_parms.pdu = pdu;
01290     view_parms.name = name;
01291     view_parms.namelen = namelen;
01292     view_parms.errorcode = 0;
01293     view_parms.check_subtree = 1;
01294 
01295     <span class="keywordflow">if</span> (pdu-&gt;<a class="code" href=
"structsnmp__pdu.html#o9">flags</a> &amp; UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01296         <span class="comment">/* Enable bypassing of view-based access control */</span>
01297         <span class="keywordflow">return</span> 0;
01298     }
01299 
01300     <span class="keywordflow">switch</span> (pdu-&gt;<a class="code" href="structsnmp__pdu.html#o0">version</a>) {
01301 <span class="preprocessor">#ifndef DISABLE_SNMPV1</span>
01302     <span class="keywordflow">case</span> SNMP_VERSION_1:
01303 <span class="preprocessor">#endif</span>
01304 <span class="preprocessor">#ifndef DISABLE_SNMPV2C</span>
01305     <span class="keywordflow">case</span> SNMP_VERSION_2c:
01306 <span class="preprocessor">#endif</span>
01307     <span class="keywordflow">case</span> SNMP_VERSION_3:
01308         <a class="code" href="group__callback.html#ga10">snmp_call_callbacks</a>(SNMP_CALLBACK_APPLICATION,
01309                             SNMPD_CALLBACK_ACM_CHECK_SUBTREE, &amp;view_parms);
01310         <span class="keywordflow">return</span> view_parms.errorcode;
01311     }
01312     <span class="keywordflow">return</span> 1;
01313 }
01314 
01315 <span class="preprocessor">#define SUBTREE_DEFAULT_CACHE_SIZE 8</span>
01316 <span class="preprocessor">#define SUBTREE_MAX_CACHE_SIZE     32</span>
01317 <span class="keywordtype">int</span> lookup_cache_size = 0; <span class=
"comment">/*enabled later after registrations are loaded */</span>
01318 
01319 <span class="keyword">typedef</span> <span class="keyword">struct </span>lookup_cache_s {
01320    netsnmp_subtree *next;
01321    netsnmp_subtree *previous;
01322 } lookup_cache;
01323 
01324 <span class="keyword">typedef</span> <span class="keyword">struct </span>lookup_cache_context_s {
01325    <span class="keywordtype">char</span> *context;
01326    <span class="keyword">struct </span>lookup_cache_context_s *next;
01327    <span class="keywordtype">int</span> thecachecount;
01328    <span class="keywordtype">int</span> currentpos;
01329    lookup_cache cache[SUBTREE_MAX_CACHE_SIZE];
01330 } lookup_cache_context;
01331 
01332 <span class="keyword">static</span> lookup_cache_context *thecontextcache = NULL;
01333 
01345 <span class="keywordtype">void</span>
<a name="l01346" id="l01346"></a><a class="code" href="group__agent__registry.html#ga9">01346</a> <a class="code" href=
"group__agent__registry.html#ga9">netsnmp_set_lookup_cache_size</a>(<span class="keywordtype">int</span> newsize) {
01347     <span class="keywordflow">if</span> (newsize &lt; 0)
01348         lookup_cache_size = SUBTREE_DEFAULT_CACHE_SIZE;
01349     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (newsize &lt; SUBTREE_MAX_CACHE_SIZE)
01350         lookup_cache_size = newsize;
01351     <span class="keywordflow">else</span>
01352         lookup_cache_size = SUBTREE_MAX_CACHE_SIZE;
01353 }
01354 
01358 <span class="keywordtype">int</span>
<a name="l01359" id="l01359"></a><a class="code" href="group__agent__registry.html#ga10">01359</a> <a class="code" href=
"group__agent__registry.html#ga10">netsnmp_get_lookup_cache_size</a>(<span class="keywordtype">void</span>) {
01360     <span class="keywordflow">return</span> lookup_cache_size;
01361 }
01362 
01363 NETSNMP_STATIC_INLINE lookup_cache_context *
01364 get_context_lookup_cache(<span class="keyword">const</span> <span class="keywordtype">char</span> *context) {
01365     lookup_cache_context *ptr;
01366     <span class="keywordflow">if</span> (!context)
01367         context = <span class="stringliteral">""</span>;
01368 
01369     <span class="keywordflow">for</span>(ptr = thecontextcache; ptr; ptr = ptr-&gt;next) {
01370         <span class="keywordflow">if</span> (strcmp(ptr-&gt;context, context) == 0)
01371             <span class="keywordflow">break</span>;
01372     }
01373     <span class="keywordflow">if</span> (!ptr) {
01374         <span class="keywordflow">if</span> (netsnmp_subtree_find_first(context)) {
01375             ptr = <a class="code" href="group__util.html#ga39">SNMP_MALLOC_TYPEDEF</a>(lookup_cache_context);
01376             ptr-&gt;next = thecontextcache;
01377             ptr-&gt;context = strdup(context);
01378             thecontextcache = ptr;
01379         } <span class="keywordflow">else</span> {
01380             <span class="keywordflow">return</span> NULL;
01381         }
01382     }
01383     <span class="keywordflow">return</span> ptr;
01384 }
01385 
01386 NETSNMP_STATIC_INLINE <span class="keywordtype">void</span>
01387 lookup_cache_add(<span class="keyword">const</span> <span class="keywordtype">char</span> *context,
01388                  netsnmp_subtree *next, netsnmp_subtree *previous) {
01389     lookup_cache_context *cptr;
01390 
01391     <span class="keywordflow">if</span> ((cptr = get_context_lookup_cache(context)) == NULL)
01392         <span class="keywordflow">return</span>;
01393     
01394     <span class="keywordflow">if</span> (cptr-&gt;thecachecount &lt; lookup_cache_size)
01395         cptr-&gt;thecachecount++;
01396 
01397     cptr-&gt;cache[cptr-&gt;currentpos].next = next;
01398     cptr-&gt;cache[cptr-&gt;currentpos].previous = previous;
01399 
01400     <span class="keywordflow">if</span> (++cptr-&gt;currentpos &gt;= lookup_cache_size)
01401         cptr-&gt;currentpos = 0;
01402 }
01403 
01404 NETSNMP_STATIC_INLINE <span class="keywordtype">void</span>
01405 lookup_cache_replace(lookup_cache *ptr,
01406                      netsnmp_subtree *next, netsnmp_subtree *previous) {
01407 
01408     ptr-&gt;next = next;
01409     ptr-&gt;previous = previous;
01410 }
01411 
01412 NETSNMP_STATIC_INLINE lookup_cache *
01413 lookup_cache_find(<span class="keyword">const</span> <span class=
"keywordtype">char</span> *context, oid *name, size_t name_len,
01414                   <span class="keywordtype">int</span> *retcmp) {
01415     lookup_cache_context *cptr;
01416     lookup_cache *ret = NULL;
01417     <span class="keywordtype">int</span> cmp;
01418     <span class="keywordtype">int</span> i;
01419 
01420     <span class="keywordflow">if</span> ((cptr = get_context_lookup_cache(context)) == NULL)
01421         <span class="keywordflow">return</span> NULL;
01422 
01423     <span class="keywordflow">for</span>(i = 0; i &lt; cptr-&gt;thecachecount &amp;&amp; i &lt; lookup_cache_size; i++) {
01424         <span class="keywordflow">if</span> (cptr-&gt;cache[i].previous-&gt;start_a)
01425             cmp = <a class="code" href="group__library.html#ga103">snmp_oid_compare</a>(name, name_len,
01426                                    cptr-&gt;cache[i].previous-&gt;start_a,
01427                                    cptr-&gt;cache[i].previous-&gt;start_len);
01428         <span class="keywordflow">else</span>
01429             cmp = 1;
01430         <span class="keywordflow">if</span> (cmp &gt;= 0) {
01431             *retcmp = cmp;
01432             ret = &amp;(cptr-&gt;cache[i]);
01433         }
01434     }
01435     <span class="keywordflow">return</span> ret;
01436 }
01437 
01438 NETSNMP_STATIC_INLINE <span class="keywordtype">void</span>
01439 invalidate_lookup_cache(<span class="keyword">const</span> <span class="keywordtype">char</span> *context) {
01440     lookup_cache_context *cptr;
01441     <span class="keywordflow">if</span> ((cptr = get_context_lookup_cache(context)) != NULL) {
01442         cptr-&gt;thecachecount = 0;
01443         cptr-&gt;currentpos = 0;
01444     }
01445 }
01446 
01447 netsnmp_subtree *
01448 netsnmp_subtree_find_prev(oid *name, size_t len, netsnmp_subtree *subtree,
01449                           <span class="keyword">const</span> <span class="keywordtype">char</span> *context_name)
01450 {
01451     lookup_cache *lookup_cache = NULL;
01452     netsnmp_subtree *myptr = NULL, *previous = NULL;
01453     <span class="keywordtype">int</span> cmp = 1;
01454     <span class="keywordtype">int</span> ll_off = 0;
01455 
01456     <span class="keywordflow">if</span> (subtree) {
01457         myptr = subtree;
01458     } <span class="keywordflow">else</span> {
01459         <span class="comment">/* look through everything */</span>
01460         <span class="keywordflow">if</span> (lookup_cache_size) {
01461             lookup_cache = lookup_cache_find(context_name, name, len, &amp;cmp);
01462             <span class="keywordflow">if</span> (lookup_cache) {
01463                 myptr = lookup_cache-&gt;next;
01464                 previous = lookup_cache-&gt;previous;
01465             }
01466             <span class="keywordflow">if</span> (!myptr)
01467                 myptr = netsnmp_subtree_find_first(context_name);
01468         } <span class="keywordflow">else</span> {
01469             myptr = netsnmp_subtree_find_first(context_name);
01470         }
01471     }
01472 
01473     <span class="comment">/*</span>
01474 <span class="comment">     * this optimization causes a segfault on sf cf alpha-linux1.</span>
01475 <span class="comment">     * ifdef out until someone figures out why and fixes it. xxx-rks 20051117</span>
01476 <span class="comment">     */</span>
01477 <span class="preprocessor">#ifndef __alpha</span>
01478 <span class="preprocessor">#define WTEST_OPTIMIZATION 1</span>
01479 <span class="preprocessor">#endif</span>
01480 <span class="preprocessor">#ifdef WTEST_OPTIMIZATION</span>
01481     DEBUGMSGTL((<span class="stringliteral">"wtest"</span>,<span class="stringliteral">"oid in: "</span>));
01482     DEBUGMSGOID((<span class="stringliteral">"wtest"</span>, name, len));
01483     DEBUGMSG((<span class="stringliteral">"wtest"</span>,<span class="stringliteral">"\n"</span>));
01484 <span class="preprocessor">#endif</span>
01485     <span class="keywordflow">for</span> (; myptr != NULL; previous = myptr, myptr = myptr-&gt;next) {
01486 <span class="preprocessor">#ifdef WTEST_OPTIMIZATION</span>
01487         <span class="comment">/* Compare the incoming oid with the linked list.  If we have</span>
01488 <span class="comment">           results of previous compares, its faster to make sure the</span>
01489 <span class="comment">           length we differed in the last check is greater than the</span>
01490 <span class="comment">           length between this pointer and the last then we don't need</span>
01491 <span class="comment">           to actually perform a comparison */</span>
01492         DEBUGMSGTL((<span class="stringliteral">"wtest"</span>,<span class="stringliteral">"oid cmp: "</span>));
01493         DEBUGMSGOID((<span class="stringliteral">"wtest"</span>, myptr-&gt;start_a, myptr-&gt;start_len));
01494         DEBUGMSG((<span class="stringliteral">"wtest"</span>,<span class=
"stringliteral">"  --- off = %d, in off = %d test = %d\n"</span>,
01495                   myptr-&gt;oid_off, ll_off,
01496                   !(ll_off &amp;&amp; myptr-&gt;oid_off &amp;&amp;
01497                     myptr-&gt;oid_off &gt; ll_off)));
01498         <span class=
"keywordflow">if</span> (!(ll_off &amp;&amp; myptr-&gt;oid_off &amp;&amp; myptr-&gt;oid_off &gt; ll_off) &amp;&amp;
01499             <a class="code" href="group__library.html#ga104">netsnmp_oid_compare_ll</a>(name, len,
01500                                    myptr-&gt;start_a, myptr-&gt;start_len,
01501                                    &amp;ll_off) &lt; 0) {
01502 <span class="preprocessor">#else</span>
01503         <span class="keywordflow">if</span> (<a class="code" href=
"group__library.html#ga103">snmp_oid_compare</a>(name, len, myptr-&gt;start_a, myptr-&gt;start_len) &lt; 0) {
01504 <span class="preprocessor">#endif</span>
01505             <span class="keywordflow">if</span> (lookup_cache_size &amp;&amp; previous &amp;&amp; cmp) {
01506                 <span class="keywordflow">if</span> (lookup_cache) {
01507                     lookup_cache_replace(lookup_cache, myptr, previous);
01508                 } <span class="keywordflow">else</span> {
01509                     lookup_cache_add(context_name, myptr, previous);
01510                 }
01511             }
01512             <span class="keywordflow">return</span> previous;
01513         }
01514     }
01515     <span class="keywordflow">return</span> previous;
01516 }
01517 
01518 netsnmp_subtree *
01519 netsnmp_subtree_find_next(oid *name, size_t len,
01520                           netsnmp_subtree *subtree, <span class="keyword">const</span> <span class=
"keywordtype">char</span> *context_name)
01521 {
01522     netsnmp_subtree *myptr = NULL;
01523 
01524     myptr = netsnmp_subtree_find_prev(name, len, subtree, context_name);
01525 
01526     <span class="keywordflow">if</span> (myptr != NULL) {
01527         myptr = myptr-&gt;next;
01528         <span class="keywordflow">while</span> (myptr != NULL &amp;&amp; (myptr-&gt;variables == NULL || 
01529                                  myptr-&gt;variables_len == 0)) {
01530             myptr = myptr-&gt;next;
01531         }
01532         <span class="keywordflow">return</span> myptr;
01533     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (subtree != NULL &amp;&amp; <a class="code"
href="group__library.html#ga103">snmp_oid_compare</a>(name, len, 
01534                                    subtree-&gt;start_a, subtree-&gt;start_len) &lt; 0) {
01535         <span class="keywordflow">return</span> subtree;
01536     } <span class="keywordflow">else</span> {
01537         <span class="keywordflow">return</span> NULL;
01538     }
01539 }
01540 
01541 netsnmp_subtree *
01542 netsnmp_subtree_find(oid *name, size_t len, netsnmp_subtree *subtree, 
01543                      <span class="keyword">const</span> <span class="keywordtype">char</span> *context_name)
01544 {
01545     netsnmp_subtree *myptr;
01546 
01547     myptr = netsnmp_subtree_find_prev(name, len, subtree, context_name);
01548     <span class="keywordflow">if</span> (myptr &amp;&amp; myptr-&gt;end_a &amp;&amp;
01549         <a class="code" href=
"group__library.html#ga103">snmp_oid_compare</a>(name, len, myptr-&gt;end_a, myptr-&gt;end_len)&lt;0) {
01550         <span class="keywordflow">return</span> myptr;
01551     }
01552 
01553     <span class="keywordflow">return</span> NULL;
01554 }
01555 
01556 <a class="code" href="structsnmp__session.html">netsnmp_session</a> *
01557 get_session_for_oid(oid *name, size_t len, <span class="keyword">const</span> <span class=
"keywordtype">char</span> *context_name)
01558 {
01559     netsnmp_subtree *myptr;
01560 
01561     myptr = netsnmp_subtree_find_prev(name, len, 
01562                                       netsnmp_subtree_find_first(context_name),
01563                                       context_name);
01564 
01565     <span class="keywordflow">while</span> (myptr &amp;&amp; myptr-&gt;variables == NULL) {
01566         myptr = myptr-&gt;<a class="code" href="structsnmp__session.html#o5">next</a>;
01567     }
01568 
01569     <span class="keywordflow">if</span> (myptr == NULL) {
01570         <span class="keywordflow">return</span> NULL;
01571     } <span class="keywordflow">else</span> {
01572         <span class="keywordflow">return</span> myptr-&gt;session;
01573     }
01574 }
01575 
01576 <span class="keywordtype">void</span>
01577 setup_tree(<span class="keywordtype">void</span>)
01578 {
01579     oid ccitt[1]           = { 0 };
01580     oid iso[1]             = { 1 };
01581     oid joint_ccitt_iso[1] = { 2 };
01582 
01583 <span class="preprocessor">#ifdef USING_AGENTX_SUBAGENT_MODULE</span>
01584     <span class="keywordtype">int</span> role =  netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
01585                                        NETSNMP_DS_AGENT_ROLE);
01586 
01587     <a class="code" href=
"group__default__store.html#ga8">netsnmp_ds_set_boolean</a>(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 
01588                            MASTER_AGENT);
01589 <span class="preprocessor">#endif</span>
01590 
01591     <span class="comment">/* </span>
01592 <span class="comment">     * we need to have the oid's in the heap, that we can *free* it for every case, </span>
01593 <span class="comment">     * thats the purpose of the duplicate_objid's</span>
01594 <span class="comment">     */</span>
01595     netsnmp_register_null(snmp_duplicate_objid(ccitt, 1), 1);
01596     netsnmp_register_null(snmp_duplicate_objid(iso, 1), 1);
01597     netsnmp_register_null(snmp_duplicate_objid(joint_ccitt_iso, 1), 1);
01598 
01599 <span class="preprocessor">#ifdef USING_AGENTX_SUBAGENT_MODULE</span>
01600     <a class="code" href=
"group__default__store.html#ga8">netsnmp_ds_set_boolean</a>(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 
01601                            role);
01602 <span class="preprocessor">#endif</span>
01603 }
01604 
01605 <span class="keywordtype">int</span> 
01606 remove_tree_entry (oid *name, size_t len) {
01607 
01608     netsnmp_subtree *sub = NULL;
01609 
01610     <span class="keywordflow">if</span> ((sub = netsnmp_subtree_find(name, len, NULL, <span class=
"stringliteral">""</span>)) == NULL) {
01611         <span class="keywordflow">return</span> MIB_NO_SUCH_REGISTRATION;
01612     }
01613 
01614     <span class="keywordflow">return</span> <a class="code" href=
"group__agent__registry.html#ga32">unregister_mib_context</a>(name, len, sub-&gt;priority,
01615                                   sub-&gt;range_subid, sub-&gt;range_ubound, <span class="stringliteral">""</span>);
01616 
01617 }
01618 
01619 
01620 <span class="keywordtype">void</span>
01621 shutdown_tree(<span class="keywordtype">void</span>) {
01622     oid ccitt[1]           = { 0 };
01623     oid iso[1]             = { 1 };
01624     oid joint_ccitt_iso[1] = { 2 };
01625 
01626     DEBUGMSGTL((<span class="stringliteral">"agent_registry"</span>, <span class=
"stringliteral">"shut down tree\n"</span>));
01627 
01628     remove_tree_entry(joint_ccitt_iso, 1);
01629     remove_tree_entry(iso, 1);
01630     remove_tree_entry(ccitt, 1);
01631 
01632 }
01633 
01634 <span class="keywordtype">void</span>
01635 clear_subtree (netsnmp_subtree *sub) {
01636 
01637     netsnmp_subtree *nxt;
01638     
01639     <span class="keywordflow">if</span> (sub == NULL)
01640         <span class="keywordflow">return</span>;
01641 
01642     <span class="keywordflow">for</span>(nxt = sub; nxt;) {
01643         <span class="keywordflow">if</span> (nxt-&gt;children != NULL) {
01644             clear_subtree(nxt-&gt;children);
01645         }
01646         sub = nxt;
01647         nxt = nxt-&gt;<a class="code" href="structsnmp__session.html#o5">next</a>;
01648         netsnmp_subtree_free(sub);
01649     }
01650 
01651 }
01652 
01653 <span class="keywordtype">void</span>
01654 clear_lookup_cache(<span class="keywordtype">void</span>) {
01655 
01656     lookup_cache_context *ptr = NULL, *next = NULL;
01657 
01658     ptr = thecontextcache;
01659     <span class="keywordflow">while</span> (ptr) {
01660         next = ptr-&gt;<a class="code" href="structsnmp__session.html#o5">next</a>;
01661         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(ptr-&gt;context);
01662         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(ptr);
01663         ptr = next;
01664     }
01665     thecontextcache = NULL; <span class="comment">/* !!! */</span>
01666 }
01667 
01668 <span class="keywordtype">void</span>
01669 clear_context(<span class="keywordtype">void</span>) {
01670 
01671     subtree_context_cache *ptr = NULL, *next = NULL;
01672 
01673     DEBUGMSGTL((<span class="stringliteral">"agent_registry"</span>, <span class=
"stringliteral">"clear context\n"</span>));
01674 
01675     ptr = get_top_context_cache(); 
01676     <span class="keywordflow">while</span> (ptr) {
01677         next = ptr-&gt;<a class="code" href="structsnmp__session.html#o5">next</a>;
01678 
01679         <span class="keywordflow">if</span> (ptr-&gt;first_subtree) {
01680             clear_subtree(ptr-&gt;first_subtree);
01681         }
01682 
01683         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(ptr-&gt;context_name);
01684         <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(ptr);
01685 
01686         ptr = next;
01687     }
01688     context_subtrees = NULL; <span class="comment">/* !!! */</span>
01689     clear_lookup_cache();
01690 }
01691 
01692 <span class="keyword">extern</span> <span class="keywordtype">void</span>     dump_idx_registry(<span class=
"keywordtype">void</span>);
01693 <span class="keywordtype">void</span>
01694 dump_registry(<span class="keywordtype">void</span>)
01695 {
01696     <span class="keyword">struct </span>variable *vp = NULL;
01697     netsnmp_subtree *myptr, *myptr2;
01698     u_char *s = NULL, *e = NULL, *v = NULL;
01699     size_t sl = 256, el = 256, vl = 256, sl_o = 0, el_o = 0, vl_o = 0;
01700     <span class="keywordtype">int</span> i = 0;
01701 
01702     <span class="keywordflow">if</span> ((s = (u_char *) calloc(sl, 1)) != NULL &amp;&amp;
01703         (e = (u_char *) calloc(sl, 1)) != NULL &amp;&amp;
01704         (v = (u_char *) calloc(sl, 1)) != NULL) {
01705 
01706         subtree_context_cache *ptr;
01707         <span class="keywordflow">for</span> (ptr = context_subtrees; ptr; ptr = ptr-&gt;next) {
01708             printf(<span class="stringliteral">"Subtrees for Context: %s\n"</span>, ptr-&gt;context_name);
01709             <span class="keywordflow">for</span> (myptr = ptr-&gt;first_subtree; myptr != NULL;
01710                  myptr = myptr-&gt;next) {
01711                 sl_o = el_o = vl_o = 0;
01712 
01713                 <span class="keywordflow">if</span> (!sprint_realloc_objid(&amp;s, &amp;sl, &amp;sl_o, 1,
01714                                           myptr-&gt;start_a,
01715                                           myptr-&gt;start_len)) {
01716                     <span class="keywordflow">break</span>;
01717                 }
01718                 <span class="keywordflow">if</span&