diff --git a/qse/cmd/http/httpd.c b/qse/cmd/http/httpd.c index efbd69eb..e1593e18 100644 --- a/qse/cmd/http/httpd.c +++ b/qse/cmd/http/httpd.c @@ -68,7 +68,6 @@ enum XCFG_ROOT, XCFG_REALM, XCFG_AUTH, - XCFG_NOAUTH, XCFG_DIRHEAD, XCFG_DIRFOOT, XCFG_ERRHEAD, @@ -846,8 +845,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg) for (i = 0; i < QSE_COUNTOF(loc_xcfg_items); i++) { - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_xcfg_items[i].x); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, loc_xcfg_items[i].y); + pair = qse_xli_findpair (httpd_xtn->xli, list, loc_xcfg_items[i].x); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, loc_xcfg_items[i].y); if (pair && pair->val->type == QSE_XLI_STR) { cfg->xcfg[i] = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len); @@ -860,8 +859,8 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg) } } - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("index")); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.index")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("index")); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.index")); if (pair && pair->val->type == QSE_XLI_STR) { qse_char_t* duptmp; @@ -870,7 +869,7 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg) duptmp = qse_xli_dupflatstr (httpd_xtn->xli, (qse_xli_str_t*)pair->val, &duplen, &count); if (duptmp == QSE_NULL) { - qse_printf (QSE_T("ERROR: in copying index\n")); + qse_printf (QSE_T("ERROR: memory failure in copying index\n")); return -1; } @@ -879,258 +878,248 @@ static int load_loccfg (qse_httpd_t* httpd, qse_xli_list_t* list, loccfg_t* cfg) if (cfg->index.files == QSE_NULL) { - qse_printf (QSE_T("ERROR: in copying index\n")); + qse_printf (QSE_T("ERROR: memory failure in copying index\n")); return -1; } cfg->index.count = count; } - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("cgi")); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.cgi")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("cgi")); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.cgi")); if (pair && pair->val->type == QSE_XLI_LIST) { - /* TODO: more sanity check... this can be done with xli schema... if supported */ qse_xli_list_t* cgilist = (qse_xli_list_t*)pair->val; for (atom = cgilist->head; atom; atom = atom->next) { + struct cgi_t* cgi; + int type; + if (atom->type != QSE_XLI_PAIR) continue; pair = (qse_xli_pair_t*)atom; - if (pair->key && pair->alias && - (pair->val->type == QSE_XLI_NIL || pair->val->type == QSE_XLI_STR)) + + if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = CGI_PREFIX; + else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = CGI_SUFFIX; + else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = CGI_NAME; + else continue; + + cgi = qse_httpd_callocmem (httpd, QSE_SIZEOF(*cgi)); + if (cgi == QSE_NULL) { - struct cgi_t* cgi; - int type; + qse_printf (QSE_T("ERROR: memory failure in copying cgi\n")); + return -1; + } - if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = CGI_PREFIX; - else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = CGI_SUFFIX; - else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = CGI_NAME; - else continue; + cgi->type = type; + cgi->spec = qse_httpd_strtombsdup (httpd, pair->alias); + if (!cgi->spec) + { + qse_httpd_freemem (httpd, cgi); + qse_printf (QSE_T("ERROR: memory failure in copying cgi name\n")); + return -1; + } + if (pair->val->type == QSE_XLI_STR) + { + qse_xli_str_t* str; + qse_size_t count = 0; - cgi = qse_httpd_callocmem (httpd, QSE_SIZEOF(*cgi)); - if (cgi == QSE_NULL) + for (str = (qse_xli_str_t*)pair->val; str; str = str->next) { - qse_printf (QSE_T("ERROR: memory failure in copying cgi\n")); - return -1; - } - - cgi->type = type; - cgi->spec = qse_httpd_strtombsdup (httpd, pair->alias); - if (!cgi->spec) - { - qse_httpd_freemem (httpd, cgi); - qse_printf (QSE_T("ERROR: memory failure in copying cgi name\n")); - return -1; - } - if (pair->val->type == QSE_XLI_STR) - { - qse_xli_str_t* str; - qse_size_t count = 0; - - for (str = (qse_xli_str_t*)pair->val; str; str = str->next) + if (count == 0) { - if (count == 0) + /* the first segment */ + if (qse_strxcmp (str->ptr, str->len, QSE_T("nph")) == 0) cgi->nph = 1; + } + else if (count == 1) + { + /* second segment */ + cgi->shebang = qse_httpd_strntombsdup (httpd, str->ptr, str->len); + if (!cgi->shebang) { - /* the first segment */ - if (qse_strxcmp (str->ptr, str->len, QSE_T("nph")) == 0) cgi->nph = 1; + qse_httpd_freemem (httpd, cgi->spec); + qse_httpd_freemem (httpd, cgi); + qse_printf (QSE_T("ERROR: memory failure in copying cgi shebang\n")); + return -1; } - else if (count == 1) - { - /* second segment */ - cgi->shebang = qse_httpd_strntombsdup (httpd, str->ptr, str->len); - if (!cgi->shebang) - { - qse_httpd_freemem (httpd, cgi->spec); - qse_httpd_freemem (httpd, cgi); - qse_printf (QSE_T("ERROR: memory failure in copying cgi shebang\n")); - return -1; - } - } - - count++; - - /* TODO: more sanity check like the number of maximum segments or the value of the first segment...*/ } + count++; + + /* TODO: more sanity check like the number of maximum segments or the value of the first segment...*/ } - if (cfg->cgi[type].tail) - cfg->cgi[type].tail->next = cgi; - else - cfg->cgi[type].head = cgi; - cfg->cgi[type].tail = cgi; + } - } + if (cfg->cgi[type].tail) + cfg->cgi[type].tail->next = cgi; + else + cfg->cgi[type].head = cgi; + cfg->cgi[type].tail = cgi; + } } - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("auth-rule")); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.auth-rule")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("auth-rule")); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.auth-rule")); if (pair && pair->val->type == QSE_XLI_LIST) { qse_xli_list_t* auth_rule_list = (qse_xli_list_t*)pair->val; for (atom = auth_rule_list->head; atom; atom = atom->next) { + struct auth_rule_t* auth_rule; + int type; + if (atom->type != QSE_XLI_PAIR) continue; pair = (qse_xli_pair_t*)atom; - if (pair->key && pair->val->type == QSE_XLI_STR) + + if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = AUTH_RULE_PREFIX; + else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = AUTH_RULE_SUFFIX; + else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = AUTH_RULE_NAME; + else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = AUTH_RULE_OTHER; + else continue; + + auth_rule = qse_httpd_callocmem (httpd, QSE_SIZEOF(*auth_rule)); + if (auth_rule == QSE_NULL) { - struct auth_rule_t* auth_rule; - int type; + qse_printf (QSE_T("ERROR: memory failure in copying auth-rule\n")); + return -1; + } - if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = AUTH_RULE_PREFIX; - else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = AUTH_RULE_SUFFIX; - else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = AUTH_RULE_NAME; - else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = AUTH_RULE_OTHER; - else continue; - - auth_rule = qse_httpd_callocmem (httpd, QSE_SIZEOF(*auth_rule)); - if (auth_rule == QSE_NULL) + auth_rule->type = type; + if (pair->alias) + { + auth_rule->spec = qse_httpd_strtombsdup (httpd, pair->alias); + if (!auth_rule->spec) { + qse_httpd_freemem (httpd, auth_rule); qse_printf (QSE_T("ERROR: memory failure in copying auth-rule\n")); return -1; } - - auth_rule->type = type; - if (pair->alias) - { - auth_rule->spec = qse_httpd_strtombsdup (httpd, pair->alias); - if (!auth_rule->spec) - { - qse_httpd_freemem (httpd, auth_rule); - qse_printf (QSE_T("ERROR: memory failure in copying auth-rule\n")); - return -1; - } - } - - auth_rule->noauth = 0; - if (qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("noauth")) == 0) auth_rule->noauth = 1; - - if (cfg->auth_rule[type].tail) - cfg->auth_rule[type].tail->next = auth_rule; - else - cfg->auth_rule[type].head = auth_rule; - cfg->auth_rule[type].tail = auth_rule; } - } + + auth_rule->noauth = 0; + if (qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("noauth")) == 0) auth_rule->noauth = 1; + + if (cfg->auth_rule[type].tail) + cfg->auth_rule[type].tail->next = auth_rule; + else + cfg->auth_rule[type].head = auth_rule; + cfg->auth_rule[type].tail = auth_rule; + } } - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("mime")); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.mime")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("mime")); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.mime")); if (pair && pair->val->type == QSE_XLI_LIST) { qse_xli_list_t* mimelist = (qse_xli_list_t*)pair->val; for (atom = mimelist->head; atom; atom = atom->next) { + struct mime_t* mime; + int type; + if (atom->type != QSE_XLI_PAIR) continue; pair = (qse_xli_pair_t*)atom; - if (pair->key && pair->val->type == QSE_XLI_STR) + + if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = MIME_PREFIX; + else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = MIME_SUFFIX; + else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = MIME_NAME; + else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = MIME_OTHER; + else continue; + + mime = qse_httpd_callocmem (httpd, QSE_SIZEOF(*mime)); + if (mime == QSE_NULL) { - struct mime_t* mime; - int type; - - if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = MIME_PREFIX; - else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = MIME_SUFFIX; - else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = MIME_NAME; - else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = MIME_OTHER; - else continue; - - mime = qse_httpd_callocmem (httpd, QSE_SIZEOF(*mime)); - if (mime == QSE_NULL) - { - qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); - return -1; - } - - mime->type = type; - mime->spec = qse_httpd_strtombsdup (httpd, pair->alias); - if (!mime->spec) - { - qse_httpd_freemem (httpd, mime); - qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); - return -1; - } - - mime->value = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len); - if (!mime->value) - { - qse_httpd_freemem (httpd, mime->spec); - qse_httpd_freemem (httpd, mime); - qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); - return -1; - } - - if (cfg->mime[type].tail) - cfg->mime[type].tail->next = mime; - else - cfg->mime[type].head = mime; - cfg->mime[type].tail = mime; + qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); + return -1; } - } - } + + mime->type = type; + mime->spec = qse_httpd_strtombsdup (httpd, pair->alias); + if (!mime->spec) + { + qse_httpd_freemem (httpd, mime); + qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); + return -1; + } + + mime->value = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len); + if (!mime->value) + { + qse_httpd_freemem (httpd, mime->spec); + qse_httpd_freemem (httpd, mime); + qse_printf (QSE_T("ERROR: memory failure in copying mime\n")); + return -1; + } + + if (cfg->mime[type].tail) + cfg->mime[type].tail->next = mime; + else + cfg->mime[type].head = mime; + cfg->mime[type].tail = mime; + } + } for (i = 0; i < 2; i++) { - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, loc_acc_items[i].x); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, loc_acc_items[i].y); + pair = qse_xli_findpair (httpd_xtn->xli, list, loc_acc_items[i].x); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, loc_acc_items[i].y); if (pair && pair->val->type == QSE_XLI_LIST) { qse_xli_list_t* acclist = (qse_xli_list_t*)pair->val; for (atom = acclist->head; atom; atom = atom->next) { + struct access_t* acc; + const qse_char_t* tmp; + qse_size_t len; + int type, value; + if (atom->type != QSE_XLI_PAIR) continue; pair = (qse_xli_pair_t*)atom; - if (pair->key && pair->val->type == QSE_XLI_STR) + + if (qse_strcmp (pair->key, QSE_T("prefix")) == 0) type = ACCESS_PREFIX; + else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0) type = ACCESS_SUFFIX; + else if (qse_strcmp (pair->key, QSE_T("name")) == 0) type = ACCESS_NAME; + else if (qse_strcmp (pair->key, QSE_T("other")) == 0) type = ACCESS_OTHER; + else continue; + + tmp = ((qse_xli_str_t*)pair->val)->ptr; + len = ((qse_xli_str_t*)pair->val)->len; + if (qse_strxcmp (tmp, len, QSE_T("noent")) == 0) value = 404; + else if (qse_strxcmp (tmp, len, QSE_T("forbid")) == 0) value = 403; + else if (qse_strxcmp (tmp, len, QSE_T("ok")) == 0) value = 200; + else continue; + /* TODO: more sanity check */ + + acc = qse_httpd_callocmem (httpd, QSE_SIZEOF(*acc)); + if (acc == QSE_NULL) { - struct access_t* acc; - const qse_char_t* tmp; - qse_size_t len; - int type, value; - - if (qse_strcmp (pair->key, QSE_T("prefix")) == 0 && pair->alias) type = ACCESS_PREFIX; - else if (qse_strcmp (pair->key, QSE_T("suffix")) == 0 && pair->alias) type = ACCESS_SUFFIX; - else if (qse_strcmp (pair->key, QSE_T("name")) == 0 && pair->alias) type = ACCESS_NAME; - else if (qse_strcmp (pair->key, QSE_T("other")) == 0 && !pair->alias) type = ACCESS_OTHER; - else continue; - - tmp = ((qse_xli_str_t*)pair->val)->ptr; - len = ((qse_xli_str_t*)pair->val)->len; - if (qse_strxcmp (tmp, len, QSE_T("noent")) == 0) value = 404; - else if (qse_strxcmp (tmp, len, QSE_T("forbid")) == 0) value = 403; - else if (qse_strxcmp (tmp, len, QSE_T("ok")) == 0) value = 200; - else continue; - /* TODO: more sanity check */ - - acc = qse_httpd_callocmem (httpd, QSE_SIZEOF(*acc)); - if (acc == QSE_NULL) + qse_printf (QSE_T("ERROR: memory failure in copying acc\n")); + return -1; + } + + acc->type = type; + if (pair->alias) + { + acc->spec = qse_httpd_strtombsdup (httpd, pair->alias); + if (!acc->spec) { - qse_printf (QSE_T("ERROR: memory failure in copying acc\n")); + qse_httpd_freemem (httpd, acc); + qse_printf (QSE_T("ERROR: memory failure in copying access\n")); return -1; } - - acc->type = type; - if (pair->alias) - { - acc->spec = qse_httpd_strtombsdup (httpd, pair->alias); - if (!acc->spec) - { - qse_httpd_freemem (httpd, acc); - qse_printf (QSE_T("ERROR: memory failure in copying access\n")); - return -1; - } - } - acc->value = value; - - if (cfg->access[i][type].tail) - cfg->access[i][type].tail->next = acc; - else - cfg->access[i][type].head = acc; - cfg->access[i][type].tail = acc; } - } - } + acc->value = value; + + if (cfg->access[i][type].tail) + cfg->access[i][type].tail->next = acc; + else + cfg->access[i][type].head = acc; + cfg->access[i][type].tail = acc; + } + } } /* TODO: support multiple auth entries here and above */ @@ -1208,8 +1197,8 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q { qse_xli_pair_t* pair; - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, scfg_items[i].x); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, scfg_items[i].y); + pair = qse_xli_findpair (httpd_xtn->xli, list, scfg_items[i].x); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, scfg_items[i].y); if (pair && pair->val->type == QSE_XLI_STR) { server_xtn->scfg[i] = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len); @@ -1223,7 +1212,7 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q } /* load host/location specific configuration */ - host_count = qse_xli_getnumpairsbyname (httpd_xtn->xli, list, QSE_T("host")); + host_count = qse_xli_getnumpairs (httpd_xtn->xli, list, QSE_T("host")); if (host_count <= 0) return 0; /* nothing to load */ QSE_ASSERT (server_xtn->cfgtab == QSE_NULL); @@ -1246,12 +1235,12 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q qse_char_t buf[32]; qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("host[%d]"), i); - host = qse_xli_findpairbyname (httpd_xtn->xli, list, buf); + host = qse_xli_findpair (httpd_xtn->xli, list, buf); if (!host) break; if (host->val->type == QSE_XLI_LIST && host->alias) { - loc_count = qse_xli_getnumpairsbyname (httpd_xtn->xli, (qse_xli_list_t*)host->val, QSE_T("location")); + loc_count = qse_xli_getnumpairs (httpd_xtn->xli, (qse_xli_list_t*)host->val, QSE_T("location")); if (((hostcfg = qse_httpd_callocmem (httpd, QSE_SIZEOF(*hostcfg))) == QSE_NULL) || ((hostcfg->hostname = qse_httpd_strtombsdup (httpd, (host->alias[0] == QSE_T('\0')? QSE_T("*"):host->alias))) == QSE_NULL)) goto oops; @@ -1263,7 +1252,7 @@ static int load_server_config (qse_httpd_t* httpd, qse_httpd_server_t* server, q j--; qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("location[%d]"), j); - loc = qse_xli_findpairbyname (httpd_xtn->xli, (qse_xli_list_t*)host->val, buf); + loc = qse_xli_findpair (httpd_xtn->xli, (qse_xli_list_t*)host->val, buf); if (!loc) break; if (loc->val->type == QSE_XLI_LIST && loc->alias) @@ -1335,7 +1324,7 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l httpd_xtn = qse_httpd_getxtnstd (httpd); - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("bind")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("bind")); if (pair == QSE_NULL || pair->val->type != QSE_XLI_STR) { /* TOOD: logging */ @@ -1351,8 +1340,8 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l return QSE_NULL; } - pair = qse_xli_findpairbyname (httpd_xtn->xli, list, QSE_T("ssl")); - if (!pair) pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.ssl")); + pair = qse_xli_findpair (httpd_xtn->xli, list, QSE_T("ssl")); + if (!pair) pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default.ssl")); if (pair && pair->val->type == QSE_XLI_STR && qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("yes")) == 0) dope.flags |= QSE_HTTPD_SERVER_SECURE; @@ -1389,7 +1378,94 @@ static int open_config_file (qse_httpd_t* httpd) { httpd_xtn_t* httpd_xtn; qse_xli_iostd_t xli_in; - int trait; + int trait, i; + + static struct + { + const qse_char_t* name; + qse_xli_scm_t scm; + } defs[] = + { + { QSE_T("name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("max-nofile"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("max-nproc"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server-default.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server-default.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, + { QSE_T("server-default.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + + { QSE_T("server"), { QSE_XLI_SCM_VALLIST, 0, 0 } }, + { QSE_T("server.bind"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, + { QSE_T("server.host.location"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, + { QSE_T("server.host.location.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server.host.location.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server.host.location.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, + { QSE_T("server.host.location.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } } + }; + httpd_xtn = (httpd_xtn_t*) qse_httpd_getxtnstd (httpd); QSE_ASSERT (httpd_xtn->xli == QSE_NULL); @@ -1402,16 +1478,40 @@ static int open_config_file (qse_httpd_t* httpd) } qse_xli_getopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait); - trait |= QSE_XLI_KEYALIAS; + trait |= QSE_XLI_VALIDATE; qse_xli_setopt (httpd_xtn->xli, QSE_XLI_TRAIT, &trait); + for (i = 0; i < QSE_COUNTOF(defs); i++) + { + if (qse_xli_definepair (httpd_xtn->xli, defs[i].name, &defs[i].scm) <= -1) + { + qse_fprintf (QSE_STDERR, QSE_T("Cannot define %s - %s\n"), defs[i].name, qse_xli_geterrmsg(httpd_xtn->xli)); + qse_xli_close (httpd_xtn->xli); + httpd_xtn->xli = QSE_NULL; + return -1; + } + } + xli_in.type = QSE_XLI_IOSTD_FILE; xli_in.u.file.path = httpd_xtn->cfgfile; xli_in.u.file.cmgr = QSE_NULL; - + if (qse_xli_readstd (httpd_xtn->xli, &xli_in) <= -1) { - qse_fprintf (QSE_STDERR, QSE_T("Cannot load %s - %s\n"), xli_in.u.file.path, qse_xli_geterrmsg(httpd_xtn->xli)); + const qse_xli_loc_t* errloc; + + errloc = qse_xli_geterrloc (httpd_xtn->xli); + + if (errloc->line > 0 || errloc->colm > 0) + { + qse_fprintf (QSE_STDERR, QSE_T("Cannot load %s at line %lu column %lu - %s\n"), + xli_in.u.file.path, (unsigned long int)errloc->line, (unsigned long int)errloc->colm, qse_xli_geterrmsg(httpd_xtn->xli)); + } + else + { + qse_fprintf (QSE_STDERR, QSE_T("Cannot load %s - %s\n"), xli_in.u.file.path, qse_xli_geterrmsg(httpd_xtn->xli)); + } + qse_xli_close (httpd_xtn->xli); httpd_xtn->xli = QSE_NULL; return -1; @@ -1440,12 +1540,14 @@ static void set_limit (qse_httpd_t* httpd, const qse_char_t* name, int what) httpd_xtn = (httpd_xtn_t*)qse_httpd_getxtnstd (httpd); - pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, name); - if (pair && pair->val->type == QSE_XLI_STR) + pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, name); + if (pair) { #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) struct rlimit lim; + QSE_ASSERT (pair->val->type == QSE_XLI_STR); + if (getrlimit (what, &lim) == 0) { const qse_char_t* str; @@ -1479,10 +1581,12 @@ static int load_config (qse_httpd_t* httpd) if (open_config_file (httpd) <= -1) goto oops; - pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("name")); - if (pair && pair->val->type == QSE_XLI_STR) + pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("name")); + if (pair) { qse_mchar_t* tmp; + + QSE_ASSERT (pair->val->type == QSE_XLI_STR); tmp = qse_httpd_strntombsdup (httpd, ((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len); if (tmp) qse_httpd_setname (httpd, tmp); qse_httpd_freemem (httpd, tmp); @@ -1499,7 +1603,7 @@ static int load_config (qse_httpd_t* httpd) { qse_char_t buf[32]; qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), i); - pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, buf); + pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, buf); if (pair == QSE_NULL) break; if (pair->val->type != QSE_XLI_LIST) @@ -1529,7 +1633,7 @@ static int load_config (qse_httpd_t* httpd) } /* load the global default */ - pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, QSE_T("server-default")); + pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, QSE_T("server-default")); if (pair && pair->val->type == QSE_XLI_LIST) { if (load_loccfg (httpd, (qse_xli_list_t*)pair->val, &httpd_xtn->dflcfg) <= -1) @@ -1563,7 +1667,7 @@ static void reconf_server (qse_httpd_t* httpd, qse_httpd_server_t* server) { qse_char_t buf[32]; qse_sprintf (buf, QSE_COUNTOF(buf), QSE_T("server[%d]"), server_xtn->num); - pair = qse_xli_findpairbyname (httpd_xtn->xli, QSE_NULL, buf); + pair = qse_xli_findpair (httpd_xtn->xli, QSE_NULL, buf); if (pair && pair->val->type == QSE_XLI_LIST) { diff --git a/qse/cmd/http/httpd.conf b/qse/cmd/http/httpd.conf index 0012a622..24692557 100644 --- a/qse/cmd/http/httpd.conf +++ b/qse/cmd/http/httpd.conf @@ -37,6 +37,7 @@ server-default { cgi { #name "t3.nph" = "nph"; + #prefix "t3." = "nph"; suffix ".cgi"; suffix ".nph" = "nph"; suffix ".awk" = "cgi", "/usr/bin/qseawk -f"; diff --git a/qse/cmd/xli/xli.c b/qse/cmd/xli/xli.c index d05d4465..527cb7bb 100644 --- a/qse/cmd/xli/xli.c +++ b/qse/cmd/xli/xli.c @@ -357,16 +357,104 @@ static int xli_main (int argc, qse_char_t* argv[]) qse_xli_setopt (xli, QSE_XLI_TRAIT, &g_trait); } +#if 0 +{ + + int i; + static struct + { + const qse_char_t* name; + qse_xli_scm_t scm; + } defs[] = + { + { QSE_T("name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("max-nofile"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("max-nproc"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server-default.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server-default.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, + { QSE_T("server-default.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server-default.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server-default.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server-default.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + + { QSE_T("server"), { QSE_XLI_SCM_VALLIST, 0, 0 } }, + { QSE_T("server.bind"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, + { QSE_T("server.host.location"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, + { QSE_T("server.host.location.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server.host.location.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, + { QSE_T("server.host.location.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, + { QSE_T("server.host.location.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, + { QSE_T("server.host.location.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, + { QSE_T("server.host.location.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, + { QSE_T("server.host.location.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } } + }; + +for (i = 0; i < QSE_COUNTOF(defs); i++) qse_xli_definepair (xli, defs[i].name, &defs[i].scm); + +} +#endif in.type = QSE_XLI_IOSTD_FILE; in.u.file.path = g_input_file; in.u.file.cmgr = g_infile_cmgr; -{ -qse_xli_scm_t scm; -scm.flags = QSE_XLI_SCM_VAL_LIST | QSE_XLI_SCM_KEY_NODUP; -qse_xli_setschema (xli, QSE_T("a.b"), &scm); -} - if (qse_xli_readstd (xli, &in) <= -1) { const qse_xli_loc_t* errloc; @@ -399,7 +487,7 @@ qse_xli_setschema (xli, QSE_T("a.b"), &scm); if (g_lookup_key) { qse_xli_pair_t* pair; - pair = qse_xli_findpairbyname (xli, QSE_NULL, g_lookup_key); + pair = qse_xli_findpair (xli, QSE_NULL, g_lookup_key); if (pair == QSE_NULL) { qse_fprintf (QSE_STDERR, diff --git a/qse/include/qse/types.h b/qse/include/qse/types.h index ea8e49c9..c6f1849a 100644 --- a/qse/include/qse/types.h +++ b/qse/include/qse/types.h @@ -57,18 +57,6 @@ enum qse_bool_t }; typedef enum qse_bool_t qse_bool_t; -/** - * The qse_tri_t type defines a tri-state type that can represent #QSE_ALIVE, - * #QSE_ZOMBIE, and #QSE_DEAD. - */ -enum qse_tri_t -{ - QSE_ALIVE = 1, - QSE_ZOMBIE = 0, - QSE_DEAD = -1 -}; -typedef enum qse_tri_t qse_tri_t; - /** @typedef qse_int_t * The qse_int_t type defines a signed integer type as large as a pointer. */ diff --git a/qse/include/qse/xli/xli.h b/qse/include/qse/xli/xli.h index 00525017..78e9dec1 100644 --- a/qse/include/qse/xli/xli.h +++ b/qse/include/qse/xli/xli.h @@ -50,8 +50,10 @@ enum qse_xli_errnum_t QSE_XLI_ELXCHR, /**< invalid character '${0} */ QSE_XLI_EXKWNR, /**< @word '${0}' not recognized */ QSE_XLI_EXKWEM, /**< @ not followed by a valid word */ - QSE_XLI_EILKEY, /**< illegal key '${0}' */ + QSE_XLI_EUDKEY, /**< undefined key '${0}' */ + QSE_XLI_ENOALI, /**< no alias for '${0}' */ QSE_XLI_EILVAL, /**< illegal value for '${0}' */ + QSE_XLI_ENOVAL, /**< no value for '${0}' */ QSE_XLI_ESTRSEG /**< too many string segments for '${0}' */ }; typedef enum qse_xli_errnum_t qse_xli_errnum_t; @@ -295,12 +297,12 @@ typedef qse_ssize_t (*qse_xli_io_impl_t) ( enum qse_xli_scm_flag_t { - QSE_XLI_SCM_REQUIRED = (1 << 0), - QSE_XLI_SCM_VAL_NIL = (1 << 1), - QSE_XLI_SCM_VAL_STR = (1 << 2), - QSE_XLI_SCM_VAL_LIST = (1 << 3), - QSE_XLI_SCM_KEY_NODUP = (1 << 4), - QSE_XLI_SCM_KEY_ALIAS = (1 << 5) + /*QSE_XLI_SCM_REQUIRED = (1 << 0), TODO: support this. */ + QSE_XLI_SCM_VALNIL = (1 << 1), + QSE_XLI_SCM_VALSTR = (1 << 2), + QSE_XLI_SCM_VALLIST = (1 << 3), + QSE_XLI_SCM_KEYNODUP = (1 << 4), + QSE_XLI_SCM_KEYALIAS = (1 << 5) }; struct qse_xli_scm_t @@ -542,13 +544,13 @@ QSE_EXPORT qse_xli_eof_t* qse_xli_inserteof ( qse_xli_atom_t* peer ); -QSE_EXPORT qse_xli_pair_t* qse_xli_findpairbyname ( +QSE_EXPORT qse_xli_pair_t* qse_xli_findpair ( qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* dotted_name ); -QSE_EXPORT qse_size_t qse_xli_getnumpairsbyname ( +QSE_EXPORT qse_size_t qse_xli_getnumpairs ( qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* dotted_name @@ -586,19 +588,25 @@ QSE_EXPORT void qse_xli_clearroot ( qse_xli_t* xli ); -QSE_EXPORT void qse_xli_clearschema ( - qse_xli_t* xli -); QSE_EXPORT void qse_xli_clear ( qse_xli_t* xli ); -QSE_EXPORT int qse_xli_setschema ( +QSE_EXPORT int qse_xli_definepair ( qse_xli_t* xli, - const qse_char_t* dotted_name, + const qse_char_t* pair_name, const qse_xli_scm_t* scm ); + +QSE_EXPORT int qse_xli_undefinepair ( + qse_xli_t* xli, + const qse_char_t* pair_name +); + +QSE_EXPORT void qse_xli_undefinepairs ( + qse_xli_t* xli +); QSE_EXPORT int qse_xli_read ( qse_xli_t* xli, diff --git a/qse/lib/xli/err.c b/qse/lib/xli/err.c index 7084908b..af0f064a 100644 --- a/qse/lib/xli/err.c +++ b/qse/lib/xli/err.c @@ -49,8 +49,10 @@ const qse_char_t* qse_xli_dflerrstr ( QSE_T("invalid character '${0}'"), QSE_T("'${0}' not recognized"), QSE_T("@ not followed by a valid word"), - QSE_T("illegal key '${0}'"), + QSE_T("undefined key '${0}'"), + QSE_T("no alias for '${0}'"), QSE_T("illegal value for '${0}'"), + QSE_T("no value for '${0}'"), QSE_T("too many string segments for '${0}'") }; diff --git a/qse/lib/xli/read.c b/qse/lib/xli/read.c index 1ee6f7df..c9540e6b 100644 --- a/qse/lib/xli/read.c +++ b/qse/lib/xli/read.c @@ -600,7 +600,9 @@ static int read_pair (qse_xli_t* xli) qse_xli_pair_t* pair; qse_xli_list_t* parlist; qse_size_t dotted_curkey_len; + qse_xli_scm_t* scm = QSE_NULL; + int key_nodup = 0, key_alias = 0; key.ptr = QSE_NULL; name = QSE_NULL; @@ -608,7 +610,44 @@ static int read_pair (qse_xli_t* xli) parlist = xli->parlink->list; - if (xli->opt.trait & QSE_XLI_KEYNODUP) + if (xli->opt.trait & QSE_XLI_KEYNODUP) key_nodup = 1; + if (xli->opt.trait & QSE_XLI_KEYALIAS) key_alias = 1; + + kloc = xli->tok.loc; + key.len = QSE_STR_LEN(xli->tok.name); + key.ptr = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr); + if (key.ptr == QSE_NULL) + { + qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); + goto oops; + } + + dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey); + if ((dotted_curkey_len > 0 && qse_str_cat (xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) || + qse_str_cat (xli->dotted_curkey, key.ptr) == (qse_size_t)-1) + { + qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); + goto oops; + } + + if (xli->opt.trait & QSE_XLI_VALIDATE) + { + qse_rbt_pair_t* pair; + + pair = qse_rbt_search (xli->schema, QSE_STR_PTR(xli->dotted_curkey), QSE_STR_LEN(xli->dotted_curkey)); + if (pair == QSE_NULL) + { + qse_xli_seterror (xli, QSE_XLI_EUDKEY, (const qse_cstr_t*)&key, &kloc); + goto oops; + } + + scm = (qse_xli_scm_t*)QSE_RBT_VPTR(pair); + + if (scm->flags & QSE_XLI_SCM_KEYNODUP) key_nodup = 2; + if (scm->flags & QSE_XLI_SCM_KEYALIAS) key_alias = 2; + } + + if (key_nodup) { qse_xli_atom_t* atom; @@ -628,47 +667,11 @@ static int read_pair (qse_xli_t* xli) } } - kloc = xli->tok.loc; - key.len = QSE_STR_LEN(xli->tok.name); - key.ptr = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr); - if (key.ptr == QSE_NULL) - { - qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); - goto oops; - } - - dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey); - if ((dotted_curkey_len > 0 && qse_str_cat (xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) || - qse_str_cat (xli->dotted_curkey, key.ptr) == (qse_size_t)-1) - { - qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); - goto oops; - } - - - if (xli->opt.trait & QSE_XLI_VALIDATE) - { - qse_rbt_pair_t* pair; - - pair = qse_rbt_search (xli->schema, QSE_STR_PTR(xli->dotted_curkey), QSE_STR_LEN(xli->dotted_curkey)); - if (pair == QSE_NULL) - { - qse_xli_seterror (xli, QSE_XLI_EILKEY, (const qse_cstr_t*)&key, &kloc); - goto oops; - } - - scm = (qse_xli_scm_t*)QSE_RBT_VPTR(pair); - - if (scm->flags & QSE_XLI_SCM_KEY_NODUP) - { - } - } - xli->tok_status |= TOK_STATUS_ENABLE_NSTR; if (get_token (xli) <= -1) goto oops; - if (xli->opt.trait & QSE_XLI_KEYALIAS) + if (key_alias) { /* the name part must be unique for the same key(s) */ if (MATCH (xli, TOK_IDENT) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_SQSTR) || MATCH(xli, TOK_NSTR)) @@ -698,6 +701,13 @@ static int read_pair (qse_xli_t* xli) if (get_token (xli) <= -1) goto oops; } + else if (key_alias == 2) + { + /* SCM_KEYALIAS is specified for this particular item. Let the alias be required. + * If KEYALIAS is globally specified with the specific one, it's optional. */ + qse_xli_seterrnum (xli, QSE_XLI_ENOALI, &key); + goto oops; + } } if (MATCH (xli, TOK_EQ)) @@ -709,7 +719,7 @@ static int read_pair (qse_xli_t* xli) qse_xli_str_t* curstrseg; qse_size_t segcount = 0; - if (scm && !(scm->flags & QSE_XLI_SCM_VAL_STR)) + if (scm && !(scm->flags & QSE_XLI_SCM_VALSTR)) { /* check the value type */ qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc); @@ -775,7 +785,7 @@ static int read_pair (qse_xli_t* xli) } else if (MATCH (xli, TOK_LBRACE)) { - if (scm && !(scm->flags & QSE_XLI_SCM_VAL_LIST)) + if (scm && !(scm->flags & QSE_XLI_SCM_VALLIST)) { /* check the value type */ qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc); @@ -809,10 +819,11 @@ static int read_pair (qse_xli_t* xli) } else if (MATCH (xli, TOK_SEMICOLON)) { - if (scm && !(scm->flags & QSE_XLI_SCM_VAL_NIL)) + if (scm && !(scm->flags & QSE_XLI_SCM_VALNIL) && + !((scm->flags & QSE_XLI_SCM_VALSTR) && scm->str_minseg <= 0)) { /* check the value type */ - qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, &kloc); + qse_xli_seterror (xli, QSE_XLI_ENOVAL, (const qse_cstr_t*)&key, &kloc); goto oops; } diff --git a/qse/lib/xli/xli.c b/qse/lib/xli/xli.c index 99bd7a50..b6438441 100644 --- a/qse/lib/xli/xli.c +++ b/qse/lib/xli/xli.c @@ -64,6 +64,7 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr) xli->schema = qse_rbt_open (mmgr, 0, QSE_SIZEOF(qse_char_t), 1); if (xli->schema == QSE_NULL) goto oops; + qse_rbt_setstyle (xli->schema, qse_getrbtstyle(QSE_RBT_STYLE_INLINE_COPIERS)); xli->root.type = QSE_XLI_LIST; xli->xnil.type = QSE_XLI_NIL; @@ -394,10 +395,6 @@ void qse_xli_clearroot (qse_xli_t* xli) free_list (xli, &xli->root); } -void qse_xli_clearschema (qse_xli_t* xli) -{ - qse_rbt_clear (xli->schema); -} /* ------------------------------------------------------ */ @@ -481,7 +478,7 @@ static qse_xli_pair_t* find_pair_by_key_and_index ( return QSE_NULL; } -qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* dotted_name) +qse_xli_pair_t* qse_xli_findpair (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* pair_name) { const qse_char_t* ptr; const qse_xli_list_t* curlist; @@ -490,7 +487,7 @@ qse_xli_pair_t* qse_xli_findpairbyname (qse_xli_t* xli, const qse_xli_list_t* li curlist = list? list: &xli->root; - ptr = dotted_name; + ptr = pair_name; while (1) { seg.ptr = ptr; @@ -596,7 +593,7 @@ noent: return QSE_NULL; } -qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* dotted_name) +qse_size_t qse_xli_getnumpairs (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* pair_name) { const qse_char_t* ptr; const qse_xli_list_t* curlist; @@ -605,7 +602,7 @@ qse_size_t qse_xli_getnumpairsbyname (qse_xli_t* xli, const qse_xli_list_t* list curlist = list? list: &xli->root; - ptr = dotted_name; + ptr = pair_name; while (1) { seg.ptr = ptr; @@ -768,20 +765,21 @@ qse_char_t* qse_xli_dupflatstr (qse_xli_t* xli, qse_xli_str_t* str, qse_size_t* return tmp; } +/* ------------------------------------------------------ */ -int qse_xli_setschema (qse_xli_t* xli, const qse_char_t* dotted_name, const qse_xli_scm_t* scm) +int qse_xli_definepair (qse_xli_t* xli, const qse_char_t* pair_name, const qse_xli_scm_t* scm) { int tmp; - tmp = scm->flags & (QSE_XLI_SCM_VAL_LIST | QSE_XLI_SCM_VAL_STR | QSE_XLI_SCM_VAL_NIL); - if (tmp != QSE_XLI_SCM_VAL_LIST && tmp != QSE_XLI_SCM_VAL_STR && tmp != QSE_XLI_SCM_VAL_NIL) + tmp = scm->flags & (QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_VALNIL); + if (tmp != QSE_XLI_SCM_VALLIST && tmp != QSE_XLI_SCM_VALSTR && tmp != QSE_XLI_SCM_VALNIL) { /* VAL_LIST, VAL_STR, VAL_NIL can't co-exist */ qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); return -1; } - if (qse_rbt_upsert (xli->schema, dotted_name, qse_strlen(dotted_name), scm, QSE_SIZEOF(scm)) == QSE_NULL) + if (qse_rbt_upsert (xli->schema, pair_name, qse_strlen(pair_name), scm, QSE_SIZEOF(*scm)) == QSE_NULL) { qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); return -1; @@ -789,3 +787,22 @@ int qse_xli_setschema (qse_xli_t* xli, const qse_char_t* dotted_name, const qse_ return 0; } + +int qse_xli_undefinepair (qse_xli_t* xli, const qse_char_t* pair_name) +{ + if (qse_rbt_delete (xli->schema, pair_name, qse_strlen(pair_name)) <= -1) + { + qse_cstr_t ea; + ea.ptr = pair_name; + ea.len = qse_strlen (ea.ptr); + qse_xli_seterrnum (xli, QSE_XLI_ENOENT, &ea); + return -1; + } + + return 0; +} + +void qse_xli_undefinepairs (qse_xli_t* xli) +{ + qse_rbt_clear (xli->schema); +}