static int handle_number(void * ctx, const char *val, unsigned int len)
{
	struct ctx *_ctx = (struct ctx *) ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);
	
	Debug("handle_number, val = %s, enter state '%s'", buf, parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	switch (_ctx->parser_state) {
		case PARSER_STATE_CONSUMED_CAPACITY_KEY: {
			if (aws_dynamo_json_get_double(val, len, &(_ctx->r->consumed_capacity_units)) == -1) {
				Warnx("handle_number: failed to get capacity int.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ROOT_MAP;
			break;
		}
		default: {
			Warnx("handle_number - unexpected state '%s'", parser_state_string(_ctx->parser_state));
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_number exit state '%s'", parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	return 1;
}
struct aws_dynamo_create_table_response *aws_dynamo_create_table(struct
								 aws_handle
								 *aws, const char
								 *request)
{
	const char *response;
	int response_len;
	struct aws_dynamo_create_table_response *r;

	if (aws_dynamo_request(aws, AWS_DYNAMO_CREATE_TABLE, request) == -1) {
		return NULL;
	}

	response = http_get_data(aws->http, &response_len);

	if (response == NULL) {
		Warnx("aws_dynamo_create_table: Failed to get response.");
		return NULL;
	}

	if ((r = aws_dynamo_parse_create_table_response(response, response_len)) == NULL) {
		Warnx("aws_dynamo_create_table: Failed to parse response: '%s'", response);
		return NULL;
	}

	return r;
}
struct aws_dynamo_delete_item_response *aws_dynamo_delete_item(struct aws_handle *aws,
	const char *request, struct aws_dynamo_attribute *attributes, int num_attributes)
{
	const char *response;
	int response_len;
	struct aws_dynamo_delete_item_response *r;

	if (aws_dynamo_request(aws, AWS_DYNAMO_DELETE_ITEM, request) == -1) {
		return NULL;
	}

	response = http_get_data(aws->http, &response_len);

	if (response == NULL) {
		Warnx("aws_dynamo_delete_item: Failed to get response.");
		return NULL; 
	}

	if ((r = aws_dynamo_parse_delete_item_response(response, response_len,
		attributes, num_attributes)) == NULL) {
		Warnx("aws_dynamo_delete_item: Failed to parse response: '%s'", response);
		return NULL; 
	}

	return r;
}
예제 #4
0
/**************************************************************************************************
	READ_TCP_LENGTH
	The first two octets of a TCP question are the length.  Read them.
	Returns 0 on success, -1 on failure.
**************************************************************************************************/
static int
read_tcp_length(TASK *t)
{
	int	rv;
	char	len[2];

	if ((rv = recv(t->fd, len, 2, 0)) != 2)
	{
		if (rv < 0)
		{
			if (errno == EAGAIN)
				return (0);
			if (errno != ECONNRESET)
				Warn("%s: %s", clientaddr(t), _("recv (length) (TCP)"));
			return (-1);
		}
		if (rv == 0)
			return (-1);
		return Warnx("%s: %s", clientaddr(t), _("TCP message length invalid"));
	}

	if ((t->len = ((len[0] << 8) | (len[1]))) < DNS_HEADERSIZE)
		return Warnx("%s: %s (%d octet%s)", clientaddr(t), _("TCP message too short"), t->len, S(t->len));
	if (t->len > DNS_MAXPACKETLEN_TCP)
		return Warnx("%s: %s (%d octet%s)", clientaddr(t), _("TCP message too long"), t->len, S(t->len));

	if (!(t->query = calloc(1, t->len + 1)))
		Err(_("out of memory"));
	t->offset = 0;
	return (0);
}
static int handle_end_array(void *ctx)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	Debug("handle_end_array enter state '%s'", parser_state_string(_ctx->parser_state));
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
		case PARSER_STATE_ATTRIBUTE_VALUE_ARRAY: {
				_ctx->parser_state = PARSER_STATE_ATTRIBUTE_MAP;
			break;
		}
	default:{
			Warnx("handle_end_array - unexpected state '%s'", parser_state_string(_ctx->parser_state));
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_end_array exit state '%s'", parser_state_string(_ctx->parser_state));
#endif				/* DEBUG_PARSER */

	return 1;
}
static int handle_end_map(void *ctx)
{
	struct ctx *_ctx = (struct ctx *) ctx;
#ifdef DEBUG_PARSER
	Debug("handle_end_map enter state '%s'", parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */
	switch (_ctx->parser_state) {
		case PARSER_STATE_ATTRIBUTE_MAP: {
				_ctx->parser_state = PARSER_STATE_ATTRIBUTES_MAP;
			break;
		}
		case PARSER_STATE_ATTRIBUTES_MAP: {
				_ctx->parser_state = PARSER_STATE_ROOT_MAP;
			break;
		}
		case PARSER_STATE_ROOT_MAP: {
				_ctx->parser_state = PARSER_STATE_NONE;
			break;
		}
		default: {
			Warnx("handle_end_map - unexpected state: %s", parser_state_string(_ctx->parser_state));
			return 0;
			break;
		}
	}
#ifdef DEBUG_PARSER
	Debug("handle_end_map exit state '%s'", parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	return 1;
}
예제 #7
0
/**************************************************************************************************
	READ_TCP_QUERY
	Returns 0 on success, -1 on failure.
**************************************************************************************************/
int
read_tcp_query(TASK *t)
{
	unsigned char *end;
	int rv;

	/* Read packet length if we haven't already */
	if (!t->len)
		return read_tcp_length(t);

	end = t->query + t->len;

	/* Read whatever data is ready */
	if ((rv = recv(t->fd, t->query + t->offset, t->len - t->offset, 0)) < 0)
		return Warn("%s: %s", clientaddr(t), _("recv (TCP)"));
	if (!rv)
		return (-1);	/* Client closed connection */

#if DEBUG_ENABLED && DEBUG_TCP
	Debug("%s: 2+%d TCP octets in", clientaddr(t), rv);
#endif

	t->offset += rv;
	if (t->offset > t->len)
		return Warnx("%s: %s", clientaddr(t), _("TCP message data too long"));
	if (t->offset < t->len)
		return 0;													/* Not finished reading */
	t->offset = 0;													/* Reset offset for writing reply */

	return new_task(t, t->query, t->len);
}
static int put_item_end_array(void *ctx)
{
	struct put_item_ctx *_ctx = (struct put_item_ctx *)ctx;
#ifdef DEBUG_PARSER
	Debug("put_item_end_array enter %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_ATTRIBUTE_VALUE:{
			/* A String Set or a Number Set, no need for a state change. */
			break;
		}
	default:{
			Warnx("put_item_end_array - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("put_item_end_array exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
static int put_item_end_map(void *ctx)
{
	struct put_item_ctx *_ctx = (struct put_item_ctx *)ctx;
#ifdef DEBUG_PARSER
	Debug("put_item_end_map enter %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_ATTRIBUTE_VALUE:{
			_ctx->parser_state = PARSER_STATE_ATTRIBUTES_MAP;
			break;
		}
	case PARSER_STATE_ATTRIBUTES_MAP:{
			_ctx->parser_state = PARSER_STATE_ROOT_MAP;
			break;
		}
	case PARSER_STATE_ROOT_MAP:{
			_ctx->parser_state = PARSER_STATE_NONE;
			break;
		}
	default:{
			Warnx("put_item_end_map - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("put_item_end_map exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
static int handle_string(void *ctx, const unsigned char *val,  unsigned int len)
{  
	struct ctx *_ctx = (struct ctx *) ctx;
	struct aws_dynamo_item *item;
	struct aws_dynamo_attribute *attribute;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("handle_string, val = %s, enter state '%s'", buf, parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	item = &(_ctx->r->item);
	attribute = &(item->attributes[_ctx->attribute_index]);

	switch (_ctx->parser_state) {
		case PARSER_STATE_ATTRIBUTE_TYPE_KEY: {
			if (aws_dynamo_parse_attribute_value(attribute, val, len) != 1) {
				Warnx("handle_string - attribute parse failed, attribute %d",
					_ctx->attribute_index);
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ATTRIBUTE_MAP;
			break;
		}
		case PARSER_STATE_ATTRIBUTE_VALUE_ARRAY: {
			if (aws_dynamo_parse_attribute_value(attribute, val, len) != 1) {
				Warnx("handle_string - attribute parse failed, attribute %d",
					_ctx->attribute_index);
				return 0;
			}
			break;
		}
		default: {
			Warnx("handle_string - unexpected state '%s'", parser_state_string(_ctx->parser_state));
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_string exit state '%s'", parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	return 1;
}  
예제 #11
0
struct aws_dynamo_put_item_response * aws_dynamo_parse_put_item_response(const char *response, int response_len, struct aws_dynamo_attribute *attributes, int num_attributes)
{
	yajl_handle hand;
	yajl_status stat;
	struct put_item_ctx _ctx = { 0 };

	_ctx.r = calloc(sizeof(*(_ctx.r)), 1);
	if (_ctx.r == NULL) {
		Warnx("aws_dynamo_parse_put_item_response: response alloc failed.");
		return NULL;
	}

	if (num_attributes > 0) {
		_ctx.r->attributes = malloc(sizeof(*(_ctx.r->attributes)) * num_attributes);
		if (_ctx.r->attributes == NULL) {
			Warnx("aws_dynamo_parse_put_item_response: attribute alloc failed.");
			free(_ctx.r);
			return NULL;
		}
		memcpy(_ctx.r->attributes, attributes, sizeof(*(attributes)) * num_attributes);
		_ctx.r->num_attributes = num_attributes;
	}

#if YAJL_MAJOR == 2
	hand = yajl_alloc(&put_item_callbacks, NULL, &_ctx);
	yajl_parse(hand, response, response_len);
	stat = yajl_complete_parse(hand);
#else
	hand = yajl_alloc(&put_item_callbacks, NULL, NULL, &_ctx);
	yajl_parse(hand, response, response_len);
	stat = yajl_parse_complete(hand);
#endif

	if (stat != yajl_status_ok) {
		unsigned char *str =
		    yajl_get_error(hand, 1, response, response_len);
		Warnx("aws_dynamo_parse_put_item_response: json parse failed, '%s'", (const char *)str);
		yajl_free_error(hand, str);
		yajl_free(hand);
		aws_dynamo_free_put_item_response(_ctx.r);
		return NULL;
	}

	yajl_free(hand);
	return _ctx.r;
}
예제 #12
0
파일: conf.c 프로젝트: shangyanjin/mydns-ng
/**************************************************************************************************
	CHECK_CONFIG_FILE_PERMS
**************************************************************************************************/
void
check_config_file_perms(void) {
    FILE *fp;

    if ((fp = fopen(opt_conf, "r"))) {
        Warnx("%s: %s", opt_conf, _("WARNING: config file is readable by unprivileged user"));
        fclose(fp);
    }
}
예제 #13
0
static int put_item_string(void *ctx, const unsigned char *val,
				 unsigned int len)
{
	struct put_item_ctx *_ctx = (struct put_item_ctx *)ctx;
	struct aws_dynamo_attribute *attribute;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("put_item_string, val = %s, enter state %d", buf,
	      _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	attribute = &(_ctx->r->attributes[_ctx->attribute_index]);

	switch (_ctx->parser_state) {
	case PARSER_STATE_ATTRIBUTE_VALUE:{
			if (aws_dynamo_parse_attribute_value(attribute, val, len) != 1) {
				Warnx("get_item_string - attribute parse failed, attribute %d",
					_ctx->attribute_index);
				return 0;
			}
			break;
		}
	default:{
			Warnx("put_item_string - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("put_item_string exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
예제 #14
0
static char *aws_dynamo_get_canonicalized_headers(struct http_headers *headers) {
	int i;
	int canonical_headers_len = 0;
	char *canonical_headers;
	char *ptr;

	/* Assume all header .name fields are lowercase. */

	/* Assume no duplicate headers (that is, all header names are
		distinct.) */

	/* Assume headers are already sorted alphabetically by header name. */

	for (i = 0; i < headers->count; i++) {
		canonical_headers_len += strlen(headers->entries[i].name);
		canonical_headers_len += strlen(headers->entries[i].value);
		canonical_headers_len += 2; /* ':' and '\n' */
	}
	canonical_headers_len++; /* \0 terminator */

	ptr = canonical_headers = calloc(sizeof(char), canonical_headers_len);

	if (ptr == NULL) {
		Err("aws_dynamo_get_canonicalized_headers: Failed to allocate.");
		return NULL;
	}

	for (i = 0; i < headers->count; i++) {
		int n;
		int remaining;

		remaining = canonical_headers_len - (ptr - canonical_headers);

		n = snprintf(ptr, remaining, "%s:%s\n", headers->entries[i].name,
			headers->entries[i].value);

		if (n == -1 || n >= remaining) {
			Warnx("aws_dynamo_get_canonicalized_headers: string buffer not large enough.");
			free(canonical_headers);
			return NULL;
		}
		ptr += n;
	}

	return canonical_headers;
}
static int handle_end_map(void *ctx)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	Debug("handle_end_map enter %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_ROOT_MAP:{
			_ctx->parser_state = PARSER_STATE_NONE;
			break;
		}
	case PARSER_STATE_TABLE_DESCRIPTION_MAP:{
			_ctx->parser_state = PARSER_STATE_ROOT_MAP;
			break;
		}
	case PARSER_STATE_PROVISIONED_THROUGHPUT_MAP:{
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	case PARSER_STATE_HASH_KEY_ELEMENT_MAP:{
			_ctx->parser_state = PARSER_STATE_KEY_SCHEMA_MAP;
			break;
		}
	case PARSER_STATE_RANGE_KEY_ELEMENT_MAP:{
			_ctx->parser_state = PARSER_STATE_KEY_SCHEMA_MAP;
			break;
		}
	case PARSER_STATE_KEY_SCHEMA_MAP:{
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	default:{
			Warnx("handle_end_map - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_end_map exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
static int handle_end_array(void *ctx)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	Debug("handle_end_array enter %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	default:{
			Warnx("handle_end_array - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_end_array exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
예제 #17
0
파일: axfr.c 프로젝트: corretgecom/mydns-ng
/* static void axfr_error(TASK *, const char *, ...) __attribute__ ((__noreturn__)); */
static void
axfr_error(TASK *t, const char *fmt, ...) {
  va_list	ap; 
  char		*msg = NULL;

  if (t) {
    task_output_info(t, NULL);
  } else {
    va_start(ap, fmt);
    VASPRINTF(&msg, fmt, ap);
    va_end(ap);

    Warnx("%s", msg);
    RELEASE(msg);
  }

  sockclose(t->fd);

  _exit(EXIT_FAILURE);
  /* NOTREACHED */
}
/* each map is a case, compare key with all valid keys for that map
 * and set state accordingly. */
static int handle_map_key(void *ctx, const unsigned char *val, unsigned int len)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("handle_map_key, val = %s, enter state %d", buf, _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_ROOT_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_TABLE_DESCRIPTION, val, len)) {
				_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown root key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_TABLE_DESCRIPTION_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_CREATION_DATE_TIME, val, len)) {
				_ctx->parser_state = PARSER_STATE_CREATION_DATE_TIME_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_KEY_SCHEMA, val, len)) {
				_ctx->parser_state = PARSER_STATE_KEY_SCHEMA_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_PROVISIONED_THROUGHPUT, val, len)) {
				_ctx->parser_state = PARSER_STATE_PROVISIONED_THROUGHPUT_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_TABLE_NAME, val, len)) {
				_ctx->parser_state = PARSER_STATE_TABLE_NAME_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_TABLE_STATUS, val, len)) {
				_ctx->parser_state = PARSER_STATE_TABLE_STATUS_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ITEM_COUNT, val, len)) {
				_ctx->parser_state = PARSER_STATE_ITEM_COUNT_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_TABLE_SIZE_BYTES, val, len)) {
				_ctx->parser_state = PARSER_STATE_TABLE_SIZE_BYTES_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown table description key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_PROVISIONED_THROUGHPUT_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_READ_CAPACITY_UNITS, val, len)) {
				_ctx->parser_state = PARSER_STATE_READ_CAPACITY_UNITS_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_WRITE_CAPACITY_UNITS, val, len)) {
				_ctx->parser_state = PARSER_STATE_WRITE_CAPACITY_UNITS_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_NUMBER_OF_DECREASES_TODAY, val, len)) {
				_ctx->parser_state = PARSER_STATE_NUMBER_OF_DECREASES_TODAY_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown provisioned throughput key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_KEY_SCHEMA_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_HASH_KEY_ELEMENT, val, len)) {
				_ctx->parser_state = PARSER_STATE_HASH_KEY_ELEMENT_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_RANGE_KEY_ELEMENT, val, len)) {
				_ctx->parser_state = PARSER_STATE_RANGE_KEY_ELEMENT_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown key schema key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_HASH_KEY_ELEMENT_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTE_NAME, val, len)) {
				_ctx->parser_state = PARSER_STATE_HASH_KEY_ATTRIBUTE_NAME_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTE_TYPE, val, len)) {
				_ctx->parser_state = PARSER_STATE_HASH_KEY_ATTRIBUTE_TYPE_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown hash key element key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_RANGE_KEY_ELEMENT_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTE_NAME, val, len)) {
				_ctx->parser_state = PARSER_STATE_RANGE_KEY_ATTRIBUTE_NAME_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTE_TYPE, val, len)) {
				_ctx->parser_state = PARSER_STATE_RANGE_KEY_ATTRIBUTE_TYPE_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("handle_map_key: Unknown range key element key '%s'.", key);
				return 0;
			}
			break;
		}
	default:{
			Warnx("handle_map_key - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_map_key exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */
	return 1;
}
예제 #19
0
파일: ixfr.c 프로젝트: corretgecom/mydns-ng
static taskexec_t
ixfr_purge_all_soas(TASK *t, void *data) {

  /*
   * Retrieve all zone id's that have deleted records.
   *
   * For each zone get the expire field and delete any records that have expired.
   *
   */

  SQL_RES	*res = NULL;
  SQL_ROW	row = NULL;

  size_t	querylen;
  const char	*QUERY0 =	"SELECT DISTINCT zone FROM %s WHERE active='%s'";
  const char	*QUERY1 = 	"SELECT origin FROM %s "
				"WHERE id=%u;";
  const char	*QUERY2 =	"DELETE FROM %s WHERE zone=%u AND active='%s' "
				" AND stamp < DATE_SUB(NOW(),INTERVAL %u SECOND);";
  char		*query = NULL;

  /*
   * Reset task timeout clock to some suitable value in the future
   */
  t->timeout = current_time + ixfr_gc_interval;	/* Try again e.g. tomorrow */

  querylen = sql_build_query(&query, QUERY0,
			     mydns_rr_table_name, mydns_rr_active_types[2]);

  if (!(res = sql_query(sql, query, querylen)))
    ErrSQL(sql, "%s: %s", desctask(t),
	   _("error loading zone id's for DELETED records"));

  RELEASE(query);

  while((row = sql_getrow(res, NULL))) {
    unsigned int	id = atou(row[0]);
    char		*origin = NULL;
    MYDNS_SOA		*soa = NULL;
    SQL_RES		*sres = NULL;

    querylen = sql_build_query(&query, QUERY1,
			       mydns_soa_table_name, id);

    if (!(res = sql_query(sql, query, querylen)))
      ErrSQL(sql, "%s: %s", desctask(t),
	     _("error loading zone from DELETED record zone id"));

    RELEASE(query);

    if (!(row = sql_getrow(res, NULL))) {
      Warnx(_("%s: no soa found for soa id %u"), desctask(t),
	    id);
      continue;
    }

    origin = row[0];

    if (mydns_soa_load(sql, &soa, origin) == 0) {
      querylen = sql_build_query(&query, QUERY2,
				 mydns_rr_table_name, soa->id, mydns_rr_active_types[2], soa->expire);

      if (sql_nrquery(sql, query, querylen) != 0)
	WarnSQL(sql, "%s: %s %s", desctask(t),
		_("error deleting expired records for zone "), soa->origin);

      RELEASE(query);

      sql_free(sres);
    }
  }

  sql_free(res);
  RELEASE(query);     

  return (TASK_CONTINUE);
}
static int handle_map_key(void *ctx, const unsigned char *val,  
                            unsigned int len)  
{  
	struct ctx *_ctx = (struct ctx *) ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);
	
	Debug("handle_map_key, val = %s, enter state '%s'", buf, parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */

	switch (_ctx->parser_state) {
		case PARSER_STATE_ROOT_MAP: {
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_CONSUMED_CAPACITY, val, len)) {
				_ctx->parser_state = PARSER_STATE_CONSUMED_CAPACITY_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTES, val, len)) {
				_ctx->parser_state = PARSER_STATE_ATTRIBUTES_KEY;

				_ctx->r->item.attributes = malloc(sizeof(*(_ctx->attributes)) * _ctx->num_attributes);
				if (_ctx->r->item.attributes == NULL) {
					Warnx("handle_map_key: attribute alloc failed.");
					return 0;
				}

				/* Set expected types for attributes. */
				memcpy(_ctx->r->item.attributes, _ctx->attributes,
					sizeof(*(_ctx->attributes)) * _ctx->num_attributes);
				_ctx->r->item.num_attributes = _ctx->num_attributes;

			} else {
				Warnx("handle_map_key: Unknown key.");
				return 0;
			}
			break;
		}
		case PARSER_STATE_ATTRIBUTES_MAP: {
			/* Set the attribute index based on the name. */
			int attribute;

			for (attribute = 0; attribute < _ctx->num_attributes; attribute++) {
				struct aws_dynamo_attribute *a = &(_ctx->attributes[attribute]);

				if (len == a->name_len && strncmp(val, a->name, len) == 0) {
					_ctx->attribute_index = attribute;
					break;
				}
			}

			if (attribute == _ctx->num_attributes) {
				Warnx("handle_map_key: Unknown attribute.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ATTRIBUTE_KEY;
			break;
		}
		case PARSER_STATE_ATTRIBUTE_MAP: {
			struct aws_dynamo_attribute *a = &(_ctx->attributes[_ctx->attribute_index]);
			const char *expected_type = aws_dynamo_attribute_types[a->type];

			if (len != strlen(expected_type) || strncmp(val, expected_type, len) != 0) {
				Warnx("handle_map_key: Unexpected attribute type.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ATTRIBUTE_TYPE_KEY;
			break;
		}
		default: {
			Warnx("handle_map_key - unexpected state: %s", parser_state_string(_ctx->parser_state));
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_map_key exit state '%s'", parser_state_string(_ctx->parser_state));
#endif /* DEBUG_PARSER */
	return 1;
}  
예제 #21
0
파일: conf.c 프로젝트: shangyanjin/mydns-ng
/**************************************************************************************************
	LOAD_CONFIG
	Load the configuration file.
**************************************************************************************************/
void
load_config(void) {
    int		n;
    struct passwd *pwd = NULL;
    struct group	*grp = NULL;

    /* Load config */
    conf_load(&Conf, opt_conf);

    /* Set defaults */
    for (n = 0; defConfig[n].name; n++) {
        if (defConfig[n].name[0] == '-' || !defConfig[n].value)
            continue;
        if (!conf_get(&Conf, defConfig[n].name, NULL))
            conf_set(&Conf, defConfig[n].name, defConfig[n].value, 1);
    }

    /* Support "mysql-user" etc. for backwards compatibility */
    if (conf_get(&Conf, "mysql-host", NULL))
        conf_set(&Conf, "db-host", conf_get(&Conf, "mysql-host", NULL), 0);
    if (conf_get(&Conf, "mysql-user", NULL))
        conf_set(&Conf, "db-user", conf_get(&Conf, "mysql-user", NULL), 0);
    if (conf_get(&Conf, "mysql-pass", NULL))
        conf_set(&Conf, "db-password", conf_get(&Conf, "mysql-pass", NULL), 0);
    if (conf_get(&Conf, "mysql-password", NULL))
        conf_set(&Conf, "db-password", conf_get(&Conf, "mysql-password", NULL), 0);

#if HAVE_GETPWUID
    /* Set default for database username to real username if none was provided */
    if (!conf_get(&Conf, "db-user", NULL)) {
        struct passwd *pwd2;

        if ((pwd2 = getpwuid(getuid())) && pwd2->pw_name) {
            conf_set(&Conf, "db-user", pwd2->pw_name, 0);
            memset(pwd2, 0, sizeof(struct passwd));
        }
    }
#endif

    /* Load user/group perms */
    if (!(pwd = getpwnam(conf_get(&Conf, "user", NULL))))
        Err(_("error loading uid for user `%s'"), conf_get(&Conf, "user", NULL));
    perms_uid = pwd->pw_uid;
    perms_gid = pwd->pw_gid;
    memset(pwd, 0, sizeof(struct passwd));

    if (!(grp = getgrnam(conf_get(&Conf, "group", NULL))) && !(grp = getgrnam("nobody"))) {
        Warnx(_("error loading gid for group `%s'"), conf_get(&Conf, "group", NULL));
        Warnx(_("using gid %lu from user `%s'"), (unsigned long)perms_gid, conf_get(&Conf, "user", NULL));
    } else {
        perms_gid = grp->gr_gid;
        memset(grp, 0, sizeof(struct group));
    }

    /* We call conf_set_logging() again after moving into background, but it's called here
       to report on errors. */
    conf_set_logging();

    /* Set global options */
    task_timeout = atou(conf_get(&Conf, "timeout", NULL));

    axfr_enabled = GETBOOL(conf_get(&Conf, "allow-axfr", NULL));
    Verbose(_("AXFR is %senabled"), (axfr_enabled)?"":_("not "));

    tcp_enabled = GETBOOL(conf_get(&Conf, "allow-tcp", NULL));
    Verbose(_("TCP ports are %senabled"), (tcp_enabled)?"":_("not "));

    dns_update_enabled = GETBOOL(conf_get(&Conf, "allow-update", NULL));
    Verbose(_("DNS UPDATE is %senabled"), (dns_update_enabled)?"":_("not "));

    mydns_soa_use_active = GETBOOL(conf_get(&Conf, "use-soa-active", NULL));
    mydns_rr_use_active = GETBOOL(conf_get(&Conf, "use-rr-active", NULL));

    dns_notify_enabled = dns_update_enabled && GETBOOL(conf_get(&Conf, "notify-enabled", NULL));
    Verbose(_("DNS NOTIFY is %senabled"), (dns_notify_enabled)?"":_("not "));
    notify_timeout = atou(conf_get(&Conf, "notify-timeout", NULL));
    notify_retries = atou(conf_get(&Conf, "notify-retries", NULL));
    notify_algorithm = conf_get(&Conf, "notify-algorithm", NULL);

    dns_ixfr_enabled = GETBOOL(conf_get(&Conf, "ixfr-enabled", NULL));
    Verbose(_("DNS IXFR is %senabled"), (dns_ixfr_enabled)?"":_("not "));
    ixfr_gc_enabled = GETBOOL(conf_get(&Conf, "ixfr-gc-enabled", NULL));
    ixfr_gc_interval = atou(conf_get(&Conf, "ixfr-gc-interval", NULL));
    ixfr_gc_delay = atou(conf_get(&Conf, "ixfr-gc-delay", NULL));

    mydns_rr_extended_data = GETBOOL(conf_get(&Conf, "extended-data-support", NULL));

    mydns_dbengine = conf_get(&Conf, "dbengine", NULL);

    wildcard_recursion = atoi(conf_get(&Conf, "wildcard-recursion", NULL));

    ignore_minimum = GETBOOL(conf_get(&Conf, "ignore-minimum", NULL));

    /* Set table names if provided */
    mydns_set_soa_table_name(conf_get(&Conf, "soa-table", NULL));
    mydns_set_rr_table_name(conf_get(&Conf, "rr-table", NULL));

    /* Set additional where clauses if provided */
    mydns_set_soa_where_clause(conf_get(&Conf, "soa-where", NULL));
    mydns_set_rr_where_clause(conf_get(&Conf, "rr-where", NULL));

    /* Set recursive server if specified */
    conf_set_recursive();

#ifdef DN_COLUMN_NAMES
    dn_default_ns = conf_get(&Conf, "default-ns", NULL);
#endif
}
예제 #22
0
파일: tftpserver.c 프로젝트: msantl/MREPRO
int main(int argc, char **argv) {
  char buffer[MAXLENGTH];

  char file[MAXLENGTH];

  char filename[MAXLENGTH];
  char filename_path[MAXLENGTH];
  char filetype[MAXLENGTH];

  char server_adresa[32];
  char klijent_adresa[32];

  char *char_p, znak;
  FILE *datoteka;

  int ch;
  int sockfd, newfd;
  int msglen, status;
  int should_be_daemon = 0;
  int should_be_binary = 1;
  int zadnji_znak_oznaka_novog_reda;
  int oznaka_kraja_datoteke;
  int retransmission_count;

  uint16_t kod_poruke, broj_bloka, tip_zahtjeva, brojac_blokova;

  pid_t pid;

  socklen_t server_l;
  struct sockaddr server;

  socklen_t client_l;
  struct sockaddr client;

  struct sockaddr_in dijete;

  struct timeval timeout;
  fd_set readfs;

  char* port = (char *)malloc(sizeof(char) * 8);

  strcpy(port, S_PORT);

  while ((ch = getopt(argc, argv, "d")) != -1) {
    switch(ch) {
      case 'd':
        should_be_daemon = 1;
        break;
      default:
        errx(1, "Usage: ./tftpserver [-d] port_name_or_number");
        break;
    }
  }

  if (argc - optind != 1) {
    errx(1, "Usage: ./tcpserver [-d] port_name_or_number");
  } else {
    strcpy(port, argv[optind]);
    /*
     * provjeri ispravnost danog porta
     * da li je ok staviti NULL ili bas moram navesti ime protokola
     */
    if (sscanf(port, "%d", &status) == 0 && getservbyname(port, NULL) == NULL) {
      errx(1, "Invalid port name given");
    }
  }

  /*
   * ako treba napravi ga demonom
   */
  if (should_be_daemon) {
    if (daemon_init("MrePro tftpserver", LOG_FTP) < 0) {
      errx(1, "daemon failed to initialize!");
    }
  } else {
    daemon_proc = 0;
  }

  /*
   * NOTE: dalje se sva upozorenja/pogreske pisu sa
   * Errx(status, format, ...)
   * koja radi errx ili syslog ovisno o varijabli daemon_proc
   */

  sockfd = noviSocket(NULL, port, &server, &server_l);

  while (1) {
    // primi prvi datagram od klijenta koji opisuje njegove zelje
    // forkaj
    // neka child posluzi klijenta
    // mi nastavljamo u petlju
    memset(buffer, 0, sizeof buffer);

    client_l = sizeof(client);
    msglen = recvfrom(sockfd, buffer, sizeof(buffer), 0, &client, &client_l);

    if ((pid = fork()) < 0) {
      Errx(daemon_proc ? LOG_ALERT : 1, "TFTP ERROR 0 ms45889: fork error");
    } else if (pid == 0) {
      /*
       * dijete
       */
      Close(sockfd);

      // clear buffers
      memset(file, 0, sizeof file);
      memset(filename, 0, sizeof filename);
      memset(filetype, 0, sizeof filetype);

      // spremi klijentovu adresu
      inet_ntop(
        client.sa_family,
        &((struct sockaddr_in *)&client)->sin_addr,
        klijent_adresa,
        sizeof(klijent_adresa)
      );

      // spremi moju adresu
      inet_ntop(
        server.sa_family,
        &((struct sockaddr_in *)&server)->sin_addr,
        server_adresa,
        sizeof(server_adresa)
      );

      // napravi novi socket

      newfd = Socket(AF_INET, SOCK_DGRAM, 0);

      memset(&dijete, 0, sizeof(dijete));
      dijete.sin_family = AF_INET;
      dijete.sin_port = htons(0);
      dijete.sin_addr.s_addr = INADDR_ANY;

      Bind(newfd, (struct sockaddr *)&dijete, sizeof (struct sockaddr));

      /*
       * prvi zahtjev dolazi na dogovoreni port
       * odgovor saljemo klijentu s nekog drugog porta i na tom portu
       * nastavljamo priamti klijentove poruke
       */
      // read = 1
      // write = 2
      // data = 3
      // ack = 4
      // error = 5

      // 1) izdvoji tip zahtjeva
      memcpy(&tip_zahtjeva, buffer, 2);
      tip_zahtjeva = ntohs(tip_zahtjeva);

      // 2) izdvoji naziv datoteke u filename
      strcpy(filename, buffer + 2);

      // 3) izdvoji nacin prijenosa u filetype
      strcpy(filetype, buffer + 2 + strlen(filename) + 1);

      for (char_p = filetype; *char_p; ++char_p) {
        *char_p = tolower(*char_p);
      }

      if (tip_zahtjeva == 1) {
        // ovisno o filetype napuni file buffer
        // za netascii treba svaki \n pretvoriti u \r\n
        // za binary samo trpaj
        // velicina datagrama je 4 + 512
        // radi najvise 3 retransmisije, 3 sekunde izmedju svake
        // jedini dozvoljeni direktorij je /tftpboot

        if (strstr(filename, "/tftpboot/") == NULL) {
          strcpy(filename_path, "/tftpboot/");
        }
        strcat(filename_path, filename);

        if (strstr(filetype, "netascii")) {
          should_be_binary = 0;
          datoteka = fopen(filename_path, "r");
        } else {
          should_be_binary = 1;
          datoteka = fopen(filename_path, "rb");
        }

        // ako datoteka ne postoji ili nemamo prava otvaranja iste
        if (datoteka == NULL) {
          status = errno;

          kod_poruke = htons(5);
          memcpy(file, &kod_poruke, 2);

          broj_bloka = htons(3 - status);
          memcpy(file + 2, &broj_bloka, 2);

          strcpy(file + 4, strerror(status));

          sendto(newfd, file, 516, 0, &client, client_l);
          Close(newfd);
          Errx(daemon_proc ? LOG_ALERT : 1, "TFTP ERROR %d ms45889 %s", 3 - status , strerror(status));
        }

        // kreni s citanjem datoteke ovisno o should_be_binary zastavici
        // te svaki paket posalji najvise 3 puta dok ne dobis potvrdu ili
        // odustani

        // spremi podatke u datagram
        oznaka_kraja_datoteke = 0;
        brojac_blokova = 1;

        while (oznaka_kraja_datoteke == 0) {

          memset(file, 0, sizeof(file));
          memset(buffer, 0, sizeof(buffer));

          kod_poruke = htons(3);
          memcpy(file, &kod_poruke, 2);

          broj_bloka = htons(brojac_blokova);
          memcpy(file + 2, &broj_bloka, 2);

          ch = 0;
          char_p = file + 4;
          zadnji_znak_oznaka_novog_reda = 0;

          while (ch < 512) {
            if (zadnji_znak_oznaka_novog_reda == 0) {
              znak = fgetc(datoteka);
            }
            zadnji_znak_oznaka_novog_reda = 0;

            if (feof(datoteka)) {
              oznaka_kraja_datoteke = 1;
              break;
            }

            if (should_be_binary == 0 && zadnji_znak_oznaka_novog_reda == 0 && znak == '\n') {
              *char_p = '\r';
              ++ch;
              ++char_p;

              if (ch == 512) {
                zadnji_znak_oznaka_novog_reda = 1;
                break;
              }
            }

            *char_p = znak;

            ++ch;
            ++char_p;
          }

          retransmission_count = 0;

          // postavimo timeout na 3 sekunde
          timeout.tv_usec = 0;
          timeout.tv_sec = 3;

          while (retransmission_count < 3) {

            sendto(newfd, file, 4 + ch, 0, &client, client_l);
            FD_ZERO(&readfs);
            FD_SET(newfd, &readfs);

            // tu sad ide timeout
            status = select(newfd + 1, &readfs, NULL, NULL, &timeout);

            if (FD_ISSET(newfd, &readfs) == 0) {
              ++ retransmission_count;
              continue;

            } else {

              msglen = recvfrom(newfd, buffer, sizeof(buffer), 0, &client, &client_l);
              retransmission_count = 5;
            }

            memcpy(&tip_zahtjeva, buffer, 2);
            tip_zahtjeva = ntohs(tip_zahtjeva);

            memcpy(&broj_bloka, buffer + 2, 2);
            broj_bloka = ntohs(broj_bloka);

            // ako je ack i ne podudaraju se brojevi posalji ponovno
            if (tip_zahtjeva == 4 && broj_bloka != brojac_blokova) {
              retransmission_count = -1;
            }
          }

          // 3 puta smo timeoutali
          if (retransmission_count == 3) {
            memset(file, 0, sizeof file);
            // pogreska
            kod_poruke = htons(5);
            memcpy(file, &kod_poruke, 2);
            // illegal TFTP option
            broj_bloka = htons(0);
            memcpy(file + 2, &broj_bloka, 2);

            strcpy(file + 4, "TFTP timeout nad istim blokom 3 puta\0");

            sendto(newfd, file, 516, 0, &client, client_l);

            Errx(daemon_proc ? LOG_ALERT : 1, "TFTP ERROR %d ms45889: timeout 3 puta");
          }

          // pogledaj sta je klijent poslao ako nije ack (mozda error)
          // tip zahtjeva
          if (tip_zahtjeva == 5 ) {
            Close(newfd);
            Errx(daemon_proc ? LOG_ALERT : 1, "TFTP ERROR %d ms45889: klijent", broj_bloka);
          }

          ++ brojac_blokova;
        }

        fclose(datoteka);

        if (daemon_proc) {
          syslog(LOG_INFO, "%s->%s", klijent_adresa, filename);
        } else {
          printf("%s->%s\n", klijent_adresa, filename);
        }

      } else {
        // pogreska
        kod_poruke = htons(5);
        memcpy(file, &kod_poruke, 2);
        // illegal TFTP option
        broj_bloka = htons(4);
        memcpy(file + 2, &broj_bloka, 2);

        strcpy(file + 4, "TFTP server podrzava samo GET request\0");

        sendto(newfd, file, 516, 0, &client, client_l);
        Warnx("TFTP ERROR 4 ms45889: podrzano samo citanje");
      }

      /*
       * ubij proces dijeteta
       */
      Close(newfd);
      _exit(0);
    }
  }

  Close(sockfd);
  free(port);

  return 0;
}
예제 #23
0
파일: conf.c 프로젝트: shangyanjin/mydns-ng
/**************************************************************************************************
	CONF_SET_RECURSIVE
	If the 'recursive' configuration option was specified, set the recursive server.
**************************************************************************************************/
static void
conf_set_recursive(void) {
    char		*c;
    const char	*address = conf_get(&Conf, "recursive", NULL);
    char		addr[512];
    int		port = 53;

    if (!address || !address[0])
        return;
    strncpy(addr, address, sizeof(addr)-1);

#if HAVE_IPV6
    if (is_ipv6(addr)) {		/* IPv6 - treat '+' as port separator */
        recursive_family = AF_INET6;
        if ((c = strchr(addr, '+'))) {
            *c++ = '\0';
            if (!(port = atoi(c)))
                port = 53;
        }
        if (inet_pton(AF_INET6, addr, &recursive_sa6.sin6_addr) <= 0) {
            Warnx("%s: %s", address, _("invalid network address for recursive server"));
            return;
        }
        recursive_sa6.sin6_family = AF_INET6;
        recursive_sa6.sin6_port = htons(port);
        forward_recursive = 1;
#if DEBUG_ENABLED && DEBUG_CONF
        DebugX("conf", 1,_("recursive forwarding service through %s:%u"),
               ipaddr(AF_INET6, &recursive_sa6.sin6_addr), port);
#endif
        recursive_fwd_server = STRDUP(address);
    } else {			/* IPv4 - treat '+' or ':' as port separator  */
#endif
        recursive_family = AF_INET;
        if ((c = strchr(addr, '+')) || (c = strchr(addr, ':'))) {
            *c++ = '\0';
            if (!(port = atoi(c)))
                port = 53;
        }
        if (inet_pton(AF_INET, addr, &recursive_sa.sin_addr) <= 0) {
            Warnx("%s: %s", address, _("invalid network address for recursive server"));
            return;
        }
        recursive_sa.sin_family = AF_INET;
        recursive_sa.sin_port = htons(port);
#if DEBUG_ENABLED &&DEBUG_CONF
        DebugX("conf", 1,_("recursive forwarding service through %s:%u"),
               ipaddr(AF_INET, &recursive_sa.sin_addr), port);
#endif
        forward_recursive = 1;
        recursive_fwd_server = STRDUP(address);
#if HAVE_IPV6
    }
#endif

    if (!forward_recursive) return;

    recursion_timeout = atou(conf_get(&Conf, "recursive-timeout", NULL));
    recursion_connect_timeout = atou(conf_get(&Conf, "recursive-connect-timeout", NULL));
    recursion_retries = atou(conf_get(&Conf, "recursive-retries", NULL));
    recursion_algorithm = conf_get(&Conf, "recursive-algorithm", NULL);

}
static int handle_string(void *ctx, const unsigned char *val, unsigned int len)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("handle_string, val = %s, enter state %d", buf, _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_TABLE_STATUS_KEY:{
			if (aws_dynamo_json_get_table_status(val, len, &(_ctx->r->status))) {
				Warnx("handle_string - failed to get table status");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	case PARSER_STATE_TABLE_NAME_KEY:{
			_ctx->r->table_name = strndup(val, len);
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	case PARSER_STATE_HASH_KEY_ATTRIBUTE_NAME_KEY:{
			_ctx->r->hash_key_name = strndup(val, len);
			_ctx->parser_state = PARSER_STATE_HASH_KEY_ELEMENT_MAP;
			break;
		}
	case PARSER_STATE_RANGE_KEY_ATTRIBUTE_NAME_KEY:{
			_ctx->r->range_key_name = strndup(val, len);
			_ctx->parser_state = PARSER_STATE_HASH_KEY_ELEMENT_MAP;
			break;
		}
	case PARSER_STATE_HASH_KEY_ATTRIBUTE_TYPE_KEY:{
			if (aws_dynamo_json_get_type(val, len, &(_ctx->r->hash_key_type))) {
				Warnx("handle_string - failed to get hash key type");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_HASH_KEY_ELEMENT_MAP;
			break;
		}
	case PARSER_STATE_RANGE_KEY_ATTRIBUTE_TYPE_KEY:{
			if (aws_dynamo_json_get_type(val, len, &(_ctx->r->range_key_type))) {
				Warnx("handle_string - failed to get hash key type");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_HASH_KEY_ELEMENT_MAP;
			break;
		}
	default:{
			Warnx("handle_string - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_string exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
예제 #25
0
static int put_item_map_key(void *ctx, const unsigned char *val,
				  unsigned int len)
{
	struct put_item_ctx *_ctx = (struct put_item_ctx *)ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("put_item_map_key, val = %s, enter state %d", buf,
	      _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_ROOT_MAP:{
			if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_ATTRIBUTES, val, len)) {
				_ctx->parser_state = PARSER_STATE_ATTRIBUTES_KEY;
			} else if (AWS_DYNAMO_VALCMP(AWS_DYNAMO_JSON_CONSUMED_CAPACITY, val, len)) {
				_ctx->parser_state = PARSER_STATE_CAPACITY_KEY;
			} else {
				char key[len + 1];
				snprintf(key, len + 1, "%s", val);

				Warnx("put_item_map_key: Unknown root key '%s'.", key);
				return 0;
			}
			break;
		}
	case PARSER_STATE_ATTRIBUTES_MAP:{
			/* Set the attribute index based on the name. */
			int attribute;

			for (attribute = 0; attribute < _ctx->r->num_attributes;
			     attribute++) {
				struct aws_dynamo_attribute *a =
				    &(_ctx->r->attributes[attribute]);

				if (len == a->name_len
				    && strncmp(val, a->name, len) == 0) {
					_ctx->attribute_index = attribute;
					break;
				}
			}

			if (attribute == _ctx->r->num_attributes) {
				char attr[len + 1];
				snprintf(attr, len + 1, "%s", val);

				Warnx("put_item_map_key: Unknown attribute '%s'.", attr);
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ATTRIBUTE_KEY;
			break;
		}
	case PARSER_STATE_ATTRIBUTE_MAP:{
			/* verify the attribute is of the expected type. */
			struct aws_dynamo_attribute *a;
			const char *expected_type;

			a = &(_ctx->r->attributes[_ctx->attribute_index]);
			expected_type = aws_dynamo_attribute_types[a->type];

			if (len != strlen(expected_type)
			    || strncmp(val, expected_type, len) != 0) {
				char type[len + 1];
				snprintf(type, len + 1, "%s", val);

				Warnx("put_item_map_key: Unexpected type for attribute %s.  Got %s, expected %s.",
					a->name, type, expected_type);
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_ATTRIBUTE_VALUE;
			break;
		}
	default:{
			Warnx("put_item_map_key - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("put_item_map_key exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */
	return 1;
}
static int handle_number(void *ctx, const char *val, unsigned int len)
{
	struct ctx *_ctx = (struct ctx *)ctx;
#ifdef DEBUG_PARSER
	char buf[len + 1];
	snprintf(buf, len + 1, "%s", val);

	Debug("handle_number, val = %s, enter state %d", buf, _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	switch (_ctx->parser_state) {
	case PARSER_STATE_CREATION_DATE_TIME_KEY:{
			double date_time;
			if (aws_dynamo_json_get_double(val, len, &date_time) == -1) {
				Warnx("handle_number: failed to get creation date time.");
				return 0;
			}
			_ctx->r->creation_date_time = (int)date_time;

			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	case PARSER_STATE_READ_CAPACITY_UNITS_KEY:{
			if (aws_dynamo_json_get_int(val, len, &(_ctx->r->read_units)) == -1) {
				Warnx("handle_number: failed to get read units.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_PROVISIONED_THROUGHPUT_MAP;
			break;
		}
	case PARSER_STATE_WRITE_CAPACITY_UNITS_KEY:{
			if (aws_dynamo_json_get_int(val, len, &(_ctx->r->write_units)) == -1) {
				Warnx("handle_number: failed to get write units.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_PROVISIONED_THROUGHPUT_MAP;
			break;
		}
	case PARSER_STATE_NUMBER_OF_DECREASES_TODAY_KEY:{
			if (aws_dynamo_json_get_int(val, len, &(_ctx->r->number_decreases_today)) == -1) {
				Warnx("handle_number: failed to get number of decreases today.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_PROVISIONED_THROUGHPUT_MAP;
			break;
		}
	case PARSER_STATE_ITEM_COUNT_KEY:{
			if (aws_dynamo_json_get_int(val, len, &(_ctx->r->item_count)) == -1) {
				Warnx("handle_number: failed to get item count.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	case PARSER_STATE_TABLE_SIZE_BYTES_KEY:{
			if (aws_dynamo_json_get_int(val, len, &(_ctx->r->table_size_bytes)) == -1) {
				Warnx("handle_number: failed to get table size bytes.");
				return 0;
			}
			_ctx->parser_state = PARSER_STATE_TABLE_DESCRIPTION_MAP;
			break;
		}
	default:{
			Warnx("handle_number - unexpected state %d", _ctx->parser_state);
			return 0;
			break;
		}
	}

#ifdef DEBUG_PARSER
	Debug("handle_number exit %d", _ctx->parser_state);
#endif				/* DEBUG_PARSER */

	return 1;
}
struct aws_dynamo_create_table_response
*aws_dynamo_parse_create_table_response(const char *response, int response_len)
{
	yajl_handle hand;
	yajl_status stat;
	struct ctx _ctx = { 0 };

	_ctx.r = calloc(sizeof(*(_ctx.r)), 1);
	if (_ctx.r == NULL) {
		Warnx("aws_dynamo_parse_create_table_response: response alloc failed.");
		return NULL;
	}

#if YAJL_MAJOR == 2
	hand = yajl_alloc(&handle_callbacks, NULL, &_ctx);
	yajl_parse(hand, response, response_len);
	stat = yajl_complete_parse(hand);
#else
	hand = yajl_alloc(&handle_callbacks, NULL, NULL, &_ctx);
	yajl_parse(hand, response, response_len);
	stat = yajl_parse_complete(hand);
#endif

	if (stat != yajl_status_ok) {
		unsigned char *str = yajl_get_error(hand, 1, response, response_len);
		Warnx("aws_dynamo_parse_create_table_response: json parse failed, '%s'", (const char *)str);
		yajl_free_error(hand, str);
		yajl_free(hand);
		aws_dynamo_free_create_table_response(_ctx.r);
		return NULL;
	}

	yajl_free(hand);
	return _ctx.r;
}