Blame agent/snmpd.c

Packit fcad23
/*
Packit fcad23
 * snmpd.c
Packit fcad23
 */
Packit fcad23
/** @defgroup agent The Net-SNMP agent
Packit fcad23
 * The snmp agent responds to SNMP queries from management stations
Packit fcad23
 */
Packit fcad23
/* Portions of this file are subject to the following copyrights.  See
Packit fcad23
 * the Net-SNMP's COPYING file for more details and other copyrights
Packit fcad23
 * that may apply:
Packit fcad23
 */
Packit fcad23
/*
Packit fcad23
 * Copyright 1988, 1989 by Carnegie Mellon University
Packit fcad23
 * 
Packit fcad23
 * All Rights Reserved
Packit fcad23
 * 
Packit fcad23
 * Permission to use, copy, modify, and distribute this software and its 
Packit fcad23
 * documentation for any purpose and without fee is hereby granted, 
Packit fcad23
 * provided that the above copyright notice appear in all copies and that
Packit fcad23
 * both that copyright notice and this permission notice appear in 
Packit fcad23
 * supporting documentation, and that the name of CMU not be
Packit fcad23
 * used in advertising or publicity pertaining to distribution of the
Packit fcad23
 * software without specific, written prior permission.  
Packit fcad23
 * 
Packit fcad23
 * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
Packit fcad23
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
Packit fcad23
 * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
Packit fcad23
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit fcad23
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
Packit fcad23
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
Packit fcad23
 * SOFTWARE.
Packit fcad23
 * *****************************************************************
Packit fcad23
 */
Packit fcad23
/*
Packit fcad23
 * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
Packit fcad23
 * Use is subject to license terms specified in the COPYING file
Packit fcad23
 * distributed with the Net-SNMP package.
Packit fcad23
 */
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
#include <net-snmp/net-snmp-features.h>
Packit fcad23
#include <net-snmp/types.h>
Packit fcad23
Packit fcad23
#if HAVE_IO_H
Packit fcad23
#include <io.h>
Packit fcad23
#endif
Packit fcad23
#include <stdio.h>
Packit fcad23
#include <errno.h>
Packit fcad23
#if HAVE_STRING_H
Packit fcad23
#include <string.h>
Packit fcad23
#else
Packit fcad23
#include <strings.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_STDLIB_H
Packit fcad23
#include <stdlib.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
#include <unistd.h>
Packit fcad23
#endif
Packit fcad23
#include <sys/types.h>
Packit fcad23
#if HAVE_NETINET_IN_H
Packit fcad23
#include <netinet/in.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_ARPA_INET_H
Packit fcad23
#include <arpa/inet.h>
Packit fcad23
#endif
Packit fcad23
#if TIME_WITH_SYS_TIME
Packit fcad23
# include <sys/time.h>
Packit fcad23
# include <time.h>
Packit fcad23
#else
Packit fcad23
# if HAVE_SYS_TIME_H
Packit fcad23
#  include <sys/time.h>
Packit fcad23
# else
Packit fcad23
#  include <time.h>
Packit fcad23
# endif
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_SELECT_H
Packit fcad23
#include <sys/select.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_SOCKET_H
Packit fcad23
#include <sys/socket.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NET_IF_H
Packit fcad23
#include <net/if.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_INET_MIB2_H
Packit fcad23
#include <inet/mib2.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_IOCTL_H
Packit fcad23
#include <sys/ioctl.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_FILE_H
Packit fcad23
#include <sys/file.h>
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_FCNTL_H
Packit fcad23
#include <fcntl.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_WAIT_H
Packit fcad23
#include <sys/wait.h>
Packit fcad23
#endif
Packit fcad23
#include <signal.h>
Packit fcad23
#ifdef HAVE_SYS_PARAM_H
Packit fcad23
#include <sys/param.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_PROCESS_H              /* Win32-getpid */
Packit fcad23
#include <process.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_LIMITS_H
Packit fcad23
#include <limits.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_PWD_H
Packit fcad23
#include <pwd.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_GRP_H
Packit fcad23
#include <grp.h>
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_CRTDBG_H
Packit fcad23
#include <crtdbg.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef PATH_MAX
Packit fcad23
# ifdef _POSIX_PATH_MAX
Packit fcad23
#  define PATH_MAX _POSIX_PATH_MAX
Packit fcad23
# else
Packit fcad23
#  define PATH_MAX 255
Packit fcad23
# endif
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit fcad23
#include "agent_global_vars.h"
Packit fcad23
Packit fcad23
#include <net-snmp/library/fd_event_manager.h>
Packit fcad23
#include <net-snmp/library/large_fd_set.h>
Packit fcad23
Packit fcad23
#include "m2m.h"
Packit fcad23
#include <net-snmp/agent/agent_module_config.h>
Packit fcad23
#include <net-snmp/agent/mib_module_config.h>
Packit fcad23
Packit fcad23
#include "snmpd.h"
Packit fcad23
Packit fcad23
#include <net-snmp/agent/mib_modules.h>
Packit fcad23
Packit fcad23
#include <net-snmp/agent/agent_trap.h>
Packit fcad23
Packit fcad23
#include <net-snmp/agent/netsnmp_close_fds.h>
Packit fcad23
#include <net-snmp/agent/table.h>
Packit fcad23
#include <net-snmp/agent/table_iterator.h>
Packit fcad23
Packit fcad23
#include "mibgroup/util_funcs/restart.h"
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Include winservice.h to support Windows Service
Packit fcad23
 */
Packit fcad23
#ifdef WIN32
Packit fcad23
#include <windows.h>
Packit fcad23
#include <tchar.h>
Packit fcad23
#include <net-snmp/library/winservice.h>
Packit fcad23
Packit fcad23
#define WIN32SERVICE
Packit fcad23
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef NETSNMP_NO_SYSTEMD
Packit fcad23
#include <net-snmp/library/sd-daemon.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
netsnmp_feature_want(logging_file)
Packit fcad23
netsnmp_feature_want(logging_stdio)
Packit fcad23
netsnmp_feature_want(logging_syslog)
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Globals.
Packit fcad23
 */
Packit fcad23
#ifdef NETSNMP_USE_LIBWRAP
Packit fcad23
#include <tcpd.h>
Packit fcad23
#endif                          /* NETSNMP_USE_LIBWRAP */
Packit fcad23
Packit fcad23
#define TIMETICK         500000L
Packit fcad23
Packit fcad23
int             snmp_dump_packet;
Packit fcad23
static int      reconfig = 0;
Packit fcad23
int             Facility = LOG_DAEMON;
Packit fcad23
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
/*
Packit fcad23
 * SNMP Agent Status 
Packit fcad23
 */
Packit fcad23
#define AGENT_RUNNING 1
Packit fcad23
#define AGENT_STOPPED 0
Packit fcad23
int             agent_status = AGENT_STOPPED;
Packit fcad23
/* app_name_long used for Event Log (syslog), SCM, registry etc */
Packit fcad23
LPCTSTR         app_name_long = _T("Net-SNMP Agent");     /* Application Name */
Packit fcad23
#endif
Packit fcad23
Packit fcad23
const char     *app_name = "snmpd";
Packit fcad23
Packit fcad23
#ifdef USING_SMUX_MODULE
Packit fcad23
#include <mibgroup/smux/smux.h>
Packit fcad23
#endif /* USING_SMUX_MODULE */
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Prototypes.
Packit fcad23
 */
Packit fcad23
static void     usage(char *);
Packit fcad23
static void     SnmpTrapNodeDown(void);
Packit fcad23
static int      receive(void);
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
static void     StopSnmpAgent(void);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * These definitions handle 4.2 systems without additional syslog facilities.
Packit fcad23
 */
Packit fcad23
#ifndef LOG_CONS
Packit fcad23
#define LOG_CONS	0       /* Don't bother if not defined... */
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_PID
Packit fcad23
#define LOG_PID		0       /* Don't bother if not defined... */
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL0
Packit fcad23
#define LOG_LOCAL0	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL1
Packit fcad23
#define LOG_LOCAL1	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL2
Packit fcad23
#define LOG_LOCAL2	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL3
Packit fcad23
#define LOG_LOCAL3	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL4
Packit fcad23
#define LOG_LOCAL4	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL5
Packit fcad23
#define LOG_LOCAL5	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL6
Packit fcad23
#define LOG_LOCAL6	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_LOCAL7
Packit fcad23
#define LOG_LOCAL7	0
Packit fcad23
#endif
Packit fcad23
#ifndef LOG_DAEMON
Packit fcad23
#define LOG_DAEMON	0
Packit fcad23
#endif
Packit fcad23
Packit fcad23
Packit fcad23
static void
Packit fcad23
usage(char *prog)
Packit fcad23
{
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
    printf("\nUsage:  %s [-register] [-quiet] [OPTIONS] [LISTENING ADDRESSES]"
Packit fcad23
           "\n        %s [-unregister] [-quiet]", prog, prog);
Packit fcad23
#else
Packit fcad23
    printf("\nUsage:  %s [OPTIONS] [LISTENING ADDRESSES]", prog);
Packit fcad23
#endif
Packit fcad23
    printf("\n"
Packit fcad23
           "\n\tVersion:  %s\n%s"
Packit fcad23
           "\t\t\t  (config search path: %s)\n%s%s",
Packit fcad23
           netsnmp_get_version(),
Packit fcad23
           "\tWeb:      http://www.net-snmp.org/\n"
Packit fcad23
           "\tEmail:    net-snmp-coders@lists.sourceforge.net\n"
Packit fcad23
           "\n  -a\t\t\tlog addresses\n"
Packit fcad23
           "  -A\t\t\tappend to the logfile rather than truncating it\n"
Packit fcad23
           "  -c FILE[,...]\t\tread FILE(s) as configuration file(s)\n"
Packit fcad23
           "  -C\t\t\tdo not read the default configuration files\n",
Packit fcad23
           get_configuration_directory(),
Packit fcad23
           "  -d\t\t\tdump sent and received SNMP packets\n"
Packit fcad23
#ifndef NETSNMP_DISABLE_DEBUGGING
Packit fcad23
           "  -D[TOKEN[,...]]\tturn on debugging output for the given TOKEN(s)\n"
Packit fcad23
	   "\t\t\t  (try ALL for extremely verbose output)\n"
Packit fcad23
	   "\t\t\t  Don't put space(s) between -D and TOKEN(s).\n"
Packit fcad23
#endif
Packit fcad23
           "  -f\t\t\tdo not fork from the shell\n",
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
           "  -g GID\t\tchange to this numeric gid after opening\n"
Packit fcad23
	   "\t\t\t  transport endpoints\n"
Packit fcad23
#endif
Packit fcad23
           "  -h, --help\t\tdisplay this usage message\n"
Packit fcad23
           "  -H\t\t\tdisplay configuration file directives understood\n"
Packit fcad23
           "  -I [-]INITLIST\tlist of mib modules to initialize (or not)\n"
Packit fcad23
           "\t\t\t  (run snmpd with -Dmib_init for a list)\n"
Packit fcad23
           "  -L <LOGOPTS>\t\ttoggle options controlling where to log to\n");
Packit fcad23
    snmp_log_options_usage("\t", stdout);
Packit fcad23
    printf("  -m MIBLIST\t\tuse MIBLIST instead of the default MIB list\n"
Packit fcad23
           "  -M DIRLIST\t\tuse DIRLIST as the list of locations to look for MIBs\n"
Packit fcad23
           "\t\t\t  (default %s)\n%s%s",
Packit fcad23
#ifndef NETSNMP_DISABLE_MIB_LOADING
Packit fcad23
           netsnmp_get_mib_directory(),
Packit fcad23
#else
Packit fcad23
           "MIBs not loaded",
Packit fcad23
#endif
Packit fcad23
           "  -p FILE\t\tstore process id in FILE\n"
Packit fcad23
           "  -q\t\t\tprint information in a more parsable format\n"
Packit fcad23
           "  -r\t\t\tdo not exit if files only accessible to root\n"
Packit fcad23
	   "\t\t\t  cannot be opened\n"
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
           "  -register\t\tregister as a Windows service\n"
Packit fcad23
           "  \t\t\t  (followed by -quiet to prevent message popups)\n"
Packit fcad23
           "  \t\t\t  (followed by the startup parameter list)\n"
Packit fcad23
           "  \t\t\t  Note that some parameters are not relevant when running as a service\n"
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
           "  -u UID\t\tchange to this uid (numeric or textual) after\n"
Packit fcad23
	   "\t\t\t  opening transport endpoints\n"
Packit fcad23
#endif
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
           "  -unregister\t\tunregister as a Windows service\n"
Packit fcad23
           "  \t\t\t  (followed -quiet to prevent message popups)\n"
Packit fcad23
#endif
Packit fcad23
           "  -v, --version\t\tdisplay version information\n"
Packit fcad23
           "  -V\t\t\tverbose display\n"
Packit fcad23
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
Packit fcad23
           "  -x ADDRESS\t\tuse ADDRESS as AgentX address\n"
Packit fcad23
#endif
Packit fcad23
#ifdef USING_AGENTX_SUBAGENT_MODULE
Packit fcad23
           "  -X\t\t\trun as an AgentX subagent rather than as an\n"
Packit fcad23
	   "\t\t\t  SNMP master agent\n"
Packit fcad23
#endif
Packit fcad23
           ,
Packit fcad23
           "\nDeprecated options:\n"
Packit fcad23
           "  -l FILE\t\tuse -Lf <FILE> instead\n"
Packit fcad23
           "  -P\t\t\tuse -p instead\n"
Packit fcad23
           "  -s\t\t\tuse -Lsd instead\n"
Packit fcad23
           "  -S d|i|0-7\t\tuse -Ls <facility> instead\n"
Packit fcad23
           "\n"
Packit fcad23
           );
Packit Service c95a82
           exit(1);
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
version(void)
Packit fcad23
{
Packit fcad23
    printf("\nNET-SNMP version:  %s\n"
Packit fcad23
           "Web:               http://www.net-snmp.org/\n"
Packit fcad23
           "Email:             net-snmp-coders@lists.sourceforge.net\n\n",
Packit fcad23
           netsnmp_get_version());
Packit fcad23
}
Packit fcad23
Packit fcad23
RETSIGTYPE
Packit fcad23
SnmpdShutDown(int a)
Packit fcad23
{
Packit fcad23
    netsnmp_running = 0;
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
    /*
Packit fcad23
     * In case of windows, select() in receive() function will not return 
Packit fcad23
     * on signal. Thats why following function is called, which closes the 
Packit fcad23
     * socket descriptors and causes the select() to return
Packit fcad23
     */
Packit fcad23
    snmp_close(main_session);
Packit fcad23
#endif
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifdef SIGHUP
Packit fcad23
RETSIGTYPE
Packit fcad23
SnmpdReconfig(int a)
Packit fcad23
{
Packit fcad23
    reconfig = 1;
Packit fcad23
    signal(SIGHUP, SnmpdReconfig);
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef SIGUSR1
Packit fcad23
RETSIGTYPE
Packit fcad23
SnmpdDump(int a)
Packit fcad23
{
Packit fcad23
    dump_registry();
Packit fcad23
    signal(SIGUSR1, SnmpdDump);
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
RETSIGTYPE
Packit fcad23
SnmpdCatchRandomSignal(int a)
Packit fcad23
{
Packit fcad23
    /* Disable all logs and log the error via syslog */
Packit fcad23
    snmp_disable_log();
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
Packit fcad23
    snmp_enable_syslog();
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
Packit fcad23
    snmp_log(LOG_ERR, "Exiting on signal %d\n", a);
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
Packit fcad23
    snmp_disable_syslog();
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
Packit fcad23
    exit(1);
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
SnmpTrapNodeDown(void)
Packit fcad23
{
Packit fcad23
    send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 2);
Packit fcad23
    /*
Packit fcad23
     * XXX  2 - Node Down #define it as NODE_DOWN_TRAP 
Packit fcad23
     */
Packit fcad23
}
Packit fcad23
Packit fcad23
/*******************************************************************-o-******
Packit fcad23
 * main - Non Windows
Packit fcad23
 * SnmpDaemonMain - Windows to support windows service
Packit fcad23
 *
Packit fcad23
 * Parameters:
Packit fcad23
 *	 argc
Packit fcad23
 *	*argv[]
Packit fcad23
 *      
Packit fcad23
 * Returns:
Packit fcad23
 *	0	Always succeeds.  (?)
Packit fcad23
 *
Packit fcad23
 *
Packit fcad23
 * Setup and start the agent daemon.
Packit fcad23
 *
Packit fcad23
 * Also successfully EXITs with zero for some options.
Packit fcad23
 */
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
static int
Packit fcad23
SnmpDaemonMain(int argc, TCHAR * argv[])
Packit fcad23
#else
Packit fcad23
int
Packit fcad23
main(int argc, char *argv[])
Packit fcad23
#endif
Packit fcad23
{
Packit fcad23
    static const char options[] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:"
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
        "g:u:"
Packit fcad23
#endif
Packit fcad23
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
Packit fcad23
        "x:"
Packit fcad23
#endif
Packit fcad23
#ifdef USING_AGENTX_SUBAGENT_MODULE
Packit fcad23
        "X"
Packit fcad23
#endif
Packit fcad23
        ;
Packit fcad23
    int             arg, i, ret, exit_code = 1;
Packit fcad23
    int             dont_fork = 0, do_help = 0;
Packit fcad23
    int             log_set = 0;
Packit fcad23
    int             agent_mode = -1;
Packit fcad23
    char           *pid_file = NULL;
Packit fcad23
    char            option_compatability[] = "-Le";
Packit fcad23
#ifndef WIN32
Packit fcad23
    int             prepared_sockets = 0;
Packit fcad23
#endif
Packit fcad23
#if HAVE_GETPID
Packit fcad23
    int fd;
Packit fcad23
    FILE           *PID;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    SOCK_STARTUP;
Packit fcad23
Packit fcad23
#ifndef NETSNMP_NO_SYSTEMD
Packit fcad23
    /* check if systemd has sockets for us and don't close them */
Packit fcad23
    prepared_sockets = netsnmp_sd_listen_fds(0);
Packit fcad23
#endif /* NETSNMP_NO_SYSTEMD */
Packit fcad23
#ifndef WIN32
Packit fcad23
    /*
Packit fcad23
     * close all non-standard file descriptors we may have
Packit fcad23
     * inherited from the shell.
Packit fcad23
     */
Packit fcad23
    if (!prepared_sockets)
Packit fcad23
        netsnmp_close_fds(2);
Packit fcad23
#endif
Packit fcad23
    
Packit fcad23
    /*
Packit fcad23
     * register signals ASAP to prevent default action (usually core)
Packit fcad23
     * for signals during startup...
Packit fcad23
     */
Packit fcad23
#ifdef SIGTERM
Packit fcad23
    DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n"));
Packit fcad23
    signal(SIGTERM, SnmpdShutDown);
Packit fcad23
#endif
Packit fcad23
#ifdef SIGINT
Packit fcad23
    DEBUGMSGTL(("signal", "registering SIGINT signal handler\n"));
Packit fcad23
    signal(SIGINT, SnmpdShutDown);
Packit fcad23
#endif
Packit fcad23
#ifdef SIGHUP
Packit fcad23
    signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
Packit fcad23
#endif
Packit fcad23
#ifdef SIGUSR1
Packit fcad23
    DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n"));
Packit fcad23
    signal(SIGUSR1, SnmpdDump);
Packit fcad23
#endif
Packit fcad23
#ifdef SIGPIPE
Packit fcad23
    DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n"));
Packit fcad23
    signal(SIGPIPE, SIG_IGN);   /* 'Inline' failure of wayward readers */
Packit fcad23
#endif
Packit fcad23
#ifdef SIGXFSZ
Packit fcad23
    signal(SIGXFSZ, SnmpdCatchRandomSignal);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef NETSNMP_NO_ROOT_ACCESS
Packit fcad23
    /*
Packit fcad23
     * Default to no.  
Packit fcad23
     */
Packit fcad23
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
			   NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
Packit fcad23
#endif
Packit fcad23
    /*
Packit fcad23
     * Default to NOT running an AgentX master.  
Packit fcad23
     */
Packit fcad23
    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
			   NETSNMP_DS_AGENT_AGENTX_MASTER, 0);
Packit fcad23
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1);
Packit fcad23
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
                       NETSNMP_DS_AGENT_AGENTX_RETRIES, -1);
Packit fcad23
Packit fcad23
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
                       NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * This is incredibly ugly, but it's probably the simplest way
Packit fcad23
     *  to handle the old '-L' option as well as the new '-Lx' style
Packit fcad23
     */
Packit fcad23
    for (i=0; i
Packit fcad23
        if (!strcmp(argv[i], "-L"))
Packit fcad23
            argv[i] = option_compatability;            
Packit fcad23
    }
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
Packit fcad23
#ifdef WIN32
Packit fcad23
    snmp_log_syslogname(app_name_long);
Packit fcad23
#else
Packit fcad23
    snmp_log_syslogname(app_name);
Packit fcad23
#endif
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
Packit fcad23
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                          NETSNMP_DS_LIB_APPTYPE, app_name);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Now process options normally.  
Packit fcad23
     */
Packit fcad23
    while ((arg = getopt(argc, argv, options)) != EOF) {
Packit fcad23
        switch (arg) {
Packit fcad23
        case '-':
Packit fcad23
            if (strcasecmp(optarg, "help") == 0) {
Packit fcad23
                usage(argv[0]);
Packit fcad23
                goto out;
Packit fcad23
            }
Packit fcad23
            if (strcasecmp(optarg, "version") == 0) {
Packit fcad23
                version();
Packit fcad23
                exit_code = 0;
Packit fcad23
                goto out;
Packit fcad23
            }
Packit fcad23
Packit fcad23
            handle_long_opt(optarg);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'a':
Packit fcad23
            log_addresses++;
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'A':
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                   NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'c':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 
Packit fcad23
				      NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'C':
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
Packit fcad23
				   NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'd':
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                   NETSNMP_DS_LIB_DUMP_PACKET,
Packit fcad23
                                   ++snmp_dump_packet);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'D':
Packit fcad23
#ifdef NETSNMP_DISABLE_DEBUGGING
Packit fcad23
            fprintf(stderr, "Debugging not configured\n");
Packit fcad23
            goto out;
Packit fcad23
#else
Packit fcad23
            debug_register_tokens(optarg);
Packit fcad23
            snmp_set_do_debugging(1);
Packit fcad23
#endif
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'f':
Packit fcad23
            dont_fork = 1;
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
        case 'g':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                char           *ecp;
Packit fcad23
                int             gid;
Packit fcad23
Packit fcad23
                gid = strtoul(optarg, &ecp, 10);
Packit fcad23
#if HAVE_GETGRNAM && HAVE_PWD_H
Packit fcad23
                if (*ecp) {
Packit fcad23
                    struct group  *info;
Packit fcad23
Packit fcad23
                    info = getgrnam(optarg);
Packit fcad23
                    gid = info ? info->gr_gid : -1;
Packit fcad23
                    endgrent();
Packit fcad23
                }
Packit fcad23
#endif
Packit fcad23
                if (gid < 0) {
Packit fcad23
                    fprintf(stderr, "Bad group id: %s\n", optarg);
Packit fcad23
                    goto out;
Packit fcad23
                }
Packit fcad23
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_GROUPID, gid);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        case 'h':
Packit fcad23
            usage(argv[0]);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'H':
Packit fcad23
            do_help = 1;
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'I':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                add_to_init_list(optarg);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE
Packit fcad23
        case 'l':
Packit fcad23
            printf("Warning: -l option is deprecated, use -Lf <file> instead\n");
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                if (strlen(optarg) > PATH_MAX) {
Packit fcad23
                    fprintf(stderr,
Packit fcad23
                            "%s: logfile path too long (limit %d chars)\n",
Packit fcad23
                            argv[0], PATH_MAX);
Packit fcad23
                    goto out;
Packit fcad23
                }
Packit fcad23
                snmp_enable_filelog(optarg,
Packit fcad23
                                    netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                                           NETSNMP_DS_LIB_APPEND_LOGFILES));
Packit fcad23
                log_set = 1;
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */
Packit fcad23
Packit fcad23
        case 'L':
Packit fcad23
	    if  (snmp_log_options( optarg, argc, argv ) < 0 ) {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            log_set = 1;
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'm':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                setenv("MIBS", optarg, 1);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'M':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                setenv("MIBDIRS", optarg, 1);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'n':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                app_name = optarg;
Packit fcad23
                netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                      NETSNMP_DS_LIB_APPTYPE, app_name);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'P':
Packit fcad23
            printf("Warning: -P option is deprecated, use -p instead\n");
Packit fcad23
	    /* FALL THROUGH */
Packit fcad23
        case 'p':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                pid_file = optarg;
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'q':
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
Packit fcad23
                                   NETSNMP_DS_LIB_QUICK_PRINT, 1);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'r':
Packit fcad23
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				      NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
Packit fcad23
        case 's':
Packit fcad23
            printf("Warning: -s option is deprecated, use -Lsd instead\n");
Packit fcad23
            snmp_enable_syslog();
Packit fcad23
            log_set = 1;
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'S':
Packit fcad23
            printf("Warning: -S option is deprecated, use -Ls <facility> instead\n");
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                switch (*optarg) {
Packit fcad23
                case 'd':
Packit fcad23
                case 'D':
Packit fcad23
                    Facility = LOG_DAEMON;
Packit fcad23
                    break;
Packit fcad23
                case 'i':
Packit fcad23
                case 'I':
Packit fcad23
                    Facility = LOG_INFO;
Packit fcad23
                    break;
Packit fcad23
                case '0':
Packit fcad23
                    Facility = LOG_LOCAL0;
Packit fcad23
                    break;
Packit fcad23
                case '1':
Packit fcad23
                    Facility = LOG_LOCAL1;
Packit fcad23
                    break;
Packit fcad23
                case '2':
Packit fcad23
                    Facility = LOG_LOCAL2;
Packit fcad23
                    break;
Packit fcad23
                case '3':
Packit fcad23
                    Facility = LOG_LOCAL3;
Packit fcad23
                    break;
Packit fcad23
                case '4':
Packit fcad23
                    Facility = LOG_LOCAL4;
Packit fcad23
                    break;
Packit fcad23
                case '5':
Packit fcad23
                    Facility = LOG_LOCAL5;
Packit fcad23
                    break;
Packit fcad23
                case '6':
Packit fcad23
                    Facility = LOG_LOCAL6;
Packit fcad23
                    break;
Packit fcad23
                case '7':
Packit fcad23
                    Facility = LOG_LOCAL7;
Packit fcad23
                    break;
Packit fcad23
                default:
Packit fcad23
                    fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg);
Packit fcad23
                    usage(argv[0]);
Packit fcad23
                }
Packit fcad23
                snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility);
Packit fcad23
                log_set = 1;
Packit fcad23
            } else {
Packit fcad23
                fprintf(stderr, "no syslog facility specified\n");
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
Packit fcad23
Packit fcad23
        case 'U':
Packit fcad23
            netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				      NETSNMP_DS_AGENT_LEAVE_PIDFILE);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
        case 'u':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                char           *ecp;
Packit fcad23
                int             uid;
Packit fcad23
Packit fcad23
                uid = strtoul(optarg, &ecp, 10);
Packit fcad23
#if HAVE_GETPWNAM && HAVE_PWD_H
Packit fcad23
                if (*ecp) {
Packit fcad23
                    struct passwd  *info;
Packit fcad23
Packit fcad23
                    info = getpwnam(optarg);
Packit fcad23
                    uid = info ? info->pw_uid : -1;
Packit fcad23
                    endpwent();
Packit fcad23
                }
Packit fcad23
#endif
Packit fcad23
                if (uid < 0) {
Packit fcad23
                    fprintf(stderr, "Bad user id: %s\n", optarg);
Packit fcad23
                    goto out;
Packit fcad23
                }
Packit fcad23
                netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_USERID, uid);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        case 'v':
Packit fcad23
            version();
Packit fcad23
            exit_code = 0;
Packit fcad23
            goto out;
Packit fcad23
Packit fcad23
        case 'V':
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_VERBOSE, 1);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE)
Packit fcad23
        case 'x':
Packit fcad23
            if (optarg != NULL) {
Packit fcad23
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				      NETSNMP_DS_AGENT_X_SOCKET, optarg);
Packit fcad23
            } else {
Packit fcad23
                usage(argv[0]);
Packit fcad23
            }
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_AGENTX_MASTER, 1);
Packit fcad23
            break;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        case 'X':
Packit fcad23
#if defined(USING_AGENTX_SUBAGENT_MODULE)
Packit fcad23
            agent_mode = SUB_AGENT;
Packit fcad23
#else
Packit fcad23
            fprintf(stderr, "%s: Illegal argument -X:"
Packit fcad23
		            "AgentX support not compiled in.\n", argv[0]);
Packit fcad23
            usage(argv[0]);
Packit fcad23
            goto out;
Packit fcad23
#endif
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case 'Y':
Packit fcad23
            netsnmp_config_remember(optarg);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        default:
Packit fcad23
            usage(argv[0]);
Packit fcad23
            break;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (do_help) {
Packit fcad23
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
                               NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
Packit fcad23
        init_agent(app_name);        /* register our .conf handlers */
Packit fcad23
        init_mib_modules();
Packit fcad23
        init_snmp(app_name);
Packit fcad23
        fprintf(stderr, "Configuration directives understood:\n");
Packit fcad23
        read_config_print_usage("  ");
Packit fcad23
        exit_code = 0;
Packit fcad23
        goto out;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (optind < argc) {
Packit fcad23
#ifndef NETSNMP_NO_LISTEN_SUPPORT
Packit fcad23
        /*
Packit fcad23
         * There are optional transport addresses on the command line.  
Packit fcad23
         */
Packit fcad23
        DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc));
Packit fcad23
        for (i = optind; i < argc; i++) {
Packit fcad23
            char *c, *astring;
Packit fcad23
            if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					   NETSNMP_DS_AGENT_PORTS))) {
Packit fcad23
                astring = (char*)malloc(strlen(c) + 2 + strlen(argv[i]));
Packit fcad23
                if (astring == NULL) {
Packit fcad23
                    fprintf(stderr, "malloc failure processing argv[%d]\n", i);
Packit fcad23
                    goto out;
Packit fcad23
                }
Packit fcad23
                sprintf(astring, "%s,%s", c, argv[i]);
Packit fcad23
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				      NETSNMP_DS_AGENT_PORTS, astring);
Packit fcad23
                SNMP_FREE(astring);
Packit fcad23
            } else {
Packit fcad23
                netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				      NETSNMP_DS_AGENT_PORTS, argv[i]);
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
Packit fcad23
                    netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					  NETSNMP_DS_AGENT_PORTS)));
Packit fcad23
#else /* NETSNMP_NO_LISTEN_SUPPORT */
Packit fcad23
        fprintf(stderr, "You specified ports to open; this agent was built to only send notifications\n");
Packit fcad23
        goto out;
Packit fcad23
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
Packit fcad23
    }
Packit fcad23
Packit fcad23
#if defined(NETSNMP_DAEMONS_DEFAULT_LOG_SYSLOG)
Packit fcad23
    if (0 == log_set)
Packit fcad23
        snmp_enable_syslog();
Packit fcad23
#else
Packit fcad23
#ifdef NETSNMP_LOGFILE
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE
Packit fcad23
    if (0 == log_set)
Packit fcad23
        snmp_enable_filelog(NETSNMP_LOGFILE,
Packit fcad23
                            netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                                   NETSNMP_DS_LIB_APPEND_LOGFILES));
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */
Packit fcad23
#endif /* NETSNMP_LOGFILE */
Packit fcad23
#endif /* ! NETSNMP_DEFAULT_LOG_SYSLOG */
Packit fcad23
Packit fcad23
#ifdef USING_UTIL_FUNCS_RESTART_MODULE
Packit fcad23
    {
Packit fcad23
        /*
Packit fcad23
         * Initialize a argv set to the current for restarting the agent.
Packit fcad23
         */
Packit fcad23
        char *cptr, **argvptr;
Packit fcad23
Packit fcad23
        argvrestartp = (char **)malloc((argc + 2) * sizeof(char *));
Packit fcad23
        argvptr = argvrestartp;
Packit fcad23
        for (i = 0, ret = 1; i < argc; i++) {
Packit fcad23
            ret += strlen(argv[i]) + 1;
Packit fcad23
        }
Packit fcad23
        argvrestart = (char *) malloc(ret);
Packit fcad23
        argvrestartname = (char *) malloc(strlen(argv[0]) + 1);
Packit fcad23
        if (!argvrestartp || !argvrestart || !argvrestartname) {
Packit fcad23
            fprintf(stderr, "malloc failure processing argvrestart\n");
Packit fcad23
            goto out;
Packit fcad23
        }
Packit fcad23
        strcpy(argvrestartname, argv[0]);
Packit fcad23
Packit fcad23
        for (cptr = argvrestart, i = 0; i < argc; i++) {
Packit fcad23
            strcpy(cptr, argv[i]);
Packit fcad23
            *(argvptr++) = cptr;
Packit fcad23
            cptr += strlen(argv[i]) + 1;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#endif /* USING_UTIL_FUNCS_RESTART_MODULE */
Packit fcad23
Packit fcad23
    if (agent_mode == -1) {
Packit fcad23
        if (strstr(argv[0], "agentxd") != NULL) {
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
				   NETSNMP_DS_AGENT_ROLE, SUB_AGENT);
Packit fcad23
        } else {
Packit fcad23
            netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
				   NETSNMP_DS_AGENT_ROLE, MASTER_AGENT);
Packit fcad23
        }
Packit fcad23
    } else {
Packit fcad23
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
			       NETSNMP_DS_AGENT_ROLE, agent_mode);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (init_agent(app_name) != 0) {
Packit fcad23
        snmp_log(LOG_ERR, "Agent initialization failed\n");
Packit fcad23
        goto out;
Packit fcad23
    }
Packit fcad23
    init_mib_modules();
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * start library 
Packit fcad23
     */
Packit fcad23
    init_snmp(app_name);
Packit fcad23
Packit fcad23
    if ((ret = init_master_agent()) != 0) {
Packit fcad23
        /*
Packit fcad23
         * Some error opening one of the specified agent transports.  
Packit fcad23
         */
Packit fcad23
        snmp_log(LOG_ERR, "Server Exiting with code 1\n");
Packit fcad23
        goto out;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Initialize the world.  Detach from the shell.  Create initial user.  
Packit fcad23
     */
Packit fcad23
    if(!dont_fork) {
Packit fcad23
        int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
                                            NETSNMP_DS_AGENT_QUIT_IMMEDIATELY);
Packit fcad23
        ret = netsnmp_daemonize(quit,
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO
Packit fcad23
                                snmp_stderrlog_status()
Packit fcad23
#else /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
Packit fcad23
                                0
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
Packit fcad23
            );
Packit fcad23
        /*
Packit fcad23
         * xxx-rks: do we care if fork fails? I think we should...
Packit fcad23
         */
Packit fcad23
        if(ret != 0) {
Packit fcad23
            snmp_log(LOG_ERR, "Server Exiting with code 1\n");
Packit fcad23
            goto out;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
#if HAVE_GETPID
Packit fcad23
    if (pid_file != NULL) {
Packit fcad23
        /*
Packit fcad23
         * unlink the pid_file, if it exists, prior to open.  Without
Packit fcad23
         * doing this the open will fail if the user specified pid_file
Packit fcad23
         * already exists.
Packit fcad23
         */
Packit fcad23
        unlink(pid_file);
Packit fcad23
        fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
Packit fcad23
        if (fd == -1) {
Packit fcad23
            snmp_log_perror(pid_file);
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                goto out;
Packit fcad23
            }
Packit fcad23
        } else {
Packit fcad23
            if ((PID = fdopen(fd, "w")) == NULL) {
Packit fcad23
                snmp_log_perror(pid_file);
Packit fcad23
                goto out;
Packit fcad23
            } else {
Packit fcad23
                fprintf(PID, "%d\n", (int) getpid());
Packit fcad23
                fclose(PID);
Packit fcad23
            }
Packit fcad23
#ifndef _MSC_VER
Packit fcad23
            /* The sequence open()/fdopen()/fclose()/close() makes MSVC crash,
Packit fcad23
               hence skip the close() call when using the MSVC runtime. */
Packit fcad23
            close(fd);
Packit fcad23
#endif
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if defined(HAVE_UNISTD_H) && (defined(HAVE_CHOWN) || defined(HAVE_SETGID) || defined(HAVE_SETUID))
Packit fcad23
    {
Packit fcad23
    const char     *persistent_dir;
Packit fcad23
    int             uid, gid;
Packit fcad23
Packit fcad23
    persistent_dir = get_persistent_directory();
Packit fcad23
    mkdirhier( persistent_dir, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
Packit fcad23
   
Packit fcad23
    uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
			     NETSNMP_DS_AGENT_USERID);
Packit fcad23
    gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
			     NETSNMP_DS_AGENT_GROUPID);
Packit fcad23
    
Packit fcad23
#ifdef HAVE_CHOWN
Packit fcad23
    if ( uid != 0 || gid != 0 )
Packit fcad23
        chown( persistent_dir, uid, gid );
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef HAVE_SETGID
Packit fcad23
    if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				  NETSNMP_DS_AGENT_GROUPID)) > 0) {
Packit fcad23
        DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
Packit fcad23
        if (setgid(gid) == -1
Packit fcad23
#ifdef HAVE_SETGROUPS
Packit fcad23
            || setgroups(1, (gid_t *)&gid) == -1
Packit fcad23
#endif
Packit fcad23
            ) {
Packit fcad23
            snmp_log_perror("setgid failed");
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                goto out;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_SETUID
Packit fcad23
    if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				  NETSNMP_DS_AGENT_USERID)) > 0) {
Packit fcad23
#if HAVE_GETPWNAM && HAVE_PWD_H && HAVE_INITGROUPS
Packit fcad23
        struct passwd *info;
Packit fcad23
Packit fcad23
        /*
Packit fcad23
         * Set supplementary groups before changing UID
Packit fcad23
         *   (which probably involves giving up privileges)
Packit fcad23
         */
Packit fcad23
        info = getpwuid(uid);
Packit fcad23
        if (info) {
Packit fcad23
            DEBUGMSGTL(("snmpd/main", "Supplementary groups for %s.\n", info->pw_name));
Packit fcad23
            if (initgroups(info->pw_name, (gid != 0 ? (gid_t)gid : info->pw_gid)) == -1) {
Packit fcad23
                snmp_log_perror("initgroups failed");
Packit fcad23
                if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
                                            NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                    goto out;
Packit fcad23
                }
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        endpwent();
Packit fcad23
#endif
Packit fcad23
        DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
Packit fcad23
        if (setuid(uid) == -1) {
Packit fcad23
            snmp_log_perror("setuid failed");
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                goto out;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#endif
Packit fcad23
    }
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Store persistent data immediately in case we crash later.  
Packit fcad23
     */
Packit fcad23
    snmp_store(app_name);
Packit fcad23
Packit fcad23
#ifdef SIGHUP
Packit fcad23
    DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n"));
Packit fcad23
    signal(SIGHUP, SnmpdReconfig);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Send coldstart trap if possible.  
Packit fcad23
     */
Packit fcad23
    send_easy_trap(0, 0);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * We're up, log our version number.  
Packit fcad23
     */
Packit fcad23
    snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
    agent_status = AGENT_RUNNING;
Packit fcad23
#endif
Packit fcad23
    netsnmp_addrcache_initialise();
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Let systemd know we're up.
Packit fcad23
     */
Packit fcad23
#ifndef NETSNMP_NO_SYSTEMD
Packit fcad23
    netsnmp_sd_notify(1, "READY=1\n");
Packit fcad23
    if (prepared_sockets)
Packit fcad23
        /*
Packit fcad23
         * Clear the environment variable, we already processed all the sockets
Packit fcad23
         * by now.
Packit fcad23
         */
Packit fcad23
        netsnmp_sd_listen_fds(1);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Forever monitor the dest_port for incoming PDUs.  
Packit fcad23
     */
Packit fcad23
    DEBUGMSGTL(("snmpd/main", "We're up.  Starting to process data.\n"));
Packit fcad23
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				NETSNMP_DS_AGENT_QUIT_IMMEDIATELY))
Packit fcad23
        receive();
Packit fcad23
    DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n"));
Packit fcad23
    SnmpTrapNodeDown();
Packit fcad23
    DEBUGMSGTL(("snmpd/main", "Bye...\n"));
Packit fcad23
    snmp_shutdown(app_name);
Packit fcad23
    shutdown_master_agent();
Packit fcad23
    shutdown_agent();
Packit fcad23
Packit fcad23
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				NETSNMP_DS_AGENT_LEAVE_PIDFILE) &&
Packit fcad23
	(pid_file != NULL)) {
Packit fcad23
        unlink(pid_file);
Packit fcad23
    }
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
    agent_status = AGENT_STOPPED;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef USING_UTIL_FUNCS_RESTART_MODULE
Packit fcad23
    SNMP_FREE(argvrestartname);
Packit fcad23
    SNMP_FREE(argvrestart);
Packit fcad23
    SNMP_FREE(argvrestartp);
Packit fcad23
#endif /* USING_UTIL_FUNCS_RESTART_MODULE */
Packit fcad23
Packit fcad23
    exit_code = 0;
Packit fcad23
Packit fcad23
out:
Packit fcad23
    SOCK_CLEANUP;
Packit fcad23
    return exit_code;
Packit fcad23
}                               /* End main() -- snmpd */
Packit fcad23
Packit fcad23
#if defined(WIN32)
Packit fcad23
Packit fcad23
#include <process.h>
Packit fcad23
#include <net-snmp/library/snmp_assert.h>
Packit fcad23
Packit fcad23
static unsigned s_threadid;
Packit fcad23
HANDLE s_thread_handle;
Packit fcad23
Packit fcad23
static unsigned __stdcall wait_for_stdin(void* arg)
Packit fcad23
{
Packit fcad23
    if (getc(stdin) != EOF)
Packit fcad23
        netsnmp_running = 0;
Packit fcad23
    return 0;
Packit fcad23
}
Packit fcad23
Packit fcad23
static void create_stdin_waiter_thread(void)
Packit fcad23
{
Packit fcad23
    netsnmp_assert(s_thread_handle == 0);
Packit fcad23
    s_thread_handle = (HANDLE)_beginthreadex(0, 0, wait_for_stdin, 0, 0, &s_threadid);
Packit fcad23
    netsnmp_assert(s_thread_handle != 0);
Packit fcad23
}
Packit fcad23
Packit fcad23
static void join_stdin_waiter_thread(void)
Packit fcad23
{
Packit fcad23
    int result;
Packit fcad23
Packit fcad23
    netsnmp_assert(s_thread_handle != 0);
Packit fcad23
    result = WaitForSingleObject(s_thread_handle, 1000);
Packit fcad23
    netsnmp_assert(result != WAIT_TIMEOUT);
Packit fcad23
    CloseHandle(s_thread_handle);
Packit fcad23
    s_thread_handle = 0;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
/*******************************************************************-o-******
Packit fcad23
 * receive
Packit fcad23
 *
Packit fcad23
 * Parameters:
Packit fcad23
 *      
Packit fcad23
 * Returns:
Packit fcad23
 *	0	On success.
Packit fcad23
 *	-1	System error.
Packit fcad23
 *
Packit fcad23
 * Infinite while-loop which monitors incoming messages for the agent.
Packit fcad23
 * Invoke the established message handlers for incoming messages on a per
Packit fcad23
 * port basis.  Handle timeouts.
Packit fcad23
 */
Packit fcad23
static int
Packit fcad23
receive(void)
Packit fcad23
{
Packit fcad23
    int             numfds;
Packit fcad23
    netsnmp_large_fd_set readfds, writefds, exceptfds;
Packit fcad23
    struct timeval  timeout, *tvp = &timeout;
Packit fcad23
    int             count, block, i;
Packit fcad23
#ifdef	USING_SMUX_MODULE
Packit fcad23
    int             sd;
Packit fcad23
#endif                          /* USING_SMUX_MODULE */
Packit fcad23
Packit fcad23
    netsnmp_large_fd_set_init(&readfds, FD_SETSIZE);
Packit fcad23
    netsnmp_large_fd_set_init(&writefds, FD_SETSIZE);
Packit fcad23
    netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * ignore early sighup during startup
Packit fcad23
     */
Packit fcad23
    reconfig = 0;
Packit fcad23
Packit fcad23
#if defined(WIN32)
Packit fcad23
    create_stdin_waiter_thread();
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Loop-forever: execute message handlers for sockets with data
Packit fcad23
     */
Packit fcad23
    while (netsnmp_running) {
Packit fcad23
        if (reconfig) {
Packit fcad23
#if HAVE_SIGHOLD
Packit fcad23
            sighold(SIGHUP);
Packit fcad23
#endif
Packit fcad23
            reconfig = 0;
Packit fcad23
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
Packit fcad23
	    /*  Stop and restart logging.  This allows logfiles to be
Packit fcad23
		rotated etc.  */
Packit fcad23
	    netsnmp_logging_restart();
Packit fcad23
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
Packit fcad23
		     netsnmp_get_version());
Packit fcad23
            update_config();
Packit fcad23
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
Packit fcad23
#if HAVE_SIGHOLD
Packit fcad23
            sigrelse(SIGHUP);
Packit fcad23
#endif
Packit fcad23
        }
Packit fcad23
Packit fcad23
        /*
Packit fcad23
         * default to sleeping for a really long time. INT_MAX
Packit fcad23
         * should be sufficient (eg we don't care if time_t is
Packit fcad23
         * a long that's bigger than an int).
Packit fcad23
         */
Packit fcad23
        tvp = &timeout;
Packit fcad23
        tvp->tv_sec = INT_MAX;
Packit fcad23
        tvp->tv_usec = 0;
Packit fcad23
Packit fcad23
        numfds = 0;
Packit fcad23
        NETSNMP_LARGE_FD_ZERO(&readfds);
Packit fcad23
        NETSNMP_LARGE_FD_ZERO(&writefds);
Packit fcad23
        NETSNMP_LARGE_FD_ZERO(&exceptfds);
Packit fcad23
        block = 0;
Packit fcad23
        snmp_select_info2(&numfds, &readfds, tvp, &block);
Packit fcad23
        if (block == 1) {
Packit fcad23
            tvp = NULL;         /* block without timeout */
Packit fcad23
	}
Packit fcad23
Packit fcad23
#ifdef	USING_SMUX_MODULE
Packit fcad23
        if (smux_listen_sd >= 0) {
Packit fcad23
            NETSNMP_LARGE_FD_SET(smux_listen_sd, &readfds);
Packit fcad23
            numfds =
Packit fcad23
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
Packit fcad23
Packit fcad23
            for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
Packit fcad23
                sd = smux_snmp_select_list_get_SD_from_List(i);
Packit fcad23
                if (sd != 0)
Packit fcad23
                {
Packit fcad23
                   NETSNMP_LARGE_FD_SET(sd, &readfds);
Packit fcad23
                   numfds = sd >= numfds ? sd + 1 : numfds;
Packit fcad23
                }
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
#endif                          /* USING_SMUX_MODULE */
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
Packit fcad23
        netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds);
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
Packit fcad23
Packit fcad23
    reselect:
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_REGISTER_SIGNAL
Packit fcad23
        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
Packit fcad23
            if (external_signal_scheduled[i]) {
Packit fcad23
                external_signal_scheduled[i]--;
Packit fcad23
                external_signal_handler[i](i);
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_REGISTER_SIGNAL */
Packit fcad23
Packit fcad23
        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
Packit fcad23
                    numfds, tvp));
Packit fcad23
        if (tvp)
Packit fcad23
            DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec,
Packit fcad23
                        (long) tvp->tv_usec));
Packit fcad23
        count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
Packit fcad23
				     tvp);
Packit fcad23
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));
Packit fcad23
Packit fcad23
        if (count > 0) {
Packit fcad23
Packit fcad23
#ifdef USING_SMUX_MODULE
Packit fcad23
            /*
Packit fcad23
             * handle the SMUX sd's 
Packit fcad23
             */
Packit fcad23
            if (smux_listen_sd >= 0) {
Packit fcad23
                for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
Packit fcad23
                    sd = smux_snmp_select_list_get_SD_from_List(i);
Packit fcad23
                    if (NETSNMP_LARGE_FD_ISSET(sd, &readfds)) {
Packit fcad23
                        if (smux_process(sd) < 0) {
Packit fcad23
                            smux_snmp_select_list_del(sd);
Packit fcad23
                        }
Packit fcad23
                    }
Packit fcad23
                }
Packit fcad23
                /*
Packit fcad23
                 * new connection 
Packit fcad23
                 */
Packit fcad23
                if (NETSNMP_LARGE_FD_ISSET(smux_listen_sd, &readfds)) {
Packit fcad23
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
Packit fcad23
                        smux_snmp_select_list_add(sd);
Packit fcad23
                    }
Packit fcad23
                }
Packit fcad23
            }
Packit fcad23
Packit fcad23
#endif                          /* USING_SMUX_MODULE */
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
Packit fcad23
            netsnmp_dispatch_external_events2(&count, &readfds,
Packit fcad23
                                              &writefds, &exceptfds);
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
Packit fcad23
Packit fcad23
            /* If there are still events leftover, process them */
Packit fcad23
            if (count > 0) {
Packit fcad23
              snmp_read2(&readfds);
Packit fcad23
            }
Packit fcad23
        } else
Packit fcad23
            switch (count) {
Packit fcad23
            case 0:
Packit fcad23
                snmp_timeout();
Packit fcad23
                break;
Packit fcad23
            case -1:
Packit fcad23
                DEBUGMSGTL(("snmpd/select", "  errno = %d\n", errno));
Packit fcad23
                if (errno == EINTR) {
Packit fcad23
                    /*
Packit fcad23
                     * likely that we got a signal. Check our special signal
Packit fcad23
                     * flags before retrying select.
Packit fcad23
                     */
Packit fcad23
		    if (netsnmp_running && !reconfig) {
Packit fcad23
                        goto reselect;
Packit fcad23
		    }
Packit fcad23
                    continue;
Packit fcad23
                } else {
Packit fcad23
                    snmp_log_perror("select");
Packit fcad23
                }
Packit fcad23
                return -1;
Packit fcad23
            default:
Packit fcad23
                snmp_log(LOG_ERR, "select returned %d\n", count);
Packit fcad23
                return -1;
Packit fcad23
            }                   /* endif -- count>0 */
Packit fcad23
Packit fcad23
        /*
Packit fcad23
         * see if persistent store needs to be saved
Packit fcad23
         */
Packit fcad23
        snmp_store_if_needed();
Packit fcad23
Packit fcad23
        /*
Packit fcad23
         * run requested alarms 
Packit fcad23
         */
Packit fcad23
        run_alarms();
Packit fcad23
Packit fcad23
        netsnmp_check_outstanding_agent_requests();
Packit fcad23
Packit fcad23
    }                           /* endwhile */
Packit fcad23
Packit fcad23
    netsnmp_large_fd_set_cleanup(&readfds);
Packit fcad23
    netsnmp_large_fd_set_cleanup(&writefds);
Packit fcad23
    netsnmp_large_fd_set_cleanup(&exceptfds);
Packit fcad23
Packit fcad23
#if defined(WIN32)
Packit fcad23
    join_stdin_waiter_thread();
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
Packit fcad23
    return 0;
Packit fcad23
Packit fcad23
}                               /* end receive() */
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
/*******************************************************************-o-******
Packit fcad23
 * snmp_input
Packit fcad23
 *
Packit fcad23
 * Parameters:
Packit fcad23
 *	 op
Packit fcad23
 *	*session
Packit fcad23
 *	 requid
Packit fcad23
 *	*pdu
Packit fcad23
 *	*magic
Packit fcad23
 *      
Packit fcad23
 * Returns:
Packit fcad23
 *	1		On success	-OR-
Packit fcad23
 *	Passes through	Return from alarmGetResponse() when 
Packit fcad23
 *	  		  USING_V2PARTY_ALARM_MODULE is defined.
Packit fcad23
 *
Packit fcad23
 * Call-back function to manage responses to traps (informs) and alarms.
Packit fcad23
 * Not used by the agent to process other Response PDUs.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
snmp_input(int op,
Packit fcad23
           netsnmp_session * session,
Packit fcad23
           int reqid, netsnmp_pdu *pdu, void *magic)
Packit fcad23
{
Packit fcad23
    struct get_req_state *state = (struct get_req_state *) magic;
Packit fcad23
Packit fcad23
    if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
Packit fcad23
        if (pdu->command == SNMP_MSG_GET) {
Packit fcad23
            if (state->type == EVENT_GET_REQ) {
Packit fcad23
                /*
Packit fcad23
                 * this is just the ack to our inform pdu 
Packit fcad23
                 */
Packit fcad23
                return 1;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
    } else if (op == NETSNMP_CALLBACK_OP_TIMED_OUT) {
Packit fcad23
        if (state->type == ALARM_GET_REQ) {
Packit fcad23
            /*
Packit fcad23
             * Need a mechanism to replace obsolete SNMPv2p alarm 
Packit fcad23
             */
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    return 1;
Packit fcad23
Packit fcad23
}                               /* end snmp_input() */
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Windows Service Related functions 
Packit fcad23
 */
Packit fcad23
#ifdef WIN32SERVICE
Packit fcad23
/************************************************************
Packit fcad23
* main function for Windows
Packit fcad23
* Parse command line arguments for startup options,
Packit fcad23
* to start as service or console mode application in windows.
Packit fcad23
* Invokes appropriate startup functions depending on the 
Packit fcad23
* parameters passed
Packit fcad23
*************************************************************/
Packit fcad23
int
Packit fcad23
    __cdecl
Packit fcad23
_tmain(int argc, TCHAR * argv[])
Packit fcad23
{
Packit fcad23
    /*
Packit fcad23
     * Define Service Name and Description, which appears in windows SCM 
Packit fcad23
     */
Packit fcad23
    LPCTSTR         lpszServiceName = app_name_long;      /* Service Registry Name */
Packit fcad23
    LPCTSTR         lpszServiceDisplayName = _T("Net-SNMP Agent");       /* Display Name */
Packit fcad23
    LPCTSTR         lpszServiceDescription =
Packit fcad23
#ifdef IFDESCR
Packit fcad23
        _T("SNMPv2c / SNMPv3 command responder from Net-SNMP. Supports MIB objects for IP,ICMP,TCP,UDP, and network interface sub-layers.");
Packit fcad23
#else
Packit fcad23
        _T("SNMPv2c / SNMPv3 command responder from Net-SNMP");
Packit fcad23
#endif
Packit fcad23
    InputParams     InputOptions;
Packit fcad23
Packit fcad23
Packit fcad23
    int             nRunType = RUN_AS_CONSOLE;
Packit fcad23
    int             quiet = 0;
Packit fcad23
    
Packit fcad23
#if 0
Packit fcad23
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    nRunType = ParseCmdLineForServiceOption(argc, argv, &quiet);
Packit fcad23
Packit fcad23
    switch (nRunType) {
Packit fcad23
    case REGISTER_SERVICE:
Packit fcad23
        /*
Packit fcad23
         * Register As service 
Packit fcad23
         */
Packit fcad23
        InputOptions.Argc = argc;
Packit fcad23
        InputOptions.Argv = argv;
Packit fcad23
        return RegisterService(lpszServiceName,
Packit fcad23
                        lpszServiceDisplayName,
Packit fcad23
                        lpszServiceDescription, &InputOptions, quiet);
Packit fcad23
    case UN_REGISTER_SERVICE:
Packit fcad23
        /*
Packit fcad23
         * Unregister service 
Packit fcad23
         */
Packit fcad23
        return UnregisterService(lpszServiceName, quiet);
Packit fcad23
    case RUN_AS_SERVICE:
Packit fcad23
        /*
Packit fcad23
         * Run as service 
Packit fcad23
         */
Packit fcad23
        /*
Packit fcad23
         * Register Stop Function 
Packit fcad23
         */
Packit fcad23
        RegisterStopFunction(StopSnmpAgent);
Packit fcad23
        return RunAsService(SnmpDaemonMain);
Packit fcad23
    default:
Packit fcad23
        /*
Packit fcad23
         * Run in console mode 
Packit fcad23
         */
Packit fcad23
        return SnmpDaemonMain(argc, argv);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * To stop Snmp Agent daemon
Packit fcad23
 * This portion is still not working
Packit fcad23
 */
Packit fcad23
void
Packit fcad23
StopSnmpAgent(void)
Packit fcad23
{
Packit fcad23
    /*
Packit fcad23
     * Shut Down Agent 
Packit fcad23
     */
Packit fcad23
    SnmpdShutDown(1);
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Wait till agent is completely stopped 
Packit fcad23
     */
Packit fcad23
Packit fcad23
    while (agent_status != AGENT_STOPPED) {
Packit fcad23
        Sleep(100);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
#endif /*WIN32SERVICE*/