Blame apps/snmptrapd_log.c

Packit Service b38f0b
/*
Packit Service b38f0b
 * snmptrapd_log.c - format SNMP trap information for logging
Packit Service b38f0b
 *
Packit Service b38f0b
 */
Packit Service b38f0b
/*****************************************************************
Packit Service b38f0b
	Copyright 1989, 1991, 1992 by Carnegie Mellon University
Packit Service b38f0b
Packit Service b38f0b
                      All Rights Reserved
Packit Service b38f0b
Packit Service b38f0b
Permission to use, copy, modify, and distribute this software and its
Packit Service b38f0b
documentation for any purpose and without fee is hereby granted,
Packit Service b38f0b
provided that the above copyright notice appear in all copies and that
Packit Service b38f0b
both that copyright notice and this permission notice appear in
Packit Service b38f0b
supporting documentation, and that the name of CMU not be
Packit Service b38f0b
used in advertising or publicity pertaining to distribution of the
Packit Service b38f0b
software without specific, written prior permission.
Packit Service b38f0b
Packit Service b38f0b
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
Packit Service b38f0b
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
Packit Service b38f0b
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
Packit Service b38f0b
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit Service b38f0b
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
Packit Service b38f0b
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
Packit Service b38f0b
SOFTWARE.
Packit Service b38f0b
******************************************************************/
Packit Service b38f0b
#include <net-snmp/net-snmp-config.h>
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_STDLIB_H
Packit Service b38f0b
#include <stdlib.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_UNISTD_H
Packit Service b38f0b
#include <unistd.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_STRING_H
Packit Service b38f0b
#include <string.h>
Packit Service b38f0b
#else
Packit Service b38f0b
#include <strings.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#include <sys/types.h>
Packit Service b38f0b
#if HAVE_SYS_WAIT_H
Packit Service b38f0b
#include <sys/wait.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_SOCKET_H
Packit Service b38f0b
#include <sys/socket.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_SOCKIO_H
Packit Service b38f0b
#include <sys/sockio.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_NETINET_IN_H
Packit Service b38f0b
#include <netinet/in.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#include <stdio.h>
Packit Service b38f0b
#include <ctype.h>
Packit Service b38f0b
#if !defined(mingw32) && defined(HAVE_SYS_TIME_H)
Packit Service b38f0b
# include <sys/time.h>
Packit Service b38f0b
# if TIME_WITH_SYS_TIME
Packit Service b38f0b
#  include <time.h>
Packit Service b38f0b
# endif
Packit Service b38f0b
#else
Packit Service b38f0b
# include <time.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_SELECT_H
Packit Service b38f0b
#include <sys/select.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_PARAM_H
Packit Service b38f0b
#include <sys/param.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYSLOG_H
Packit Service b38f0b
#include <syslog.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_IOCTL_H
Packit Service b38f0b
#include <sys/ioctl.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_NET_IF_H
Packit Service b38f0b
#include <net/if.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_NETDB_H
Packit Service b38f0b
#include <netdb.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_ARPA_INET_H
Packit Service b38f0b
#include <arpa/inet.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_FCNTL_H
Packit Service b38f0b
#include <fcntl.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/net-snmp-includes.h>
Packit Service b38f0b
#include "snmptrapd_handlers.h"
Packit Service b38f0b
#include "snmptrapd_log.h"
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
#ifndef BSD4_3
Packit Service b38f0b
#define BSD4_2
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * These flags mark undefined values in the options structure 
Packit Service b38f0b
 */
Packit Service b38f0b
#define UNDEF_CMD '*'
Packit Service b38f0b
#define UNDEF_PRECISION -1
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * This structure holds the options for a single format command 
Packit Service b38f0b
 */
Packit Service b38f0b
typedef struct {
Packit Service b38f0b
    char            cmd;        /* the format command itself */
Packit Service b38f0b
    size_t          width;      /* the field's minimum width */
Packit Service b38f0b
    int             precision;  /* the field's precision */
Packit Service b38f0b
    int             left_justify;       /* if true, left justify this field */
Packit Service b38f0b
    int             alt_format; /* if true, display in alternate format */
Packit Service b38f0b
    int             leading_zeroes;     /* if true, display with leading zeroes */
Packit Service b38f0b
} options_type;
Packit Service b38f0b
Packit Service b38f0b
char            separator[32];
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * These symbols define the characters that the parser recognizes.
Packit Service b38f0b
 * The rather odd choice of symbols comes from an attempt to avoid
Packit Service b38f0b
 * colliding with the ones that printf uses, so that someone could add
Packit Service b38f0b
 * printf functionality to this code and turn it into a library
Packit Service b38f0b
 * routine in the future.  
Packit Service b38f0b
 */
Packit Service b38f0b
typedef enum {
Packit Service b38f0b
    CHR_FMT_DELIM = '%',        /* starts a format command */
Packit Service b38f0b
    CHR_LEFT_JUST = '-',        /* left justify */
Packit Service b38f0b
    CHR_LEAD_ZERO = '0',        /* use leading zeroes */
Packit Service b38f0b
    CHR_ALT_FORM = '#',         /* use alternate format */
Packit Service b38f0b
    CHR_FIELD_SEP = '.',        /* separates width and precision fields */
Packit Service b38f0b
Packit Service b38f0b
    /* Date / Time Information */
Packit Service b38f0b
    CHR_CUR_TIME = 't',         /* current time, Unix format */
Packit Service b38f0b
    CHR_CUR_YEAR = 'y',         /* current year */
Packit Service b38f0b
    CHR_CUR_MONTH = 'm',        /* current month */
Packit Service b38f0b
    CHR_CUR_MDAY = 'l',         /* current day of month */
Packit Service b38f0b
    CHR_CUR_HOUR = 'h',         /* current hour */
Packit Service b38f0b
    CHR_CUR_MIN = 'j',          /* current minute */
Packit Service b38f0b
    CHR_CUR_SEC = 'k',          /* current second */
Packit Service b38f0b
    CHR_UP_TIME = 'T',          /* uptime, Unix format */
Packit Service b38f0b
    CHR_UP_YEAR = 'Y',          /* uptime year */
Packit Service b38f0b
    CHR_UP_MONTH = 'M',         /* uptime month */
Packit Service b38f0b
    CHR_UP_MDAY = 'L',          /* uptime day of month */
Packit Service b38f0b
    CHR_UP_HOUR = 'H',          /* uptime hour */
Packit Service b38f0b
    CHR_UP_MIN = 'J',           /* uptime minute */
Packit Service b38f0b
    CHR_UP_SEC = 'K',           /* uptime second */
Packit Service b38f0b
Packit Service b38f0b
    /* transport information */
Packit Service b38f0b
    CHR_AGENT_IP = 'a',         /* agent's IP address */
Packit Service b38f0b
    CHR_AGENT_NAME = 'A',       /* agent's host name if available */
Packit Service b38f0b
Packit Service b38f0b
    /* authentication information */
Packit Service b38f0b
    CHR_SNMP_VERSION = 's',     /* SNMP Version Number */
Packit Service b38f0b
    CHR_SNMP_SECMOD  = 'S',     /* SNMPv3 Security Model Version Number */
Packit Service b38f0b
    CHR_SNMP_USER = 'u',        /* SNMPv3 secName or v1/v2c community */
Packit Service b38f0b
    CHR_TRAP_CONTEXTID = 'E',   /* SNMPv3 context engineID if available */
Packit Service b38f0b
Packit Service b38f0b
    /* PDU information */
Packit Service b38f0b
    CHR_PDU_IP = 'b',           /* PDU's IP address */
Packit Service b38f0b
    CHR_PDU_NAME = 'B',         /* PDU's host name if available */
Packit Service b38f0b
    CHR_PDU_ENT = 'N',          /* PDU's enterprise string */
Packit Service b38f0b
    CHR_PDU_WRAP = 'P',         /* PDU's wrapper info (community, security) */
Packit Service b38f0b
    CHR_TRAP_NUM = 'w',         /* trap number */
Packit Service b38f0b
    CHR_TRAP_DESC = 'W',        /* trap's description (textual) */
Packit Service b38f0b
    CHR_TRAP_STYPE = 'q',       /* trap's subtype */
Packit Service b38f0b
    CHR_TRAP_VARSEP = 'V',      /* character (or string) to separate variables */
Packit Service b38f0b
    CHR_TRAP_VARS = 'v'        /* tab-separated list of trap's variables */
Packit Service b38f0b
Packit Service b38f0b
} parse_chr_type;
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * These symbols define the states for the parser's state machine 
Packit Service b38f0b
 */
Packit Service b38f0b
typedef enum {
Packit Service b38f0b
    PARSE_NORMAL,               /* looking for next character */
Packit Service b38f0b
    PARSE_BACKSLASH,            /* saw a backslash */
Packit Service b38f0b
    PARSE_IN_FORMAT,            /* saw a % sign, in a format command */
Packit Service b38f0b
    PARSE_GET_WIDTH,            /* getting field width */
Packit Service b38f0b
    PARSE_GET_PRECISION,        /* getting field precision */
Packit Service b38f0b
    PARSE_GET_SEPARATOR         /* getting field separator */
Packit Service b38f0b
} parse_state_type;
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * macros 
Packit Service b38f0b
 */
Packit Service b38f0b
Packit Service b38f0b
#define is_cur_time_cmd(chr) ((((chr) == CHR_CUR_TIME)     \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_YEAR)  \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_MONTH) \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_MDAY)  \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_HOUR)  \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_MIN)   \
Packit Service b38f0b
			       || ((chr) == CHR_CUR_SEC)) ? TRUE : FALSE)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character is a format command that outputs
Packit Service b38f0b
      * some field that deals with the current time.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_up_time_cmd(chr) ((((chr) == CHR_UP_TIME)     \
Packit Service b38f0b
			      || ((chr) == CHR_UP_YEAR)  \
Packit Service b38f0b
			      || ((chr) == CHR_UP_MONTH) \
Packit Service b38f0b
			      || ((chr) == CHR_UP_MDAY)  \
Packit Service b38f0b
			      || ((chr) == CHR_UP_HOUR)  \
Packit Service b38f0b
			      || ((chr) == CHR_UP_MIN)   \
Packit Service b38f0b
			      || ((chr) == CHR_UP_SEC)) ? TRUE : FALSE)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character is a format command that outputs
Packit Service b38f0b
      * some field that deals with up-time.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_agent_cmd(chr) ((((chr) == CHR_AGENT_IP) \
Packit Service b38f0b
			    || ((chr) == CHR_AGENT_NAME)) ? TRUE : FALSE)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character outputs information about the
Packit Service b38f0b
      * agent.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - the character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_pdu_ip_cmd(chr) ((((chr) == CHR_PDU_IP)   \
Packit Service b38f0b
			  || ((chr) == CHR_PDU_NAME)) ? TRUE : FALSE)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character outputs information about the SNMP
Packit Service b38f0b
      *      authentication information
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - the character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_auth_cmd(chr) ((((chr) == CHR_SNMP_VERSION       \
Packit Service b38f0b
                            || (chr) == CHR_SNMP_SECMOD     \
Packit Service b38f0b
                            || (chr) == CHR_SNMP_USER)) ? TRUE : FALSE)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character outputs information about the PDU's
Packit Service b38f0b
      * host name or IP address.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - the character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_trap_cmd(chr) ((((chr) == CHR_TRAP_NUM)      \
Packit Service b38f0b
			   || ((chr) == CHR_TRAP_DESC)  \
Packit Service b38f0b
			   || ((chr) == CHR_TRAP_STYPE) \
Packit Service b38f0b
			   || ((chr) == CHR_TRAP_VARS)) ? TRUE : FALSE)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character outputs information about the trap.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - the character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_fmt_cmd(chr) ((is_cur_time_cmd (chr)     \
Packit Service b38f0b
			  || is_up_time_cmd (chr)   \
Packit Service b38f0b
			  || is_auth_cmd (chr)   \
Packit Service b38f0b
			  || is_agent_cmd (chr)     \
Packit Service b38f0b
			  || is_pdu_ip_cmd (chr)    \
Packit Service b38f0b
                          || ((chr) == CHR_PDU_ENT) \
Packit Service b38f0b
                          || ((chr) == CHR_TRAP_CONTEXTID) \
Packit Service b38f0b
                          || ((chr) == CHR_PDU_WRAP) \
Packit Service b38f0b
			  || is_trap_cmd (chr)) ? TRUE : FALSE)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if the character is a format command.
Packit Service b38f0b
      * 
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define is_numeric_cmd(chr) ((is_cur_time_cmd(chr)   \
Packit Service b38f0b
			      || is_up_time_cmd(chr) \
Packit Service b38f0b
			      || (chr) == CHR_TRAP_NUM) ? TRUE : FALSE)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Returns true if this is a numeric format command.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    chr - character to check
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
#define reference(var) ((var) == (var))
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Some compiler options will tell the compiler to be picky and
Packit Service b38f0b
      * warn you if you pass a parameter to a function but don't use it.
Packit Service b38f0b
      * This macro lets you reference a parameter so that the compiler won't
Packit Service b38f0b
      * generate the warning. It has no other effect.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    var - the parameter to reference
Packit Service b38f0b
      */
Packit Service b38f0b
Packit Service b38f0b
static void
Packit Service b38f0b
init_options(options_type * options)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Initialize a structure that contains the option settings for
Packit Service b38f0b
      * a format command.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    options - points to the structure to initialize
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    /*
Packit Service b38f0b
     * initialize the structure's fields 
Packit Service b38f0b
     */
Packit Service b38f0b
    options->cmd = '*';
Packit Service b38f0b
    options->width = 0;
Packit Service b38f0b
    options->precision = UNDEF_PRECISION;
Packit Service b38f0b
    options->left_justify = FALSE;
Packit Service b38f0b
    options->alt_format = FALSE;
Packit Service b38f0b
    options->leading_zeroes = FALSE;
Packit Service b38f0b
    return;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_output_temp_bfr(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                        int allow_realloc,
Packit Service b38f0b
                        u_char ** temp_buf, options_type * options)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Append the contents of the temporary buffer to the specified
Packit Service b38f0b
      * buffer using the correct justification, leading zeroes, width,
Packit Service b38f0b
      * precision, and other characteristics specified in the options
Packit Service b38f0b
      * structure.
Packit Service b38f0b
      *
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    temp_buf - pointer to string to append onto output buffer.  THIS
Packit Service b38f0b
      *               STRING IS free()d BY THIS FUNCTION.
Packit Service b38f0b
      *    options  - what options to use when appending string
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    size_t          temp_len;   /* length of temporary buffer */
Packit Service b38f0b
    size_t          temp_to_write;      /* # of chars to write from temp bfr */
Packit Service b38f0b
    size_t          char_to_write;      /* # of other chars to write */
Packit Service b38f0b
    size_t          zeroes_to_write;    /* fill to precision with zeroes for numbers */
Packit Service b38f0b
Packit Service b38f0b
    if (temp_buf == NULL || *temp_buf == NULL) {
Packit Service b38f0b
        return 1;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Figure out how many characters are in the temporary buffer now,
Packit Service b38f0b
     * and how many of them we'll write.
Packit Service b38f0b
     */
Packit Service b38f0b
    temp_len = strlen((char *) *temp_buf);
Packit Service b38f0b
    temp_to_write = temp_len;
Packit Service b38f0b
Packit Service b38f0b
    if (options->precision != UNDEF_PRECISION &&
Packit Service b38f0b
        temp_to_write > (size_t)options->precision) {
Packit Service b38f0b
        temp_to_write = options->precision;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Handle leading characters.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if ((!options->left_justify) && (temp_to_write < options->width)) {
Packit Service b38f0b
        zeroes_to_write = options->precision - temp_to_write;
Packit Service b38f0b
        if (!is_numeric_cmd(options->cmd)) {
Packit Service b38f0b
            zeroes_to_write = 0;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        for (char_to_write = options->width - temp_to_write;
Packit Service b38f0b
             char_to_write > 0; char_to_write--) {
Packit Service b38f0b
            if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                    *(*buf + *out_len) = '\0';
Packit Service b38f0b
                    free(*temp_buf);
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
            if (options->leading_zeroes || zeroes_to_write-- > 0) {
Packit Service b38f0b
                *(*buf + *out_len) = '0';
Packit Service b38f0b
            } else {
Packit Service b38f0b
                *(*buf + *out_len) = ' ';
Packit Service b38f0b
            }
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Truncate the temporary buffer and append its contents.  
Packit Service b38f0b
     */
Packit Service b38f0b
    *(*temp_buf + temp_to_write) = '\0';
Packit Service b38f0b
    if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, *temp_buf)) {
Packit Service b38f0b
        free(*temp_buf);
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Handle trailing characters.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if ((options->left_justify) && (temp_to_write < options->width)) {
Packit Service b38f0b
        for (char_to_write = options->width - temp_to_write;
Packit Service b38f0b
             char_to_write > 0; char_to_write--) {
Packit Service b38f0b
            if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                    *(*buf + *out_len) = '\0';
Packit Service b38f0b
                    free(*temp_buf);
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
            *(*buf + *out_len) = '0';
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Slap on a trailing \0 for good measure.  
Packit Service b38f0b
     */
Packit Service b38f0b
Packit Service b38f0b
    *(*buf + *out_len) = '\0';
Packit Service b38f0b
    free(*temp_buf);
Packit Service b38f0b
    *temp_buf = NULL;
Packit Service b38f0b
    return 1;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_time_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                        int allow_realloc,
Packit Service b38f0b
                        options_type * options, netsnmp_pdu *pdu)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Handle a format command that deals with the current or up-time.
Packit Service b38f0b
      * Append the correct time information to the buffer subject to the
Packit Service b38f0b
      * buffer's length limit.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options - options governing how to write the field
Packit Service b38f0b
      *    pdu     - information about this trap
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    time_t          time_val;   /* the time value to output */
Packit Service b38f0b
    unsigned long   time_ul;    /* u_long time/timeticks */
Packit Service b38f0b
    struct tm      *parsed_time;        /* parsed version of current time */
Packit Service b38f0b
    char           *safe_bfr = NULL;
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* the format command to use */
Packit Service b38f0b
Packit Service b38f0b
    if ((safe_bfr = (char *) calloc(30, 1)) == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Get the time field to output.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (is_up_time_cmd(fmt_cmd)) {
Packit Service b38f0b
        time_ul = pdu->time;
Packit Service b38f0b
    } else {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Note: a time_t is a signed long.  
Packit Service b38f0b
         */
Packit Service b38f0b
        time(&time_val);
Packit Service b38f0b
        time_ul = (unsigned long) time_val;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Handle output in Unix time format.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (fmt_cmd == CHR_CUR_TIME) {
Packit Service b38f0b
        sprintf(safe_bfr, "%lu", time_ul);
Packit Service b38f0b
    } else if (fmt_cmd == CHR_UP_TIME && !options->alt_format) {
Packit Service b38f0b
        sprintf(safe_bfr, "%lu", time_ul);
Packit Service b38f0b
    } else if (fmt_cmd == CHR_UP_TIME) {
Packit Service b38f0b
        unsigned int    centisecs, seconds, minutes, hours, days;
Packit Service b38f0b
Packit Service b38f0b
        centisecs = time_ul % 100;
Packit Service b38f0b
        time_ul /= 100;
Packit Service b38f0b
        days = time_ul / (60 * 60 * 24);
Packit Service b38f0b
        time_ul %= (60 * 60 * 24);
Packit Service b38f0b
Packit Service b38f0b
        hours = time_ul / (60 * 60);
Packit Service b38f0b
        time_ul %= (60 * 60);
Packit Service b38f0b
Packit Service b38f0b
        minutes = time_ul / 60;
Packit Service b38f0b
        seconds = time_ul % 60;
Packit Service b38f0b
Packit Service b38f0b
        switch (days) {
Packit Service b38f0b
        case 0:
Packit Service b38f0b
            sprintf(safe_bfr, "%u:%02u:%02u.%02u",
Packit Service b38f0b
                    hours, minutes, seconds, centisecs);
Packit Service b38f0b
            break;
Packit Service b38f0b
        case 1:
Packit Service b38f0b
            sprintf(safe_bfr, "1 day, %u:%02u:%02u.%02u",
Packit Service b38f0b
                    hours, minutes, seconds, centisecs);
Packit Service b38f0b
            break;
Packit Service b38f0b
        default:
Packit Service b38f0b
            sprintf(safe_bfr, "%u days, %u:%02u:%02u.%02u",
Packit Service b38f0b
                    days, hours, minutes, seconds, centisecs);
Packit Service b38f0b
        }
Packit Service b38f0b
    } else {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Handle other time fields.  
Packit Service b38f0b
         */
Packit Service b38f0b
Packit Service b38f0b
        if (options->alt_format) {
Packit Service b38f0b
            parsed_time = gmtime(&time_val);
Packit Service b38f0b
        } else {
Packit Service b38f0b
            parsed_time = localtime(&time_val);
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        switch (fmt_cmd) {
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Output year. The year field is unusual: if there's a restriction 
Packit Service b38f0b
             * on precision, we want to truncate from the left of the number,
Packit Service b38f0b
             * not the right, so someone printing the year 1972 with 2 digit 
Packit Service b38f0b
             * precision gets "72" not "19".
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_YEAR:
Packit Service b38f0b
        case CHR_UP_YEAR:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_year + 1900);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * output month 
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_MONTH:
Packit Service b38f0b
        case CHR_UP_MONTH:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_mon + 1);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * output day of month 
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_MDAY:
Packit Service b38f0b
        case CHR_UP_MDAY:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_mday);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * output hour 
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_HOUR:
Packit Service b38f0b
        case CHR_UP_HOUR:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_hour);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * output minute 
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_MIN:
Packit Service b38f0b
        case CHR_UP_MIN:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_min);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * output second 
Packit Service b38f0b
             */
Packit Service b38f0b
        case CHR_CUR_SEC:
Packit Service b38f0b
        case CHR_UP_SEC:
Packit Service b38f0b
            sprintf(safe_bfr, "%d", parsed_time->tm_sec);
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * unknown format command - just output the character 
Packit Service b38f0b
             */
Packit Service b38f0b
        default:
Packit Service b38f0b
            sprintf(safe_bfr, "%c", fmt_cmd);
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Output with correct justification, leading zeroes, etc.  
Packit Service b38f0b
     */
Packit Service b38f0b
    return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                   (u_char **) & safe_bfr, options);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_ip_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                      int allow_realloc,
Packit Service b38f0b
                      options_type * options, netsnmp_pdu *pdu,
Packit Service b38f0b
                      netsnmp_transport *transport)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Handle a format command that deals with an IP address 
Packit Service b38f0b
      * or host name.  Append the information to the buffer subject to
Packit Service b38f0b
      * the buffer's length limit.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options   - options governing how to write the field
Packit Service b38f0b
      *    pdu       - information about this trap 
Packit Service b38f0b
      *    transport - the transport descriptor
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    struct in_addr *agent_inaddr = (struct in_addr *) pdu->agent_addr;
Packit Service b38f0b
    struct hostent *host = NULL;       /* corresponding host name */
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* what we're formatting */
Packit Service b38f0b
    u_char         *temp_buf = NULL;
Packit Service b38f0b
    size_t          temp_buf_len = 64, temp_out_len = 0;
Packit Service b38f0b
    char           *tstr;
Packit Service b38f0b
    unsigned int    oflags;
Packit Service b38f0b
Packit Service b38f0b
    if ((temp_buf = (u_char*)calloc(temp_buf_len, 1)) == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Decide exactly what to output.  
Packit Service b38f0b
     */
Packit Service b38f0b
    switch (fmt_cmd) {
Packit Service b38f0b
    case CHR_AGENT_IP:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write a numerical address.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
Packit Service b38f0b
                         (u_char *)inet_ntoa(*agent_inaddr))) {
Packit Service b38f0b
            if (temp_buf != NULL) {
Packit Service b38f0b
                free(temp_buf);
Packit Service b38f0b
            }
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_AGENT_NAME:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Try to resolve the agent_addr field as a hostname; fall back
Packit Service b38f0b
         * to numerical address.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
                                    NETSNMP_DS_APP_NUMERIC_IP)) {
Packit Service b38f0b
            host = netsnmp_gethostbyaddr((char *) pdu->agent_addr, 4, AF_INET);
Packit Service b38f0b
        }
Packit Service b38f0b
        if (host != NULL) {
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
Packit Service b38f0b
                             (const u_char *)host->h_name)) {
Packit Service b38f0b
                if (temp_buf != NULL) {
Packit Service b38f0b
                    free(temp_buf);
Packit Service b38f0b
                }
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        } else {
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
Packit Service b38f0b
                             (u_char *)inet_ntoa(*agent_inaddr))) {
Packit Service b38f0b
                if (temp_buf != NULL) {
Packit Service b38f0b
                    free(temp_buf);
Packit Service b38f0b
                }
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_PDU_IP:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the numerical transport information.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (transport != NULL && transport->f_fmtaddr != NULL) {
Packit Service b38f0b
            oflags = transport->flags;
Packit Service b38f0b
            transport->flags &= ~NETSNMP_TRANSPORT_FLAG_HOSTNAME;
Packit Service b38f0b
            tstr = transport->f_fmtaddr(transport, pdu->transport_data,
Packit Service b38f0b
                                        pdu->transport_data_length);
Packit Service b38f0b
            transport->flags = oflags;
Packit Service b38f0b
          
Packit Service b38f0b
            if (!tstr) goto noip;
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len,
Packit Service b38f0b
                             1, (u_char *)tstr)) {
Packit Service b38f0b
                SNMP_FREE(temp_buf);
Packit Service b38f0b
                SNMP_FREE(tstr);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
            SNMP_FREE(tstr);
Packit Service b38f0b
        } else {
Packit Service b38f0b
noip:
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
Packit Service b38f0b
                             (const u_char*)"<UNKNOWN>")) {
Packit Service b38f0b
                SNMP_FREE(temp_buf);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_PDU_NAME:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Try to convert the numerical transport information
Packit Service b38f0b
         *  into a hostname.  Or rather, have the transport-specific
Packit Service b38f0b
         *  address formatting routine do this.
Packit Service b38f0b
         * Otherwise falls back to the numeric address format.
Packit Service b38f0b
         */
Packit Service b38f0b
        if (transport != NULL && transport->f_fmtaddr != NULL) {
Packit Service b38f0b
            oflags = transport->flags;
Packit Service b38f0b
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
                                        NETSNMP_DS_APP_NUMERIC_IP))
Packit Service b38f0b
                transport->flags |= NETSNMP_TRANSPORT_FLAG_HOSTNAME;
Packit Service b38f0b
            tstr = transport->f_fmtaddr(transport, pdu->transport_data,
Packit Service b38f0b
                                        pdu->transport_data_length);
Packit Service b38f0b
            transport->flags = oflags;
Packit Service b38f0b
          
Packit Service b38f0b
            if (!tstr) goto nohost;
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len,
Packit Service b38f0b
                             1, (u_char *)tstr)) {
Packit Service b38f0b
                SNMP_FREE(temp_buf);
Packit Service b38f0b
                SNMP_FREE(tstr);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
            SNMP_FREE(tstr);
Packit Service b38f0b
        } else {
Packit Service b38f0b
nohost:
Packit Service b38f0b
            if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
Packit Service b38f0b
                             (const u_char*)"<UNKNOWN>")) {
Packit Service b38f0b
                SNMP_FREE(temp_buf);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Don't know how to handle this command - write the character itself.  
Packit Service b38f0b
         */
Packit Service b38f0b
    default:
Packit Service b38f0b
        temp_buf[0] = fmt_cmd;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Output with correct justification, leading zeroes, etc.  
Packit Service b38f0b
     */
Packit Service b38f0b
    return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                   &temp_buf, options);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_ent_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                       int allow_realloc,
Packit Service b38f0b
                       options_type * options, netsnmp_pdu *pdu)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Handle a format command that deals with OID strings. 
Packit Service b38f0b
      * Append the information to the buffer subject to the
Packit Service b38f0b
      * buffer's length limit.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options - options governing how to write the field
Packit Service b38f0b
      *    pdu     - information about this trap 
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* what we're formatting */
Packit Service b38f0b
    u_char         *temp_buf = NULL;
Packit Service b38f0b
    size_t          temp_buf_len = 64, temp_out_len = 0;
Packit Service b38f0b
Packit Service b38f0b
    if ((temp_buf = (u_char *) calloc(temp_buf_len, 1)) == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Decide exactly what to output.  
Packit Service b38f0b
     */
Packit Service b38f0b
    switch (fmt_cmd) {
Packit Service b38f0b
    case CHR_PDU_ENT:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the enterprise oid.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!sprint_realloc_objid
Packit Service b38f0b
            (&temp_buf, &temp_buf_len, &temp_out_len, 1, pdu->enterprise,
Packit Service b38f0b
             pdu->enterprise_length)) {
Packit Service b38f0b
            free(temp_buf);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_TRAP_CONTEXTID:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the context oid.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!sprint_realloc_hexstring
Packit Service b38f0b
            (&temp_buf, &temp_buf_len, &temp_out_len, 1, pdu->contextEngineID,
Packit Service b38f0b
             pdu->contextEngineIDLen)) {
Packit Service b38f0b
            free(temp_buf);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Don't know how to handle this command - write the character itself.  
Packit Service b38f0b
         */
Packit Service b38f0b
    default:
Packit Service b38f0b
        temp_buf[0] = fmt_cmd;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Output with correct justification, leading zeroes, etc.  
Packit Service b38f0b
     */
Packit Service b38f0b
    return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                   &temp_buf, options);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_trap_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                        int allow_realloc,
Packit Service b38f0b
                        options_type * options, netsnmp_pdu *pdu)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Handle a format command that deals with the trap itself. 
Packit Service b38f0b
      * Append the information to the buffer subject to the buffer's 
Packit Service b38f0b
      * length limit.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options - options governing how to write the field
Packit Service b38f0b
      *    pdu     - information about this trap 
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    netsnmp_variable_list *vars;        /* variables assoc with trap */
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* what we're outputting */
Packit Service b38f0b
    u_char         *temp_buf = NULL;
Packit Service b38f0b
    size_t          tbuf_len = 64, tout_len = 0;
Packit Service b38f0b
    const char           *sep = separator;
Packit Service b38f0b
    const char           *default_sep = "\t";
Packit Service b38f0b
    const char           *default_alt_sep = ", ";
Packit Service b38f0b
Packit Service b38f0b
    if ((temp_buf = (u_char *) calloc(tbuf_len, 1)) == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Decide exactly what to output.  
Packit Service b38f0b
     */
Packit Service b38f0b
    switch (fmt_cmd) {
Packit Service b38f0b
    case CHR_TRAP_NUM:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the trap's number.  
Packit Service b38f0b
         */
Packit Service b38f0b
        tout_len = sprintf((char*)temp_buf, "%ld", pdu->trap_type);
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_TRAP_DESC:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the trap's description.  
Packit Service b38f0b
         */
Packit Service b38f0b
        tout_len =
Packit Service b38f0b
            sprintf((char*)temp_buf, "%s", trap_description(pdu->trap_type));
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_TRAP_STYPE:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the trap's subtype.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC) {
Packit Service b38f0b
            tout_len = sprintf((char*)temp_buf, "%ld", pdu->specific_type);
Packit Service b38f0b
        } else {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Get object ID for the trap.  
Packit Service b38f0b
             */
Packit Service b38f0b
            size_t          obuf_len = 64, oout_len = 0, trap_oid_len = 0;
Packit Service b38f0b
            oid             trap_oid[MAX_OID_LEN + 2] = { 0 };
Packit Service b38f0b
            u_char         *obuf = NULL;
Packit Service b38f0b
            char           *ptr = NULL;
Packit Service b38f0b
Packit Service b38f0b
            if ((obuf = (u_char *) calloc(obuf_len, 1)) == NULL) {
Packit Service b38f0b
                free(temp_buf);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
Packit Service b38f0b
            trap_oid_len = pdu->enterprise_length;
Packit Service b38f0b
            memcpy(trap_oid, pdu->enterprise, trap_oid_len * sizeof(oid));
Packit Service b38f0b
            if (trap_oid[trap_oid_len - 1] != 0) {
Packit Service b38f0b
                trap_oid[trap_oid_len] = 0;
Packit Service b38f0b
                trap_oid_len++;
Packit Service b38f0b
            }
Packit Service b38f0b
            trap_oid[trap_oid_len] = pdu->specific_type;
Packit Service b38f0b
            trap_oid_len++;
Packit Service b38f0b
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Find the element after the last dot.  
Packit Service b38f0b
             */
Packit Service b38f0b
            if (!sprint_realloc_objid(&obuf, &obuf_len, &oout_len, 1,
Packit Service b38f0b
                                      trap_oid, trap_oid_len)) {
Packit Service b38f0b
                if (obuf != NULL) {
Packit Service b38f0b
                    free(obuf);
Packit Service b38f0b
                }
Packit Service b38f0b
                free(temp_buf);
Packit Service b38f0b
		return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
Packit Service b38f0b
            ptr = strrchr((char *) obuf, '.');
Packit Service b38f0b
            if (ptr != NULL) {
Packit Service b38f0b
                if (!snmp_strcat
Packit Service b38f0b
                    (&temp_buf, &tbuf_len, &tout_len, 1, (u_char *) ptr)) {
Packit Service b38f0b
                    free(obuf);
Packit Service b38f0b
                    if (temp_buf != NULL) {
Packit Service b38f0b
                        free(temp_buf);
Packit Service b38f0b
                    }
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
                free(obuf);
Packit Service b38f0b
            } else {
Packit Service b38f0b
                free(temp_buf);
Packit Service b38f0b
                temp_buf = obuf;
Packit Service b38f0b
                tbuf_len = obuf_len;
Packit Service b38f0b
                tout_len = oout_len;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_TRAP_VARS:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Write the trap's variables.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!sep || !*sep)
Packit Service b38f0b
            sep = (options->alt_format ? default_alt_sep : default_sep);
Packit Service b38f0b
        for (vars = pdu->variables; vars != NULL;
Packit Service b38f0b
             vars = vars->next_variable) {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Print a separator between variables,
Packit Service b38f0b
             *   (plus beforehand if the alt format is used)
Packit Service b38f0b
             */
Packit Service b38f0b
            if (options->alt_format ||
Packit Service b38f0b
                vars != pdu->variables ) {
Packit Service b38f0b
                if (!snmp_strcat(&temp_buf, &tbuf_len, &tout_len, 1, (const u_char *)sep)) {
Packit Service b38f0b
                    if (temp_buf != NULL) {
Packit Service b38f0b
                        free(temp_buf);
Packit Service b38f0b
                    }
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
            if (!sprint_realloc_variable
Packit Service b38f0b
                (&temp_buf, &tbuf_len, &tout_len, 1, vars->name,
Packit Service b38f0b
                 vars->name_length, vars)) {
Packit Service b38f0b
                if (temp_buf != NULL) {
Packit Service b38f0b
                    free(temp_buf);
Packit Service b38f0b
                }
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    default:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Don't know how to handle this command - write the character itself.  
Packit Service b38f0b
         */
Packit Service b38f0b
        temp_buf[0] = fmt_cmd;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Output with correct justification, leading zeroes, etc.  
Packit Service b38f0b
     */
Packit Service b38f0b
    return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                   &temp_buf, options);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_auth_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                        int allow_realloc,
Packit Service b38f0b
                        options_type * options, netsnmp_pdu *pdu)
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Handle a format command that deals with authentication
Packit Service b38f0b
      * information.
Packit Service b38f0b
      * Append the information to the buffer subject to the buffer's 
Packit Service b38f0b
      * length limit.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options - options governing how to write the field
Packit Service b38f0b
      *    pdu     - information about this trap 
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* what we're outputting */
Packit Service b38f0b
    u_char         *temp_buf = NULL;
Packit Service b38f0b
    size_t          tbuf_len = 64;
Packit Service b38f0b
    unsigned int    i;
Packit Service b38f0b
Packit Service b38f0b
    if ((temp_buf = (u_char*)calloc(tbuf_len, 1)) == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    switch (fmt_cmd) {
Packit Service b38f0b
Packit Service b38f0b
    case CHR_SNMP_VERSION:
Packit Service b38f0b
        snprintf((char*)temp_buf, tbuf_len, "%ld", pdu->version);
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_SNMP_SECMOD:
Packit Service b38f0b
        snprintf((char*)temp_buf, tbuf_len, "%d", pdu->securityModel);
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    case CHR_SNMP_USER:
Packit Service b38f0b
        switch ( pdu->version ) {
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV1
Packit Service b38f0b
        case SNMP_VERSION_1:
Packit Service b38f0b
#endif
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV2C
Packit Service b38f0b
        case SNMP_VERSION_2c:
Packit Service b38f0b
#endif
Packit Service b38f0b
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
Packit Service b38f0b
            while ((*out_len + pdu->community_len + 1) >= *buf_len) {
Packit Service b38f0b
                if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                    if (temp_buf)
Packit Service b38f0b
                        free(temp_buf);
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
Packit Service b38f0b
            for (i = 0; i < pdu->community_len; i++) {
Packit Service b38f0b
                if (isprint(pdu->community[i])) {
Packit Service b38f0b
                    *(*buf + *out_len) = pdu->community[i];
Packit Service b38f0b
                } else {
Packit Service b38f0b
                    *(*buf + *out_len) = '.';
Packit Service b38f0b
                }
Packit Service b38f0b
                (*out_len)++;
Packit Service b38f0b
            }
Packit Service b38f0b
            *(*buf + *out_len) = '\0';
Packit Service b38f0b
            break;
Packit Service b38f0b
#endif
Packit Service b38f0b
        default:
Packit Service b38f0b
            snprintf((char*)temp_buf, tbuf_len, "%s", pdu->securityName);
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
Packit Service b38f0b
    default:
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Don't know how to handle this command - write the character itself.  
Packit Service b38f0b
         */
Packit Service b38f0b
        temp_buf[0] = fmt_cmd;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Output with correct justification, leading zeroes, etc.  
Packit Service b38f0b
     */
Packit Service b38f0b
    return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                   &temp_buf, options);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_wrap_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                        int allow_realloc, netsnmp_pdu *pdu)
Packit Service b38f0b
{
Packit Service b38f0b
    size_t          i = 0;
Packit Service b38f0b
Packit Service b38f0b
    switch (pdu->command) {
Packit Service b38f0b
    case SNMP_MSG_TRAP:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "TRAP")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
    case SNMP_MSG_TRAP2:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "TRAP2")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
    case SNMP_MSG_INFORM:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "INFORM")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    switch (pdu->version) {
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV1
Packit Service b38f0b
    case SNMP_VERSION_1:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", SNMP v1")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
#endif
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV2C
Packit Service b38f0b
    case SNMP_VERSION_2c:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", SNMP v2c")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
#endif
Packit Service b38f0b
    case SNMP_VERSION_3:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", SNMP v3")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        break;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    switch (pdu->version) {
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV1
Packit Service b38f0b
    case SNMP_VERSION_1:
Packit Service b38f0b
#endif
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_SNMPV2C
Packit Service b38f0b
    case SNMP_VERSION_2c:
Packit Service b38f0b
#endif
Packit Service b38f0b
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", community ")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        while ((*out_len + pdu->community_len + 1) >= *buf_len) {
Packit Service b38f0b
            if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        for (i = 0; i < pdu->community_len; i++) {
Packit Service b38f0b
            if (isprint(pdu->community[i])) {
Packit Service b38f0b
                *(*buf + *out_len) = pdu->community[i];
Packit Service b38f0b
            } else {
Packit Service b38f0b
                *(*buf + *out_len) = '.';
Packit Service b38f0b
            }
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
        }
Packit Service b38f0b
        *(*buf + *out_len) = '\0';
Packit Service b38f0b
        break;
Packit Service b38f0b
#endif
Packit Service b38f0b
    case SNMP_VERSION_3:
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", user ")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        while ((*out_len + pdu->securityNameLen + 1) >= *buf_len) {
Packit Service b38f0b
            if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        for (i = 0; i < pdu->securityNameLen; i++) {
Packit Service b38f0b
            if (isprint((unsigned char)(pdu->securityName[i]))) {
Packit Service b38f0b
                *(*buf + *out_len) = pdu->securityName[i];
Packit Service b38f0b
            } else {
Packit Service b38f0b
                *(*buf + *out_len) = '.';
Packit Service b38f0b
            }
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
        }
Packit Service b38f0b
        *(*buf + *out_len) = '\0';
Packit Service b38f0b
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ", context ")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        while ((*out_len + pdu->contextNameLen + 1) >= *buf_len) {
Packit Service b38f0b
            if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        for (i = 0; i < pdu->contextNameLen; i++) {
Packit Service b38f0b
            if (isprint((unsigned char)(pdu->contextName[i]))) {
Packit Service b38f0b
                *(*buf + *out_len) = pdu->contextName[i];
Packit Service b38f0b
            } else {
Packit Service b38f0b
                *(*buf + *out_len) = '.';
Packit Service b38f0b
            }
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
        }
Packit Service b38f0b
        *(*buf + *out_len) = '\0';
Packit Service b38f0b
    }
Packit Service b38f0b
    return 1;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_dispatch_format_cmd(u_char ** buf, size_t * buf_len,
Packit Service b38f0b
                            size_t * out_len, int allow_realloc,
Packit Service b38f0b
                            options_type * options, netsnmp_pdu *pdu,
Packit Service b38f0b
                            netsnmp_transport *transport)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Dispatch a format command to the appropriate command handler.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    options   - options governing how to write the field
Packit Service b38f0b
      *    pdu       - information about this trap
Packit Service b38f0b
      *    transport - the transport descriptor
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    char            fmt_cmd = options->cmd;     /* for speed */
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * choose the appropriate command handler 
Packit Service b38f0b
     */
Packit Service b38f0b
Packit Service b38f0b
    if (is_cur_time_cmd(fmt_cmd) || is_up_time_cmd(fmt_cmd)) {
Packit Service b38f0b
        return realloc_handle_time_fmt(buf, buf_len, out_len,
Packit Service b38f0b
                                       allow_realloc, options, pdu);
Packit Service b38f0b
    } else if (is_agent_cmd(fmt_cmd) || is_pdu_ip_cmd(fmt_cmd)) {
Packit Service b38f0b
        return realloc_handle_ip_fmt(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                     options, pdu, transport);
Packit Service b38f0b
    } else if (is_trap_cmd(fmt_cmd)) {
Packit Service b38f0b
        return realloc_handle_trap_fmt(buf, buf_len, out_len,
Packit Service b38f0b
                                       allow_realloc, options, pdu);
Packit Service b38f0b
    } else if (is_auth_cmd(fmt_cmd)) {
Packit Service b38f0b
        return realloc_handle_auth_fmt(buf, buf_len, out_len,
Packit Service b38f0b
                                       allow_realloc, options, pdu);
Packit Service b38f0b
    } else if (fmt_cmd == CHR_PDU_ENT || fmt_cmd == CHR_TRAP_CONTEXTID) {
Packit Service b38f0b
        return realloc_handle_ent_fmt(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                      options, pdu);
Packit Service b38f0b
    } else if (fmt_cmd == CHR_PDU_WRAP) {
Packit Service b38f0b
        return realloc_handle_wrap_fmt(buf, buf_len, out_len,
Packit Service b38f0b
                                       allow_realloc, pdu);
Packit Service b38f0b
    } else {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * unknown format command - just output the character 
Packit Service b38f0b
         */
Packit Service b38f0b
        char            fmt_cmd_string[2] = { 0, 0 };
Packit Service b38f0b
        fmt_cmd_string[0] = fmt_cmd;
Packit Service b38f0b
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) fmt_cmd_string);
Packit Service b38f0b
    }
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
static int
Packit Service b38f0b
realloc_handle_backslash(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                         int allow_realloc, char fmt_cmd)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *     Handle a character following a backslash. Append the resulting 
Packit Service b38f0b
      * character to the buffer subject to the buffer's length limit.
Packit Service b38f0b
      *     This routine currently isn't sophisticated enough to handle
Packit Service b38f0b
      * \nnn or \xhh formats.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    fmt_cmd - the character after the backslash
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    char            temp_bfr[3];        /* for bulding temporary strings */
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * select the proper output character(s) 
Packit Service b38f0b
     */
Packit Service b38f0b
    switch (fmt_cmd) {
Packit Service b38f0b
    case 'a':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\a");
Packit Service b38f0b
    case 'b':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\b");
Packit Service b38f0b
    case 'f':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\f");
Packit Service b38f0b
    case 'n':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\n");
Packit Service b38f0b
    case 'r':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\r");
Packit Service b38f0b
    case 't':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\t");
Packit Service b38f0b
    case 'v':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\v");
Packit Service b38f0b
    case '\\':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\\");
Packit Service b38f0b
    case '?':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "?");
Packit Service b38f0b
    case '%':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "%");
Packit Service b38f0b
    case '\'':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\'");
Packit Service b38f0b
    case '"':
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) "\"");
Packit Service b38f0b
    default:
Packit Service b38f0b
        sprintf(temp_bfr, "\\%c", fmt_cmd);
Packit Service b38f0b
        return snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                           (const u_char *) temp_bfr);
Packit Service b38f0b
    }
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
realloc_format_plain_trap(u_char ** buf, size_t * buf_len,
Packit Service b38f0b
                          size_t * out_len, int allow_realloc,
Packit Service b38f0b
                          netsnmp_pdu *pdu, netsnmp_transport *transport)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Format the trap information in the default way and put the results
Packit Service b38f0b
      * into the buffer, truncating at the buffer's length limit. This
Packit Service b38f0b
      * routine returns 1 if the output was completed successfully or
Packit Service b38f0b
      * 0 if it is truncated due to a memory allocation failure.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    pdu       - the pdu information
Packit Service b38f0b
      *    transport - the transport descriptor
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    time_t          now;        /* the current time */
Packit Service b38f0b
    struct tm      *now_parsed; /* time in struct format */
Packit Service b38f0b
    char            safe_bfr[200];      /* holds other strings */
Packit Service b38f0b
    struct in_addr *agent_inaddr = (struct in_addr *) pdu->agent_addr;
Packit Service b38f0b
    struct hostent *host = NULL;       /* host name */
Packit Service b38f0b
    netsnmp_variable_list *vars;        /* variables assoc with trap */
Packit Service b38f0b
Packit Service b38f0b
    if (buf == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Print the current time. Since we don't know how long the buffer is,
Packit Service b38f0b
     * and snprintf isn't yet standard, build the timestamp in a separate
Packit Service b38f0b
     * buffer of guaranteed length and then copy it to the output buffer.
Packit Service b38f0b
     */
Packit Service b38f0b
    time(&now;;
Packit Service b38f0b
    now_parsed = localtime(&now;;
Packit Service b38f0b
    sprintf(safe_bfr, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d ",
Packit Service b38f0b
            now_parsed->tm_year + 1900, now_parsed->tm_mon + 1,
Packit Service b38f0b
            now_parsed->tm_mday, now_parsed->tm_hour,
Packit Service b38f0b
            now_parsed->tm_min, now_parsed->tm_sec);
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
         (const u_char *) safe_bfr)) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Get info about the sender.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit Service b38f0b
                                NETSNMP_DS_APP_NUMERIC_IP)) {
Packit Service b38f0b
        host = netsnmp_gethostbyaddr((char *) pdu->agent_addr, 4, AF_INET);
Packit Service b38f0b
    }
Packit Service b38f0b
    if (host != (struct hostent *) NULL) {
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) host->h_name)) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) " [")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                         (const u_char *) inet_ntoa(*agent_inaddr))) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "] ")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
    } else {
Packit Service b38f0b
        if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                         (const u_char *) inet_ntoa(*agent_inaddr))) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Append PDU transport info.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (transport != NULL && transport->f_fmtaddr != NULL) {
Packit Service b38f0b
        char           *tstr =
Packit Service b38f0b
            transport->f_fmtaddr(transport, pdu->transport_data,
Packit Service b38f0b
                                 pdu->transport_data_length);
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "(via ")) {
Packit Service b38f0b
            if (tstr != NULL) {
Packit Service b38f0b
                free(tstr);
Packit Service b38f0b
            }
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, (u_char *)tstr)) {
Packit Service b38f0b
            if (tstr != NULL) {
Packit Service b38f0b
                free(tstr);
Packit Service b38f0b
            }
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (tstr != NULL) {
Packit Service b38f0b
            free(tstr);
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ") ")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Add security wrapper information.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!realloc_handle_wrap_fmt
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc, pdu)) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n\t")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Add enterprise information.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!sprint_realloc_objid(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                              pdu->enterprise, pdu->enterprise_length)) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc, (const u_char *) " ")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                     (const u_char *)trap_description(pdu->trap_type))) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
         (const u_char *) " Trap (")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Handle enterprise specific traps.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
Packit Service b38f0b
        size_t          obuf_len = 64, oout_len = 0, trap_oid_len = 0;
Packit Service b38f0b
        oid             trap_oid[MAX_OID_LEN + 2] = { 0 };
Packit Service b38f0b
        char           *ent_spec_code = NULL;
Packit Service b38f0b
        u_char         *obuf = NULL;
Packit Service b38f0b
Packit Service b38f0b
        if ((obuf = (u_char *) calloc(obuf_len, 1)) == NULL) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Get object ID for the trap.  
Packit Service b38f0b
         */
Packit Service b38f0b
        trap_oid_len = pdu->enterprise_length;
Packit Service b38f0b
        memcpy(trap_oid, pdu->enterprise, trap_oid_len * sizeof(oid));
Packit Service b38f0b
        if (trap_oid[trap_oid_len - 1] != 0) {
Packit Service b38f0b
            trap_oid[trap_oid_len] = 0;
Packit Service b38f0b
            trap_oid_len++;
Packit Service b38f0b
        }
Packit Service b38f0b
        trap_oid[trap_oid_len] = pdu->specific_type;
Packit Service b38f0b
        trap_oid_len++;
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Find the element after the last dot.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!sprint_realloc_objid(&obuf, &obuf_len, &oout_len, 1,
Packit Service b38f0b
                                  trap_oid, trap_oid_len)) {
Packit Service b38f0b
            if (obuf != NULL) {
Packit Service b38f0b
                free(obuf);
Packit Service b38f0b
            }
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        ent_spec_code = strrchr((char *) obuf, '.');
Packit Service b38f0b
        if (ent_spec_code != NULL) {
Packit Service b38f0b
            ent_spec_code++;
Packit Service b38f0b
        } else {
Packit Service b38f0b
            ent_spec_code = (char *) obuf;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Print trap info.  
Packit Service b38f0b
         */
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) ent_spec_code)) {
Packit Service b38f0b
            free(obuf);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        free(obuf);
Packit Service b38f0b
    } else {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Handle traps that aren't enterprise specific.  
Packit Service b38f0b
         */
Packit Service b38f0b
        sprintf(safe_bfr, "%ld", pdu->specific_type);
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) safe_bfr)) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Finish the line.  
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
         (const u_char *) ") Uptime: ")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                     (const u_char *) uptime_string(pdu->time,
Packit Service b38f0b
                                                    safe_bfr))) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Finally, output the PDU variables. 
Packit Service b38f0b
     */
Packit Service b38f0b
    for (vars = pdu->variables; vars != NULL; vars = vars->next_variable) {
Packit Service b38f0b
        if (!snmp_strcat
Packit Service b38f0b
            (buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
             (const u_char *) "\t")) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (!sprint_realloc_variable(buf, buf_len, out_len, allow_realloc,
Packit Service b38f0b
                                     vars->name, vars->name_length,
Packit Service b38f0b
                                     vars)) {
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!snmp_strcat
Packit Service b38f0b
        (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n")) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * String is already null-terminated.  That's all folks!  
Packit Service b38f0b
     */
Packit Service b38f0b
    return 1;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
realloc_format_trap(u_char ** buf, size_t * buf_len, size_t * out_len,
Packit Service b38f0b
                    int allow_realloc, const char *format_str,
Packit Service b38f0b
                    netsnmp_pdu *pdu, netsnmp_transport *transport)
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * Function:
Packit Service b38f0b
      *    Format the trap information for display in a log. Place the results
Packit Service b38f0b
      *    in the specified buffer (truncating to the length of the buffer).
Packit Service b38f0b
      *    Returns the number of characters it put in the buffer.
Packit Service b38f0b
      *
Packit Service b38f0b
      * Input Parameters:
Packit Service b38f0b
      *    buf, buf_len, out_len, allow_realloc - standard relocatable
Packit Service b38f0b
      *                                           buffer parameters
Packit Service b38f0b
      *    format_str - specifies how to format the trap info
Packit Service b38f0b
      *    pdu        - the pdu information
Packit Service b38f0b
      *    transport  - the transport descriptor
Packit Service b38f0b
      */
Packit Service b38f0b
{
Packit Service b38f0b
    unsigned long   fmt_idx = 0;        /* index into the format string */
Packit Service b38f0b
    options_type    options;    /* formatting options */
Packit Service b38f0b
    parse_state_type state = PARSE_NORMAL;      /* state of the parser */
Packit Service b38f0b
    char            next_chr;   /* for speed */
Packit Service b38f0b
    int             reset_options = TRUE;       /* reset opts on next NORMAL state */
Packit Service b38f0b
Packit Service b38f0b
    if (buf == NULL) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    memset(separator, 0, sizeof(separator));
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Go until we reach the end of the format string:  
Packit Service b38f0b
     */
Packit Service b38f0b
    for (fmt_idx = 0; format_str[fmt_idx] != '\0'; fmt_idx++) {
Packit Service b38f0b
        next_chr = format_str[fmt_idx];
Packit Service b38f0b
        switch (state) {
Packit Service b38f0b
        case PARSE_NORMAL:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Looking for next character.  
Packit Service b38f0b
             */
Packit Service b38f0b
            if (reset_options) {
Packit Service b38f0b
                init_options(&options);
Packit Service b38f0b
                reset_options = FALSE;
Packit Service b38f0b
            }
Packit Service b38f0b
            if (next_chr == '\\') {
Packit Service b38f0b
                state = PARSE_BACKSLASH;
Packit Service b38f0b
            } else if (next_chr == CHR_FMT_DELIM) {
Packit Service b38f0b
                state = PARSE_IN_FORMAT;
Packit Service b38f0b
            } else {
Packit Service b38f0b
                if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                    if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                        return 0;
Packit Service b38f0b
                    }
Packit Service b38f0b
                }
Packit Service b38f0b
                *(*buf + *out_len) = next_chr;
Packit Service b38f0b
                (*out_len)++;
Packit Service b38f0b
            }
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        case PARSE_GET_SEPARATOR:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Parse the separator character
Packit Service b38f0b
             * XXX - Possibly need to handle quoted strings ??
Packit Service b38f0b
             */
Packit Service b38f0b
	    {   char *sep = separator;
Packit Service b38f0b
		size_t i, j;
Packit Service b38f0b
		i = sizeof(separator);
Packit Service b38f0b
		j = 0;
Packit Service b38f0b
		memset(separator, 0, i);
Packit Service b38f0b
		while (j < i && next_chr && next_chr != CHR_FMT_DELIM) {
Packit Service b38f0b
		    if (next_chr == '\\') {
Packit Service b38f0b
			/*
Packit Service b38f0b
			 * Handle backslash interpretation
Packit Service b38f0b
			 * Print to "separator" string rather than the output buffer
Packit Service b38f0b
			 *    (a bit of a hack, but it should work!)
Packit Service b38f0b
			 */
Packit Service b38f0b
			next_chr = format_str[++fmt_idx];
Packit Service b38f0b
			if (!realloc_handle_backslash
Packit Service b38f0b
			    ((u_char **)&sep, &i, &j, 0, next_chr)) {
Packit Service b38f0b
			    return 0;
Packit Service b38f0b
			}
Packit Service b38f0b
		    } else {
Packit Service b38f0b
			separator[j++] = next_chr;
Packit Service b38f0b
		    }
Packit Service b38f0b
		    next_chr = format_str[++fmt_idx];
Packit Service b38f0b
		}
Packit Service b38f0b
	    }
Packit Service b38f0b
            state = PARSE_IN_FORMAT;
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        case PARSE_BACKSLASH:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Found a backslash.  
Packit Service b38f0b
             */
Packit Service b38f0b
            if (!realloc_handle_backslash
Packit Service b38f0b
                (buf, buf_len, out_len, allow_realloc, next_chr)) {
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
            state = PARSE_NORMAL;
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        case PARSE_IN_FORMAT:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * In a format command.  
Packit Service b38f0b
             */
Packit Service b38f0b
            reset_options = TRUE;
Packit Service b38f0b
            if (next_chr == CHR_LEFT_JUST) {
Packit Service b38f0b
                options.left_justify = TRUE;
Packit Service b38f0b
            } else if (next_chr == CHR_LEAD_ZERO) {
Packit Service b38f0b
                options.leading_zeroes = TRUE;
Packit Service b38f0b
            } else if (next_chr == CHR_ALT_FORM) {
Packit Service b38f0b
                options.alt_format = TRUE;
Packit Service b38f0b
            } else if (next_chr == CHR_FIELD_SEP) {
Packit Service b38f0b
                state = PARSE_GET_PRECISION;
Packit Service b38f0b
            } else if (next_chr == CHR_TRAP_VARSEP) {
Packit Service b38f0b
                state = PARSE_GET_SEPARATOR;
Packit Service b38f0b
            } else if ((next_chr >= '1') && (next_chr <= '9')) {
Packit Service b38f0b
                options.width =
Packit Service b38f0b
                    ((unsigned long) next_chr) - ((unsigned long) '0');
Packit Service b38f0b
                state = PARSE_GET_WIDTH;
Packit Service b38f0b
            } else if (is_fmt_cmd(next_chr)) {
Packit Service b38f0b
                options.cmd = next_chr;
Packit Service b38f0b
                if (!realloc_dispatch_format_cmd
Packit Service b38f0b
                    (buf, buf_len, out_len, allow_realloc, &options, pdu,
Packit Service b38f0b
                     transport)) {
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            } else {
Packit Service b38f0b
                if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                    if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                        return 0;
Packit Service b38f0b
                    }
Packit Service b38f0b
                }
Packit Service b38f0b
                *(*buf + *out_len) = next_chr;
Packit Service b38f0b
                (*out_len)++;
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            }
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        case PARSE_GET_WIDTH:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Parsing a width field.  
Packit Service b38f0b
             */
Packit Service b38f0b
            reset_options = TRUE;
Packit Service b38f0b
            if (isdigit((unsigned char)(next_chr))) {
Packit Service b38f0b
                options.width *= 10;
Packit Service b38f0b
                options.width +=
Packit Service b38f0b
                    (unsigned long) next_chr - (unsigned long) '0';
Packit Service b38f0b
            } else if (next_chr == CHR_FIELD_SEP) {
Packit Service b38f0b
                state = PARSE_GET_PRECISION;
Packit Service b38f0b
            } else if (is_fmt_cmd(next_chr)) {
Packit Service b38f0b
                options.cmd = next_chr;
Packit Service b38f0b
                if (!realloc_dispatch_format_cmd
Packit Service b38f0b
                    (buf, buf_len, out_len, allow_realloc, &options, pdu,
Packit Service b38f0b
                     transport)) {
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            } else {
Packit Service b38f0b
                if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                    if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                        return 0;
Packit Service b38f0b
                    }
Packit Service b38f0b
                }
Packit Service b38f0b
                *(*buf + *out_len) = next_chr;
Packit Service b38f0b
                (*out_len)++;
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            }
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        case PARSE_GET_PRECISION:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Parsing a precision field.  
Packit Service b38f0b
             */
Packit Service b38f0b
            reset_options = TRUE;
Packit Service b38f0b
            if (isdigit((unsigned char)(next_chr))) {
Packit Service b38f0b
                if (options.precision == UNDEF_PRECISION) {
Packit Service b38f0b
                    options.precision =
Packit Service b38f0b
                        (unsigned long) next_chr - (unsigned long) '0';
Packit Service b38f0b
                } else {
Packit Service b38f0b
                    options.precision *= 10;
Packit Service b38f0b
                    options.precision +=
Packit Service b38f0b
                        (unsigned long) next_chr - (unsigned long) '0';
Packit Service b38f0b
                }
Packit Service b38f0b
            } else if (is_fmt_cmd(next_chr)) {
Packit Service b38f0b
                options.cmd = next_chr;
Packit Service b38f0b
                if ((options.precision != UNDEF_PRECISION) &&
Packit Service b38f0b
                    (options.width < (size_t)options.precision)) {
Packit Service b38f0b
                    options.width = (size_t)options.precision;
Packit Service b38f0b
                }
Packit Service b38f0b
                if (!realloc_dispatch_format_cmd
Packit Service b38f0b
                    (buf, buf_len, out_len, allow_realloc, &options, pdu,
Packit Service b38f0b
                     transport)) {
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            } else {
Packit Service b38f0b
                if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                    if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                        return 0;
Packit Service b38f0b
                    }
Packit Service b38f0b
                }
Packit Service b38f0b
                *(*buf + *out_len) = next_chr;
Packit Service b38f0b
                (*out_len)++;
Packit Service b38f0b
                state = PARSE_NORMAL;
Packit Service b38f0b
            }
Packit Service b38f0b
            break;
Packit Service b38f0b
Packit Service b38f0b
        default:
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Unknown state.  
Packit Service b38f0b
             */
Packit Service b38f0b
            reset_options = TRUE;
Packit Service b38f0b
            if ((*out_len + 1) >= *buf_len) {
Packit Service b38f0b
                if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
Packit Service b38f0b
                    return 0;
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
            *(*buf + *out_len) = next_chr;
Packit Service b38f0b
            (*out_len)++;
Packit Service b38f0b
            state = PARSE_NORMAL;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    *(*buf + *out_len) = '\0';
Packit Service b38f0b
    return 1;
Packit Service b38f0b
}