📄 cl_msg.c
字号:
msg->netstringlen += 0; /*4; */ /* for type*/ msg->types[next] = FT_STRUCT; internal_type = type; msg->nfields++; return(HA_OK); default: /*case FT_STRING:*/ newstringlen = msg->stringlen + (namelen+vallen+2); internal_type = FT_STRING; if (name[0] == '('){ if (name[2] != ')'){ if (!cl_msg_quiet_fmterr) { cl_log(LOG_ERR , "ha_msg_addraw_ll()" ": no closing parentheses"); } return(HA_FAIL); } sscanf(name + 1, "%d", &internal_type); if (internal_type == FT_STRING){ cl_log(LOG_ERR , "ha_msg_addraw_ll(): wrong type"); return(HA_FAIL); } } if (internal_type == FT_BINARY){ char tmpbuf[MAXMSG]; int nlo = 3; /*name length overhead*/ cp_name = name; cp_namelen = namelen - nlo ; memmove(cp_name, name + nlo, namelen - nlo); cp_name[namelen - nlo] = EOS; memcpy(tmpbuf, value,vallen); cp_vallen = base64_to_binary(tmpbuf, vallen , value, vallen); cp_value = value; }else if (internal_type == FT_STRUCT ){ struct ha_msg *tmpmsg; int nlo = 3; /* iname length overhead */ cp_name = name; cp_namelen = namelen - nlo ; memmove(cp_name, name + nlo, namelen - nlo); cp_name[namelen - nlo] = EOS; if (convert(value, vallen, depth,SYM_TO_NL) != HA_OK){ cl_log(LOG_ERR , "ha_msg_addraw_ll(): convert failed"); return(HA_FAIL); } tmpmsg = string2msg_ll(value, vallen,depth + 1, 0); if (tmpmsg == NULL){ cl_log(LOG_ERR , "ha_msg_addraw_ll()" ": string2msg_ll failed"); return(HA_FAIL); } ha_free(value); cp_value = tmpmsg; cp_vallen = sizeof(struct ha_msg); }else{ /* SHOULDN'T THIS CASE ALSO BE namelen+nlo ?? * * And if it should be, then factor this code out * from all the branches of this if statement * At least explain why this is different. * * string is : name=value * binary is : (FT_BINARY) = value * struct is : (FT_STRUCT) = value * therefore, string name does not have any overhead * */ cp_name = name; cp_namelen = namelen; cp_value = value; cp_vallen = vallen; } } if (newstringlen >= MAXMSG) { cl_log(LOG_ERR, "ha_msg_addraw_ll(): " "cannot add name/value to ha_msg (value too big)"); if (cp_value) { if (internal_type == FT_STRUCT) { ha_msg_del((struct ha_msg *)cp_value); }else{ cl_free(cp_value); } cp_value = NULL; } if (cp_name) { cl_free(cp_name); cp_name = NULL; } return(HA_FAIL); } next = msg->nfields; msg->values[next] = cp_value; msg->vlens[next] = cp_vallen; msg->names[next] = cp_name; msg->nlens[next] = cp_namelen; msg->stringlen = newstringlen; msg->netstringlen += intlen(cp_namelen) + (cp_namelen) + intlen(cp_vallen) + cp_vallen + 4 ; msg->netstringlen += 4; /* for type*/ if (type == FT_BINARY || internal_type == FT_BINARY){ msg->types[next] = FT_BINARY; }else if (internal_type == FT_STRUCT){ msg->types[next] = FT_STRUCT; } msg->nfields++; AUDITMSG(msg); return(HA_OK);}static intha_msg_addraw(struct ha_msg * msg, const char * name, size_t namelen, const void * value, size_t vallen, int type, int depth){ char *cpvalue; char *cpname; int ret; if ((cpname = ha_malloc(namelen+1)) == NULL) { cl_log(LOG_ERR, "ha_msg_addraw: no memory for string (name)"); return(HA_FAIL); } strncpy(cpname, name, namelen); cpname[namelen] = EOS; if(type == FT_STRING || type == FT_BINARY){ if ((cpvalue = ha_malloc(vallen+1)) == NULL) { cl_log(LOG_ERR, "ha_msg_addraw: no memory for string (value)"); return(HA_FAIL); } memcpy(cpvalue, value, vallen); cpvalue[vallen] = EOS; }else{ cpvalue = (char*)ha_msg_copy( (const struct ha_msg*) value); if(cpvalue == NULL){ cl_log(LOG_ERR, "ha_msg_addraw: copying message failed"); ha_free(cpname); return(HA_FAIL); } } ret = ha_msg_addraw_ll(msg, cpname, namelen, cpvalue, vallen , type, depth); if (ret != HA_OK){ cl_log(LOG_ERR, "ha_msg_addraw(): ha_msg_addraw_ll failed"); ha_free(cpname); if (type == FT_STRING || type== FT_BINARY) { ha_free(cpvalue); }else{ struct ha_msg* p; memcpy(&p,&cpvalue, sizeof(struct ha_msg*)); ha_msg_del(p); } } return(ret);}/*Add a null-terminated name and binary value to a message*/intha_msg_addbin(struct ha_msg * msg, const char * name, const void * value, size_t vallen){ return(ha_msg_addraw(msg, name, strlen(name), value, vallen, FT_BINARY, 0));}/*Add a null-terminated name and struct value to a message*/intha_msg_addstruct(struct ha_msg * msg, const char * name, void * value){ /* size is 0 because size is useless in this case*/ return ha_msg_addraw(msg, name, strlen(name), value, 0, FT_STRUCT, 0); }/* Add a null-terminated name and value to a message */intha_msg_add(struct ha_msg * msg, const char * name, const char * value){ return(ha_msg_nadd(msg, name, strlen(name), value, strlen(value)));}/* Add a name/value pair to a message (with sizes for name and value) */intha_msg_nadd(struct ha_msg * msg, const char * name, int namelen , const char * value, int vallen){ return(ha_msg_addraw(msg, name, namelen, value, vallen, FT_STRING, 0));}/* Add a name/value/type to a message (with sizes for name and value) */intha_msg_nadd_type(struct ha_msg * msg, const char * name, int namelen , const char * value, int vallen, int type){ return(ha_msg_addraw(msg, name, namelen, value, vallen, type, 0));}/* Add a "name=value" line to the name, value pairs in a message */static intha_msg_add_nv_depth(struct ha_msg* msg, const char * nvline, const char * bufmax, int depth){ int namelen; const char * valp; int vallen; if (!nvline) { cl_log(LOG_ERR, "ha_msg_add_nv: NULL nvline"); return(HA_FAIL); } /* How many characters before the '='? */ if ((namelen = strcspn(nvline, EQUAL)) <= 0 || nvline[namelen] != '=') { if (!cl_msg_quiet_fmterr) { cl_log(LOG_WARNING , "ha_msg_add_nv: line doesn't contain '='"); cl_log(LOG_INFO, "%s", nvline); } return(HA_FAIL); } valp = nvline + namelen +1; /* Point just *past* the '=' */ if (valp >= bufmax) return HA_FAIL; vallen = strcspn(valp, CRNL); if ((valp + vallen) >= bufmax) return HA_FAIL; /* Call ha_msg_nadd to actually add the name/value pair */ return(ha_msg_addraw(msg, nvline, namelen, valp, vallen , FT_STRING, depth));}intha_msg_add_nv(struct ha_msg* msg, const char * nvline, const char * bufmax){ return(ha_msg_add_nv_depth(msg, nvline, bufmax, 0));}static void *cl_get_value(const struct ha_msg * msg, const char * name, size_t * vallen, int *type){ int j; if (!msg || !msg->names || !msg->values) { cl_log(LOG_ERR, "ha_msg_value: NULL msg"); return(NULL); } AUDITMSG(msg); for (j=0; j < msg->nfields; ++j) { if (strcmp(name, msg->names[j]) == 0) { if (vallen){ *vallen = msg->vlens[j]; } if (type){ *type = msg->types[j]; } return(msg->values[j]); } } return(NULL);}const void *cl_get_binary(const struct ha_msg *msg, const char * name, size_t * vallen){ const void *ret; int type; ret = cl_get_value( msg, name, vallen, &type); if (ret == NULL || type != FT_BINARY){ cl_log(LOG_WARNING, "field %s not found or " "it is not binary", name); return(NULL); } return(ret);}const char *cl_get_string(const struct ha_msg *msg, const char *name){ const void *ret; int type; ret = cl_get_value( msg, name, NULL, &type); if (ret == NULL || type != FT_STRING){ return(NULL); } return(ret);}intcl_get_type(const struct ha_msg *msg, const char *name){ const void *ret; int type; ret = cl_get_value( msg, name, NULL, &type); if (ret == NULL ||( type != FT_STRING && type != FT_BINARY && type != FT_STRUCT)) { cl_log(LOG_WARNING, "field %s not found or " "it is not any valid type", name); return(-1); } return(type);}struct ha_msg *cl_get_struct(const struct ha_msg *msg, const char* name){ struct ha_msg *ret; int type; size_t vallen; ret = (struct ha_msg *)cl_get_value(msg, name, &vallen, &type); if (ret == NULL || type != FT_STRUCT){ cl_log(LOG_ERR, "field %s not found or" " it is not a struct", name); return(NULL); } return(ret);}/* Modify the value associated with a particular name */static intcl_msg_mod(struct ha_msg * msg, const char * name, const void* value, size_t vlen, int type){ int j; AUDITMSG(msg); if (msg == NULL || name == NULL || value == NULL) { cl_log(LOG_ERR, "cl_msg_mod: NULL input."); return HA_FAIL; } for (j=0; j < msg->nfields; ++j) { if (strcmp(name, msg->names[j]) == 0) { char * newv ; int newlen = vlen; int sizediff = 0; if (type != msg->types[j]){ cl_log(LOG_ERR, "cl_msg_mod: " "type mismatch for field %s", name); return(HA_FAIL); } if(type == FT_STRING || type == FT_BINARY){ newv = ha_malloc(vlen + 1); if (newv == NULL) { cl_log(LOG_ERR, "cl_msg_mod: out of memory"); return(HA_FAIL); } memcpy(newv, value, vlen); newv[vlen] = '\0'; ha_free(msg->values[j]); } else{ newv = (char*)ha_msg_copy( (const struct ha_msg*)value); if( newv == NULL){ cl_log(LOG_ERR, "cl_msg_mod: make a message copy failed"); return(HA_FAIL); } ha_msg_del((struct ha_msg *) msg->values[j]); } msg->values[j] = newv; sizediff = newlen - msg->vlens[j]; msg->stringlen += sizediff; msg->netstringlen += intlen(newlen) + newlen - intlen(msg->vlens[j]) - msg->vlens[j]; msg->vlens[j] = newlen; AUDITMSG(msg); return(HA_OK); } } return(ha_msg_nadd_type(msg, name,strlen(name), value, vlen, type));}intcl_msg_modstruct(struct ha_msg * msg, const char* name, const struct ha_msg* value){ return cl_msg_mod(msg, name, value, 0, FT_STRUCT);}intcl_msg_modbin(struct ha_msg * msg, const char* name, const void* value, size_t vlen){ return cl_msg_mod(msg, name, value, vlen, FT_BINARY); }/* Modify the value associated with a particular name */intcl_msg_modstring(struct ha_msg * msg, const char * name, const char * value){ return cl_msg_mod(msg, name, value, strlen(value), FT_STRING);}/* Return the next message found in the stream */struct ha_msg *msgfromstream(FILE * f){ char buf[MAXMSGLINE]; char * getsret; clearerr(f); /* Skip until we find a MSG_START (hopefully we skip nothing) */ while(1) { getsret = fgets(buf, sizeof(buf), f); if (!getsret) { break; } if (strcmp(buf, MSG_START) == 0) { return msgfromstream_string(f); } if (strcmp(buf, MSG_START_NETSTRING) == 0){ return msgfromstream_netstring(f); } } return NULL;}/* Return the next message found in the stream with string format */struct ha_msg *msgfromstream_string(FILE * f){ char buf[MAXMSGLINE]; const char * bufmax = buf + sizeof(buf); struct ha_msg* ret; char * getsret; if ((ret = ha_msg_new(0)) == NULL) { /* Getting an error with EINTR is pretty normal */ /* (so is EOF) */ if ( (!ferror(f) || (errno != EINTR && errno != EAGAIN)) && !feof(f)) { cl_log(LOG_ERR, "msgfromstream: cannot get message"); } return(NULL); } /* Add Name=value pairs until we reach MSG_END or EOF */ while(1) { getsret = fgets(buf, MAXMSGLINE, f); if (!getsret) { break; } if (strnlen(buf, MAXMSGLINE) > MAXMSGLINE - 2) { cl_log(LOG_DEBUG , "msgfromstream: field too long [%s]" , buf); } if (!strcmp(buf, MSG_END)) { break; } /* Add the "name=value" string on this line to the message */ if (ha_msg_add_nv(ret, buf, bufmax) != HA_OK) { cl_log(LOG_ERR, "NV failure (msgfromsteam): [%s]" , buf); ha_msg_del(ret); ret=NULL; return(NULL); } } return(ret);}/* Return the next message found in the stream with string format*/struct ha_msg *msgfromstream_netstring(FILE * f){ struct ha_msg * ret; char total_databuf[MAXMSG]; char * sp = total_databuf; if ((ret = ha_msg_new(0)) == NULL) { /* Getting an error with EINTR is pretty normal */ /* (so is EOF) */ if ( (!ferror(f) || (errno != EINTR && errno != EAGAIN)) && !feof(f)) { cl_log(LOG_ERR , "msgfromstream_netstring(): cannot get message"); } return(NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -