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

mib.c

00001 /*
00002  * mib.c
00003  *
00004  * $Id: mib_8c-source.html 14005 2005-12-30 19:14:23Z alex_b $
00005  *
00006  * Update: 1998-07-17 <jhy@gsu.edu>
00007  * Added print_oid_report* functions.
00008  *
00009  */
00010 /* Portions of this file are subject to the following copyrights.  See
00011  * the Net-SNMP's COPYING file for more details and other copyrights
00012  * that may apply:
00013  */
00014 /**********************************************************************
00015         Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00016 
00017                       All Rights Reserved
00018 
00019 Permission to use, copy, modify, and distribute this software and its
00020 documentation for any purpose and without fee is hereby granted,
00021 provided that the above copyright notice appear in all copies and that
00022 both that copyright notice and this permission notice appear in
00023 supporting documentation, and that the name of CMU not be
00024 used in advertising or publicity pertaining to distribution of the
00025 software without specific, written prior permission.
00026 
00027 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
00028 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00029 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
00030 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00031 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00032 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00033 SOFTWARE.
00034 ******************************************************************/
00035 /*
00036  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
00037  * Use is subject to license terms specified in the COPYING file
00038  * distributed with the Net-SNMP package.
00039  */
00040 #include <net-snmp/net-snmp-config.h>
00041 
00042 #include <stdio.h>
00043 #include <ctype.h>
00044 #include <sys/types.h>
00045 #if HAVE_NETINET_IN_H
00046 #include <netinet/in.h>
00047 #endif
00048 #if TIME_WITH_SYS_TIME
00049 # ifdef WIN32
00050 #  include <sys/timeb.h>
00051 # else
00052 #  include <sys/time.h>
00053 # endif
00054 # include <time.h>
00055 #else
00056 # if HAVE_SYS_TIME_H
00057 #  include <sys/time.h>
00058 # else
00059 #  include <time.h>
00060 # endif
00061 #endif
00062 #if HAVE_STRING_H
00063 #include <string.h>
00064 #else
00065 #include <strings.h>
00066 #endif
00067 #if HAVE_STDLIB_H
00068 #include <stdlib.h>
00069 #endif
00070 #if HAVE_SYS_SELECT_H
00071 #include <sys/select.h>
00072 #endif
00073 
00074 #if HAVE_WINSOCK_H
00075 #include <winsock.h>
00076 #endif
00077 
00078 #if HAVE_DMALLOC_H
00079 #include <dmalloc.h>
00080 #endif
00081 
00082 #include <net-snmp/types.h>
00083 #include <net-snmp/output_api.h>
00084 #include <net-snmp/config_api.h>
00085 #include <net-snmp/utilities.h>
00086 
00087 #include <net-snmp/library/asn1.h>
00088 #include <net-snmp/library/snmp_api.h>
00089 #include <net-snmp/library/mib.h>
00090 #include <net-snmp/library/parse.h>
00091 #include <net-snmp/library/int64.h>
00092 #include <net-snmp/library/snmp_client.h>
00093 
00100 static char    *uptimeString(u_long, char *, size_t);
00101 
00102 static struct tree *_get_realloc_symbol(const oid * objid, size_t objidlen,
00103                                         struct tree *subtree,
00104                                         u_char ** buf, size_t * buf_len,
00105                                         size_t * out_len,
00106                                         int allow_realloc,
00107                                         int *buf_overflow,
00108                                         struct index_list *in_dices,
00109                                         size_t * end_of_known);
00110 
00111 static int      print_tree_node(u_char ** buf, size_t * buf_len,
00112                                 size_t * out_len, int allow_realloc,
00113                                 struct tree *tp, int width);
00114 static void     handle_mibdirs_conf(const char *token, char *line);
00115 static void     handle_mibs_conf(const char *token, char *line);
00116 static void     handle_mibfile_conf(const char *token, char *line);
00117 
00118 static void     _oid_finish_printing(const oid * objid, size_t objidlen,
00119                                      u_char ** buf, size_t * buf_len,
00120                                      size_t * out_len,
00121                                      int allow_realloc, int *buf_overflow);
00122 
00123 /*
00124  * helper functions for get_module_node 
00125  */
00126 static int      node_to_oid(struct tree *, oid *, size_t *);
00127 #ifndef DISABLE_MIB_LOADING
00128 static int      _add_strings_to_oid(struct tree *, char *,
00129                                     oid *, size_t *, size_t);
00130 #else
00131 static int      _add_strings_to_oid(void *, char *,
00132                                     oid *, size_t *, size_t);
00133 #endif /* DISABLE_MIB_LOADING */
00134 
00135 #ifndef DISABLE_MIB_LOADING
00136 extern struct tree *tree_head;
00137 static struct tree *tree_top;
00138 
00139 struct tree    *Mib;            /* Backwards compatibility */
00140 #endif /* DISABLE_MIB_LOADING */
00141 
00142 oid             RFC1213_MIB[] = { 1, 3, 6, 1, 2, 1 };
00143 static char     Standard_Prefix[] = ".1.3.6.1.2.1";
00144 
00145 /*
00146  * Set default here as some uses of read_objid require valid pointer. 
00147  */
00148 static char    *Prefix = &Standard_Prefix[0];
00149 typedef struct _PrefixList {
00150     const char     *str;
00151     int             len;
00152 }              *PrefixListPtr, PrefixList;
00153 
00154 /*
00155  * Here are the prefix strings.
00156  * Note that the first one finds the value of Prefix or Standard_Prefix.
00157  * Any of these MAY start with period; all will NOT end with period.
00158  * Period is added where needed.  See use of Prefix in this module.
00159  */
00160 PrefixList      mib_prefixes[] = {
00161     {&Standard_Prefix[0]},      /* placeholder for Prefix data */
00162     {".iso.org.dod.internet.mgmt.mib-2"},
00163     {".iso.org.dod.internet.experimental"},
00164     {".iso.org.dod.internet.private"},
00165     {".iso.org.dod.internet.snmpParties"},
00166     {".iso.org.dod.internet.snmpSecrets"},
00167     {NULL, 0}                   /* end of list */
00168 };
00169 
00170 enum inet_address_type {
00171     IPV4 = 1,
00172     IPV6 = 2,
00173     IPV4Z = 3,
00174     IPV6Z = 4,
00175     DNS = 16
00176 };
00177 
00178 
00189 static char    *
00190 uptimeString(u_long timeticks, char *buf, size_t buflen)
00191 {
00192     int             centisecs, seconds, minutes, hours, days;
00193 
00194     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) {
00195         snprintf(buf, buflen, "%lu", timeticks);
00196         return buf;
00197     }
00198 
00199 
00200     centisecs = timeticks % 100;
00201     timeticks /= 100;
00202     days = timeticks / (60 * 60 * 24);
00203     timeticks %= (60 * 60 * 24);
00204 
00205     hours = timeticks / (60 * 60);
00206     timeticks %= (60 * 60);
00207 
00208     minutes = timeticks / 60;
00209     seconds = timeticks % 60;
00210 
00211     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT))
00212         snprintf(buf, buflen, "%d:%d:%02d:%02d.%02d",
00213                 days, hours, minutes, seconds, centisecs);
00214     else {
00215         if (days == 0) {
00216             snprintf(buf, buflen, "%d:%02d:%02d.%02d",
00217                     hours, minutes, seconds, centisecs);
00218         } else if (days == 1) {
00219             snprintf(buf, buflen, "%d day, %d:%02d:%02d.%02d",
00220                     days, hours, minutes, seconds, centisecs);
00221         } else {
00222             snprintf(buf, buflen, "%d days, %d:%02d:%02d.%02d",
00223                     days, hours, minutes, seconds, centisecs);
00224         }
00225     }
00226     return buf;
00227 }
00228 
00229 
00230 
00239 static void
00240 sprint_char(char *buf, const u_char ch)
00241 {
00242     if (isprint(ch) || isspace(ch)) {
00243         sprintf(buf, "%c", (int) ch);
00244     } else {
00245         sprintf(buf, ".");
00246     }
00247 }
00248 
00249 
00250 
00270 int
00271 _sprint_hexstring_line(u_char ** buf, size_t * buf_len, size_t * out_len,
00272                        int allow_realloc, const u_char * cp, size_t line_len)
00273 {
00274     const u_char   *tp;
00275     const u_char   *cp2 = cp;
00276     size_t          lenleft = line_len;
00277 
00278     /*
00279      * Make sure there's enough room for the hex output....
00280      */
00281     while ((*out_len + line_len*3+1) >= *buf_len) {
00282         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00283             return 0;
00284         }
00285     }
00286 
00287     /*
00288      * .... and display the hex values themselves....
00289      */
00290     for (; lenleft >= 8; lenleft-=8) {
00291         sprintf((char *) (*buf + *out_len),
00292                 "%02X %02X %02X %02X %02X %02X %02X %02X ", cp[0], cp[1],
00293                 cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
00294         *out_len += strlen((char *) (*buf + *out_len));
00295         cp       += 8;
00296     }
00297     for (; lenleft > 0; lenleft--) {
00298         sprintf((char *) (*buf + *out_len), "%02X ", *cp++);
00299         *out_len += strlen((char *) (*buf + *out_len));
00300     }
00301 
00302     /*
00303      * .... plus (optionally) do the same for the ASCII equivalent.
00304      */
00305     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT)) {
00306         while ((*out_len + line_len+5) >= *buf_len) {
00307             if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00308                 return 0;
00309             }
00310         }
00311         sprintf((char *) (*buf + *out_len), "  [");
00312         *out_len += strlen((char *) (*buf + *out_len));
00313         for (tp = cp2; tp < cp; tp++) {
00314             sprint_char((char *) (*buf + *out_len), *tp);
00315             (*out_len)++;
00316         }
00317         sprintf((char *) (*buf + *out_len), "]");
00318         *out_len += strlen((char *) (*buf + *out_len));
00319     }
00320     return 1;
00321 }
00322 
00323 int
00324 sprint_realloc_hexstring(u_char ** buf, size_t * buf_len, size_t * out_len,
00325                          int allow_realloc, const u_char * cp, size_t len)
00326 {
00327     int line_len = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
00328                                       NETSNMP_DS_LIB_HEX_OUTPUT_LENGTH);
00329     if (!line_len)
00330         line_len=len;
00331 
00332     for (; (int)len > line_len; len -= line_len) {
00333         if(!_sprint_hexstring_line(buf, buf_len, out_len, allow_realloc, cp, line_len))
00334             return 0;
00335         *(*buf + (*out_len)++) = '\n';
00336         *(*buf + *out_len) = 0;
00337         cp += line_len;
00338     }
00339     if(!_sprint_hexstring_line(buf, buf_len, out_len, allow_realloc, cp, len))
00340         return 0;
00341     *(*buf + *out_len) = 0;
00342     return 1;
00343 }
00344 
00345 
00346 
00366 int
00367 sprint_realloc_asciistring(u_char ** buf, size_t * buf_len,
00368                            size_t * out_len, int allow_realloc,
00369                            const u_char * cp, size_t len)
00370 {
00371     int             i;
00372 
00373     for (i = 0; i < (int) len; i++) {
00374         if (isprint(*cp) || isspace(*cp)) {
00375             if (*cp == '\\' || *cp == '"') {
00376                 if ((*out_len >= *buf_len) &&
00377                     !(allow_realloc && snmp_realloc(buf, buf_len))) {
00378                     return 0;
00379                 }
00380                 *(*buf + (*out_len)++) = '\\';
00381             }
00382             if ((*out_len >= *buf_len) &&
00383                 !(allow_realloc && snmp_realloc(buf, buf_len))) {
00384                 return 0;
00385             }
00386             *(*buf + (*out_len)++) = *cp++;
00387         } else {
00388             if ((*out_len >= *buf_len) &&
00389                 !(allow_realloc && snmp_realloc(buf, buf_len))) {
00390                 return 0;
00391             }
00392             *(*buf + (*out_len)++) = '.';
00393             cp++;
00394         }
00395     }
00396     if ((*out_len >= *buf_len) &&
00397         !(allow_realloc && snmp_realloc(buf, buf_len))) {
00398         return 0;
00399     }
00400     *(*buf + *out_len) = '\0';
00401     return 1;
00402 }
00403 
00426 int
00427 sprint_realloc_octet_string(u_char ** buf, size_t * buf_len,
00428                             size_t * out_len, int allow_realloc,
00429                             const netsnmp_variable_list * var,
00430                             const struct enum_list *enums, const char *hint,
00431                             const char *units)
00432 {
00433     size_t          saved_out_len = *out_len;
00434     const char     *saved_hint = hint;
00435     int             hex = 0, x = 0;
00436     u_char         *cp;
00437     int             output_format;
00438 
00439     if ((var->type != ASN_OCTET_STR) && 
00440         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
00441         const char      str[] = "Wrong Type (should be OCTET STRING): ";
00442         if (snmp_strcat
00443             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
00444             return sprint_realloc_by_type(buf, buf_len, out_len,
00445                                           allow_realloc, var, NULL, NULL,
00446                                           NULL);
00447         } else {
00448             return 0;
00449         }
00450     }
00451 
00452 
00453     if (hint) {
00454         int             repeat, width = 1;
00455         long            value;
00456         char            code = 'd', separ = 0, term = 0, ch, intbuf[16];
00457         u_char         *ecp;
00458 
00459         if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00460             if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
00461                              (const u_char *) "STRING: ")) {
00462                 return 0;
00463             }
00464         }
00465         cp = var->val.string;
00466         ecp = cp + var->val_len;
00467 
00468         while (cp < ecp) {
00469             repeat = 1;
00470             if (*hint) {
00471                 if (*hint == '*') {
00472                     repeat = *cp++;
00473                     hint++;
00474                 }
00475                 width = 0;
00476                 while ('0' <= *hint && *hint <= '9')
00477                     width = (width * 10) + (*hint++ - '0');
00478                 code = *hint++;
00479                 if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9')
00480                     && (width != 0
00481                         || (ch != 'x' && ch != 'd' && ch != 'o')))
00482                     separ = *hint++;
00483                 else
00484                     separ = 0;
00485                 if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9')
00486                     && (width != 0
00487                         || (ch != 'x' && ch != 'd' && ch != 'o')))
00488                     term = *hint++;
00489                 else
00490                     term = 0;
00491             }
00492 
00493             while (repeat && cp < ecp) {
00494                 value = 0;
00495                 if (code != 'a' && code != 't') {
00496                     for (x = 0; x < width; x++) {
00497                         value = value * 256 + *cp++;
00498                     }
00499                 }
00500                 switch (code) {
00501                 case 'x':
00502                     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
00503                                                NETSNMP_DS_LIB_2DIGIT_HEX_OUTPUT)
00504                                        && value < 16) {
00505                         sprintf(intbuf, "0%lx", value);
00506                     } else {
00507                         sprintf(intbuf, "%lx", value);
00508                     }
00509                     if (!snmp_strcat
00510                         (buf, buf_len, out_len, allow_realloc,
00511                          (u_char *) intbuf)) {
00512                         return 0;
00513                     }
00514                     break;
00515                 case 'd':
00516                     sprintf(intbuf, "%ld", value);
00517                     if (!snmp_strcat
00518                         (buf, buf_len, out_len, allow_realloc,
00519                          (u_char *) intbuf)) {
00520                         return 0;
00521                     }
00522                     break;
00523                 case 'o':
00524                     sprintf(intbuf, "%lo", value);
00525                     if (!snmp_strcat
00526                         (buf, buf_len, out_len, allow_realloc,
00527                          (u_char *) intbuf)) {
00528                         return 0;
00529                     }
00530                     break;
00531                 case 't': /* new in rfc 3411 */
00532                 case 'a':
00533                     while ((*out_len + width + 1) >= *buf_len) {
00534                         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00535                             return 0;
00536                         }
00537                     }
00538                     for (x = 0; x < width && cp < ecp; x++) {
00539                         *(*buf + *out_len) = *cp++;
00540                         (*out_len)++;
00541                     }
00542                     *(*buf + *out_len) = '\0';
00543                     break;
00544                 default:
00545                     *out_len = saved_out_len;
00546                     if (snmp_strcat(buf, buf_len, out_len, allow_realloc,
00547                                     (const u_char *) "(Bad hint ignored: ")
00548                         && snmp_strcat(buf, buf_len, out_len,
00549                                        allow_realloc,
00550                                        (const u_char *) saved_hint)
00551                         && snmp_strcat(buf, buf_len, out_len,
00552                                        allow_realloc,
00553                                        (const u_char *) ") ")) {
00554                         return sprint_realloc_octet_string(buf, buf_len,
00555                                                            out_len,
00556                                                            allow_realloc,
00557                                                            var, enums,
00558                                                            NULL, NULL);
00559                     } else {
00560                         return 0;
00561                     }
00562                 }
00563 
00564                 if (cp < ecp && separ) {
00565                     while ((*out_len + 1) >= *buf_len) {
00566                         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00567                             return 0;
00568                         }
00569                     }
00570                     *(*buf + *out_len) = separ;
00571                     (*out_len)++;
00572                     *(*buf + *out_len) = '\0';
00573                 }
00574                 repeat--;
00575             }
00576 
00577             if (term && cp < ecp) {
00578                 while ((*out_len + 1) >= *buf_len) {
00579                     if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00580                         return 0;
00581                     }
00582                 }
00583                 *(*buf + *out_len) = term;
00584                 (*out_len)++;
00585                 *(*buf + *out_len) = '\0';
00586             }
00587         }
00588 
00589         if (units) {
00590             return (snmp_strcat
00591                     (buf, buf_len, out_len, allow_realloc,
00592                      (const u_char *) " ")
00593                     && snmp_strcat(buf, buf_len, out_len, allow_realloc,
00594                                    (const u_char *) units));
00595         }
00596         if ((*out_len >= *buf_len) &&
00597             !(allow_realloc && snmp_realloc(buf, buf_len))) {
00598             return 0;
00599         }
00600         *(*buf + *out_len) = '\0';
00601 
00602         return 1;
00603     }
00604 
00605     output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT);
00606     if (0 == output_format) {
00607         output_format = NETSNMP_STRING_OUTPUT_GUESS;
00608     }
00609     switch (output_format) {
00610     case NETSNMP_STRING_OUTPUT_GUESS:
00611         hex = 0;
00612         for (cp = var->val.string, x = 0; x < (int) var->val_len; x++, cp++) {
00613             if (!isprint(*cp) && !isspace(*cp)) {
00614                 hex = 1;
00615             }
00616         }
00617         break;
00618 
00619     case NETSNMP_STRING_OUTPUT_ASCII:
00620         hex = 0;
00621         break;
00622 
00623     case NETSNMP_STRING_OUTPUT_HEX:
00624         hex = 1;
00625         break;
00626     }
00627 
00628     if (var->val_len == 0) {
00629         return snmp_strcat(buf, buf_len, out_len, allow_realloc,
00630                            (const u_char *) "\"\"");
00631     }
00632 
00633     if (hex) {
00634         if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00635             if (!snmp_strcat
00636                 (buf, buf_len, out_len, allow_realloc,
00637                  (const u_char *) "\"")) {
00638                 return 0;
00639             }
00640         } else {
00641             if (!snmp_strcat
00642                 (buf, buf_len, out_len, allow_realloc,
00643                  (const u_char *) "Hex-STRING: ")) {
00644                 return 0;
00645             }
00646         }
00647 
00648         if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
00649                                       var->val.string, var->val_len)) {
00650             return 0;
00651         }
00652 
00653         if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00654             if (!snmp_strcat
00655                 (buf, buf_len, out_len, allow_realloc,
00656                  (const u_char *) "\"")) {
00657                 return 0;
00658             }
00659         }
00660     } else {
00661         if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00662             if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
00663                              (const u_char *) "STRING: ")) {
00664                 return 0;
00665             }
00666         }
00667         if (!snmp_strcat
00668             (buf, buf_len, out_len, allow_realloc,
00669              (const u_char *) "\"")) {
00670             return 0;
00671         }
00672         if (!sprint_realloc_asciistring
00673             (buf, buf_len, out_len, allow_realloc, var->val.string,
00674              var->val_len)) {
00675             return 0;
00676         }
00677         if (!snmp_strcat
00678             (buf, buf_len, out_len, allow_realloc,
00679              (const u_char *) "\"")) {
00680             return 0;
00681         }
00682     }
00683 
00684     if (units) {
00685         return (snmp_strcat
00686                 (buf, buf_len, out_len, allow_realloc,
00687                  (const u_char *) " ")
00688                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
00689                                (const u_char *) units));
00690     }
00691     return 1;
00692 }
00693 
00694 #ifdef OPAQUE_SPECIAL_TYPES
00695 
00718 int
00719 sprint_realloc_float(u_char ** buf, size_t * buf_len,
00720                      size_t * out_len, int allow_realloc,
00721                      const netsnmp_variable_list * var,
00722                      const struct enum_list *enums,
00723                      const char *hint, const char *units)
00724 {
00725     if ((var->type != ASN_OPAQUE_FLOAT) &&
00726         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
00727         u_char          str[] = "Wrong Type (should be Float): ";
00728         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
00729             return sprint_realloc_by_type(buf, buf_len, out_len,
00730                                           allow_realloc, var, NULL, NULL,
00731                                           NULL);
00732         } else {
00733             return 0;
00734         }
00735     }
00736 
00737     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00738         if (!snmp_strcat
00739             (buf, buf_len, out_len, allow_realloc,
00740              (const u_char *) "Opaque: Float: ")) {
00741             return 0;
00742         }
00743     }
00744 
00745 
00746     /*
00747      * How much space needed for max. length float?  128 is overkill.  
00748      */
00749 
00750     while ((*out_len + 128 + 1) >= *buf_len) {
00751         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00752             return 0;
00753         }
00754     }
00755 
00756     sprintf((char *) (*buf + *out_len), "%f", *var->val.floatVal);
00757     *out_len += strlen((char *) (*buf + *out_len));
00758 
00759     if (units) {
00760         return (snmp_strcat
00761                 (buf, buf_len, out_len, allow_realloc,
00762                  (const u_char *) " ")
00763                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
00764                                (const u_char *) units));
00765     }
00766     return 1;
00767 }
00768 
00769 
00792 int
00793 sprint_realloc_double(u_char ** buf, size_t * buf_len,
00794                       size_t * out_len, int allow_realloc,
00795                       const netsnmp_variable_list * var,
00796                       const struct enum_list *enums,
00797                       const char *hint, const char *units)
00798 {
00799     if ((var->type != ASN_OPAQUE_DOUBLE) && 
00800         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
00801         const char      str[] = "Wrong Type (should be Double): ";
00802         if (snmp_strcat
00803             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
00804             return sprint_realloc_by_type(buf, buf_len, out_len,
00805                                           allow_realloc, var, NULL, NULL,
00806                                           NULL);
00807         } else {
00808             return 0;
00809         }
00810     }
00811 
00812     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00813         if (!snmp_strcat
00814             (buf, buf_len, out_len, allow_realloc,
00815              (const u_char *) "Opaque: Float: ")) {
00816             return 0;
00817         }
00818     }
00819 
00820     /*
00821      * How much space needed for max. length double?  128 is overkill.  
00822      */
00823 
00824     while ((*out_len + 128 + 1) >= *buf_len) {
00825         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
00826             return 0;
00827         }
00828     }
00829 
00830     sprintf((char *) (*buf + *out_len), "%f", *var->val.doubleVal);
00831     *out_len += strlen((char *) (*buf + *out_len));
00832 
00833     if (units) {
00834         return (snmp_strcat
00835                 (buf, buf_len, out_len, allow_realloc,
00836                  (const u_char *) " ")
00837                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
00838                                (const u_char *) units));
00839     }
00840     return 1;
00841 }
00842 
00843 #endif                          /* OPAQUE_SPECIAL_TYPES */
00844 
00845 
00868 int
00869 sprint_realloc_counter64(u_char ** buf, size_t * buf_len, size_t * out_len,
00870                          int allow_realloc,
00871                          const netsnmp_variable_list * var,
00872                          const struct enum_list *enums,
00873                          const char *hint, const char *units)
00874 {
00875     char            a64buf[I64CHARSZ + 1];
00876 
00877     if ((var->type != ASN_COUNTER64
00878 #ifdef OPAQUE_SPECIAL_TYPES
00879         && var->type != ASN_OPAQUE_COUNTER64
00880         && var->type != ASN_OPAQUE_I64 && var->type != ASN_OPAQUE_U64
00881 #endif
00882         ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
00883         u_char          str[] = "Wrong Type (should be Counter64): ";
00884         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
00885             return sprint_realloc_by_type(buf, buf_len, out_len,
00886                                           allow_realloc, var, NULL, NULL,
00887                                           NULL);
00888         } else {
00889             return 0;
00890         }
00891     }
00892 
00893     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
00894 #ifdef OPAQUE_SPECIAL_TYPES
00895         if (var->type != ASN_COUNTER64) {
00896             if (!snmp_strcat
00897                 (buf, buf_len, out_len, allow_realloc,
00898                  (const u_char *) "Opaque: ")) {
00899                 return 0;
00900             }
00901         }
00902 #endif
00903 #ifdef OPAQUE_SPECIAL_TYPES
00904         switch (var->type) {
00905         case ASN_OPAQUE_U64:
00906             if (!snmp_strcat
00907                 (buf, buf_len, out_len, allow_realloc,
00908                  (const u_char *) "UInt64: ")) {
00909                 return 0;
00910             }
00911             break;
00912         case ASN_OPAQUE_I64:
00913             if (!snmp_strcat
00914                 (buf, buf_len, out_len, allow_realloc,
00915                  (const u_char *) "Int64: ")) {
00916                 return 0;
00917             }
00918             break;
00919         case ASN_COUNTER64:
00920         case ASN_OPAQUE_COUNTER64:
00921 #endif
00922             if (!snmp_strcat
00923                 (buf, buf_len, out_len, allow_realloc,
00924                  (const u_char *) "Counter64: ")) {
00925                 return 0;
00926             }
00927 #ifdef OPAQUE_SPECIAL_TYPES
00928         }
00929 #endif
00930     }
00931 #ifdef OPAQUE_SPECIAL_TYPES
00932     if (var->type == ASN_OPAQUE_I64) {
00933         printI64(a64buf, var->val.counter64);
00934         if (!snmp_strcat
00935             (buf, buf_len, out_len, allow_realloc,
00936              (const u_char *) a64buf)) {
00937             return 0;
00938         }
00939     } else {
00940 #endif
00941         printU64(a64buf, var->val.counter64);
00942         if (!snmp_strcat
00943             (buf, buf_len, out_len, allow_realloc,
00944              (const u_char *) a64buf)) {
00945             return 0;
00946         }
00947 #ifdef OPAQUE_SPECIAL_TYPES
00948     }
00949 #endif
00950 
00951     if (units) {
00952         return (snmp_strcat
00953                 (buf, buf_len, out_len, allow_realloc,
00954                  (const u_char *) " ")
00955                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
00956                                (const u_char *) units));
00957     }
00958     return 1;
00959 }
00960 
00961 
00982 int
00983 sprint_realloc_opaque(u_char ** buf, size_t * buf_len,
00984                       size_t * out_len, int allow_realloc,
00985                       const netsnmp_variable_list * var,
00986                       const struct enum_list *enums,
00987                       const char *hint, const char *units)
00988 {
00989     if ((var->type != ASN_OPAQUE
00990 #ifdef OPAQUE_SPECIAL_TYPES
00991         && var->type != ASN_OPAQUE_COUNTER64
00992         && var->type != ASN_OPAQUE_U64
00993         && var->type != ASN_OPAQUE_I64
00994         && var->type != ASN_OPAQUE_FLOAT && var->type != ASN_OPAQUE_DOUBLE
00995 #endif                          /* OPAQUE_SPECIAL_TYPES */
00996         ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
00997         u_char          str[] = "Wrong Type (should be Opaque): ";
00998         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
00999             return sprint_realloc_by_type(buf, buf_len, out_len,
01000                                           allow_realloc, var, NULL, NULL,
01001                                           NULL);
01002         } else {
01003             return 0;
01004         }
01005     }
01006 #ifdef OPAQUE_SPECIAL_TYPES
01007     switch (var->type) {
01008     case ASN_OPAQUE_COUNTER64:
01009     case ASN_OPAQUE_U64:
01010     case ASN_OPAQUE_I64:
01011         return sprint_realloc_counter64(buf, buf_len, out_len,
01012                                         allow_realloc, var, enums, hint,
01013                                         units);
01014         break;
01015 
01016     case ASN_OPAQUE_FLOAT:
01017         return sprint_realloc_float(buf, buf_len, out_len, allow_realloc,
01018                                     var, enums, hint, units);
01019         break;
01020 
01021     case ASN_OPAQUE_DOUBLE:
01022         return sprint_realloc_double(buf, buf_len, out_len, allow_realloc,
01023                                      var, enums, hint, units);
01024         break;
01025 
01026     case ASN_OPAQUE:
01027 #endif
01028         if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01029             u_char          str[] = "OPAQUE: ";
01030             if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01031                 return 0;
01032             }
01033         }
01034         if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
01035                                       var->val.string, var->val_len)) {
01036             return 0;
01037         }
01038 #ifdef OPAQUE_SPECIAL_TYPES
01039     }
01040 #endif
01041     if (units) {
01042         return (snmp_strcat
01043                 (buf, buf_len, out_len, allow_realloc,
01044                  (const u_char *) " ")
01045                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01046                                (const u_char *) units));
01047     }
01048     return 1;
01049 }
01050 
01051 
01072 int
01073 sprint_realloc_object_identifier(u_char ** buf, size_t * buf_len,
01074                                  size_t * out_len, int allow_realloc,
01075                                  const netsnmp_variable_list * var,
01076                                  const struct enum_list *enums,
01077                                  const char *hint, const char *units)
01078 {
01079     int             buf_overflow = 0;
01080 
01081     if ((var->type != ASN_OBJECT_ID) &&
01082         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01083         u_char          str[] =
01084             "Wrong Type (should be OBJECT IDENTIFIER): ";
01085         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01086             return sprint_realloc_by_type(buf, buf_len, out_len,
01087                                           allow_realloc, var, NULL, NULL,
01088                                           NULL);
01089         } else {
01090             return 0;
01091         }
01092     }
01093 
01094     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01095         u_char          str[] = "OID: ";
01096         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01097             return 0;
01098         }
01099     }
01100 
01101     netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, allow_realloc,
01102                                       &buf_overflow,
01103                                       (oid *) (var->val.objid),
01104                                       var->val_len / sizeof(oid));
01105 
01106     if (buf_overflow) {
01107         return 0;
01108     }
01109 
01110     if (units) {
01111         return (snmp_strcat
01112                 (buf, buf_len, out_len, allow_realloc,
01113                  (const u_char *) " ")
01114                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01115                                (const u_char *) units));
01116     }
01117     return 1;
01118 }
01119 
01120 
01121 
01142 int
01143 sprint_realloc_timeticks(u_char ** buf, size_t * buf_len, size_t * out_len,
01144                          int allow_realloc,
01145                          const netsnmp_variable_list * var,
01146                          const struct enum_list *enums,
01147                          const char *hint, const char *units)
01148 {
01149     char            timebuf[40];
01150 
01151     if ((var->type != ASN_TIMETICKS) && 
01152         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01153         u_char          str[] = "Wrong Type (should be Timeticks): ";
01154         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01155             return sprint_realloc_by_type(buf, buf_len, out_len,
01156                                           allow_realloc, var, NULL, NULL,
01157                                           NULL);
01158         } else {
01159             return 0;
01160         }
01161     }
01162 
01163     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) {
01164         char            str[16];
01165         sprintf(str, "%lu", *(u_long *) var->val.integer);
01166         if (!snmp_strcat
01167             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
01168             return 0;
01169         }
01170         return 1;
01171     }
01172     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01173         char            str[32];
01174         sprintf(str, "Timeticks: (%lu) ", *(u_long *) var->val.integer);
01175         if (!snmp_strcat
01176             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
01177             return 0;
01178         }
01179     }
01180     uptimeString(*(u_long *) (var->val.integer), timebuf, sizeof(timebuf));
01181     if (!snmp_strcat
01182         (buf, buf_len, out_len, allow_realloc, (const u_char *) timebuf)) {
01183         return 0;
01184     }
01185     if (units) {
01186         return (snmp_strcat
01187                 (buf, buf_len, out_len, allow_realloc,
01188                  (const u_char *) " ")
01189                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01190                                (const u_char *) units));
01191     }
01192     return 1;
01193 }
01194 
01195 
01216 int
01217 sprint_realloc_hinted_integer(u_char ** buf, size_t * buf_len,
01218                               size_t * out_len, int allow_realloc,
01219                               long val, const char decimaltype,
01220                               const char *hint, const char *units)
01221 {
01222     char            fmt[10] = "%l@", tmp[256];
01223     int             shift, len;
01224 
01225     if (hint[1] == '-') {
01226         shift = atoi(hint + 2);
01227     } else {
01228         shift = 0;
01229     }
01230 
01231     if (hint[0] == 'd') {
01232         /*
01233          * We might *actually* want a 'u' here.  
01234          */
01235         fmt[2] = decimaltype;
01236     } else {
01237         /*
01238          * DISPLAY-HINT character is 'b', 'o', or 'x'.  
01239          */
01240         fmt[2] = hint[0];
01241     }
01242 
01243     sprintf(tmp, fmt, val);
01244     if (shift != 0) {
01245         len = strlen(tmp);
01246         if (shift <= len) {
01247             tmp[len + 1] = 0;
01248             while (shift--) {
01249                 tmp[len] = tmp[len - 1];
01250                 len--;
01251             }
01252             tmp[len] = '.';
01253         } else {
01254             tmp[shift + 1] = 0;
01255             while (shift) {
01256                 if (len-- > 0) {
01257                     tmp[shift] = tmp[len];
01258                 } else {
01259                     tmp[shift] = '0';
01260                 }
01261                 shift--;
01262             }
01263             tmp[0] = '.';
01264         }
01265     }
01266     return snmp_strcat(buf, buf_len, out_len, allow_realloc, tmp);
01267 }
01268 
01269 
01290 int
01291 sprint_realloc_integer(u_char ** buf, size_t * buf_len, size_t * out_len,
01292                        int allow_realloc,
01293                        const netsnmp_variable_list * var,
01294                        const struct enum_list *enums,
01295                        const char *hint, const char *units)
01296 {
01297     char           *enum_string = NULL;
01298 
01299     if ((var->type != ASN_INTEGER) && 
01300         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01301         u_char          str[] = "Wrong Type (should be INTEGER): ";
01302         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01303             return sprint_realloc_by_type(buf, buf_len, out_len,
01304                                           allow_realloc, var, NULL, NULL,
01305                                           NULL);
01306         } else {
01307             return 0;
01308         }
01309     }
01310     for (; enums; enums = enums->next) {
01311         if (enums->value == *var->val.integer) {
01312             enum_string = enums->label;
01313             break;
01314         }
01315     }
01316 
01317     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01318         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
01319                          (const u_char *) "INTEGER: ")) {
01320             return 0;
01321         }
01322     }
01323 
01324     if (enum_string == NULL ||
01325         netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
01326         if (hint) {
01327             if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len,
01328                                                 allow_realloc,
01329                                                 *var->val.integer, 'd',
01330                                                 hint, units))) {
01331                 return 0;
01332             }
01333         } else {
01334             char            str[16];
01335             sprintf(str, "%ld", *var->val.integer);
01336             if (!snmp_strcat
01337                 (buf, buf_len, out_len, allow_realloc,
01338                  (const u_char *) str)) {
01339                 return 0;
01340             }
01341         }
01342     } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01343         if (!snmp_strcat
01344             (buf, buf_len, out_len, allow_realloc,
01345              (const u_char *) enum_string)) {
01346             return 0;
01347         }
01348     } else {
01349         char            str[16];
01350         sprintf(str, "(%ld)", *var->val.integer);
01351         if (!snmp_strcat
01352             (buf, buf_len, out_len, allow_realloc,
01353              (const u_char *) enum_string)) {
01354             return 0;
01355         }
01356         if (!snmp_strcat
01357             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
01358             return 0;
01359         }
01360     }
01361 
01362     if (units) {
01363         return (snmp_strcat
01364                 (buf, buf_len, out_len, allow_realloc,
01365                  (const u_char *) " ")
01366                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01367                                (const u_char *) units));
01368     }
01369     return 1;
01370 }
01371 
01372 
01393 int
01394 sprint_realloc_uinteger(u_char ** buf, size_t * buf_len, size_t * out_len,
01395                         int allow_realloc,
01396                         const netsnmp_variable_list * var,
01397                         const struct enum_list *enums,
01398                         const char *hint, const char *units)
01399 {
01400     char           *enum_string = NULL;
01401 
01402     if ((var->type != ASN_UINTEGER) && 
01403         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01404         u_char          str[] = "Wrong Type (should be UInteger32): ";
01405         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01406             return sprint_realloc_by_type(buf, buf_len, out_len,
01407                                           allow_realloc, var, NULL, NULL,
01408                                           NULL);
01409         } else {
01410             return 0;
01411         }
01412     }
01413 
01414     for (; enums; enums = enums->next) {
01415         if (enums->value == *var->val.integer) {
01416             enum_string = enums->label;
01417             break;
01418         }
01419     }
01420 
01421     if (enum_string == NULL ||
01422         netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
01423         if (hint) {
01424             if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len,
01425                                                 allow_realloc,
01426                                                 *var->val.integer, 'u',
01427                                                 hint, units))) {
01428                 return 0;
01429             }
01430         } else {
01431             char            str[16];
01432             sprintf(str, "%lu", *var->val.integer);
01433             if (!snmp_strcat
01434                 (buf, buf_len, out_len, allow_realloc,
01435                  (const u_char *) str)) {
01436                 return 0;
01437             }
01438         }
01439     } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01440         if (!snmp_strcat
01441             (buf, buf_len, out_len, allow_realloc,
01442              (const u_char *) enum_string)) {
01443             return 0;
01444         }
01445     } else {
01446         char            str[16];
01447         sprintf(str, "(%lu)", *var->val.integer);
01448         if (!snmp_strcat
01449             (buf, buf_len, out_len, allow_realloc,
01450              (const u_char *) enum_string)) {
01451             return 0;
01452         }
01453         if (!snmp_strcat
01454             (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
01455             return 0;
01456         }
01457     }
01458 
01459     if (units) {
01460         return (snmp_strcat
01461                 (buf, buf_len, out_len, allow_realloc,
01462                  (const u_char *) " ")
01463                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01464                                (const u_char *) units));
01465     }
01466     return 1;
01467 }
01468 
01469 
01490 int
01491 sprint_realloc_gauge(u_char ** buf, size_t * buf_len, size_t * out_len,
01492                      int allow_realloc,
01493                      const netsnmp_variable_list * var,
01494                      const struct enum_list *enums,
01495                      const char *hint, const char *units)
01496 {
01497     char            tmp[32];
01498 
01499     if ((var->type != ASN_GAUGE) && 
01500         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01501         u_char          str[] =
01502             "Wrong Type (should be Gauge32 or Unsigned32): ";
01503         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01504             return sprint_realloc_by_type(buf, buf_len, out_len,
01505                                           allow_realloc, var, NULL, NULL,
01506                                           NULL);
01507         } else {
01508             return 0;
01509         }
01510     }
01511 
01512     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01513         u_char          str[] = "Gauge32: ";
01514         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01515             return 0;
01516         }
01517     }
01518     if (hint) {
01519         if (!sprint_realloc_hinted_integer(buf, buf_len, out_len,
01520                                            allow_realloc,
01521                                            *var->val.integer, 'u', hint,
01522                                            units)) {
01523             return 0;
01524         }
01525     } else {
01526         sprintf(tmp, "%lu", *var->val.integer);
01527         if (!snmp_strcat
01528             (buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) {
01529             return 0;
01530         }
01531     }
01532     if (units) {
01533         return (snmp_strcat
01534                 (buf, buf_len, out_len, allow_realloc,
01535                  (const u_char *) " ")
01536                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01537                                (const u_char *) units));
01538     }
01539     return 1;
01540 }
01541 
01542 
01563 int
01564 sprint_realloc_counter(u_char ** buf, size_t * buf_len, size_t * out_len,
01565                        int allow_realloc,
01566                        const netsnmp_variable_list * var,
01567                        const struct enum_list *enums,
01568                        const char *hint, const char *units)
01569 {
01570     char            tmp[32];
01571 
01572     if ((var->type != ASN_COUNTER) && 
01573         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01574         u_char          str[] = "Wrong Type (should be Counter32): ";
01575         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01576             return sprint_realloc_by_type(buf, buf_len, out_len,
01577                                           allow_realloc, var, NULL, NULL,
01578                                           NULL);
01579         } else {
01580             return 0;
01581         }
01582     }
01583 
01584     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01585         u_char          str[] = "Counter32: ";
01586         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01587             return 0;
01588         }
01589     }
01590     sprintf(tmp, "%lu", *var->val.integer);
01591     if (!snmp_strcat
01592         (buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) {
01593         return 0;
01594     }
01595     if (units) {
01596         return (snmp_strcat
01597                 (buf, buf_len, out_len, allow_realloc,
01598                  (const u_char *) " ")
01599                 && snmp_strcat(buf, buf_len, out_len, allow_realloc,
01600                                (const u_char *) units));
01601     }
01602     return 1;
01603 }
01604 
01605 
01626 int
01627 sprint_realloc_networkaddress(u_char ** buf, size_t * buf_len,
01628                               size_t * out_len, int allow_realloc,
01629                               const netsnmp_variable_list * var,
01630                               const struct enum_list *enums, const char *hint,
01631                               const char *units)
01632 {
01633     size_t          i;
01634 
01635     if ((var->type != ASN_IPADDRESS) && 
01636         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01637         u_char          str[] = "Wrong Type (should be NetworkAddress): ";
01638         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01639             return sprint_realloc_by_type(buf, buf_len, out_len,
01640                                           allow_realloc, var, NULL, NULL,
01641                                           NULL);
01642         } else {
01643             return 0;
01644         }
01645     }
01646 
01647     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01648         u_char          str[] = "Network Address: ";
01649         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01650             return 0;
01651         }
01652     }
01653 
01654     while ((*out_len + (var->val_len * 3) + 2) >= *buf_len) {
01655         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
01656             return 0;
01657         }
01658     }
01659 
01660     for (i = 0; i < var->val_len; i++) {
01661         sprintf((char *) (*buf + *out_len), "%02X", var->val.string[i]);
01662         *out_len += 2;
01663         if (i < var->val_len - 1) {
01664             *(*buf + *out_len) = ':';
01665             (*out_len)++;
01666         }
01667     }
01668     return 1;
01669 }
01670 
01671 
01692 int
01693 sprint_realloc_ipaddress(u_char ** buf, size_t * buf_len, size_t * out_len,
01694                          int allow_realloc,
01695                          const netsnmp_variable_list * var,
01696                          const struct enum_list *enums,
01697                          const char *hint, const char *units)
01698 {
01699     u_char         *ip = var->val.string;
01700 
01701     if ((var->type != ASN_IPADDRESS) && 
01702         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01703         u_char          str[] = "Wrong Type (should be IpAddress): ";
01704         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01705             return sprint_realloc_by_type(buf, buf_len, out_len,
01706                                           allow_realloc, var, NULL, NULL,
01707                                           NULL);
01708         } else {
01709             return 0;
01710         }
01711     }
01712 
01713     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01714         u_char          str[] = "IpAddress: ";
01715         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01716             return 0;
01717         }
01718     }
01719     while ((*out_len + 17) >= *buf_len) {
01720         if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
01721             return 0;
01722         }
01723     }
01724     if (ip)
01725         sprintf((char *) (*buf + *out_len), "%d.%d.%d.%d",
01726                                             ip[0], ip[1], ip[2], ip[3]);
01727     *out_len += strlen((char *) (*buf + *out_len));
01728     return 1;
01729 }
01730 
01731 
01752 int
01753 sprint_realloc_null(u_char ** buf, size_t * buf_len, size_t * out_len,
01754                     int allow_realloc,
01755                     const netsnmp_variable_list * var,
01756                     const struct enum_list *enums,
01757                     const char *hint, const char *units)
01758 {
01759     if ((var->type != ASN_NULL) && 
01760         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01761         u_char          str[] = "Wrong Type (should be NULL): ";
01762         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01763             return sprint_realloc_by_type(buf, buf_len, out_len,
01764                                           allow_realloc, var, NULL, NULL,
01765                                           NULL);
01766         } else {
01767             return 0;
01768         }
01769     } else {
01770         u_char          str[] = "NULL";
01771         return snmp_strcat(buf, buf_len, out_len, allow_realloc, str);
01772     }
01773 }
01774 
01775 
01796 int
01797 sprint_realloc_bitstring(u_char ** buf, size_t * buf_len, size_t * out_len,
01798                          int allow_realloc,
01799                          const netsnmp_variable_list * var,
01800                          const struct enum_list *enums,
01801                          const char *hint, const char *units)
01802 {
01803     int             len, bit;
01804     u_char         *cp;
01805     char           *enum_string;
01806 
01807     if ((var->type != ASN_BIT_STR && var->type != ASN_OCTET_STR) &&
01808         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01809         u_char          str[] = "Wrong Type (should be BITS): ";
01810         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01811             return sprint_realloc_by_type(buf, buf_len, out_len,
01812                                           allow_realloc, var, NULL, NULL,
01813                                           NULL);
01814         } else {
01815             return 0;
01816         }
01817     }
01818 
01819     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01820         u_char          str[] = "\"";
01821         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01822             return 0;
01823         }
01824     } else {
01825         u_char          str[] = "BITS: ";
01826         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01827             return 0;
01828         }
01829     }
01830     if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
01831                                   var->val.bitstring, var->val_len)) {
01832         return 0;
01833     }
01834 
01835     if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01836         u_char          str[] = "\"";
01837         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01838             return 0;
01839         }
01840     } else {
01841         cp = var->val.bitstring;
01842         for (len = 0; len < (int) var->val_len; len++) {
01843             for (bit = 0; bit < 8; bit++) {
01844                 if (*cp & (0x80 >> bit)) {
01845                     enum_string = NULL;
01846                     for (; enums; enums = enums->next) {
01847                         if (enums->value == (len * 8) + bit) {
01848                             enum_string = enums->label;
01849                             break;
01850                         }
01851                     }
01852                     if (enum_string == NULL ||
01853                         netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
01854                                        NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
01855                         char            str[16];
01856                         sprintf(str, "%d ", (len * 8) + bit);
01857                         if (!snmp_strcat
01858                             (buf, buf_len, out_len, allow_realloc,
01859                              (const u_char *) str)) {
01860                             return 0;
01861                         }
01862                     } else {
01863                         char            str[16];
01864                         sprintf(str, "(%d) ", (len * 8) + bit);
01865                         if (!snmp_strcat
01866                             (buf, buf_len, out_len, allow_realloc,
01867                              (const u_char *) enum_string)) {
01868                             return 0;
01869                         }
01870                         if (!snmp_strcat
01871                             (buf, buf_len, out_len, allow_realloc,
01872                              (const u_char *) str)) {
01873                             return 0;
01874                         }
01875                     }
01876                 }
01877             }
01878             cp++;
01879         }
01880     }
01881     return 1;
01882 }
01883 
01884 int
01885 sprint_realloc_nsapaddress(u_char ** buf, size_t * buf_len,
01886                            size_t * out_len, int allow_realloc,
01887                            const netsnmp_variable_list * var,
01888                            const struct enum_list *enums, const char *hint,
01889                            const char *units)
01890 {
01891     if ((var->type != ASN_NSAP) && 
01892         (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
01893         u_char          str[] = "Wrong Type (should be NsapAddress): ";
01894         if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01895             return sprint_realloc_by_type(buf, buf_len, out_len,
01896                                           allow_realloc, var, NULL, NULL,
01897                                           NULL);
01898         } else {
01899             return 0;
01900         }
01901     }
01902 
01903     if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
01904         u_char          str[] = "NsapAddress: ";
01905         if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
01906             return 0;
01907         }
01908     }
01909 
01910     return sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
01911                                     var->val.string, var->val_len);
01912 }
01913 
01914 
01935 int
01936 sprint_realloc_badtype(u_char ** buf, size_t * buf_len, size_t * out_len,
01937                        int allow_realloc,
01938                        const netsnmp_variable_list * var,
01939                        const struct enum_list *enums,
01940                        const char *hint, const char *units)
01941 {
01942     u_char          str[] = "Variable has bad type";
01943 
01944     return snmp_strcat(buf, buf_len, out_len, allow_realloc, str);
01945 }
01946 
01947 
01948 
01970 int
01971 sprint_realloc_by_type(u_char ** buf, size_t * buf_len, size_t * out_len,
01972                        int allow_realloc,
01973                        const netsnmp_variable_list * var,
01974                        const struct enum_list *enums,
01975                        const char *hint, const char *units)
01976 {
01977     DEBUGMSGTL(("output", "sprint_by_type, type %d\n", var->type));
01978 
01979     switch (var->type) {
01980     case ASN_INTEGER:
01981         return sprint_realloc_integer(buf, buf_len, out_len, allow_realloc,
01982                                       var, enums, hint, units);
01983     case ASN_OCTET_STR:
01984         return sprint_realloc_octet_string(buf, buf_len, out_len,
01985                                            allow_realloc, var, enums, hint,
01986                                            units);
01987     case ASN_BIT_STR:
01988         return sprint_realloc_bitstring(buf, buf_len, out_len,
01989                                         allow_realloc, var, enums, hint,
01990                                         units);
01991     case ASN_OPAQUE:
01992         return sprint_realloc_opaque(buf, buf_len, out_len, allow_realloc,
01993                                      var, enums, hint, units);
01994     case ASN_OBJECT_ID:
01995         return sprint_realloc_object_identifier(buf, buf_len, out_len,
01996                                                 allow_realloc, var, enums,
01997                                                 hint, units);
01998     case ASN_TIMETICKS:
01999         return sprint_realloc_timeticks(buf, buf_len, out_len,
02000                                         allow_realloc, var, enums, hint,
02001                                         units);
02002     case ASN_GAUGE:
02003         return sprint_realloc_gauge(buf, buf_len, out_len, allow_realloc,
02004                                     var, enums, hint, units);
02005     case ASN_COUNTER:
02006         return sprint_realloc_counter(buf, buf_len, out_len, allow_realloc,
02007                                       var, enums, hint, units);
02008     case ASN_IPADDRESS:
02009         return sprint_realloc_ipaddress(buf, buf_len, out_len,
02010                                         allow_realloc, var, enums, hint,
02011                                         units);
02012     case ASN_NULL:
02013         return sprint_realloc_null(buf, buf_len, out_len, allow_realloc,
02014                                    var, enums, hint, units);
02015     case ASN_UINTEGER:
02016         return sprint_realloc_uinteger(buf, buf_len, out_len,
02017                                        allow_realloc, var, enums, hint,
02018                                        units);
02019     case ASN_COUNTER64:
02020 #ifdef OPAQUE_SPECIAL_TYPES
02021     case ASN_OPAQUE_U64:
02022     case ASN_OPAQUE_I64:
02023     case ASN_OPAQUE_COUNTER64:
02024 #endif                          /* OPAQUE_SPECIAL_TYPES */
02025         return sprint_realloc_counter64(buf, buf_len, out_len,
02026                                         allow_realloc, var, enums, hint,
02027                                         units);
02028 #ifdef OPAQUE_SPECIAL_TYPES
02029     case ASN_OPAQUE_FLOAT:
02030         return sprint_realloc_float(buf, buf_len, out_len, allow_realloc,
02031                                     var, enums, hint, units);
02032     case ASN_OPAQUE_DOUBLE:
02033         return sprint_realloc_double(buf, buf_len, out_len, allow_realloc,
02034                                      var, enums, hint, units);
02035 #endif                          /* OPAQUE_SPECIAL_TYPES */
02036     default:
02037         DEBUGMSGTL(("sprint_by_type", "bad type: %d\n", var->type));
02038         return sprint_realloc_badtype(buf, buf_len, out_len, allow_realloc,
02039                                       var, enums, hint, units);
02040     }
02041 }
02042 
02043 
02044 #ifndef DISABLE_MIB_LOADING
02045 
02050 struct tree    *
02051 get_tree_head(void)
02052 {
02053     return (tree_head);
02054 }
02055 
02056 static char    *confmibdir = NULL;
02057 static char    *confmibs = NULL;
02058 
02059 static void
02060 handle_mibdirs_conf(const char *token, char *line)
02061 {
02062     char           *ctmp;
02063 
02064     if (confmibdir) {
02065         if ((*line == '+') || (*line == '-')) {
02066             ctmp = (char *) malloc(strlen(confmibdir) + strlen(line) + 2);
02067             if (!ctmp) {
02068                 DEBUGMSGTL(("read_config:initmib",
02069                             "mibdir conf malloc failed"));
02070                 return;
02071             }
02072             if(*line++ == '+')
02073                 sprintf(ctmp, "%s%c%s", confmibdir, ENV_SEPARATOR_CHAR, line);
02074             else
02075                 sprintf(ctmp, "%s%c%s", line, ENV_SEPARATOR_CHAR, confmibdir);
02076         } else {
02077             ctmp = strdup(line);
02078             if (!ctmp) {
02079                 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
02080                 return;
02081             }
02082         }
02083         SNMP_FREE(confmibdir);
02084     } else {
02085         ctmp = strdup(line);
02086         if (!ctmp) {
02087             DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
02088             return;
02089         }
02090     }
02091     confmibdir = ctmp;
02092     DEBUGMSGTL(("read_config:initmib", "using mibdirs: %s\n", confmibdir));
02093 }
02094 
02095 static void
02096 handle_mibs_conf(const char *token, char *line)
02097 {
02098     char           *ctmp;
02099 
02100     if (confmibs) {
02101         if ((*line == '+') || (*line == '-')) {
02102             ctmp = (char *) malloc(strlen(confmibs) + strlen(line) + 2);
02103             if (!ctmp) {
02104                 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
02105                 return;
02106             }
02107             if(*line++ == '+')
02108                 sprintf(ctmp, "%s%c%s", confmibs, ENV_SEPARATOR_CHAR, line);
02109             else
02110                 sprintf(ctmp, "%s%c%s", line, ENV_SEPARATOR_CHAR, confmibdir);
02111         } else {
02112             ctmp = strdup(line);
02113             if (!ctmp) {
02114                 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
02115                 return;
02116             }
02117         }
02118         SNMP_FREE(confmibs);
02119     } else {
02120         ctmp = strdup(line);
02121         if (!ctmp) {
02122             DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
02123             return;
02124         }
02125     }
02126     confmibs = ctmp;
02127     DEBUGMSGTL(("read_config:initmib", "using mibs: %s\n", confmibs));
02128 }
02129 
02130 
02131 static void
02132 handle_mibfile_conf(const char *token, char *line)
02133 {
02134     DEBUGMSGTL(("read_config:initmib", "reading mibfile: %s\n", line));
02135     read_mib(line);
02136 }
02137 #endif
02138 
02139 static void
02140 handle_print_numeric(const char *token, char *line)
02141 {
02142     const char *value;
02143     char       *st;
02144 
02145     value = strtok_r(line, " \t\n", &st);
02146     if ((strcasecmp(value, "yes")  == 0) || 
02147         (strcasecmp(value, "true") == 0) ||
02148         (*value == '1')) {
02149 
02150         netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
02151                                                   NETSNMP_OID_OUTPUT_NUMERIC);
02152     }
02153 }
02154 
02155 char           *
02156 snmp_out_toggle_options(char *options)
02157 {
02158     while (*options) {
02159         switch (*options++) {
02160         case '0':
02161             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID,
02162                                       NETSNMP_DS_LIB_2DIGIT_HEX_OUTPUT);
02163             break;
02164         case 'a':
02165             netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT,
02166                                                       NETSNMP_STRING_OUTPUT_ASCII);
02167             break;
02168         case 'b':
02169             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS);
02170             break;
02171         case 'e':
02172             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
02173             break;
02174         case 'E':
02175             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES);
02176             break;
02177         case 'f':
02178             netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
02179                                                       NETSNMP_OID_OUTPUT_FULL);
02180             break;
02181         case 'n':
02182             netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
02183                                                       NETSNMP_OID_OUTPUT_NUMERIC);
02184             break;
02185         case 'q':
02186             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
02187             break;
02188         case 'Q':
02189             netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT, 1);
02190             netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
02191             break;
02192         case 's':
02193             netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
02194                                                       NETSNMP_OID_OUTPUT_SUFFIX);
02195             break;
02196         case 'S':
02197             netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
02198                                                       NET