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
1.3.9.1
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.