static int 
lxl_dns_parse_root_rr(lxl_int_t argc, char (*argv)[64], lxl_uint_t line, void *args)
{
	/* . ttl class type data */
	uint16_t type;
	size_t len;
	char *dns_str_type, *data;
	lxl_dns_rr_t rr;
	lxl_dns_rdata_t *rdata;

	if (argc == 4) {
		dns_str_type = argv[2];
		data = argv[3];
	} else if (argc == 5) {
		dns_str_type = argv[3];
		data = argv[4];
	} else {
		lxl_log_error(LXL_LOG_EMERG, 0, "need 4 | 5 argv, line %lu argc is %ld", line, argc);
		return -1;
	}

	type = lxl_dns_get_rr_type(dns_str_type, strlen(dns_str_type));
	if (type == LXL_DNS_INVALID_TYPE) {
		lxl_log_error(LXL_LOG_EMERG, 0, "unknow dns type %s, line %lu", dns_str_type, line);
		return -1;
	}

	if(type != LXL_DNS_A && type != LXL_DNS_AAAA && type != LXL_DNS_NS) {
		lxl_log_error(LXL_LOG_EMERG, 0, "root domain(.) suport A AAAA NS, not suport type %s", dns_str_type);
		return -1;
	}

	len = strlen(data);
	rdata = lxl_dns_rdata_create(data, len, type);
	if (rdata == NULL) {
		return -1;
	}

	len = strlen(argv[0]);
	lxl_dns_domain_dot_to_label(argv[0], len);
	if (len == 1) {
		rr.nlen = 1;
	} else {
		rr.nlen = len + 1;
	}
	rr.name = argv[0];
	rr.type = type;
	rr.ttl = atoi(argv[1]);
	LXL_DNS_CHECK_TTL(rr.ttl);
	rr.expires_sec = lxl_current_sec + rr.ttl;
	rr.update_flags = LXL_DNS_RR_NORMAL_TYPE;
	rr.rdlength = rdata->rdlength;
	rr.rdata = rdata->rdata;
	rr.soa_nlen = 0;
	rr.soa_flags = LXL_DNS_RRSET_NORMAL_TYPE;

	if (lxl_dns_rr_add(lxl_dns_pool, lxl_dns_root_zone, &rr) == 1) {
		lxl_free(rdata);
		return -1;
	}

	lxl_free(rdata);
	return 1; 
}
예제 #2
0
char *
lxl_conf_parse(lxl_conf_t *cf, lxl_str_t *filename)
{
	int fd;
	lxl_int_t rc;
	lxl_buf_t buf;
	lxl_conf_file_t conf_file;
	enum {
		parse_file = 0,
		parse_block
	} type;

	if (filename) {
		fd = open(filename->data, O_RDONLY);
		if (fd == -1) {
			lxl_conf_log_error(LXL_LOG_EMERG, cf, errno, "open() \"%s\" failed", filename->data);
			return LXL_CONF_ERROR;
		}

		cf->conf_file = &conf_file;
		if (lxl_fd_info(fd, &cf->conf_file->file.info) == -1) {
			lxl_log_error(LXL_LOG_EMERG, errno, lxl_fd_info_n " \"%s\" failed", filename->data);
		}

		cf->conf_file->buffer = &buf;
		buf.start = lxl_alloc(LXL_CONF_BUFFER);
		if (buf.start == NULL) {
			goto failed;
		}

		buf.pos =  buf.start;
		buf.last = buf.start;
		buf.end = buf.last + LXL_CONF_BUFFER;
		cf->conf_file->line = 1;

		cf->conf_file->file.fd = fd;
		cf->conf_file->file.name.len = filename->len;
		cf->conf_file->file.name.data = filename->data;
		cf->conf_file->file.offset = 0;
		cf->conf_file->file.sys_offset = 0;

		type = parse_file;
	} else {
		type = parse_block;
	}

	for (; ;) {
		rc = lxl_conf_read_token(cf);

#if 1
		lxl_uint_t i, nelts;
		lxl_str_t *value;
		nelts = lxl_array_nelts(cf->args);
		value = lxl_array_elts(cf->args);
		for (i = 0; i < nelts; ++i) {
			lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "args: index:%lu value:%s", i, value[i].data);
		}
#endif
		
		if (rc == LXL_ERROR) {
			goto done;
		}

		if (rc == LXL_CONF_BLOCK_DONE) {
			if (type != parse_block) {
				lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected end of file, unexpected \"}\"");
			}

			goto done;
		}

		if (rc == LXL_CONF_FILE_DONE) {
			if (type == parse_block) {
				lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected end of file, expecting \"}\"");
				goto failed;
			}

			goto done;
		}

		/*if (cf->handler) {
			
		}*/

		rc = lxl_conf_handler(cf, rc);
		
		if (rc == -1) {
			goto failed;
		}
	}

failed:
	
	rc = LXL_ERROR;

done:

	if (filename) {
		if (cf->conf_file->buffer->start) {
			lxl_free(cf->conf_file->buffer->start);
		} 

		if (close(fd) == -1) {
			lxl_log_error(LXL_LOG_ALERT, errno, "close() %s failed", filename->data);
			return LXL_CONF_ERROR;

		}
	}

	if (rc == LXL_ERROR) {
		return LXL_CONF_ERROR;
	}
	
	return LXL_CONF_OK;
	
}