static int parse_plugins(struct ejudge_cfg *cfg, struct xml_tree *tree) { struct xml_tree *p, *q; struct ejudge_plugin *plg; struct xml_attr *a; if (!tree) return 0; if (tree->tag != TG_PLUGINS) return xml_err_elem_not_allowed(tree); if (xml_empty_text(tree) < 0) return -1; if (tree->first) return xml_err_attrs(tree); for (p = tree->first_down; p; p = p->right) { if (p->tag != TG_PLUGIN) return xml_err_elem_not_allowed(p); if (xml_empty_text(p) < 0) return -1; plg = (struct ejudge_plugin*) p; for (a = p->first; a; a = a->next) { switch (a->tag) { case AT_NAME: plg->name = a->text; a->text = 0; break; case AT_TYPE: plg->type = a->text; a->text = 0; break; case AT_LOAD: if (xml_attr_bool(a, &plg->load_flag) < 0) return -1; break; case AT_DEFAULT: if (xml_attr_bool(a, &plg->default_flag) < 0) return -1; break; default: return xml_err_attr_not_allowed(p, a); } } xml_tree_free_attrs(p, &ejudge_config_parse_spec); if (!plg->name) return xml_err_attr_undefined(p, AT_NAME); if (!plg->type) return xml_err_attr_undefined(p, AT_TYPE); for (q = p->first_down; q; q = q->right) { ASSERT(q->tag == TG__DEFAULT); if (!strcmp(q->name[0], "config")) { if (plg->data) return xml_err_elem_redefined(q); plg->data = q; } else if (!strcmp(q->name[0], "path")) { if (xml_leaf_elem(q, &plg->path, 1, 0) < 0) return -1; } else { return xml_err_elem_not_allowed(q); } } if (!plg->data) return xml_err_elem_undefined(p, TG_CONFIG); } cfg->plugin_list = tree->first_down; return 0; }
void nxml_tdecl_ref(tag_declaration tdecl) { char tag[20]; xml_list_add(xl_tags, tdecl); sprintf(tag, "%s-ref", tagkind_name(tdecl->kind)); xml_tag_start(tag); if (tdecl->name) xml_attr("name", tdecl->name); xml_attr_bool("scoped", !!tdecl->container/* || tdecl->container_function*/); xml_attr_ptr("ref", tdecl); xml_tag_end_pop(); }
struct ejudge_cfg * ejudge_cfg_do_parse(char const *path) { struct xml_tree *tree = 0, *p; struct ejudge_cfg *cfg = 0; struct xml_attr *a; unsigned char **p_str; xml_err_path = path; xml_err_spec = &ejudge_config_parse_spec; tree = xml_build_tree(NULL, path, &ejudge_config_parse_spec); if (!tree) return 0; if (tree->tag != TG_CONFIG) { xml_err_top_level(tree, TG_CONFIG); goto failed; } cfg = (struct ejudge_cfg *) tree; xfree(cfg->b.text); cfg->b.text = 0; cfg->l10n = -1; cfg->ejudge_xml_path = xstrdup(path); for (a = cfg->b.first; a; a = a->next) { switch (a->tag) { case AT_ENABLE_L10N: case AT_DISABLE_L10N: case AT_L10N: if (xml_attr_bool(a, &cfg->l10n) < 0) goto failed; if (a->tag == AT_DISABLE_L10N) cfg->l10n = !cfg->l10n; break; case AT_DISABLE_COOKIE_IP_CHECK: if (xml_attr_bool(a, &cfg->disable_cookie_ip_check) < 0) goto failed; break; case AT_ENABLE_COOKIE_IP_CHECK: if (xml_attr_bool(a, &cfg->enable_cookie_ip_check) < 0) goto failed; break; case AT_ENABLE_CONTEST_SELECT: if (xml_attr_bool(a, &cfg->enable_contest_select) < 0) goto failed; break; case AT_DISABLE_NEW_USERS: if (xml_attr_bool(a, &cfg->disable_new_users) < 0) goto failed; break; default: xml_err_attr_not_allowed(&cfg->b, a); goto failed; } } for (p = cfg->b.first_down; p; p = p->right) { if (cfg_final_offsets[p->tag] > 0) { p_str = XPDEREF(unsigned char *, cfg, cfg_final_offsets[p->tag]); if (xml_leaf_elem(p, p_str, 1, 0) < 0) goto failed; continue; } switch (p->tag) { case TG_USER_MAP: if (!(cfg->user_map = parse_user_map(path, p))) goto failed; break; case TG_CAPS: if (parse_capabilities(cfg, p) < 0) goto failed; break; case TG_SERIALIZATION_KEY: { int k, n; if (cfg->serialization_key) { xml_err_elem_redefined(p); goto failed; } if (!p->text || !p->text[0] || sscanf(p->text, "%d%n", &k, &n) != 1 || p->text[n] || k <= 0 || k >= 32768) { xml_err_elem_invalid(p); goto failed; } cfg->serialization_key = k; } break; case TG_PLUGINS: if (parse_plugins(cfg, p) < 0) goto failed; break; case TG_COMPILE_SERVERS: if (parse_compile_servers(cfg, p) < 0) goto failed; break; case TG_SERVE_PATH: break; case TG_HOSTS_OPTIONS: cfg->hosts_options = p; break; default: xml_err_elem_not_allowed(p); break; } }
static int t3_parse_xml( FILE *log, struct xml_tree *t, struct t3_in_packet *r) { struct xml_attr *a; struct xml_tree *uq, *uqx; int submit_count = 0, uqx_count = 0, i; struct t3_in_submit *rs; unsigned char *a_type = 0; unsigned char *slash = 0; if (!t) return 0; if (t->tag != TG_EXAMCHECK) { logerr("root element must be <examcheck>"); return -1; } for (a = t->first; a; a = a->next) { if (a->tag == AT_E) { r->exam_guid = a->text; a->text = 0; } } for (uq = t->first_down; uq; uq = uq->right) { if (uq->tag == TG_UQ) ++submit_count; } if (!submit_count) return 0; if (submit_count > MAX_UQ_COUNT || submit_count < 0) { logerr("too many (%d) <uq> elements", submit_count); return -1; } r->submit_count = submit_count; XCALLOC(r->submits, submit_count); for (uq = t->first_down, i = -1; uq; uq = uq->right) { if (uq->tag != TG_UQ) continue; rs = &r->submits[++i]; a_type = 0; for (a = uq->first; a; a = a->next) { switch (a->tag) { case AT_Q: rs->prob_guid = a->text; a->text = 0; break; case AT_U: rs->user_guid = a->text; a->text = 0; break; case AT_TYPE: a_type = a->text; break; case AT_Q_EXTID: rs->prob_extid = a->text; a->text = 0; break; } } if (!rs->prob_guid) { xml_err_attr_undefined(uq, AT_Q); return -1; } if (!rs->user_guid) { xml_err_attr_undefined(uq, AT_U); return -1; } uqx_count = 0; for (uqx = uq->first_down; uqx; uqx = uqx->right) { if (uqx->tag == TG_UQXFILE) ++uqx_count; } if (!uqx_count) { rs->skip_flag = 1; continue; //xml_err_elem_undefined(uq, TG_UQXFILE); //return -1; } if (uqx_count != 1) { xml_err(uq, "only one element <uqxfile> is allowed"); //return -1; } for (uqx = uq->first_down; uqx && uqx->tag != TG_UQXFILE; uqx = uqx->right); rs->gzipped = -1; for (a = uqx->first; a; a = a->next) { switch (a->tag) { case AT_FILENAME: rs->filename = a->text; a->text = 0; break; case AT_GZIPPED: if (xml_attr_bool(a, &rs->gzipped) < 0) return -1; break; case AT_TYPE: a_type = a->text; break; } } if (!a_type) { xml_err_attr_undefined(uqx, AT_TYPE); return -1; } if (!rs->filename) { xml_err_attr_undefined(uqx, AT_FILENAME); return -1; } // type="LANG/CHARSET" if (!(slash = strchr(a_type, '/'))) { rs->prog_lang = xstrdup(a_type); } else { rs->prog_lang = xmemdup(a_type, slash - a_type); rs->prog_charset = xstrdup(slash + 1); } if (rs->gzipped == -1) { // check for some well-known suffixes int len = strlen(rs->filename); if (ends_with(rs->filename, len, ".gz", 3)) { rs->gzipped = 1; } else { rs->gzipped = 0; } } } return 0; }