#!/bin/sh # This is `snmp2.38' (part 38 of snmp2). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `snmp2/README.vxWorks' 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" != 38; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping snmp2/README.vxWorks' else echo 'x - continuing file snmp2/README.vxWorks' sed 's/^X//' << 'SHAR_EOF' >> 'snmp2/README.vxWorks' && X Carl Kalbfleisch cwk@irrational.ssc.gov Larry Hoff hoff@gw1.ags.bnl.gov X 1, 2, 3) The porting of the code was done in a manner by adding "#ifdef VXWORKS" conditional compilations to the code. This allows the code to support the pre-existing SUN and vxWorks archetectures. Header files that are provided by vxWorks do not provide all the necessary defintions for the code. Where appropriate, a "wrapper" fro the vxWorks header file was created in the snmplib directory in the form VXxxx.h where xxx.h is the name of the standard header file. This VXxxx.h header file includes the vxWorks header file, and then adds the additional functionality required by vxWorks. X 4) A number of routines are required by the agent that are not provided by vxWorks. This routines are: X qsort, strcasecmp, random, gethostbyname, getservbyname, gettimeofday, nlist X In addition to these routines, a routine called exec was implemented to make launching the the applications follow a more UNIX-like command line. for example exec "snmpget -v 1 george public .1.3.6.1.4.1.535.1.3.1.0" would first create argc, argv and pass them to a routine named snmpget. This makes porting the application easier since it no longer requires that the command line interface be modified. Porting of other UNIX applications may benefit from this interface, but they may also require additional functions like getopt. X Finally, a set of routeins are needed to complement the SSC Real Time MIB. load.o implements the CPU idle time calculation. A file with Single Board Computer (SBC) specific functions to reboot the VME crate are needed as well. The file m162.0, m167.o, m147.o shold be laoded depending on the architecture. The reboot_vme function implemented in those routines should probaly be changed to a reboot_hook in vxWorks instead. X Each of the support routines are in the "vx" subdirectory. X 5) implement SSCL Real Time MIB. Adding MIB variables to the agent is a matter of modifying file agent/snmp_vars.c and agent/snmp_vars.h. First structures are defined for each of five tables in the SSC real time MIB. These structures are defined in snmp_vars.c: X X struct variable2 ssclrt_vxboot_variables[] X struct variable2 ssclrt_vxclock_variables[] X struct variable2 ssclrt_snmpd_variables[] X struct variable2 ssclrt_idle_variables[] X struct variable2 ssclrt_system_variables[] X Second, there is a "magic" number defined for each OID in the snmp_vars.h file. This magic number is used by the var_sscl_XXX function defined below to locate the OID being referenced by the call to that lookup function. X Next, the subtrees definition is expanded to contain the definitions of the SSCL Real Time MIB structures that are included above. X Next, Five routines are added for read access to the MIB: X var_sscl_vxboot X var_sscl_vxclock X var_sscl_snmpd X var_sscl_idle X var_sscl_system The details of these routeins are pretty straight forward. One thing to look out for is that the lin "newname [xx] = 0" is criticial to the "compare ()" function returning the correct value. Beware that the xx value is the index in an C array representing the OID instance. For example, an object in the SSCL Real Time MIB idle group is the currentIdle. Its object ID is 1.3.6.1.4.1.535.1.3.1.0. The trailing 0 is the 10th element of a C array representing the OID, and is the zero appended with the "newname [10] = 0" statement in the routine var_sscl_idle (). X In the routines the var_sscl_XXX, the processing for an object gets the value and returns a pointer to it. If the object is writable, then the write_method pointer is assigned to the function which handles setting the value. There are 4 write methods associated with the MIB. These are: X X write_vxboot () X write_ssclrt_snmpd () X write_ssclrt_idle () X write_ssclrt_system () X The setting of a value is intended to be done as a four step process. This is explained fully in the source code. For now, the four step process is ignored to prevent memory allocation/deallocation requirements. X Finally, supporting the SSCL Real-Time MIB requires the addition of the support functions load.o and a board specific routine to handle the reboot_vme function. If the board you are using is not one currently supported, then the options are to use the generic.o, or add support for the board support yourself. Essentially adding the support is a matter of implementing reboot_vme for you board. X With all of this in mind, using the RT-MIB is the next topic. Essentially there are three command line programs of interest: X X snmpget X snmpwalk X snmpset X The first two are provided with the CMU code. The second is a public domain program obtained off the internet. All run on SUN. snmpget and snmpwalk are documented in the CMU distribution. X examples are: X To walk the SSCL Real-Time MIB X nervous> snmpwalk -v 1 george public .1.3.6.1.4.1.535 enterprises.sscl.realTime.rtos.vxworks.vxBootParams.bootDev.0 = "ei" Hex: 65 69 enterprises.sscl.realTime.rtos.vxworks.vxBootParams.hostName.0 = "fetid" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.targetName.0 = "george" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.ethernetAddr.0 = "143.202.24.147:ffffffc0" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.backplaneAddr.0 = "" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.hostAddr.0 = "143.202.20.141" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.gatewayAddr.0 = "143.202.24.129" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.bootFile.0 = "/export/putrid/vxworks_5.1/config/mv162/vxWorks" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.startupScript.0 = "/usr/local/comms/vxWorks/startup/targets/george" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.userName.0 = "cwk" Hex: 63 77 6B enterprises.sscl.realTime.rtos.vxworks.vxBootParams.password.0 = "" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.other.0 = "" enterprises.sscl.realTime.rtos.vxworks.vxBootParams.processorNumber.0 = 4 enterprises.sscl.realTime.rtos.vxworks.vxBootParams.flags.0 = 32 enterprises.sscl.realTime.rtos.vxworks.vxKernel.vxClock.sysClkRate.0 = 60 enterprises.sscl.realTime.rtos.vxworks.vxKernel.vxClock.ticks.0 = 737715 enterprises.sscl.realTime.snmpd.agentVersion.0 = "SSCL SNMPv2 agent version 1.00" enterprises.sscl.realTime.snmpd.portVersion.0 = "vxWorks Port version 0.00" enterprises.sscl.realTime.snmpd.taskPriority.0 = 100 enterprises.sscl.realTime.idle.currentIdle.0 = 98 enterprises.sscl.realTime.idle.tenSecondIdle.0 = 98 enterprises.sscl.realTime.idle.sixtySecondIdle.0 = 95 enterprises.sscl.realTime.idle.userIdle.0 = 98 enterprises.sscl.realTime.idle.userInterval.0 = 30 enterprises.sscl.realTime.idle.calibration.0 = 8317342 enterprises.sscl.realTime.idle.historySize.0 = 1024 enterprises.sscl.realTime.idle.historyValid.0 = 1024 enterprises.sscl.realTime.system.reboot.0 = 0 enterprises.sscl.realTime.system.rebootVME.0 = 0 enterprises.sscl.realTime.system.abortReboot.0 = 0 enterprises.sscl.realTime.system.silent.0 = 0 enterprises.sscl.realTime.system.spuriousInts.0 = 0 X X To retrieve the 60 second idle orion> snmpget -v 1 george public .1.3.6.1.4.1.535.1.3.3.0 enterprises.sscl.realTime.idle.sixtySecondIdle.0 = 98 X X To set the user interval: orion> snmpset -h george -c private 1.3.6.1.4.1.535.1.3.5.0 Integer 45 Request Id: 0 Error: noError Index: 0 Count: 1 X Name: 1.3.6.1.4.1.535.1.3.5.0 Kind: Integer Value: 45 X X To set the startupScript: orion> snmpset -h george -c private 1.3.6.1.4.1.535.1.1.2.4.9.0 OctetString "/us r/local/comms/vxWorks/startup/targets/george" Request Id: 0 Error: badValue Index: 1 Count: 1 X Name: 1.3.6.1.4.1.535.1.1.2.4.9.0 Kind: OctetString Value: "/usr/local/comms/vxWorks/startup/targets/george" X X 6) Loading SNMPv2 on vxWorks To load the SNMPv2 on vxWorks, a vxWorks script load.vxWorks is provided. This loads each of teh object modules into memory. There is a matter of re-entrancy that may or may not be a problem in your system. This matter is that the gethostbyname is not re-entrant. It returns a pointer to gloabl memory. If the agent is the only code loaded into the system then there is no concern of this re-entrancy problem. If the applications are loaded as well, then there may be a problem. The easiest soluton is to link each of the applications and the agent seperately with inet_vx.o prior to loading them into the target system. This way, each has its own copy of that routine, each with its own copy of the global memory to return. Another way is to modify the inet_vx.o code so that the gethostbyname routine allocates memory for each task to return a pointer specific for each task that calls it. A simple hash function would allow some number of tasks to call the routine. X X X X X SHAR_EOF echo 'File snmp2/README.vxWorks is complete' && $shar_touch -am 1015123793 'snmp2/README.vxWorks' && chmod 0644 'snmp2/README.vxWorks' || echo 'restore of snmp2/README.vxWorks failed' shar_count="`wc -c < 'snmp2/README.vxWorks'`" test 9108 -eq "$shar_count" || echo "snmp2/README.vxWorks: original size 9108, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/Makefile ============== if test ! -d 'snmp2/vx'; then echo 'x - creating directory snmp2/vx' mkdir 'snmp2/vx' fi if test -f 'snmp2/vx/Makefile' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/Makefile (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/Makefile (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/Makefile' && # # Makefile for BSD extensions to vxWorks # OBJS = random.o qsort.o inet_vx.o strcasecmp.o load.o exec.o nlist.o syslog.o \ X gettimeofday.o \ X m162.o m167.o m147.o generic.o X INCLUDES = -I$(VXWORKS)/h -I../snmplib CFLAGS=-g -DDEBUG $(INCLUDES) -DCPU=MC68030 -DVXWORKS -c X CC = cc68k LNK = ld68k LDFLAGS = -X -r AOUT_CONVERT = /bin/cat X all: $(OBJS) X X.c.o : X $(CC) $(CFLAGS) $< X clean : X rm -f *.o SHAR_EOF $shar_touch -am 1015123793 'snmp2/vx/Makefile' && chmod 0644 'snmp2/vx/Makefile' || echo 'restore of snmp2/vx/Makefile failed' shar_count="`wc -c < 'snmp2/vx/Makefile'`" test 399 -eq "$shar_count" || echo "snmp2/vx/Makefile: original size 399, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/qsort.c ============== if test -f 'snmp2/vx/qsort.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/qsort.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/qsort.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/qsort.c' && /*- X * Copyright (c) 1980, 1983, 1990 The Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ X #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)qsort.c 5.9 (Berkeley) 2/23/91"; #endif /* LIBC_SCCS and not lint */ X #include #include #include X /* X * MTHRESH is the smallest partition for which we compare for a median X * value instead of using the middle value. X */ #define MTHRESH 6 X /* X * THRESH is the minimum number of entries in a partition for continued X * partitioning. X */ #define THRESH 4 X void qsort(bot, nmemb, size, compar) X void *bot; X size_t nmemb, size; #ifdef VXWORKS X int (*compar) (); #else X int (*compar) __P((const void *, const void *)); #endif { X static void insertion_sort(), quick_sort(); X X if (nmemb <= 1) X return; X X if (nmemb >= THRESH) X quick_sort(bot, nmemb, size, compar); X else X insertion_sort(bot, nmemb, size, compar); } X /* X * Swap two areas of size number of bytes. Although qsort(3) permits random X * blocks of memory to be sorted, sorting pointers is almost certainly the X * common case (and, were it not, could easily be made so). Regardless, it X * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer X * arithmetic gets lost in the time required for comparison function calls. X */ #define SWAP(a, b) { \ X cnt = size; \ X do { \ X ch = *a; \ X *a++ = *b; \ X *b++ = ch; \ X } while (--cnt); \ } X /* X * Knuth, Vol. 3, page 116, Algorithm Q, step b, argues that a single pass X * of straight insertion sort after partitioning is complete is better than X * sorting each small partition as it is created. This isn't correct in this X * implementation because comparisons require at least one (and often two) X * function calls and are likely to be the dominating expense of the sort. X * Doing a final insertion sort does more comparisons than are necessary X * because it compares the "edges" and medians of the partitions which are X * known to be already sorted. X * X * This is also the reasoning behind selecting a small THRESH value (see X * Knuth, page 122, equation 26), since the quicksort algorithm does less X * comparisons than the insertion sort. X */ #define SORT(bot, n) { \ X if (n > 1) \ X if (n == 2) { \ X t1 = bot + size; \ X if (compar(t1, bot) < 0) \ X SWAP(t1, bot); \ X } else \ X insertion_sort(bot, n, size, compar); \ } X static void quick_sort(bot, nmemb, size, compar) X register char *bot; X register int size; X int nmemb, (*compar)(); { X register int cnt; X register u_char ch; X register char *top, *mid, *t1, *t2; X register int n1, n2; X char *bsv; X static void insertion_sort(); X X /* bot and nmemb must already be set. */ partition: X X /* find mid and top elements */ X mid = bot + size * (nmemb >> 1); X top = bot + (nmemb - 1) * size; X X /* X * Find the median of the first, last and middle element (see Knuth, X * Vol. 3, page 123, Eq. 28). This test order gets the equalities X * right. X */ X if (nmemb >= MTHRESH) { X n1 = compar(bot, mid); X n2 = compar(mid, top); X if (n1 < 0 && n2 > 0) X t1 = compar(bot, top) < 0 ? top : bot; X else if (n1 > 0 && n2 < 0) X t1 = compar(bot, top) > 0 ? top : bot; X else X t1 = mid; X X /* if mid element not selected, swap selection there */ X if (t1 != mid) { X SWAP(t1, mid); X mid -= size; X } X } X X /* Standard quicksort, Knuth, Vol. 3, page 116, Algorithm Q. */ #define didswap n1 #define newbot t1 #define replace t2 X didswap = 0; X for (bsv = bot;;) { X for (; bot < mid && compar(bot, mid) <= 0; bot += size); X while (top > mid) { X if (compar(mid, top) <= 0) { X top -= size; X continue; X } X newbot = bot + size; /* value of bot after swap */ X if (bot == mid) /* top <-> mid, mid == top */ X replace = mid = top; X else { /* bot <-> top */ X replace = top; X top -= size; X } X goto swap; X } X if (bot == mid) X break; X X /* bot <-> mid, mid == bot */ X replace = mid; X newbot = mid = bot; /* value of bot after swap */ X top -= size; X swap: SWAP(bot, replace); X bot = newbot; X didswap = 1; X } X X /* X * Quicksort behaves badly in the presence of data which is already X * sorted (see Knuth, Vol. 3, page 119) going from O N lg N to O N^2. X * To avoid this worst case behavior, if a re-partitioning occurs X * without swapping any elements, it is not further partitioned and X * is insert sorted. This wins big with almost sorted data sets and X * only loses if the data set is very strangely partitioned. A fix X * for those data sets would be to return prematurely if the insertion X * sort routine is forced to make an excessive number of swaps, and X * continue the partitioning. X */ X if (!didswap) { X insertion_sort(bsv, nmemb, size, compar); X return; X } X X /* X * Re-partition or sort as necessary. Note that the mid element X * itself is correctly positioned and can be ignored. X */ #define nlower n1 #define nupper n2 X bot = bsv; X nlower = (mid - bot) / size; /* size of lower partition */ X mid += size; X nupper = nmemb - nlower - 1; /* size of upper partition */ X X /* X * If must call recursively, do it on the smaller partition; this X * bounds the stack to lg N entries. X */ X if (nlower > nupper) { X if (nupper >= THRESH) X quick_sort(mid, nupper, size, compar); X else { X SORT(mid, nupper); X if (nlower < THRESH) { X SORT(bot, nlower); X return; X } X } X nmemb = nlower; X } else { X if (nlower >= THRESH) X quick_sort(bot, nlower, size, compar); X else { X SORT(bot, nlower); X if (nupper < THRESH) { X SORT(mid, nupper); X return; X } X } X bot = mid; X nmemb = nupper; X } X goto partition; X /* NOTREACHED */ } X static void insertion_sort(bot, nmemb, size, compar) X char *bot; X register int size; X int nmemb, (*compar)(); { X register int cnt; X register u_char ch; X register char *s1, *s2, *t1, *t2, *top; X X /* X * A simple insertion sort (see Knuth, Vol. 3, page 81, Algorithm X * S). Insertion sort has the same worst case as most simple sorts X * (O N^2). It gets used here because it is (O N) in the case of X * sorted data. X */ X top = bot + nmemb * size; X for (t1 = bot + size; t1 < top;) { X for (t2 = t1; (t2 -= size) >= bot && compar(t1, t2) < 0;); X if (t1 != (t2 += size)) { X /* Bubble bytes up through each element. */ X for (cnt = size; cnt--; ++t1) { X ch = *t1; X for (s1 = s2 = t1; (s2 -= size) >= t2; s1 = s2) X *s1 = *s2; X *s1 = ch; X } X } else X t1 += size; X } } SHAR_EOF $shar_touch -am 1015123793 'snmp2/vx/qsort.c' && chmod 0644 'snmp2/vx/qsort.c' || echo 'restore of snmp2/vx/qsort.c failed' shar_count="`wc -c < 'snmp2/vx/qsort.c'`" test 8109 -eq "$shar_count" || echo "snmp2/vx/qsort.c: original size 8109, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/random.c ============== if test -f 'snmp2/vx/random.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/random.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/random.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/random.c' && /* X * Copyright (c) 1983 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ X #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)random.c 5.9 (Berkeley) 2/23/91"; #endif /* LIBC_SCCS and not lint */ X #include #include X /* X * random.c: X * X * An improved random number generation package. In addition to the standard X * rand()/srand() like interface, this package also has a special state info X * interface. The initstate() routine is called with a seed, an array of X * bytes, and a count of how many bytes are being passed in; this array is X * then initialized to contain information for random number generation with X * that much state information. Good sizes for the amount of state X * information are 32, 64, 128, and 256 bytes. The state can be switched by X * calling the setstate() routine with the same array as was initiallized X * with initstate(). By default, the package runs with 128 bytes of state X * information and generates far better random numbers than a linear X * congruential generator. If the amount of state information is less than X * 32 bytes, a simple linear congruential R.N.G. is used. X * X * Internally, the state information is treated as an array of longs; the X * zeroeth element of the array is the type of R.N.G. being used (small X * integer); the remainder of the array is the state information for the X * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of X * state information, which will allow a degree seven polynomial. (Note: X * the zeroeth word of state information also has some other information X * stored in it -- see setstate() for details). X * X * The random number generation technique is a linear feedback shift register X * approach, employing trinomials (since there are fewer terms to sum up that X * way). In this approach, the least significant bit of all the numbers in X * the state table will act as a linear feedback shift register, and will X * have period 2^deg - 1 (where deg is the degree of the polynomial being X * used, assuming that the polynomial is irreducible and primitive). The X * higher order bits will have longer periods, since their values are also X * influenced by pseudo-random carries out of the lower bits. The total X * period of the generator is approximately deg*(2**deg - 1); thus doubling X * the amount of state information has a vast influence on the period of the X * generator. Note: the deg*(2**deg - 1) is an approximation only good for X * large deg, when the period of the shift register is the dominant factor. X * With deg equal to seven, the period is actually much longer than the X * 7*(2**7 - 1) predicted by this formula. X */ X /* X * For each of the currently supported random number generators, we have a X * break value on the amount of state information (you need at least this X * many bytes of state info to support this random number generator), a degree X * for the polynomial (actually a trinomial) that the R.N.G. is based on, and X * the separation between the two lower order coefficients of the trinomial. X */ #define TYPE_0 0 /* linear congruential */ #define BREAK_0 8 #define DEG_0 0 #define SEP_0 0 X #define TYPE_1 1 /* x**7 + x**3 + 1 */ #define BREAK_1 32 #define DEG_1 7 #define SEP_1 3 X #define TYPE_2 2 /* x**15 + x + 1 */ #define BREAK_2 64 #define DEG_2 15 #define SEP_2 1 X #define TYPE_3 3 /* x**31 + x**3 + 1 */ #define BREAK_3 128 #define DEG_3 31 #define SEP_3 3 X #define TYPE_4 4 /* x**63 + x + 1 */ #define BREAK_4 256 #define DEG_4 63 #define SEP_4 1 X /* X * Array versions of the above information to make code run faster -- X * relies on fact that TYPE_i == i. X */ #define MAX_TYPES 5 /* max number of types above */ X static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; X /* X * Initially, everything is set up as if from: X * X * initstate(1, &randtbl, 128); X * X * Note that this initialization takes advantage of the fact that srandom() X * advances the front and rear pointers 10*rand_deg times, and hence the X * rear pointer which starts at 0 will also end up at zero; thus the zeroeth X * element of the state information, which contains info about the current X * position of the rear pointer is just X * X * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. X */ X static long randtbl[DEG_3 + 1] = { X TYPE_3, X 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, X 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, X 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, X 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, X 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, X 0x27fb47b9, }; X /* X * fptr and rptr are two pointers into the state info, a front and a rear X * pointer. These two pointers are always rand_sep places aparts, as they X * cycle cyclically through the state information. (Yes, this does mean we X * could get away with just one pointer, but the code for random() is more X * efficient this way). The pointers are left positioned as they would be X * from the call X * X * initstate(1, randtbl, 128); X * X * (The position of the rear pointer, rptr, is really 0 (as explained above X * in the initialization of randtbl) because the state table pointer is set X * to point to randtbl[1] (as explained below). X */ static long *fptr = &randtbl[SEP_3 + 1]; static long *rptr = &randtbl[1]; X /* X * The following things are the pointer to the state information table, the X * type of the current generator, the degree of the current polynomial being X * used, and the separation between the two pointers. Note that for efficiency X * of random(), we remember the first location of the state information, not X * the zeroeth. Hence it is valid to access state[-1], which is used to X * store the type of the R.N.G. Also, we remember the last location, since X * this is more efficient than indexing every time to find the address of X * the last element to see if the front and rear pointers have wrapped. X */ static long *state = &randtbl[1]; static int rand_type = TYPE_3; static int rand_deg = DEG_3; static int rand_sep = SEP_3; static long *end_ptr = &randtbl[DEG_3 + 1]; X /* X * srandom: X * X * Initialize the random number generator based on the given seed. If the X * type is the trivial no-state-information type, just remember the seed. X * Otherwise, initializes state[] based on the given "seed" via a linear X * congruential generator. Then, the pointers are set to known locations X * that are exactly rand_sep places apart. Lastly, it cycles the state X * information a given number of times to get rid of any initial dependencies X * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] X * for default usage relies on values produced by this routine. X */ void srandom(x) X u_int x; { X register int i, j; X X if (rand_type == TYPE_0) X state[0] = x; X else { X j = 1; X state[0] = x; X for (i = 1; i < rand_deg; i++) X state[i] = 1103515245 * state[i - 1] + 12345; X fptr = &state[rand_sep]; X rptr = &state[0]; X for (i = 0; i < 10 * rand_deg; i++) X (void)random(); X } } X /* X * initstate: X * X * Initialize the state information in the given array of n bytes for future X * random number generation. Based on the number of bytes we are given, and X * the break values for the different R.N.G.'s, we choose the best (largest) X * one we can and set things up for it. srandom() is then called to X * initialize the state information. X * X * Note that on return from srandom(), we set state[-1] to be the type X * multiplexed with the current value of the rear pointer; this is so X * successive calls to initstate() won't lose this information and will be X * able to restart with setstate(). X * X * Note: the first thing we do is save the current state, if any, just like X * setstate() so that it doesn't matter when initstate is called. X * X * Returns a pointer to the old state. X */ char * initstate(seed, arg_state, n) X u_int seed; /* seed for R.N.G. */ X char *arg_state; /* pointer to state array */ X int n; /* # bytes of state info */ { X register char *ostate = (char *)(&state[-1]); X X if (rand_type == TYPE_0) X state[-1] = rand_type; X else X state[-1] = MAX_TYPES * (rptr - state) + rand_type; X if (n < BREAK_0) { X (void)fprintf(stderr, X "random: not enough state (%d bytes); ignored.\n", n); X return(0); X } X if (n < BREAK_1) { X rand_type = TYPE_0; X rand_deg = DEG_0; X rand_sep = SEP_0; X } else if (n < BREAK_2) { X rand_type = TYPE_1; X rand_deg = DEG_1; X rand_sep = SEP_1; X } else if (n < BREAK_3) { X rand_type = TYPE_2; X rand_deg = DEG_2; X rand_sep = SEP_2; X } else if (n < BREAK_4) { X rand_type = TYPE_3; X rand_deg = DEG_3; X rand_sep = SEP_3; X } else { X rand_type = TYPE_4; X rand_deg = DEG_4; X rand_sep = SEP_4; X } X state = &(((long *)arg_state)[1]); /* first location */ X end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ X srandom(seed); X if (rand_type == TYPE_0) X state[-1] = rand_type; X else X state[-1] = MAX_TYPES*(rptr - state) + rand_type; X return(ostate); } X /* X * setstate: X * X * Restore the state from the given state array. X * X * Note: it is important that we also remember the locations of the pointers X * in the current state information, and restore the locations of the pointers X * from the old state information. This is done by multiplexing the pointer X * location into the zeroeth word of the state information. X * X * Note that due to the order in which things are done, it is OK to call X * setstate() with the same state as the current state. X * X * Returns a pointer to the old state information. X */ char * setstate(arg_state) X char *arg_state; { X register long *new_state = (long *)arg_state; X register int type = new_state[0] % MAX_TYPES; X register int rear = new_state[0] / MAX_TYPES; X char *ostate = (char *)(&state[-1]); X X if (rand_type == TYPE_0) X state[-1] = rand_type; X else X state[-1] = MAX_TYPES * (rptr - state) + rand_type; X switch(type) { X case TYPE_0: X case TYPE_1: X case TYPE_2: X case TYPE_3: X case TYPE_4: X rand_type = type; X rand_deg = degrees[type]; X rand_sep = seps[type]; X break; X default: X (void)fprintf(stderr, X "random: state info corrupted; not changed.\n"); X } X state = &new_state[1]; X if (rand_type != TYPE_0) { X rptr = &state[rear]; X fptr = &state[(rear + rand_sep) % rand_deg]; X } X end_ptr = &state[rand_deg]; /* set end_ptr too */ X return(ostate); } X /* X * random: X * X * If we are using the trivial TYPE_0 R.N.G., just do the old linear X * congruential bit. Otherwise, we do our fancy trinomial stuff, which is X * the same in all the other cases due to all the global variables that have X * been set up. The basic operation is to add the number at the rear pointer X * into the one at the front pointer. Then both pointers are advanced to X * the next location cyclically in the table. The value returned is the sum X * generated, reduced to 31 bits by throwing away the "least random" low bit. X * X * Note: the code takes advantage of the fact that both the front and X * rear pointers can't wrap on the same call by not testing the rear X * pointer if the front one has wrapped. X * X * Returns a 31-bit random number. X */ long random() { X long i; X X if (rand_type == TYPE_0) X i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; X else { X *fptr += *rptr; X i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */ X if (++fptr >= end_ptr) { X fptr = state; X ++rptr; X } else if (++rptr >= end_ptr) X rptr = state; X } X return(i); } SHAR_EOF $shar_touch -am 1015123793 'snmp2/vx/random.c' && chmod 0644 'snmp2/vx/random.c' || echo 'restore of snmp2/vx/random.c failed' shar_count="`wc -c < 'snmp2/vx/random.c'`" test 13317 -eq "$shar_count" || echo "snmp2/vx/random.c: original size 13317, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/strcasecmp.c ============== if test -f 'snmp2/vx/strcasecmp.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/strcasecmp.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/strcasecmp.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/strcasecmp.c' && /* X * Copyright (c) 1987 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ #ifdef VXWORKS #else #include #endif #include X #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)strcasecmp.c 5.10 (Berkeley) 1/26/91"; #endif /* LIBC_SCCS and not lint */ X typedef unsigned char u_char; X /* X * This array is designed for mapping upper and lower case letter X * together for a case independent comparison. The mappings are X * based upon ascii character sequences. X */ static const u_char charmap[] = { X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', X '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', X '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', X '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', X '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', X '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', X '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', X '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', X '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', X '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', X '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', X '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', X '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', X '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', X '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', X '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', X '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', X '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', X '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', X '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', X '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', X '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', X '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', X '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', X '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', }; X int strcasecmp(s1, s2) X const char *s1, *s2; { X register const u_char *cm = charmap, X *us1 = (const u_char *)s1, X *us2 = (const u_char *)s2; X X while (cm[*us1] == cm[*us2++]) X if (*us1++ == '\0') X return (0); X return (cm[*us1] - cm[*--us2]); } X int strncasecmp(s1, s2, n) X const char *s1, *s2; X register size_t n; { X if (n != 0) { X register const u_char *cm = charmap, X *us1 = (const u_char *)s1, X *us2 = (const u_char *)s2; X X do { X if (cm[*us1] != cm[*us2++]) X return (cm[*us1] - cm[*--us2]); X if (*us1++ == '\0') X break; X } while (--n != 0); X } X return (0); } SHAR_EOF $shar_touch -am 1015123793 'snmp2/vx/strcasecmp.c' && chmod 0644 'snmp2/vx/strcasecmp.c' || echo 'restore of snmp2/vx/strcasecmp.c failed' shar_count="`wc -c < 'snmp2/vx/strcasecmp.c'`" test 4958 -eq "$shar_count" || echo "snmp2/vx/strcasecmp.c: original size 4958, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/exec.c ============== if test -f 'snmp2/vx/exec.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/exec.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/exec.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/exec.c' && /* X * X * X * (c) Copyright 1993 by Associated Universities, Inc. (AUI) 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 AUI not be X * used in advertising or publicity pertaining to distribution of the X * software without specific, written prior permission. X * X * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. X * AUI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL X * AUI 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 * X */ X #include "vxWorks.h" /* vxWorks - specific definitions */ #include "symbol.h" /* symbol table definitions */ #include "symLib.h" /* symLib interface definitions */ #include "taskLib.h" /* task control block definitions */ #include "taskHookLib.h" /* task delete hook interface definitions */ #include "stdio.h" /* sprintf */ #include "string.h" /* strlen, strtok, etc. */ X IMPORT SYMTAB_ID sysSymTbl; /* The Id of the symbol table containing entry points */ X int nice(int tid, int priority){ X return taskPrioritySet(tid, priority); } X static const char *WHITE_SPACE = " \t\n"; X static void deleteHook(WIND_TCB *pTcb){ X (void)free((char *) pTcb->spare1); X (void)free((char *) pTcb->spare2); } X int exec( X char *commandLine /* command line to be executed */ X ){ X X /* Let's allocate some space for the arg vector and the locally-used entryName */ X char **argv = (char **) malloc(sizeof(argv[0])); /* start off with enough room for one pointer */ X char *entryName = (char *) malloc(strlen(commandLine)+1); /* keep an extra char for a '_' */ X X int retVal, argc = 0; /* the saved return value and the arg count */ X X SYM_TYPE dummy; /* We don't care about the symbol type */ X FUNCPTR entry; /* But we *do* need the entry point */ X X if(argv == NULL || entryName == NULL) /* any problems? barf */ X goto clean; X X sprintf(entryName, "_%s", commandLine); X X /* This is the sort of ugly code that the C language promotes*/ X /* We need to tokenize the command line, supstituting the NULL X character for white space. We also need to keep a count of the X tokens in argc, and a set of pointers to the tokens in argv. X We need to keep doing this until there are no more tokens, X in addition, we need to watch out in case we run out of X heap in the middle of the whole process. X */ X X argv[argc++] = (char *) strtok(&entryName[1], WHITE_SPACE); X do argv=(char**)realloc(argv, (argc+1)*sizeof(*argv)); X while(argv != NULL && (argv[argc++] = (char *) strtok(NULL, WHITE_SPACE)) != NULL); X X /* if we're out of memory */ X if(argv == NULL) X goto clean; X X /* Can't find the entry point? barf */ X if(symFindByName (sysSymTbl, entryName, (char **) &entry, &dummy) == ERROR) X goto clean; X X /* add delete hooks to clean up dynamic memory */ X /* This implementation is questionable, since we don't know X if spare 1 & 2 are already in use. X */ X taskTcb(taskIdSelf())->spare1 = (int) argv; X taskTcb(taskIdSelf())->spare2 = (int) entryName; X X if(taskDeleteHookAdd((FUNCPTR) deleteHook)==ERROR) X goto clean; X X /* fire up the routine */ X retVal = (*entry)(argc, argv); X X /* If the routine returns OK, we can free up the memory ourselves, X rather than waitin for the task hook */ X (void)taskDeleteHookDelete((FUNCPTR)deleteHook); X (void)free(argv); X (void)free(entryName); X X return retVal; X clean : X if(argv != NULL) free(argv); X if(entryName != NULL) free(entryName); X return ERROR; } X X X spawn (priority, string) { X printf ("Spawning Task Blast at priority %d...", priority); X if (taskSpawn ("spawn", priority, 0, 0x4000, exec, string, 0, 0, 0, 0, 0, 0, 0, 0, 0)) X { X printf ("OK\n"); X } X else X { X printf ("FAILED\n"); X } X } SHAR_EOF $shar_touch -am 1026094393 'snmp2/vx/exec.c' && chmod 0644 'snmp2/vx/exec.c' || echo 'restore of snmp2/vx/exec.c failed' shar_count="`wc -c < 'snmp2/vx/exec.c'`" test 4375 -eq "$shar_count" || echo "snmp2/vx/exec.c: original size 4375, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/vx/load.c ============== if test -f 'snmp2/vx/load.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/vx/load.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/vx/load.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/vx/load.c' && /* X * load.c X * X * Carl W. Kalbfleisch X * X * Copyright (C) 1993, University Research Association X * All Rights Reserved X * X * X * DISCLAIMER X * X * The software is licensed on an "as is" basis only. Universities Research X * Association, Inc. (URA) makes no representations or warranties, express X * or implied. By way of example but not of limitation, URA makes no X * representations or WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY X * PARTICULAR PURPOSE, that the use of the licensed software will not X * infringe any patent, copyright, or trademark, or as to the use (or the X * results of the use) of the licensed software or written material in X * terms of correctness, accuracy, reliability, currentness or otherwise. X * The entire risk as to the results and performance of the licensed X * software is assumed by the user. Universities Research Association, Inc. X * and any of its trustees, overseers, directors, officers, employees, X * agents or contractors shall not be liable under any claim, charge, or X * demand, whether in contract, tort, criminal law, or otherwise, for any X * and all loss, cost, charge, claim, demand, fee, expense, or damage of X * every nature and kind arising out of, connected with, resulting from or X * sustained as a result of using this software. In no event shall URA be X * liable for special, direct, indirect or consequential damages, losses, X * costs, charges, claims, demands, fees or expenses of any nature or kind. X * X * -------------------------------------------------------------------------- X * X * X * routines for computing system load average. X * X * by defining an external reference to __current_average, X * any software in the system can read the current average X * X * ported from pSOS+ to vxworks X * X * by Lee Miller (214)708-6171 Internet Email: lmiller@slug.ssc.gov X * Feb 22, 1992 X * lmiller@slug.ssc.gov X * X */ X #include #include #include #include #include X /* X * format of buffer output by Load Export task X */ X #define LOAD_PORT 0x9357 X #define MAX_TO_SEND 100 X struct export_buffer_st { X unsigned int num_sent; X unsigned int record [MAX_TO_SEND]; X }; X #define LOAD_REF_TYPE X /* X * load_ref.h X * X * uesed in conjunction with routines that want to access X * the cpu load calculation set up by the load.c code. X * X * If LOAD_DEF_TYPE is defined, the storage for the X * variables is defined, otherwise they are defined X * as external references. X */ #ifndef LOAD_REF_TYPE #define LOAD_REF_TYPE extern #endif X #define NUM_HIST 1024 #define NEXT_INDEX(x,l) (( x < l-1) ? x+1 : 0) #define PREV_INDEX(x) (( x == 0) ? NUM_HIST-1 : x-1) X LOAD_REF_TYPE unsigned int __current_average; LOAD_REF_TYPE unsigned int __history_index; SHAR_EOF : || echo 'restore of snmp2/vx/load.c failed' fi echo 'End of snmp2 part 38' echo 'File snmp2/vx/load.c is continued in part 39' echo 39 > _sharseq.tmp exit 0