static char * lxl_dns_core_listen(lxl_conf_t *cf, lxl_command_t *cmd, void *conf) { size_t off; lxl_uint_t i, nelts; lxl_url_t u; lxl_str_t *value; in_port_t port; struct sockaddr *sa; struct sockaddr_in *sin; lxl_dns_listen_t *ls; lxl_dns_core_main_conf_t *cmcf; value = lxl_array_elts(cf->args); u.url = value[1]; u.listen = 1; if (lxl_parse_url(cf->pool, &u) != 0) { if (u.err) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "%s in \"%s\" of the \"listen\" directive", u.err, u.url.data); } return LXL_CONF_ERROR; } cmcf = lxl_dns_conf_get_module_main_conf(cf, lxl_dns_core_module); ls = lxl_array_elts(&cmcf->listens); nelts = lxl_array_nelts(&cmcf->listens); for (i = 0; i < nelts; ++i) { sa = (struct sockaddr *) ls[i].sockaddr; off = offsetof(struct sockaddr_in, sin_addr); sin = (struct sockaddr_in *) sa; port = sin->sin_port; if (memcmp(ls[i].sockaddr + off, u.sockaddr + off, 4) != 0) { continue; } if (port != u.port) { continue; } lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "duplicate \"%s\" address and port again", &u.url); return LXL_CONF_ERROR; } ls = lxl_array_push(&cmcf->listens); if (ls == NULL) { return LXL_CONF_ERROR; } memset(ls, 0x00, sizeof(lxl_dns_listen_t)); memcpy(ls->sockaddr, u.sockaddr, u.socklen); ls->socklen = u.socklen; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; return LXL_CONF_OK; }
static char * lxl_dns_core_server(lxl_conf_t *cf, lxl_command_t *cmd, void *conf) { char *rv; void *mconf; lxl_uint_t i; lxl_conf_t pcf; lxl_dns_module_t *module; lxl_dns_conf_ctx_t *ctx, *main_ctx; lxl_dns_core_srv_conf_t *cscf, **cscfp; lxl_dns_core_main_conf_t *cmcf; ctx = lxl_pcalloc(cf->pool, sizeof(lxl_dns_conf_ctx_t)); if (ctx == NULL) { return LXL_CONF_ERROR; } main_ctx = cf->ctx; ctx->main_conf = main_ctx->main_conf; ctx->srv_conf = lxl_pcalloc(cf->pool, lxl_dns_max_module * sizeof(void *)); if (ctx->srv_conf == NULL) { return LXL_CONF_ERROR; } for (i = 0; lxl_modules[i]; ++i) { if (lxl_modules[i]->type != LXL_DNS_MODULE) { continue; } module = lxl_modules[i]->ctx; if (module->create_srv_conf) { mconf = module->create_srv_conf(cf); if (mconf == NULL) { return LXL_CONF_ERROR; } ctx->srv_conf[lxl_modules[i]->ctx_index] = mconf; } } cscf = ctx->srv_conf[lxl_dns_core_module.ctx_index]; cscf->ctx = ctx; cmcf = ctx->main_conf[lxl_dns_core_module.ctx_index]; cscfp = lxl_array_push(&cmcf->servers); if (cscfp == NULL) { return LXL_CONF_ERROR; } *cscfp = cscf; pcf = *cf; cf->ctx = ctx; cf->cmd_type = LXL_DNS_SRV_CONF; rv = lxl_conf_parse(cf, NULL); *cf = pcf; return rv; }
static int lxl_conf_read_token(lxl_conf_t *cf) { char ch, *dst, *src, *start; off_t file_size; size_t len; ssize_t n, size; lxl_str_t *word; lxl_buf_t *b; lxl_uint_t found, start_line, last_space, sharp_comment; found = 0; last_space = 1; sharp_comment = 0; lxl_array_clear(cf->args); b = cf->conf_file->buffer; start = b->pos; start_line = cf->conf_file->line; file_size = lxl_file_size(&cf->conf_file->file.info); for (; ;) { if (b->pos >= b->last) { if (cf->conf_file->file.offset >= file_size) { if (cf->args->nelts > 0 || !last_space) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected end file, \";\" or \"}\""); return LXL_ERROR; } return LXL_CONF_FILE_DONE; } len = b->pos - start; if (len == LXL_CONF_BUFFER) { cf->conf_file->line = start_line; lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "too long paraments \"%*s...\" started", start); return LXL_ERROR; } if (len) { memmove(b->start, start, len); } size = (ssize_t) (file_size - cf->conf_file->file.offset); if (size > b->end - (b->start + len)) { size = b->end - (b->start + len); } n = lxl_read_file(&cf->conf_file->file, b->start + len, size, cf->conf_file->file.offset); if (n == -1) { return -1; } if (n != size) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, lxl_read_file_n " returned only %ld bytes instead of %ld", n, size); return -1; } b->pos = b->start + len; b->last = b->pos + n; start = b->start; } ch = *b->pos++; if (ch == '\n') { cf->conf_file->line++; if (sharp_comment) { sharp_comment = 0; } } if (sharp_comment) { continue; } if (last_space) { if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) { continue; } start = b->pos - 1; start_line = cf->conf_file->line; switch (ch) { case ';': if (lxl_array_nelts(cf->args) == 0) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected \";\""); return LXL_ERROR; } return LXL_OK; case '{': if (lxl_array_nelts(cf->args) == 0) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected \"{\""); return LXL_ERROR; } return LXL_CONF_BLOCK_START; case '}': if (lxl_array_nelts(cf->args) != 0) { lxl_conf_log_error(LXL_LOG_EMERG, cf, 0, "unexpected \"}\""); return LXL_ERROR; } return LXL_CONF_BLOCK_DONE; case '#': sharp_comment = 1; continue; default: last_space = 0; } } else { if (ch == ' ' || ch == '\t' || ch == CR || ch == LF || ch == ';' || ch == '{') { last_space = 1; found = 1; } if (found) { word = lxl_array_push(cf->args); if (word == NULL) { return LXL_ERROR; } word->data = lxl_pnalloc(cf->pool, b->pos - start + 1); if (word == NULL) { return LXL_ERROR; } for (dst = word->data, src = start, len = 0; src < b->pos - 1; ++len) { *dst++ = *src++; } *dst = '\0'; word->len = len; if (ch == ';') { return LXL_OK; } if (ch == '{') { return LXL_CONF_BLOCK_START; } found = 0; } } } }