| 
 |  | 
When xselect indicates the SMUX file descriptor is ready for reading, the peer program calls the routine smux_wait to return the next event from the SNMP agent.
The event is filled-in from a static area. On the next call to smux_init, smux_close, or smux_wait, the value is overwritten.
On failure, smux_errno will be set to one of parameterMissing, invalidOperation, inProgress, or youLoseBig. See the section ``Error recovery'' for an explanation of these error codes. The peer program takes the appropriate action based on the error code returned.
struct type_SNMP_SMUX__PDUs *event;Next, the peer program switches based on the actual event returned:if (smux_wait(&event, NOTOK) == NOTOK) { if (smux_errno == inProgress) return;
LIB_ERROR2("smux_wait: %s [%s]", smux_error(smux_errno), smux_info); smux_fd = NOTOK; return; }
The actual code is fairly straightforward:SMUX__PDUs_registerResponse SMUX__PDUs_get__request SMUX__PDUs_get__next__request SMUX__PDUs_set__request SMUX__PDUs_commitOrRollback SMUX__PDUs_close
   switch (event->offset) {
   case SMUX__PDUs_registerResponse:
       if (!tc->t_name)
           goto unexpected;
       {
           struct type_SNMP_RRspPDU *rsp = event->un.registerResponse;
   
           if (rsp->parm == RRspPDU_failure)
               LIB_ERROR1("SMUX registration of %s failed\n", tc->t_tree);
           else {
               if (debug)
                   printf("SMUX register: %s out=%d\n", tc->t_tree, rsp->parm);
               got_at_least_one = 1;
           }
       }
       for (tc++; tc->t_tree; tc++)
           if (tc->t_name) {
               if (smux_register(tc->t_name, -1, tc->t_access)
                   == NOTOK) {
                   LIB_ERROR2("smux_register: %s [%s]\n",
                    smux_error(smux_errno), smux_info);
                   goto losing;
               }
               if (debug)
                   printf("SMUX register: %s in=%d\n", tc->t_tree, -1);
               break;
           }
       if (!tc->t_tree) {
           if (!got_at_least_one) {
               dont_bother_anymore = 1;
               (void) smux_close(goingDown);
               goto losing;
           }
           if (smux_trap(trap_coldStart, 0,
                (struct type_SNMP_VarBindList *) 0) == NOTOK) {
               LIB_ERROR2("smux_trap: %s [%s]", smux_error(smux_errno),
                      smux_info);
               goto losing;
           }
       }
       break;
   
   case SMUX__PDUs_get__request:
   case SMUX__PDUs_get__next__request:
   case SMUX__PDUs_set__request:
       do_smux(event->un.get__request, event->offset);
       break;
   
   case SMUX__PDUs_commitOrRollback:
       {
           register struct triple *tz;
   
           for (tz = triples; tz->t_tree; tz++)
               if (tz->t_name)
                   (void) (*tz->t_sync) (event->un.commitOrRollback->parm);
       }
       break;
   
   case SMUX__PDUs_close:
       if (debug)
           printf("SMUX close: %s\n", smux_error(event->un.close->parm));
       goto losing;
   
   case SMUX__PDUs_simple:
   case SMUX__PDUs_registerRequest:
   case SMUX__PDUs_get__response:
   case SMUX__PDUs_trap:
   unexpected:    ;
       LIB_ERROR1("unexpectedOperation: %d", event->offset);
       (void) smux_close(protocolError);
       goto losing;
   
   default:
       LIB_ERROR1("badOperation: %d", event->offset);
       (void) smux_close(protocolError);
       goto losing;
   }
Note the use of the smux_trap routine
to send a coldStart trap
once the peer has successfully registered the
MIB module it will be managing.
The trap codes are:
If this routine fails, smux_errno will be set to one of invalidOperation, congestion, or youLoseBig.trap_coldStart trap_warmStart trap_linkDown trap_linkUp trap_authenticationFailure trap_egpNeighborLoss trap_enterpriseSpecific