Example #1
0
/* map free radius attribute to user defined json element name */
int mod_attribute_to_element(const char *name, json_object *map, void *buf) {
	json_object *jval;  /* json object values */

	/* clear buffer */
	memset((char *) buf, 0, MAX_KEY_SIZE);

	/* attempt to map attribute */
	if (json_object_object_get_ex(map, name, &jval)) {
		int length;     /* json value length */
		/* get value length */
		length = json_object_get_string_len(jval);
		/* check buffer size */
		if (length > MAX_KEY_SIZE -1) {
			/* oops ... this value is bigger than our buffer ... error out */
			ERROR("rlm_couchbase: json map value larger than MAX_KEY_SIZE - %d", MAX_KEY_SIZE);
			/* return fail */
			return -1;
		} else {
			/* copy string value to buffer */
			strncpy(buf, json_object_get_string(jval), length);
			/* return good */
			return 0;
		}
	}

	/* debugging */
	DEBUG("rlm_couchbase: skipping attribute with no map entry - %s", name);

	/* default return */
	return -1;
}
Example #2
0
static void set_grid(struct per_session_data *data, const char *buf) {
    int row, col;
    json_object *json_grid = json_tokener_parse(buf);
    if (json_object_get_type(json_grid) != json_type_array) {
        return;
    }
    if (json_object_array_length(json_grid) != NUM_ROWS) {
        return;
    }
    for (row = 0; row < NUM_ROWS; row++) {
        json_object *json_row = json_object_array_get_idx(json_grid, row);
        const char *row_buf;
        if (json_object_get_string_len(json_row) != NUM_COLS) {
            return;
        }
        row_buf = json_object_get_string(json_row);
        for (col = 0; col < NUM_COLS; col++) {
            color_t color;
            switch (row_buf[col]) {
                case 'R': color = RED;    break;
                case 'Y': color = YELLOW; break;
                case 'G': color = GREEN;  break;
                case 'B': color = BLUE;   break;
                case 'V': color = VIOLET; break;
                default: return;
            }
            data->grid[col] = SET_COLUMN_COLOR(data->grid[col], row, color);
        }
    }
    data->new_game = 0;
}
/**
 * Retrieve the authentication token and service catalog from a now-complete Keystone JSON response,
 * and store them in the Keystone context structure for later use.
 */
static enum keystone_error
process_keystone_json(keystone_context_t *context, struct json_object *response)
{
	struct json_object *access, *token, *id;

	if (context->pvt.debug) {
		json_object_to_file_ext("/dev/stderr", response, JSON_C_TO_STRING_PRETTY);
	}
	if (!json_object_is_type(response, json_type_object)) {
		context->keystone_error("response is not an object", KSERR_PARSE);
		return KSERR_PARSE; /* Not the expected JSON object */
	}
	/* Everything is in an "access" sub-object */
	if (!json_object_object_get_ex(response, "access", &access)) {
		context->keystone_error("response lacks 'access' key", KSERR_PARSE);
		return KSERR_PARSE; /* Lacking the expected key */
	}
	if (!json_object_is_type(access, json_type_object)) {
		context->keystone_error("response.access is not an object", KSERR_PARSE);
		return KSERR_PARSE; /* Not the expected JSON object */
	}
	/* Service catalog */
	if (!json_object_object_get_ex(access, "serviceCatalog", &context->pvt.services)) {
		context->keystone_error("response.access lacks 'serviceCatalog' key", KSERR_PARSE);
		return KSERR_PARSE;
	}
	if (!json_object_is_type(context->pvt.services, json_type_array)) {
		context->keystone_error("response.access.serviceCatalog not an array", KSERR_PARSE);
		return KSERR_PARSE;
	}
	/* Authentication token */
	if (!json_object_object_get_ex(access, "token", &token)) {
		context->keystone_error("reponse.access lacks 'token' key", KSERR_PARSE);
		return KSERR_PARSE; /* Lacking the expected key */
	}
	if (!json_object_is_type(token, json_type_object)) {
		context->keystone_error("response.access.token is not an object", KSERR_PARSE);
		return KSERR_PARSE; /* Not the expected JSON object */
	}
	if (!json_object_object_get_ex(token, "id", &id)) {
		context->keystone_error("response.access.token lacks 'id' key", KSERR_PARSE);
		return KSERR_PARSE; /* Lacking the expected key */
	}
	if (!json_object_is_type(id, json_type_string)) {
		context->keystone_error("response.access.token.id is not a string", KSERR_PARSE);
		return KSERR_PARSE; /* Not the expected JSON string */
	}
	context->pvt.auth_token = context->allocator(
		context->pvt.auth_token,
		json_object_get_string_len(id)
		+ 1 /* '\0' */
	);
	if (NULL == context->pvt.auth_token) {
		return KSERR_PARSE; /* Allocation failed */
	}
	strcpy(context->pvt.auth_token, json_object_get_string(id));

	return KSERR_SUCCESS;
}
Example #4
0
int pv_get_json (struct sip_msg* msg,  pv_param_t* pvp, pv_value_t* val)
{

	pv_json_t * var ;
	json_t * obj;
	json_name * id = (json_name *) pvp->pvn.u.dname;
	UNUSED(id);


	if( expand_tag_list( msg, ((json_name *)pvp->pvn.u.dname)->tags ) < 0)
	{
		LM_ERR("Cannot expand variables in path\n");
		return pv_get_null( msg, pvp, val);
	}


	var = get_pv_json(pvp);

	if( var == NULL )
	{
		/* this is not an error - we simply came across a json spec
		 * pointing a json var which was never set/init */
		LM_DBG("Variable named:%.*s not found\n",id->name.len,id->name.s);
		return pv_get_null( msg, pvp, val);
	}

	obj = get_object(var, pvp, NULL, 0);
	memset(val, 0, sizeof(pv_value_t));

	if( obj == NULL )
		return pv_get_null( msg, pvp, val);

	if( json_object_is_type(obj, json_type_int) )
	{
		val->rs.s = sint2str(json_object_get_int(obj), &val->rs.len);
		val->ri = json_object_get_int(obj);;
		val->flags |= PV_VAL_INT|PV_TYPE_INT|PV_VAL_STR;

	}
	else if( json_object_is_type(obj, json_type_string))
	{
		val->flags = PV_VAL_STR;
		val->rs.s = (char*)json_object_get_string( obj );
#if JSON_LIB_VERSION >= 10
		val->rs.len = json_object_get_string_len( obj );
#else
		val->rs.len = strlen(val->rs.s);
#endif
	} else {
		val->flags = PV_VAL_STR;
		val->rs.s = (char*)json_object_to_json_string( obj );
		val->rs.len = strlen(val->rs.s);
	}

	return 0;
}
/**
 *  Get the string length at a certain index
 *  @param  index
 *  @return string
 */
size_t Array::strlen(int index) const
{
    // get the value at this location
    json_object *value = json_object_array_get_idx(_json, index);

    // in case our type isn't string we return an empty string
    if (json_object_get_type(value) != json_type_string) return 0;

    // get the string length
    return json_object_get_string_len(value);
}
Example #6
0
Variant json_object_to_variant(json_object *new_obj, const bool assoc,
                               const bool stable_maps, const bool collections) {
    json_type type;
    int64_t i64;

    if (!new_obj) {
        return Variant(Variant::NullInit());
    }

    type = json_object_get_type(new_obj);
    switch (type) {
    case json_type_double:
        return Variant(json_object_get_double(new_obj));

    case json_type_string:
        return Variant(String(json_object_get_string(new_obj),
                              json_object_get_string_len(new_obj),
                              CopyString));

    case json_type_int:
        i64 = json_object_get_int64(new_obj);
        if (i64==INT64_MAX || i64==INT64_MIN) {
            // php notice: integer overflow detected
        }
        return Variant(i64);

    case json_type_boolean:
        if (json_object_get_boolean(new_obj)) {
            return Variant(true);
        } else {
            return Variant(false);
        }

    case json_type_null:
        return Variant(Variant::NullInit());

    case json_type_array:
        return json_type_array_to_variant(new_obj, assoc, stable_maps,
                                          collections);

    case json_type_object:
        return json_type_object_to_variant(new_obj, assoc, stable_maps,
                                           collections);

    default:
        // warning type <type> not yet implemented
        return Variant(Variant::NullInit());
    }
}
static void GenStat(Stat* s, json_object* v) {
    switch (json_object_get_type(v)) {
    case json_type_object:
        {
            json_object_object_foreach(v, key, val) {
                GenStat(s, val);
                s->stringCount++;
                s->stringLength += strlen(key);
                s->memberCount++;
            }
            s->objectCount++;
        }
        break;

    case json_type_array:
        for (int i = 0; i < json_object_array_length(v); i++)
            GenStat(s, json_object_array_get_idx(v, i));
        s->elementCount += json_object_array_length(v);
        s->arrayCount++;
        break;

    case json_type_string:
        s->stringCount++;
        s->stringLength += json_object_get_string_len(v);
        break;

    case json_type_int:
    case json_type_double:
        s->numberCount++;
        break;

    case json_type_boolean:
        if (json_object_get_boolean(v))
            s->trueCount++;
        else
            s->falseCount++;
        break;

        break;

    case json_type_null:
        s->nullCount++;
        break;
    }
Example #8
0
int command_forward(json_object *json, BIO *bio_src)
{
   int r = -1, len = 0;
   json_object *params = NULL, *body = NULL;
   char *address = NULL, *cookie = NULL, *data = NULL, buf[100 * 1024];
   BIO *bio_conn = NULL;

   do {
      if(!(params = json_object_object_get(json, "params"))) break;
      if(!(address = (char *)json_object_get_string(json_object_object_get(params, "address")))) break;
      logme(LOGMSG_DEBUG, "FORWARD -> address: %s", address);
      if(!(cookie = (char *)json_object_get_string(json_object_object_get(params, "cookie")))) break;
      logme(LOGMSG_DEBUG, "FORWARD -> cookie: %s", cookie);

      if(!(body = json_object_object_get(json, "body"))) break;
      if(!(data = (char *)json_object_get_string(body))) break;
      if(!(len = json_object_get_string_len(body))) break;
      logme(LOGMSG_DEBUG, "FORWARD -> data: %d bytes", len);

      if(!(bio_conn = BIO_new_connect(address))) break;
      if(BIO_do_connect(bio_conn) <= 0) { logme(LOGMSG_ERROR, "Unable to connect to %s", address); break; }
      if(BIO_printf(bio_conn, "POST / HTTP/1.0\r\n" \
                              "Host: %s\r\n" \
                              "Accept: */" "*\r\n" \
                              "Cookie: %s\r\n" \
                              "Content-Length: %d\r\n" \
                              "Content-Type: application/octet-stream\r\n" \
                              "Connection: close\r\n" \
                              "\r\n",
                              address, cookie, len) <= 0) break;
      if(BIO_write(bio_conn, data, len) != len) break;
      (void)BIO_flush(bio_conn);

      while((len = BIO_read(bio_conn, buf, sizeof(buf))) > 0) if(BIO_write(bio_src, buf, len) != len) break;
      if(len != 0) break;

      r = 0;
   } while(0);
   if(bio_conn) BIO_free(bio_conn);

   return r;
}
Example #9
0
void LoginOutputData::parse(json_object* obj) {
    if (obj == NULL)
        return;

    json_object* node;

    node = json_object_object_get(obj, "accountid");
    this->accountid = json_object_get_int(node);
    node = json_object_object_get(obj, "nickname");
    this->nickname.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "gender");
    this->gender = json_object_get_int(node);
    node = json_object_object_get(obj, "birthday");
    this->birthday.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "rank");
    this->rank.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "introduction");
    this->introduction.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "points");
    this->points = json_object_get_int(node);
    node = json_object_object_get(obj, "impactpower");
    this->impactpower = json_object_get_int(node);
    node = json_object_object_get(obj, "listenpower");
    this->listenpower = json_object_get_int(node);
    node = json_object_object_get(obj, "avatar");
    this->avatar.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "voice");
    this->voice.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "voicetime");
    this->voicetime = json_object_get_int(node);
    node = json_object_object_get(obj, "viptypeid");
    this->viptypeid = json_object_get_int(node);
    node = json_object_object_get(obj, "vipstarttime");
    this->vipstarttime.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "vipexpiretime");
    this->vipexpiretime.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "created");
    this->created.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "status");
    this->status = json_object_get_int(node);
    node = json_object_object_get(obj, "kind");
    this->kind = json_object_get_int(node);
    node = json_object_object_get(obj, "gold");
    this->gold = json_object_get_int(node);
    node = json_object_object_get(obj, "nativeplace");
    this->nativeplace.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "occupation");
    this->occupation.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "dialect");
    this->dialect.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "devicetoken");
    this->devicetoken.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "ipowerlevel");
    this->ipowerlevel = json_object_get_int(node);
    node = json_object_object_get(obj, "lpowerlevel");
    this->lpowerlevel = json_object_get_int(node);
    node = json_object_object_get(obj, "isaskpermit");
    this->isaskpermit = json_object_get_int(node);
    node = json_object_object_get(obj, "isagainstpermit");
    this->isagainstpermit = json_object_get_int(node);
    node = json_object_object_get(obj, "giftcount");
    this->giftcount = json_object_get_int(node);
    node = json_object_object_get(obj, "pickuppoints");
    this->pickuppoints = json_object_get_int(node);
    node = json_object_object_get(obj, "levelconfig");
    node = json_object_object_get(obj, "isquickuser");
    this->isquickuser = json_object_get_int(node);
    node = json_object_object_get(obj, "isplisttester");
    this->isplisttester = json_object_get_int(node);
    node = json_object_object_get(obj, "clientversion");
    this->clientversion.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "updateurl");
    this->updateurl.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "updatedesc");
    this->updatedesc.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "restoredefaultplist");
    this->restoredefaultplist = json_object_get_int(node);
    node = json_object_object_get(obj, "bindplatformlist");
    array_list* array =  json_object_get_array(obj);
    if (array) {
        int len = array_list_length(array);
        for (int i = 0; i < len; i++) {
            json_object *obj = (json_object*)array_list_get_idx(array, i);
            if (!obj)
                continue;

            json_type type = json_object_get_type(obj);
            if (type == json_type_object) {
                //* tmp = new ();
                //tmp.parse(obj);
                //bindplatformlist.push_back(tmp);
            } else if (type == json_type_int) {
                //bindplatformlist.push_back(itoa(json_object_get_int(obj)));
            } else if (type == json_type_double) {
                //bindplatformlist.push_back(json_object_get_double(obj));
            } else if (type == json_type_string) {
                string str;
                bindplatformlist.push_back(str.assign(json_object_get_string(obj), json_object_get_string_len(obj)));
            }
        }
    }
    node = json_object_object_get(obj, "username");
    this->username.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "platform");
    this->platform.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "askpoints1");
    this->askpoints1 = json_object_get_int(node);
    node = json_object_object_get(obj, "askpoints2");
    this->askpoints2 = json_object_get_int(node);
    node = json_object_object_get(obj, "background");
    this->background.assign(json_object_get_string(node), json_object_get_string_len(node));
    node = json_object_object_get(obj, "pushmessage");
    this->pushmessage = json_object_get_int(node);
    node = json_object_object_get(obj, "lbs");
    this->lbs = json_object_get_int(node);
    node = json_object_object_get(obj, "weixinur");
    this->weixinur = json_object_get_int(node);
    node = json_object_object_get(obj, "activitystatus");
    this->activitystatus = json_object_get_int(node);
    node = json_object_object_get(obj, "shareversions");
    this->shareversions = json_object_get_int(node);
    node = json_object_object_get(obj, "isnewdialect");
    this->isnewdialect = json_object_get_int(node);
    node = json_object_object_get(obj, "vcolor");
    this->vcolor = json_object_get_int(node);
    node = json_object_object_get(obj, "isready");
    this->isready = json_object_get_int(node);
    node = json_object_object_get(obj, "tabidx");
    this->tabidx = json_object_get_int(node);


}
Example #10
0
int pv_get_json_ext(struct sip_msg* msg,  pv_param_t* pvp, pv_value_t* val, int flags)
{

	pv_json_t * var ;
	json_t * obj;
	json_name * id = (json_name *) pvp->pvn.u.dname;
	UNUSED(id);

	if( expand_tag_list( msg, ((json_name *)pvp->pvn.u.dname)->tags ) < 0)
	{
		LM_ERR("Cannot expand variables in path\n");
		return pv_get_null( msg, pvp, val);
	}


	var = get_pv_json(pvp);

	if( var == NULL )
	{
		/* this is not an error - we simply came across a json spec
		 * pointing a json var which was never set/init */
		LM_DBG("Variable named:%.*s not found\n",id->name.len,id->name.s);
		return pv_get_null( msg, pvp, val);
	}

	obj = get_object(var, pvp, NULL, 0, 0);

	memset(val, 0, sizeof(pv_value_t));

	if( obj == NULL )
		return pv_get_null( msg, pvp, val);

	if (pvp->pvi.type == PV_IDX_INT) {
		if (pv_json_iterate(&obj, pvp, id, val) < 0) {
			LM_DBG("Failed to iterate\n");
			return pv_get_null(msg, pvp, val);
		}

		if (val->flags == PV_VAL_STR || val->flags == PV_VAL_NULL)
			/* val is set */
			return 0;
		/* else we got an object */
	} else if (pvp->pvi.type == PV_IDX_ALL) {
		LM_ERR("\"[*]\" index only supported in for each statement\n");
		return pv_get_null(msg, pvp, val);
	}

	if( json_object_is_type(obj, json_type_int) )
	{
		val->rs.s = sint2str(json_object_get_int(obj), &val->rs.len);
		val->ri = json_object_get_int(obj);;
		val->flags |= PV_VAL_INT|PV_TYPE_INT|PV_VAL_STR;

	}
	else if( json_object_is_type(obj, json_type_string))
	{
		val->flags = PV_VAL_STR;
		val->rs.s = (char*)json_object_get_string( obj );
#if JSON_C_VERSION_NUM >= JSON_C_VERSION_010
		val->rs.len = json_object_get_string_len( obj );
#else
		val->rs.len = strlen(val->rs.s);
#endif
	} else {
		val->flags = PV_VAL_STR;
		val->rs.s = (char*)json_object_to_json_string_ext( obj, flags);
		val->rs.len = strlen(val->rs.s);
	}

	return 0;
}
Example #11
0
int main(int argc, char **argv)
{
	struct json_object *json;
	struct array_list *tests;
	struct lh_entry *entry;
	char *key;
	struct json_object *val;
	int i;
	context ctx;

	if (argc != 2) {
		printf("Usage: %s <filename>\n", argv[0]);
		return 1;
	}

	json = json_object_from_file(argv[1]);
	assert(!is_error(json));

	assert(strcmp((char *) ((json_object_get_object(json)->head)->k),
			"tests") == 0);

	/* Get array of tests */
	tests = json_object_get_array((struct json_object *)
			(json_object_get_object(json)->head)->v);

	for (i = 0; i < array_list_length(tests); i++) {
		/* Get test */
		struct json_object *test =
			(struct json_object *) array_list_get_idx(tests, i);

		ctx.last_start_tag = NULL;
		ctx.content_model = NULL;
		ctx.process_cdata = false;

		/* Extract settings */
		for (entry = json_object_get_object(test)->head; entry;
				entry = entry->next) {
			key = (char *) entry->k;
			val = (struct json_object *) entry->v;

			if (strcmp(key, "description") == 0) {
				printf("Test: %s\n",
					json_object_get_string(val));
			} else if (strcmp(key, "input") == 0) {
				ctx.input = (const uint8_t *)
					json_object_get_string(val);
				ctx.input_len =	json_object_get_string_len(val);
			} else if (strcmp(key, "output") == 0) {
				ctx.output = json_object_get_array(val);
				ctx.output_index = 0;
				ctx.char_off = 0;
			} else if (strcmp(key, "lastStartTag") == 0) {
				ctx.last_start_tag = (const char *)
						json_object_get_string(val);
			} else if (strcmp(key, "contentModelFlags") == 0) {
				ctx.content_model =
						json_object_get_array(val);
			} else if (strcmp(key, "processCDATA") == 0) {
				ctx.process_cdata =
					json_object_get_boolean(val);
			}
		}

		/* And run the test */
		run_test(&ctx);
	}

	json_object_put(json);

	printf("PASS\n");

	return 0;
}
Example #12
0
hubbub_error token_handler(const hubbub_token *token, void *pw)
{
	static const char *token_names[] = {
		"DOCTYPE", "StartTag", "EndTag",
		"Comment", "Character", "EOF"
	};
	size_t i;
	context *ctx = (context *) pw;
	struct json_object *obj = NULL;
	struct array_list *items;

	for (; ctx->output_index < array_list_length(ctx->output);
			ctx->output_index++) {
		/* Get object for index */
		obj = (struct json_object *)
				array_list_get_idx(ctx->output,
						ctx->output_index);

		/* If it's not a string, we've found the expected output */
		if (json_object_get_type(obj) != json_type_string)
			break;

		/* Otherwise, it must be a parse error */
		assert(strcmp(json_object_get_string(obj),
				 "ParseError") == 0);
	}

	/* If we've run off the end, this is an error -- the tokeniser has
	 * produced more tokens than expected. We allow for the generation
	 * of a terminating EOF token, however. */
	assert("too many tokens" &&
			(ctx->output_index < array_list_length(ctx->output) ||
			token->type == HUBBUB_TOKEN_EOF));

	/* Got a terminating EOF -- no error */
	if (ctx->output_index >= array_list_length(ctx->output))
		return HUBBUB_OK;

	/* Now increment the output index so we don't re-expect this token */
	ctx->output_index++;

	/* Expected output must be an array */
	assert(json_object_get_type(obj) == json_type_array);

	items = json_object_get_array(obj);

	printf("got %s: expected %s\n", token_names[token->type],
			json_object_get_string((struct json_object *)
				array_list_get_idx(items, 0)));

	/* Make sure we got the token we expected */
	assert(strcmp(token_names[token->type],
			json_object_get_string((struct json_object *)
				array_list_get_idx(items, 0))) == 0);

	switch (token->type) {
	case HUBBUB_TOKEN_DOCTYPE:
	{
		const char *expname = json_object_get_string(
				array_list_get_idx(items, 1));
		const char *exppub = json_object_get_string(
				array_list_get_idx(items, 2));
		const char *expsys = json_object_get_string(
				array_list_get_idx(items, 3));
		bool expquirks = !json_object_get_boolean(
				array_list_get_idx(items, 4));
		const char *gotname = (const char *)token->data.doctype.name.ptr;
		const char *gotpub, *gotsys;

		printf("'%.*s' %sids:\n",
				(int) token->data.doctype.name.len,
				gotname,
				token->data.doctype.force_quirks ?
						"(force-quirks) " : "");

		if (token->data.doctype.public_missing) {
			gotpub = NULL;
			printf("\tpublic: missing\n");
		} else {
			gotpub = (const char *) token->data.doctype.public_id.ptr;
			printf("\tpublic: '%.*s' (%d)\n",
				(int) token->data.doctype.public_id.len,
				gotpub,
				(int) token->data.doctype.public_id.len);
		}

		if (token->data.doctype.system_missing) {
			gotsys = NULL;
			printf("\tsystem: missing\n");
		} else {
			gotsys = (const char *) token->data.doctype.system_id.ptr;
			printf("\tsystem: '%.*s' (%d)\n",
				(int) token->data.doctype.system_id.len,
				gotsys,
				(int) token->data.doctype.system_id.len);
		}

		assert(token->data.doctype.name.len == strlen(expname));
		assert(strncmp(gotname, expname, strlen(expname)) == 0);

		assert((exppub == NULL) ==
				(token->data.doctype.public_missing == true));
		if (exppub) {
			assert(token->data.doctype.public_id.len == strlen(exppub));
			assert(strncmp(gotpub, exppub, strlen(exppub)) == 0);
		}

		assert((expsys == NULL) ==
				(token->data.doctype.system_missing == true));
		if (gotsys) {
			assert(token->data.doctype.system_id.len == strlen(expsys));
			assert(strncmp(gotsys, expsys, strlen(expsys)) == 0);
		}

		assert(expquirks == token->data.doctype.force_quirks);
	}
		break;
	case HUBBUB_TOKEN_START_TAG:
	{
		const char *expname = json_object_get_string(
				array_list_get_idx(items, 1));
		struct lh_entry *expattrs = json_object_get_object(
				array_list_get_idx(items, 2))->head;
		bool self_closing = json_object_get_boolean(
				array_list_get_idx(items, 3));

		const char *tagname = (const char *)
				token->data.tag.name.ptr;

		printf("expected: '%s' %s\n",
				expname,
				(self_closing) ? "(self-closing) " : "");

		printf("     got: '%.*s' %s\n",
				(int) token->data.tag.name.len,
				tagname,
				(token->data.tag.self_closing) ?
						"(self-closing) " : "");

		if (token->data.tag.n_attributes > 0) {
			printf("attributes:\n");
		}

		assert(token->data.tag.name.len == strlen(expname));
		assert(strncmp(tagname, expname, strlen(expname)) == 0);

		assert((token->data.tag.n_attributes == 0) ==
				(expattrs == NULL));

		assert(self_closing == token->data.tag.self_closing);

		for (i = 0; i < token->data.tag.n_attributes; i++) {
			char *expname = (char *) expattrs->k;
			const char *expval = json_object_get_string(
					(struct json_object *) expattrs->v);
			const char *gotname = (const char *)
				token->data.tag.attributes[i].name.ptr;
			size_t namelen =
				token->data.tag.attributes[i].name.len;
			const char *gotval = (const char *)
				token->data.tag.attributes[i].value.ptr;
			size_t vallen =
				token->data.tag.attributes[i].value.len;

			printf("\t'%.*s' = '%.*s'\n",
					(int) namelen, gotname,
					(int) vallen, gotval);

			assert(namelen == strlen(expname));
			assert(strncmp(gotname, expname,
						strlen(expname)) == 0);
			assert(vallen == strlen(expval));
			assert(strncmp(gotval, expval, strlen(expval)) == 0);

			expattrs = expattrs->next;
		}

		assert(expattrs == NULL);
	}
		break;
	case HUBBUB_TOKEN_END_TAG:
	{
		const char *expname = json_object_get_string(
				array_list_get_idx(items, 1));
		const char *tagname = (const char *)
				token->data.tag.name.ptr;

		printf("'%.*s' %s\n",
				(int) token->data.tag.name.len,
				tagname,
				(token->data.tag.n_attributes > 0) ?
						"attributes:" : "");

		assert(token->data.tag.name.len == strlen(expname));
		assert(strncmp(tagname, expname, strlen(expname)) == 0);
	}
		break;
	case HUBBUB_TOKEN_COMMENT:
	{
		const char *expstr = json_object_get_string(
				array_list_get_idx(items, 1));
		const char *gotstr = (const char *)
				token->data.comment.ptr;

		printf("expected: '%s'\n", expstr);
		printf("     got: '%.*s'\n",
				(int) token->data.comment.len, gotstr);

		assert(token->data.comment.len == strlen(expstr));
		assert(strncmp(gotstr, expstr, strlen(expstr)) == 0);
	}
		break;
	case HUBBUB_TOKEN_CHARACTER:
	{
		int expstrlen = json_object_get_string_len(
				array_list_get_idx(items, 1));
		const char *expstr =json_object_get_string( 
				array_list_get_idx(items, 1));
		const char *gotstr = (const char *)
				token->data.character.ptr;
		size_t len = min(token->data.character.len,
				expstrlen - ctx->char_off);

		printf("expected: '%.*s'\n", (int) len, expstr + ctx->char_off);
		printf("     got: '%.*s'\n", 
				(int) token->data.character.len, gotstr);

		assert(memcmp(gotstr, expstr + ctx->char_off, len) == 0);

		if (len < token->data.character.len) {
			/* Expected token only contained part of the data
			 * Calculate how much is left, then try again with
			 * the next expected token */
			hubbub_token t;

			t.type = HUBBUB_TOKEN_CHARACTER;
			t.data.character.ptr += len;
			t.data.character.len -= len;

			ctx->char_off = 0;

			token_handler(&t, pw);
		} else if (strlen(expstr + ctx->char_off) >
				token->data.character.len) {
			/* Tokeniser output only contained part of the data
			 * in the expected token; calculate the offset into
			 * the token and process the remainder next time */
			ctx->char_off += len;
			ctx->output_index--;
		} else {
			/* Exact match - clear offset */
			ctx->char_off = 0;
		}
	}
		break;
	case HUBBUB_TOKEN_EOF:
		printf("\n");
		break;
	}

	return HUBBUB_OK;
}
/* write accounting data to couchbase */
static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *request) {
	rlm_couchbase_t *inst = instance;   /* our module instance */
	void *handle = NULL;                /* connection pool handle */
	VALUE_PAIR *vp;                     /* radius value pair linked list */
	char dockey[MAX_KEY_SIZE];          /* our document key */
	char document[MAX_VALUE_SIZE];      /* our document body */
	char element[MAX_KEY_SIZE];         /* mapped radius attribute to element name */
	int status = 0;                     /* account status type */
	int docfound = 0;                   /* document found toggle */
	lcb_error_t cb_error = LCB_SUCCESS; /* couchbase error holder */

	/* assert packet as not null */
	rad_assert(request->packet != NULL);

	/* sanity check */
	if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE, 0, TAG_ANY)) == NULL) {
		/* log debug */
		RDEBUG("could not find status type in packet");
		/* return */
		return RLM_MODULE_NOOP;
	}

	/* set status */
	status = vp->vp_integer;

	/* acknowledge the request but take no action */
	if (status == PW_STATUS_ACCOUNTING_ON || status == PW_STATUS_ACCOUNTING_OFF) {
		/* log debug */
		RDEBUG("handling accounting on/off request without action");
		/* return */
		return RLM_MODULE_OK;
	}

	/* get handle */
	handle = fr_connection_get(inst->pool);

	/* check handle */
	if (!handle) return RLM_MODULE_FAIL;

	/* set handle pointer */
	rlm_couchbase_handle_t *handle_t = handle;

	/* set couchbase instance */
	lcb_t cb_inst = handle_t->handle;

	/* set cookie */
	cookie_t *cookie = handle_t->cookie;

	/* check cookie */
	if (cookie) {
		/* clear cookie */
		memset(cookie, 0, sizeof(cookie_t));
	} else {
		/* log error */
		RERROR("cookie not usable - possibly not allocated");
		/* free connection */
		if (handle) {
			fr_connection_release(inst->pool, handle);
		}
		/* return */
		return RLM_MODULE_FAIL;
	}

	/* attempt to build document key */
	if (radius_xlat(dockey, sizeof(dockey), request, inst->acct_key, NULL, NULL) < 0) {
		/* log error */
		RERROR("could not find accounting key attribute (%s) in packet", inst->acct_key);
		/* release handle */
		if (handle) {
			fr_connection_release(inst->pool, handle);
		}
		/* return */
		return RLM_MODULE_NOOP;
	}

	/* init cookie error status */
	cookie->jerr = json_tokener_success;

	/* attempt to fetch document */
	cb_error = couchbase_get_key(cb_inst, cookie, dockey);

	/* check error */
	if (cb_error != LCB_SUCCESS || cookie->jerr != json_tokener_success) {
		/* log error */
		RERROR("failed to execute get request or parse returned json object");
		/* free json object */
		if (cookie->jobj) {
			json_object_put(cookie->jobj);
		}
	} else {
		/* check cookie json object */
		if (cookie->jobj != NULL) {
			/* set doc found */
			docfound = 1;
			/* debugging */
			RDEBUG("parsed json body from couchbase: %s", json_object_to_json_string(cookie->jobj));
		}
	}

	/* start json document if needed */
	if (docfound != 1) {
		/* debugging */
		RDEBUG("document not found - creating new json document");
		/* create new json object */
		cookie->jobj = json_object_new_object();
		/* set 'docType' element for new document */
		json_object_object_add(cookie->jobj, "docType", json_object_new_string(inst->doctype));
		/* set start and stop times ... ensure we always have these elements */
		json_object_object_add(cookie->jobj, "startTimestamp", json_object_new_string("null"));
		json_object_object_add(cookie->jobj, "stopTimestamp", json_object_new_string("null"));
	}

	/* status specific replacements for start/stop time */
	switch (status) {
		case PW_STATUS_START:
			/* add start time */
			if ((vp = pairfind(request->packet->vps, PW_EVENT_TIMESTAMP, 0, TAG_ANY)) != NULL) {
				/* add to json object */
				json_object_object_add(cookie->jobj, "startTimestamp", mod_value_pair_to_json_object(request, vp));
			}
		break;
		case PW_STATUS_STOP:
			/* add stop time */
			if ((vp = pairfind(request->packet->vps, PW_EVENT_TIMESTAMP, 0, TAG_ANY)) != NULL) {
				/* add to json object */
				json_object_object_add(cookie->jobj, "stopTimestamp", mod_value_pair_to_json_object(request, vp));
			}
			/* check start timestamp and adjust if needed */
			mod_ensure_start_timestamp(cookie->jobj, request->packet->vps);
		break;
		case PW_STATUS_ALIVE:
			/* check start timestamp and adjust if needed */
			mod_ensure_start_timestamp(cookie->jobj, request->packet->vps);
		break;
		default:
			/* we shouldn't get here - free json object */
			if (cookie->jobj) {
				json_object_put(cookie->jobj);
			}
			/* release our connection handle */
			if (handle) {
				fr_connection_release(inst->pool, handle);
			}
			/* return without doing anything */
			return RLM_MODULE_NOOP;
	}

	/* loop through pairs and add to json document */
	for (vp = request->packet->vps; vp; vp = vp->next) {
		/* map attribute to element */
		if (mod_attribute_to_element(vp->da->name, inst->map, &element) == 0) {
			/* debug */
			RDEBUG("mapped attribute %s => %s", vp->da->name, element);
			/* add to json object with mapped name */
			json_object_object_add(cookie->jobj, element, mod_value_pair_to_json_object(request, vp));
		}
	}

	/* make sure we have enough room in our document buffer */
	if ((unsigned int) json_object_get_string_len(cookie->jobj) > sizeof(document) - 1) {
		/* this isn't good */
		RERROR("could not write json document - insufficient buffer space");
		/* free json output */
		if (cookie->jobj) {
			json_object_put(cookie->jobj);
		}
		/* release handle */
		if (handle) {
			fr_connection_release(inst->pool, handle);
		}
		/* return */
		return RLM_MODULE_FAIL;
	} else {
		/* copy json string to document */
		strlcpy(document, json_object_to_json_string(cookie->jobj), sizeof(document));
		/* free json output */
		if (cookie->jobj) {
			json_object_put(cookie->jobj);
		}
	}

	/* debugging */
	RDEBUG("setting '%s' => '%s'", dockey, document);

	/* store document/key in couchbase */
	cb_error = couchbase_set_key(cb_inst, dockey, document, inst->expire);

	/* check return */
	if (cb_error != LCB_SUCCESS) {
		RERROR("failed to store document (%s): %s (0x%x)", dockey, lcb_strerror(NULL, cb_error), cb_error);
	}

	/* release handle */
	if (handle) {
		fr_connection_release(inst->pool, handle);
	}

	/* return */
	return RLM_MODULE_OK;
}
Example #14
0
int
read_handler(int fd)
{
    char rbuf[MAXPKTSIZE] = "";
    int readbytes;
    json_object *jobj;
    int ctype;
    int is_reg_pkt = 0;
    int numtoread;

#ifdef WWDEBUG
    fprintf(stderr, "About to read on FD - %d, type - %d\n", fd, sock_data[fd].ctype);
#endif

    // First check if there is any remaining payload from previous
    // transmission for this socket and decide the # of bytes to read.
    if ((sock_data[fd].r_payloadlen > 0) && (sock_data[fd].r_payloadlen < MAXPKTSIZE - 1)) {
        numtoread = sock_data[fd].r_payloadlen;
    } else {
        numtoread = MAXPKTSIZE - 1;
    }

    if ((readbytes = recv(fd, rbuf, numtoread, 0)) == -1) {
        perror("recv");
        FD_CLR(fd, &rfds);
        close(fd);
        return 0;
    }
    rbuf[readbytes] = '\0';
    //fprintf(stderr, "Rx a string of size %d - %s\n",readbytes,rbuf);
    //fprintf(stderr, "Rx a string of size %d \n",readbytes);

    // Is this required ?
    if (strlen(rbuf) == 0) {
#ifdef WWDEBUG
        fprintf(stderr, "\nSeems like the remote client connected\n");
        fprintf(stderr, "to this socket has closed its connection\n");
        fprintf(stderr, "So I'm closing the socket\n");
#endif
        FD_CLR(fd, &rfds);
        close(fd);
        return 0;
    }
    // If the read buffer is from pending transmission append to accrualbuf
    // Or else treat it as a new packet.
    if (sock_data[fd].r_payloadlen > 0) {
        strcat(sock_data[fd].accrual_buf, rbuf);
        sock_data[fd].r_payloadlen = sock_data[fd].r_payloadlen - readbytes;
    } else {
        apphdr *app_h = (apphdr *) rbuf;
        appdata *app_d = (appdata *) (rbuf + sizeof(apphdr));

        //printf("Len of the payload - %d, %s\n", app_h->len,app_d->payload);

        // plus 1 to store the NULL char
        sock_data[fd].accrual_buf = (char *) malloc(app_h->len + 1);
        strcpy(sock_data[fd].accrual_buf, app_d->payload);
        sock_data[fd].r_payloadlen = app_h->len - strlen(sock_data[fd].accrual_buf);
        //printf("strlen(sock_data[%d].accrual_buf) = %d\n", fd, strlen(sock_data[fd].accrual_buf));
    }

    if (sock_data[fd].r_payloadlen > 0) {
        //Still has more reading to do
        //printf("r_payloadlen = %d\n", sock_data[fd].r_payloadlen);
        return (0);
    }
#ifdef WWDEBUG
    printf("Done reading totally, now processing the received data packet\n");
#endif

/*
  if(sock_data[fd].ctype == UNKNOWN) {
	int ctype;
	ctype = get_int_from_json(json_tokener_parse(sock_data[fd].accrual_buf),"CONN_TYPE");
	if(ctype == -1) {
	  printf("Not able to determine type\n");
	} else {
	  sock_data[fd].ctype = ctype;
	  //printf("Conn type - %d on sock - %d\n",ctype, fd);
	}
   } else if(sock_data[fd].ctype == COLLECTOR) {
*/

    jobj = json_tokener_parse(sock_data[fd].accrual_buf);
    ctype = get_int_from_json(jobj, "CONN_TYPE");
    if (ctype == -1) {
#ifdef WWDEBUG
        printf("Either not able to determine type or not a registration packet\n");
#endif
    } else {
        sock_data[fd].ctype = ctype;
        is_reg_pkt = 1;
        //printf("Conn type - %d on sock - %d\n",ctype, fd);
    }

    if (is_reg_pkt != 1) {
        if (sock_data[fd].ctype == COLLECTOR) {
            apphdr *app_h = (apphdr *) rbuf;

            //printf("%s\n",sock_data[fd].accrual_buf);
            update_dbase(app_h->timestamp, app_h->nodename, jobj);
        } else if (sock_data[fd].ctype == APPLICATION) {
            const char *sqlite_cmd;
            size_t cmd_len = 0;
            json_object *json_sqlite_cmd;

            json_sqlite_cmd = json_object_object_get(jobj, "sqlite_cmd");
            if (json_sqlite_cmd) {
                sqlite_cmd = json_object_get_string(json_sqlite_cmd);
                cmd_len = json_object_get_string_len(json_sqlite_cmd);
            }

            sock_data[fd].sqlite_cmd = malloc(MAX_SQL_SIZE);
            if (cmd_len) {
                char sql_stmt[] = "SELECT nodename,jsonblob FROM " SQLITE_DB_TB1NAME " LEFT JOIN " SQLITE_DB_TB2NAME " ON "
                    SQLITE_DB_TB1NAME ".rowid = " SQLITE_DB_TB2NAME ".blobid WHERE ";

                /* FIXME */
                strcpy(sock_data[fd].sqlite_cmd, sql_stmt);
                strcat(sock_data[fd].sqlite_cmd, sqlite_cmd);
            } else {
                // App sent an empty SQL command so we need to return all JSONs we have
                strcpy(sock_data[fd].sqlite_cmd, "SELECT nodename,jsonblob FROM " SQLITE_DB_TB1NAME);
            }
        }
    }
    json_object_put(jobj);

    if (sock_data[fd].accrual_buf != NULL) {
        free(sock_data[fd].accrual_buf);
        sock_data[fd].accrual_buf = NULL;
    }
    FD_CLR(fd, &rfds);
    FD_SET(fd, &wfds);
    return 0;
}
Example #15
0
OSStatus _property_write_create_response(struct mico_service_t *service_table, 
                                    char *key, json_object *val,
                                    json_object *out_write_obj, json_object *out_err_prop_obj)
{
  OSStatus err = kUnknownErr;
  int iid = 0;
  int service_index = 0;
  int property_index = 0;
  int ret = 0;
  
  int int_value = 0;
  float float_value = 0;
  bool boolean_value = false;
  const char *set_string = NULL;
  int set_string_len = 0;
  
  require_action(service_table, exit, err = kParamErr);
  require_action(key, exit, err = kParamErr);
  require_action(val, exit, err = kParamErr);
  require_action(out_write_obj, exit, err = kParamErr);
  require_action(out_err_prop_obj, exit, err = kParamErr);
  
  Str2Int((uint8_t*)key, &iid);
  //properties_log("properties write iid=%d.", iid);
  
  err = FindPropertyByIID(service_table, iid, &service_index, &property_index);
  require_noerr(err, exit);
  
  if( MICO_PROP_PERMS_WRITABLE (service_table[service_index].properties[property_index].perms) ){
    switch(service_table[service_index].properties[property_index].format){
    case MICO_PROP_TYPE_INT:{
      //properties_log("prop got: %s, iid=%d, value=%d", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((int*)service_table[service_index].properties[property_index].value));
      // property set (hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        int_value = json_object_get_int(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index],
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&int_value, sizeof(int));
        if (0 == ret){  // set ok, update property value
          *((int*)service_table[service_index].properties[property_index].value) =  int_value;
          json_object_object_add(out_write_obj, key, json_object_new_int(int_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_FLOAT:{
      //properties_log("prop got: %s, iid=%d, value=%f", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((float*)service_table[service_index].properties[property_index].value));
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        float_value = json_object_get_double(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&float_value, sizeof(float));
        if (0 == ret){  // set ok, update property value
          *((float*)service_table[service_index].properties[property_index].value) = float_value;
          json_object_object_add(out_write_obj, key, json_object_new_double(float_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_STRING:{
      //properties_log("prop got: %s, iid=%d, value=%s", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               (char*)service_table[service_index].properties[property_index].value);
      
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        set_string = json_object_get_string(val);
        set_string_len = json_object_get_string_len(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)set_string, set_string_len);
        if (0 == ret){  // set ok, update property value
          memset((char*)(service_table[service_index].properties[property_index].value), '\0', service_table[service_index].properties[property_index].maxStringLen);
          strncpy((char*)(service_table[service_index].properties[property_index].value), set_string, set_string_len);
          *(service_table[service_index].properties[property_index].value_len) = set_string_len;
          json_object_object_add(out_write_obj, key, json_object_new_string(set_string));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_BOOL:{
      //properties_log("prop got: %s, iid=%d, value=%d", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((bool*)service_table[service_index].properties[property_index].value));
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        boolean_value = json_object_get_boolean(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&boolean_value, sizeof(bool));
        if (0 == ret){  // set ok, update property value
          *((bool*)service_table[service_index].properties[property_index].value) = boolean_value;
          json_object_object_add(out_write_obj, key, json_object_new_boolean(boolean_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    default:
      properties_log("ERROR: Unsupported format!");
      json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_DATA_FORMAT_ERR));
      err = kWriteErr;
      break;
    }
  }
  else{
    properties_log("ERROR: property is read only!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_WRITABLE));
    err = kNotWritableErr;
  }
  
exit:
  if(kNotFoundErr == err){   // property not found
    properties_log("ERROR: property not found!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_FOUND));
  }
  if(kRequestErr == err){   // service can not be set
    properties_log("ERROR: service can not be set!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_SUPPORTED));
  }
  return err;
}
Example #16
0
tlog_grc
tlog_json_msg_init(struct tlog_json_msg *msg, struct json_object *obj)
{
    struct json_object *o;
    int rc;
    const char *str;
    int end;
    int64_t session;
    int64_t id;
    int64_t pos;

    assert(msg != NULL);

    memset(msg, 0, sizeof(*msg));

    if (obj == NULL) {
        assert(tlog_json_msg_is_valid(msg));
        return true;
    }

#define GET_FIELD(_name_token, _type_token) \
    do {                                                            \
        if (!json_object_object_get_ex(obj, #_name_token, &o)) {    \
            return TLOG_RC_JSON_MSG_FIELD_MISSING;                  \
        }                                                           \
        if (json_object_get_type(o) != json_type_##_type_token) {   \
            return TLOG_RC_JSON_MSG_FIELD_INVALID_TYPE;             \
        }                                                           \
    } while (0)

#define GET_FIELD_ALT_TYPE2(_name_token, _type_token1, _type_token2) \
    do {                                                                \
        if (!json_object_object_get_ex(obj, #_name_token, &o)) {        \
            return TLOG_RC_JSON_MSG_FIELD_MISSING;                      \
        }                                                               \
        if (json_object_get_type(o) != json_type_##_type_token1 &&      \
            json_object_get_type(o) != json_type_##_type_token2) {      \
            return TLOG_RC_JSON_MSG_FIELD_INVALID_TYPE;                 \
        }                                                               \
    } while (0)

#define GET_OPTIONAL_FIELD(_name_token, _type_token) \
    do {                                                            \
        if (json_object_object_get_ex(obj, #_name_token, &o) &&     \
            json_object_get_type(o) != json_type_##_type_token) {   \
            return TLOG_RC_JSON_MSG_FIELD_INVALID_TYPE;             \
        }                                                           \
    } while (0)

    GET_FIELD_ALT_TYPE2(ver, string, int);
    /* NOTE: Converting number to string can fail */
    str = json_object_get_string(o);
    if (str == NULL) {
        return TLOG_GRC_ERRNO;
    }
    end = 0;
    rc = sscanf(str, "%u%n.%u%n",
                &msg->ver_major, &end, &msg->ver_minor, &end);
    if (rc < 1 || str[end] != '\0' || msg->ver_major > 2) {
        return TLOG_RC_JSON_MSG_FIELD_INVALID_VALUE_VER;
    }

    GET_FIELD(host, string);
    msg->host = json_object_get_string(o);

    GET_OPTIONAL_FIELD(rec, string);
    msg->rec = json_object_get_string(o);

    GET_FIELD(user, string);
    msg->user = json_object_get_string(o);

    GET_FIELD(term, string);
    msg->term = json_object_get_string(o);

    GET_FIELD(session, int);
    session = json_object_get_int64(o);
    if (session < 1 || session > UINT_MAX) {
        return TLOG_RC_JSON_MSG_FIELD_INVALID_VALUE_SESSION;
    }
    msg->session = (unsigned int)session;

    GET_FIELD(id, int);
    id = json_object_get_int64(o);
    if (id < 0
#if INT64_MAX > SIZE_MAX
        || id > (int64_t)SIZE_MAX
#endif
    ) {
        return TLOG_RC_JSON_MSG_FIELD_INVALID_VALUE_ID;
    }
    msg->id = (size_t)id;

    GET_FIELD(pos, int);
    pos = json_object_get_int64(o);
    if (pos < 0 || pos > TLOG_DELAY_MAX_MS_NUM) {
        return TLOG_RC_JSON_MSG_FIELD_INVALID_VALUE_POS;
    }
    msg->pos.tv_sec = pos / 1000;
    msg->pos.tv_nsec = pos % 1000 * 1000000;

    GET_FIELD(timing, string);
    msg->timing_ptr = json_object_get_string(o);

    GET_FIELD(in_txt, string);
    msg->in_txt_ptr = json_object_get_string(o);
    msg->in_txt_len = (size_t)json_object_get_string_len(o);

    GET_FIELD(in_bin, array);
    msg->in_bin_obj = o;
    msg->in_bin_pos = 0;

    GET_FIELD(out_txt, string);
    msg->out_txt_ptr = json_object_get_string(o);
    msg->out_txt_len = (size_t)json_object_get_string_len(o);

    GET_FIELD(out_bin, array);
    msg->out_bin_obj = o;
    msg->out_bin_pos = 0;

#undef GET_OPTIONAL_FIELD
#undef GET_FIELD_ALT_TYPE2
#undef GET_FIELD

    msg->obj = json_object_get(obj);
    assert(tlog_json_msg_is_valid(msg));
    return TLOG_RC_OK;
}