move string format utils to sigar_format.[ch]
This commit is contained in:
		
							parent
							
								
									6e51d8ac7b
								
							
						
					
					
						commit
						f037037b0a
					
				@ -24,6 +24,7 @@
 | 
			
		||||
#include "sigar_ptql.h"
 | 
			
		||||
#include "sigar_util.h"
 | 
			
		||||
#include "sigar_os.h"
 | 
			
		||||
#include "sigar_format.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -190,13 +190,6 @@ typedef struct {
 | 
			
		||||
SIGAR_DECLARE(int) sigar_uptime_get(sigar_t *sigar,
 | 
			
		||||
                                    sigar_uptime_t *uptime);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int) sigar_uptime_string(sigar_t *sigar, 
 | 
			
		||||
                                       sigar_uptime_t *uptime,
 | 
			
		||||
                                       char *buffer,
 | 
			
		||||
                                       int buflen);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_format_size(sigar_uint64_t size, char *buf);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    double loadavg[3];
 | 
			
		||||
} sigar_loadavg_t;
 | 
			
		||||
@ -706,10 +699,6 @@ sigar_net_listen_address_get(sigar_t *sigar,
 | 
			
		||||
                             unsigned long port,
 | 
			
		||||
                             sigar_net_address_t *address);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    char user[32];
 | 
			
		||||
    char device[32];
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								include/sigar_format.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/sigar_format.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 | 
			
		||||
 * This file is part of SIGAR.
 | 
			
		||||
 * 
 | 
			
		||||
 * SIGAR is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation. This program is distributed
 | 
			
		||||
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 | 
			
		||||
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
			
		||||
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
			
		||||
 * details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
			
		||||
 * USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SIGAR_FORMAT_H
 | 
			
		||||
#define SIGAR_FORMAT_H
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int) sigar_uptime_string(sigar_t *sigar, 
 | 
			
		||||
                                       sigar_uptime_t *uptime,
 | 
			
		||||
                                       char *buffer,
 | 
			
		||||
                                       int buflen);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_format_size(sigar_uint64_t size, char *buf);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type);
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										305
									
								
								src/sigar.c
									
									
									
									
									
								
							
							
						
						
									
										305
									
								
								src/sigar.c
									
									
									
									
									
								
							@ -184,174 +184,6 @@ SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar,
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *sigar_error_string(int err)
 | 
			
		||||
{
 | 
			
		||||
    switch (err) {
 | 
			
		||||
      case SIGAR_ENOTIMPL:
 | 
			
		||||
        return "This function has not been implemented on this platform";
 | 
			
		||||
      default:
 | 
			
		||||
        return "Error string not specified yet";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_strerror(sigar_t *sigar, int err)
 | 
			
		||||
{
 | 
			
		||||
    char *buf;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        return sigar->errbuf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (err > SIGAR_OS_START_ERROR) {
 | 
			
		||||
        if ((buf = sigar_os_error_string(sigar, err)) != NULL) {
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
        return "Unknown OS Error"; /* should never happen */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (err > SIGAR_START_ERROR) {
 | 
			
		||||
        return sigar_error_string(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return sigar_strerror_get(err, sigar->errbuf, sizeof(sigar->errbuf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *sigar_strerror_get(int err, char *errbuf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    char *buf = NULL;
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    DWORD len;
 | 
			
		||||
 | 
			
		||||
    len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
 | 
			
		||||
                        FORMAT_MESSAGE_IGNORE_INSERTS,
 | 
			
		||||
                        NULL,
 | 
			
		||||
                        err,
 | 
			
		||||
                        0, /* default language */
 | 
			
		||||
                        (LPTSTR)errbuf,
 | 
			
		||||
                        (DWORD)buflen,
 | 
			
		||||
                        NULL);
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_STRERROR_R) && defined(HAVE_STRERROR_R_GLIBC)
 | 
			
		||||
    /*
 | 
			
		||||
     * strerror_r man page says:
 | 
			
		||||
     * "The GNU version may, but need not, use the user supplied buffer"
 | 
			
		||||
     */
 | 
			
		||||
    buf = strerror_r(err, errbuf, buflen);
 | 
			
		||||
#elif defined(HAVE_STRERROR_R)
 | 
			
		||||
    if (strerror_r(err, errbuf, buflen) < 0) {
 | 
			
		||||
        buf = "Unknown Error";
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    /* strerror() is thread safe on solaris and hpux */
 | 
			
		||||
    buf = strerror(err);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (buf != NULL) {
 | 
			
		||||
        SIGAR_STRNCPY(errbuf, buf, buflen);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
#endif
 | 
			
		||||
    return errbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sigar_strerror_set(sigar_t *sigar, char *msg)
 | 
			
		||||
{
 | 
			
		||||
    SIGAR_SSTRCPY(sigar->errbuf, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#define vsnprintf _vsnprintf
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void sigar_strerror_printf(sigar_t *sigar, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    vsnprintf(sigar->errbuf, sizeof(sigar->errbuf), format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int) sigar_uptime_string(sigar_t *sigar, 
 | 
			
		||||
                                       sigar_uptime_t *uptime,
 | 
			
		||||
                                       char *buffer,
 | 
			
		||||
                                       int buflen)
 | 
			
		||||
{
 | 
			
		||||
    char *ptr = buffer;
 | 
			
		||||
    int time = (int)uptime->uptime;
 | 
			
		||||
    int minutes, hours, days, offset = 0;
 | 
			
		||||
 | 
			
		||||
    /* XXX: get rid of sprintf and/or check for overflow */
 | 
			
		||||
    days = time / (60*60*24);
 | 
			
		||||
 | 
			
		||||
    if (days) {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%d day%s, ",
 | 
			
		||||
                          days, (days > 1) ? "s" : "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    minutes = time / 60;
 | 
			
		||||
    hours = minutes / 60;
 | 
			
		||||
    hours = hours % 24;
 | 
			
		||||
    minutes = minutes % 60;
 | 
			
		||||
 | 
			
		||||
    if (hours) {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%2d:%02d",
 | 
			
		||||
                          hours, minutes);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%d min", minutes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* copy apr_strfsize */
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_format_size(sigar_uint64_t size, char *buf)
 | 
			
		||||
{
 | 
			
		||||
    const char ord[] = "KMGTPE";
 | 
			
		||||
    const char *o = ord;
 | 
			
		||||
    int remain;
 | 
			
		||||
 | 
			
		||||
    if (size == SIGAR_FIELD_NOTIMPL) {
 | 
			
		||||
        buf[0] = '-';
 | 
			
		||||
        buf[1] = '\0';
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (size < 973) {
 | 
			
		||||
        sprintf(buf, "%3d ", (int) size);
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        remain = (int)(size & 1023);
 | 
			
		||||
        size >>= 10;
 | 
			
		||||
 | 
			
		||||
        if (size >= 973) {
 | 
			
		||||
            ++o;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (size < 9 || (size == 9 && remain < 973)) {
 | 
			
		||||
            if ((remain = ((remain * 5) + 256) / 512) >= 10) {
 | 
			
		||||
                ++size;
 | 
			
		||||
                remain = 0;
 | 
			
		||||
            }
 | 
			
		||||
            sprintf(buf, "%d.%d%c", (int) size, remain, *o);
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (remain >= 512) {
 | 
			
		||||
            ++size;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sprintf(buf, "%3d%c", (int) size, *o);
 | 
			
		||||
 | 
			
		||||
        return buf;
 | 
			
		||||
    } while (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int) sigar_sys_info_get(sigar_t *sigar,
 | 
			
		||||
                                      sigar_sys_info_t *sysinfo)
 | 
			
		||||
{
 | 
			
		||||
@ -386,92 +218,6 @@ int sigar_sys_info_get_uname(sigar_sys_info_t *sysinfo)
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
 | 
			
		||||
int sigar_user_name_get(sigar_t *sigar, int uid, char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct passwd *pw = NULL;
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETPWUID_R
 | 
			
		||||
    struct passwd pwbuf;
 | 
			
		||||
    char buffer[512];
 | 
			
		||||
 | 
			
		||||
    if (getpwuid_r(uid, &pwbuf, buffer, sizeof(buffer), &pw) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
    if (!pw) {
 | 
			
		||||
        return ENOENT;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if ((pw = getpwuid(uid)) == NULL) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    strncpy(buf, pw->pw_name, buflen);
 | 
			
		||||
    buf[buflen-1] = '\0';
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sigar_group_name_get(sigar_t *sigar, int gid, char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct group *gr;
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETGRGID_R
 | 
			
		||||
    struct group grbuf;
 | 
			
		||||
    char buffer[512];
 | 
			
		||||
 | 
			
		||||
    if (getgrgid_r(gid, &grbuf, buffer, sizeof(buffer), &gr) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if ((gr = getgrgid(gid)) == NULL) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    if (gr && gr->gr_name) {
 | 
			
		||||
        strncpy(buf, gr->gr_name, buflen);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        /* seen on linux.. apache httpd.conf has:
 | 
			
		||||
         * Group #-1
 | 
			
		||||
         * results in uid == -1 and gr == NULL.
 | 
			
		||||
         * wtf getgrgid_r doesnt fail instead? 
 | 
			
		||||
         */
 | 
			
		||||
        sprintf(buf, "%d", gid);
 | 
			
		||||
    }
 | 
			
		||||
    buf[buflen-1] = '\0';
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sigar_user_id_get(sigar_t *sigar, const char *name, int *uid)
 | 
			
		||||
{
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
    struct passwd *pw;
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETPWNAM_R
 | 
			
		||||
    struct passwd pwbuf;
 | 
			
		||||
    char buf[512];
 | 
			
		||||
 | 
			
		||||
    if (getpwnam_r(name, &pwbuf, buf, sizeof(buf), &pw) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if (!(pw = getpwnam(name))) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    *uid = (int)pw->pw_uid;
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int)
 | 
			
		||||
sigar_proc_cred_name_get(sigar_t *sigar, sigar_pid_t pid,
 | 
			
		||||
                         sigar_proc_cred_name_t *proccredname)
 | 
			
		||||
@ -882,57 +628,6 @@ sigar_net_connection_list_destroy(sigar_t *sigar,
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type)
 | 
			
		||||
{
 | 
			
		||||
    switch (type) {
 | 
			
		||||
      case SIGAR_NETCONN_TCP:
 | 
			
		||||
        return "tcp";
 | 
			
		||||
      case SIGAR_NETCONN_UDP:
 | 
			
		||||
        return "udp";
 | 
			
		||||
      case SIGAR_NETCONN_RAW:
 | 
			
		||||
        return "raw";
 | 
			
		||||
      case SIGAR_NETCONN_UNIX:
 | 
			
		||||
        return "unix";
 | 
			
		||||
      default:
 | 
			
		||||
        return "unknown";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state)
 | 
			
		||||
{
 | 
			
		||||
    switch (state) {
 | 
			
		||||
      case SIGAR_TCP_ESTABLISHED:
 | 
			
		||||
        return "ESTABLISHED";
 | 
			
		||||
      case SIGAR_TCP_SYN_SENT:
 | 
			
		||||
        return "SYN_SENT";
 | 
			
		||||
      case SIGAR_TCP_SYN_RECV:
 | 
			
		||||
        return "SYN_RECV";
 | 
			
		||||
      case SIGAR_TCP_FIN_WAIT1:
 | 
			
		||||
        return "FIN_WAIT1";
 | 
			
		||||
      case SIGAR_TCP_FIN_WAIT2:
 | 
			
		||||
        return "FIN_WAIT2";
 | 
			
		||||
      case SIGAR_TCP_TIME_WAIT:
 | 
			
		||||
        return "TIME_WAIT";
 | 
			
		||||
      case SIGAR_TCP_CLOSE:
 | 
			
		||||
        return "CLOSE";
 | 
			
		||||
      case SIGAR_TCP_CLOSE_WAIT:
 | 
			
		||||
        return "CLOSE_WAIT";
 | 
			
		||||
      case SIGAR_TCP_LAST_ACK:
 | 
			
		||||
        return "LAST_ACK";
 | 
			
		||||
      case SIGAR_TCP_LISTEN:
 | 
			
		||||
        return "LISTEN";
 | 
			
		||||
      case SIGAR_TCP_CLOSING:
 | 
			
		||||
        return "CLOSING";
 | 
			
		||||
      case SIGAR_TCP_IDLE:
 | 
			
		||||
        return "IDLE";
 | 
			
		||||
      case SIGAR_TCP_BOUND:
 | 
			
		||||
        return "BOUND";
 | 
			
		||||
      case SIGAR_TCP_UNKNOWN:
 | 
			
		||||
      default:
 | 
			
		||||
        return "UNKNOWN";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(__linux__)
 | 
			
		||||
/* 
 | 
			
		||||
 * implement sigar_net_connection_list_get using sigar_net_connection_walk
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										334
									
								
								src/sigar_format.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								src/sigar_format.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,334 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 | 
			
		||||
 * This file is part of SIGAR.
 | 
			
		||||
 * 
 | 
			
		||||
 * SIGAR is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation. This program is distributed
 | 
			
		||||
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 | 
			
		||||
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
			
		||||
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
			
		||||
 * details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
			
		||||
 * USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Utility functions to provide string formatting of SIGAR data */
 | 
			
		||||
 | 
			
		||||
#include "sigar.h"
 | 
			
		||||
#include "sigar_private.h"
 | 
			
		||||
#include "sigar_util.h"
 | 
			
		||||
#include "sigar_os.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
int sigar_user_name_get(sigar_t *sigar, int uid, char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct passwd *pw = NULL;
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETPWUID_R
 | 
			
		||||
    struct passwd pwbuf;
 | 
			
		||||
    char buffer[512];
 | 
			
		||||
 | 
			
		||||
    if (getpwuid_r(uid, &pwbuf, buffer, sizeof(buffer), &pw) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
    if (!pw) {
 | 
			
		||||
        return ENOENT;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if ((pw = getpwuid(uid)) == NULL) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    strncpy(buf, pw->pw_name, buflen);
 | 
			
		||||
    buf[buflen-1] = '\0';
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sigar_group_name_get(sigar_t *sigar, int gid, char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct group *gr;
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETGRGID_R
 | 
			
		||||
    struct group grbuf;
 | 
			
		||||
    char buffer[512];
 | 
			
		||||
 | 
			
		||||
    if (getgrgid_r(gid, &grbuf, buffer, sizeof(buffer), &gr) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if ((gr = getgrgid(gid)) == NULL) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    if (gr && gr->gr_name) {
 | 
			
		||||
        strncpy(buf, gr->gr_name, buflen);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        /* seen on linux.. apache httpd.conf has:
 | 
			
		||||
         * Group #-1
 | 
			
		||||
         * results in uid == -1 and gr == NULL.
 | 
			
		||||
         * wtf getgrgid_r doesnt fail instead? 
 | 
			
		||||
         */
 | 
			
		||||
        sprintf(buf, "%d", gid);
 | 
			
		||||
    }
 | 
			
		||||
    buf[buflen-1] = '\0';
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sigar_user_id_get(sigar_t *sigar, const char *name, int *uid)
 | 
			
		||||
{
 | 
			
		||||
    /* XXX cache lookup */
 | 
			
		||||
    struct passwd *pw;
 | 
			
		||||
 | 
			
		||||
# ifdef HAVE_GETPWNAM_R
 | 
			
		||||
    struct passwd pwbuf;
 | 
			
		||||
    char buf[512];
 | 
			
		||||
 | 
			
		||||
    if (getpwnam_r(name, &pwbuf, buf, sizeof(buf), &pw) != 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# else
 | 
			
		||||
    if (!(pw = getpwnam(name))) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    *uid = (int)pw->pw_uid;
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *sigar_error_string(int err)
 | 
			
		||||
{
 | 
			
		||||
    switch (err) {
 | 
			
		||||
      case SIGAR_ENOTIMPL:
 | 
			
		||||
        return "This function has not been implemented on this platform";
 | 
			
		||||
      default:
 | 
			
		||||
        return "Error string not specified yet";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_strerror(sigar_t *sigar, int err)
 | 
			
		||||
{
 | 
			
		||||
    char *buf;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        return sigar->errbuf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (err > SIGAR_OS_START_ERROR) {
 | 
			
		||||
        if ((buf = sigar_os_error_string(sigar, err)) != NULL) {
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
        return "Unknown OS Error"; /* should never happen */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (err > SIGAR_START_ERROR) {
 | 
			
		||||
        return sigar_error_string(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return sigar_strerror_get(err, sigar->errbuf, sizeof(sigar->errbuf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *sigar_strerror_get(int err, char *errbuf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    char *buf = NULL;
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    DWORD len;
 | 
			
		||||
 | 
			
		||||
    len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
 | 
			
		||||
                        FORMAT_MESSAGE_IGNORE_INSERTS,
 | 
			
		||||
                        NULL,
 | 
			
		||||
                        err,
 | 
			
		||||
                        0, /* default language */
 | 
			
		||||
                        (LPTSTR)errbuf,
 | 
			
		||||
                        (DWORD)buflen,
 | 
			
		||||
                        NULL);
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_STRERROR_R) && defined(HAVE_STRERROR_R_GLIBC)
 | 
			
		||||
    /*
 | 
			
		||||
     * strerror_r man page says:
 | 
			
		||||
     * "The GNU version may, but need not, use the user supplied buffer"
 | 
			
		||||
     */
 | 
			
		||||
    buf = strerror_r(err, errbuf, buflen);
 | 
			
		||||
#elif defined(HAVE_STRERROR_R)
 | 
			
		||||
    if (strerror_r(err, errbuf, buflen) < 0) {
 | 
			
		||||
        buf = "Unknown Error";
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    /* strerror() is thread safe on solaris and hpux */
 | 
			
		||||
    buf = strerror(err);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (buf != NULL) {
 | 
			
		||||
        SIGAR_STRNCPY(errbuf, buf, buflen);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
#endif
 | 
			
		||||
    return errbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sigar_strerror_set(sigar_t *sigar, char *msg)
 | 
			
		||||
{
 | 
			
		||||
    SIGAR_SSTRCPY(sigar->errbuf, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#define vsnprintf _vsnprintf
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void sigar_strerror_printf(sigar_t *sigar, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    vsnprintf(sigar->errbuf, sizeof(sigar->errbuf), format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* copy apr_strfsize */
 | 
			
		||||
SIGAR_DECLARE(char *) sigar_format_size(sigar_uint64_t size, char *buf)
 | 
			
		||||
{
 | 
			
		||||
    const char ord[] = "KMGTPE";
 | 
			
		||||
    const char *o = ord;
 | 
			
		||||
    int remain;
 | 
			
		||||
 | 
			
		||||
    if (size == SIGAR_FIELD_NOTIMPL) {
 | 
			
		||||
        buf[0] = '-';
 | 
			
		||||
        buf[1] = '\0';
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (size < 973) {
 | 
			
		||||
        sprintf(buf, "%3d ", (int) size);
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        remain = (int)(size & 1023);
 | 
			
		||||
        size >>= 10;
 | 
			
		||||
 | 
			
		||||
        if (size >= 973) {
 | 
			
		||||
            ++o;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (size < 9 || (size == 9 && remain < 973)) {
 | 
			
		||||
            if ((remain = ((remain * 5) + 256) / 512) >= 10) {
 | 
			
		||||
                ++size;
 | 
			
		||||
                remain = 0;
 | 
			
		||||
            }
 | 
			
		||||
            sprintf(buf, "%d.%d%c", (int) size, remain, *o);
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (remain >= 512) {
 | 
			
		||||
            ++size;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sprintf(buf, "%3d%c", (int) size, *o);
 | 
			
		||||
 | 
			
		||||
        return buf;
 | 
			
		||||
    } while (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(int) sigar_uptime_string(sigar_t *sigar, 
 | 
			
		||||
                                       sigar_uptime_t *uptime,
 | 
			
		||||
                                       char *buffer,
 | 
			
		||||
                                       int buflen)
 | 
			
		||||
{
 | 
			
		||||
    char *ptr = buffer;
 | 
			
		||||
    int time = (int)uptime->uptime;
 | 
			
		||||
    int minutes, hours, days, offset = 0;
 | 
			
		||||
 | 
			
		||||
    /* XXX: get rid of sprintf and/or check for overflow */
 | 
			
		||||
    days = time / (60*60*24);
 | 
			
		||||
 | 
			
		||||
    if (days) {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%d day%s, ",
 | 
			
		||||
                          days, (days > 1) ? "s" : "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    minutes = time / 60;
 | 
			
		||||
    hours = minutes / 60;
 | 
			
		||||
    hours = hours % 24;
 | 
			
		||||
    minutes = minutes % 60;
 | 
			
		||||
 | 
			
		||||
    if (hours) {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%2d:%02d",
 | 
			
		||||
                          hours, minutes);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        offset += sprintf(ptr + offset, "%d min", minutes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type)
 | 
			
		||||
{
 | 
			
		||||
    switch (type) {
 | 
			
		||||
      case SIGAR_NETCONN_TCP:
 | 
			
		||||
        return "tcp";
 | 
			
		||||
      case SIGAR_NETCONN_UDP:
 | 
			
		||||
        return "udp";
 | 
			
		||||
      case SIGAR_NETCONN_RAW:
 | 
			
		||||
        return "raw";
 | 
			
		||||
      case SIGAR_NETCONN_UNIX:
 | 
			
		||||
        return "unix";
 | 
			
		||||
      default:
 | 
			
		||||
        return "unknown";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state)
 | 
			
		||||
{
 | 
			
		||||
    switch (state) {
 | 
			
		||||
      case SIGAR_TCP_ESTABLISHED:
 | 
			
		||||
        return "ESTABLISHED";
 | 
			
		||||
      case SIGAR_TCP_SYN_SENT:
 | 
			
		||||
        return "SYN_SENT";
 | 
			
		||||
      case SIGAR_TCP_SYN_RECV:
 | 
			
		||||
        return "SYN_RECV";
 | 
			
		||||
      case SIGAR_TCP_FIN_WAIT1:
 | 
			
		||||
        return "FIN_WAIT1";
 | 
			
		||||
      case SIGAR_TCP_FIN_WAIT2:
 | 
			
		||||
        return "FIN_WAIT2";
 | 
			
		||||
      case SIGAR_TCP_TIME_WAIT:
 | 
			
		||||
        return "TIME_WAIT";
 | 
			
		||||
      case SIGAR_TCP_CLOSE:
 | 
			
		||||
        return "CLOSE";
 | 
			
		||||
      case SIGAR_TCP_CLOSE_WAIT:
 | 
			
		||||
        return "CLOSE_WAIT";
 | 
			
		||||
      case SIGAR_TCP_LAST_ACK:
 | 
			
		||||
        return "LAST_ACK";
 | 
			
		||||
      case SIGAR_TCP_LISTEN:
 | 
			
		||||
        return "LISTEN";
 | 
			
		||||
      case SIGAR_TCP_CLOSING:
 | 
			
		||||
        return "CLOSING";
 | 
			
		||||
      case SIGAR_TCP_IDLE:
 | 
			
		||||
        return "IDLE";
 | 
			
		||||
      case SIGAR_TCP_BOUND:
 | 
			
		||||
        return "BOUND";
 | 
			
		||||
      case SIGAR_TCP_UNKNOWN:
 | 
			
		||||
      default:
 | 
			
		||||
        return "UNKNOWN";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user