Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
agent_registry.c File Reference
Main Page   Data Structures   File List   Data Fields   Globals  

agent_registry.c File Reference

#include <config.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <dmalloc.h>
#include "mibincl.h"
#include "snmp_client.h"
#include "default_store.h"
#include "ds_agent.h"
#include "callback.h"
#include "agent_callbacks.h"
#include "agent_registry.h"
#include "snmp_alarm.h"
#include "snmp_secmod.h"
#include "vacm.h"
#include "snmpd.h"
#include "mibgroup/struct.h"
#include "helpers/old_api.h"
#include "helpers/null.h"
#include "helpers/table.h"
#include "helpers/table_iterator.h"
#include "mib_module_includes.h"

Go to the source code of this file.


Defines

#define IN_SNMP_VARS_C

Functions

subtree_context_cacheget_top_context_cache (void)
subtreefind_first_subtree (const char *context_name)
subtreeadd_subtree (struct subtree *new_tree, const char *context_name)
subtreereplace_first_subtree (struct subtree *new_tree, const char *context_name)
int tree_compare (const struct subtree *ap, const struct subtree *bp)
subtreesplit_subtree (struct subtree *current, oid name[], int name_len)
int load_subtree (struct subtree *new_sub, const char *context_name)
int register_mib_context2 (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen, int priority, int range_subid, oid range_ubound, struct snmp_session *ss, const char *context, int timeout, int flags, handler_registration *reginfo)
int register_mib_context (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen, int priority, int range_subid, oid range_ubound, struct snmp_session *ss, const char *context, int timeout, int flags)
void register_mib_reattach_subtree (struct subtree *it)
void register_mib_reattach (void)
int register_mib_range (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen, int priority, int range_subid, oid range_ubound, struct snmp_session *ss)
int register_mib_priority (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen, int priority)
int register_mib (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen)
int register_mib_table_row (const char *moduleName, struct variable *var, size_t varsize, size_t numvars, oid *mibloc, size_t mibloclen, int priority, int var_subid, struct snmp_session *ss, const char *context, int timeout, int flags)
void unload_subtree (struct subtree *sub, struct subtree *prev)
int unregister_mib_context (oid *name, size_t len, int priority, int range_subid, oid range_ubound, const char *context)
int unregister_mib_range (oid *name, size_t len, int priority, int range_subid, oid range_ubound)
int unregister_mib_priority (oid *name, size_t len, int priority)
int unregister_mib (oid *name, size_t len)
void unregister_mibs_by_session (struct snmp_session *ss)
subtreefree_subtree (struct subtree *st)
int in_a_view (oid *name, size_t *namelen, struct snmp_pdu *pdu, int type)
int check_access (struct snmp_pdu *pdu)
int compare_tree (const oid *in_name1, size_t len1, const oid *in_name2, size_t len2)
subtreefind_subtree_previous (oid *name, size_t len, struct subtree *subtree, const char *context_name)
subtreefind_subtree_next (oid *name, size_t len, struct subtree *subtree, const char *context_name)
subtreefind_subtree (oid *name, size_t len, struct subtree *subtree, const char *context_name)
snmp_session * get_session_for_oid (oid *name, size_t len, const char *context_name)
void setup_tree (void)
void dump_idx_registry (void)
void dump_registry (void)
int register_readfd (int fd, void(*func)(int, void *), void *data)
int register_writefd (int fd, void(*func)(int, void *), void *data)
int register_exceptfd (int fd, void(*func)(int, void *), void *data)
int unregister_readfd (int fd)
int unregister_writefd (int fd)
int unregister_exceptfd (int fd)
RETSIGTYPE agent_SIGCHLD_handler (int sig)
int register_signal (int sig, void(*func)(int))
int unregister_signal (int sig)

Variables

subtree_context_cachecontext_subtrees = NULL
int external_readfd [NUM_EXTERNAL_FDS]
int external_readfdlen = 0
int external_writefd [NUM_EXTERNAL_FDS]
int external_writefdlen = 0
int external_exceptfd [NUM_EXTERNAL_FDS]
int external_exceptfdlen = 0
void(* external_readfdfunc [NUM_EXTERNAL_FDS])(int, void *)
void(* external_writefdfunc [NUM_EXTERNAL_FDS])(int, void *)
void(* external_exceptfdfunc [NUM_EXTERNAL_FDS])(int, void *)
void * external_readfd_data [NUM_EXTERNAL_FDS]
void * external_writefd_data [NUM_EXTERNAL_FDS]
void * external_exceptfd_data [NUM_EXTERNAL_FDS]
int external_signal_scheduled [NUM_EXTERNAL_SIGS]
void(* external_signal_handler [NUM_EXTERNAL_SIGS])(int)

Define Documentation

#define IN_SNMP_VARS_C
 

Definition at line 8 of file agent_registry.c.


Function Documentation

struct subtree* add_subtree struct subtree   new_tree,
const char *    context_name
 

Definition at line 90 of file agent_registry.c.

Referenced by replace_first_subtree().

00090                                                                 {
00091     subtree_context_cache *ptr = SNMP_MALLOC_TYPEDEF(subtree_context_cache);
00092     if (!context_name)
00093         context_name = "";
00094 
00095     if (!ptr)
00096         return NULL;
00097 
00098     DEBUGMSGTL(("add_subtree","adding subtree for context: \"%s\"\n", context_name));
00099     ptr->next = context_subtrees;
00100     ptr->first_subtree = new_tree;
00101     ptr->context_name = strdup(context_name);
00102     context_subtrees = ptr;
00103     return ptr->first_subtree;
00104 }

RETSIGTYPE agent_SIGCHLD_handler int    sig
 

Definition at line 1172 of file agent_registry.c.

01173 {
01174   external_signal_scheduled[SIGCHLD]++;
01175 #ifndef HAVE_SIGACTION
01176   /* signal() sucks. It *might* have SysV semantics, which means that
01177    * a signal handler is reset once it gets called. Ensure that it
01178    * remains active.
01179    */
01180   signal(SIGCHLD, agent_SIGCHLD_handler);
01181 #endif
01182 }

int check_access struct snmp_pdu *    pdu
 

Definition at line 866 of file agent_registry.c.

00867 {
00868   struct view_parameters view_parms;
00869   view_parms.pdu = pdu;
00870   view_parms.name = 0;
00871   view_parms.namelen = 0;
00872   view_parms.errorcode = 0;
00873 
00874   if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
00875     return 0;           /* Enable bypassing of view-based access control */
00876 
00877   switch (pdu->version) {
00878   case SNMP_VERSION_1:
00879   case SNMP_VERSION_2c:
00880   case SNMP_VERSION_3:
00881     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
00882                         SNMPD_CALLBACK_ACM_CHECK_INITIAL,
00883                         &view_parms);
00884     return view_parms.errorcode;
00885   }
00886   return 1;
00887 }

int compare_tree const oid *    in_name1,
size_t    len1,
const oid *    in_name2,
size_t    len2
 

Definition at line 897 of file agent_registry.c.

00901 {
00902     register int len, res;
00903     register const oid * name1 = in_name1;
00904     register const oid * name2 = in_name2;
00905 
00906     /* len = minimum of len1 and len2 */
00907     if (len1 < len2)
00908         len = len1;
00909     else
00910         len = len2;
00911     /* find first non-matching OID */
00912     while(len-- > 0){
00913         res = *(name1++) - *(name2++);
00914         if (res < 0)
00915             return -1;
00916         if (res > 0)
00917             return 1;
00918     }
00919     /* both OIDs equal up to length of shorter OID */
00920     if (len1 < len2)
00921         return -1;
00922 
00923     /* name1 matches name2 for length of name2, or they are equal */
00924     return 0;
00925 }

void dump_idx_registry void   
 

Definition at line 495 of file agent_index.c.

00496 {
00497     struct snmp_index *idxptr, *idxptr2;
00498     char start_oid[SPRINT_MAX_LEN];
00499     char end_oid[SPRINT_MAX_LEN];
00500 
00501     if ( snmp_index_head )
00502         printf("\nIndex Allocations:\n");
00503     for( idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid) {
00504         sprint_objid(start_oid, idxptr->varbind->name, idxptr->varbind->name_length);
00505         printf("%s indexes:\n", start_oid);
00506         for( idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx) {
00507             switch( idxptr2->varbind->type ) {
00508                 case ASN_INTEGER:
00509                     printf("    %c %ld %c\n",
00510                         ( idxptr2->session ? ' ' : '(' ),
00511                           *idxptr2->varbind->val.integer,
00512                         ( idxptr2->session ? ' ' : ')' ));
00513                     break;
00514                 case ASN_OCTET_STR:
00515                     printf("    %c %s %c\n",
00516                         ( idxptr2->session ? ' ' : '(' ),
00517                           idxptr2->varbind->val.string,
00518                         ( idxptr2->session ? ' ' : ')' ));
00519                     break;
00520                 case ASN_OBJECT_ID:
00521                     sprint_objid(end_oid, idxptr2->varbind->val.objid,
00522                                 idxptr2->varbind->val_len/sizeof(oid));
00523                     printf("    %c %s %c\n",
00524                         ( idxptr2->session ? ' ' : '(' ),
00525                           end_oid,
00526                         ( idxptr2->session ? ' ' : ')' ));
00527                     break;
00528                 default:
00529                     printf("unsupported type (%d)\n",
00530                                 idxptr2->varbind->type);
00531             }
00532         }
00533     }
00534 }

void dump_registry void   
 

Definition at line 1031 of file agent_registry.c.

01032 {
01033     struct subtree *myptr, *myptr2;
01034     char start_oid[SPRINT_MAX_LEN];
01035     char end_oid[SPRINT_MAX_LEN];
01036 
01037     subtree_context_cache *ptr;
01038     for(ptr = context_subtrees; ptr; ptr = ptr->next) {
01039         printf("Subtrees for Context: %s\n", ptr->context_name);
01040         for( myptr = ptr->first_subtree ; myptr != NULL; myptr = myptr->next) {
01041             sprint_objid(start_oid, myptr->start, myptr->start_len);
01042             sprint_objid(end_oid, myptr->end, myptr->end_len);
01043             printf("%s%c %s - %s %c\n",
01044                    (myptr->flags & FULLY_QUALIFIED_INSTANCE)?"[FQI] ":"",
01045                    ( myptr->variables ? ' ' : '(' ),
01046                    start_oid, end_oid,
01047                    ( myptr->variables ? ' ' : ')' ));
01048             for( myptr2 = myptr ; myptr2 != NULL; myptr2 = myptr2->children) {
01049                 if ( myptr2->label && myptr2->label[0] )
01050                     printf("\t%s\n", myptr2->label);
01051             }
01052         }
01053     }
01054 
01055     dump_idx_registry();
01056 }

struct subtree* find_first_subtree const char *    context_name
 

Definition at line 74 of file agent_registry.c.

00074                                              {
00075     subtree_context_cache *ptr;
00076     if (!context_name)
00077         context_name = "";
00078     DEBUGMSGTL(("find_first_subtree","looking for subtree for context: \"%s\"\n", context_name));
00079     for(ptr = context_subtrees; ptr; ptr = ptr->next) {
00080         if (strcmp(ptr->context_name, context_name) == 0) {
00081             DEBUGMSGTL(("find_first_subtree","found one for: \"%s\"\n", context_name));
00082             return ptr->first_subtree;
00083         }
00084     }
00085     DEBUGMSGTL(("find_first_subtree","Didn't find a subtree for: \"%s\"\n", context_name));
00086     return NULL;
00087 }

struct subtree* find_subtree oid *    name,
size_t    len,
struct subtree   subtree,
const char *    context_name
 

Definition at line 967 of file agent_registry.c.

00971 {
00972   struct subtree *myptr;
00973 
00974   myptr = find_subtree_previous(name, len, subtree, context_name);
00975   if (myptr && snmp_oid_compare(name, len, myptr->end, myptr->end_len) < 0)
00976         return myptr;
00977 
00978   return NULL;
00979 }

struct subtree* find_subtree_next oid *    name,
size_t    len,
struct subtree   subtree,
const char *    context_name
 

Definition at line 947 of file agent_registry.c.

00951 {
00952   struct subtree *myptr = NULL;
00953 
00954   myptr = find_subtree_previous(name, len, subtree, context_name);
00955   if ( myptr != NULL ) {
00956      myptr = myptr->next;
00957      while ( myptr && (myptr->variables == NULL || myptr->variables_len == 0) )
00958          myptr = myptr->next;
00959      return myptr;
00960   }
00961   else if (subtree && snmp_oid_compare(name, len, subtree->start, subtree->start_len) < 0)
00962      return subtree;
00963   else
00964      return NULL;
00965 }

struct subtree* find_subtree_previous oid *    name,
size_t    len,
struct subtree   subtree,
const char *    context_name
 

Definition at line 927 of file agent_registry.c.

00931 {
00932   struct subtree *myptr, *previous = NULL;
00933 
00934   if ( subtree )
00935         myptr = subtree;
00936   else
00937         myptr = find_first_subtree(context_name);  /* look through everything */
00938 
00939   for( ; myptr != NULL; previous = myptr, myptr = myptr->next) {
00940     if (snmp_oid_compare(name, len, myptr->start, myptr->start_len) < 0) {
00941       return previous;
00942     }
00943   }
00944   return previous;
00945 }

struct subtree* free_subtree struct subtree   st
 

Definition at line 806 of file agent_registry.c.

00807 {
00808   struct subtree *ret = NULL;
00809 
00810   if (st->variables != NULL &&
00811       snmp_oid_compare(st->name, st->namelen, st->start, st->start_len) == 0) {
00812     free(st->variables);
00813     st->variables = NULL;
00814   }
00815   if (st->next != NULL) {
00816     ret = st->next;
00817   }
00818   free(st);
00819   return ret;
00820 }

struct snmp_session* get_session_for_oid oid *    name,
size_t    len,
const char *    context_name
 

Definition at line 981 of file agent_registry.c.

00983 {
00984    struct subtree *myptr;
00985 
00986    myptr = find_subtree_previous(name, len, find_first_subtree(context_name),
00987                                  context_name);
00988    while ( myptr && myptr->variables == NULL )
00989         myptr = myptr->next;
00990 
00991    if ( myptr == NULL )
00992         return NULL;
00993    else
00994         return myptr->session;
00995 }

subtree_context_cache* get_top_context_cache void   
 

Definition at line 69 of file agent_registry.c.

00069                                                    {
00070     return context_subtrees;
00071 }

int in_a_view oid *    name,
size_t *    namelen,
struct snmp_pdu *    pdu,
int    type
 

Definition at line 831 of file agent_registry.c.

00835 {
00836 
00837   struct view_parameters view_parms;
00838   view_parms.pdu = pdu;
00839   view_parms.name = name;
00840   if (namelen)
00841       view_parms.namelen = *namelen;
00842   else
00843       view_parms.namelen = 0;
00844   view_parms.errorcode = 0;
00845 
00846   if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
00847     return VACM_SUCCESS; /* Enable bypassing of view-based access control */
00848 
00849   /* check for v1 and counter64s, since snmpv1 doesn't support it */
00850   if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64)
00851     return VACM_NOTINVIEW;
00852   switch (pdu->version) {
00853   case SNMP_VERSION_1:
00854   case SNMP_VERSION_2c:
00855   case SNMP_VERSION_3:
00856     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
00857                         &view_parms);
00858     return view_parms.errorcode;
00859   }
00860   return VACM_NOSECNAME;
00861 }

int load_subtree struct subtree   new_sub,
const char *    context_name
 

Definition at line 203 of file agent_registry.c.

Referenced by register_mib_context2(), and register_mib_table_row().

00204 {
00205     struct subtree *tree1, *tree2, *new2;
00206     struct subtree *prev, *next;
00207     int res;
00208 
00209     if ( new_sub == NULL )
00210         return MIB_REGISTERED_OK;       /* Degenerate case */
00211 
00212                 /*
00213                  * Find the subtree that contains the start of 
00214                  *  the new subtree (if any)...
00215                  */
00216     tree1 = find_subtree( new_sub->start, new_sub->start_len, NULL,
00217                           context_name );
00218                 /*
00219                  * ...and the subtree that follows the new one
00220                  *      (NULL implies this is the final region covered)
00221                  */  
00222     if ( tree1 == NULL )
00223         tree2 = find_subtree_next( new_sub->start, new_sub->start_len, NULL,
00224                                    context_name);
00225     else
00226         tree2 = tree1->next;
00227 
00228 
00229         /*
00230          * Handle new subtrees that start in virgin territory.
00231          */
00232     if ( tree1 == NULL ) {
00233         new2 = NULL;
00234                 /* Is there any overlap with later subtrees ? */
00235         if ( tree2 && snmp_oid_compare( new_sub->end, new_sub->end_len,
00236                                         tree2->start, tree2->start_len ) > 0 )
00237             new2 = split_subtree( new_sub, tree2->start, tree2->start_len );
00238                 /*
00239                  * Link the new subtree (less any overlapping region)
00240                  *  with the list of existing registrations
00241                  */
00242         if ( tree2 ) {
00243             new_sub->prev = tree2->prev;
00244             tree2->prev       = new_sub;
00245         }
00246         else
00247             new_sub->prev = find_subtree_previous( new_sub->start, new_sub->start_len, NULL, context_name );
00248 
00249         if ( new_sub->prev )
00250             new_sub->prev->next = new_sub;
00251         else
00252             replace_first_subtree(new_sub, context_name);
00253 
00254         new_sub->next     = tree2;
00255 
00256                 /*
00257                  * If there was any overlap,
00258                  *  recurse to merge in the overlapping region
00259                  *  (including anything that may follow the overlap)
00260                  */
00261         if ( new2 )
00262             return load_subtree( new2, context_name );
00263     }
00264 
00265     else {
00266         /*
00267          *  If the new subtree starts *within* an existing registration
00268          *    (rather than at the same point as it), then split the
00269          *    existing subtree at this point.
00270          */
00271         if ( snmp_oid_compare( new_sub->start, new_sub->start_len, 
00272                                tree1->start,   tree1->start_len) != 0 )
00273             tree1 = split_subtree( tree1, new_sub->start, new_sub->start_len);
00274             if ( tree1 == NULL )
00275                 return MIB_REGISTRATION_FAILED;
00276 
00277         /*  Now consider the end of this existing subtree:
00278          *      If it matches the new subtree precisely,
00279          *        simply merge the new one into the list of children
00280          *      If it includes the whole of the new subtree,
00281          *        split it at the appropriate point, and merge again
00282          *
00283          *      If the new subtree extends beyond this existing region,
00284          *        split it, and recurse to merge the two parts.
00285          */
00286 
00287          switch ( snmp_oid_compare( new_sub->end, new_sub->end_len, 
00288                                     tree1->end,   tree1->end_len))  {
00289 
00290                 case -1:        /* Existing subtree contains new one */
00291                         (void) split_subtree( tree1,
00292                                         new_sub->end, new_sub->end_len);
00293                         /* Fall Through */
00294 
00295                 case  0:        /* The two trees match precisely */
00296                         /*
00297                          * Note: This is the only point where the original
00298                          *       registration OID ("name") is used
00299                          */
00300                         prev = NULL;
00301                         next = tree1;
00302                         while ( next && next->namelen > new_sub->namelen ) {
00303                                 prev = next;
00304                                 next = next->children;
00305                         }
00306                         while ( next && next->namelen == new_sub->namelen &&
00307                                         next->priority < new_sub->priority ) {
00308                                 prev = next;
00309                                 next = next->children;
00310                         }
00311                         if ( next &&    next->namelen  == new_sub->namelen &&
00312                                         next->priority == new_sub->priority )
00313                            return MIB_DUPLICATE_REGISTRATION;
00314 
00315                         if ( prev ) {
00316                             new_sub->children = next;
00317                             prev->children    = new_sub;
00318                             new_sub->prev = prev->prev;
00319                             new_sub->next = prev->next;
00320                         }
00321                         else {
00322                             new_sub->children = next;
00323                             new_sub->prev = next->prev;
00324                             new_sub->next = next->next;
00325 
00326                             for ( next = new_sub->next ;
00327                                   next != NULL ;
00328                                   next = next->children )
00329                                         next->prev = new_sub;
00330 
00331                             for ( prev = new_sub->prev ;
00332                                   prev != NULL ;
00333                                   prev = prev->children )
00334                                         prev->next = new_sub;
00335                         }
00336                         break;
00337 
00338                 case  1:        /* New subtree contains the existing one */
00339                         new2 = split_subtree( new_sub,
00340                                         tree1->end, tree1->end_len);
00341                         res = load_subtree( new_sub, context_name );
00342                         if ( res != MIB_REGISTERED_OK ) {
00343                             free_subtree(new2);
00344                             return res;
00345                         }
00346                         return load_subtree( new2, context_name );
00347 
00348          }
00349 
00350     }
00351     return 0;
00352 }

int register_exceptfd int    fd,
void(*    func)(int, void *),
void *    data
 

Definition at line 1097 of file agent_registry.c.

01097                                                                      {
01098     if (external_exceptfdlen < NUM_EXTERNAL_FDS) {
01099         external_exceptfd[external_exceptfdlen] = fd;
01100         external_exceptfdfunc[external_exceptfdlen] = func;
01101         external_exceptfd_data[external_exceptfdlen] = data;
01102         external_exceptfdlen++;
01103         DEBUGMSGTL(("register_exceptfd", "registered fd %d\n", fd));
01104         return FD_REGISTERED_OK;
01105     } else {
01106         snmp_log(LOG_CRIT, "register_exceptfd: too many file descriptors\n");
01107         return FD_REGISTRATION_FAILED;
01108     }
01109 }

int register_mib const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen
 

Definition at line 565 of file agent_registry.c.

00571 {
00572   return register_mib_priority( moduleName, var, varsize, numvars,
00573                                 mibloc, mibloclen, DEFAULT_MIB_PRIORITY );
00574 }

int register_mib_context const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen,
int    priority,
int    range_subid,
oid    range_ubound,
struct snmp_session *    ss,
const char *    context,
int    timeout,
int    flags
 

Definition at line 481 of file agent_registry.c.

00493                                 {
00494     return register_old_api(moduleName, var, varsize, numvars, mibloc,
00495                             mibloclen, priority,
00496                             range_subid, range_ubound,
00497                             ss, context, timeout, flags);
00498 }

int register_mib_context2 const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen,
int    priority,
int    range_subid,
oid    range_ubound,
struct snmp_session *    ss,
const char *    context,
int    timeout,
int    flags,
handler_registration   reginfo
 

Definition at line 355 of file agent_registry.c.

Referenced by register_handler().

00369 {
00370   struct subtree *subtree, *sub2;
00371   int res, i;
00372   struct register_parameters reg_parms;
00373   
00374   subtree = (struct subtree *) malloc(sizeof(struct subtree));
00375   if (subtree == NULL) {
00376     return MIB_REGISTRATION_FAILED;
00377   }
00378   memset(subtree, 0, sizeof(struct subtree));
00379 
00380   DEBUGMSGTL(("register_mib", "registering \"%s\" at ", moduleName));
00381   DEBUGMSGOID(("register_mib", mibloc, mibloclen));
00382   DEBUGMSG(("register_mib","\n"));
00383     
00384         /*
00385          * Create the new subtree node being registered
00386          */
00387   memcpy(subtree->name, mibloc, mibloclen*sizeof(oid));
00388   subtree->namelen = (u_char) mibloclen;
00389   memcpy(subtree->start, mibloc, mibloclen*sizeof(oid));
00390   subtree->start_len = (u_char) mibloclen;
00391   memcpy(subtree->end, mibloc, mibloclen*sizeof(oid));
00392   subtree->end[ mibloclen-1 ]++;        /* XXX - or use 'variables' info ? */
00393   subtree->end_len = (u_char) mibloclen;
00394   memcpy(subtree->label, moduleName, strlen(moduleName)+1);
00395   if (var) {
00396     subtree->variables = (struct variable *) malloc(varsize*numvars);
00397     if (subtree->variables == NULL) {
00398       free(subtree);
00399       return MIB_REGISTRATION_FAILED;
00400     }
00401     memcpy(subtree->variables, var, numvars*varsize);
00402     subtree->variables_len = numvars;
00403     subtree->variables_width = varsize;
00404   }
00405   subtree->priority = priority;
00406   subtree->timeout  = timeout;
00407   subtree->range_subid = range_subid;
00408   subtree->range_ubound = range_ubound;
00409   subtree->session = ss;
00410   subtree->reginfo = reginfo;
00411   subtree->flags = (u_char)flags;  /* used to identify instance oids */
00412   subtree->cacheid = -1;
00413   res = load_subtree(subtree, context);
00414 
00415         /*
00416          * If registering a range,
00417          *   use the first subtree as a template
00418          *   for the rest of the range
00419          */
00420   if (( res == MIB_REGISTERED_OK ) && ( range_subid != 0 )) {
00421     for ( i = mibloc[range_subid-1] +1 ; i <= (int)range_ubound ; i++ ) {
00422         sub2 = (struct subtree *) malloc(sizeof(struct subtree));
00423 
00424         if (sub2 == NULL) {
00425             unregister_mib_context(mibloc, mibloclen, priority,
00426                                    range_subid, range_ubound, context);
00427             return MIB_REGISTRATION_FAILED;
00428         }
00429 
00430         memcpy(sub2, subtree, sizeof(struct subtree));
00431 
00432         /*  Note: have to deep-copy sub2->variables, otherwise it will
00433             be free()d more than once.  This is kind of inefficient.  */
00434         
00435         if (subtree->variables != NULL) {
00436           sub2->variables = (struct variable *)malloc(varsize * numvars);
00437           if (sub2->variables == NULL) {
00438             free(sub2);
00439             unregister_mib_context(mibloc, mibloclen, priority,
00440                                    range_subid, range_ubound, context);
00441             return MIB_REGISTRATION_FAILED;
00442           }
00443 
00444           memcpy(sub2->variables, var, numvars * varsize);
00445         }
00446         
00447         sub2->name[range_subid-1] = i;
00448         sub2->start[range_subid-1] = i;
00449         sub2->end[  range_subid-1] = i;         /* XXX - ???? */
00450         res = load_subtree(sub2, context);
00451         if (res != MIB_REGISTERED_OK) {
00452             unregister_mib_context( mibloc, mibloclen, priority,
00453                                   range_subid, range_ubound, context);
00454             return MIB_REGISTRATION_FAILED;
00455         }
00456     }
00457   } else if (res == MIB_DUPLICATE_REGISTRATION ||
00458              res == MIB_REGISTRATION_FAILED) {
00459       free_subtree(subtree);
00460   }
00461 
00462   reg_parms.name = mibloc;
00463   reg_parms.namelen = mibloclen;
00464   reg_parms.priority = priority;
00465   reg_parms.range_subid  = range_subid;
00466   reg_parms.range_ubound = range_ubound;
00467   reg_parms.timeout = timeout;
00468   reg_parms.flags = (u_char)flags;
00469 
00470   /*  Should this really be called if the registration hasn't actually 
00471       succeeded?  */
00472 
00473   snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_REGISTER_OID,
00474                       &reg_parms);
00475 
00476   return res;
00477 }

int register_mib_priority const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen,
int    priority
 

Definition at line 552 of file agent_registry.c.

00559 {
00560   return register_mib_range( moduleName, var, varsize, numvars,
00561                                 mibloc, mibloclen, priority, 0, 0, NULL );
00562 }

int register_mib_range const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen,
int    priority,
int    range_subid,
oid    range_ubound,
struct snmp_session *    ss
 

Definition at line 535 of file agent_registry.c.

00545 {
00546   return register_mib_context( moduleName, var, varsize, numvars,
00547                                 mibloc, mibloclen, priority,
00548                                 range_subid, range_ubound, ss, "", -1, 0);
00549 }

void register_mib_reattach void   
 

Definition at line 527 of file agent_registry.c.

00527                             {
00528     subtree_context_cache *ptr;
00529     for(ptr = context_subtrees; ptr; ptr = ptr->next) {
00530         register_mib_reattach_subtree(ptr->first_subtree);
00531     }
00532 }

void register_mib_reattach_subtree struct subtree   it
 

Definition at line 502 of file agent_registry.c.

Referenced by register_mib_reattach().

00502                                                   {
00503   struct register_parameters reg_parms;
00504 
00505   if (it->namelen > 1) {
00506       /* only do registrations that are not the top level nodes */
00507       /* XXX: do this better */
00508       reg_parms.name = it->name;
00509       reg_parms.namelen = it->namelen;
00510       reg_parms.priority = it->priority;
00511       reg_parms.range_subid  = it->range_subid;
00512       reg_parms.range_ubound = it->range_ubound;
00513       reg_parms.timeout = it->timeout;
00514       reg_parms.flags = it->flags;
00515       snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_REGISTER_OID,
00516                           &reg_parms);
00517   }
00518   
00519   if (it->children)
00520       register_mib_reattach_subtree(it->children);
00521   if (it->next)
00522       register_mib_reattach_subtree(it->next);
00523 }

int register_mib_table_row const char *    moduleName,
struct variable   var,
size_t    varsize,
size_t    numvars,
oid *    mibloc,
size_t    mibloclen,
int    priority,
int    var_subid,
struct snmp_session *    ss,
const char *    context,
int    timeout,
int    flags
 

Definition at line 578 of file agent_registry.c.

00590 {
00591   struct subtree *subtree;
00592   struct register_parameters reg_parms;
00593   int rc, x;
00594   u_char *v;
00595 
00596   for(x = 0; x < numvars; x++) {
00597 
00598     /* 
00599      * allocate a subtree for the mib registration
00600      */
00601     subtree = (struct subtree *) malloc(sizeof(struct subtree));
00602     if (subtree == NULL) {
00603       unregister_mib_context(mibloc, mibloclen, priority, 
00604                              var_subid, numvars, context);
00605       return MIB_REGISTRATION_FAILED;
00606     }
00607 
00608     /* 
00609      * fill in subtree
00610      */
00611     memcpy(subtree->name, mibloc, mibloclen*sizeof(oid));
00612     subtree->name[var_subid - 1] += x;
00613     subtree->namelen = (u_char) mibloclen;
00614 
00615     memcpy(subtree->start, mibloc, mibloclen*sizeof(oid));
00616     subtree->start[var_subid - 1] += x;
00617     subtree->start_len = (u_char) mibloclen;
00618 
00619     memcpy(subtree->end, mibloc, mibloclen*sizeof(oid));
00620     subtree->end[var_subid - 1] += x;
00621     subtree->end[mibloclen - 1]++;
00622     subtree->end_len = (u_char) mibloclen;
00623 
00624     memcpy(subtree->label, moduleName, strlen(moduleName)+1);
00625 
00626     if (var) {
00627       v = (u_char *)var + (x*varsize);
00628       subtree->variables = (struct variable *) malloc(varsize);
00629       memcpy(subtree->variables, v, varsize);
00630       subtree->variables_len = 1;
00631       subtree->variables_width = varsize;
00632     }
00633 
00634     subtree->priority = priority;
00635     subtree->timeout  = timeout;
00636     subtree->session = ss;
00637     subtree->flags = (u_char)flags;
00638     subtree->cacheid = -1;
00639 
00640     /*  Since we're not really making use of this in the normal way:  */
00641 
00642     subtree->range_subid = 0;
00643     subtree->range_ubound = 0;
00644 
00645     /*
00646      * load the subtree
00647      */
00648     rc = load_subtree(subtree, context);
00649     if ((rc != MIB_REGISTERED_OK)) {
00650       unregister_mib_context(mibloc, mibloclen, priority, 
00651                              var_subid, numvars, context);
00652       return rc;
00653     }
00654   }
00655 
00656   /*
00657    * fill out registration parameters
00658    */
00659   reg_parms.name = mibloc;
00660   reg_parms.namelen = mibloclen;
00661   reg_parms.priority = priority;
00662   reg_parms.flags = (u_char)flags;
00663   reg_parms.range_subid  = var_subid;
00664   reg_parms.range_ubound = (mibloc[var_subid-1] + numvars - 1);
00665   reg_parms.timeout = timeout;
00666   rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, 1, &reg_parms);
00667   return rc;
00668 }

int register_readfd int    fd,
void(*    func)(int, void *),
void *    data
 

Definition at line 1069 of file agent_registry.c.

01069                                                                    {
01070     if (external_readfdlen < NUM_EXTERNAL_FDS) {
01071         external_readfd[external_readfdlen] = fd;
01072         external_readfdfunc[external_readfdlen] = func;
01073         external_readfd_data[external_readfdlen] = data;
01074         external_readfdlen++;
01075         DEBUGMSGTL(("register_readfd", "registered fd %d\n", fd));
01076         return FD_REGISTERED_OK;
01077     } else {
01078         snmp_log(LOG_CRIT, "register_readfd: too many file descriptors\n");
01079         return FD_REGISTRATION_FAILED;
01080     }
01081 }

int register_signal int    sig,
void(*    func)(int)
 

Definition at line 1184 of file agent_registry.c.

01185 {
01186 
01187     switch (sig) {
01188 #if defined(SIGCHLD)
01189     case SIGCHLD:
01190 #ifdef HAVE_SIGACTION
01191         {
01192                 static struct sigaction act;
01193                 act.sa_handler = agent_SIGCHLD_handler;
01194                 sigemptyset(&act.sa_mask);
01195                 act.sa_flags = 0;
01196                 sigaction(SIGCHLD, &act, NULL);
01197         }
01198 #else
01199         signal(SIGCHLD, agent_SIGCHLD_handler);
01200 #endif
01201         break;
01202 #endif
01203     default:
01204         snmp_log(LOG_CRIT,
01205                  "register_signal: signal %d cannot be handled\n", sig);
01206         return SIG_REGISTRATION_FAILED;
01207     }
01208 
01209     external_signal_handler[sig] = func;
01210     external_signal_scheduled[sig] = 0;
01211     
01212     DEBUGMSGTL(("register_signal", "registered signal %d\n", sig));
01213     return SIG_REGISTERED_OK;
01214 }

int register_writefd int    fd,
void(*    func)(int, void *),
void *    data
 

Definition at line 1083 of file agent_registry.c.

01083                                                                     {
01084     if (external_writefdlen < NUM_EXTERNAL_FDS) {
01085         external_writefd[external_writefdlen] = fd;
01086         external_writefdfunc[external_writefdlen] = func;
01087         external_writefd_data[external_writefdlen] = data;
01088         external_writefdlen++;
01089         DEBUGMSGTL(("register_writefd", "registered fd %d\n", fd));
01090         return FD_REGISTERED_OK;
01091     } else {
01092         snmp_log(LOG_CRIT, "register_writefd: too many file descriptors\n");
01093         return FD_REGISTRATION_FAILED;
01094     }
01095 }

struct subtree* replace_first_subtree struct subtree   new_tree,
const char *    context_name
 

Definition at line 107 of file agent_registry.c.

Referenced by load_subtree().

00107                                                                           {
00108     subtree_context_cache *ptr;
00109     if (!context_name)
00110         context_name = "";
00111     for(ptr = context_subtrees; ptr; ptr = ptr->next) {
00112         if (strcmp(ptr->context_name, context_name) == 0) {
00113             ptr->first_subtree = new_tree;
00114             return ptr->first_subtree;
00115         }
00116     }
00117     return add_subtree(new_tree, context_name);
00118 }

void setup_tree void   
 

Definition at line 1006 of file agent_registry.c.

Referenced by init_agent().

01007 {
01008 #ifdef USING_AGENTX_SUBAGENT_MODULE
01009   int role;
01010 
01011   role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE);
01012   ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
01013 #endif
01014 
01015   register_null(root_subtrees[0].name,  root_subtrees[0].namelen);
01016   register_null(root_subtrees[1].name,  root_subtrees[1].namelen);
01017   register_null(root_subtrees[2].name,  root_subtrees[2].namelen);
01018   
01019   /* Support for 'static' subtrees (subtrees_old) has now been dropped */
01020 
01021   /* No longer necessary to sort the mib tree - this is inherent in
01022      the construction of the subtree structure */
01023 
01024 #ifdef USING_AGENTX_SUBAGENT_MODULE
01025   ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);
01026 #endif
01027 }

struct subtree* split_subtree struct subtree   current,
oid    name[],
int    name_len
 

Definition at line 134 of file agent_registry.c.

Referenced by load_subtree().

00135 {
00136     struct subtree *new_sub, *ptr;
00137     int i;
00138     char *cp;
00139 
00140     if ( snmp_oid_compare(name, name_len,
00141                           current->end, current->end_len) > 0 )
00142         return NULL;    /* Split comes after the end of this subtree */
00143 
00144     new_sub = (struct subtree *)malloc(sizeof(struct subtree));
00145     if ( new_sub == NULL )
00146         return NULL;
00147     memcpy(new_sub, current, sizeof(struct subtree));
00148 
00149         /* Set up the point of division */
00150     memcpy(current->end,   name, name_len*sizeof(oid));
00151     memcpy(new_sub->start, name, name_len*sizeof(oid));
00152     current->end_len   = name_len;
00153     new_sub->start_len = name_len;
00154 
00155         /*
00156          * Split the variables between the two new subtrees
00157          */
00158     i = current->variables_len;
00159     current->variables_len = 0;
00160 
00161     for ( ; i > 0 ; i-- ) {
00162                 /* Note that the variable "name" field omits
00163                    the prefix common to the whole registration,
00164                    hence the strange comparison here */
00165         if ( snmp_oid_compare( new_sub->variables[0].name,
00166                                new_sub->variables[0].namelen,
00167                                name     + current->namelen, 
00168                                name_len - current->namelen ) >= 0 )
00169             break;      /* All following variables belong to the second subtree */
00170 
00171         current->variables_len++;
00172         new_sub->variables_len--;
00173         cp = (char *)new_sub->variables;
00174         new_sub->variables = (struct variable *)(cp + new_sub->variables_width);
00175     }
00176 
00177         /* Delegated trees should retain their variables regardless */
00178     if ( current->variables_len > 0 &&
00179                 IS_DELEGATED((u_char)current->variables[0].type)) {
00180         new_sub->variables_len = 1;
00181         new_sub->variables     = current->variables;
00182     }
00183 
00184         /* Propogate this split down through any children */
00185     if ( current->children )
00186         new_sub->children = split_subtree(current->children, name, name_len);
00187 
00188         /* Retain the correct linking of the list */
00189     for ( ptr = current ; ptr != NULL ; ptr=ptr->children )
00190           ptr->next = new_sub;
00191     for ( ptr = new_sub ; ptr != NULL ; ptr=ptr->children )
00192           ptr->prev = current;
00193     for ( ptr = new_sub->next ; ptr != NULL ; ptr=ptr->children )
00194           ptr->prev = new_sub;
00195 
00196     /* retain original APIv2 registration information */
00197     new_sub->reginfo = current->reginfo;
00198 
00199     return new_sub;
00200 }

int tree_compare const struct subtree   ap,
const struct subtree   bp
 

Definition at line 122 of file agent_registry.c.

00123 {
00124   return snmp_oid_compare(ap->name,ap->namelen,bp->name,bp->namelen);
00125 }

void unload_subtree struct subtree   sub,
struct subtree   prev
 

Definition at line 671 of file agent_registry.c.

Referenced by unregister_mib_context(), and unregister_mibs_by_session().

00672 {
00673     struct subtree *ptr;
00674 
00675     if ( prev != NULL ) {       /* non-leading entries are easy */
00676         prev->children = sub->children;
00677         return;
00678     }
00679                         /* otherwise, we need to amend our neighbours as well */
00680 
00681     if ( sub->children == NULL) {       /* just remove this node completely */
00682         for (ptr = sub->prev ; ptr ; ptr=ptr->children )
00683             ptr->next = sub->next;
00684         for (ptr = sub->next ; ptr ; ptr=ptr->children )
00685             ptr->prev = sub->prev;
00686         return;
00687     }
00688     else {
00689         for (ptr = sub->prev ; ptr ; ptr=ptr->children )
00690             ptr->next = sub->children;
00691         for (ptr = sub->next ; ptr ; ptr=ptr->children )
00692             ptr->prev = sub->children;
00693         return;
00694     }
00695 }

int unregister_exceptfd int    fd
 

Definition at line 1145 of file agent_registry.c.

01145                                 {
01146     int i, j;
01147 
01148     for (i = 0; i < external_exceptfdlen; i++) {
01149         if (external_exceptfd[i] == fd) {
01150             external_exceptfdlen--;
01151             for (j = i; j < external_exceptfdlen; j++) {
01152                 external_exceptfd[j] = external_exceptfd[j+1];
01153                 external_exceptfd_data[j] = external_exceptfd_data[j+1];
01154             }
01155             DEBUGMSGTL(("unregister_exceptfd", "unregistered fd %d\n", fd));
01156             return FD_UNREGISTERED_OK;
01157         }
01158     }
01159     return FD_NO_SUCH_REGISTRATION;
01160 }

int unregister_mib oid *    name,
size_t    len
 

Definition at line 774 of file agent_registry.c.

00776 {
00777   return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );
00778 }

int unregister_mib_context oid *    name,
size_t    len,
int    priority,
int    range_subid,
oid    range_ubound,
const char *    context
 

Definition at line 698 of file agent_registry.c.

00700 {
00701   struct subtree *list, *myptr;
00702   struct subtree *prev, *child;             /* loop through children */
00703   struct register_parameters reg_parms;
00704 
00705   list = find_subtree( name, len, find_first_subtree(context), context );
00706   if ( list == NULL )
00707         return MIB_NO_SUCH_REGISTRATION;
00708 
00709   for ( child=list, prev=NULL;  child != NULL;
00710                                 prev=child, child=child->children ) {
00711       if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 )
00712           && ( child->priority == priority ))
00713                 break;  /* found it */
00714   }
00715   if ( child == NULL )
00716         return MIB_NO_SUCH_REGISTRATION;
00717 
00718   unload_subtree( child, prev );
00719   myptr = child;        /* remember this for later */
00720 
00721                 /*
00722                  *  Now handle any occurances in the following subtrees,
00723                  *      as a result of splitting this range.  Due to the
00724                  *      nature of the way such splits work, the first
00725                  *      subtree 'slice' that doesn't refer to the given
00726                  *      name marks the end of the original region.
00727                  *
00728                  *  This should also serve to register ranges.
00729                  */
00730 
00731   for ( list = myptr->next ; list != NULL ; list=list->next ) {
00732         for ( child=list, prev=NULL;  child != NULL;
00733                                       prev=child, child=child->children ) {
00734             if (( snmp_oid_compare( child->name, child->namelen,
00735                                                         name, len) == 0 )
00736                 && ( child->priority == priority )) {
00737 
00738                     unload_subtree( child, prev );
00739                     free_subtree( child );
00740                     break;
00741             }
00742         }
00743         if ( child == NULL )    /* Didn't find the given name */
00744             break;
00745   }
00746   free_subtree( myptr );
00747   
00748   reg_parms.name = name;
00749   reg_parms.namelen = len;
00750   reg_parms.priority = priority;
00751   reg_parms.range_subid  = range_subid;
00752   reg_parms.range_ubound = range_ubound;
00753   reg_parms.flags = 0x00;  /*  this is okay I think  */
00754   snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREGISTER_OID,
00755                       &reg_parms);
00756 
00757   return MIB_UNREGISTERED_OK;
00758 }

int unregister_mib_priority oid *    name,
size_t    len,
int    priority
 

Definition at line 768 of file agent_registry.c.

00769 {
00770   return unregister_mib_range( name, len, priority, 0, 0 );
00771 }

int unregister_mib_range oid *    name,
size_t    len,
int    priority,
int    range_subid,
oid    range_ubound
 

Definition at line 761 of file agent_registry.c.

00763 {
00764   return unregister_mib_context( name, len, priority, range_subid, range_ubound, "" );
00765 }

void unregister_mibs_by_session struct snmp_session *    ss
 

Definition at line 781 of file agent_registry.c.

00782 {
00783   struct subtree *list, *list2;
00784   struct subtree *child, *prev, *next_child;
00785 
00786   for( list = (find_first_subtree(ss->contextName)); list != NULL;
00787        list = list2) {
00788     list2 = list->next;
00789     for ( child=list, prev=NULL;  child != NULL; child=next_child ) {
00790 
00791       next_child = child->children;
00792       if (( (ss->flags & SNMP_FLAGS_SUBSESSION) && child->session == ss ) ||
00793           (!(ss->flags & SNMP_FLAGS_SUBSESSION) && child->session &&
00794                                       child->session->subsession == ss )) {
00795               unload_subtree( child, prev );
00796               free_subtree( child );
00797       }
00798       else
00799           prev = child;
00800     }
00801   }
00802 }

int unregister_readfd int    fd
 

Definition at line 1111 of file agent_registry.c.

01111                               {
01112     int i, j;
01113 
01114     for (i = 0; i < external_readfdlen; i++) {
01115         if (external_readfd[i] == fd) {
01116             external_readfdlen--;
01117             for (j = i; j < external_readfdlen; j++) {
01118                 external_readfd[j] = external_readfd[j+1];
01119                 external_readfd_data[j] = external_readfd_data[j+1];
01120             }
01121             DEBUGMSGTL(("unregister_readfd", "unregistered fd %d\n", fd));
01122             return FD_UNREGISTERED_OK;
01123         }
01124     }
01125     return FD_NO_SUCH_REGISTRATION;
01126 }

int unregister_signal int    sig
 

Definition at line 1216 of file agent_registry.c.

01216                                {
01217     signal(sig, SIG_DFL);
01218     DEBUGMSGTL(("unregister_signal", "unregistered signal %d\n", sig));
01219     return SIG_UNREGISTERED_OK;
01220 }

int unregister_writefd int    fd
 

Definition at line 1128 of file agent_registry.c.

01128                                {
01129     int i, j;
01130 
01131     for (i = 0; i < external_writefdlen; i++) {
01132         if (external_writefd[i] == fd) {
01133             external_writefdlen--;
01134             for (j = i; j < external_writefdlen; j++) {
01135                 external_writefd[j] = external_writefd[j+1];
01136                 external_writefd_data[j] = external_writefd_data[j+1];
01137             }
01138             DEBUGMSGTL(("unregister_writefd", "unregistered fd %d\n", fd));
01139             return FD_UNREGISTERED_OK;
01140         }
01141     }
01142     return FD_NO_SUCH_REGISTRATION;
01143 }

Variable Documentation

subtree_context_cache* context_subtrees = NULL
 

Definition at line 67 of file agent_registry.c.

int external_exceptfd[NUM_EXTERNAL_FDS]
 

Definition at line 1061 of file agent_registry.c.

void* external_exceptfd_data[NUM_EXTERNAL_FDS]
 

Definition at line 1067 of file agent_registry.c.

void(* external_exceptfdfunc[NUM_EXTERNAL_FDS])(int, void *)
 

Definition at line 1064 of file agent_registry.c.

int external_exceptfdlen = 0
 

Definition at line 1061 of file agent_registry.c.

int external_readfd[NUM_EXTERNAL_FDS]
 

Definition at line 1059 of file agent_registry.c.

void* external_readfd_data[NUM_EXTERNAL_FDS]
 

Definition at line 1065 of file agent_registry.c.

void(* external_readfdfunc[NUM_EXTERNAL_FDS])(int, void *)
 

Definition at line 1062 of file agent_registry.c.

int external_readfdlen = 0
 

Definition at line 1059 of file agent_registry.c.

void(* external_signal_handler[NUM_EXTERNAL_SIGS])(int)
 

Definition at line 1163 of file agent_registry.c.

int external_signal_scheduled[NUM_EXTERNAL_SIGS]
 

Definition at line 1162 of file agent_registry.c.

int external_writefd[NUM_EXTERNAL_FDS]
 

Definition at line 1060 of file agent_registry.c.

void* external_writefd_data[NUM_EXTERNAL_FDS]
 

Definition at line 1066 of file agent_registry.c.

void(* external_writefdfunc[NUM_EXTERNAL_FDS])(int, void *)
 

Definition at line 1063 of file agent_registry.c.

int external_writefdlen = 0
 

Definition at line 1060 of file agent_registry.c.


Generated on Sat Nov 10 14:09:54 2001 for net-snmp by doxygen1.2.11 written by Dimitri van Heesch, © 1997-2001
[an error occurred while processing this directive] [an error occurred while processing this directive]

Valid CSS!


Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.