| 
 |  | 
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 ``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; }
SMUX__PDUs_registerResponse SMUX__PDUs_get__request SMUX__PDUs_get__next__request SMUX__PDUs_set__request SMUX__PDUs_commitOrRollback SMUX__PDUs_closeThe actual code is fairly straightforward:
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;
}
free_SNMP_SMUX_PDU(event);
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:
trap_coldStart trap_warmStart trap_linkDown trap_linkUp trap_authenticationFailure trap_egpNeighborLoss trap_enterpriseSpecificIf this routine fails, smux_errno will be set to one of invalidOperation, congestion, or youLoseBig.