#!/bin/sh # This is `snmp2.34' (part 34 of snmp2). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `snmp2/agent/context_vars.c' is being continued... # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 34; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping snmp2/agent/context_vars.c' else echo 'x - continuing file snmp2/agent/context_vars.c' sed 's/^X//' << 'SHAR_EOF' >> 'snmp2/agent/context_vars.c' && X struct contextEntry *cp, *lowcp = NULL; X u_long mask; X struct timeval now; /* X * This routine handles requests for variables of the form: X X * .iso.org.dod.internet.snmpV2.snmpModules.partyMIB.partyMIBObjects X * .snmpContexts.contextTable.contextEntry.X.oid X * or .1.3.6.1.6.3.3.2.2.1.1.X.oid, where the oid suffix is X * variable length X * Therefore, the index starts at name[12]. X */ X X mask = 1 << (vp->magic - 1); X bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid)); X if (exact){ X if (*length < 13 || X bcmp((char *)name, (char *)vp->name, 11 * sizeof(oid))) X return NULL; X *write_method = write_context; X cp = context_getEntry(name + 12, *length - 12); X if (cp == NULL) X return NULL; X if (!(cp->contextBitMask & mask)) X return NULL; X } else { X /* find "next" control entry */ X context_scanInit(); X for(cp = context_scanNext(); cp; cp = context_scanNext()){ X if (!(cp->contextBitMask & mask)) X continue; X bcopy((char *)cp->contextIdentity, (char *)(newname + 12), X cp->contextIdentityLen * sizeof(oid)); X newnamelen = 12 + cp->contextIdentityLen; X if ((compare(newname, newnamelen, name, *length) > 0) && X (!lowcp || compare(newname, newnamelen, X lowname, lownamelen) < 0)){ X /* X * if new one is greater than input and closer to input than X * previous lowest, save this one as the "next" one. X */ X bcopy((char *)newname, (char *)lowname, newnamelen * sizeof(oid)); X lownamelen = newnamelen; X lowcp = cp; X } X } X if (lowcp == NULL) X return NULL; X cp = lowcp; X bcopy((char *)lowname, (char *)name, lownamelen * sizeof(oid)); X *length = lownamelen; X } X X *var_len = sizeof(long); X long_return = 0; X X switch (vp->magic){ X case CONTEXTINDEX: X return (u_char *)&cp->contextIndex; X case CONTEXTLOCAL: X return (u_char *)&cp->contextLocal; X case CONTEXTVIEWINDEX: X return (u_char *)&cp->contextViewIndex; X case CONTEXTLOCALENTITY: X *var_len = cp->contextLocalEntityLen; X return (u_char *)cp->contextLocalEntity; X case CONTEXTLOCALTIME: X if (cp->contextLocalTime == CURRENTTIME){ X *var_len = sizeof(currentTime); X return (u_char *)currentTime; X } else if (cp->contextLocalTime == RESTARTTIME){ X *var_len = sizeof(restartTime); X return (u_char *)restartTime; X } else { X ERROR(""); X return NULL; X } X case CONTEXTDSTPARTYINDEX: X *var_len = 8; X bzero(return_buf, 8); X return (u_char *)return_buf; X case CONTEXTSRCPARTYINDEX: X *var_len = 8; X bzero(return_buf, 8); X return (u_char *)return_buf; X case CONTEXTPROXYCONTEXT: X *var_len = cp->contextProxyContextLen * sizeof(oid); X return (u_char *)cp->contextProxyContext; X case CONTEXTSTORAGETYPE: X return (u_char *)&cp->contextStorageType; X case CONTEXTSTATUS: X if (cp->contextStatus == CONTEXTNOTINSERVICE X && cp->contextBitMask != CONTEXTCOMPLETE_MASK){ X long_return = CONTEXTNOTREADY; X return (u_char *)&long_return; X } X return (u_char *)&cp->contextStatus; X default: X ERROR(""); X } X return NULL; } SHAR_EOF echo 'File snmp2/agent/context_vars.c is complete' && $shar_touch -am 1015123693 'snmp2/agent/context_vars.c' && chmod 0644 'snmp2/agent/context_vars.c' || echo 'restore of snmp2/agent/context_vars.c failed' shar_count="`wc -c < 'snmp2/agent/context_vars.c'`" test 21165 -eq "$shar_count" || echo "snmp2/agent/context_vars.c: original size 21165, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/agent/event.c ============== if test -f 'snmp2/agent/event.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/agent/event.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/agent/event.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/agent/event.c' && /*********************************************************** X Copyright 1992 by Carnegie Mellon University X X All Rights Reserved X X Permission to use, copy, modify, and distribute this software and its X documentation for any purpose and without fee is hereby granted, X provided that the above copyright notice appear in all copies and that X both that copyright notice and this permission notice appear in X supporting documentation, and that the name of CMU not be X used in advertising or publicity pertaining to distribution of the X software without specific, written prior permission. X X CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL X CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR X ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X SOFTWARE. X ******************************************************************/ X /* event.c: implement the event group of the RMON MIB */ X #include #ifdef VXWORKS #include #else #include #endif #include #include #ifdef VXWORKS #include "VXtime.h" #else #include #include #include #endif #include #include #include #include "snmp_vars.h" #include "m2m.h" #include "snmp_vars_m2m.h" #include "alarm.h" #include "event.h" #include "snmp_api.h" #include "party.h" #include "snmp_client.h" X static struct eventEntry *eventTab = NULL; static struct eventNotifyEntry *eventNotifyTab = NULL; static long eventNextIndex = 1; X #define MIN_INTERVAL 1 /* one second */ #define MAX_RETRANSMISSIONS 20 X /* hint for var_eventlogtab() */ static struct eventEntry *eventHint = NULL; static struct eventNotifyEntry *eventNotifyHint = NULL; X void time_subtract(result, t1, t2) X struct timeval *result, *t1, *t2; { X result->tv_usec = t1->tv_usec - t2->tv_usec; X result->tv_sec = t1->tv_sec - t2->tv_sec; X while (result->tv_usec < 0L) { X (result->tv_usec) += 1000000L; X (result->tv_sec)--; X } } X /* insert the given row into the event table, ordered by index */ static void eventInsertRow(event) X struct eventEntry *event; { X struct eventEntry *current; X struct eventEntry *prev; X X for (current = eventTab, prev = NULL; current; current = current->next) { X if (current->index > event->index) { X break; X } X prev = current; X } X X /* put the new entry before "current" */ X event->next = current; X if (prev) { X prev->next = event; X } X else { X /* this is first on the list */ X eventTab = event; X } } X /* insert the given row into the event table, ordered by index */ static void eventNotifyInsertRow(event) X struct eventNotifyEntry *event; { X struct eventNotifyEntry *current; X struct eventNotifyEntry *prev; X X for (current = eventNotifyTab, prev = NULL; current; X current = current->next) { X if (current->index > event->index) { X break; X } X prev = current; X } X X /* put the new entry before "current" */ X event->next = current; X if (prev) { X prev->next = event; X } X else { X /* this is first on the list */ X eventNotifyTab = event; X } } X /* free the shadow space that was allocated to this row */ static void eventFreeShadow(event) X struct eventEntry *event; { X if (event->shadow == NULL) { X return; X } X X free((char *)event->shadow); X event->shadow = NULL; } X /* free the shadow space that was allocated to this row */ static void eventNotifyFreeShadow(event) X struct eventNotifyEntry *event; { X if (event->shadow == NULL) { X return; X } X X free((char *)event->shadow); X event->shadow = NULL; } X /* delete the given row from the event table, and free the memory X ** associated with it. X */ static void eventDeleteRow(event) X struct eventEntry *event; { X struct eventEntry *temp; X struct eventEntry *prev = NULL; X X for (temp = eventTab; temp; temp = temp->next) { X if (temp == event) { X /* this is the one to remove */ X if (prev) { X prev->next = temp->next; X } X else { X /* this is the first on the list */ X eventTab = temp->next; X } X break; X } X prev = temp; X } X X /* KLF debugging */ X if (temp == NULL) { X printf("eventDeleteRow: didn't find row (%d) in eventTab\n", X event->index); X } X X eventFreeShadow(event); X eventHint = NULL; /* invalidate the hint */ X free((char *)event); } X /* delete the given row from the event table, and free the memory X ** associated with it. X */ static void eventNotifyDeleteRow(event) X struct eventNotifyEntry *event; { X struct eventNotifyEntry *temp; X struct eventNotifyEntry *prev = NULL; X X for (temp = eventNotifyTab; temp; temp = temp->next) { X if (temp == event) { X /* this is the one to remove */ X if (prev) { X prev->next = temp->next; X } X else { X /* this is the first on the list */ X eventNotifyTab = temp->next; X } X break; X } X prev = temp; X } X X /* KLF debugging */ X if (temp == NULL) { X printf("eventNotifyDeleteRow: didn't find row (%d) in eventNotifyTab\n", X event->index); X } X X eventNotifyFreeShadow(event); X eventNotifyHint = NULL; /* invalidate the hint */ X free((char *)event); } X /* create a shadow structure for the given row, and copy the world-visible X ** data into the shadow structure. Returns 1 on success, 0 otherwise. X */ static int eventShadowRow(event) X struct eventEntry *event; { X int i = 0; X X if (event->shadow != NULL) { X /* it's already been created */ X return 1; X } X X event->shadow = (struct eventEntry *)malloc(sizeof(struct eventEntry)); X while ((event->shadow == NULL) && (i++ < 5)) { X eventFreeSpace(); X event->shadow = (struct eventEntry *)malloc(sizeof(struct eventEntry)); X } X if (event->shadow == NULL) { X /* no more memory */ X return 0; X } X X bcopy((char *)event, (char *)event->shadow, sizeof(struct eventEntry)); X X return 1; } X /* create a shadow structure for the given row, and copy the world-visible X ** data into the shadow structure. Returns 1 on success, 0 otherwise. X */ static int eventNotifyShadowRow(event) X struct eventNotifyEntry *event; { X int i = 0; X X if (event->shadow != NULL) { X /* it's already been created */ X return 1; X } X X event->shadow = (struct eventNotifyEntry *)malloc(sizeof(struct eventNotifyEntry)); X while ((event->shadow == NULL) && (i++ < 5)) { X eventFreeSpace(); X event->shadow = (struct eventNotifyEntry *)malloc(sizeof(struct eventNotifyEntry)); X } X if (event->shadow == NULL) { X /* no more memory */ X return 0; X } X X bcopy((char *)event, (char *)event->shadow, sizeof(struct eventNotifyEntry)); X X return 1; } X /* return a pointer to the given row in eventTab */ static struct eventEntry * eventGetRow(index) X int index; { X struct eventEntry *event; X X for (event = eventTab; event; event = event->next) { X if (event->index == index) { X return event; X } X } X X return NULL; } X /* create a new row for the event table, with the given index. X ** Create a shadow for the row. Put default values into the shadow. X ** Return a pointer to the new row. This routine does not check that X ** the index has not already been used, and does not make the row X ** visible to a management station that is doing a walk of the table. X ** It makes sure the index is in the valid range. X */ static struct eventEntry * eventNewRow(index) X int index; { X struct eventEntry *event; X int i = 0; X X if ((index < 1) || (index > 65535)) { X return NULL; X } X X event = (struct eventEntry *)malloc(sizeof(struct eventEntry)); X while ((event == NULL) && (i++ < 5)) { X eventFreeSpace(); X event = (struct eventEntry *)malloc(sizeof(struct eventEntry)); X } X if (event == NULL) { X /* no more room */ X return NULL; X } X X bzero((char *)event, sizeof(struct eventEntry)); X X event->index = index; X event->status = ENTRY_DESTROY; X X event->bitmask = EVENTTABINDEXMASK; X X eventInsertRow(event); X X /* this will copy the index, status, and bitmask into the shadow area */ X if (eventShadowRow(event) == 0) { X /* weren't able to allocate space for the shadow area, so X ** remove the entry from the list. X */ X eventDeleteRow(event); X return NULL; X } X X /* add default entries to the shadow copy. The only variable that X ** isn't defaulted is owner. X */ X event->shadow->status = ENTRY_NOTINSERVICE; X /* KLF should I bother to default these? */ X X /* note that this assignment implies that lastTimeSent defaults to zero */ X event->shadow->bitmask |= (EVENTTABSTATUSMASK | X EVENTTABEVENTSMASK | EVENTTABLASTTIMESENTMASK); X X eventNextIndex = random() & 0x0000ffff; X while (eventGetRow(eventNextIndex) != NULL) { X eventNextIndex = random() & 0x0000ffff; X } X return event; } X /* create a new row for the event table, with the given index. X ** Create a shadow for the row. Put default values into the shadow. X ** Return a pointer to the new row. This routine does not check that X ** the index has not already been used, and does not make the row X ** visible to a management station that is doing a walk of the table. X ** It makes sure the index is in the valid range. X */ static struct eventNotifyEntry * eventNotifyNewRow(index, context, contextLen) X int index; X oid *context; X int contextLen; { X struct eventNotifyEntry *event; X int i = 0; X X if ((index < 1) || (index > 65535)) { X return NULL; X } X X event = (struct eventNotifyEntry *)malloc(sizeof(struct eventNotifyEntry)); X while ((event == NULL) && (i++ < 5)) { X eventNotifyFreeSpace(); X event = (struct eventNotifyEntry *)malloc(sizeof(struct eventNotifyEntry)); X } X if (event == NULL) { X /* no more room */ X return NULL; X } X X bzero((char *)event, sizeof(struct eventNotifyEntry)); X X event->index = index; X event->contextLen = contextLen; X bcopy(context, event->context, contextLen * sizeof(oid)); X event->status = ENTRY_DESTROY; X event->interval = 30; X event->retransmissions = 5; X event->lifetime = 86400; X X eventNotifyInsertRow(event); X X /* this will copy the index, status, and bitmask into the shadow area */ X if (eventNotifyShadowRow(event) == 0) { X /* weren't able to allocate space for the shadow area, so X ** remove the entry from the list. X */ X eventNotifyDeleteRow(event); X return NULL; X } X X /* add default entries to the shadow copy. The only variable that X ** isn't defaulted is owner. X */ X event->shadow->status = ENTRY_NOTINSERVICE; X /* KLF should I bother to default these? */ X X /* note that this assignment implies that lastTimeSent defaults to zero */ X event->shadow->bitmask |= (EVENTNOTIFYTABSTATUSMASK X | EVENTNOTIFYTABINTERVALMASK X | EVENTNOTIFYTABLIFETIMEMASK X | EVENTNOTIFYTABRETRANSMISSIONSMASK); X X return event; } X /* return a pointer to the given row in eventTab */ static struct eventNotifyEntry * eventNotifyGetRow(index, context, contextLen) X int index; X oid *context; X int contextLen; { X struct eventNotifyEntry *event; X X for (event = eventNotifyTab; event; event = event->next) { X if (event->index == index && event->contextLen == contextLen X && !bcmp(event->context, context, X contextLen * sizeof(oid))) { X return event; X } X } X X return NULL; } X /* copy the data in the given row from the shadow copy into the world- X ** visible copy, and get rid of the shadow copy. If no shadow copy X ** exists, just return. If we are setting the row to invalid, delete it. X */ static void eventCommitRow(event) X struct eventEntry *event; { X struct eventEntry *nextPtr; X X if (event->shadow == NULL) { X return; X } X X /* if this entry is being set to invalid, just delete it */ X if (event->shadow->status == ENTRY_DESTROY) { X eventDeleteRow(event); X return; X } X X /* save and restore the pointers. This is done because eventFreeSpace() X ** may have been called since the shadow was created. This could X ** have changed any of the event pointers. X */ X nextPtr = event->next; X bcopy((char *)event->shadow, (char *)event, sizeof(struct eventEntry)); X X if (event->next != nextPtr) { X /* KLF debugging */ X printf("eventCommitRow(%d): next pointer was different\n", X event->index); X event->next = nextPtr; X } X X eventFreeShadow(event); } X /* copy the data in the given row from the shadow copy into the world- X ** visible copy, and get rid of the shadow copy. If no shadow copy X ** exists, just return. If we are setting the row to invalid, delete it. X */ static void eventNotifyCommitRow(event) X struct eventNotifyEntry *event; { X struct eventNotifyEntry *nextPtr; X X if (event->shadow == NULL) { X return; X } X X /* if this entry is being set to invalid, just delete it */ X if (event->shadow->status == ENTRY_DESTROY) { X eventNotifyDeleteRow(event); X return; X } X X /* save and restore the pointers. This is done because eventFreeSpace() X ** may have been called since the shadow was created. This could X ** have changed any of the event pointers. X */ X nextPtr = event->next; X bcopy((char *)event->shadow, (char *)event, sizeof(struct eventNotifyEntry)); X X if (event->next != nextPtr) { X /* KLF debugging */ X printf("eventNotifyCommitRow(%d): next pointer was different\n", X event->index); X event->next = nextPtr; X } X X eventNotifyFreeShadow(event); } X /* free some memory that's being used by this module. Called when a X ** routine can't malloc some space. Returns true if successful, and false X ** if not. X */ Export int eventFreeSpace() { X int spaceFreed = FALSE; X X /* nothing */ X return spaceFreed; } X /* free some memory that's being used by this module. Called when a X ** routine can't malloc some space. Returns true if successful, and false X ** if not. X */ Export int eventNotifyFreeSpace() { X int spaceFreed = FALSE; X X /* nothing */ X return spaceFreed; } X X /* add the variables for a objectUnavailableAlarm trap to the ** end of varList. */ eventUnavailFillInVars(varList, alarm) X struct variable_list *varList; X struct alarmEntry *alarm; { X struct variable_list *vp; X X vp = (struct variable_list *)malloc(sizeof(struct variable_list)); X varList->next_variable = vp; X X vp->name = (oid *)malloc(alarmVariableOidLen * sizeof(oid)); X bcopy(alarmVariableOid, vp->name, alarmVariableOidLen * sizeof(oid)); X vp->name_length = alarmVariableOidLen; X vp->type = ASN_OBJECT_ID; X vp->val_len = alarm->variableLen * sizeof(oid); X vp->val.objid = (oid *)malloc(vp->val_len); X bcopy(alarm->variable, vp->val.objid, vp->val_len); X vp->next_variable = NULL; } X /* add the variables for an alarm trap to the end of varList */ static void eventAlarmFillInVars(varList, alarm, trapType) X struct variable_list *varList; X struct alarmEntry *alarm; X int trapType; { X struct variable_list *aVar; X struct variable_list *prevVar; X X aVar = (struct variable_list *)malloc(sizeof(struct variable_list)); X varList->next_variable = aVar; X X aVar->name = (oid *)malloc((alarmVariableOidLen + alarm->contextLength + 1) * sizeof(oid)); X bcopy(alarmVariableOid, aVar->name, alarmVariableOidLen * sizeof(oid)); X aVar->name[alarmVariableOidLen] = alarm->contextLength; X bcopy(alarm->contextID, aVar->name + alarmVariableOidLen + 1, X alarm->contextLength * sizeof(oid)); X aVar->name_length = alarmVariableOidLen + alarm->contextLength + 1; X aVar->type = ASN_OBJECT_ID; X aVar->val_len = alarm->variableLen * sizeof(oid); X aVar->val.objid = (oid *)malloc(aVar->val_len); X bcopy(alarm->variable, aVar->val.objid, aVar->val_len); X aVar->next_variable = NULL; X prevVar = aVar; X X aVar = (struct variable_list *)malloc(sizeof(struct variable_list)); X prevVar->next_variable = aVar; X X aVar->name = (oid *)malloc((alarmSampleTypeOidLen + alarm->contextLength + 1) * sizeof(oid)); X bcopy(alarmSampleTypeOid, aVar->name, alarmSampleTypeOidLen * sizeof(oid)); X aVar->name[alarmSampleTypeOidLen] = alarm->contextLength; X bcopy(alarm->contextID, aVar->name + alarmSampleTypeOidLen + 1, X alarm->contextLength * sizeof(oid)); X aVar->name_length = alarmSampleTypeOidLen + alarm->contextLength + 1; X aVar->type = ASN_INTEGER; X aVar->val_len = sizeof(alarm->sampleType); X aVar->val.integer = (long *)malloc(sizeof(long)); X bcopy(&alarm->sampleType, aVar->val.integer, sizeof(long)); X aVar->next_variable = NULL; X prevVar = aVar; X X aVar = (struct variable_list *)malloc(sizeof(struct variable_list)); X prevVar->next_variable = aVar; X X aVar->name = (oid *)malloc((alarmValueOidLen + alarm->contextLength + 1) * sizeof(oid)); X bcopy(alarmValueOid, aVar->name, alarmValueOidLen * sizeof(oid)); X aVar->name[alarmValueOidLen] = alarm->contextLength; X bcopy(alarm->contextID, aVar->name + alarmValueOidLen + 1, X alarm->contextLength * sizeof(oid)); X aVar->name_length = alarmValueOidLen + alarm->contextLength + 1; X aVar->type = ASN_INTEGER; X aVar->val_len = sizeof(alarm->value); X aVar->val.integer = (long *)malloc(sizeof(long)); X bcopy(&alarm->value, aVar->val.integer, sizeof(long)); X aVar->next_variable = NULL; X prevVar = aVar; X X aVar = (struct variable_list *)malloc(sizeof(struct variable_list)); X prevVar->next_variable = aVar; X X if (trapType == TRAP_RISING_ALARM) { X aVar->name = (oid *)malloc((alarmRisingThreshOidLen + alarm->contextLength + 1) * sizeof(oid)); X bcopy(alarmRisingThreshOid, aVar->name, X alarmRisingThreshOidLen * sizeof(oid)); X aVar->name[alarmRisingThreshOidLen] = alarm->contextLength; X bcopy(alarm->contextID, aVar->name + alarmRisingThreshOidLen + 1, X alarm->contextLength * sizeof(oid)); X aVar->name_length = alarmRisingThreshOidLen + alarm->contextLength + 1; X aVar->type = ASN_INTEGER; X aVar->val_len = sizeof(alarm->risingThresh); X aVar->val.integer = (long *)malloc(sizeof(long)); X bcopy(&alarm->risingThresh, aVar->val.integer, sizeof(long)); X } X else { X aVar->name = (oid *)malloc((alarmFallingThreshOidLen + alarm->contextLength + 1) * sizeof(oid)); X bcopy(alarmFallingThreshOid, aVar->name, X alarmFallingThreshOidLen * sizeof(oid)); X aVar->name[alarmFallingThreshOidLen] = alarm->contextLength; X bcopy(alarm->contextID, aVar->name + alarmFallingThreshOidLen + 1, X alarm->contextLength * sizeof(oid)); X aVar->name_length = alarmFallingThreshOidLen + alarm->contextLength + 1; X aVar->type = ASN_INTEGER; X aVar->val_len = sizeof(alarm->fallingThresh); X aVar->val.integer = (long *)malloc(sizeof(long)); X bcopy(&alarm->fallingThresh, aVar->val.integer, sizeof(long)); X } X aVar->next_variable = NULL; } X /* send an SNMPv2 Inform as notification of this event */ static void eventSendTrap(event, eventType, generic) X struct eventEntry *event; X int eventType; X void *generic; /* info needed to fill in variables */ { X struct eventNotifyEntry *np; X struct variable_list *vp; X struct snmp_pdu *pdu; X struct partyEntry *pp; X u_long uptime; X extern u_long sysUpTime(); X X for (np = eventNotifyTab; np; np = np->next) { X if (np->index != event->index X || np->status != ENTRY_ACTIVE X || !np->ss) /* if session isn't set up, punt */ X continue; X pp = party_getEntry(np->dstParty, np->dstPartyLen); X if (!pp) X continue; X X vp = (struct variable_list *)malloc(sizeof(struct variable_list)); X X /* sysUpTime is the first oid in the inform pdu */ X vp->name = (oid *)malloc(sysUpTimeOidLen * sizeof(oid)); X bcopy(sysUpTimeOid, vp->name, sysUpTimeOidLen * sizeof(oid)); X vp->name_length = sysUpTimeOidLen; X vp->type = TIMETICKS; X uptime = sysUpTime(); X vp->val_len = sizeof(uptime); X vp->val.objid = (oid *)malloc(vp->val_len); X bcopy(sysUpTime, vp->val.integer, vp->val_len); X vp->next_variable = NULL; X X vp->next_variable X = (struct variable_list *)malloc(sizeof(struct variable_list)); X X /* event->id is the second oid in the inform pdu */ X vp->next_variable->name = (oid *)malloc((eventIdOidLen + 1) * sizeof(oid)); X bcopy(eventIdOid, vp->next_variable->name, eventIdOidLen * sizeof(oid)); X vp->next_variable->name[eventIdOidLen] = event->index; X vp->next_variable->name_length = eventIdOidLen + 1; X vp->next_variable->type = ASN_OBJECT_ID; X vp->next_variable->val_len = event->idLen * sizeof(oid); X vp->next_variable->val.objid = (oid *)malloc(vp->next_variable->val_len); X bcopy(event->id, vp->next_variable->val.objid, vp->next_variable->val_len); X vp->next_variable->next_variable = NULL; X X /* event->id should override the eventType that was passed in */ X if (!bcmp(trapRisingAlarmOid, event->id, trapRisingAlarmOidLen)) { X eventType = EVENT_TYPE_RISING; X } X else if (!bcmp(trapFallingAlarmOid, event->id, X trapFallingAlarmOidLen)) { X eventType = EVENT_TYPE_FALLING; X } X else if (!bcmp(trapObjUnavailAlarmOid, event->id, X trapObjUnavailAlarmOidLen)) { X eventType = EVENT_TYPE_UNAVAILABLE; X } X X switch(eventType) { X case EVENT_TYPE_STARTUP_RISING: X case EVENT_TYPE_RISING: X eventAlarmFillInVars(vp, (struct alarmEntry *)generic, X TRAP_RISING_ALARM); X break; X case EVENT_TYPE_STARTUP_FALLING: X case EVENT_TYPE_FALLING: X eventAlarmFillInVars(vp, (struct alarmEntry *)generic, X TRAP_FALLING_ALARM); X break; X case EVENT_TYPE_UNAVAILABLE: X eventUnavailFillInVars(vp, (struct alarmEntry *)generic); X break; X default: X printf("eventSendTrap: unrecognized eventType %d\n", eventType); X break; X } X X pdu = snmp_pdu_create(INFORM_REQ_MSG); X bcopy(pp->partyTAddress, (char *)&pdu->address.sin_addr.s_addr, 4); X bcopy(pp->partyTAddress + 4, &pdu->address.sin_port, 2); X pdu->address.sin_port = 162; X pdu->address.sin_family = AF_INET; X pdu->variables = vp; X (void)snmp_send(np->ss, pdu); X } } X /* perform the action indicated by the event entry corresponding to index X ** in the event table X */ Export void eventGenerate(index, eventType, generic) X int index; X int eventType; X void *generic; /* info needed for traps */ { X struct eventEntry *event; X extern u_long sysUpTime(); X X event = eventGetRow(index); X if (event == NULL) { X /* event doesn't exist */ X return; X } X X /* set this before calling eventSendTrap(), so it can use the value */ X event->lastTimeSent = sysUpTime(); X event->numEvents++; X X eventSendTrap(event, eventType, generic); } X /* count down the lifetime timer, and remove the row when it reaches zero */ Export void eventTimer(now) X struct timeval *now; { X struct eventNotifyEntry *np; X struct eventNotifyEntry *next; X struct timeval elapsed; X static struct timeval lastCall = {0, 0}; X X if (lastCall.tv_sec == 0) { X /* initialization */ X lastCall.tv_sec = now->tv_sec; X lastCall.tv_usec = now->tv_usec; X return; X } X X time_subtract(&elapsed, now, &lastCall); X X if (elapsed.tv_sec < 0) { X /* if it's been less than a second, pretend we didn't get called */ X return; X } X X for (np = eventNotifyTab; np; np = next) { X next = np->next; X np->lifetime -= elapsed.tv_sec; X if (np->lifetime <= 0) { X if (np->status != ENTRY_ACTIVE){ X np->lifetime = 0; X } else { X eventNotifyDeleteRow(np); X } X } X } X X /* set lastCall to now, but skip the usecs that haven't been X ** subtracted from np->lifetime yet X */ X elapsed.tv_sec = 0; X time_subtract(&lastCall, now, &elapsed); } X /* X * If statP is non-NULL, the referenced object is at that location. X * If statP is NULL and event is non-NULL, the instance (row) exists, but not X * this variable. X * If statP is NULL and event is NULL, then neither this instance nor the X * variable exists. X */ /* return TRUE on success and FALSE on failure */ static int write_eventtab(action, var_val, var_val_type, var_val_len, statP, X name, name_len) X int action; /* IN - RESERVE1, RESERVE2, COMMIT, or FREE */ X u_char *var_val; /* IN - input or output buffer space */ X u_char var_val_type; /* IN - type of input buffer */ X int var_val_len; /* IN - input and output buffer len */ X u_char *statP; /* IN - pointer to local statistic */ X oid *name; /* IN - pointer to name requested */ X int name_len; /* IN - number of sub-ids in the name */ { X register int index; X register int variable; X register struct eventEntry *event; X int size; X int int_value; X u_char string_value[MAX_OWNER_STR_LEN]; X oid id_value[MAX_NAME_LEN]; X int buffersize = 1000; X X /* .1.3.6.1.6.3.2.1.2.2.1.6.1 */ X X if (name_len != 13) X return SNMP_ERR_NOCREATION; X index = name[name_len - 1]; X event = eventGetRow(index); X X switch (action) { X case RESERVE1: X if (event == NULL) { X event = eventNewRow(index); X if (event == NULL) { X /* no memory for row */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X else { X /* we have a row, but some vars will change. Remember X ** the current numbers. X */ X if (eventShadowRow(event) == 0) { X /* not enough memory available */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X break; X case RESERVE2: X if (event == NULL) { X /* this should have been created in the RESERVE1 phase */ X return SNMP_ERR_GENERR; X } X break; X case COMMIT: X if (event == NULL) { X return SNMP_ERR_GENERR; X } X eventCommitRow(event); X return SNMP_ERR_NOERROR; X case FREE: X if (event == NULL) { X return SNMP_ERR_GENERR; X } X if (event->status == ENTRY_DESTROY) { X /* this row did not exist before we began this RESERVE/FREE X ** cycle, so delete it now. X */ X eventDeleteRow(event); X } else { X /* the row existed before, so just get rid of the shadow X ** copy. X */ X eventFreeShadow(event); X } X return SNMP_ERR_NOERROR; X } X X variable = name[name_len - 2]; X X /* description, type, community, owner, and status X ** are the only user-writable variables in this table. X */ X switch (variable) { X case EVENTTABID: X if (action == RESERVE1) { X if (var_val_type != ASN_OBJECT_ID) { X return SNMP_ERR_WRONGTYPE; X } X size = sizeof(id_value); X if (asn_parse_objid(var_val, &buffersize, &var_val_type, X id_value, &size) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X event->shadow->idLen = size; X bcopy(id_value, event->shadow->id, size * sizeof(oid)); X event->shadow->bitmask |= EVENTTABIDMASK; X } X break; X case EVENTTABDESCRIPTION: X if (action == RESERVE1) { X if (var_val_type != ASN_OCTET_STR) { X return SNMP_ERR_WRONGTYPE; X } X size = sizeof(string_value); X if (asn_parse_string(var_val, &buffersize, &var_val_type, X string_value, &size) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X event->shadow->descriptionLen = size; X bcopy(string_value, event->shadow->description, size); X event->shadow->bitmask |= EVENTTABDESCRIPTIONMASK; X } X break; X case EVENTTABSTATUS: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X if (int_value < ENTRY_ACTIVE X || int_value > ENTRY_DESTROY X || int_value == ENTRY_NOTREADY X || int_value == ENTRY_CREATEANDGO) { X return SNMP_ERR_WRONGVALUE; X } X X if (int_value == ENTRY_CREATEANDWAIT X || int_value == ENTRY_CREATEANDGO) { X if (event->status != ENTRY_DESTROY) { X /* this is an entry that already existed; not X ** allowed to set it to createRequest X */ X return SNMP_ERR_INCONSISTENTVALUE; X } X int_value = ENTRY_NOTINSERVICE; X } X X event->shadow->status = int_value; X event->shadow->bitmask |= EVENTTABSTATUSMASK; X } X else if (action == RESERVE2) { X if ((event->shadow->status == ENTRY_ACTIVE) && X (event->shadow->bitmask != EVENTTABCOMPLETEMASK)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X default: X return SNMP_ERR_GENERR; X } X X return SNMP_ERR_NOERROR; } X void eventNotifyUpdateSession(np) X struct eventNotifyEntry *np; { X struct snmp_session session; X struct get_req_state *state; X extern int snmp_input(); X u_long destAddr; X X if (np->status != ENTRY_ACTIVE) X return; X X ((u_char *)&destAddr)[0] = (u_char)np->context[9]; X ((u_char *)&destAddr)[1] = (u_char)np->context[10]; X ((u_char *)&destAddr)[2] = (u_char)np->context[11]; X ((u_char *)&destAddr)[3] = (u_char)np->context[12]; X X np->srcPartyLen X = np->dstPartyLen = np->contextLen= MAX_NAME_LEN; X ms_party_init(destAddr, np->srcParty, &(np->srcPartyLen), X np->dstParty, &(np->dstPartyLen), X np->context, &(np->contextLen)); X X if (np->ss) X snmp_close(np->ss); X X state = (struct get_req_state *)malloc(sizeof(struct get_req_state)); X state->type = EVENT_GET_REQ; X state->info = (void *)NULL; X np->magic = state; X bzero((char *)&session, sizeof(struct snmp_session)); X session.peername = SNMP_DEFAULT_PEERNAME; X session.version = SNMP_VERSION_2; X session.srcParty = np->srcParty; X session.srcPartyLen = np->srcPartyLen; X session.dstParty = np->dstParty; X session.dstPartyLen = np->dstPartyLen; X session.context = np->context; X session.contextLen = np->contextLen; X session.retries = np->retransmissions; X session.timeout = np->interval * 1000000; X session.callback = snmp_input; X session.callback_magic = (void *)state; X np->ss = snmp_open(&session); X /* no need to check for error, there nothing to do about it anyway */ X if (!np->ss) X ERROR(""); } X /* X * If statP is non-NULL, the referenced object is at that location. X * If statP is NULL and event is non-NULL, the instance (row) exists, but not X * this variable. X * If statP is NULL and event is NULL, then neither this instance nor the X * variable exists. X */ /* return TRUE on success and FALSE on failure */ static int write_eventnotifytab(action, var_val, var_val_type, var_val_len, statP, X name, name_len) X int action; /* IN - RESERVE1, RESERVE2, COMMIT, or FREE */ X u_char *var_val; /* IN - input or output buffer space */ X u_char var_val_type; /* IN - type of input buffer */ X int var_val_len; /* IN - input and output buffer len */ X u_char *statP; /* IN - pointer to local statistic */ X oid *name; /* IN - pointer to name requested */ X int name_len; /* IN - number of sub-ids in the name */ { X register int index; X register int variable; X register struct eventNotifyEntry *event; X int int_value; X int buffersize = 1000; X oid *context; X int contextLen; X X /* .1.3.6.1.6.3.2.1.2.5.1.4.int.len.context */ X X if (name_len < 15) X return SNMP_ERR_NOCREATION; X index = name[12]; X contextLen = name[13]; X context = name + 14; X event = eventNotifyGetRow(index, context, contextLen); X X switch (action) { X case RESERVE1: X if (event == NULL) { X event = eventNotifyNewRow(index, context, contextLen); X if (event == NULL) { X /* no memory for row */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X else { X /* we have a row, but some vars will change. Remember X ** the current numbers. X */ X if (eventNotifyShadowRow(event) == 0) { X /* not enough memory available */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X break; X case RESERVE2: X if (event == NULL) { X /* this should have been created in the RESERVE1 phase */ X return SNMP_ERR_GENERR; X } X break; X case COMMIT: X if (event == NULL) { X return SNMP_ERR_GENERR; X } X eventNotifyCommitRow(event); X eventNotifyUpdateSession(event); X return SNMP_ERR_NOERROR; X case FREE: X if (event == NULL) { X return SNMP_ERR_GENERR; X } X if (event->status == ENTRY_DESTROY) { X /* this row did not exist before we began this RESERVE/FREE X ** cycle, so delete it now. X */ X eventNotifyDeleteRow(event); X } X else { X /* the row existed before, so just get rid of the shadow X ** copy. X */ X eventNotifyFreeShadow(event); X } X return SNMP_ERR_NOERROR; X } X X variable = name[11]; X X /* description, type, community, owner, and status X ** are the only user-writable variables in this table. X */ X switch (variable) { X case EVENTNOTIFYTABINTERVAL: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X if (int_value < MIN_INTERVAL) { X int_value = MIN_INTERVAL; X } X event->shadow->interval = int_value; X event->shadow->bitmask |= EVENTNOTIFYTABINTERVALMASK; X } X break; X case EVENTNOTIFYTABRETRANSMISSIONS: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X if (int_value > MAX_RETRANSMISSIONS) { X int_value = MAX_RETRANSMISSIONS; X } X event->shadow->retransmissions = int_value; X event->shadow->bitmask |= EVENTNOTIFYTABRETRANSMISSIONSMASK; X } X break; X case EVENTNOTIFYTABLIFETIME: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X event->shadow->lifetime = int_value; X event->shadow->bitmask |= EVENTNOTIFYTABLIFETIMEMASK; X } X break; X case EVENTNOTIFYTABSTATUS: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGLENGTH; X } X if (int_value < ENTRY_ACTIVE X || int_value > ENTRY_DESTROY X || int_value == ENTRY_NOTREADY X || int_value == ENTRY_CREATEANDGO) { X return SNMP_ERR_WRONGVALUE; X } X X if (int_value == ENTRY_CREATEANDWAIT X || int_value == ENTRY_CREATEANDGO) { X if (event->status != ENTRY_DESTROY) { X /* this is an entry that already existed; not X ** allowed to set it to createRequest X */ X return SNMP_ERR_INCONSISTENTVALUE; X } X int_value = ENTRY_NOTINSERVICE; X } X X event->shadow->status = int_value; X event->shadow->bitmask |= EVENTNOTIFYTABSTATUSMASK; X } X else if (action == RESERVE2) { X if ((event->shadow->status == ENTRY_ACTIVE) && X (event->shadow->bitmask != EVENTNOTIFYTABCOMPLETEMASK)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X default: X return SNMP_ERR_GENERR; X } X X return SNMP_ERR_NOERROR; } X Export u_char * var_eventnextindex(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X int result; X X *write_method = NULL; X result = compare(name, *length, vp->name, (int)vp->namelen); X if ((exact && (result != 0)) || (!exact && (result >= 0))) X return NULL; X X bcopy((char *)vp->name, (char *)name, X (int)vp->namelen * sizeof(oid)); X *length = vp->namelen; X *var_len = sizeof(long); X X switch (vp->magic) { X case EVENTNEXTINDEX: X return (u_char *)&eventNextIndex; X default: X ERROR(""); X } X X return NULL; } X /* respond to requests for variables in the event table */ Export u_char * var_eventtab(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X oid newname[MAX_NAME_LEN]; X int result; X int mask; X struct eventEntry *event; X X /* .1.3.6.1.6.3.2.1.2.2.1.6.int */ X X mask = 1 << (vp->magic - 1); X bcopy((char *)vp->name, (char *)newname, vp->namelen * sizeof(oid)); X *write_method = write_eventtab; X X /* find "next" process */ X for (event = eventTab; event; event = event->next) { X if ((event->bitmask & mask) == 0) { X /* this variable isn't available for inspection */ X continue; X } X newname[12] = (oid)event->index; X result = compare(name, *length, newname, 13); X if ((exact && (result == 0)) || (!exact && (result < 0))) X break; X } X if (event == NULL) { X return NULL; X } X X bcopy((char *)newname, (char *)name, (int)13 * sizeof(oid)); X *length = 13; X *var_len = sizeof(long); X X switch (vp->magic) { X case EVENTTABID: X *var_len = event->idLen * sizeof(oid); X return (u_char *)event->id; X case EVENTTABDESCRIPTION: X *var_len = event->descriptionLen; X return (u_char *)event->description; X case EVENTTABEVENTS: X *write_method = NULL; X return (u_char *)&event->numEvents; X case EVENTTABLASTTIMESENT: X *write_method = NULL; X return (u_char *)&event->lastTimeSent; X case EVENTTABSTATUS: X if (event->status == ENTRY_NOTINSERVICE){ X if (event->bitmask != EVENTTABCOMPLETEMASK){ X long_return = ENTRY_NOTREADY; X return (u_char *)&long_return; X } X } X return (u_char *)&event->status; X default: X ERROR(""); X } X X return NULL; } X /* respond to queries for eventNotifyMinInterval and eventNotifyMaxRetransmissions */ Export u_char * var_eventnotifyvars(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X int result; X X *write_method = 0; X result = compare(name, *length, vp->name, (int)vp->namelen); X if ((exact && (result != 0)) || (!exact && (result >= 0))) X return NULL; X X bcopy((char *)vp->name, (char *)name, X (int)vp->namelen * sizeof(oid)); X *length = vp->namelen; X *var_len = sizeof(long); X X switch (vp->magic) { X case EVENTMININTERVAL: X long_return = MIN_INTERVAL; X return (u_char *)&long_return; X case EVENTMAXRETRANS: X long_return = MAX_RETRANSMISSIONS; X return (u_char *)&long_return; X default: X ERROR(""); X } X X return NULL; } X /* respond to requests for variables in the event table */ Export u_char * var_eventnotifytab(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X oid newname[MAX_NAME_LEN]; X int result; X int mask; X struct eventNotifyEntry *event; X X X mask = 1 << (vp->magic - 1); X bcopy((char *)vp->name, (char *)newname, vp->namelen * sizeof(oid)); X *write_method = write_eventnotifytab; X X /* .1.3.6.1.6.3.2.1.2.5.1.4.int.len.context */ X X /* find "next" eventNotify entry */ X for (event = eventNotifyTab; event; event = event->next) { X if ((event->bitmask & mask) == 0) { X /* this variable isn't available for inspection */ X continue; X } X newname[12] = (oid)event->index; X newname[13] = (oid)event->contextLen; X bcopy(event->context, newname+14, event->contextLen * sizeof(oid)); X result = compare(name, *length, newname, 14 + event->contextLen); X if ((exact && (result == 0)) || (!exact && (result < 0))) X break; X } X if (event == NULL) { X return NULL; X } X X bcopy((char *)newname, (char *)name, X (int)(14 + event->contextLen) * sizeof(oid)); X *length = 14 + event->contextLen; X *var_len = sizeof(long); X X switch (vp->magic) { X case EVENTNOTIFYTABINTERVAL: X return (u_char *)&event->interval; X case EVENTNOTIFYTABRETRANSMISSIONS: X return (u_char *)&event->retransmissions; X case EVENTNOTIFYTABLIFETIME: X return (u_char *)&event->lifetime; X case EVENTNOTIFYTABSTATUS: X if (event->status == ENTRY_NOTINSERVICE){ X if (event->bitmask != EVENTNOTIFYTABCOMPLETEMASK){ X long_return = ENTRY_NOTREADY; X return (u_char *)&long_return; X } X } X return (u_char *)&event->status; X default: X ERROR(""); X } X X return NULL; } SHAR_EOF $shar_touch -am 1015123693 'snmp2/agent/event.c' && chmod 0644 'snmp2/agent/event.c' || echo 'restore of snmp2/agent/event.c failed' shar_count="`wc -c < 'snmp2/agent/event.c'`" test 42012 -eq "$shar_count" || echo "snmp2/agent/event.c: original size 42012, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/agent/event.h ============== if test -f 'snmp2/agent/event.h' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/agent/event.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/agent/event.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/agent/event.h' && /* include file for event module */ SHAR_EOF : || echo 'restore of snmp2/agent/event.h failed' fi echo 'End of snmp2 part 34' echo 'File snmp2/agent/event.h is continued in part 35' echo 35 > _sharseq.tmp exit 0