Beispiel #1
0
xmlrpc_value* generate_request_array ( xmlrpc_env *env , xmlrpc_value *arr)
{
#if 1
   Task task = gen_prime (task);

   xmlrpc_value *v1 = xmlrpc_build_value(env, "s", task._clientid);
   xmlrpc_value *v2 = xmlrpc_build_value(env, "s", task.p);
   xmlrpc_value *v3 = xmlrpc_build_value(env, "s", task.m);

#endif
#if 0
char s[20];
sprintf(s,"%d",getpid());
   Task task = gen_prime (task);
   xmlrpc_value *v1 = xmlrpc_build_value(env, "s", s);
   xmlrpc_value *v2 = xmlrpc_build_value(env, "s", "45");
   xmlrpc_value *v3 = xmlrpc_build_value(env, "s", "54");

#endif   
   xmlrpc_array_append_item (env,arr,v1);
   xmlrpc_array_append_item (env,arr,v2);
   xmlrpc_array_append_item (env,arr,v3);
   
   return arr; 
}
Beispiel #2
0
/* Pack the information from any client method into a generic xmlrpc
   struct to send to the server */
xmlrpc_value *
callinfo_pack(xmlrpc_env *envP, struct call_info *cip)
{
  xmlrpc_value *s = xmlrpc_struct_new(envP);
  xmlrpc_value *methargs = xmlrpc_array_new(envP);
  xmlrpc_value *files = xmlrpc_array_new(envP);
  int i;

  xmlrpc_struct_set_value(envP, s, "clientIP", xmlrpc_string_new(envP, nonull(cip->clientIP)));
  xmlrpc_struct_set_value(envP, s, "serverURL", xmlrpc_string_new(envP, nonull(cip->serverURL)));
  xmlrpc_struct_set_value(envP, s, "session", xmlrpc_string_new(envP, nonull(cip->session)));
  xmlrpc_struct_set_value(envP, s, "method", xmlrpc_string_new(envP, nonull(cip->method)));
  xmlrpc_struct_set_value(envP, s, "user", xmlrpc_string_new(envP, nonull(cip->user)));
  xmlrpc_struct_set_value(envP, s, "password", xmlrpc_string_new(envP, nonull(cip->password)));
  xmlrpc_struct_set_value(envP, s, "project", xmlrpc_string_new(envP, nonull(cip->project)));
  xmlrpc_struct_set_value(envP, s, "version", xmlrpc_string_new(envP, nonull(cip->version)));

  if (cip->methodargs)
    {
      for (i = 0; cip->methodargs[i]; ++i)
	{
	  if (!strncmp(cip->methodargs[i], "file:", 5))
	    {
	      char *file_what, *file_name;
	      
	      file_what = strdup(&cip->methodargs[i][5]);
	      file_name = strchr(file_what, '=');
	      if (file_name)
		{
		  xmlrpc_value * fstruct;
		  *file_name++ = '\0';
		  fstruct = file_pack(envP, file_what, file_name);
		  xmlrpc_array_append_item(envP, files, fstruct);
		}
	      else
		{
		  fprintf(stderr, "oracc-client: bad -Mfile arg, expected -Mfile:WHAT=NAME\n");
		  exit(1);
		}
	    }
	  else
	    xmlrpc_array_append_item(envP, methargs, xmlrpc_string_new(envP, cip->methodargs[i]));
	}
    }

  xmlrpc_struct_set_value(envP, s, "method-args", methargs);
  xmlrpc_struct_set_value(envP, s, "method-data", files);

  return s;
}
int
wpCreatePostStruct(xmlrpc_env *env, char *username, char*password, wppost_t *post, xmlrpc_value **paramArray, int mode) {
	int retval = 0;
	xmlrpc_value *blogidP, *postidP, *usernameP, *passwordP, *titleP, *descriptionP, *dateP, *publishP, *categoryP, *contentP, *tokenP;
	char *token;
	char *categories = NULL, *catPtr;
	if ( mode == 0 ) {
		post->blogid = wpGetBlogId(username, password, post->url);
		if (post->blogid == NULL) {
			fprintf(stderr, "NULL Blog Id\n");
			retval = 1;
			goto out;	
		}
		blogidP = xmlrpc_string_new(env, post->blogid);
		postidP = NULL;
	} else {
		blogidP = NULL;
		postidP = xmlrpc_string_new(env, post->postid);
	}
	usernameP = xmlrpc_string_new(env, username);
	passwordP = xmlrpc_string_new(env, password);
	titleP = xmlrpc_string_new(env, post->subject);
	descriptionP = xmlrpc_string_new(env, post->body);
	if(!strcmp(post->status, "draft")) {
		publishP = xmlrpc_bool_new(env, FALSE);
	} else {
		publishP = xmlrpc_bool_new(env, TRUE);
	}
	dateP = xmlrpc_datetime_new_sec(env, time(NULL));
	asprintf(&categories, "%s", post->categories);
	catPtr = categories;
	categoryP = xmlrpc_array_new(env);
	token = strtok(categories, ",");
	tokenP = xmlrpc_string_new(env, token);
	xmlrpc_array_append_item(env, categoryP, tokenP);
	while( (token = strtok( (char *) NULL, ",") ) != NULL ) {
		tokenP = xmlrpc_string_new(env, token);
		xmlrpc_array_append_item(env, categoryP, tokenP);
	}
	free(catPtr);
	contentP = xmlrpc_struct_new(env);
	xmlrpc_struct_set_value(env, contentP, "title", titleP);
	xmlrpc_struct_set_value(env, contentP, "description", descriptionP);
	xmlrpc_struct_set_value(env, contentP, "dateCreated", dateP);
	xmlrpc_struct_set_value(env, contentP, "categories", categoryP);
	/* Populate the Parameter Array */
	*paramArray = xmlrpc_array_new(env);
	if (mode == 0)
		xmlrpc_array_append_item(env, *paramArray, blogidP);
	else
		xmlrpc_array_append_item(env, *paramArray, postidP);
	xmlrpc_array_append_item(env, *paramArray, usernameP);
	xmlrpc_array_append_item(env, *paramArray, passwordP);
	xmlrpc_array_append_item(env, *paramArray, contentP);
	xmlrpc_array_append_item(env, *paramArray, publishP);
out:
	return retval;
}
static int recur_build_response_array( xmlrpc_env * env, struct mi_node * tree,
                                       str * buf )
{
    for ( ; tree ; tree = tree->next ) {
        if (!(tree->flags & MI_WRITTEN)) {
            if ( xr_write_node( buf, tree ) != 0 ) {
                LM_ERR("failed to get MI node data!\n");
                return -1;
            }

            /* we are sure that this node has been written
            * => avoid writing it again */
            tree->flags |= MI_WRITTEN;
        }

        reply_buffer[reply_buffer_len-buf->len] = 0;
        reply_item = xmlrpc_build_value(env, "s", reply_buffer);
        xmlrpc_array_append_item(env, xr_response, reply_item);

        buf->s = reply_buffer;
        buf->len = reply_buffer_len;

        if ( tree->kids ) {
            if ( recur_build_response_array(env, tree->kids, buf) != 0 )
                return -1;
        }
    }
    return 0;
}
xmlrpc_value* GetConferences(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data)
{
	MCU *mcu = (MCU *)user_data;
	MCU::ConferencesInfo list;

	//Obtenemos la referencia
	if(!mcu->GetConferenceList(list))
		return xmlerror(env,"Could not retreive conference info list\n");

	//Create array
	xmlrpc_value* arr = xmlrpc_array_new(env);

	//Process result
	for (MCU::ConferencesInfo::iterator it = list.begin(); it!=list.end(); ++it)
	{
		//Create array
		xmlrpc_value* val = xmlrpc_build_value(env,"(isi)",it->second.id,it->second.name.c_str(),it->second.numPart);
		//Add it
		xmlrpc_array_append_item(env,arr,val);
		//Release
		xmlrpc_DECREF(val);
	}

	//return
	return xmlok(env,arr);
}
Beispiel #6
0
// {int32 key, string name, string path}[] = archiver.archives()
xmlrpc_value *get_archives(xmlrpc_env *env, xmlrpc_value *args, void *user)
{
#ifdef LOGFILE
    LOG_MSG("archiver.archives\n");
#endif
    // Get Configuration
    ServerConfig config;
    if (!get_config(env, config))
        return 0;
    // Create result
    AutoXmlRpcValue result(xmlrpc_build_value(env, "()"));
    if (env->fault_occurred)
        return 0;
    stdList<ServerConfig::Entry>::const_iterator i;
    for (i=config.config.begin(); i!=config.config.end(); ++i)
    {
        AutoXmlRpcValue archive(
            xmlrpc_build_value(env, "{s:i,s:s,s:s}",
                               "key",  i->key,
                               "name", i->name.c_str(),
                               "path", i->path.c_str()));
        xmlrpc_array_append_item(env, result, archive);
    }
    return result.release();
}
static xmlrpc_value *
convert_params(xmlrpc_env *        const envP,
               const xml_element * const elemP) {
/*----------------------------------------------------------------------------
   Convert an XML element representing a list of parameters (i.e.  a
   <params> element) to an xmlrpc_value of type array.  Note that an
   array is normally represented in XML by a <value> element.  We use
   type xmlrpc_value to represent the parameter list just for convenience.
-----------------------------------------------------------------------------*/
    xmlrpc_value *array, *item;
    int size, i;
    xml_element **params, *param, *value;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(elemP != NULL);

    /* Set up our error-handling preconditions. */
    array = item = NULL;

    /* Allocate an array to hold our parameters. */
    array = xmlrpc_build_value(envP, "()");
    XMLRPC_FAIL_IF_FAULT(envP);

    /* We're responsible for checking our own element name. */
    CHECK_NAME(envP, elemP, "params");    

    /* Iterate over our children. */
    size = xml_element_children_size(elemP);
    params = xml_element_children(elemP);
    for (i = 0; i < size; ++i) {
        unsigned int const maxNest = xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);

        param = params[i];
        CHECK_NAME(envP, param, "param");
        CHECK_CHILD_COUNT(envP, param, 1);

        value = xml_element_children(param)[0];

        CHECK_NAME(envP, value, "value");

        xmlrpc_parseValue(envP, maxNest, value, &item);
        XMLRPC_FAIL_IF_FAULT(envP);

        xmlrpc_array_append_item(envP, array, item);
        xmlrpc_DECREF(item);
        item = NULL;
        XMLRPC_FAIL_IF_FAULT(envP);
    }

 cleanup:
    if (envP->fault_occurred) {
        if (array)
            xmlrpc_DECREF(array);
        if (item)
            xmlrpc_DECREF(item);
        return NULL;
    }
    return array;
}
Beispiel #8
0
/* vxdb.mount.get(string name[, string dst]) */
xmlrpc_value *m_vxdb_mount_get(xmlrpc_env *env, xmlrpc_value *p, void *c)
{
	xmlrpc_value *params, *response = NULL;
	char *name, *dst;
	int rc;
	xid_t xid;

	params = method_init(env, p, c, VCD_CAP_MOUNT, M_OWNER);
	method_return_if_fault(env);

	xmlrpc_decompose_value(env, params,
			"{s:s,s:s,*}",
			"name", &name,
			"dst", &dst);
	method_return_if_fault(env);

	method_empty_params(1, &dst);

	if (dst && !validate_path(dst))
		method_return_faultf(env, MEINVAL,
				"invalid dst value: %s", dst);

	if (!(xid = vxdb_getxid(name)))
		method_return_fault(env, MENOVPS);

	if (dst)
		rc = vxdb_prepare(&dbr,
				"SELECT src,dst,type,opts FROM mount "
				"WHERE xid = %d AND dst = '%s'",
				xid, dst);

	else
		rc = vxdb_prepare(&dbr,
				"SELECT src,dst,type,opts FROM mount "
				"WHERE xid = %d ORDER BY dst ASC",
				xid);

	if (rc != VXDB_OK)
		method_return_vxdb_fault(env);

	response = xmlrpc_array_new(env);

	vxdb_foreach_step(rc, dbr)
		xmlrpc_array_append_item(env, response, xmlrpc_build_value(env,
				"{s:s,s:s,s:s,s:s}",
				"src",  vxdb_column_text(dbr, 0),
				"dst",  vxdb_column_text(dbr, 1),
				"type", vxdb_column_text(dbr, 2),
				"opts", vxdb_column_text(dbr, 3)));

	if (rc != VXDB_DONE)
		method_set_vxdb_fault(env);

	vxdb_finalize(dbr);

	return response;
}
void
value::appendToCArray(xmlrpc_value * const arrayP) const {
/*----------------------------------------------------------------------------
  Append this value to the C array 'arrayP'.
----------------------------------------------------------------------------*/
    env_wrap env;

    xmlrpc_array_append_item(&env.env_c, arrayP, this->cValueP);

    throwIfError(env);
}
Beispiel #10
0
// Return CtrlInfo encoded a per "meta" returned by archiver.get_values
static xmlrpc_value *encode_ctrl_info(xmlrpc_env *env, const CtrlInfo *info)
{
    if (info && info->getType() == CtrlInfo::Enumerated)
    {
        AutoXmlRpcValue states(xmlrpc_build_value(env, "()"));
        stdString state_txt;
        size_t i, num = info->getNumStates();
        for (i=0; i<num; ++i)
        {
            info->getState(i, state_txt);
            AutoXmlRpcValue state(
                xmlrpc_build_value(env, "s#",
                                   state_txt.c_str(), state_txt.length()));
            xmlrpc_array_append_item(env, states, state);
        }
        xmlrpc_value *meta = xmlrpc_build_value(
            env, "{s:i,s:V}",
            "type", (xmlrpc_int32)META_TYPE_ENUM,
            "states", (xmlrpc_value *)states);
        return meta;
    }
    if (info && info->getType() == CtrlInfo::Numeric)
    {
        return xmlrpc_build_value(
            env, "{s:i,s:d,s:d,s:d,s:d,s:d,s:d,s:i,s:s}",
            "type", (xmlrpc_int32)META_TYPE_NUMERIC,
            "disp_high",  make_finite(info->getDisplayHigh()),
            "disp_low",   make_finite(info->getDisplayLow()),
            "alarm_high", make_finite(info->getHighAlarm()),
            "warn_high",  make_finite(info->getHighWarning()),
            "warn_low",   make_finite(info->getLowWarning()),
            "alarm_low",  make_finite(info->getLowAlarm()),
            "prec", (xmlrpc_int32)info->getPrecision(),
            "units", info->getUnits());
    }
    return xmlrpc_build_value(
            env, "{s:i,s:d,s:d,s:d,s:d,s:d,s:d,s:i,s:s}",
            "type", (xmlrpc_int32)META_TYPE_NUMERIC,
            "disp_high",  10.0,
            "disp_low",   0.0,
            "alarm_high", 0.0,
            "warn_high",  0.0,
            "warn_low",   0.0,
            "alarm_low",  0.0,
            "prec", (xmlrpc_int32) 1,
            "units", "<NO DATA>");
    /*
    return  xmlrpc_build_value(env, "{s:i,s:(s)}",
                               "type", (xmlrpc_int32)META_TYPE_ENUM,
                               "states", "<NO DATA>");
    */
}
static xmlrpc_value *
system_multicall(xmlrpc_env *   const envP,
                 xmlrpc_value * const paramArrayP,
                 void *         const serverInfo,
                 void *         const callInfo) {

    xmlrpc_registry * registryP;
    xmlrpc_value * resultsP;
    xmlrpc_value * methlistP;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT_ARRAY_OK(paramArrayP);
    XMLRPC_ASSERT_PTR_OK(serverInfo);

    resultsP = NULL;  /* defeat compiler warning */

    /* Turn our arguments into something more useful. */
    registryP = (xmlrpc_registry*) serverInfo;

    getMethListFromMulticallPlist(envP, paramArrayP, &methlistP);
    if (!envP->fault_occurred) {
        /* Create an initially empty result list. */
        resultsP = xmlrpc_array_new(envP);
        if (!envP->fault_occurred) {
            /* Loop over our input list, calling each method in turn. */
            unsigned int const methodCount =
                xmlrpc_array_size(envP, methlistP);
            unsigned int i;
            for (i = 0; i < methodCount && !envP->fault_occurred; ++i) {
                xmlrpc_value * const methinfoP = 
                    xmlrpc_array_get_item(envP, methlistP, i);
            
                xmlrpc_value * resultP;
            
                XMLRPC_ASSERT_ENV_OK(envP);
            
                callOneMethod(envP, registryP, methinfoP, callInfo, &resultP);
            
                if (!envP->fault_occurred) {
                    /* Append this method result to our master array. */
                    xmlrpc_array_append_item(envP, resultsP, resultP);
                    xmlrpc_DECREF(resultP);
                }
            }
            if (envP->fault_occurred)
                xmlrpc_DECREF(resultsP);
            xmlrpc_DECREF(methlistP);
        }
    }
    return resultsP;
}
static int recur_flush_response_array(xmlrpc_env * env, struct mi_node *tree,
                                      str *buf)
{
    struct mi_node *kid, *tmp;
    int ret;

    for(kid = tree->kids ; kid ; ) {
        /* write the current kid */
        if (!(kid->flags & MI_WRITTEN)) {
            if (xr_write_node( buf, kid)!=0) {
                LM_ERR("failed to write - line too long!\n");
                return -1;
            }

            /* we are sure that this node has been written
            * => avoid writing it again */
            kid->flags |= MI_WRITTEN;
        }

        reply_buffer[reply_buffer_len-buf->len] = 0;
        reply_item = xmlrpc_build_value(env, "s", reply_buffer);
        xmlrpc_array_append_item(env, xr_response, reply_item);

        buf->s = reply_buffer;
        buf->len = reply_buffer_len;

        /* write the current kid's children */
        if ((ret = recur_flush_response_array(env, kid, buf))<0)
            return -1;
        else if (ret > 0)
            return ret;

        if (!(kid->flags & MI_NOT_COMPLETED)) {
            tmp = kid;
            kid = kid->next;
            tree->kids = kid;

            if(!tmp->kids) {
                /* this node does not have any kids */
                free_mi_node(tmp);
            }
        }
        else {
            /* the node will have more kids => to keep the tree shape, do not
             * flush any other node for now */
            return 1;
        }
    }

    return 0;
}
xmlrpc_value* GetParticipantStatistics(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data)
{
	MCU *mcu = (MCU *)user_data;
	MultiConf *conf = NULL;

	 //Parseamos
	int confId;
	int partId;
	xmlrpc_parse_value(env, param_array, "(ii)", &confId, &partId);

	//Comprobamos si ha habido error
	if(env->fault_occurred)
		xmlerror(env,"Fault occurred\n");

	//Obtenemos la referencia
	if(!mcu->GetConferenceRef(confId,&conf))
		return xmlerror(env,"Conference does not exist");

	//Get statistics
	MultiConf::ParticipantStatistics *partStats = conf->GetParticipantStatistic(partId);

	//Liberamos la referencia
	mcu->ReleaseConferenceRef(confId);

	//Salimos
	if(!partStats)
		return xmlerror(env,"Participant not found\n");

	//Create array
	xmlrpc_value* arr = xmlrpc_array_new(env);
	
	//Process result
	for (MultiConf::ParticipantStatistics::iterator it = partStats->begin(); it!=partStats->end(); ++it)
	{
		//Get media
		std::string media = it->first;
		//Get stats
		MediaStatistics stats = it->second;
		//Create array
		xmlrpc_value* val = xmlrpc_build_value(env,"(siiiiiii)",media.c_str(),stats.isReceiving,stats.isSending,stats.lostRecvPackets,stats.numRecvPackets,stats.numSendPackets,stats.totalRecvBytes,stats.totalSendBytes);
		//Add it
		xmlrpc_array_append_item(env,arr,val);
		//Release
		xmlrpc_DECREF(val);
	}

	//return
	return xmlok(env,arr);
}
Beispiel #14
0
static xmlrpc_value *
license_lookup_from_packages (xmlrpc_env   *env,
                              xmlrpc_value *param_array,
                              void         *user_data)
{
    xmlrpc_value *xmlrpc_packages;
    RCPackageSList *packages = NULL;
    GSList *licenses = NULL;
    xmlrpc_value *license_texts = NULL;
    GSList *iter;

    xmlrpc_parse_value (env, param_array, "(A)", &xmlrpc_packages);
    XMLRPC_FAIL_IF_FAULT (env);

    packages = rcd_xmlrpc_array_to_rc_package_slist (xmlrpc_packages, env,
                                                     RCD_PACKAGE_FROM_XMLRPC_PACKAGE);
    XMLRPC_FAIL_IF_FAULT (env);

    licenses = rcd_license_lookup_from_package_slist (packages);

    license_texts = xmlrpc_build_value (env, "()");
    XMLRPC_FAIL_IF_FAULT (env);

    for (iter = licenses; iter; iter = iter->next) {
        xmlrpc_value *xmlrpc_text;

        xmlrpc_text = xmlrpc_build_value (env, "s", (char *) iter->data);
        XMLRPC_FAIL_IF_FAULT (env);

        xmlrpc_array_append_item (env, license_texts, xmlrpc_text);
        XMLRPC_FAIL_IF_FAULT (env);
        xmlrpc_DECREF (xmlrpc_text);
    }

cleanup:

    if (packages) {
        rc_package_slist_unref (packages);
        g_slist_free (packages);
    }

    g_slist_free (licenses);

    if (env->fault_occurred)
        return NULL;

    return license_texts;
}
Beispiel #15
0
Datei: you.c Projekt: joeshaw/rcd
static xmlrpc_value *
you_license (xmlrpc_env   *env,
             xmlrpc_value *param_array,
             void         *user_data)
{
    xmlrpc_value *xmlrpc_patches = NULL;
    RCYouPatchSList *patches = NULL;
    GSList *licenses = NULL;
    xmlrpc_value *xmlrpc_licenses = NULL;
    GSList *iter;

    xmlrpc_parse_value (env, param_array, "(A)", &xmlrpc_patches);
    XMLRPC_FAIL_IF_FAULT (env);

    patches = rc_xmlrpc_array_to_rc_you_patch_slist
        (xmlrpc_patches, env, RC_YOU_PATCH_FROM_XMLRPC_PATCH);
    XMLRPC_FAIL_IF_FAULT (env);

    licenses = rc_you_patch_slist_lookup_licenses (patches);

    xmlrpc_licenses = xmlrpc_build_value (env, "()");
    XMLRPC_FAIL_IF_FAULT (env);

    for (iter = licenses; iter; iter = iter->next) {
        xmlrpc_value *xmlrpc_text;

        xmlrpc_text = xmlrpc_build_value (env, "s", (char *) iter->data);
        XMLRPC_FAIL_IF_FAULT (env);

        xmlrpc_array_append_item (env, xmlrpc_licenses, xmlrpc_text);
        XMLRPC_FAIL_IF_FAULT (env);
        xmlrpc_DECREF (xmlrpc_text);
    }

 cleanup:

    if (patches) {
        rc_you_patch_slist_unref (patches);
        g_slist_free (patches);
    }

    g_slist_free (licenses);

    if (env->fault_occurred)
        return NULL;

    return xmlrpc_licenses;
}
Beispiel #16
0
static void
get_priv_cb (RCDPrivileges priv,
             const char   *priv_name,
             gpointer      user_data)
{
    struct GetPrivInfo *info = user_data;
    xmlrpc_value *value;

    value = xmlrpc_build_value (info->env, "s", priv_name);
    
    xmlrpc_array_append_item (info->env, info->array, value);
    XMLRPC_FAIL_IF_FAULT (info->env);

 cleanup:
    xmlrpc_DECREF (value);
}
bool ArchiveDataClient::getValues(int key, stdVector<stdString> &names,
                                  const epicsTime &start, const epicsTime &end,
                                  int count, int how,
                                  value_callback callback, void *callback_arg)
{
    xmlrpc_value *name_array, *result, *element;
    size_t n;
    name_array = xmlrpc_build_value(&env, "()");
    if (log_fault())
        return false;
     for (n=0; n<names.size(); ++n)
    {
        element = xmlrpc_build_value(&env, "s", names[n].c_str());
        if (log_fault())
            return false;
        xmlrpc_array_append_item(&env, name_array, element);
        if (log_fault())
            return false;
        xmlrpc_DECREF(element);
    }
    xmlrpc_int32 start_sec, start_nano, end_sec, end_nano;
    epicsTime2pieces(start, start_sec, start_nano);
    epicsTime2pieces(end, end_sec, end_nano);
    result = xmlrpc_client_call(&env, (char *)URL,
                                "archiver.values", "(iViiiiii)",
                                (xmlrpc_int32)key, name_array,
                                start_sec, start_nano, end_sec, end_nano,
                                (xmlrpc_int32)count, (xmlrpc_int32)how);
    if (log_fault())
        return false;
    xmlrpc_DECREF(name_array);
    size_t channel_count = xmlrpc_array_size(&env, result);
    xmlrpc_value *channel_result;
    for (n=0; n<channel_count; ++n)
    {
        channel_result = xmlrpc_array_get_item(&env, result, n);
        if (log_fault())
            return false;
        if (!decode_channel(channel_result, n, callback, callback_arg))
            return false;
    }
    xmlrpc_DECREF(result);
    return true;
}
Beispiel #18
0
    // "visitor" for BinaryTree of channel names
    static void add_name_to_result(const ChannelInfo &info, void *arg)
    {
        UserArg *user_arg = (UserArg *)arg;
        xmlrpc_int32 ss, sn, es, en;
        epicsTime2pieces(info.start, ss, sn);
        epicsTime2pieces(info.end, es, en);        

        LOG_MSG("Found name '%s'\n", info.name.c_str());

        AutoXmlRpcValue channel(xmlrpc_build_value(
                                    user_arg->env,
                                    "{s:s,s:i,s:i,s:i,s:i}",
                                    "name", info.name.c_str(),
                                    "start_sec", ss, "start_nano", sn,
                                    "end_sec", es,   "end_nano", en));
        if (user_arg->env->fault_occurred)
            return;
        xmlrpc_array_append_item(user_arg->env, user_arg->result, channel);
    }
Beispiel #19
0
static void
add_mirror_cb (RCDMirror *mirror, gpointer user_data)
{
    struct GetAllInfo *info = user_data;
    xmlrpc_value *mirror_value;

    if (info->failed)
        return;

    mirror_value = rcd_mirror_to_xmlrpc (mirror, info->env);
    if (mirror_value) {
        xmlrpc_array_append_item (info->env, info->array, mirror_value);
        xmlrpc_DECREF (mirror_value);
        return;
    }

    /* Fall through on error */
    info->failed = TRUE;
}
Beispiel #20
0
static void
test_value_array(void) {

    xmlrpc_value *v;
    xmlrpc_env env;
    size_t len;
    xmlrpc_value * itemP;

    /* Basic array-building test. */

    xmlrpc_env_init(&env);

    TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_ARRAY), "ARRAY"));

    v = xmlrpc_array_new(&env);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
    len = xmlrpc_array_size(&env, v);
    TEST_NO_FAULT(&env);
    TEST(len == 0);

    itemP = xmlrpc_int_new(&env, 7);
    TEST_NO_FAULT(&env);
    xmlrpc_array_append_item(&env, v, itemP);
    TEST_NO_FAULT(&env);
    len = xmlrpc_array_size(&env, v);
    TEST_NO_FAULT(&env);
    TEST(len == 1);
    xmlrpc_DECREF(itemP);

    xmlrpc_DECREF(v);

    v = xmlrpc_build_value(&env, "()");
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
    len = xmlrpc_array_size(&env, v);
    TEST_NO_FAULT(&env);
    TEST(len == 0);
    xmlrpc_DECREF(v);

    xmlrpc_env_clean(&env);
}
Beispiel #21
0
xmlrpc_value *xmlrpccmd_core_get_log(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const userData) {

	uint32_t last_id;

	xmlrpc_decompose_value(envP, paramArrayP, "(i)", &last_id);
	if (envP->fault_occurred)
		return NULL;

	xmlrpc_value *res = xmlrpc_array_new(envP);
	if (envP->fault_occurred)
		return NULL;

	pomlog_rlock();

	struct pomlog_entry *log = pomlog_get_tail();

	if (log->id <= last_id) {
		pomlog_unlock();
		return res;
	}

	while (log && log->id > last_id + 1)
		log = log->prev;

	while (log) {
		xmlrpc_value *entry = xmlrpc_build_value(envP, "{s:i,s:i,s:s,s:s}",
								"id", log->id,
								"level", log->level,
								"file", log->file,
								"data", log->data);
		xmlrpc_array_append_item(envP, res, entry);
		xmlrpc_DECREF(entry);
		log = log->next;

	}
	pomlog_unlock();

	return res;
}
Beispiel #22
0
static int recur_build_response_array( xmlrpc_env * env, struct mi_node * tree, str * buf )
{
	for ( ; tree ; tree = tree->next ) {
		
		if ( xr_write_node( buf, tree ) != 0 ) {
			LM_ERR("failed to get MI node data!\n");
			return -1;
		}	

		reply_buffer[reply_buffer_len-buf->len] = 0;
		reply_item = xmlrpc_build_value(env, "s", reply_buffer);
		xmlrpc_array_append_item(env, xr_response, reply_item);
		
		buf->s = reply_buffer; 
		buf->len = reply_buffer_len;

		if ( tree->kids ) {
			if ( recur_build_response_array(env, tree->kids, buf) != 0 )
				return -1;
		}
	}
	return 0;
}
static void
parseArrayDataChild(xmlrpc_env *   const envP,
                    xml_element *  const childP,
                    unsigned int   const maxRecursion,
                    xmlrpc_value * const arrayP) {

    const char * const elemName = xml_element_name(childP);

    if (!xmlrpc_streq(elemName, "value"))
        setParseFault(envP, "<data> element has <%s> child.  "
                      "Only <value> makes sense.", elemName);
    else {
        xmlrpc_value * itemP;

        xmlrpc_parseValue(envP, maxRecursion-1, childP, &itemP);

        if (!envP->fault_occurred) {
            xmlrpc_array_append_item(envP, arrayP, itemP);

            xmlrpc_DECREF(itemP);
        }
    }
}
Beispiel #24
0
static void
get_all_cb (RCDIdentity *id,
            gpointer user_data)
{
    struct GetAllInfo *info = user_data;
    char *auth_str;
    xmlrpc_value *value;

    auth_str = rcd_privileges_to_string (id->privileges);

    value = xmlrpc_build_value (info->env,
                                "(ss)",
                                id->username,
                                auth_str);

    g_free (auth_str);

    xmlrpc_array_append_item (info->env, info->array, value);
    XMLRPC_FAIL_IF_FAULT (info->env);

 cleanup:
    xmlrpc_DECREF (value);
}
static void
createMethodListArray(xmlrpc_env *      const envP,
                      xmlrpc_registry * const registryP,
                      xmlrpc_value **   const methodListPP) {
/*----------------------------------------------------------------------------
   Create as an XML-RPC array value a list of names of methods registered
   in registry 'registryP'.

   This is the type of value that the system.listMethods method is supposed
   to return.
-----------------------------------------------------------------------------*/
    xmlrpc_value * methodListP;

    methodListP = xmlrpc_array_new(envP);

    if (!envP->fault_occurred) {
        xmlrpc_methodNode * methodNodeP;
        for (methodNodeP = registryP->methodListP->firstMethodP;
             methodNodeP && !envP->fault_occurred;
             methodNodeP = methodNodeP->nextP) {
            
            xmlrpc_value * methodNameVP;
            
            methodNameVP = xmlrpc_string_new(envP, methodNodeP->methodName);
            
            if (!envP->fault_occurred) {
                xmlrpc_array_append_item(envP, methodListP, methodNameVP);
                
                xmlrpc_DECREF(methodNameVP);
            }
        }
        if (envP->fault_occurred)
            xmlrpc_DECREF(methodListP);
    }
    *methodListPP = methodListP;
}
Beispiel #26
0
static xmlrpc_value * method_get_reports(xmlrpc_env * const env,
		   xmlrpc_value * const param_array,
		   void * const user_data)
{
	int has_more;
	xmlrpc_value *ret = 0, *item = 0;

	UNUSED_ARGUMENT(param_array);
	UNUSED_ARGUMENT(user_data);

	DEBUG_MSG(LOG_NOTICE, "Method get_reports called");

	struct _report *report = get_reports(&has_more);

	ret = xmlrpc_array_new(env);

	/* Add information if there's more reports pending */
	item = xmlrpc_int_new(env, has_more);
	xmlrpc_array_append_item(env, ret, item);
	xmlrpc_DECREF(item);

	while (report) {
		xmlrpc_value *rv = xmlrpc_build_value(env,
			"("
			"{s:i,s:i,s:i,s:i,s:i,s:i}" /* timeval */
			"{s:i,s:i,s:i,s:i}" /* bytes */
			"{s:i,s:i,s:i,s:i}" /* block counts */
			"{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}" /* RTT, IAT, Delay */
			"{s:i,s:i}" /* MTU */
			"{s:i,s:i,s:i,s:i,s:i}" /* TCP info */
			"{s:i,s:i,s:i,s:i,s:i}" /* ...      */
			"{s:i,s:i,s:i,s:i,s:i}" /* ...      */
			"{s:i}"
			")",

			"id", report->id,
			"type", report->type,
			"begin_tv_sec", (int)report->begin.tv_sec,
			"begin_tv_nsec", (int)report->begin.tv_nsec,
			"end_tv_sec", (int)report->end.tv_sec,
			"end_tv_nsec", (int)report->end.tv_nsec,

			"bytes_read_high", (int32_t)(report->bytes_read >> 32),
			"bytes_read_low", (int32_t)(report->bytes_read & 0xFFFFFFFF),
			"bytes_written_high", (int32_t)(report->bytes_written >> 32),
			"bytes_written_low", (int32_t)(report->bytes_written & 0xFFFFFFFF),

			"request_blocks_read", report->request_blocks_read,
			"request_blocks_written", report->request_blocks_written,
			"response_blocks_read", report->response_blocks_read,
			"response_blocks_written", report->response_blocks_written,

			"rtt_min", report->rtt_min,
			"rtt_max", report->rtt_max,
			"rtt_sum", report->rtt_sum,
			"iat_min", report->iat_min,
			"iat_max", report->iat_max,
			"iat_sum", report->iat_sum,
			"delay_min", report->delay_min,
			"delay_max", report->delay_max,
			"delay_sum", report->delay_sum,

			"pmtu", report->pmtu,
			"imtu", report->imtu,

/* Currently, not all members of the TCP_INFO socket option are used by the
 * FreeBSD kernel. Other members will contain zeroes */
			"tcpi_snd_cwnd", (int)report->tcp_info.tcpi_snd_cwnd,
			"tcpi_snd_ssthresh", (int)report->tcp_info.tcpi_snd_ssthresh,
			"tcpi_unacked", (int)report->tcp_info.tcpi_unacked,
			"tcpi_sacked", (int)report->tcp_info.tcpi_sacked,
			"tcpi_lost", (int)report->tcp_info.tcpi_lost,
			"tcpi_retrans", (int)report->tcp_info.tcpi_retrans,
			"tcpi_retransmits", (int)report->tcp_info.tcpi_retransmits,
			"tcpi_fackets", (int)report->tcp_info.tcpi_fackets,
			"tcpi_reordering", (int)report->tcp_info.tcpi_reordering,
			"tcpi_rtt", (int)report->tcp_info.tcpi_rtt,
			"tcpi_rttvar", (int)report->tcp_info.tcpi_rttvar,
			"tcpi_rto", (int)report->tcp_info.tcpi_rto,
			"tcpi_backoff", (int)report->tcp_info.tcpi_backoff,
			"tcpi_ca_state", (int)report->tcp_info.tcpi_ca_state,
			"tcpi_snd_mss", (int)report->tcp_info.tcpi_snd_mss,

			"status", report->status
		);

		xmlrpc_array_append_item(env, ret, rv);

		xmlrpc_DECREF(rv);

		struct _report *next = report->next;
		free(report);
		report = next;
	}

	if (env->fault_occurred)
		logging_log(LOG_WARNING, "Method get_reports failed: %s", env->fault_string);
	else {
		DEBUG_MSG(LOG_WARNING, "Method get_reports successful");
	}

	return ret;
}
Beispiel #27
0
// { int32  ver, string desc } = archiver.info()
xmlrpc_value *get_info(xmlrpc_env *env, xmlrpc_value *args, void *user)
{
#ifdef LOGFILE
    LOG_MSG("archiver.info\n");
#endif
    int i;
    const char *config = get_config_name(env);
    if (!config)
        return 0;
#ifdef LOGFILE
    LOG_MSG("config: '%s'\n", config);
#endif
    char description[500];
    sprintf(description,
            "Channel Archiver Data Server V%d,\n"
            "for " EPICS_VERSION_STRING ",\n"
            "built " __DATE__ ", " __TIME__ "\n"
            "from sources for version " ARCH_VERSION_TXT "\n"
            "Config: '%s'\n",
            ARCH_VER, config);
    AutoXmlRpcValue how(xmlrpc_build_value(env, "(sssss)",
                                           "raw",
                                           "spreadsheet",
                                           "average",
                                           "plot-binning",
                                           "linear"));
    if (env->fault_occurred)
        return 0;
    // 'status': array of all status string.
    AutoXmlRpcValue element;
    AutoXmlRpcValue status(xmlrpc_build_value(env, "()"));
    if (env->fault_occurred)
        return 0;
    for (i=0; i<=lastEpicsAlarmCond; ++i)
    {
        element = xmlrpc_build_value(env, "s", epicsAlarmConditionStrings[i]);
        xmlrpc_array_append_item(env, status, element);
        if (env->fault_occurred)
            return 0;
    }
    // 'severity': array of all severity strings.
    AutoXmlRpcValue severity(xmlrpc_build_value(env, "()"));
    for (i=0; i<=lastEpicsAlarmSev; ++i)
    {
        element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                     "num", (xmlrpc_int32)i,
                                     "sevr", epicsAlarmSeverityStrings[i],
                                     "has_value", (xmlrpc_bool) 1,
                                     "txt_stat", (xmlrpc_bool) 1);
        xmlrpc_array_append_item(env, severity, element);
        if (env->fault_occurred)
            return 0;
    }
    // ... including the archive-specific ones.
    element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                 "num", (xmlrpc_int32)ARCH_EST_REPEAT,
                                 "sevr", "Est_Repeat",
                                 "has_value", (xmlrpc_bool) 1,
                                 "txt_stat", (xmlrpc_bool) 0);
    xmlrpc_array_append_item(env, severity, element);
    element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                 "num", (xmlrpc_int32)ARCH_REPEAT,
                                 "sevr", "Repeat",
                                 "has_value", (xmlrpc_bool) 1,
                                 "txt_stat", (xmlrpc_bool) 0);
    xmlrpc_array_append_item(env, severity, element);
    element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                 "num", (xmlrpc_int32)ARCH_DISCONNECT,
                                 "sevr", "Disconnected",
                                 "has_value", (xmlrpc_bool) 0,
                                 "txt_stat", (xmlrpc_bool) 1);
    xmlrpc_array_append_item(env, severity, element);
    element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                 "num", (xmlrpc_int32)ARCH_STOPPED,
                                 "sevr", "Archive_Off",
                                 "has_value", (xmlrpc_bool) 0,
                                 "txt_stat", (xmlrpc_bool) 1);
    xmlrpc_array_append_item(env, severity, element);
    element = xmlrpc_build_value(env, "{s:i,s:s,s:b,s:b}",
                                 "num", (xmlrpc_int32)ARCH_DISABLED,
                                 "sevr", "Archive_Disabled",
                                 "has_value", (xmlrpc_bool) 0,
                                 "txt_stat", (xmlrpc_bool) 1);
    xmlrpc_array_append_item(env, severity, element);
    // Overall result.
    return xmlrpc_build_value(env, "{s:i,s:s,s:V,s:V,s:V}",
                              "ver", ARCH_VER,
                              "desc", description,
                              "how", how.get(),
                              "stat", status.get(),
                              "sevr", severity.get());
}
Beispiel #28
0
// Return the data for all the names[], start .. end etc.
// as get_values() is supposed to return them.
//
// Returns raw values if interpol <= 0.0.
// Returns 0 on error.
xmlrpc_value *get_sheet_data(xmlrpc_env *env,
                             int key,
                             const stdVector<stdString> names,
                             const epicsTime &start, const epicsTime &end,
                             long count,
                             ReaderFactory::How how, double delta)
{
    try
    {
#ifdef LOGFILE
        stdString txt;
        LOG_MSG("get_sheet_data\n");
        LOG_MSG("Start : %s\n", epicsTimeTxt(start, txt));
        LOG_MSG("End   : %s\n", epicsTimeTxt(end, txt));
        LOG_MSG("Method: %s\n", ReaderFactory::toString(how, delta));
 #endif
        AutoPtr<Index> index(open_index(env, key));
        if (env->fault_occurred)
            return 0;

        AutoPtr<SpreadsheetReader> sheet(new SpreadsheetReader(*index, how, delta));
    
        AutoXmlRpcValue results(xmlrpc_build_value(env, "()"));
        if (env->fault_occurred)
            return 0;    

        long name_count = names.size();
        AutoArrayPtr<AutoXmlRpcValue> meta     (new AutoXmlRpcValue[name_count]);
        AutoArrayPtr<AutoXmlRpcValue> values   (new AutoXmlRpcValue[name_count]);
        AutoArrayPtr<xmlrpc_int32>    xml_type (new xmlrpc_int32[name_count]);
        AutoArrayPtr<xmlrpc_int32>    xml_count(new xmlrpc_int32[name_count]);
        AutoArrayPtr<size_t>          ch_vals  (new size_t[name_count]);
        bool ok = sheet->find(names, &start);
        long i;
        // Per-channel meta-info.
        for (i=0; i<name_count; ++i)
        {
#ifdef LOGFILE
            LOG_MSG("Handling '%s'\n", names[i].c_str());
#endif
            ch_vals[i] = 0;
            values[i] = xmlrpc_build_value(env, "()");            
            if (env->fault_occurred)
                return 0;
            if (sheet->found(i))
            {   // Fix meta/type/count based on first value
                meta[i] = encode_ctrl_info(env, &sheet->getInfo(i));
                dbr_type_to_xml_type(sheet->getType(i), sheet->getCount(i),
                                     xml_type[i], xml_count[i]);
#if 0
                LOG_MSG("Ch %lu: type, count = %d, %d\n", i, (int)xml_type[i], (int)xml_count[i]);
#endif
            }
            else
            {   // Channel exists, but has no data
                meta[i] = encode_ctrl_info(env, 0);
                xml_type[i] = XML_ENUM;
                xml_count[i] = 1;
            }
        }
        // Collect values
        long num_vals = 0;
        while (ok && num_vals < count && sheet->getTime() < end)
        {
            for (i=0; i<name_count; ++i)
            {
                if (sheet->get(i))
                {
                    ++ch_vals[i];
                    encode_value(env,
                                 sheet->getType(i), sheet->getCount(i),
                                 sheet->getTime(), sheet->get(i),
                                 xml_type[i], xml_count[i], values[i]);
                }
                else
                {   // Encode as no value, but one of them ;-)
                    // to avoid confusion w/ viewers that like to see some data in any case.
                    encode_value(env, 0, 1, sheet->getTime(), 0,
                                 xml_type[i], xml_count[i], values[i]);
                }
                
            }
            ++num_vals;
            ok = sheet->next();
        }
        // Assemble result = { name, meta, type, count, values }
        for (i=0; i<name_count; ++i)
        {
            AutoXmlRpcValue result(
                xmlrpc_build_value(env, "{s:s,s:V,s:i,s:i,s:V}",
                                   "name",   names[i].c_str(),
                                   "meta",   meta[i].get(),
                                   "type",   xml_type[i],
                                   "count",  xml_count[i],
                                   "values", values[i].get()));    
            // Add to result array
            xmlrpc_array_append_item(env, results, result);
#ifdef LOGFILE
            LOG_MSG("Ch %lu: %zu values\n", i, ch_vals[i]);
#endif
        }
#ifdef LOGFILE
        LOG_MSG("%ld values total\n", num_vals);
#endif
        return results.release();
    }
    catch (GenericException &e)
    {
#ifdef LOGFILE
        LOG_MSG("Error:\n%s\n", e.what());
#endif
        xmlrpc_env_set_fault_formatted(env, ARCH_DAT_DATA_ERROR,
                                       "%s", e.what());
    }
    return 0;
}
Beispiel #29
0
// Return the data for all the names[], start .. end etc.
// as get_values() is supposed to return them.
// Returns 0 on error.
xmlrpc_value *get_channel_data(xmlrpc_env *env,
                               int key,
                               const stdVector<stdString> names,
                               const epicsTime &start, const epicsTime &end,
                               long count,
                               ReaderFactory::How how, double delta)
{
    AutoXmlRpcValue results;
    try
    {
#ifdef LOGFILE
        stdString txt;
        LOG_MSG("get_channel_data\n");
        LOG_MSG("Method: %s\n", ReaderFactory::toString(how, delta));
        LOG_MSG("Start:  %s\n", epicsTimeTxt(start, txt));
        LOG_MSG("End  :  %s\n", epicsTimeTxt(end, txt));
#endif
        AutoPtr<Index> index(open_index(env, key));
        if (env->fault_occurred)
            return 0;
        AutoPtr<DataReader> reader(ReaderFactory::create(*index, how, delta));
        results = xmlrpc_build_value(env, "()");
        if (env->fault_occurred)
            return 0;
        long i, name_count = names.size();
        for (i=0; i<name_count; ++i)
        {
#ifdef LOGFILE
            LOG_MSG("Handling '%s'\n", names[i].c_str());
#endif
            long num_vals = 0;            
            AutoXmlRpcValue values(xmlrpc_build_value(env, "()"));
            if (env->fault_occurred)
                return 0;
            const RawValue::Data *data = reader->find(names[i], &start);
            AutoXmlRpcValue meta;
            xmlrpc_int32 xml_type, xml_count;
            if (data == 0)
            {   // No exception from file error etc., just no data.
                meta = encode_ctrl_info(env, 0);
                xml_type = XML_ENUM;
                xml_count = 1;
            }
            else
            {
                // Fix meta/type/count based on first value
                meta = encode_ctrl_info(env, &reader->getInfo());
                dbr_type_to_xml_type(reader->getType(), reader->getCount(),
                                     xml_type, xml_count);
                while (num_vals < count
                       && data
                       && RawValue::getTime(data) < end)
                {
                    encode_value(env, reader->getType(), reader->getCount(),
                                 RawValue::getTime(data), data,
                                 xml_type, xml_count, values);
                    ++num_vals;
                    data = reader->next();
                }
            }
            // Assemble result = { name, meta, type, count, values }
            AutoXmlRpcValue result(xmlrpc_build_value(
                                       env, "{s:s,s:V,s:i,s:i,s:V}",
                                       "name",   names[i].c_str(),
                                       "meta",   (xmlrpc_value *)meta,
                                       "type",   xml_type,
                                       "count",  xml_count,
                                       "values", (xmlrpc_value *)values));
            // Add to result array
            xmlrpc_array_append_item(env, results, result);
#ifdef LOGFILE
            LOG_MSG("%ld values\n", num_vals);
#endif
        } // for ( .. name .. )
    }
    catch (GenericException &e)
    {
#ifdef LOGFILE
        LOG_MSG("Error:\n%s\n", e.what());
#endif
        xmlrpc_env_set_fault_formatted(env, ARCH_DAT_DATA_ERROR,
                                       "%s", e.what());
        return 0;
    }
    return results.release();
}
Beispiel #30
0
// Given a raw sample dbr_type/count/time/data,
// map it onto xml_type/count and add to values.
// Handles the special case data == 0,
// which happens for undefined cells in a SpreadsheetReader.
void encode_value(xmlrpc_env *env,
                  DbrType dbr_type, DbrCount dbr_count,
                  const epicsTime &time, const RawValue::Data *data,
                  xmlrpc_int32 xml_type, xmlrpc_int32 xml_count,
                  xmlrpc_value *values)
{
    if (xml_count > dbr_count)
        xml_count = dbr_count;
    AutoXmlRpcValue val_array(xmlrpc_build_value(env, "()"));
    if (env->fault_occurred)
        return;
    int i;
    switch (xml_type)
    {
        case XML_STRING:
        {
            stdString txt;
            if (data)
                RawValue::getValueString(txt, dbr_type, dbr_count, data, 0);
            AutoXmlRpcValue element(xmlrpc_build_value(env, "s#",
                                                       txt.c_str(), txt.length()));
            xmlrpc_array_append_item(env, val_array, element);
        }
        break;
        case XML_INT:
        case XML_ENUM:
        {
            long l;
            for (i=0; i < xml_count; ++i)
            {
                if (!data  ||
                    !RawValue::getLong(dbr_type, dbr_count, data, l, i))
                    l = 0;
                AutoXmlRpcValue element(xmlrpc_build_value(env, "i", (xmlrpc_int32)l));
                xmlrpc_array_append_item(env, val_array, element);
            }
        }
        break;
        case XML_DOUBLE:
        {
            double d;
            for (i=0; i < xml_count; ++i)
            {
                if (data  &&
                    RawValue::getDouble(dbr_type, dbr_count, data, d, i))
                
                {   /* XML-RPC, being XML, sends all numbers as strings.
                     * Unfortunately, XML-RPC also insists in the simple 'dot'
                     * notation and prohibits exponential notation.
                     * A number like 1e-300 would turn into
                     * "0.0000000..." with 300 zeroes,
                     * which is too long for the internal print buffer of
                     * the xml-rpc C library.
                     * Since such huge and tiny numbers can't be transferred,
                     * they are replaced by 0 with stat/sevr UDF/INVALID.
                     *
                     * The cut-off point is somewhat arbitrary.
                     * The XML-RPC library uses an internal print buffer
                     * of about 120 characters.
                     * Since PVs are usually scaled to be human-readable,
                     * with only vacuum readings using exp. notation for
                     * data like "1e-8 Torr", exponents of +-50 seemed
                     * reasonable.
                     */
                    if (d > 0.0)
                    {
                        if (d < 1e-50  ||  d > 1e50)   { d = 0.0; data = 0; }
                    }
                    else if (d < 0.0)
                    {  
                        if (d > -1e-50  ||  d < -1e50) { d = 0.0; data = 0; }
                    }
                } 
                else
                    d = 0.0;
                AutoXmlRpcValue element(xmlrpc_build_value(env, "d", d));
                xmlrpc_array_append_item(env, val_array, element);
            }
        }
    }
    xmlrpc_int32 secs, nano;
    epicsTime2pieces(time, secs, nano);
    AutoXmlRpcValue value;
    if (data)
        value.set(xmlrpc_build_value(
                      env, "{s:i,s:i,s:i,s:i,s:V}",
                      "stat", (xmlrpc_int32)RawValue::getStat(data),
                      "sevr", (xmlrpc_int32)RawValue::getSevr(data),
                      "secs", secs,
                      "nano", nano,
                      "value", (xmlrpc_value *)val_array));
    else
        value.set(xmlrpc_build_value(
                      env, "{s:i,s:i,s:i,s:i,s:V}",
                      "stat", (xmlrpc_int32)UDF_ALARM,
                      "sevr", (xmlrpc_int32)INVALID_ALARM,
                      "secs", secs,
                      "nano", nano,
                      "value",  (xmlrpc_value *)val_array));    
    xmlrpc_array_append_item(env, values, value);
}