diff options
| author | osmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-03-12 15:24:16 +0000 |
|---|---|---|
| committer | osmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-03-12 15:24:16 +0000 |
| commit | 883163bc42892ffe0885e94b701ef9da4da3cf70 (patch) | |
| tree | d9b8592102201e0396de3807a223d5b87c72f1bd /src/libs/zbxsysinfo/sysinfo.c | |
| parent | e929cc4053168b46b81475715e98230eed01badc (diff) | |
| download | zabbix-883163bc42892ffe0885e94b701ef9da4da3cf70.tar.gz zabbix-883163bc42892ffe0885e94b701ef9da4da3cf70.tar.xz zabbix-883163bc42892ffe0885e94b701ef9da4da3cf70.zip | |
- fixed system.cpu.util[] (Eugene)
- improved configuration script (Eugene)
- fixed floats values (Eugene)
- developed agent result convertion (Eugene)
- more fixes
- TODO: WinXX agent \!\!\!
git-svn-id: svn://svn.zabbix.com/trunk@3886 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/libs/zbxsysinfo/sysinfo.c')
| -rw-r--r-- | src/libs/zbxsysinfo/sysinfo.c | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/src/libs/zbxsysinfo/sysinfo.c b/src/libs/zbxsysinfo/sysinfo.c new file mode 100644 index 00000000..67a8adc3 --- /dev/null +++ b/src/libs/zbxsysinfo/sysinfo.c @@ -0,0 +1,780 @@ +/* +** ZABBIX +** Copyright (C) 2000-2005 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** 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., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + +#include "common.h" +#include "sysinfo.h" +#include "log.h" +#include "alias.h" + +#include "common/common.h" + +#if defined(WITH_COMMON_METRICS) +# include "common/common.h" +#endif /* USE_COMMON_METRICS */ + +#if defined(WITH_SIMPLE_METRICS) +# include "simple/simple.h" +#endif /* USE_SIMPLE_METRICS */ + +#if defined(WITH_SPECIFIC_METRICS) +# include "specsysinfo.h" +#endif /* USE_SPECIFIC_METRICS */ + +ZBX_METRIC *commands=NULL; + +void add_metric(ZBX_METRIC *new) +{ + register int i; + + assert(new); + + if(new->key == NULL) + return; + + for(i=0;;i++) + { + if(commands[i].key == NULL) + { + + commands[i].key = strdup(new->key); + commands[i].flags = new->flags; + + commands[i].function=new->function; + + if(new->main_param == NULL) + commands[i].main_param=NULL; + else + commands[i].main_param=strdup(new->main_param); + + if(new->test_param == NULL) + commands[i].test_param=NULL; + else + commands[i].test_param=strdup(new->test_param); + + commands=realloc(commands,(i+2)*sizeof(ZBX_METRIC)); + commands[i+1].key=NULL; + break; + } + } +} + +void add_user_parameter(char *key,char *command) +{ + register int i; + char usr_cmd[MAX_STRING_LEN]; + char usr_param[MAX_STRING_LEN]; + unsigned flag = 0; + + i = parse_command(key, usr_cmd, MAX_STRING_LEN, usr_param, MAX_STRING_LEN); + if(i == 0) + { + zabbix_log( LOG_LEVEL_WARNING, "Can't add user specifed key \"%s\". Can't parse key!", key); + return; + } + else if(i == 2) /* with specifed parameters */ + { + if(strcmp(usr_param,"*")){ /* must be '*' parameters */ + zabbix_log(LOG_LEVEL_WARNING, "Can't add user specifed key \"%s\". Incorrect key!", key); + return; + } + flag |= CF_USEUPARAM; + } + + for(i=0;;i++) + { + /* Add new parameters */ + if( commands[i].key == 0) + { + commands[i].key = strdup(usr_cmd); + commands[i].flags = flag; + commands[i].function = &EXECUTE_STR; + commands[i].main_param = strdup(command); + commands[i].test_param = 0; + + commands=realloc(commands,(i+2)*sizeof(ZBX_METRIC)); + commands[i+1].key=NULL; + + break; + } + + /* Replace existing parameters */ + if(strcmp(commands[i].key, key) == 0) + { + if(commands[i].key) + free(commands[i].key); + if(commands[i].main_param) + free(commands[i].main_param); + if(commands[i].test_param) + free(commands[i].test_param); + + commands[i].key = strdup(key); + commands[i].flags = flag; + commands[i].function = &EXECUTE_STR; + commands[i].main_param = strdup(command); + commands[i].test_param = 0; + + break; + } + } +} + +void init_metrics() +{ + register int i; + + commands = malloc(sizeof(ZBX_METRIC)); + commands[0].key=NULL; + +#if defined(WITH_COMMON_METRICS) + for(i=0;parameters_common[i].key!=0;i++) + { + add_metric(¶meters_common[i]); + } +#endif /* USE_COMMON_METRICS */ + +#if defined(WITH_SPECIFIC_METRICS) + for(i=0;parameters_specific[i].key!=0;i++) + { + add_metric(¶meters_specific[i]); + } +#endif /* USE_SPECIFIC_METRICS */ + +#if defined(WITH_SIMPLE_METRICS) + for(i=0;parameters_simple[i].key!=0;i++) + { + add_metric(¶meters_simple[i]); + } +#endif /* USE_SIMPLE_METRICS */ +} + +void escape_string(char *from, char *to, int maxlen) +{ + register int i,ptr; + char *f; + + ptr=0; + f=(char *)strdup(from); + for(i=0;f[i]!=0;i++) + { + if( (f[i]=='\'') || (f[i]=='\\')) + { + if(ptr>maxlen-1) break; + to[ptr]='\\'; + if(ptr+1>maxlen-1) break; + to[ptr+1]=f[i]; + ptr+=2; + } + else + { + if(ptr>maxlen-1) break; + to[ptr]=f[i]; + ptr++; + } + } + free(f); + + to[ptr]=0; + to[maxlen-1]=0; +} + +int copy_result(AGENT_RESULT *src, AGENT_RESULT *dist) +{ + assert(src); + assert(dist); + + free_result(dist); + dist->type = src->type; + dist->dbl = src->dbl; + if(src->str) + { + dist->str = strdup(src->str); + if(!dist->str) + return 1; + } + if(src->msg) + { + dist->msg = strdup(src->msg); + if(!dist->msg) + return 1; + } + return 0; +} + +void free_result(AGENT_RESULT *result) +{ + UNSET_DBL_RESULT(result); + UNSET_UI64_RESULT(result); + UNSET_STR_RESULT(result); + UNSET_TEXT_RESULT(result); + UNSET_MSG_RESULT(result); +} + +void init_result(AGENT_RESULT *result) +{ + /* don't use `free_result(result)`, dangerous recycling */ + + result->type = 0; + + result->ui64 = 0; + result->dbl = 0; + result->str = NULL; + result->text = NULL; + result->msg = NULL; +} + +int parse_command( /* return value: 0 - error; 1 - command without parameters; 2 - command with parameters */ + const char *command, + char *cmd, + int cmd_max_len, + char *param, + int param_max_len + ) +{ + char *pl, *pr; + char localstr[MAX_STRING_LEN]; + int ret = 2; + + zbx_strlcpy(localstr, command, MAX_STRING_LEN); + + if(cmd) + zbx_strlcpy(cmd, "", cmd_max_len); + if(param) + zbx_strlcpy(param, "", param_max_len); + + pl = strstr(localstr, "["); + pr = strstr(localstr, "]"); + + if(pl > pr) + return 0; + + if((pl && !pr) || (!pl && pr)) + return 0; + + if(pl != NULL) + pl[0] = 0; + if(pr != NULL) + pr[0] = 0; + + if(cmd) + zbx_strlcpy(cmd, localstr, cmd_max_len); + + if(pl && pr && param) + zbx_strlcpy(param, &pl[1] , param_max_len); + + if(!pl && !pr) + ret = 1; + + return ret; +} + +void test_parameter(char* key) +{ + AGENT_RESULT result; + + memset(&result, 0, sizeof(AGENT_RESULT)); + process(key, PROCESS_TEST, &result); + if(result.type & AR_DOUBLE) + { + printf(" [d|" ZBX_FS_DBL "]", result.dbl); + } + if(result.type & AR_UINT64) + { + printf(" [u|" ZBX_FS_UI64 "]", result.ui64); + } + if(result.type & AR_STRING) + { + printf(" [s|%s]", result.str); + } + if(result.type & AR_TEXT) + { + printf(" [t|%s]", result.text); + } + if(result.type & AR_MESSAGE) + { + printf(" [m|%s]", result.msg); + } + + free_result(&result); + printf("\n"); + + fflush(stdout); +} + +void test_parameters(void) +{ + register int i; + AGENT_RESULT result; + +#if defined(_WINDOWS) +#endif + + memset(&result, 0, sizeof(AGENT_RESULT)); + + for(i=0; 0 != commands[i].key; i++) + { + process(commands[i].key, PROCESS_TEST | PROCESS_USE_TEST_PARAM, &result); + if(result.type & AR_DOUBLE) + { + printf(" [d|" ZBX_FS_DBL "]", result.dbl); + } + if(result.type & AR_UINT64) + { + printf(" [u|" ZBX_FS_UI64 "]", result.ui64); + } + if(result.type & AR_STRING) + { + printf(" [s|%s]", result.str); + } + if(result.type & AR_TEXT) + { + printf(" [t|%s]", result.text); + } + if(result.type & AR_MESSAGE) + { + printf(" [m|%s]", result.msg); + } + free_result(&result); + printf("\n"); + + fflush(stdout); + } +} + +int replace_param(const char *cmd, const char *param, char *out, int outlen) +{ + int ret = SUCCEED; + char buf[MAX_STRING_LEN]; + char command[MAX_STRING_LEN]; + register char *pl, *pr; + + assert(out); + + out[0] = '\0'; + + if(!cmd && !param) + return ret; + + zbx_strlcpy(command, cmd, MAX_STRING_LEN); + + pl = command; + while((pr = strchr(pl, '$')) && outlen > 0) + { + pr[0] = '\0'; + zbx_strlcat(out, pl, outlen); + outlen -= MIN((int)strlen(pl), (int)outlen); + pr[0] = '$'; + + if (pr[1] >= '0' && pr[1] <= '9') + { + buf[0] = '\0'; + + if(pr[1] == '0') + { + zbx_strlcpy(buf, command, MAX_STRING_LEN); + } + else + { + get_param(param, (int)(pr[1] - '0'), buf, MAX_STRING_LEN); + } + + zbx_strlcat(out, buf, outlen); + outlen -= MIN((int)strlen(buf), (int)outlen); + + pl = pr + 2; + continue; + } else if(pr[1] == '$') + { + pr++; /* remove second '$' symbol */ + } + + pl = pr + 1; + zbx_strlcat(out, "$", outlen); + outlen -= 1; + } + zbx_strlcat(out, pl, outlen); + outlen -= MIN((int)strlen(pl), (int)outlen); + + return ret; +} + +int process(const char *in_command, unsigned flags, AGENT_RESULT *result) +{ + register char *p; + register int i; + + int (*function)() = NULL; + int ret = SUCCEED; + int err = SYSINFO_RET_OK; + + char usr_cmd[MAX_STRING_LEN]; + char usr_param[MAX_STRING_LEN]; + + char usr_command[MAX_STRING_LEN]; + int usr_command_len; + + char param[MAX_STRING_LEN]; + + + assert(result); + init_result(result); + + alias_expand(in_command, usr_command, MAX_STRING_LEN); + + usr_command_len = (int)strlen(usr_command); + + for( p=usr_command+usr_command_len-1; p>usr_command && ( *p=='\r' || *p =='\n' || *p == ' ' ); --p ); + + if( (p[1]=='\r') || (p[1]=='\n') || (p[1]==' ')) + { + p[1]=0; + } + + function=0; + + if(parse_command(usr_command, usr_cmd, MAX_STRING_LEN, usr_param, MAX_STRING_LEN) != 0) + { + + for(i=0; commands[i].key != 0; i++) + { + if( strcmp(commands[i].key, usr_cmd) == 0) + { + function=commands[i].function; + break; + } + } + } + + param[0] = '\0'; + if(function != 0) + { + + if(commands[i].flags & CF_USEUPARAM) + { + if((flags & PROCESS_TEST) && (flags & PROCESS_USE_TEST_PARAM) && commands[i].test_param) + { + zbx_strlcpy(usr_param, commands[i].test_param, MAX_STRING_LEN); + } + } + else + { + usr_param[0] = '\0'; + } + + if(commands[i].main_param) + { + if(commands[i].flags & CF_USEUPARAM) + { + err = replace_param( + commands[i].main_param, + usr_param, + param, + MAX_STRING_LEN); + } + else + { + zbx_snprintf(param, sizeof(param), "%s", commands[i].main_param); + } + } + else + { + zbx_snprintf(param, sizeof(param), "%s", usr_param); + } + + if(err != FAIL) + { + err = function(usr_command, param, flags, result); + + if(err == SYSINFO_RET_FAIL) + err = NOTSUPPORTED; + else if(err == SYSINFO_RET_TIMEOUT) + err = TIMEOUT_ERROR; + } + } + else + { + err = NOTSUPPORTED; + } + + if(flags & PROCESS_TEST) + { + printf("%s", usr_cmd); + if(commands[i].flags & CF_USEUPARAM) + { + printf("[%s]", param); + i = (int)strlen(param)+2; + } else i = 0; + i += (int)strlen(usr_cmd); + +#define COLUMN_2_X 45 /* max of spaces count */ + i = i > COLUMN_2_X ? 1 : (COLUMN_2_X - i); + + printf("%-*.*s", i, i, " "); /* print spaces */ + } + + if(err == NOTSUPPORTED) + { + if(!(result->type & AR_MESSAGE)) + { + SET_MSG_RESULT(result, strdup("ZBX_NOTSUPPORTED")); + } + ret = NOTSUPPORTED; + } + else if(err == TIMEOUT_ERROR) + { + if(!(result->type & AR_MESSAGE)) + { + SET_MSG_RESULT(result, strdup("ZBX_ERROR")); + } + ret = TIMEOUT_ERROR; + } + + return ret; +} + +int set_result_type(AGENT_RESULT *result, int value_type, char *c) +{ + int ret = FAIL; + + assert(result); + + if(value_type == ITEM_VALUE_TYPE_UINT64) + { + del_zeroes(c); + if(is_uint(c) == SUCCEED) + { + SET_UI64_RESULT(result, zbx_atoui64(c)); + ret = SUCCEED; + } + } + else if(value_type == ITEM_VALUE_TYPE_FLOAT) + { + if(is_double(c) == SUCCEED) + { + SET_DBL_RESULT(result, atof(c)); + ret = SUCCEED; + } + else if(is_uint(c) == SUCCEED) + { + SET_DBL_RESULT(result, strtod(c, NULL)); + ret = SUCCEED; + } + } + else if(value_type == ITEM_VALUE_TYPE_STR) + { + SET_STR_RESULT(result, strdup(c)); + ret = SUCCEED; + } + else if(value_type == ITEM_VALUE_TYPE_TEXT) + { + SET_TEXT_RESULT(result, strdup(c)); + ret = SUCCEED; + } + else if(value_type == ITEM_VALUE_TYPE_LOG) + { + SET_STR_RESULT(result, strdup(c)); + ret = SUCCEED; + } + + return ret; +} + +static zbx_uint64_t* get_result_ui64_value(AGENT_RESULT *result) +{ + zbx_uint64_t tmp; + + assert(result); + + if(ISSET_UI64(result)) + { + /* nothing to do */ + } + else if(ISSET_DBL(result)) + { + SET_UI64_RESULT(result, result->dbl); + } + else if(ISSET_STR(result)) + { + if(EOF != sscanf(result->str, ZBX_FS_UI64, &tmp)) + SET_UI64_RESULT(result, tmp); + } + else if(ISSET_TEXT(result)) + { + if(EOF != sscanf(result->text, ZBX_FS_UI64, &tmp)) + SET_UI64_RESULT(result, tmp); + } + /* skip AR_MESSAGE - it is information field */ + + if(ISSET_UI64(result)) + { + return &result->ui64; + } + + return NULL; +} + +static double* get_result_dbl_value(AGENT_RESULT *result) +{ + double tmp; + + assert(result); + + if(ISSET_DBL(result)) + { + /* nothing to do */ + } + else if(ISSET_UI64(result)) + { + SET_DBL_RESULT(result, result->ui64); + } + else if(ISSET_STR(result)) + { + if(EOF != sscanf(result->str, ZBX_FS_DBL, &tmp)) + SET_DBL_RESULT(result, tmp); + } + else if(ISSET_TEXT(result)) + { + if(EOF != sscanf(result->text, ZBX_FS_DBL, &tmp)) + SET_DBL_RESULT(result, tmp); + } + /* skip AR_MESSAGE - it is information field */ + + if(ISSET_DBL(result)) + { + return &result->dbl; + } + + return NULL; +} + +static char** get_result_str_value(AGENT_RESULT *result) +{ + register char *p, tmp; + + assert(result); + + if(ISSET_STR(result)) + { + /* nothing to do */ + } + else if(ISSET_TEXT(result)) + { + /* NOTE: copy only line */ + for(p = result->text; *p != '\0' && *p != '\r' && *p != '\n'; p++); + tmp = *p; /* remember result->text character */ + *p = '\0'; /* replace to EOL */ + SET_STR_RESULT(result, strdup(result->text)); /* copy line */ + *p = tmp; /* restore result->text character */ + + } + else if(ISSET_UI64(result)) + { + SET_STR_RESULT(result, zbx_dsprintf(NULL, ZBX_FS_UI64, result->ui64)) + } + else if(ISSET_DBL(result)) + { + SET_STR_RESULT(result, zbx_dsprintf(NULL, ZBX_FS_DBL, result->dbl)) + } + /* skip AR_MESSAGE - it is information field */ + + if(ISSET_STR(result)) + { + return &result->str; + } + + return NULL; +} + +static char** get_result_text_value(AGENT_RESULT *result) +{ + assert(result); + + if(ISSET_TEXT(result)) + { + /* nothing to do */ + } + else if(ISSET_STR(result)) + { + SET_TEXT_RESULT(result, strdup(result->str)); + } + else if(ISSET_UI64(result)) + { + SET_TEXT_RESULT(result, zbx_dsprintf(NULL, ZBX_FS_UI64, result->ui64)) + } + else if(ISSET_DBL(result)) + { + SET_TEXT_RESULT(result, zbx_dsprintf(NULL, ZBX_FS_DBL, result->dbl)) + } + /* skip AR_MESSAGE - it is information field */ + + if(ISSET_TEXT(result)) + { + return &result->text; + } + + return NULL; +} + +/****************************************************************************** + * * + * Function: get_result_value_by_type * + * * + * Purpose: return vslue of result in special type * + * if falue missed convert existed value to requested type * + * * + * Return value: * + * NULL - if value are missed or can't be conferted * + * * + * Author: Eugene Grigorjev * + * * + * Comments: beter use definitions * + * GET_UI64_RESULT * + * GET_DBL_RESULT * + * GET_STR_RESULT * + * GET_TEXT_RESULT * + * GET_MSG_RESULT * + * * + * AR_MESSAGE - skiped in convertion * + * * + ******************************************************************************/ +void *get_result_value_by_type(AGENT_RESULT *result, int require_type) +{ + assert(result); + + switch(require_type) + { + case AR_UINT64: + return (void*)get_result_ui64_value(result); + break; + case AR_DOUBLE: + return (void*)get_result_dbl_value(result); + break; + case AR_STRING: + return (void*)get_result_str_value(result); + break; + case AR_TEXT: + return (void*)get_result_text_value(result); + break; + case AR_MESSAGE: + if(ISSET_MSG(result)) return (void*)(&result->msg); + break; + default: + break; + } + return NULL; +} |
