Blame snmplib/system.c

Packit Service b38f0b
/*
Packit Service b38f0b
 * system.c
Packit Service b38f0b
 */
Packit Service b38f0b
/* Portions of this file are subject to the following copyright(s).  See
Packit Service b38f0b
 * the Net-SNMP's COPYING file for more details and other copyrights
Packit Service b38f0b
 * that may apply:
Packit Service b38f0b
 */
Packit Service b38f0b
/***********************************************************
Packit Service b38f0b
        Copyright 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
/*
Packit Service b38f0b
 * Portions of this file are copyrighted by:
Packit Service b38f0b
 * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
Packit Service b38f0b
 * Use is subject to license terms specified in the COPYING file
Packit Service b38f0b
 * distributed with the Net-SNMP package.
Packit Service b38f0b
 */
Packit Service b38f0b
/*
Packit Service b38f0b
 * Portions of this file are copyrighted by:
Packit Service b38f0b
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
Packit Service b38f0b
 * Use is subject to license terms specified in the COPYING file
Packit Service b38f0b
 * distributed with the Net-SNMP package.
Packit Service b38f0b
 *
Packit Service b38f0b
 * Portions of this file are copyrighted by:
Packit Service b38f0b
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
Packit Service b38f0b
 * Use is subject to license terms specified in the COPYING file
Packit Service b38f0b
 * distributed with the Net-SNMP package.
Packit Service b38f0b
 */
Packit Service b38f0b
/*
Packit Service b38f0b
 * System dependent routines go here
Packit Service b38f0b
 */
Packit Service b38f0b
#include <net-snmp/net-snmp-config.h>
Packit Service b38f0b
#include <net-snmp/net-snmp-features.h>
Packit Service b38f0b
#include <stdio.h>
Packit Service b38f0b
#include <ctype.h>
Packit Service b38f0b
#include <errno.h>
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_IO_H
Packit Service b38f0b
#include <io.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_DIRECT_H
Packit Service b38f0b
#include <direct.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_STDLIB_H
Packit Service b38f0b
#include <stdlib.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if TIME_WITH_SYS_TIME
Packit Service b38f0b
# include <sys/time.h>
Packit Service b38f0b
# include <time.h>
Packit Service b38f0b
#else
Packit Service b38f0b
# if HAVE_SYS_TIME_H
Packit Service b38f0b
#  include <sys/time.h>
Packit Service b38f0b
# else
Packit Service b38f0b
#  include <time.h>
Packit Service b38f0b
# endif
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#include <sys/types.h>
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_NETINET_IN_H
Packit Service b38f0b
#include <netinet/in.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_SOCKET_H
Packit Service b38f0b
#include <sys/socket.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
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_SOCKIO_H
Packit Service b38f0b
#include <sys/sockio.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_IOCTL_H
Packit Service b38f0b
#include <sys/ioctl.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#ifdef HAVE_NLIST_H
Packit Service b38f0b
#include <nlist.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_FILE_H
Packit Service b38f0b
#include <sys/file.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_KSTAT_H
Packit Service b38f0b
#include <kstat.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_PARAM_H
Packit Service b38f0b
#include <sys/param.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_SYS_SYSCTL_H
Packit Service b38f0b
#include <sys/sysctl.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
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
Packit Service b38f0b
#if HAVE_DMALLOC_H
Packit Service b38f0b
#include <dmalloc.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#ifdef HAVE_SYS_STAT_H
Packit Service b38f0b
#include <sys/stat.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
#if defined(hpux10) || defined(hpux11)
Packit Service b38f0b
#include <sys/pstat.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_UTSNAME_H
Packit Service b38f0b
#include <sys/utsname.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_SYSTEMCFG_H
Packit Service b38f0b
#include <sys/systemcfg.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_SYS_SYSTEMINFO_H
Packit Service b38f0b
#include <sys/systeminfo.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if defined(darwin9)
Packit Service b38f0b
#include <crt_externs.h>        /* for _NSGetArgv() */
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_PWD_H
Packit Service b38f0b
#include <pwd.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_GRP_H
Packit Service b38f0b
#include <grp.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_LIMITS_H
Packit Service b38f0b
#include <limits.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_ARPA_INET_H
Packit Service b38f0b
#include <arpa/inet.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
#if 1 /*HAVE_ARPA_NAMESER_H*/
Packit Service b38f0b
#include <arpa/nameser.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#include <validator/validator.h>
Packit Service b38f0b
/* NetSNMP and DNSSEC-Tools both define FREE. We'll not use either here. */
Packit Service b38f0b
#undef FREE
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/types.h>
Packit Service b38f0b
#include <net-snmp/output_api.h>
Packit Service b38f0b
#include <net-snmp/utilities.h>
Packit Service b38f0b
#include <net-snmp/library/system.h>    /* for "internal" definitions */
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/library/snmp_api.h>
Packit Service b38f0b
#include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */
Packit Service b38f0b
Packit Service b38f0b
#include "inet_ntop.h"
Packit Service b38f0b
Packit Service b38f0b
/* NetSNMP and DNSSEC-Tools both define FREE. We'll not use either here. */
Packit Service b38f0b
#undef FREE
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(system_all, libnetsnmp)
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(user_information, system_all)
Packit Service b38f0b
netsnmp_feature_child_of(calculate_sectime_diff, system_all)
Packit Service b38f0b
Packit Service b38f0b
#ifndef IFF_LOOPBACK
Packit Service b38f0b
#	define IFF_LOOPBACK 0
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#ifdef  INADDR_LOOPBACK
Packit Service b38f0b
# define LOOPBACK    INADDR_LOOPBACK
Packit Service b38f0b
#else
Packit Service b38f0b
# define LOOPBACK    0x7f000001
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#ifndef EAI_FAIL
Packit Service b38f0b
# define EAI_FAIL    -4    /* Non-recoverable failure in name res.  */
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if defined(HAVE_FORK)
Packit Service b38f0b
static void
Packit Service b38f0b
_daemon_prep(int stderr_log)
Packit Service b38f0b
{
Packit Service b38f0b
    int fd;
Packit Service b38f0b
Packit Service b38f0b
    /* Avoid keeping any directory in use. */
Packit Service b38f0b
    chdir("/");
Packit Service b38f0b
Packit Service b38f0b
    if (stderr_log)
Packit Service b38f0b
        return;
Packit Service b38f0b
Packit Service b38f0b
    fd = open("/dev/null", O_RDWR);
Packit Service b38f0b
    
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Close inherited file descriptors to avoid
Packit Service b38f0b
     * keeping unnecessary references.
Packit Service b38f0b
     */
Packit Service b38f0b
    close(STDIN_FILENO);
Packit Service b38f0b
    close(STDOUT_FILENO);
Packit Service b38f0b
    close(STDERR_FILENO);
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Redirect std{in,out,err} to /dev/null, just in case.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (fd >= 0) {
Packit Service b38f0b
        dup2(fd, STDIN_FILENO);
Packit Service b38f0b
        dup2(fd, STDOUT_FILENO);
Packit Service b38f0b
        dup2(fd, STDERR_FILENO);
Packit Service b38f0b
        close(fd);
Packit Service b38f0b
    }
Packit Service b38f0b
}
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
/**
Packit Service b38f0b
 * fork current process into the background.
Packit Service b38f0b
 *
Packit Service b38f0b
 * This function forks a process into the background, in order to
Packit Service b38f0b
 * become a daemon process. It does a few things along the way:
Packit Service b38f0b
 *
Packit Service b38f0b
 * - becoming a process/session group leader, and  forking a second time so
Packit Service b38f0b
 *   that process/session group leader can exit.
Packit Service b38f0b
 *
Packit Service b38f0b
 * - changing the working directory to /
Packit Service b38f0b
 *
Packit Service b38f0b
 * - closing stdin, stdout and stderr (unless stderr_log is set) and
Packit Service b38f0b
 *   redirecting them to /dev/null
Packit Service b38f0b
 *
Packit Service b38f0b
 * @param quit_immediately : indicates if the parent process should
Packit Service b38f0b
 *                           exit after a successful fork.
Packit Service b38f0b
 * @param stderr_log       : indicates if stderr is being used for
Packit Service b38f0b
 *                           logging and shouldn't be closed
Packit Service b38f0b
 * @returns -1 : fork error
Packit Service b38f0b
 *           0 : child process returning
Packit Service b38f0b
 *          >0 : parent process returning. returned value is the child PID.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
netsnmp_daemonize(int quit_immediately, int stderr_log)
Packit Service b38f0b
{
Packit Service b38f0b
    int i = 0;
Packit Service b38f0b
    DEBUGMSGT(("daemonize","deamonizing...\n"));
Packit Service b38f0b
#if HAVE_FORK
Packit Service b38f0b
#if defined(darwin9)
Packit Service b38f0b
     char            path [PATH_MAX] = "";
Packit Service b38f0b
     uint32_t        size = sizeof (path);
Packit Service b38f0b
Packit Service b38f0b
     /*
Packit Service b38f0b
      * if we are already launched in a "daemonized state", just
Packit Service b38f0b
      * close & redirect the file descriptors
Packit Service b38f0b
      */
Packit Service b38f0b
     if(getppid() <= 2) {
Packit Service b38f0b
         _daemon_prep(stderr_log);
Packit Service b38f0b
         return 0;
Packit Service b38f0b
     }
Packit Service b38f0b
Packit Service b38f0b
     if (_NSGetExecutablePath (path, &size))
Packit Service b38f0b
         return -1;
Packit Service b38f0b
#endif
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Fork to return control to the invoking process and to
Packit Service b38f0b
     * guarantee that we aren't a process group leader.
Packit Service b38f0b
     */
Packit Service b38f0b
#if HAVE_FORKALL
Packit Service b38f0b
    i = forkall();
Packit Service b38f0b
#else
Packit Service b38f0b
    i = fork();
Packit Service b38f0b
#endif
Packit Service b38f0b
    if (i != 0) {
Packit Service b38f0b
        /* Parent. */
Packit Service b38f0b
        DEBUGMSGT(("daemonize","first fork returned %d.\n", i));
Packit Service b38f0b
        if(i == -1) {
Packit Service b38f0b
            snmp_log(LOG_ERR,"first fork failed (errno %d) in "
Packit Service b38f0b
                     "netsnmp_daemonize()\n", errno);
Packit Service b38f0b
            return -1;
Packit Service b38f0b
        }
Packit Service b38f0b
        if (quit_immediately) {
Packit Service b38f0b
            DEBUGMSGT(("daemonize","parent exiting\n"));
Packit Service b38f0b
            exit(0);
Packit Service b38f0b
        }
Packit Service b38f0b
    } else {
Packit Service b38f0b
        /* Child. */
Packit Service b38f0b
#ifdef HAVE_SETSID
Packit Service b38f0b
        /* Become a process/session group leader. */
Packit Service b38f0b
        setsid();
Packit Service b38f0b
#endif
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Fork to let the process/session group leader exit.
Packit Service b38f0b
         */
Packit Service b38f0b
#if HAVE_FORKALL
Packit Service b38f0b
	i = forkall();
Packit Service b38f0b
#else
Packit Service b38f0b
	i = fork();
Packit Service b38f0b
#endif
Packit Service b38f0b
        if (i != 0) {
Packit Service b38f0b
            DEBUGMSGT(("daemonize","second fork returned %d.\n", i));
Packit Service b38f0b
            if(i == -1) {
Packit Service b38f0b
                snmp_log(LOG_ERR,"second fork failed (errno %d) in "
Packit Service b38f0b
                         "netsnmp_daemonize()\n", errno);
Packit Service b38f0b
            }
Packit Service b38f0b
            /* Parent. */
Packit Service b38f0b
            exit(0);
Packit Service b38f0b
        }
Packit Service b38f0b
#ifndef WIN32
Packit Service b38f0b
        else {
Packit Service b38f0b
            /* Child. */
Packit Service b38f0b
            
Packit Service b38f0b
            DEBUGMSGT(("daemonize","child continuing\n"));
Packit Service b38f0b
Packit Service b38f0b
#if ! defined(darwin9)
Packit Service b38f0b
            _daemon_prep(stderr_log);
Packit Service b38f0b
#else
Packit Service b38f0b
             /*
Packit Service b38f0b
              * Some darwin calls (using mach ports) don't work after
Packit Service b38f0b
              * a fork. So, now that we've forked, we re-exec ourself
Packit Service b38f0b
              * to ensure that the child's mach ports are all set up correctly,
Packit Service b38f0b
              * the getppid call above will prevent the exec child from
Packit Service b38f0b
              * forking...
Packit Service b38f0b
              */
Packit Service b38f0b
             char * const *argv = *_NSGetArgv ();
Packit Service b38f0b
             DEBUGMSGT(("daemonize","re-execing forked child\n"));
Packit Service b38f0b
             execv (path, argv);
Packit Service b38f0b
             snmp_log(LOG_ERR,"Forked child unable to re-exec - %s.\n", strerror (errno));
Packit Service b38f0b
             exit (0);
Packit Service b38f0b
#endif
Packit Service b38f0b
        }
Packit Service b38f0b
#endif /* !WIN32 */
Packit Service b38f0b
    }
Packit Service b38f0b
#endif /* HAVE_FORK */
Packit Service b38f0b
    return i;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * ********************************************* 
Packit Service b38f0b
 */
Packit Service b38f0b
#ifdef							WIN32
Packit Service b38f0b
in_addr_t
Packit Service b38f0b
get_myaddr(void)
Packit Service b38f0b
{
Packit Service b38f0b
    char            local_host[130];
Packit Service b38f0b
    int             result;
Packit Service b38f0b
    LPHOSTENT       lpstHostent;
Packit Service b38f0b
    SOCKADDR_IN     in_addr, remote_in_addr;
Packit Service b38f0b
    SOCKET          hSock;
Packit Service b38f0b
    int             nAddrSize = sizeof(SOCKADDR);
Packit Service b38f0b
Packit Service b38f0b
    in_addr.sin_addr.s_addr = INADDR_ANY;
Packit Service b38f0b
Packit Service b38f0b
    result = gethostname(local_host, sizeof(local_host));
Packit Service b38f0b
    if (result == 0) {
Packit Service b38f0b
        lpstHostent = gethostbyname((LPSTR) local_host);
Packit Service b38f0b
        if (lpstHostent) {
Packit Service b38f0b
            in_addr.sin_addr.s_addr =
Packit Service b38f0b
                *((u_long FAR *) (lpstHostent->h_addr));
Packit Service b38f0b
            return ((in_addr_t) in_addr.sin_addr.s_addr);
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * if we are here, than we don't have host addr 
Packit Service b38f0b
     */
Packit Service b38f0b
    hSock = socket(AF_INET, SOCK_DGRAM, 0);
Packit Service b38f0b
    if (hSock != INVALID_SOCKET) {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * connect to any port and address 
Packit Service b38f0b
         */
Packit Service b38f0b
        remote_in_addr.sin_family = AF_INET;
Packit Service b38f0b
        remote_in_addr.sin_port = htons(IPPORT_ECHO);
Packit Service b38f0b
        remote_in_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
Packit Service b38f0b
        result =
Packit Service b38f0b
            connect(hSock, (LPSOCKADDR) & remote_in_addr,
Packit Service b38f0b
                    sizeof(SOCKADDR));
Packit Service b38f0b
        if (result != SOCKET_ERROR) {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * get local ip address 
Packit Service b38f0b
             */
Packit Service b38f0b
            getsockname(hSock, (LPSOCKADDR) & in_addr,
Packit Service b38f0b
                        (int FAR *) &nAddrSize);
Packit Service b38f0b
        }
Packit Service b38f0b
        closesocket(hSock);
Packit Service b38f0b
    }
Packit Service b38f0b
    return ((in_addr_t) in_addr.sin_addr.s_addr);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
long
Packit Service b38f0b
get_uptime(void)
Packit Service b38f0b
{
Packit Service b38f0b
    long            return_value = 0;
Packit Service b38f0b
    DWORD           buffersize = (sizeof(PERF_DATA_BLOCK) +
Packit Service b38f0b
                                  sizeof(PERF_OBJECT_TYPE)),
Packit Service b38f0b
        type = REG_EXPAND_SZ;
Packit Service b38f0b
    PPERF_DATA_BLOCK perfdata = NULL;
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * min requirement is one PERF_DATA_BLOCK plus one PERF_OBJECT_TYPE 
Packit Service b38f0b
     */
Packit Service b38f0b
    perfdata = (PPERF_DATA_BLOCK) malloc(buffersize);
Packit Service b38f0b
    if (!perfdata)
Packit Service b38f0b
        return 0;
Packit Service b38f0b
Packit Service b38f0b
    memset(perfdata, 0, buffersize);
Packit Service b38f0b
Packit Service b38f0b
    RegQueryValueEx(HKEY_PERFORMANCE_DATA,
Packit Service b38f0b
                    "Global", NULL, &type, (LPBYTE) perfdata, &buffersize);
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * we can not rely on the return value since there is always more so
Packit Service b38f0b
     * we check the signature 
Packit Service b38f0b
     */
Packit Service b38f0b
Packit Service b38f0b
    if (wcsncmp(perfdata->Signature, L"PERF", 4) == 0) {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * signature ok, and all we need is in the in the PERF_DATA_BLOCK 
Packit Service b38f0b
         */
Packit Service b38f0b
        return_value = (long) ((perfdata->PerfTime100nSec.QuadPart /
Packit Service b38f0b
                                (LONGLONG) 100000));
Packit Service b38f0b
    } else
Packit Service b38f0b
        return_value = GetTickCount() / 10;
Packit Service b38f0b
Packit Service b38f0b
    RegCloseKey(HKEY_PERFORMANCE_DATA);
Packit Service b38f0b
    free(perfdata);
Packit Service b38f0b
Packit Service b38f0b
    return return_value;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
char           *
Packit Service b38f0b
winsock_startup(void)
Packit Service b38f0b
{
Packit Service b38f0b
    WORD            VersionRequested;
Packit Service b38f0b
    WSADATA         stWSAData;
Packit Service b38f0b
    int             i;
Packit Service b38f0b
    static char     errmsg[100];
Packit Service b38f0b
Packit Service b38f0b
	/* winsock 1: use MAKEWORD(1,1) */
Packit Service b38f0b
	/* winsock 2: use MAKEWORD(2,2) */
Packit Service b38f0b
Packit Service b38f0b
    VersionRequested = MAKEWORD(2,2);
Packit Service b38f0b
    i = WSAStartup(VersionRequested, &stWSAData);
Packit Service b38f0b
    if (i != 0) {
Packit Service b38f0b
        if (i == WSAVERNOTSUPPORTED)
Packit Service b38f0b
            sprintf(errmsg,
Packit Service b38f0b
                    "Unable to init. socket lib, does not support 1.1");
Packit Service b38f0b
        else {
Packit Service b38f0b
            sprintf(errmsg, "Socket Startup error %d", i);
Packit Service b38f0b
        }
Packit Service b38f0b
        return (errmsg);
Packit Service b38f0b
    }
Packit Service b38f0b
    return (NULL);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
void
Packit Service b38f0b
winsock_cleanup(void)
Packit Service b38f0b
{
Packit Service b38f0b
    WSACleanup();
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
#else                           /* ! WIN32 */
Packit Service b38f0b
/*******************************************************************/
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * XXX  What if we have multiple addresses?  Or no addresses for that matter?
Packit Service b38f0b
 * XXX  Could it be computed once then cached?  Probably not worth it (not
Packit Service b38f0b
 *                                                           used very often).
Packit Service b38f0b
 */
Packit Service b38f0b
in_addr_t
Packit Service b38f0b
get_myaddr(void)
Packit Service b38f0b
{
Packit Service b38f0b
    int             sd, i, lastlen = 0;
Packit Service b38f0b
    struct ifconf   ifc;
Packit Service b38f0b
    struct ifreq   *ifrp = NULL;
Packit Service b38f0b
    in_addr_t       addr;
Packit Service b38f0b
    char           *buf = NULL;
Packit Service b38f0b
Packit Service b38f0b
    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF on
Packit Service b38f0b
     * some platforms; see W. R. Stevens, ``Unix Network Programming Volume
Packit Service b38f0b
     * I'', p.435.  
Packit Service b38f0b
     */
Packit Service b38f0b
Packit Service b38f0b
    for (i = 8;; i += 8) {
Packit Service b38f0b
        buf = (char *) calloc(i, sizeof(struct ifreq));
Packit Service b38f0b
        if (buf == NULL) {
Packit Service b38f0b
            close(sd);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        }
Packit Service b38f0b
        ifc.ifc_len = i * sizeof(struct ifreq);
Packit Service b38f0b
        ifc.ifc_buf = (caddr_t) buf;
Packit Service b38f0b
Packit Service b38f0b
        if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
Packit Service b38f0b
            if (errno != EINVAL || lastlen != 0) {
Packit Service b38f0b
                /*
Packit Service b38f0b
                 * Something has gone genuinely wrong.  
Packit Service b38f0b
                 */
Packit Service b38f0b
                free(buf);
Packit Service b38f0b
                close(sd);
Packit Service b38f0b
                return 0;
Packit Service b38f0b
            }
Packit Service b38f0b
            /*
Packit Service b38f0b
             * Otherwise, it could just be that the buffer is too small.  
Packit Service b38f0b
             */
Packit Service b38f0b
        } else {
Packit Service b38f0b
            if (ifc.ifc_len == lastlen) {
Packit Service b38f0b
                /*
Packit Service b38f0b
                 * The length is the same as the last time; we're done.  
Packit Service b38f0b
                 */
Packit Service b38f0b
                break;
Packit Service b38f0b
            }
Packit Service b38f0b
            lastlen = ifc.ifc_len;
Packit Service b38f0b
        }
Packit Service b38f0b
        free(buf);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    for (ifrp = ifc.ifc_req;
Packit Service b38f0b
        (char *)ifrp < (char *)ifc.ifc_req + ifc.ifc_len;
Packit Service b38f0b
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
Packit Service b38f0b
        ifrp = (struct ifreq *)(((char *) ifrp) +
Packit Service b38f0b
                                sizeof(ifrp->ifr_name) +
Packit Service b38f0b
                                ifrp->ifr_addr.sa_len)
Packit Service b38f0b
#else
Packit Service b38f0b
        ifrp++
Packit Service b38f0b
#endif
Packit Service b38f0b
        ) {
Packit Service b38f0b
        if (ifrp->ifr_addr.sa_family != AF_INET) {
Packit Service b38f0b
            continue;
Packit Service b38f0b
        }
Packit Service b38f0b
        addr = ((struct sockaddr_in *) &(ifrp->ifr_addr))->sin_addr.s_addr;
Packit Service b38f0b
Packit Service b38f0b
        if (ioctl(sd, SIOCGIFFLAGS, (char *) ifrp) < 0) {
Packit Service b38f0b
            continue;
Packit Service b38f0b
        }
Packit Service b38f0b
        if ((ifrp->ifr_flags & IFF_UP)
Packit Service b38f0b
#ifdef IFF_RUNNING
Packit Service b38f0b
            && (ifrp->ifr_flags & IFF_RUNNING)
Packit Service b38f0b
#endif                          /* IFF_RUNNING */
Packit Service b38f0b
            && !(ifrp->ifr_flags & IFF_LOOPBACK)
Packit Service b38f0b
            && addr != LOOPBACK) {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * I *really* don't understand why this is necessary.  Perhaps for
Packit Service b38f0b
             * some broken platform?  Leave it for now.  JBPN  
Packit Service b38f0b
             */
Packit Service b38f0b
#ifdef SYS_IOCTL_H_HAS_SIOCGIFADDR
Packit Service b38f0b
            if (ioctl(sd, SIOCGIFADDR, (char *) ifrp) < 0) {
Packit Service b38f0b
                continue;
Packit Service b38f0b
            }
Packit Service b38f0b
            addr =
Packit Service b38f0b
                ((struct sockaddr_in *) &(ifrp->ifr_addr))->sin_addr.
Packit Service b38f0b
                s_addr;
Packit Service b38f0b
#endif
Packit Service b38f0b
            free(buf);
Packit Service b38f0b
            close(sd);
Packit Service b38f0b
            return addr;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
    free(buf);
Packit Service b38f0b
    close(sd);
Packit Service b38f0b
    return 0;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
#if !defined(solaris2) && !defined(linux) && !defined(cygwin)
Packit Service b38f0b
/*
Packit Service b38f0b
 * Returns boottime in centiseconds(!).
Packit Service b38f0b
 *      Caches this for future use.
Packit Service b38f0b
 */
Packit Service b38f0b
long
Packit Service b38f0b
get_boottime(void)
Packit Service b38f0b
{
Packit Service b38f0b
    static long     boottime_csecs = 0;
Packit Service b38f0b
#if defined(hpux10) || defined(hpux11)
Packit Service b38f0b
    struct pst_static pst_buf;
Packit Service b38f0b
#else
Packit Service b38f0b
    struct timeval  boottime;
Packit Service b38f0b
#ifdef	NETSNMP_CAN_USE_SYSCTL
Packit Service b38f0b
    int             mib[2];
Packit Service b38f0b
    size_t          len;
Packit Service b38f0b
#elif defined(NETSNMP_CAN_USE_NLIST)
Packit Service b38f0b
    int             kmem;
Packit Service b38f0b
#if !defined(hpux)
Packit Service b38f0b
    static char boottime_name[] = "_boottime";
Packit Service b38f0b
#else
Packit Service b38f0b
    static char boottime_name[] = "boottime";
Packit Service b38f0b
#endif
Packit Service b38f0b
    static char empty_name[] = "";
Packit Service b38f0b
    struct nlist nl[2];
Packit Service b38f0b
Packit Service b38f0b
    memset(nl, 0, sizeof(nl));
Packit Service b38f0b
    nl[0].n_name = boottime_name;
Packit Service b38f0b
    nl[1].n_name = empty_name;
Packit Service b38f0b
#endif                          /* NETSNMP_CAN_USE_SYSCTL */
Packit Service b38f0b
#endif                          /* hpux10 || hpux 11 */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    if (boottime_csecs != 0)
Packit Service b38f0b
        return (boottime_csecs);
Packit Service b38f0b
Packit Service b38f0b
#if defined(hpux10) || defined(hpux11)
Packit Service b38f0b
    pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0);
Packit Service b38f0b
    boottime_csecs = pst_buf.boot_time * 100;
Packit Service b38f0b
#elif NETSNMP_CAN_USE_SYSCTL
Packit Service b38f0b
    mib[0] = CTL_KERN;
Packit Service b38f0b
    mib[1] = KERN_BOOTTIME;
Packit Service b38f0b
Packit Service b38f0b
    len = sizeof(boottime);
Packit Service b38f0b
Packit Service b38f0b
    sysctl(mib, 2, &boottime, &len, NULL, 0);
Packit Service b38f0b
    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
Packit Service b38f0b
#elif defined(NETSNMP_CAN_USE_NLIST)
Packit Service b38f0b
    if ((kmem = open("/dev/kmem", 0)) < 0)
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    nlist(KERNEL_LOC, nl);
Packit Service b38f0b
    if (nl[0].n_type == 0) {
Packit Service b38f0b
        close(kmem);
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    lseek(kmem, (long) nl[0].n_value, L_SET);
Packit Service b38f0b
    read(kmem, &boottime, sizeof(boottime));
Packit Service b38f0b
    close(kmem);
Packit Service b38f0b
    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
Packit Service b38f0b
#else
Packit Service b38f0b
    return 0;
Packit Service b38f0b
#endif                          /* hpux10 || hpux 11 */
Packit Service b38f0b
Packit Service b38f0b
    return (boottime_csecs);
Packit Service b38f0b
}
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
/**
Packit Service b38f0b
 * Returns the system uptime in centiseconds.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @note The value returned by this function is not identical to sysUpTime
Packit Service b38f0b
 *   defined in RFC 1213. get_uptime() returns the system uptime while
Packit Service b38f0b
 *   sysUpTime represents the time that has elapsed since the most recent
Packit Service b38f0b
 *   restart of the network manager (snmpd).
Packit Service b38f0b
 *
Packit Service b38f0b
 * @see See also netsnmp_get_agent_uptime().
Packit Service b38f0b
 */
Packit Service b38f0b
long
Packit Service b38f0b
get_uptime(void)
Packit Service b38f0b
{
Packit Service b38f0b
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
Packit Service b38f0b
    static char lbolt_name[] = "lbolt";
Packit Service b38f0b
    struct nlist nl;
Packit Service b38f0b
    int kmem;
Packit Service b38f0b
    time_t lbolt;
Packit Service b38f0b
    nl.n_name = lbolt_name;
Packit Service b38f0b
    if(knlist(&nl, 1, sizeof(struct nlist)) != 0) return(0);
Packit Service b38f0b
    if(nl.n_type == 0 || nl.n_value == 0) return(0);
Packit Service b38f0b
    if((kmem = open("/dev/mem", 0)) < 0) return 0;
Packit Service b38f0b
    lseek(kmem, (long) nl.n_value, L_SET);
Packit Service b38f0b
    read(kmem, &lbolt, sizeof(lbolt));
Packit Service b38f0b
    close(kmem);
Packit Service b38f0b
    return(lbolt);
Packit Service b38f0b
#elif defined(solaris2)
Packit Service b38f0b
    kstat_ctl_t    *ksc = kstat_open();
Packit Service b38f0b
    kstat_t        *ks;
Packit Service b38f0b
    kid_t           kid;
Packit Service b38f0b
    kstat_named_t  *named;
Packit Service b38f0b
    u_long          lbolt = 0;
Packit Service b38f0b
Packit Service b38f0b
    if (ksc) {
Packit Service b38f0b
        ks = kstat_lookup(ksc, "unix", -1, "system_misc");
Packit Service b38f0b
        if (ks) {
Packit Service b38f0b
            kid = kstat_read(ksc, ks, NULL);
Packit Service b38f0b
            if (kid != -1) {
Packit Service b38f0b
                named = kstat_data_lookup(ks, "lbolt");
Packit Service b38f0b
                if (named) {
Packit Service b38f0b
#ifdef KSTAT_DATA_UINT32
Packit Service b38f0b
                    lbolt = named->value.ui32;
Packit Service b38f0b
#else
Packit Service b38f0b
                    lbolt = named->value.ul;
Packit Service b38f0b
#endif
Packit Service b38f0b
                }
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
        kstat_close(ksc);
Packit Service b38f0b
    }
Packit Service b38f0b
    return lbolt;
Packit Service b38f0b
#elif defined(linux) || defined(cygwin)
Packit Service b38f0b
    FILE           *in = fopen("/proc/uptime", "r");
Packit Service b38f0b
    long            uptim = 0, a, b;
Packit Service b38f0b
    if (in) {
Packit Service b38f0b
        if (2 == fscanf(in, "%ld.%ld", &a, &b))
Packit Service b38f0b
            uptim = a * 100 + b;
Packit Service b38f0b
        fclose(in);
Packit Service b38f0b
    }
Packit Service b38f0b
    return uptim;
Packit Service b38f0b
#else
Packit Service b38f0b
    struct timeval  now;
Packit Service b38f0b
    long            boottime_csecs, nowtime_csecs;
Packit Service b38f0b
Packit Service b38f0b
    boottime_csecs = get_boottime();
Packit Service b38f0b
    if (boottime_csecs == 0)
Packit Service b38f0b
        return 0;
Packit Service b38f0b
    gettimeofday(&now, (struct timezone *) 0);
Packit Service b38f0b
    nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);
Packit Service b38f0b
Packit Service b38f0b
    return (nowtime_csecs - boottime_csecs);
Packit Service b38f0b
#endif
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
#endif                          /* ! WIN32 */
Packit Service b38f0b
/*******************************************************************/
Packit Service b38f0b
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
static val_context_t *_val_context = NULL;
Packit Service b38f0b
Packit Service b38f0b
static val_context_t *
Packit Service b38f0b
netsnmp_validator_context(void)
Packit Service b38f0b
{
Packit Service b38f0b
    if (NULL == _val_context) {
Packit Service b38f0b
        int rc;
Packit Service b38f0b
        char *apptype = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
Packit Service b38f0b
                                              NETSNMP_DS_LIB_APPTYPE);
Packit Service b38f0b
        DEBUGMSGTL(("dns:sec:context", "creating dnssec context for %s\n",
Packit Service b38f0b
                    apptype));
Packit Service b38f0b
        rc = val_create_context(apptype, &_val_context);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    return _val_context;
Packit Service b38f0b
}
Packit Service b38f0b
#endif /* DNSSEC_LOCAL_VALIDATION */
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
netsnmp_gethostbyname_v4(const char* name, in_addr_t *addr_out)
Packit Service b38f0b
{
Packit Service b38f0b
    static int use_dns_workaround = -1;
Packit Service b38f0b
Packit Service b38f0b
    if (use_dns_workaround < 0)
Packit Service b38f0b
        use_dns_workaround = getenv("NETSNMP_DNS_WORKAROUND") != 0;
Packit Service b38f0b
    if (use_dns_workaround) {
Packit Service b38f0b
        /*
Packit Service b38f0b
         * A hack that avoids that T070com2sec_simple fails due to the DNS
Packit Service b38f0b
         * client filtering out 127.0.0.x addresses and/or redirecting DNS
Packit Service b38f0b
         * resolution failures to a web page.
Packit Service b38f0b
         */
Packit Service b38f0b
        if (strcmp(name, "onea.net-snmp.org") == 0) {
Packit Service b38f0b
            *addr_out = htonl(INADDR_LOOPBACK);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        } else if (strcmp(name, "twoa.net-snmp.org") == 0) {
Packit Service b38f0b
            *addr_out = htonl(INADDR_LOOPBACK + 1);
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        } else if (strcmp(name, "no.such.address.") == 0) {
Packit Service b38f0b
            return -1;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    {
Packit Service b38f0b
#if HAVE_GETADDRINFO
Packit Service b38f0b
    struct addrinfo *addrs = NULL;
Packit Service b38f0b
    struct addrinfo hint;
Packit Service b38f0b
    int             err;
Packit Service b38f0b
Packit Service b38f0b
    memset(&hint, 0, sizeof hint);
Packit Service b38f0b
    hint.ai_flags = 0;
Packit Service b38f0b
    hint.ai_family = PF_INET;
Packit Service b38f0b
    hint.ai_socktype = SOCK_DGRAM;
Packit Service b38f0b
    hint.ai_protocol = 0;
Packit Service b38f0b
Packit Service b38f0b
    err = netsnmp_getaddrinfo(name, NULL, &hint, &addrs);
Packit Service b38f0b
    if (err != 0) {
Packit Service b38f0b
        return -1;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (addrs != NULL) {
Packit Service b38f0b
        memcpy(addr_out,
Packit Service b38f0b
               &((struct sockaddr_in *) addrs->ai_addr)->sin_addr,
Packit Service b38f0b
               sizeof(in_addr_t));
Packit Service b38f0b
        freeaddrinfo(addrs);
Packit Service b38f0b
    } else {
Packit Service b38f0b
        DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                    "Failed to resolve IPv4 hostname\n"));
Packit Service b38f0b
    }
Packit Service b38f0b
    return 0;
Packit Service b38f0b
Packit Service b38f0b
#elif HAVE_GETHOSTBYNAME
Packit Service b38f0b
    struct hostent *hp = NULL;
Packit Service b38f0b
Packit Service b38f0b
    hp = netsnmp_gethostbyname(name);
Packit Service b38f0b
    if (hp == NULL) {
Packit Service b38f0b
        DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                    "hostname (couldn't resolve)\n"));
Packit Service b38f0b
        return -1;
Packit Service b38f0b
    } else if (hp->h_addrtype != AF_INET) {
Packit Service b38f0b
        DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                    "hostname (not AF_INET!)\n"));
Packit Service b38f0b
        return -1;
Packit Service b38f0b
    } else {
Packit Service b38f0b
        DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                    "hostname (resolved okay)\n"));
Packit Service b38f0b
        memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
Packit Service b38f0b
    }
Packit Service b38f0b
    return 0;
Packit Service b38f0b
Packit Service b38f0b
#elif HAVE_GETIPNODEBYNAME
Packit Service b38f0b
    struct hostent *hp = NULL;
Packit Service b38f0b
    int             err;
Packit Service b38f0b
Packit Service b38f0b
    hp = getipnodebyname(peername, AF_INET, 0, &err;;
Packit Service b38f0b
    if (hp == NULL) {
Packit Service b38f0b
        DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                    "hostname (couldn't resolve = %d)\n", err));
Packit Service b38f0b
        return -1;
Packit Service b38f0b
    }
Packit Service b38f0b
    DEBUGMSGTL(("get_thisaddr",
Packit Service b38f0b
                "hostname (resolved okay)\n"));
Packit Service b38f0b
    memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
Packit Service b38f0b
    return 0;
Packit Service b38f0b
Packit Service b38f0b
#else /* HAVE_GETIPNODEBYNAME */
Packit Service b38f0b
    return -1;
Packit Service b38f0b
#endif
Packit Service b38f0b
    }
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
netsnmp_getaddrinfo(const char *name, const char *service,
Packit Service b38f0b
                    const struct addrinfo *hints, struct addrinfo **res)
Packit Service b38f0b
{
Packit Service b38f0b
#if HAVE_GETADDRINFO
Packit Service b38f0b
    struct addrinfo *addrs = NULL;
Packit Service b38f0b
    struct addrinfo hint;
Packit Service b38f0b
    int             err;
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
    val_status_t    val_status;
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("dns:getaddrinfo", "looking up "));
Packit Service b38f0b
    if (name)
Packit Service b38f0b
        DEBUGMSG(("dns:getaddrinfo", "\"%s\"", name));
Packit Service b38f0b
    else
Packit Service b38f0b
        DEBUGMSG(("dns:getaddrinfo", "<NULL>"));
Packit Service b38f0b
Packit Service b38f0b
    if (service)
Packit Service b38f0b
	DEBUGMSG(("dns:getaddrinfo", ":\"%s\"", service));
Packit Service b38f0b
Packit Service b38f0b
    if (hints)
Packit Service b38f0b
	DEBUGMSG(("dns:getaddrinfo", " with hint ({ ... })"));
Packit Service b38f0b
    else
Packit Service b38f0b
	DEBUGMSG(("dns:getaddrinfo", " with no hint"));
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSG(("dns:getaddrinfo", "\n"));
Packit Service b38f0b
Packit Service b38f0b
    if (NULL == hints) {
Packit Service b38f0b
        memset(&hint, 0, sizeof hint);
Packit Service b38f0b
        hint.ai_flags = 0;
Packit Service b38f0b
        hint.ai_family = PF_INET;
Packit Service b38f0b
        hint.ai_socktype = SOCK_DGRAM;
Packit Service b38f0b
        hint.ai_protocol = 0;
Packit Service b38f0b
        hints = &hint;
Packit Service b38f0b
    } else {
Packit Service b38f0b
        memcpy(&hint, hints, sizeof hint);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
#ifndef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
    err = getaddrinfo(name, NULL, &hint, &addrs);
Packit Service b38f0b
#else /* DNSSEC_LOCAL_VALIDATION */
Packit Service b38f0b
    err = val_getaddrinfo(netsnmp_validator_context(), name, NULL, &hint,
Packit Service b38f0b
                          &addrs, &val_status);
Packit Service b38f0b
    DEBUGMSGTL(("dns:sec:val", "err %d, val_status %d / %s; trusted: %d\n",
Packit Service b38f0b
                err, val_status, p_val_status(val_status),
Packit Service b38f0b
                val_istrusted(val_status)));
Packit Service b38f0b
    if (! val_istrusted(val_status)) {
Packit Service b38f0b
        int rc;
Packit Service b38f0b
        if ((err != 0) && VAL_GETADDRINFO_HAS_STATUS(err)) {
Packit Service b38f0b
            snmp_log(LOG_WARNING,
Packit Service b38f0b
                     "WARNING: UNTRUSTED error in DNS resolution for %s!\n",
Packit Service b38f0b
                     name);
Packit Service b38f0b
            rc = EAI_FAIL;
Packit Service b38f0b
        } else {
Packit Service b38f0b
            snmp_log(LOG_WARNING,
Packit Service b38f0b
                     "The authenticity of DNS response is not trusted (%s)\n",
Packit Service b38f0b
                     p_val_status(val_status));
Packit Service b38f0b
            rc = EAI_NONAME;
Packit Service b38f0b
        }
Packit Service b38f0b
        /** continue anyways if DNSSEC_WARN_ONLY is set */
Packit Service b38f0b
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
Packit Service b38f0b
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
Packit Service b38f0b
            return rc;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
#endif /* DNSSEC_LOCAL_VALIDATION */
Packit Service b38f0b
    *res = addrs;
Packit Service b38f0b
    if ((0 == err) && addrs && addrs->ai_addr) {
Packit Service b38f0b
        DEBUGMSGTL(("dns:getaddrinfo", "answer { AF_INET, %s:%hu }\n",
Packit Service b38f0b
                    inet_ntoa(((struct sockaddr_in*)addrs->ai_addr)->sin_addr),
Packit Service b38f0b
                    ntohs(((struct sockaddr_in*)addrs->ai_addr)->sin_port)));
Packit Service b38f0b
    }
Packit Service b38f0b
    return err;
Packit Service b38f0b
#else
Packit Service b38f0b
    NETSNMP_LOGONCE((LOG_ERR, "getaddrinfo not available"));
Packit Service b38f0b
    return EAI_FAIL;
Packit Service b38f0b
#endif /* getaddrinfo */
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
struct hostent *
Packit Service b38f0b
netsnmp_gethostbyname(const char *name)
Packit Service b38f0b
{
Packit Service b38f0b
#if HAVE_GETHOSTBYNAME
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
    val_status_t val_status;
Packit Service b38f0b
#endif
Packit Service b38f0b
    struct hostent *hp = NULL;
Packit Service b38f0b
Packit Service b38f0b
    if (NULL == name)
Packit Service b38f0b
        return NULL;
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("dns:gethostbyname", "looking up %s\n", name));
Packit Service b38f0b
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
    hp  = val_gethostbyname(netsnmp_validator_context(), name, &val_status);
Packit Service b38f0b
    DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n",
Packit Service b38f0b
                val_status, p_val_status(val_status),
Packit Service b38f0b
                val_istrusted(val_status)));
Packit Service b38f0b
    if (!val_istrusted(val_status)) {
Packit Service b38f0b
        snmp_log(LOG_WARNING,
Packit Service b38f0b
                 "The authenticity of DNS response is not trusted (%s)\n",
Packit Service b38f0b
                 p_val_status(val_status));
Packit Service b38f0b
        /** continue anyways if DNSSEC_WARN_ONLY is set */
Packit Service b38f0b
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
Packit Service b38f0b
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
Packit Service b38f0b
            hp = NULL;
Packit Service b38f0b
    }
Packit Service b38f0b
    else if (val_does_not_exist(val_status) && hp)
Packit Service b38f0b
        hp = NULL;
Packit Service b38f0b
#else
Packit Service b38f0b
    hp = gethostbyname(name);
Packit Service b38f0b
#endif
Packit Service b38f0b
    if (hp == NULL) {
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyname",
Packit Service b38f0b
                    "couldn't resolve %s\n", name));
Packit Service b38f0b
    } else if (hp->h_addrtype != AF_INET
Packit Service b38f0b
#ifdef AF_INET6
Packit Service b38f0b
               && hp->h_addrtype != AF_INET6
Packit Service b38f0b
#endif
Packit Service b38f0b
        ) {
Packit Service b38f0b
#ifdef AF_INET6
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyname",
Packit Service b38f0b
                    "warning: response for %s not AF_INET/AF_INET6!\n", name));
Packit Service b38f0b
#else
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyname",
Packit Service b38f0b
                    "warning: response for %s not AF_INET!\n", name));
Packit Service b38f0b
#endif
Packit Service b38f0b
    } else {
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyname",
Packit Service b38f0b
                    "%s resolved okay\n", name));
Packit Service b38f0b
    }
Packit Service b38f0b
    return hp;
Packit Service b38f0b
#else
Packit Service b38f0b
    NETSNMP_LOGONCE((LOG_ERR, "gethostbyname not available"));
Packit Service b38f0b
    return NULL;
Packit Service b38f0b
#endif /* HAVE_GETHOSTBYNAME */
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/**
Packit Service b38f0b
 * Look up the host name via DNS.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @param[in] addr Pointer to the address to resolve. This argument points e.g.
Packit Service b38f0b
 *   to a struct in_addr for AF_INET or to a struct in6_addr for AF_INET6.
Packit Service b38f0b
 * @param[in] len  Length in bytes of *addr.
Packit Service b38f0b
 * @param[in] type Address family, e.g. AF_INET or AF_INET6.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @return Pointer to a hostent structure if address lookup succeeded or NULL
Packit Service b38f0b
 *   if the lookup failed.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @see See also the gethostbyaddr() man page.
Packit Service b38f0b
 */
Packit Service b38f0b
struct hostent *
Packit Service b38f0b
netsnmp_gethostbyaddr(const void *addr, socklen_t len, int type)
Packit Service b38f0b
{
Packit Service b38f0b
#if HAVE_GETHOSTBYADDR
Packit Service b38f0b
    struct hostent *hp = NULL;
Packit Service b38f0b
    char buf[64];
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("dns:gethostbyaddr", "resolving %s\n",
Packit Service b38f0b
                inet_ntop(type, addr, buf, sizeof(buf))));
Packit Service b38f0b
Packit Service b38f0b
#ifdef DNSSEC_LOCAL_VALIDATION
Packit Service b38f0b
    val_status_t val_status;
Packit Service b38f0b
    hp = val_gethostbyaddr(netsnmp_validator_context(), addr, len, type,
Packit Service b38f0b
                           &val_status);
Packit Service b38f0b
    DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n",
Packit Service b38f0b
                val_status, p_val_status(val_status),
Packit Service b38f0b
                val_istrusted(val_status)));
Packit Service b38f0b
    if (!val_istrusted(val_status)) {
Packit Service b38f0b
        snmp_log(LOG_WARNING,
Packit Service b38f0b
                 "The authenticity of DNS response is not trusted (%s)\n",
Packit Service b38f0b
                 p_val_status(val_status));
Packit Service b38f0b
        /** continue anyways if DNSSEC_WARN_ONLY is set */
Packit Service b38f0b
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
Packit Service b38f0b
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
Packit Service b38f0b
            hp = NULL;
Packit Service b38f0b
    }
Packit Service b38f0b
    else if (val_does_not_exist(val_status) && hp)
Packit Service b38f0b
        hp = NULL;
Packit Service b38f0b
#else
Packit Service b38f0b
    hp = gethostbyaddr(addr, len, type);
Packit Service b38f0b
#endif
Packit Service b38f0b
    if (hp == NULL) {
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyaddr", "couldn't resolve addr\n"));
Packit Service b38f0b
    } else if (hp->h_addrtype != AF_INET) {
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyaddr",
Packit Service b38f0b
                    "warning: response for addr not AF_INET!\n"));
Packit Service b38f0b
    } else {
Packit Service b38f0b
        DEBUGMSGTL(("dns:gethostbyaddr", "addr resolved okay\n"));
Packit Service b38f0b
    }
Packit Service b38f0b
    return hp;
Packit Service b38f0b
#else
Packit Service b38f0b
    NETSNMP_LOGONCE((LOG_ERR, "gethostbyaddr not available"));
Packit Service b38f0b
    return NULL;
Packit Service b38f0b
#endif
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************/
Packit Service b38f0b
Packit Service b38f0b
#ifndef HAVE_STRNCASECMP
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * test for NULL pointers before and NULL characters after
Packit Service b38f0b
 * * comparing possibly non-NULL strings.
Packit Service b38f0b
 * * WARNING: This function does NOT check for array overflow.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
strncasecmp(const char *s1, const char *s2, size_t nch)
Packit Service b38f0b
{
Packit Service b38f0b
    size_t          ii;
Packit Service b38f0b
    int             res = -1;
Packit Service b38f0b
Packit Service b38f0b
    if (!s1) {
Packit Service b38f0b
        if (!s2)
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        return (-1);
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!s2)
Packit Service b38f0b
        return (1);
Packit Service b38f0b
Packit Service b38f0b
    for (ii = 0; (ii < nch) && *s1 && *s2; ii++, s1++, s2++) {
Packit Service b38f0b
        res = (int) (tolower(*s1) - tolower(*s2));
Packit Service b38f0b
        if (res != 0)
Packit Service b38f0b
            break;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (ii == nch) {
Packit Service b38f0b
        s1--;
Packit Service b38f0b
        s2--;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (!*s1) {
Packit Service b38f0b
        if (!*s2)
Packit Service b38f0b
            return 0;
Packit Service b38f0b
        return (-1);
Packit Service b38f0b
    }
Packit Service b38f0b
    if (!*s2)
Packit Service b38f0b
        return (1);
Packit Service b38f0b
Packit Service b38f0b
    return (res);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
strcasecmp(const char *s1, const char *s2)
Packit Service b38f0b
{
Packit Service b38f0b
    return strncasecmp(s1, s2, 1000000);
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
#endif                          /* HAVE_STRNCASECMP */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
#ifndef HAVE_STRDUP
Packit Service b38f0b
char           *
Packit Service b38f0b
strdup(const char *src)
Packit Service b38f0b
{
Packit Service b38f0b
    int             len;
Packit Service b38f0b
    char           *dst;
Packit Service b38f0b
Packit Service b38f0b
    len = strlen(src) + 1;
Packit Service b38f0b
    if ((dst = (char *) malloc(len)) == NULL)
Packit Service b38f0b
        return (NULL);
Packit Service b38f0b
    strcpy(dst, src);
Packit Service b38f0b
    return (dst);
Packit Service b38f0b
}
Packit Service b38f0b
#endif                          /* HAVE_STRDUP */
Packit Service b38f0b
Packit Service b38f0b
#ifndef HAVE_SETENV
Packit Service b38f0b
int
Packit Service b38f0b
setenv(const char *name, const char *value, int overwrite)
Packit Service b38f0b
{
Packit Service b38f0b
    char           *cp;
Packit Service b38f0b
    int             ret;
Packit Service b38f0b
Packit Service b38f0b
    if (overwrite == 0) {
Packit Service b38f0b
        if (getenv(name))
Packit Service b38f0b
            return 0;
Packit Service b38f0b
    }
Packit Service b38f0b
    cp = (char *) malloc(strlen(name) + strlen(value) + 2);
Packit Service b38f0b
    if (cp == NULL)
Packit Service b38f0b
        return -1;
Packit Service b38f0b
    sprintf(cp, "%s=%s", name, value);
Packit Service b38f0b
    ret = putenv(cp);
Packit Service b38f0b
#ifdef WIN32
Packit Service b38f0b
    free(cp);
Packit Service b38f0b
#endif
Packit Service b38f0b
    return ret;
Packit Service b38f0b
}
Packit Service b38f0b
#endif                          /* HAVE_SETENV */
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(calculate_time_diff, netsnmp_unused)
Packit Service b38f0b
#ifndef NETSNMP_FEATURE_REMOVE_CALCULATE_TIME_DIFF
Packit Service b38f0b
/**
Packit Service b38f0b
 * Compute (*now - *then) in centiseconds.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
calculate_time_diff(const struct timeval *now, const struct timeval *then)
Packit Service b38f0b
{
Packit Service b38f0b
    struct timeval  diff;
Packit Service b38f0b
Packit Service b38f0b
    NETSNMP_TIMERSUB(now, then, &diff);
Packit Service b38f0b
    return (int)(diff.tv_sec * 100 + diff.tv_usec / 10000);
Packit Service b38f0b
}
Packit Service b38f0b
#endif /* NETSNMP_FEATURE_REMOVE_CALCULATE_TIME_DIFF */
Packit Service b38f0b
Packit Service b38f0b
#ifndef NETSNMP_FEATURE_REMOVE_CALCULATE_SECTIME_DIFF
Packit Service b38f0b
/** Compute rounded (*now - *then) in seconds. */
Packit Service b38f0b
u_int
Packit Service b38f0b
calculate_sectime_diff(const struct timeval *now, const struct timeval *then)
Packit Service b38f0b
{
Packit Service b38f0b
    struct timeval  diff;
Packit Service b38f0b
Packit Service b38f0b
    NETSNMP_TIMERSUB(now, then, &diff);
Packit Service b38f0b
    return (u_int)(diff.tv_sec + (diff.tv_usec >= 500000L));
Packit Service b38f0b
}
Packit Service b38f0b
#endif /* NETSNMP_FEATURE_REMOVE_CALCULATE_SECTIME_DIFF */
Packit Service b38f0b
Packit Service b38f0b
#ifndef HAVE_STRCASESTR
Packit Service b38f0b
/*
Packit Service b38f0b
 * only glibc2 has this.
Packit Service b38f0b
 */
Packit Service b38f0b
char           *
Packit Service b38f0b
strcasestr(const char *haystack, const char *needle)
Packit Service b38f0b
{
Packit Service b38f0b
    const char     *cp1 = haystack, *cp2 = needle;
Packit Service b38f0b
    const char     *cx;
Packit Service b38f0b
    int             tstch1, tstch2;
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * printf("looking for '%s' in '%s'\n", needle, haystack); 
Packit Service b38f0b
     */
Packit Service b38f0b
    if (cp1 && cp2 && *cp1 && *cp2)
Packit Service b38f0b
        for (cp1 = haystack, cp2 = needle; *cp1;) {
Packit Service b38f0b
            cx = cp1;
Packit Service b38f0b
            cp2 = needle;
Packit Service b38f0b
            do {
Packit Service b38f0b
                /*
Packit Service b38f0b
                 * printf("T'%c' ", *cp1); 
Packit Service b38f0b
                 */
Packit Service b38f0b
                if (!*cp2) {    /* found the needle */
Packit Service b38f0b
                    /*
Packit Service b38f0b
                     * printf("\nfound '%s' in '%s'\n", needle, cx); 
Packit Service b38f0b
                     */
Packit Service b38f0b
                    return NETSNMP_REMOVE_CONST(char *, cx);
Packit Service b38f0b
                }
Packit Service b38f0b
                if (!*cp1)
Packit Service b38f0b
                    break;
Packit Service b38f0b
Packit Service b38f0b
                tstch1 = toupper(*cp1);
Packit Service b38f0b
                tstch2 = toupper(*cp2);
Packit Service b38f0b
                if (tstch1 != tstch2)
Packit Service b38f0b
                    break;
Packit Service b38f0b
                /*
Packit Service b38f0b
                 * printf("M'%c' ", *cp1); 
Packit Service b38f0b
                 */
Packit Service b38f0b
                cp1++;
Packit Service b38f0b
                cp2++;
Packit Service b38f0b
            }
Packit Service b38f0b
            while (1);
Packit Service b38f0b
            if (*cp1)
Packit Service b38f0b
                cp1++;
Packit Service b38f0b
        }
Packit Service b38f0b
    /*
Packit Service b38f0b
     * printf("\n"); 
Packit Service b38f0b
     */
Packit Service b38f0b
    if (cp1 && *cp1)
Packit Service b38f0b
        return NETSNMP_REMOVE_CONST(char *, cp1);
Packit Service b38f0b
Packit Service b38f0b
    return NULL;
Packit Service b38f0b
}
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
int
Packit Service b38f0b
mkdirhier(const char *pathname, mode_t mode, int skiplast)
Packit Service b38f0b
{
Packit Service b38f0b
    struct stat     sbuf;
Packit Service b38f0b
    char           *ourcopy = strdup(pathname);
Packit Service b38f0b
    char           *entry;
Packit Service b38f0b
    char           *buf = NULL;
Packit Service b38f0b
    char           *st = NULL;
Packit Service b38f0b
    int             res;
Packit Service b38f0b
Packit Service b38f0b
    res = SNMPERR_GENERR;
Packit Service b38f0b
    if (!ourcopy)
Packit Service b38f0b
        goto out;
Packit Service b38f0b
Packit Service b38f0b
    buf = malloc(strlen(pathname) + 2);
Packit Service b38f0b
    if (!buf)
Packit Service b38f0b
        goto out;
Packit Service b38f0b
Packit Service b38f0b
#if defined (WIN32) || defined (cygwin)
Packit Service b38f0b
    /* convert backslash to forward slash */
Packit Service b38f0b
    for (entry = ourcopy; *entry; entry++)
Packit Service b38f0b
        if (*entry == '\\')
Packit Service b38f0b
            *entry = '/';
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    entry = strtok_r(ourcopy, "/", &st);
Packit Service b38f0b
Packit Service b38f0b
    buf[0] = '\0';
Packit Service b38f0b
Packit Service b38f0b
#if defined (WIN32) || defined (cygwin)
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Check if first entry contains a drive-letter
Packit Service b38f0b
     *   e.g  "c:/path"
Packit Service b38f0b
     */
Packit Service b38f0b
    if ((entry) && (':' == entry[1]) &&
Packit Service b38f0b
        (('\0' == entry[2]) || ('/' == entry[2]))) {
Packit Service b38f0b
        strcat(buf, entry);
Packit Service b38f0b
        entry = strtok_r(NULL, "/", &st);
Packit Service b38f0b
    }
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * check to see if filename is a directory 
Packit Service b38f0b
     */
Packit Service b38f0b
    while (entry) {
Packit Service b38f0b
        strcat(buf, "/");
Packit Service b38f0b
        strcat(buf, entry);
Packit Service b38f0b
        entry = strtok_r(NULL, "/", &st);
Packit Service b38f0b
        if (entry == NULL && skiplast)
Packit Service b38f0b
            break;
Packit Service b38f0b
        if (stat(buf, &sbuf) < 0) {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * DNE, make it 
Packit Service b38f0b
             */
Packit Service b38f0b
#ifdef WIN32
Packit Service b38f0b
            if (CreateDirectory(buf, NULL) == 0)
Packit Service b38f0b
#else
Packit Service b38f0b
            if (mkdir(buf, mode) == -1)
Packit Service b38f0b
#endif
Packit Service b38f0b
                goto out;
Packit Service b38f0b
            else
Packit Service b38f0b
                snmp_log(LOG_INFO, "Created directory: %s\n", buf);
Packit Service b38f0b
        } else {
Packit Service b38f0b
            /*
Packit Service b38f0b
             * exists, is it a file? 
Packit Service b38f0b
             */
Packit Service b38f0b
            if ((sbuf.st_mode & S_IFDIR) == 0) {
Packit Service b38f0b
                /*
Packit Service b38f0b
                 * ack! can't make a directory on top of a file 
Packit Service b38f0b
                 */
Packit Service b38f0b
                goto out;
Packit Service b38f0b
            }
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
    res = SNMPERR_SUCCESS;
Packit Service b38f0b
out:
Packit Service b38f0b
    free(buf);
Packit Service b38f0b
    free(ourcopy);
Packit Service b38f0b
    return res;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/**
Packit Service b38f0b
 * netsnmp_mktemp creates a temporary file based on the
Packit Service b38f0b
 *                 configured tempFilePattern
Packit Service b38f0b
 *
Packit Service b38f0b
 * @return file descriptor
Packit Service b38f0b
 */
Packit Service b38f0b
const char     *
Packit Service b38f0b
netsnmp_mktemp(void)
Packit Service b38f0b
{
Packit Service b38f0b
#ifdef PATH_MAX
Packit Service b38f0b
    static char     name[PATH_MAX];
Packit Service b38f0b
#else
Packit Service b38f0b
    static char     name[256];
Packit Service b38f0b
#endif
Packit Service b38f0b
    int             fd = -1;
Packit Service b38f0b
Packit Service b38f0b
    strlcpy(name, get_temp_file_pattern(), sizeof(name));
Packit Service b38f0b
#ifdef HAVE_MKSTEMP
Packit Service b38f0b
    {
Packit Service b38f0b
        mode_t oldmask = umask(~(S_IRUSR | S_IWUSR));
Packit Service b38f0b
        netsnmp_assert(oldmask != (mode_t)(-1));
Packit Service b38f0b
        fd = mkstemp(name);
Packit Service b38f0b
        umask(oldmask);
Packit Service b38f0b
    }
Packit Service b38f0b
#else
Packit Service b38f0b
    if (mktemp(name)) {
Packit Service b38f0b
# ifndef WIN32
Packit Service b38f0b
        fd = open(name, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
Packit Service b38f0b
# else
Packit Service b38f0b
        /*
Packit Service b38f0b
         * Win32 needs _S_IREAD | _S_IWRITE to set permissions on file
Packit Service b38f0b
         * after closing
Packit Service b38f0b
         */
Packit Service b38f0b
        fd = _open(name, _O_CREAT | _O_EXCL | _O_WRONLY, _S_IREAD | _S_IWRITE);
Packit Service b38f0b
# endif
Packit Service b38f0b
    }
Packit Service b38f0b
#endif
Packit Service b38f0b
    if (fd >= 0) {
Packit Service b38f0b
        close(fd);
Packit Service b38f0b
        DEBUGMSGTL(("netsnmp_mktemp", "temp file created: %s\n",
Packit Service b38f0b
                    name));
Packit Service b38f0b
        return name;
Packit Service b38f0b
    }
Packit Service b38f0b
    snmp_log(LOG_ERR, "netsnmp_mktemp: error creating file %s\n",
Packit Service b38f0b
             name);
Packit Service b38f0b
    return NULL;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * This function was created to differentiate actions
Packit Service b38f0b
 * that are appropriate for Linux 2.4 kernels, but not later kernels.
Packit Service b38f0b
 *
Packit Service b38f0b
 * This function can be used to test kernels on any platform that supports uname().
Packit Service b38f0b
 *
Packit Service b38f0b
 * If not running a platform that supports uname(), return -1.
Packit Service b38f0b
 *
Packit Service b38f0b
 * If ospname matches, and the release matches up through the prefix,
Packit Service b38f0b
 *  return 0.
Packit Service b38f0b
 * If the release is ordered higher, return 1.
Packit Service b38f0b
 * Be aware that "ordered higher" is not a guarantee of correctness.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
netsnmp_os_prematch(const char *ospmname,
Packit Service b38f0b
                    const char *ospmrelprefix)
Packit Service b38f0b
{
Packit Service b38f0b
#if HAVE_SYS_UTSNAME_H
Packit Service b38f0b
  static int printOSonce = 1;
Packit Service b38f0b
  struct utsname utsbuf;
Packit Service b38f0b
  if ( 0 > uname(&utsbuf))
Packit Service b38f0b
    return -1;
Packit Service b38f0b
Packit Service b38f0b
  if (printOSonce) {
Packit Service b38f0b
    printOSonce = 0;
Packit Service b38f0b
    /* show the four elements that the kernel can be sure of */
Packit Service b38f0b
  DEBUGMSGT(("daemonize","sysname '%s',\nrelease '%s',\nversion '%s',\nmachine '%s'\n",
Packit Service b38f0b
      utsbuf.sysname, utsbuf.release, utsbuf.version, utsbuf.machine));
Packit Service b38f0b
  }
Packit Service b38f0b
  if (0 != strcasecmp(utsbuf.sysname, ospmname)) return -1;
Packit Service b38f0b
Packit Service b38f0b
  /* Required to match only the leading characters */
Packit Service b38f0b
  return strncasecmp(utsbuf.release, ospmrelprefix, strlen(ospmrelprefix));
Packit Service b38f0b
Packit Service b38f0b
#else
Packit Service b38f0b
Packit Service b38f0b
  return -1;
Packit Service b38f0b
Packit Service b38f0b
#endif /* HAVE_SYS_UTSNAME_H */
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/**
Packit Service b38f0b
 * netsnmp_os_kernel_width determines kernel width at runtime
Packit Service b38f0b
 * Currently implemented for IRIX, AIX and Tru64 Unix
Packit Service b38f0b
 *
Packit Service b38f0b
 * @return kernel width (usually 32 or 64) on success, -1 on error
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
netsnmp_os_kernel_width(void)
Packit Service b38f0b
{
Packit Service b38f0b
#ifdef irix6
Packit Service b38f0b
  char buf[8];
Packit Service b38f0b
  sysinfo(_MIPS_SI_OS_NAME, buf, 7);
Packit Service b38f0b
  if (strncmp("IRIX64", buf, 6) == 0) {
Packit Service b38f0b
    return 64;
Packit Service b38f0b
  } else if (strncmp("IRIX", buf, 4) == 0) {
Packit Service b38f0b
    return 32;
Packit Service b38f0b
  } else {
Packit Service b38f0b
    return -1;
Packit Service b38f0b
  }
Packit Service b38f0b
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
Packit Service b38f0b
  return (__KERNEL_32() ? 32 : (__KERNEL_64() ? 64 : -1));
Packit Service b38f0b
#elif defined(osf4) || defined(osf5) || defined(__alpha)
Packit Service b38f0b
  return 64; /* Alpha is always 64bit */
Packit Service b38f0b
#else
Packit Service b38f0b
  /* kernel width detection not implemented */
Packit Service b38f0b
  return -1;
Packit Service b38f0b
#endif
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(str_to_uid, user_information)
Packit Service b38f0b
#ifndef NETSNMP_FEATURE_REMOVE_STR_TO_UID
Packit Service b38f0b
/**
Packit Service b38f0b
 * Convert a user name or number into numeric form.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @param[in] useroruid Either a Unix user name or the ASCII representation
Packit Service b38f0b
 *   of a user number.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @return Either a user number > 0 or 0 if useroruid is not a valid user
Packit Service b38f0b
 *   name, not a valid user number or the name of the root user.
Packit Service b38f0b
 */
Packit Service b38f0b
int netsnmp_str_to_uid(const char *useroruid) {
Packit Service b38f0b
    int uid;
Packit Service b38f0b
#if HAVE_GETPWNAM && HAVE_PWD_H
Packit Service b38f0b
    struct passwd *pwd;
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    uid = atoi(useroruid);
Packit Service b38f0b
Packit Service b38f0b
    if (uid == 0) {
Packit Service b38f0b
#if HAVE_GETPWNAM && HAVE_PWD_H
Packit Service b38f0b
        pwd = getpwnam(useroruid);
Packit Service b38f0b
        uid = pwd ? pwd->pw_uid : 0;
Packit Service b38f0b
        endpwent();
Packit Service b38f0b
#endif
Packit Service b38f0b
        if (uid == 0)
Packit Service b38f0b
            snmp_log(LOG_WARNING, "Can't identify user (%s).\n", useroruid);
Packit Service b38f0b
    }
Packit Service b38f0b
    return uid;
Packit Service b38f0b
    
Packit Service b38f0b
}
Packit Service b38f0b
#endif /* NETSNMP_FEATURE_REMOVE_STR_TO_UID */
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(str_to_gid, user_information)
Packit Service b38f0b
#ifndef NETSNMP_FEATURE_REMOVE_STR_TO_GID
Packit Service b38f0b
/**
Packit Service b38f0b
 * Convert a group name or number into numeric form.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @param[in] grouporgid Either a Unix group name or the ASCII representation
Packit Service b38f0b
 *   of a group number.
Packit Service b38f0b
 *
Packit Service b38f0b
 * @return Either a group number > 0 or 0 if grouporgid is not a valid group
Packit Service b38f0b
 *   name, not a valid group number or the root group.
Packit Service b38f0b
 */
Packit Service b38f0b
int netsnmp_str_to_gid(const char *grouporgid)
Packit Service b38f0b
{
Packit Service b38f0b
    int gid;
Packit Service b38f0b
Packit Service b38f0b
    gid = atoi(grouporgid);
Packit Service b38f0b
Packit Service b38f0b
    if (gid == 0) {
Packit Service b38f0b
#if HAVE_GETGRNAM && HAVE_GRP_H
Packit Service b38f0b
        struct group  *grp;
Packit Service b38f0b
Packit Service b38f0b
        grp = getgrnam(grouporgid);
Packit Service b38f0b
        gid = grp ? grp->gr_gid : 0;
Packit Service b38f0b
        endgrent();
Packit Service b38f0b
#endif
Packit Service b38f0b
        if (gid == 0)
Packit Service b38f0b
            snmp_log(LOG_WARNING, "Can't identify group (%s).\n", grouporgid);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    return gid;
Packit Service b38f0b
}
Packit Service b38f0b
#endif /* NETSNMP_FEATURE_REMOVE_STR_TO_GID */