Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
Main Page | Modules | Data Structures | File List | Data Fields | Related Pages | Examples

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     u_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             if ((NULL != delim) && (NULL != strchr(delim, *cp))) {
00442                 cp++;
00443                 continue;
00444             }
00445             return 0;
00446         }
00447         if (sscanf(cp, "%2x", &subid) == 0) {
00448             return 0;
00449         }
00450         /*
00451          * if we dont' have enough space, realloc.
00452          * (snmp_realloc will adjust buf_len to new size)
00453          */
00454         if ((*offset >= *buf_len) &&
00455             !(allow_realloc && snmp_realloc(buf, buf_len))) {
00456             return 0;
00457         }
00458         *(*buf + *offset) = (u_char) subid;
00459         (*offset)++;
00460         if (*++cp == '\0') {
00461             /*
00462              * Odd number of hex digits is an error.  
00463              */
00464             return 0;
00465         } else {
00466             cp++;
00467         }
00468     }
00469     return 1;
00470 }
00471 
00483 int
00484 snmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
00485                    int allow_realloc, const char *hex)
00486 {
00487     return netsnmp_hex_to_binary(buf, buf_len, offset, allow_realloc, hex, " ");
00488 }
00489 
00490 /*******************************************************************-o-******
00491  * dump_chunk
00492  *
00493  * Parameters:
00494  *      *title  (May be NULL.)
00495  *      *buf
00496  *       size
00497  */
00498 void
00499 dump_chunk(const char *debugtoken, const char *title, const u_char * buf,
00500            int size)
00501 {
00502     u_int           printunit = 64;     /* XXX  Make global. */
00503     char            chunk[SNMP_MAXBUF], *s, *sp;
00504 
00505     if (title && (*title != '\0')) {
00506         DEBUGMSGTL((debugtoken, "%s\n", title));
00507     }
00508 
00509 
00510     memset(chunk, 0, SNMP_MAXBUF);
00511     size = binary_to_hex(buf, size, &s);
00512     sp = s;
00513 
00514     while (size > 0) {
00515         if (size > (int) printunit) {
00516             strncpy(chunk, sp, printunit);
00517             chunk[printunit] = '\0';
00518             DEBUGMSGTL((debugtoken, "\t%s\n", chunk));
00519         } else {
00520             DEBUGMSGTL((debugtoken, "\t%s\n", sp));
00521         }
00522 
00523         sp += printunit;
00524         size -= printunit;
00525     }
00526 
00527 
00528     SNMP_FREE(s);
00529 
00530 }                               /* end dump_chunk() */
00531 
00532 
00533 
00534 
00535 /*******************************************************************-o-******
00536  * dump_snmpEngineID
00537  *
00538  * Parameters:
00539  *      *estring
00540  *      *estring_len
00541  *      
00542  * Returns:
00543  *      Allocated memory pointing to a string of buflen char representing
00544  *      a printf'able form of the snmpEngineID.
00545  *
00546  *      -OR- NULL on error.
00547  *
00548  *
00549  * Translates the snmpEngineID TC into a printable string.  From RFC 2271,
00550  * Section 5 (pp. 36-37):
00551  *
00552  * First bit:   0       Bit string structured by means non-SNMPv3.
00553  *              1       Structure described by SNMPv3 SnmpEngineID TC.
00554  *  
00555  * Bytes 1-4:           Enterprise ID.  (High bit of first byte is ignored.)
00556  *  
00557  * Byte 5:      0       (RESERVED by IANA.)
00558  *              1       IPv4 address.           (   4 octets)
00559  *              2       IPv6 address.           (  16 octets)
00560  *              3       MAC address.            (   6 octets)
00561  *              4       Locally defined text.   (0-27 octets)
00562  *              5       Locally defined octets. (0-27 octets)
00563  *              6-127   (RESERVED for enterprise.)
00564  *  
00565  * Bytes 6-32:          (Determined by byte 5.)
00566  *  
00567  *
00568  * Non-printable characters are given in hex.  Text is given in quotes.
00569  * IP and MAC addresses are given in standard (UN*X) conventions.  Sections
00570  * are comma separated.
00571  *
00572  * esp, remaining_len and s trace the state of the constructed buffer.
00573  * s will be defined if there is something to return, and it will point
00574  * to the end of the constructed buffer.
00575  *
00576  *
00577  * ASSUME  "Text" means printable characters.
00578  *
00579  * XXX  Must the snmpEngineID always have a minimum length of 12?
00580  *      (Cf. part 2 of the TC definition.)
00581  * XXX  Does not enforce upper-bound of 32 bytes.
00582  * XXX  Need a switch to decide whether to use DNS name instead of a simple
00583  *      IP address.
00584  *
00585  * FIX  Use something other than snprint_hexstring which doesn't add 
00586  *      trailing spaces and (sometimes embedded) newlines...
00587  */
00588 #ifdef SNMP_TESTING_CODE
00589 char           *
00590 dump_snmpEngineID(const u_char * estring, size_t * estring_len)
00591 {
00592 #define eb(b)   ( *(esp+b) & 0xff )
00593 
00594     int             rval = SNMPERR_SUCCESS, gotviolation = 0, slen = 0;
00595     u_int           remaining_len;
00596 
00597     char            buf[SNMP_MAXBUF], *s = NULL, *t;
00598     const u_char   *esp = estring;
00599 
00600     struct in_addr  iaddr;
00601 
00602 
00603 
00604     /*
00605      * Sanity check.
00606      */
00607     if (!estring || (*estring_len <= 0)) {
00608         QUITFUN(SNMPERR_GENERR, dump_snmpEngineID_quit);
00609     }
00610     remaining_len = *estring_len;
00611     memset(buf, 0, SNMP_MAXBUF);
00612 
00613 
00614 
00615     /*
00616      * Test first bit.  Return immediately with a hex string, or
00617      * begin by formatting the enterprise ID.
00618      */
00619     if (!(*esp & 0x80)) {
00620         snprint_hexstring(buf, SNMP_MAXBUF, esp, remaining_len);
00621         s = strchr(buf, '\0');
00622         s -= 1;
00623         goto dump_snmpEngineID_quit;
00624     }
00625 
00626     s = buf;
00627     s += sprintf(s, "enterprise %d, ", ((*(esp + 0) & 0x7f) << 24) |
00628                  ((*(esp + 1) & 0xff) << 16) |
00629                  ((*(esp + 2) & 0xff) << 8) | ((*(esp + 3) & 0xff)));
00630     /*
00631      * XXX  Ick. 
00632      */
00633 
00634     if (remaining_len < 5) {    /* XXX  Violating string. */
00635         goto dump_snmpEngineID_quit;
00636     }
00637 
00638     esp += 4;                   /* Incremented one more in the switch below. */
00639     remaining_len -= 5;
00640 
00641 
00642 
00643     /*
00644      * Act on the fifth byte.
00645      */
00646     switch ((int) *esp++) {
00647     case 1:                    /* IPv4 address. */
00648 
00649         if (remaining_len < 4)
00650             goto dump_snmpEngineID_violation;
00651         memcpy(&iaddr.s_addr, esp, 4);
00652 
00653         if (!(t = inet_ntoa(iaddr)))
00654             goto dump_snmpEngineID_violation;
00655         s += sprintf(s, "%s", t);
00656 
00657         esp += 4;
00658         remaining_len -= 4;
00659         break;
00660 
00661     case 2:                    /* IPv6 address. */
00662 
00663         if (remaining_len < 16)
00664             goto dump_snmpEngineID_violation;
00665 
00666         s += sprintf(s,
00667                      "%02X%02X %02X%02X %02X%02X %02X%02X::"
00668                      "%02X%02X %02X%02X %02X%02X %02X%02X",
00669                      eb(0), eb(1), eb(2), eb(3),
00670                      eb(4), eb(5), eb(6), eb(7),
00671                      eb(8), eb(9), eb(10), eb(11),
00672                      eb(12), eb(13), eb(14), eb(15));
00673 
00674         esp += 16;
00675         remaining_len -= 16;
00676         break;
00677 
00678     case 3:                    /* MAC address. */
00679 
00680         if (remaining_len < 6)
00681             goto dump_snmpEngineID_violation;
00682 
00683         s += sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X",
00684                      eb(0), eb(1), eb(2), eb(3), eb(4), eb(5));
00685 
00686         esp += 6;
00687         remaining_len -= 6;
00688         break;
00689 
00690     case 4:                    /* Text. */
00691 
00692         /*
00693          * Doesn't exist on all (many) architectures 
00694          */
00695         /*
00696          * s += snprintf(s, remaining_len+3, "\"%s\"", esp); 
00697          */
00698         s += sprintf(s, "\"%s\"", esp);
00699         goto dump_snmpEngineID_quit;
00700         break;
00701      /*NOTREACHED*/ case 5:    /* Octets. */
00702 
00703         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00704                           esp, remaining_len);
00705         s = strchr(buf, '\0');
00706         s -= 1;
00707         goto dump_snmpEngineID_quit;
00708         break;
00709        /*NOTREACHED*/ dump_snmpEngineID_violation:
00710     case 0:                    /* Violation of RESERVED, 
00711                                  * *   -OR- of expected length.
00712                                  */
00713         gotviolation = 1;
00714         s += sprintf(s, "!!! ");
00715 
00716     default:                   /* Unknown encoding. */
00717 
00718         if (!gotviolation) {
00719             s += sprintf(s, "??? ");
00720         }
00721         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00722                           esp, remaining_len);
00723         s = strchr(buf, '\0');
00724         s -= 1;
00725 
00726         goto dump_snmpEngineID_quit;
00727 
00728     }                           /* endswitch */
00729 
00730 
00731 
00732     /*
00733      * Cases 1-3 (IP and MAC addresses) should not have trailing
00734      * octets, but perhaps they do.  Throw them in too.  XXX
00735      */
00736     if (remaining_len > 0) {
00737         s += sprintf(s, " (??? ");
00738 
00739         snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
00740                           esp, remaining_len);
00741         s = strchr(buf, '\0');
00742         s -= 1;
00743 
00744         s += sprintf(s, ")");
00745     }
00746 
00747 
00748 
00749   dump_snmpEngineID_quit:
00750     if (s) {
00751         slen = s - buf + 1;
00752         s = calloc(1, slen);
00753         memcpy(s, buf, (slen) - 1);
00754     }
00755 
00756     memset(buf, 0, SNMP_MAXBUF);        /* XXX -- Overkill? XXX: Yes! */
00757 
00758     return s;
00759 
00760 #undef eb
00761 }                               /* end dump_snmpEngineID() */
00762 #endif                          /* SNMP_TESTING_CODE */
00763 
00764 
00769 marker_t
00770 atime_newMarker(void)
00771 {
00772     marker_t        pm = (marker_t) calloc(1, sizeof(struct timeval));
00773     gettimeofday((struct timeval *) pm, 0);
00774     return pm;
00775 }
00776 
00780 void
00781 atime_setMarker(marker_t pm)
00782 {
00783     if (!pm)
00784         return;
00785 
00786     gettimeofday((struct timeval *) pm, 0);
00787 }
00788 
00789 
00793 long
00794 atime_diff(marker_t first, marker_t second)
00795 {
00796     struct timeval *tv1, *tv2, diff;
00797 
00798     tv1 = (struct timeval *) first;
00799     tv2 = (struct timeval *) second;
00800 
00801     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00802     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00803 
00804     return (diff.tv_sec * 1000 + diff.tv_usec / 1000);
00805 }
00806 
00810 u_long
00811 uatime_diff(marker_t first, marker_t second)
00812 {
00813     struct timeval *tv1, *tv2, diff;
00814 
00815     tv1 = (struct timeval *) first;
00816     tv2 = (struct timeval *) second;
00817 
00818     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00819     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00820 
00821     return (((u_long) diff.tv_sec) * 1000 + diff.tv_usec / 1000);
00822 }
00823 
00828 u_long
00829 uatime_hdiff(marker_t first, marker_t second)
00830 {
00831     struct timeval *tv1, *tv2, diff;
00832     u_long          res;
00833 
00834     tv1 = (struct timeval *) first;
00835     tv2 = (struct timeval *) second;
00836 
00837     diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1;
00838     diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000;
00839 
00840     res = ((u_long) diff.tv_sec) * 100 + diff.tv_usec / 10000;
00841     return res;
00842 }
00843 
00848 int
00849 atime_ready(marker_t pm, int deltaT)
00850 {
00851     marker_t        now;
00852     long            diff;
00853     if (!pm)
00854         return 0;
00855 
00856     now = atime_newMarker();
00857 
00858     diff = atime_diff(pm, now);
00859     free(now);
00860     if (diff < deltaT)
00861         return 0;
00862 
00863     return 1;
00864 }
00865 
00870 int
00871 uatime_ready(marker_t pm, unsigned int deltaT)
00872 {
00873     marker_t        now;
00874     u_long          diff;
00875     if (!pm)
00876         return 0;
00877 
00878     now = atime_newMarker();
00879 
00880     diff = uatime_diff(pm, now);
00881     free(now);
00882     if (diff < deltaT)
00883         return 0;
00884 
00885     return 1;
00886 }
00887 
00888 
00889         /*
00890          * Time-related utility functions
00891          */
00892 
00896 int
00897 marker_tticks(marker_t pm)
00898 {
00899     int             res;
00900     marker_t        now = atime_newMarker();
00901 
00902     res = atime_diff(pm, now);
00903     free(now);
00904     return res / 10;            /* atime_diff works in msec, not csec */
00905 }
00906 
00907 int
00908 timeval_tticks(struct timeval *tv)
00909 {
00910     return marker_tticks((marker_t) tv);
00911 }
00912 
00925 char *netsnmp_getenv(const char *name)
00926 {
00927 #if !defined (WIN32) && !defined (cygwin)
00928   return (getenv(name));
00929 #else
00930   char *temp = NULL;  
00931   HKEY hKey;
00932   unsigned char * key_value = NULL;
00933   DWORD key_value_size = 0;
00934   DWORD key_value_type = 0;
00935   DWORD getenv_worked = 0;
00936 
00937   DEBUGMSGTL(("read_config", "netsnmp_getenv called with name: %s\n",name));
00938 
00939   if (!(name))
00940     return NULL;
00941   
00942   /* Try environment variable first */ 
00943   temp = getenv(name);
00944   if (temp) {
00945     getenv_worked = 1;
00946     DEBUGMSGTL(("read_config", "netsnmp_getenv will return from ENV: %s\n",temp));
00947   }
00948   
00949   /* Next try HKCU */
00950   if (temp == NULL)
00951   {
00952     if (RegOpenKeyExA(
00953           HKEY_CURRENT_USER, 
00954           "SOFTWARE\\Net-SNMP", 
00955           0, 
00956           KEY_QUERY_VALUE, 
00957           &hKey) == ERROR_SUCCESS) {   
00958       
00959       if (RegQueryValueExA(
00960             hKey, 
00961             name, 
00962             NULL, 
00963             &key_value_type, 
00964             NULL,               /* Just get the size */
00965             &key_value_size) == ERROR_SUCCESS) {
00966 
00967         if (key_value)
00968           SNMP_FREE(key_value);
00969 
00970         /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
00971          * string data in registry is missing one (which is unlikely).
00972          */
00973         key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char));
00974         
00975         if (RegQueryValueExA(
00976               hKey, 
00977               name, 
00978               NULL, 
00979               &key_value_type, 
00980               key_value, 
00981               &key_value_size) == ERROR_SUCCESS) {
00982         }
00983         temp = key_value;
00984       }
00985       RegCloseKey(hKey);
00986       if (temp)
00987         DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKCU: %s\n",temp));
00988     }
00989   }
00990 
00991   /* Next try HKLM */
00992   if (temp == NULL)
00993   {
00994     if (RegOpenKeyExA(
00995           HKEY_LOCAL_MACHINE, 
00996           "SOFTWARE\\Net-SNMP", 
00997           0, 
00998           KEY_QUERY_VALUE, 
00999           &hKey) == ERROR_SUCCESS) {   
01000       
01001       if (RegQueryValueExA(
01002             hKey, 
01003             name, 
01004             NULL, 
01005             &key_value_type, 
01006             NULL,               /* Just get the size */
01007             &key_value_size) == ERROR_SUCCESS) {
01008 
01009         if (key_value)
01010           SNMP_FREE(key_value);
01011 
01012         /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
01013          * string data in registry is missing one (which is unlikely).
01014          */
01015         key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char));
01016         
01017         if (RegQueryValueExA(
01018               hKey, 
01019               name, 
01020               NULL, 
01021               &key_value_type, 
01022               key_value, 
01023               &key_value_size) == ERROR_SUCCESS) {
01024         }
01025         temp = key_value;
01026 
01027       }
01028       RegCloseKey(hKey);
01029       if (temp)
01030         DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKLM: %s\n",temp));
01031     }
01032   }
01033   
01034   if (temp && !getenv_worked) {
01035     setenv(name, temp, 1);
01036     SNMP_FREE(temp);
01037   }
01038 
01039   DEBUGMSGTL(("read_config", "netsnmp_getenv returning: %s\n",getenv(name)));
01040 
01041   return(getenv(name));
01042 #endif
01043 }
01044 

Generated on Fri Dec 30 13:47:51 2005 for net-snmp by  doxygen 1.3.9.1

Valid CSS!


Last modified: Thursday, 01-Mar-2007 16:20:12 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.