tools.c

00001 /*
00002  * tools.c
00003  */
00004 
00005 #define NETSNMP_TOOLS_C 1 /* dont re-define malloc wrappers here */
00006 
00007 #include <net-snmp/net-snmp-config.h>
00008 
00009 #include <ctype.h>
00010 #include <stdio.h>
00011 #include <sys/types.h>
00012 #if TIME_WITH_SYS_TIME
00013 # ifdef WIN32
00014 #  include <sys/timeb.h>
00015 # else
00016 #  include <sys/time.h>
00017 # endif
00018 # include <time.h>
00019 #else
00020 # if HAVE_SYS_TIME_H
00021 #  include <sys/time.h>
00022 # else
00023 #  include <time.h>
00024 # endif
00025 #endif
00026 #ifdef HAVE_SYS_SOCKET_H
00027 #include <sys/socket.h>
00028 #endif
00029 #if HAVE_WINSOCK_H
00030 #include <winsock.h>
00031 #endif
00032 #ifdef HAVE_STDLIB_H
00033 #include <stdlib.h>
00034 #endif
00035 #if HAVE_STRING_H
00036 #include <string.h>
00037 #else
00038 #include <strings.h>
00039 #endif
00040 #ifdef HAVE_NETINET_IN_H
00041 #include <netinet/in.h>
00042 #endif
00043 #ifdef HAVE_ARPA_INET_H
00044 #include <arpa/inet.h>
00045 #endif
00046 #ifdef cygwin
00047 #include <windows.h>
00048 #endif
00049 
00050 #if HAVE_DMALLOC_H
00051 #include <dmalloc.h>
00052 #endif
00053 
00054 #include <net-snmp/types.h>
00055 #include <net-snmp/output_api.h>
00056 #include <net-snmp/utilities.h>
00057 #include <net-snmp/library/tools.h>     /* for "internal" definitions */
00058 
00059 #include <net-snmp/library/snmp_api.h>
00060 #include <net-snmp/library/mib.h>
00061 #include <net-snmp/library/scapi.h>
00062 
00063 #ifdef WIN32
00064 
00067 char * netsnmp_strdup( const char * ptr)
00068 {
00069     return strdup(ptr);
00070 }
00074 void * netsnmp_calloc(size_t nmemb, size_t size)
00075 {
00076     return calloc(nmemb, size);
00077 }
00078 
00082 void * netsnmp_malloc(size_t size)
00083 {
00084     return malloc(size);
00085 }
00086 
00090 void * netsnmp_realloc( void * ptr, size_t size)
00091 {
00092     return realloc(ptr, size);
00093 }
00094 
00099 void netsnmp_free( void * ptr)
00100 {
00101     if (ptr)
00102         free(ptr);
00103 }
00104 #endif /* WIN32 */
00105 
00120 int
00121 snmp_realloc(u_char ** buf, size_t * buf_len)
00122 {
00123     u_char         *new_buf = NULL;
00124     size_t          new_buf_len = 0;
00125 
00126     if (buf == NULL) {
00127         return 0;
00128     }
00129 
00130     if (*buf_len <= 255) {
00131         new_buf_len = *buf_len + 256;
00132     } else if (*buf_len > 255 && *buf_len <= 8191) {
00133         new_buf_len = *buf_len * 2;
00134     } else if (*buf_len > 8191) {
00135         new_buf_len = *buf_len + 8192;
00136     }
00137 
00138     if (*buf == NULL) {
00139         new_buf = (u_char *) malloc(new_buf_len);
00140     } else {
00141         new_buf = (u_char *) realloc(*buf, new_buf_len);
00142     }
00143 
00144     if (new_buf != NULL) {
00145         *buf = new_buf;
00146         *buf_len = new_buf_len;
00147         return 1;
00148     } else {
00149         return 0;
00150     }
00151 }
00152 
00153 int
00154 snmp_strcat(u_char ** buf, size_t * buf_len, size_t * out_len,
00155             int allow_realloc, const u_char * s)
00156 {
00157     if (buf == NULL || buf_len == NULL || out_len == NULL) {
00158         return 0;
00159     }
00160 
00161     if (s == NULL) {
00162         /*
00163          * Appending a NULL string always succeeds since it is a NOP.  
00164          */
00165         return 1;
00166     }
00167 
00168     while ((*out_len + strlen((const char *) s) + 1) >= *buf_len) {
00169         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00170             return 0;
00171         }
00172     }
00173 
00174     strcpy((char *) (*buf + *out_len), (const char *) s);
00175     *out_len += strlen((char *) (*buf + *out_len));
00176     return 1;
00177 }
00178 
00184 void
00185 free_zero(void *buf, size_t size)
00186 {
00187     if (buf) {
00188         memset(buf, 0, size);
00189         free(buf);
00190     }
00191 
00192 }                               /* end free_zero() */
00193 
00204 u_char         *
00205 malloc_random(size_t * size)
00206 {
00207     int             rval = SNMPERR_SUCCESS;
00208     u_char         *buf = (u_char *) calloc(1, *size);
00209 
00210     if (buf) {
00211         rval = sc_random(buf, size);
00212 
00213         if (rval < 0) {
00214             free_zero(buf, *size);
00215             buf = NULL;
00216         } else {
00217             *size = rval;
00218         }
00219     }
00220 
00221     return buf;
00222 
00223 }                               /* end malloc_random() */
00224 
00235 int
00236 memdup(u_char ** to, const u_char * from, size_t size)
00237 {
00238     if (to == NULL)
00239         return SNMPERR_GENERR;
00240     if (from == NULL) {
00241         *to = NULL;
00242         return SNMPERR_SUCCESS;
00243     }
00244     if ((*to = (u_char *) malloc(size)) == NULL)
00245         return SNMPERR_GENERR;
00246     memcpy(*to, from, size);
00247     return SNMPERR_SUCCESS;
00248 
00249 }                               /* end memdup() */
00250 
00254 char           *
00255 netsnmp_strdup_and_null(const u_char * from, size_t from_len)
00256 {
00257     char         *ret;
00258 
00259     if (from_len == 0 || from[from_len - 1] != '\0') {
00260         ret = malloc(from_len + 1);
00261         if (!ret)
00262             return NULL;
00263         ret[from_len] = '\0';
00264     } else {
00265         ret = malloc(from_len);
00266         if (!ret)
00267             return NULL;
00268         ret[from_len - 1] = '\0';
00269     }
00270     memcpy(ret, from, from_len);
00271     return ret;
00272 }
00273 
00286 u_int
00287 binary_to_hex(const u_char * input, size_t len, char **output)
00288 {
00289     u_int           olen = (len * 2) + 1;
00290     char           *s = (char *) calloc(1, olen), *op = s;
00291     const u_char   *ip = input;
00292 
00293 
00294     while (ip - input < (int) len) {
00295         *op++ = VAL2HEX((*ip >> 4) & 0xf);
00296         *op++ = VAL2HEX(*ip & 0xf);
00297         ip++;
00298     }
00299     *op = '\0';
00300 
00301     *output = s;
00302     return olen;
00303 
00304 }                               /* end binary_to_hex() */
00305 
00306 
00307 
00308 
00323 int
00324 hex_to_binary2(const u_char * input, size_t len, char **output)
00325 {
00326     u_int           olen = (len / 2) + (len % 2);
00327     char           *s = (char *) calloc(1, (olen) ? olen : 1), *op = s;
00328     const u_char   *ip = input;
00329 
00330 
00331     *output = NULL;
00332     *op = 0;
00333     if (len % 2) {
00334         if (!isxdigit(*ip))
00335             goto hex_to_binary2_quit;
00336         *op++ = HEX2VAL(*ip);
00337         ip++;
00338     }
00339 
00340     while (ip - input < (int) len) {
00341         if (!isxdigit(*ip))
00342             goto hex_to_binary2_quit;
00343         *op = HEX2VAL(*ip) << 4;
00344         ip++;
00345 
00346         if (!isxdigit(*ip))
00347             goto hex_to_binary2_quit;
00348         *op++ += HEX2VAL(*ip);
00349         ip++;
00350     }
00351 
00352     *output = s;
00353     return olen;
00354 
00355   hex_to_binary2_quit:
00356     free_zero(s, olen);
00357     return -1;
00358 
00359 }                               /* end hex_to_binary2() */
00360 
00361 int
00362 snmp_decimal_to_binary(u_char ** buf, size_t * buf_len, size_t * out_len,
00363                        int allow_realloc, const char *decimal)
00364 {
00365     int             subid = 0;
00366     const char     *cp = decimal;
00367 
00368     if (buf == NULL || buf_len == NULL || out_len == NULL
00369         || decimal == NULL) {
00370         return 0;
00371     }
00372 
00373     while (*cp != '\0') {
00374         if (isspace((int) *cp) || *cp == '.') {
00375             cp++;
00376             continue;
00377         }
00378         if (!isdigit((int) *cp)) {
00379             return 0;
00380         }
00381         if ((subid = atoi(cp)) > 255) {
00382             return 0;
00383         }
00384         if ((*out_len >= *buf_len) &&
00385             !(allow_realloc && snmp_realloc(buf, buf_len))) {
00386             return 0;
00387         }
00388         *(*buf + *out_len) = (u_char) subid;
00389         (*out_len)++;
00390         while (isdigit((int) *cp)) {
00391             cp++;
00392         }
00393     }
00394     return 1;
00395 }
00396 
00424 int
00425 netsnmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
00426                       int allow_realloc, const char *hex, const char *delim)
00427 {
00428     int             subid = 0;
00429     const char     *cp = hex;
00430 
00431     if (buf == NULL || buf_len == NULL || offset == NULL || hex == NULL) {
00432         return 0;
00433     }
00434 
00435     if ((*cp == '0') && ((*(cp + 1) == 'x') || (*(cp + 1) == 'X'))) {
00436         cp += 2;
00437     }
00438 
00439     while (*cp != '\0') {
00440         if (!isxdigit((int) *cp) ||
00441             !isxdigit((int) *(cp+1))) {
00442             if ((NULL != delim) && (NULL != strchr(delim, *cp))) {
00443                 cp++;
00444                 continue;
00445             }
00446             return 0;
00447         }
00448         if (sscanf(cp, "%2x", &subid) == 0) {
00449             return 0;
00450         }
00451         /*
00452          * if we dont' have enough space, realloc.
00453          * (snmp_realloc will adjust buf_len to new size)
00454          */
00455         if ((*offset >= *buf_len) &&
00456             !(allow_realloc && snmp_realloc(buf, buf_len))) {
00457             return 0;
00458         }
00459         *(*buf + *offset) = (u_char) subid;
00460         (*offset)++;
00461         if (*++cp == '\0') {
00462             /*
00463              * Odd number of hex digits is an error.  
00464              */
00465             return 0;
00466         } else {
00467             cp++;
00468         }
00469     }
00470     return 1;
00471 }
00472 
00484 int
00485 snmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
00486                    int allow_realloc, const char *hex)
00487 {
00488     return netsnmp_hex_to_binary(buf, buf_len, offset, allow_realloc, hex, " ");
00489 }
00490 
00491 /*******************************************************************-o-******
00492  * dump_chunk
00493  *
00494  * Parameters:
00495  *      *title  (May be NULL.)
00496  *      *buf
00497  *       size
00498  */
00499 void
00500 dump_chunk(const char *debugtoken, const char *title, const u_char * buf,
00501            int size)
00502 {
00503     u_int           printunit = 64;     /* XXX  Make global. */
00504     char            chunk[SNMP_MAXBUF], *s, *sp;
00505 
00506     if (title && (*title != '\0')) {
00507         DEBUGMSGTL((debugtoken, "%s\n", title));
00508     }
00509 
00510 
00511     memset(chunk, 0, SNMP_MAXBUF);
00512     size = binary_to_hex(buf, size, &s);
00513     sp = s;
00514 
00515     while (size > 0) {
00516         if (size > (int) printunit) {
00517             strncpy(chunk, sp, printunit);
00518             chunk[printunit] = '\0';
00519             DEBUGMSGTL((debugtoken, "\t%s\n", chunk));
00520         } else {
00521             DEBUGMSGTL((debugtoken, "\t%s\n", sp));
00522         }
00523 
00524         sp += printunit;
00525         size -= printunit;
00526     }
00527 
00528 
00529     SNMP_FREE(s);
00530 
00531 }                               /* end dump_chunk() */
00532 
00533 
00534 
00535 
00536 /*******************************************************************-o-******
00537  * dump_snmpEngineID
00538  *
00539  * Parameters:
00540  *      *estring
00541  *      *estring_len
00542  *      
00543  * Returns:
00544  *      Allocated memory pointing to a string of buflen char representing
00545  *      a printf'able form of the snmpEngineID.
00546  *
00547  *      -OR- NULL on error.
00548  *
00549  *
00550  * Translates the snmpEngineID TC into a printable string.  From RFC 2271,
00551  * Section 5 (pp. 36-37):
00552  *
00553  * First bit:   0       Bit string structured by means non-SNMPv3.
00554  *              1       Structure described by SNMPv3 SnmpEngineID TC.
00555  *  
00556  * Bytes 1-4:           Enterprise ID.  (High bit of first byte is ignored.)
00557  *  
00558  * Byte 5:      0       (RESERVED by IANA.)
00559  *              1       IPv4 address.           (   4 octets)
00560  *              2       IPv6 address.           (  16 octets)
00561  *              3       MAC address.            (   6 octets)
00562  *              4       Locally defined text.   (0-27 octets)
00563  *              5       Locally defined octets. (0-27 octets)
00564  *              6-127   (RESERVED for enterprise.)
00565  *  
00566  * Bytes 6-32:          (Determined by byte 5.)
00567  *  
00568  *
00569  * Non-printable characters are given in hex.  Text is given in quotes.
00570  * IP and MAC addresses are given in standard (UN*X) conventions.  Sections
00571  * are comma separated.
00572  *
00573  * esp, remaining_len and s trace the state of the constructed buffer.
00574  * s will be defined if there is something to return, and it will point
00575  * to the end of the constructed buffer.
00576  *
00577  *
00578  * ASSUME  "Text" means printable characters.
00579  *
00580  * XXX  Must the snmpEngineID always have a minimum length of 12?
00581  *      (Cf. part 2 of the TC definition.)
00582  * XXX  Does not enforce upper-bound of 32 bytes.
00583  * XXX  Need a switch to decide whether to use DNS name instead of a simple
00584  *      IP address.
00585  *
00586  * FIX  Use something other than snprint_hexstring which doesn't add 
00587  *      trailing spaces and (sometimes embedded) newlines...
00588  */
00589 #ifdef SNMP_TESTING_CODE
00590 char           *
00591 dump_snmpEngineID(const u_char * estring, size_t * estring_len)
00592 {
00593 #define eb(b)   ( *(esp+b) & 0xff )
00594 
00595     int             rval = SNMPERR_SUCCESS, gotviolation = 0, slen = 0;
00596     u_int           remaining_len;
00597 
00598     char            buf[SNMP_MAXBUF], *s = NULL, *t;
00599     const u_char   *esp = estring;
00600 
00601     struct in_addr  iaddr;
00602 
00603 
00604 
00605     /*
00606      * Sanity check.
00607      */
00608     if (!estring || (*estring_len <= 0)) {
00609         QUITFUN(SNMPERR_GENERR, dump_snmpEngineID_quit);
00610     }
00611     remaining_len = *estring_len;
00612     memset(buf, 0, SNMP_MAXBUF);
00613 
00614 
00615 
00616     /*
00617      * Test first bit.  Return immediately with a hex string, or
00618      * begin by formatting the enterprise ID.
00619      */
00620     if (!(*esp & 0x80)) {
00621         snprint_hexstring(buf, SNMP_MAXBUF, esp, remaining_len);
00622         s = strchr(buf, '\0');
00623         s -= 1;
00624         goto dump_snmpEngineID_quit;
00625     }
00626 
00627     s = buf;
00628     s += sprintf(s, "enterprise %d, ", ((*(esp + 0) & 0x7f) << 24) |
00629                  ((*(esp + 1) & 0xff) << 16) |
00630                  ((*(esp + 2) & 0xff) << 8) | ((*(esp + 3) & 0xff)));
00631     /*
00632      * XXX  Ick. 
00633      */
00634 
00635     if (remaining_len < 5) {    /* XXX  Violating string. */
00636         goto dump_snmpEngineID_quit;
00637     }
00638 
00639     esp += 4;                   /* Incremented one more in the switch below. */
00640     remaining_len -= 5;
00641 
00642 
00643 
00644     /*
00645      * Act on the fifth byte.
00646      */
00647     switch ((int) *esp++) {
00648     case 1:                    /* IPv4 address. */
00649 
00650         if (remaining_len < 4)
00651             goto dump_snmpEngineID_violation;
00652         memcpy(&iaddr.s_addr, esp, 4);
00653 
00654         if (!(t = inet_ntoa(iaddr)))
00655             goto dump_snmpEngineID_violation;
00656         s += sprintf(s, "%s", t);
00657 
00658         esp += 4;
00659         remaining_len -= 4;
00660         break;
00661 
00662     case 2:                    /* IPv6 address. */
00663 
00664         if (remaining_len < 16)
00665             goto dump_snmpEngineID_violation;
00666 
00667         s += sprintf(s,
00668                      "%02X%02X %02X%02X %02X%02X %02X%02X::"
00669                      "%02X%02X %02X%02X %02X%02X %02X%02X",
00670                      eb(0), eb(1), eb(2), eb(3),
00671                      eb(4), eb(5), eb(6), eb(7),
00672                      eb(8), eb(9), eb(10), eb(11),
00673                      eb(12), eb(13), eb(14), eb(15));
00674 
00675         esp += 16;
00676         remaining_len -= 16;
00677         break;
00678 
00679     case 3:                    /* MAC address. */
00680 
00681         if (remaining_len < 6)
00682             goto dump_snmpEngineID_violation;
00683 
00684         s += sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X",
00685                      eb(0), eb(1), eb(2), eb(3), eb(4), eb(5));
00686 
00687         esp += 6;
00688         remaining_len -= 6;
00689         break;
00690 
00691     case 4:                    /* Text. */
00692 
00693         /*
00694          * Doesn't exist on all (many) architectures 
00695          */
00696         /*
00697          * s += snprintf(s, remaining_len+3, "\"%s\"", esp); 
00698          */
00699         s += sprintf(s, "\"%s\"", esp);
00700         goto dump_snmpEngineID_quit;
00701         break;
00702      /*NOTREACHED*/ case 5:    /* Octets. */
00703 
00704         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00705                           esp, remaining_len);
00706         s = strchr(buf, '\0');
00707         s -= 1;
00708         goto dump_snmpEngineID_quit;
00709         break;
00710        /*NOTREACHED*/ dump_snmpEngineID_violation:
00711     case 0:                    /* Violation of RESERVED, 
00712                                  * *   -OR- of expected length.
00713                                  */
00714         gotviolation = 1;
00715         s += sprintf(s, "!!! ");
00716 
00717     default:                   /* Unknown encoding. */
00718 
00719         if (!gotviolation) {
00720             s += sprintf(s, "??? ");
00721         }
00722         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00723                           esp, remaining_len);
00724         s = strchr(buf, '\0');
00725         s -= 1;
00726 
00727         goto dump_snmpEngineID_quit;
00728 
00729     }                           /* endswitch */
00730 
00731 
00732 
00733     /*
00734      * Cases 1-3 (IP and MAC addresses) should not have trailing
00735      * octets, but perhaps they do.  Throw them in too.  XXX
00736      */
00737     if (remaining_len > 0) {
00738         s += sprintf(s, " (??? ");
00739 
00740         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00741                           esp, remaining_len);
00742         s = strchr(buf, '\0');
00743         s -= 1;
00744 
00745         s += sprintf(s, ")");
00746     }
00747 
00748 
00749 
00750   dump_snmpEngineID_quit:
00751     if (s) {
00752         slen = s - buf + 1;
00753         s = calloc(1, slen);
00754         memcpy(s, buf, (slen) - 1);
00755     }
00756 
00757     memset(buf, 0, SNMP_MAXBUF);        /* XXX -- Overkill? XXX: Yes! */
00758 
00759     return s;
00760 
00761 #undef eb
00762 }                               /* end dump_snmpEngineID() */
00763 #endif                          /* SNMP_TESTING_CODE */
00764 
00765 
00770 marker_t
00771 atime_newMarker(void)
00772 {
00773     marker_t        pm = (marker_t) calloc(1, sizeof(struct timeval));
00774     gettimeofday((struct timeval *) pm, 0);
00775     return pm;
00776 }
00777 
00781 void
00782 atime_setMarker(marker_t pm)
00783 {
00784     if (!pm)
00785         return;
00786 
00787     gettimeofday((struct timeval *) pm, 0);
00788 }
00789 
00790 
00794 long
00795 atime_diff(marker_t first, marker_t second)
00796 {
00797     struct timeval *tv1, *tv2, diff;
00798 
00799     tv1 = (struct timeval *) first;
00800     tv2 = (struct timeval *) second;
00801 
00802     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00803     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00804 
00805     return (diff.tv_sec * 1000 + diff.tv_usec / 1000);
00806 }
00807 
00811 u_long
00812 uatime_diff(marker_t first, marker_t second)
00813 {
00814     struct timeval *tv1, *tv2, diff;
00815 
00816     tv1 = (struct timeval *) first;
00817     tv2 = (struct timeval *) second;
00818 
00819     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00820     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00821 
00822     return (((u_long) diff.tv_sec) * 1000 + diff.tv_usec / 1000);
00823 }
00824 
00829 u_long
00830 uatime_hdiff(marker_t first, marker_t second)
00831 {
00832     struct timeval *tv1, *tv2, diff;
00833     u_long          res;
00834 
00835     tv1 = (struct timeval *) first;
00836     tv2 = (struct timeval *) second;
00837 
00838     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00839     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00840 
00841     res = ((u_long) diff.tv_sec) * 100 + diff.tv_usec / 10000;
00842     return res;
00843 }
00844 
00849 int
00850 atime_ready(marker_t pm, int deltaT)
00851 {
00852     marker_t        now;
00853     long            diff;
00854     if (!pm)
00855         return 0;
00856 
00857     now = atime_newMarker();
00858 
00859     diff = atime_diff(pm, now);
00860     free(now);
00861     if (diff < deltaT)
00862         return 0;
00863 
00864     return 1;
00865 }
00866 
00871 int
00872 uatime_ready(marker_t pm, unsigned int deltaT)
00873 {
00874     marker_t        now;
00875     u_long          diff;
00876     if (!pm)
00877         return 0;
00878 
00879     now = atime_newMarker();
00880 
00881     diff = uatime_diff(pm, now);
00882     free(now);
00883     if (diff < deltaT)
00884         return 0;
00885 
00886     return 1;
00887 }
00888 
00889 
00890         /*
00891          * Time-related utility functions
00892          */
00893 
00897 int
00898 marker_tticks(marker_t pm)
00899 {
00900     int             res;
00901     marker_t        now = atime_newMarker();
00902 
00903     res = atime_diff(pm, now);
00904     free(now);
00905     return res / 10;            /* atime_diff works in msec, not csec */
00906 }
00907 
00908 int
00909 timeval_tticks(struct timeval *tv)
00910 {
00911     return marker_tticks((marker_t) tv);
00912 }
00913 
00926 char *netsnmp_getenv(const char *name)
00927 {
00928 #if !defined (WIN32) && !defined (cygwin)
00929   return (getenv(name));
00930 #else
00931   char *temp = NULL;  
00932   HKEY hKey;
00933   unsigned char * key_value = NULL;
00934   DWORD key_value_size = 0;
00935   DWORD key_value_type = 0;
00936   DWORD getenv_worked = 0;
00937 
00938   DEBUGMSGTL(("read_config", "netsnmp_getenv called with name: %s\n",name));
00939 
00940   if (!(name))
00941     return NULL;
00942   
00943   /* Try environment variable first */ 
00944   temp = getenv(name);
00945   if (temp) {
00946     getenv_worked = 1;
00947     DEBUGMSGTL(("read_config", "netsnmp_getenv will return from ENV: %s\n",temp));
00948   }
00949   
00950   /* Next try HKCU */
00951   if (temp == NULL)
00952   {
00953     if (RegOpenKeyExA(
00954           HKEY_CURRENT_USER, 
00955           "SOFTWARE\\Net-SNMP", 
00956           0, 
00957           KEY_QUERY_VALUE, 
00958           &hKey) == ERROR_SUCCESS) {   
00959       
00960       if (RegQueryValueExA(
00961             hKey, 
00962             name, 
00963             NULL, 
00964             &key_value_type, 
00965             NULL,               /* Just get the size */
00966             &key_value_size) == ERROR_SUCCESS) {
00967 
00968         if (key_value)
00969           SNMP_FREE(key_value);
00970 
00971         /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
00972          * string data in registry is missing one (which is unlikely).
00973          */
00974         key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char));
00975         
00976         if (RegQueryValueExA(
00977               hKey, 
00978               name, 
00979               NULL, 
00980               &key_value_type, 
00981               key_value, 
00982               &key_value_size) == ERROR_SUCCESS) {
00983         }
00984         temp = key_value;
00985       }
00986       RegCloseKey(hKey);
00987       if (temp)
00988         DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKCU: %s\n",temp));
00989     }
00990   }
00991 
00992   /* Next try HKLM */
00993   if (temp == NULL)
00994   {
00995     if (RegOpenKeyExA(
00996           HKEY_LOCAL_MACHINE, 
00997           "SOFTWARE\\Net-SNMP", 
00998           0, 
00999           KEY_QUERY_VALUE, 
01000           &hKey) == ERROR_SUCCESS) {   
01001       
01002       if (RegQueryValueExA(
01003             hKey, 
01004             name, 
01005             NULL, 
01006             &key_value_type, 
01007             NULL,               /* Just get the size */
01008             &key_value_size) == ERROR_SUCCESS) {
01009 
01010         if (key_value)
01011           SNMP_FREE(key_value);
01012 
01013         /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
01014          * string data in registry is missing one (which is unlikely).
01015          */
01016         key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char));
01017         
01018         if (RegQueryValueExA(
01019               hKey, 
01020               name, 
01021               NULL, 
01022               &key_value_type, 
01023               key_value, 
01024               &key_value_size) == ERROR_SUCCESS) {
01025         }
01026         temp = key_value;
01027 
01028       }
01029       RegCloseKey(hKey);
01030       if (temp)
01031         DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKLM: %s\n",temp));
01032     }
01033   }
01034   
01035   if (temp && !getenv_worked) {
01036     setenv(name, temp, 1);
01037     SNMP_FREE(temp);
01038   }
01039 
01040   DEBUGMSGTL(("read_config", "netsnmp_getenv returning: %s\n",getenv(name)));
01041 
01042   return(getenv(name));
01043 #endif
01044 }
01045 
01046 /*
01047  * swap the order of an inet addr string
01048  */
01049 int
01050 netsnmp_addrstr_hton(char *ptr, size_t len)
01051 {
01052 #ifndef WORDS_BIGENDIAN
01053     char tmp[8];
01054     
01055     if (8 == len) {
01056         tmp[0] = ptr[6];
01057         tmp[1] = ptr[7];
01058         tmp[2] = ptr[4];
01059         tmp[3] = ptr[5];
01060         tmp[4] = ptr[2];
01061         tmp[5] = ptr[3];
01062         tmp[6] = ptr[0];
01063         tmp[7] = ptr[1];
01064         memcpy (ptr, &tmp, 8);
01065     }
01066     else if (32 == len) {
01067         netsnmp_addrstr_hton(ptr   , 8);
01068         netsnmp_addrstr_hton(ptr+8 , 8);
01069         netsnmp_addrstr_hton(ptr+16, 8);
01070         netsnmp_addrstr_hton(ptr+24, 8);
01071     }
01072     else
01073         return -1;
01074 #endif
01075 
01076     return 0;
01077 }

net-snmpに対してSat Sep 5 13:14:28 2009に生成されました。  doxygen 1.4.7