📄 cl_msg_types.c
字号:
/* * Heartbeat message type functions * * Copyright (C) 2004 Guochun Shi <gshi@ncsa.uiuc.edu> * * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <portability.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <time.h>#include <errno.h>#include <sys/utsname.h>#include <ha_msg.h>#include <unistd.h>#include <clplumbing/cl_malloc.h>#include <clplumbing/cl_log.h>#include <clplumbing/ipc.h>#include <clplumbing/base64.h>#include <clplumbing/netstring.h>#include <glib.h>#ifndef MAX# define MAX(a,b) (((a) > (b)) ? (a) : (b))#endif#define NL_TO_SYM 0#define SYM_TO_NL 1int SPECIAL_SYMS[]={ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29};extern const char* FT_strings[];struct ha_msg* string2msg_ll(const char*, size_t, int, int);int compose_netstring(char*, const char*, const char*, size_t, size_t*);int msg2netstring_buf(const struct ha_msg*, char*, size_t, size_t*);int struct_display_print_spaces(char *buffer, int depth);int struct_display_as_xml(int log_level, int depth, struct ha_msg *data, const char *prefix, gboolean formatted);int struct_stringlen(size_t namlen, size_t vallen, const void* value);int struct_netstringlen(size_t namlen, size_t vallen, const void* value); static intintlen(int x){ char buf[20]; return snprintf(buf, sizeof(buf), "%d", x);}/* compute the total size of the resulted string if the string list is to be converted */size_tstring_list_pack_length(const GList* _list){ size_t i; GList* list = NULL; size_t total_length = 0; memcpy(&list, &_list, sizeof(GList*)); (void)list; if (list == NULL){ cl_log(LOG_WARNING, "string_list_pack_length():" "list is NULL"); return 0; } for (i = 0; i < g_list_length(list) ; i++){ char * element = g_list_nth_data(list, i); if (element == NULL){ cl_log(LOG_ERR, "string_list_pack_length: " "%luth element of the string list is NULL" , (unsigned long)i); return 0; } total_length += intlen(strlen(element)) + strlen(element) + 2; /* 2 is for ":" and "," */ } return total_length ;}/* convert a string list into a single string the format to convert is similar to netstring: <length> ":" <the actual string> "," for example, a list containing two strings "abc" "defg" will be converted into 3:abc,4:defg, @list: the list to be converted @buf: the converted string should be put in the @buf @maxp: max pointer*/intstring_list_pack(GList* list, char* buf, char* maxp){ size_t i; char* p = buf; for (i = 0; i < g_list_length(list) ; i++){ char * element = g_list_nth_data(list, i); int element_len = strlen(element); if (element == NULL){ cl_log(LOG_ERR, "string_list_pack: " "%luth element of the string list is NULL" , (unsigned long)i); return 0; } p += sprintf(p, "%d:%s,", element_len,element); if (p >= maxp){ cl_log(LOG_ERR, "string_list_pack: " "buffer overflowed "); return 0; } } return (p - buf);}/* this is reverse process of pack_string_list*/GList* string_list_unpack(const char* packed_str_list, size_t length){ GList* list = NULL; const char* psl = packed_str_list; const char * maxp= packed_str_list + length; int len = 0; while(TRUE){ char* buf; if (*psl == '\0' || psl >= maxp){ break; } if (sscanf( psl, "%d:", &len) <= 0 ){ break; } if (len <=0){ cl_log(LOG_ERR, "unpack_string_list:" "reading len of string error"); if (list){ list_cleanup(list); } return NULL; } while (*psl != ':' && *psl != '\0' ){ psl++; } if (*psl == '\0'){ break; } psl++; buf = ha_malloc(len + 1); if (buf == NULL){ cl_log(LOG_ERR, "unpack_string_list:" "unable to allocate buf"); if(list){ list_cleanup(list); } return NULL; } memcpy(buf, psl, len); buf[len] = '\0'; list = g_list_append(list, buf); psl +=len; if (*psl != ','){ cl_log(LOG_ERR, "unpack_string_list:" "wrong format, s=%s",packed_str_list); } psl++; } return list;}static voidstring_memfree(void* value){ if (value){ ha_free(value); }else { cl_log(LOG_ERR, "string_memfree: " "value is NULL"); } return;}static voidbinary_memfree(void* value){ string_memfree(value);}static voidstruct_memfree( void* value){ struct ha_msg* msg; if (!value){ cl_log(LOG_ERR, "value is NULL"); return ; } msg = (struct ha_msg*) value; ha_msg_del(msg); return ;}static voidlist_memfree(void* value){ if (!value){ cl_log(LOG_ERR, "value is NULL"); return ; } list_cleanup(value); }static void* binary_dup(const void* value, size_t len){ char* dupvalue; /* 0 byte binary field is allowed*/ if (value == NULL && len > 0){ cl_log(LOG_ERR, "binary_dup:" "NULL value with non-zero len=%d", (int)len); return NULL; } dupvalue = ha_malloc(len + 1); if (dupvalue == NULL){ cl_log(LOG_ERR, "binary_dup:" "ha_malloc failed"); return NULL; } if (value != NULL) { memcpy(dupvalue, value, len); } dupvalue[len] =0; return dupvalue;}static void*string_dup(const void* value, size_t len){ return binary_dup(value, len);}static void*struct_dup(const void* value, size_t len){ char* dupvalue; (void)len; if (!value){ cl_log(LOG_ERR,"struct_dup:" "value is NULL"); return NULL ; } dupvalue = (void*)ha_msg_copy((const struct ha_msg*)value); if (dupvalue == NULL){ cl_log(LOG_ERR, "struct_dup: " "ha_msg_copy failed"); return NULL; } return dupvalue;}static GList* list_copy(const GList* _list){ size_t i; GList* newlist = NULL; GList* list; memcpy(&list, &_list, sizeof(GList*)); for (i = 0; i < g_list_length(list); i++){ char* dup_element = NULL; char* element = g_list_nth_data(list, i); int len; if (element == NULL){ cl_log(LOG_WARNING, "list_cleanup:" "element is NULL"); continue; } len = strlen(element); dup_element= ha_malloc(len + 1); if ( dup_element == NULL){ cl_log(LOG_ERR, "duplicate element failed"); continue; } memcpy(dup_element, element,len); dup_element[len] = 0; newlist = g_list_append(newlist, dup_element); } return newlist;}static void*list_dup( const void* value, size_t len){ char* dupvalue; (void)len; if (!value){ cl_log(LOG_ERR,"struct_dup:" "value is NULL"); return NULL ; } dupvalue = (void*)list_copy((const GList*)value); if (!dupvalue){ cl_log(LOG_ERR, "list_dup: " "list_copy failed"); return NULL; } return dupvalue;}static voidstring_display(int log_level, int seq, char* name, void* value){ HA_MSG_ASSERT(name); HA_MSG_ASSERT(value); cl_log(log_level, "MSG[%d] : [%s=%s]", seq, name, (const char*)value); return;}static voidbinary_display(int log_level, int seq, char* name, void* value){ HA_MSG_ASSERT(value); HA_MSG_ASSERT(name); cl_log(log_level, "MSG[%d] : [(%s)%s=%p]", seq, FT_strings[FT_BINARY], name, value);}static voidstruct_display(int log_level, int seq, char* name, void* value){ HA_MSG_ASSERT(name); HA_MSG_ASSERT(value); cl_log(log_level, "MSG[%d] : [(%s)%s=%p]", seq, FT_strings[FT_STRUCT], name, value); if(cl_get_string((struct ha_msg*) value, F_XML_TAGNAME) == NULL) { cl_log_message(log_level, (struct ha_msg*) value); } else { /* use a more friendly output format for nested messages */ struct_display_as_xml(log_level, 0, value, NULL, TRUE); }}#define update_buffer_head(buffer, len) if(len < 0) { \ (*buffer) = EOS; return -1; \ } else { \ buffer += len; \ }intstruct_display_print_spaces(char *buffer, int depth) { int lpc = 0; int spaces = 2*depth; /* <= so that we always print 1 space - prevents problems with syslog */ for(lpc = 0; lpc <= spaces; lpc++) { if(sprintf(buffer, "%c", ' ') < 1) { return -1; } buffer += 1; } return lpc;}intstruct_display_as_xml( int log_level, int depth, struct ha_msg *data, const char *prefix, gboolean formatted) { int lpc = 0; int printed = 0; gboolean has_children = FALSE; char print_buffer[1000]; char *buffer = print_buffer; const char *name = cl_get_string(data, F_XML_TAGNAME); if(data == NULL) { return 0; } else if(name == NULL) { cl_log(LOG_WARNING, "Struct at depth %d had no name", depth); cl_log_message(log_level, data); return 0; } if(formatted) { printed = struct_display_print_spaces(buffer, depth); update_buffer_head(buffer, printed); } printed = sprintf(buffer, "<%s", name); update_buffer_head(buffer, printed); for (lpc = 0; lpc < data->nfields; lpc++) { const char *prop_name = data->names[lpc]; const char *prop_value = data->values[lpc]; if(data->types[lpc] != FT_STRING) { continue; } else if(prop_name == NULL) { continue; /* hide the next two */ } else if(strcmp(F_XML_TAGNAME, prop_name) == 0) { continue; } else if(strcmp(F_XML_PARENT, prop_name) == 0) { continue; } printed = sprintf(buffer, " %s=\"%s\"", prop_name, prop_value); update_buffer_head(buffer, printed); } for (lpc = 0; lpc < data->nfields; lpc++) { if(data->types[lpc] == FT_STRUCT) { has_children = TRUE; break; } } printed = sprintf(buffer, "%s>", has_children==0?"/":""); update_buffer_head(buffer, printed); cl_log(log_level, "%s%s", prefix?prefix:"", print_buffer); buffer = print_buffer; if(has_children == FALSE) { return 0; } for (lpc = 0; lpc < data->nfields; lpc++) { if(data->types[lpc] != FT_STRUCT) { continue; } else if(0 > struct_display_as_xml( log_level, depth+1, data->values[lpc], prefix, formatted)) { return -1; } } if(formatted) { printed = struct_display_print_spaces(buffer, depth); update_buffer_head(buffer, printed); } cl_log(log_level, "%s%s</%s>", prefix?prefix:"", print_buffer, name); return 0;}static int liststring(GList* list, char* buf, int maxlen){ char* p = buf; char* maxp = buf + maxlen; size_t i; for ( i = 0; i < g_list_length(list); i++){ char* element = g_list_nth_data(list, i); if (element == NULL) { cl_log(LOG_ERR, "%luth element is NULL " , (unsigned long)i); return HA_FAIL; } else{ if (i == 0){ p += sprintf(p,"%s",element); }else{ p += sprintf(p," %s",element); } } if ( p >= maxp){ cl_log(LOG_ERR, "buffer overflow"); return HA_FAIL; } } return HA_OK;}static voidlist_display(int log_level, int seq, char* name, void* value){ GList* list; char buf[MAXLENGTH]; HA_MSG_ASSERT(name); HA_MSG_ASSERT(value); list = value; if (liststring(list, buf, MAXLENGTH) != HA_OK){ cl_log(LOG_ERR, "liststring error"); return; } cl_log(log_level, "MSG[%d] :[(%s)%s=%s]", seq, FT_strings[FT_LIST], name, buf); return ; }/* * This function changes each new line in the input string * into a special symbol, or the other way around */static intconvert(char* s, int len, int depth, int direction){ int i; if (direction != NL_TO_SYM && direction != SYM_TO_NL){ cl_log(LOG_ERR, "convert(): direction not defined!"); return(HA_FAIL); } if (depth >= MAXDEPTH ){ cl_log(LOG_ERR, "convert(): MAXDEPTH exceeded"); return(HA_FAIL); } for (i = 0; i < len && s[i] != EOS; i++){ switch(direction){ case NL_TO_SYM : if (s[i] == '\n'){ s[i] = SPECIAL_SYMS[depth]; break; } if (s[i] == SPECIAL_SYMS[depth]){ cl_log(LOG_ERR , "convert(): special symbol \'%c\' found" " in string at %d (len=%d)", s[i], i, len); return(HA_FAIL); } break; case SYM_TO_NL: if (s[i] == '\n'){ cl_log(LOG_ERR , "convert(): new line found in" " converted string"); return(HA_FAIL); } if (s[i] == SPECIAL_SYMS[depth]){ s[i] = '\n'; break; } break; default: /* nothing, never executed*/; } } return(HA_OK);}static int string_stringlen(size_t namlen, size_t vallen, const void* value){ HA_MSG_ASSERT(value); HA_MSG_ASSERT( vallen == strlen(value)); return namlen + vallen+ 2;}static int string_netstringlen(size_t namlen, size_t vallen, const void* value){ int length; HA_MSG_ASSERT(value); HA_MSG_ASSERT( vallen == strlen(value)); length = intlen(namlen) + (namlen) + intlen(vallen) + vallen + 4 ; length += 4; /* for type*/ return length;}static intbinary_stringlen(size_t namlen, size_t vallen, const void* value){ HA_MSG_ASSERT(value); return namlen + B64_stringlen(vallen) + 2 + 3; /*overhead 3 is for type*/ }static intbinary_netstringlen(size_t namlen, size_t vallen, const void* value){ int length; HA_MSG_ASSERT(value); length = intlen(namlen) + (namlen) + intlen(vallen) + vallen + 4 ; length += 4; /* for type*/ return length; }intstruct_stringlen(size_t namlen, size_t vallen, const void* value){ const struct ha_msg* childmsg; HA_MSG_ASSERT(value); (void)vallen; childmsg = (const struct ha_msg*)value; return namlen +2 + 3 + get_stringlen(childmsg); /*overhead 3 is for type*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -