static int do_update_entry( struct rldb_mysql_cnts *cs, int run_id, const struct run_entry *re, int flags) { struct rldb_mysql_state *state = cs->plugin_state; struct runlog_state *rls = cs->rl_state; struct run_entry *de; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; ASSERT(run_id >= 0 && run_id < rls->run_u); de = &rls->runs[run_id]; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "UPDATE %sruns SET ", state->md->table_prefix); generate_update_entry_clause(state, cmd_f, re, flags); fprintf(cmd_f, " WHERE contest_id = %d AND run_id = %d ;", cs->contest_id, run_id); close_memstream(cmd_f); cmd_f = 0; if (state->mi->simple_query(state->md, cmd_t, cmd_z) < 0) goto fail; xfree(cmd_t); cmd_t = 0; cmd_z = 0; update_entry(de, re, flags); return run_id; fail: if (cmd_f) fclose(cmd_f); xfree(cmd_t); return -1; }
static int do_update_header( struct rldb_mysql_cnts *cs, const struct run_header *rh, int flags) { struct rldb_mysql_state *state = cs->plugin_state; struct runlog_state *rls = cs->rl_state; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "UPDATE %srunheaders SET ", state->md->table_prefix); generate_update_header_clause(state, cmd_f, rh, flags); fprintf(cmd_f, " WHERE contest_id = %d ;", cs->contest_id); close_memstream(cmd_f); cmd_f = 0; if (state->mi->simple_query(state->md, cmd_t, cmd_z) < 0) goto fail; xfree(cmd_t); cmd_t = 0; cmd_z = 0; update_header(&rls->head, rh, flags); return 0; fail: if (cmd_f) fclose(cmd_f); xfree(cmd_t); return -1; }
/* V_LENS -> V_TREE -> V_STRING -> V_STRING */ static struct value *lens_put(struct info *info, struct value *l, struct value *tree, struct value *str) { assert(l->tag == V_LENS); assert(tree->tag == V_TREE); assert(str->tag == V_STRING); struct memstream ms; struct value *v; struct lns_error *err; init_memstream(&ms); lns_put(ms.stream, l->lens, tree->origin->children, str->string->str, &err); close_memstream(&ms); if (err == NULL && ! HAS_ERR(info)) { v = make_value(V_STRING, ref(info)); v->string = make_string(ms.buf); } else { v = make_exn_lns_error(info, err, str->string->str); free_lns_error(err); FREE(ms.buf); } return v; }
static void exn_print_tree(struct value *exn, struct tree *tree) { struct memstream ms; init_memstream(&ms); dump_tree(ms.stream, tree); close_memstream(&ms); exn_printf_line(exn, "%s", ms.buf); FREE(ms.buf); }
static int reset_func( struct rldb_plugin_cnts *cdata, time_t init_duration, time_t init_sched_time, time_t init_finish_time) { struct rldb_mysql_cnts *cs = (struct rldb_mysql_cnts*) cdata; struct rldb_mysql_state *state = cs->plugin_state; struct common_mysql_iface *mi = state->mi; struct common_mysql_state *md = state->md; struct runlog_state *rls = cs->rl_state; struct run_header_internal rh; int i; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; struct timeval curtime; rls->run_u = 0; if (rls->run_a > 0) { memset(rls->runs, 0, sizeof(rls->runs[0]) * rls->run_a); for (i = 0; i < rls->run_a; ++i) rls->runs[i].status = RUN_EMPTY; } memset(&rls->head, 0, sizeof(rls->head)); rls->head.version = 2; rls->head.duration = init_duration; rls->head.sched_time = init_sched_time; rls->head.finish_time = init_finish_time; mi->simple_fquery(md, "DELETE FROM %sruns WHERE contest_id = %d ;", md->table_prefix, cs->contest_id); mi->simple_fquery(md, "DELETE FROM %srunheaders WHERE contest_id = %d ;", md->table_prefix, cs->contest_id); memset(&rh, 0, sizeof(rh)); gettimeofday(&curtime, 0); rh.contest_id = cs->contest_id; rh.duration = init_duration; rh.sched_time = init_sched_time; rh.finish_time = init_finish_time; rh.last_change_time = curtime.tv_sec; rh.last_change_nsec = curtime.tv_usec * 1000; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "INSERT INTO %srunheaders VALUES ( ", md->table_prefix); mi->unparse_spec(md, cmd_f, HEADERS_ROW_WIDTH, headers_spec, &rh); fprintf(cmd_f, " ) ;"); close_memstream(cmd_f); cmd_f = 0; mi->simple_query(md, cmd_t, cmd_z); xfree(cmd_t); cmd_t = 0; return 0; }
int super_html_serve_unparse_and_save( const unsigned char *path, const unsigned char *tmp_path, const struct sid_state *sstate, const struct ejudge_cfg *config, const unsigned char *charset, const unsigned char *header, const unsigned char *footer, const unsigned char *audit) { char *new_text = 0; size_t new_size = 0; char *old_text = 0; size_t old_size = 0; FILE *f; if (sstate->serve_parse_errors || !sstate->global) return 0; if (!charset || !*charset) charset = EJUDGE_CHARSET; if (!header) header = ""; if (!footer) footer = ""; f = open_memstream(&new_text, &new_size); fprintf(f, "# -*- coding: %s -*-\n", charset); fputs(header, f); super_html_serve_unparse_serve_cfg(f, config, sstate); fputs(footer, f); close_memstream(f); f = 0; if (generic_read_file(&old_text, 0, &old_size, 0, 0, path, 0) >= 0 && new_size == old_size && memcmp(new_text, old_text, new_size) == 0) { info("serve_unparse_and_save: %s not changed", path); xfree(old_text); xfree(new_text); unlink(tmp_path); return 0; } xfree(old_text); old_text = 0; old_size = 0; if (!(f = fopen(tmp_path, "w"))) { xfree(new_text); return -1; } fwrite(new_text, 1, new_size, f); xfree(new_text); new_text = 0; new_size = 0; fputs(audit, f); if (ferror(f) || fclose(f) < 0) { fclose(f); unlink(tmp_path); return -1; } return 1; }
unsigned char * opcaps_unparse(int left_margin, int max_width, opcap_t cap) { char *out_str = 0; size_t out_len = 0; FILE *f; f = open_memstream(&out_str, &out_len); opcaps_unparse_2(f, left_margin, max_width, cap); close_memstream(f); return out_str; }
static int run_one_test(struct test *test) { int r; struct augeas *aug = NULL; struct memstream ms; int result = 0; MEMZERO(&ms, 1); aug = aug_init("/dev/null", lensdir, AUG_NO_STDINC|AUG_NO_MODL_AUTOLOAD); fail(aug == NULL, "aug_init"); fail(aug_error(aug) != AUG_NOERROR, "aug_init: errcode was %d", aug_error(aug)); printf("%-30s ... ", test->name); r = load_module(aug, test); if (r < 0) goto error; r = init_memstream(&ms); fail(r < 0, "init_memstream"); r = aug_srun(aug, ms.stream, test->cmd); fail(r != test->result, "return value: expected %d, actual %d", test->result, r); fail(aug_error(aug) != test->errcode, "errcode: expected %s, actual %s", errtokens[test->errcode], errtokens[aug_error(aug)]); r = close_memstream(&ms); fail(r < 0, "close_memstream"); fail(ms.buf == NULL, "close_memstream left buf NULL"); if (test->out != NULL) { fail(STRNEQ(ms.buf, test->out), "output: expected '%s', actual '%s'", test->out, ms.buf); } else if (test->out_present) { fail(strlen(ms.buf) == 0, "output: expected some output"); } else { fail(strlen(ms.buf) > 0, "output: expected nothing, actual '%s'", ms.buf); } printf("PASS\n"); done: free(ms.buf); aug_close(aug); return result; error: result = -1; goto done; }
static int execute_commands(const unsigned char *dir, const unsigned char **cmds, unsigned char **p_log_txt) { FILE *fout = 0; char *fout_txt = 0; size_t fout_len = 0; int i; unsigned char *s; fout = open_memstream(&fout_txt, &fout_len); for (i = 0; cmds[i]; i++) { fprintf(fout, ">%s\n", cmds[i]); s = read_process_output(cmds[i], dir, 0, 1); fprintf(fout, "%s\n", s); xfree(s); } close_memstream(fout); fout = 0; if (p_log_txt) *p_log_txt = fout_txt; else xfree(fout_txt); return 1; }
static void cmd_http_request( struct server_framework_state *state, struct client_state *p, size_t pkt_size, const struct new_server_prot_packet *pkt_gen) { enum { MAX_PARAM_NUM = 10000, MAX_PARAM_SIZE = 128 * 1024 * 1024, }; const struct new_server_prot_http_request *pkt; size_t in_size; const ej_size_t *arg_sizes, *env_sizes, *param_name_sizes, *param_sizes; unsigned long bptr; const unsigned char ** args; const unsigned char ** envs; const unsigned char ** param_names; const unsigned char ** params; size_t *my_param_sizes; int i; char *out_txt = 0; size_t out_size = 0; FILE *out_f = 0; struct http_request_info hr; unsigned char info_buf[1024]; unsigned char *pbuf = info_buf; memset(&hr, 0, sizeof(hr)); hr.id = p->id; hr.client_state = p; hr.fw_state = state; gettimeofday(&hr.timestamp1, 0); hr.current_time = hr.timestamp1.tv_sec; hr.locale_id = -1; if (pkt_size < sizeof(*pkt)) return nsf_err_packet_too_small(state, p, pkt_size, sizeof(*pkt)); pkt = (const struct new_server_prot_http_request *) pkt_gen; if (pkt->arg_num < 0 || pkt->arg_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); if (pkt->env_num < 0 || pkt->env_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); if (pkt->param_num < 0 || pkt->param_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); in_size = sizeof(*pkt); in_size += pkt->arg_num * sizeof(ej_size_t); in_size += pkt->env_num * sizeof(ej_size_t); in_size += pkt->param_num * 2 * sizeof(ej_size_t); if (pkt_size < in_size) return nsf_err_packet_too_small(state, p, pkt_size, in_size); XALLOCAZ(args, pkt->arg_num); XALLOCAZ(envs, pkt->env_num); XALLOCAZ(param_names, pkt->param_num); XALLOCAZ(params, pkt->param_num); XALLOCAZ(my_param_sizes, pkt->param_num); bptr = (unsigned long) pkt; bptr += sizeof(*pkt); arg_sizes = (const ej_size_t *) bptr; bptr += pkt->arg_num * sizeof(ej_size_t); env_sizes = (const ej_size_t *) bptr; bptr += pkt->env_num * sizeof(ej_size_t); param_name_sizes = (const ej_size_t *) bptr; bptr += pkt->param_num * sizeof(ej_size_t); param_sizes = (const ej_size_t *) bptr; bptr += pkt->param_num * sizeof(ej_size_t); for (i = 0; i < pkt->arg_num; i++) { if (arg_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += arg_sizes[i] + 1; } for (i = 0; i < pkt->env_num; i++) { if (env_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += env_sizes[i] + 1; } for (i = 0; i < pkt->param_num; i++) { if (param_name_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); if (param_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += param_name_sizes[i] + 1; in_size += param_sizes[i] + 1; } if (pkt_size != in_size) return nsf_err_bad_packet_length(state, p, pkt_size, in_size); for (i = 0; i < pkt->arg_num; i++) { args[i] = (const unsigned char*) bptr; bptr += arg_sizes[i] + 1; if (strlen(args[i]) != arg_sizes[i]) return nsf_err_protocol_error(state, p); } for (i = 0; i < pkt->env_num; i++) { envs[i] = (const unsigned char*) bptr; bptr += env_sizes[i] + 1; if (strlen(envs[i]) != env_sizes[i]) return nsf_err_protocol_error(state, p); } for (i = 0; i < pkt->param_num; i++) { param_names[i] = (const unsigned char*) bptr; bptr += param_name_sizes[i] + 1; if (strlen(param_names[i]) != param_name_sizes[i]) return nsf_err_protocol_error(state, p); params[i] = (const unsigned char *) bptr; my_param_sizes[i] = param_sizes[i]; bptr += param_sizes[i] + 1; } hr.arg_num = pkt->arg_num; hr.args = args; hr.env_num = pkt->env_num; hr.envs = envs; hr.param_num = pkt->param_num; hr.param_names = param_names; hr.param_sizes = my_param_sizes; hr.params = params; hr.config = ejudge_config; // ok, generate HTML out_f = open_memstream(&out_txt, &out_size); ns_handle_http_request(state, p, out_f, &hr); close_memstream(out_f); out_f = 0; *pbuf = 0; // report IP? if (hr.ssl_flag) { pbuf = stpcpy(pbuf, "HTTPS:"); } else { pbuf = stpcpy(pbuf, "HTTPS:"); } pbuf = stpcpy(pbuf, xml_unparse_ipv6(&hr.ip)); *pbuf++ = ':'; if (hr.role_name) { pbuf = stpcpy(pbuf, hr.role_name); } if (hr.action > 0 && hr.action < NEW_SRV_ACTION_LAST && ns_symbolic_action_table[hr.action]) { *pbuf++ = '/'; pbuf = stpcpy(pbuf, ns_symbolic_action_table[hr.action]); } if (hr.session_id) { *pbuf++ = '/'; *pbuf++ = 'S'; pbuf += sprintf(pbuf, "%016llx", hr.session_id); if (hr.client_key) { *pbuf++ = '-'; pbuf += sprintf(pbuf, "%016llx", hr.client_key); } } if (hr.user_id > 0) { *pbuf++ = '/'; *pbuf++ = 'U'; pbuf += sprintf(pbuf, "%d", hr.user_id); } if (hr.contest_id > 0) { *pbuf++ = '/'; *pbuf++ = 'C'; pbuf += sprintf(pbuf, "%d", hr.contest_id); } // no reply now if (hr.no_reply) goto cleanup; if (hr.protocol_reply) { xfree(out_txt); out_txt = 0; info("%d:%s -> %d", p->id, info_buf, hr.protocol_reply); nsf_close_client_fds(p); nsf_send_reply(state, p, hr.protocol_reply); goto cleanup; } // if (hr.content_type && hr.content_type[0]) { // generate header char *hdr_t = NULL; size_t hdr_z = 0; FILE *hdr_f = open_memstream(&hdr_t, &hdr_z); fprintf(hdr_f, "Content-Type: %s\n", hr.content_type); fprintf(hdr_f, "Cache-Control: no-cache\n"); fprintf(hdr_f, "Pragma: no-cache\n"); if (hr.client_key) { fprintf(hdr_f, "Set-Cookie: EJSID=%016llx; Path=/\n", hr.client_key); } putc('\n', hdr_f); if (out_size > 0) { fwrite(out_txt, 1, out_size, hdr_f); } fclose(hdr_f); hdr_f = NULL; free(out_txt); out_txt = hdr_t; out_size = hdr_z; } if (!out_txt || !*out_txt) { xfree(out_txt); out_txt = 0; if (hr.allow_empty_output) { info("%d:%s -> OK", p->id, info_buf); nsf_close_client_fds(p); nsf_send_reply(state, p, NEW_SRV_RPL_OK); goto cleanup; } out_f = open_memstream(&out_txt, &out_size); ns_html_err_internal_error(out_f, &hr, 0, "empty output generated"); close_memstream(out_f); out_f = 0; xfree(out_txt); out_txt = 0; } nsf_new_autoclose(state, p, out_txt, out_size); info("%d:%s -> OK, %zu", p->id, info_buf, out_size); nsf_send_reply(state, p, NEW_SRV_RPL_OK); cleanup: if (hr.log_f) fclose(hr.log_f); xfree(hr.log_t); xfree(hr.login); xfree(hr.name); xfree(hr.name_arm); xfree(hr.script_part); xfree(hr.body_attr); }
int main(int argc, char *argv[]) { int i = 1, j = 0; char *key = 0; path_t cpp_opts = {0}; int code = 0; int prepare_flags = 0; unsigned char *user = 0, *group = 0, *workdir = 0; #if HAVE_SETSID - 0 path_t log_path; #endif /* HAVE_SETSID */ int pid = -1; char **argv_restart = 0; unsigned char *ejudge_xml_path = 0; unsigned char *compile_cfg_path = 0; path_t compile_cfg_buf = { 0 }; path_t contests_home_dir = { 0 }; path_t compile_home_dir = { 0 }; #if HAVE_OPEN_MEMSTREAM - 0 FILE *lang_log_f = 0; char *lang_log_t = 0; size_t lang_log_z = 0; #endif /* HAVE_OPEN_MEMSTREAM */ path_t tmp_path; int tmp_len; #if defined __WIN32__ path_t tmp_dir = { 0 }; path_t std_compile_home_dir = { 0 }; #endif enum { SUBST_SIZE = 16 }; const unsigned char *subst_src[SUBST_SIZE]; const unsigned char *subst_dst[SUBST_SIZE]; const unsigned char **subst_src_ptr = 0; const unsigned char **subst_dst_ptr = 0; start_set_self_args(argc, argv); XCALLOC(argv_restart, argc + 2); argv_restart[j++] = argv[0]; //if (argc == 1) goto print_usage; code = 1; while (i < argc) { if (!strcmp(argv[i], "-i")) { initialize_mode = 1; i++; } else if (!strcmp(argv[i], "-k")) { if (++i >= argc) goto print_usage; argv_restart[j++] = argv[i]; key = argv[i++]; } else if (!strcmp(argv[i], "-D")) { daemon_mode = 1; i++; } else if (!strcmp(argv[i], "-R")) { restart_mode = 1; i++; } else if (!strncmp(argv[i], "-D", 2)) { if (cpp_opts[0]) pathcat(cpp_opts, " "); argv_restart[j++] = argv[i]; pathcat(cpp_opts, argv[i++]); } else if (!strcmp(argv[i], "-u")) { if (++i >= argc) goto print_usage; user = argv[i++]; } else if (!strcmp(argv[i], "-g")) { if (++i >= argc) goto print_usage; group = argv[i++]; } else if (!strcmp(argv[i], "-C")) { if (++i >= argc) goto print_usage; workdir = argv[i++]; } else if (!strcmp(argv[i], "-d")) { daemon_mode = 1; i++; } else if (!strcmp(argv[i], "-r")) { if (++i >= argc) goto print_usage; snprintf(contests_home_dir, sizeof(contests_home_dir), "%s", argv[i++]); } else if (!strcmp(argv[i], "-c")) { if (++i >= argc) goto print_usage; snprintf(compile_home_dir, sizeof(compile_home_dir), "%s", argv[i++]); } else if (!strcmp(argv[i], "-x")) { if (++i >= argc) goto print_usage; ejudge_xml_path = argv[i++]; argv_restart[j++] = "-x"; argv_restart[j++] = ejudge_xml_path; } else if (!strcmp(argv[i], "--help")) { code = 0; goto print_usage; } else break; } argv_restart[j++] = "-R"; if (i < argc) { compile_cfg_path = argv[i]; argv_restart[j++] = argv[i++]; } if (i < argc) goto print_usage; argv_restart[j] = 0; start_set_args(argv_restart); if ((pid = start_find_process("ej-compile", 0)) > 0) { fprintf(stderr, "%s: is already running as pid %d\n", argv[0], pid); return 1; } #if defined EJUDGE_XML_PATH if (!ejudge_xml_path) ejudge_xml_path = EJUDGE_XML_PATH; #endif /* EJUDGE_XML_PATH */ if (!ejudge_xml_path) { fprintf(stderr, "%s: ejudge.xml configuration file is not specified\n", argv[0]); return 1; } #if defined EJUDGE_CONTESTS_HOME_DIR if (contests_home_dir[0]) { tmp_len = strlen(EJUDGE_CONTESTS_HOME_DIR); if (!strncmp(ejudge_xml_path, EJUDGE_CONTESTS_HOME_DIR, tmp_len)) { snprintf(tmp_path, sizeof(tmp_path), "%s%s", contests_home_dir, ejudge_xml_path + tmp_len); ejudge_xml_path = xstrdup(tmp_path); } } #endif #ifndef __WIN32__ ejudge_config = ejudge_cfg_parse(ejudge_xml_path); if (!ejudge_config) { fprintf(stderr, "%s: ejudge.xml is invalid\n", argv[0]); return 1; } #endif #ifdef __WIN32__ if (!compile_home_dir[0] && contests_home_dir[0]) { snprintf(compile_home_dir, sizeof(compile_home_dir), "%s/win32_compile", contests_home_dir); } if (!compile_cfg_path && compile_home_dir[0]) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/conf/compile.cfg", compile_home_dir); compile_cfg_path = xstrdup(compile_cfg_buf); } if (!compile_cfg_path && contests_home_dir[0]) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/win32_compile/conf/compile.cfg", contests_home_dir); compile_cfg_path = xstrdup(compile_cfg_buf); } if (!compile_cfg_path && ejudge_config && ejudge_config->compile_home_dir) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/conf/compile.cfg", ejudge_config->compile_home_dir); compile_cfg_path = compile_cfg_buf; } if (!compile_cfg_path && ejudge_config && ejudge_config->contests_home_dir) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/win32_compile/conf/compile.cfg", ejudge_config->contests_home_dir); compile_cfg_path = compile_cfg_buf; } #if defined EJUDGE_CONTESTS_HOME_DIR if (!compile_cfg_path) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/compile/conf/win32_compile.cfg", EJUDGE_CONTESTS_HOME_DIR); compile_cfg_path = compile_cfg_buf; } #endif /* EJUDGE_CONTESTS_HOME_DIR */ if (!compile_cfg_path) { fprintf(stderr, "%s: compile.cfg is not specified\n", argv[0]); return 1; } #else if (!compile_cfg_path && ejudge_config && ejudge_config->compile_home_dir) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/conf/compile.cfg", ejudge_config->compile_home_dir); compile_cfg_path = compile_cfg_buf; } if (!compile_cfg_path && ejudge_config && ejudge_config->contests_home_dir) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/compile/conf/compile.cfg", ejudge_config->contests_home_dir); compile_cfg_path = compile_cfg_buf; } #if defined EJUDGE_CONTESTS_HOME_DIR if (!compile_cfg_path) { snprintf(compile_cfg_buf, sizeof(compile_cfg_buf), "%s/compile/conf/compile.cfg", EJUDGE_CONTESTS_HOME_DIR); compile_cfg_path = compile_cfg_buf; } #endif /* EJUDGE_CONTESTS_HOME_DIR */ if (!compile_cfg_path) { fprintf(stderr, "%s: compile.cfg is not specified\n", argv[0]); return 1; } #endif /* __WIN32__ */ if (start_prepare(user, group, workdir) < 0) return 1; memset(subst_src, 0, sizeof(subst_src)); memset(subst_dst, 0, sizeof(subst_dst)); #ifdef __WIN32__ int subst_idx = 0; if (compile_home_dir[0]) { if (ejudge_config) { subst_src[subst_idx] = ejudge_config->compile_home_dir; subst_dst[subst_idx] = compile_home_dir; subst_idx++; } else { snprintf(std_compile_home_dir, sizeof(std_compile_home_dir), "%s/compile", EJUDGE_CONTESTS_HOME_DIR); subst_src[subst_idx] = std_compile_home_dir; subst_dst[subst_idx] = compile_home_dir; subst_idx++; } } if (contests_home_dir[0]) { subst_src[subst_idx] = EJUDGE_CONTESTS_HOME_DIR; subst_dst[subst_idx] = contests_home_dir; subst_idx++; } if (compile_home_dir[0]) { subst_src[subst_idx] = "/COMPILE_HOME_DIR"; subst_dst[subst_idx] = compile_home_dir; subst_idx++; } if (contests_home_dir[0]) { subst_src[subst_idx] = "/CONTESTS_HOME_DIR"; subst_dst[subst_idx] = contests_home_dir; subst_idx++; } subst_src[subst_idx] = "/TMPDIR"; subst_dst[subst_idx] = get_tmp_dir(tmp_dir, sizeof(tmp_dir)); subst_idx++; fprintf(stderr, "Win32 substitutions:\n"); for (int j = 0; subst_src[j]; ++j) { fprintf(stderr, "%s -> %s\n", subst_src[j], subst_dst[j]); } subst_src_ptr = subst_src; subst_dst_ptr = subst_dst; #endif if (prepare(&serve_state, compile_cfg_path, prepare_flags, PREPARE_COMPILE, cpp_opts, 0, subst_src_ptr, subst_dst_ptr) < 0) return 1; #if HAVE_OPEN_MEMSTREAM - 0 if (!(lang_log_f = open_memstream(&lang_log_t, &lang_log_z))) return 1; if (lang_config_configure(lang_log_f, serve_state.global->lang_config_dir, serve_state.max_lang, serve_state.langs) < 0) { fclose(lang_log_f); lang_log_f = 0; fprintf(stderr, "%s", lang_log_t); return 1; } close_memstream(lang_log_f); lang_log_f = 0; #else if (lang_config_configure(stderr, serve_state.global->lang_config_dir, serve_state.max_lang, serve_state.langs) < 0) return 1; #endif /* HAVE_OPEN_MEMSTREAM */ if (key && filter_languages(key) < 0) return 1; if (create_dirs(&serve_state, PREPARE_COMPILE) < 0) return 1; if (check_config() < 0) return 1; if (initialize_mode) return 0; #if HAVE_SETSID - 0 log_path[0] = 0; #if defined EJUDGE_CONTESTS_HOME_DIR if (!log_path[0]) { snprintf(log_path, sizeof(log_path), "%s/var/ej-compile.log", EJUDGE_CONTESTS_HOME_DIR); } #endif if (!log_path[0]) { snprintf(log_path, sizeof(log_path), "%s/ej-compile.log", serve_state.global->var_dir); } if (daemon_mode) { // daemonize itself if (start_open_log(log_path) < 0) return 1; if ((pid = fork()) < 0) return 1; if (pid > 0) _exit(0); if (setsid() < 0) return 1; #if HAVE_OPEN_MEMSTREAM - 0 == 1 fprintf(stderr, "%s", lang_log_t); #endif /* HAVE_OPEN_MEMSTREAM */ } else if (restart_mode) { if (start_open_log(log_path) < 0) return 1; } #endif /* HAVE_SETSID */ #if HAVE_OPEN_MEMSTREAM - 0 == 1 xfree(lang_log_t); lang_log_t = 0; lang_log_z = 0; #endif /* HAVE_OPEN_MEMSTREAM */ if (do_loop() < 0) return 1; if (interrupt_restart_requested()) start_restart(); return 0; print_usage: printf("Usage: %s [ OPTS ] [config-file]\n", argv[0]); printf(" -k key - specify language key\n"); printf(" -DDEF - define a symbol for preprocessor\n"); printf(" -D - start in daemon mode\n"); printf(" -i - initialize mode: create all dirs and exit\n"); printf(" -k KEY - specify a language filter key\n"); printf(" -u U - start as user U (only as root)\n"); printf(" -g G - start as group G (only as root)\n"); printf(" -C D - change directory to D\n"); printf(" -x X - specify a path to ejudge.xml file\n"); printf(" -r S - substitute ${CONTESTS_HOME_DIR} for S in the config\n"); printf(" -c C - substitute ${COMPILE_HOME_DIR} for C in the config\n"); return code; }
static int get_insert_run_id( struct rldb_plugin_cnts *cdata, time_t create_time, int user_id, int create_nsec) { struct rldb_mysql_cnts *cs = (struct rldb_mysql_cnts *) cdata; struct rldb_mysql_state *state = cs->plugin_state; struct common_mysql_iface *mi = state->mi; struct common_mysql_state *md = state->md; struct runlog_state *rls = cs->rl_state; struct run_entry_internal ri; struct run_entry *re; struct timeval curtime; int run_id, i; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; if ((run_id = find_insert_point(rls, create_time, create_nsec, user_id)) < 0) goto fail; ASSERT(run_id < rls->run_u); if (rls->runs[run_id].status != RUN_EMPTY) { // move [run_id, run_u - 1) one forward memmove(&rls->runs[run_id + 1], &rls->runs[run_id], (rls->run_u - run_id - 1) * sizeof(rls->runs[0])); for (i = run_id + 1; i < rls->run_u; ++i) rls->runs[i].run_id = i; if (mi->simple_fquery(md, "UPDATE %sruns SET run_id = run_id + 1 WHERE contest_id = %d AND run_id >= %d ORDER BY run_id DESC;", md->table_prefix, cs->contest_id, run_id) < 0) goto fail; } re = &rls->runs[run_id]; memset(re, 0, sizeof(*re)); re->run_id = run_id; re->time = create_time; re->nsec = create_nsec; //re->user_id = user_id; re->status = RUN_EMPTY; memset(&ri, 0, sizeof(ri)); gettimeofday(&curtime, 0); ri.run_id = run_id; ri.contest_id = cs->contest_id; ri.create_time = create_time; ri.create_nsec = create_nsec; ri.status = RUN_EMPTY; //ri.user_id = user_id; ri.last_change_time = curtime.tv_sec; ri.last_change_nsec = curtime.tv_usec * 1000; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "INSERT INTO %sruns VALUES ( ", md->table_prefix); mi->unparse_spec(md, cmd_f, RUNS_ROW_WIDTH, runs_spec, &ri); fprintf(cmd_f, " ) ;"); close_memstream(cmd_f); cmd_f = 0; if (mi->simple_query(md, cmd_t, cmd_z) < 0) goto fail; xfree(cmd_t); cmd_t = 0; return run_id; fail: if (cmd_f) fclose(cmd_f); xfree(cmd_t); return -1; }
static int load_header( struct rldb_mysql_cnts *cs, int flags, time_t init_duration, time_t init_sched_time, time_t init_finish_time) { struct rldb_mysql_state *state = cs->plugin_state; struct common_mysql_iface *mi = state->mi; struct common_mysql_state *md = state->md; struct runlog_state *rls = cs->rl_state; struct run_header_internal rh; struct timeval curtime; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; memset(&rh, 0, sizeof(rh)); if (mi->fquery(md, HEADERS_ROW_WIDTH, "SELECT * FROM %srunheaders WHERE contest_id = %d ; ", md->table_prefix, cs->contest_id) < 0) goto fail; if (md->row_count > 1) { err("rldb_mysql: load_header: row_count == %d", md->row_count); goto fail; } if (!md->row_count) { mi->free_res(md); gettimeofday(&curtime, 0); rh.contest_id = cs->contest_id; rh.duration = init_duration; rh.sched_time = init_sched_time; rh.finish_time = init_finish_time; rh.last_change_time = curtime.tv_sec; rh.last_change_nsec = curtime.tv_usec * 1000; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "INSERT INTO %srunheaders VALUES ( ", md->table_prefix); mi->unparse_spec(md, cmd_f, HEADERS_ROW_WIDTH, headers_spec, &rh); fprintf(cmd_f, " ) ;"); close_memstream(cmd_f); cmd_f = 0; if (mi->simple_query(md, cmd_t, cmd_z) < 0) goto fail; xfree(cmd_t); cmd_t = 0; memset(&rls->head, 0, sizeof(rls->head)); rls->head.version = 2; rls->head.byte_order = 0; rls->head.duration = init_duration; rls->head.sched_time = init_sched_time; rls->head.finish_time = init_finish_time; return 0; } if (mi->next_row(md) < 0) goto fail; if (mi->parse_spec(md, md->field_count, md->row, md->lengths, HEADERS_ROW_WIDTH, headers_spec, &rh) < 0) goto fail; mi->free_res(md); memset(&rls->head, 0, sizeof(rls->head)); rls->head.version = 2; rls->head.byte_order = 0; rls->head.start_time = rh.start_time; rls->head.sched_time = rh.sched_time; rls->head.duration = rh.duration; rls->head.stop_time = rh.stop_time; rls->head.finish_time = rh.finish_time; rls->head.saved_duration = rh.saved_duration; rls->head.saved_stop_time = rh.saved_stop_time; rls->head.saved_finish_time = rh.saved_finish_time; return 1; fail: if (cmd_f) fclose(cmd_f); xfree(cmd_t); mi->free_res(md); return -1; }
static int put_entry_func( struct rldb_plugin_cnts *cdata, const struct run_entry *re) { struct rldb_mysql_cnts *cs = (struct rldb_mysql_cnts *) cdata; struct rldb_mysql_state *state = cs->plugin_state; struct runlog_state *rls = cs->rl_state; struct run_entry_internal ri; struct timeval curtime; char *cmd_t = 0; size_t cmd_z = 0; FILE *cmd_f = 0; ASSERT(re); ASSERT(re->run_id >= 0); expand_runs(rls, re->run_id); if (rls->runs[re->run_id].status != RUN_EMPTY) return -1; if (re->status == RUN_EMPTY) return -1; // FIXME: check, that time is valid memset(&ri, 0, sizeof(ri)); gettimeofday(&curtime, 0); ri.run_id = re->run_id; ri.contest_id = cs->contest_id; ri.size = re->size; ri.create_time = re->time; ri.create_nsec = re->nsec; ri.user_id = re->user_id; ri.prob_id = re->prob_id; ri.lang_id = re->lang_id; ri.status = re->status; ri.ip_version = 4; if (re->ipv6_flag) ri.ip_version = 6; run_entry_to_ipv6(re, &ri.ip); ri.ssl_flag = re->ssl_flag; if (re->sha1[0] || re->sha1[1] || re->sha1[2] || re->sha1[3] || re->sha1[4]) { ri.hash = unparse_sha1(re->sha1); } #if CONF_HAS_LIBUUID { char uuid_buf[40]; if (re->run_uuid.v[0] || re->run_uuid.v[1] || re->run_uuid.v[2] || re->run_uuid.v[3]) { uuid_unparse((void*) &re->run_uuid, uuid_buf); ri.run_uuid = uuid_buf; } } #endif ri.score = re->score; ri.test_num = re->test; ri.score_adj = re->score_adj; ri.locale_id = re->locale_id; ri.judge_id = re->judge_id; ri.variant = re->variant; ri.pages = re->pages; ri.is_imported = re->is_imported; ri.is_hidden = re->is_hidden; ri.is_readonly = re->is_readonly; if (re->mime_type) { ri.mime_type = (unsigned char*) mime_type_get_type(re->mime_type); } ri.last_change_time = curtime.tv_sec; ri.last_change_nsec = curtime.tv_usec * 1000; ri.is_marked = re->is_marked; ri.is_saved = re->is_saved; ri.saved_status = re->saved_status; ri.saved_score = re->saved_score; ri.saved_test = re->saved_test; ri.passed_mode = re->passed_mode; ri.eoln_type = re->eoln_type; ri.store_flags = re->store_flags; ri.token_flags = re->token_flags; ri.token_count = re->token_count; cmd_f = open_memstream(&cmd_t, &cmd_z); fprintf(cmd_f, "INSERT INTO %sruns VALUES ( ", state->md->table_prefix); state->mi->unparse_spec(state->md, cmd_f, RUNS_ROW_WIDTH, runs_spec, &ri); fprintf(cmd_f, " ) ;"); close_memstream(cmd_f); cmd_f = 0; if (state->mi->simple_query(state->md, cmd_t, cmd_z) < 0) goto fail; xfree(cmd_t); cmd_t = 0; memcpy(&rls->runs[re->run_id], re, sizeof(rls->runs[0])); return 0; fail: if (cmd_f) fclose(cmd_f); xfree(cmd_t); return -1; }
int super_html_read_serve( FILE *flog, const unsigned char *path, const struct ejudge_cfg *config, const struct contest_desc *cnts, struct sid_state *sstate) { struct stat sb; int cond_count = 0, total, i, cur_id, j, arch, k; struct generic_section_config *pg; struct section_global_data *global; struct section_problem_data *prob, *aprob; struct section_tester_data *tst, *atst; struct section_language_data *lang; size_t vm_size, st_size; size_t *mem_lims, *st_lims; int *mem_cnt, *st_cnt; //int mem_u, st_u, max_i; path_t check_cmd = { 0 }; FILE *fuh; char *fuh_text = 0; size_t fuh_size = 0; path_t cs_spool_dir; path_t conf_dir; path_t tmppath; unsigned char *prob_no_any = 0; size_t cs_spool_dir_len = 0; unsigned char cs_conf_file[PATH_MAX]; if (!cnts) { fprintf(flog, "No contest XML description\n"); return -1; } if (!cnts->conf_dir || !*cnts->conf_dir) { snprintf(conf_dir, sizeof(conf_dir), "%s/%s", cnts->root_dir, "conf"); } else if (!os_IsAbsolutePath(cnts->conf_dir)) { snprintf(conf_dir, sizeof(conf_dir), "%s/%s", cnts->root_dir, cnts->conf_dir); } else { snprintf(conf_dir, sizeof(conf_dir), "%s", cnts->conf_dir); } if (stat(path, &sb) < 0) { // file do not exist return 0; } if (!S_ISREG(sb.st_mode)) { fprintf(flog, "File `%s' not a regular file\n", path); return -1; } if (access(path, R_OK) < 0) { fprintf(flog, "File `%s' is not readable\n", path); return -1; } // FIXME: redirect output? if (!(sstate->cfg = prepare_parse_config_file(path, &cond_count))) { fprintf(flog, "Parsing of `%s' failed\n", path); return -1; } if (cond_count > 0) { fprintf(flog, "The configuration file uses conditional compilation directives\n"); return -1; } // find global section for (pg = sstate->cfg; pg; pg = pg->next) if (!pg->name[0] || !strcmp(pg->name, "global")) break; if (!pg) { fprintf(flog, "The global section is not defined\n"); return -1; } global = sstate->global = (struct section_global_data *) pg; // set up the default value of the root_dir if (!global->root_dir[0]) { snprintf(global->root_dir, sizeof(global->root_dir), "%06d", global->contest_id); } if (!os_IsAbsolutePath(global->root_dir) && config && config->contests_home_dir && os_IsAbsolutePath(config->contests_home_dir)) { snprintf(tmppath, sizeof(tmppath), "%s/%s", config->contests_home_dir, global->root_dir); snprintf(global->root_dir, sizeof(global->root_dir), "%s", tmppath); } #if defined EJUDGE_CONTESTS_HOME_DIR if (!os_IsAbsolutePath(global->root_dir)) { snprintf(tmppath, sizeof(tmppath), "%s/%s", EJUDGE_CONTESTS_HOME_DIR, global->root_dir); snprintf(global->root_dir, sizeof(global->root_dir), "%s", tmppath); } #endif if (!os_IsAbsolutePath(global->root_dir)) { err("global.root_dir must be absolute directory!"); return -1; } // check variables that we don't want to be ever set if (prepare_check_forbidden_global(flog, global) < 0) return -1; // contest_id, conf_dir, root_dir must match if (global->contest_id != cnts->id) { fprintf(flog, "contest_id does not match\n"); return -1; } if (strcmp(global->root_dir, cnts->root_dir)) { fprintf(flog, "root_dir does not match\n"); return -1; } /* if ((!cnts->conf_dir && global->conf_dir) || (cnts->conf_dir && strcmp(cnts->conf_dir, global->conf_dir))) { fprintf(flog, "conf_dir does not match\n"); return -1; } */ // compile server must be used if (!global->compile_dir[0]) { fprintf(flog, "compilation server is not used\n"); return -1; } if (!os_IsAbsolutePath(global->compile_dir)) { snprintf(tmppath, sizeof(tmppath), "%s/var/%s", global->root_dir, global->compile_dir); path_normalize(tmppath, sizeof(tmppath)); snprintf(global->compile_dir, sizeof(global->compile_dir), "%s", tmppath); } if (!config->compile_home_dir) { fprintf(flog, "compile server home dir is not set\n"); return -1; } // cut off "/var/compile" suffix from the compile dir snprintf(cs_spool_dir, sizeof(cs_spool_dir), "%s", global->compile_dir); cs_spool_dir_len = strlen(cs_spool_dir); if (cs_spool_dir_len < sizeof(compile_dir_suffix) || strcmp(cs_spool_dir+cs_spool_dir_len-sizeof(compile_dir_suffix)+1, compile_dir_suffix) != 0) { fprintf(flog, "invalid `compile_dir' %s\n", cs_spool_dir); return -1; } cs_spool_dir[cs_spool_dir_len-sizeof(compile_dir_suffix)+1] = 0; sstate->compile_home_dir = xstrdup(cs_spool_dir); //fprintf(stderr, "compile_home_dir>>%s<<\n", sstate->compile_home_dir); /* snprintf(cs_spool_dir, sizeof(cs_spool_dir), "%s/var/compile", config->compile_home_dir); if (strcmp(cs_spool_dir, global->compile_dir)) { fprintf(flog, "non-default compilation server is used\n"); return -1; } */ prepare_set_global_defaults(global); if (global->stand2_file_name[0]) sstate->enable_stand2 = 1; if (global->plog_file_name[0]) sstate->enable_plog = 1; if (global->stand_extra_format[0]) sstate->enable_extra_col = 1; fuh = open_memstream(&fuh_text, &fuh_size); prepare_unparse_unhandled_global(fuh, global); close_memstream(fuh); fuh = 0; if (fuh_text && *fuh_text) { global->unhandled_vars = fuh_text; } else { xfree(fuh_text); } fuh_text = 0; fuh_size = 0; // collect languages total = 0; cur_id = 0; for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "language") != 0) continue; lang = (struct section_language_data*) pg; if (!lang->id) lang->id = cur_id + 1; cur_id = lang->id; if (lang->id <= 0 || lang->id > EJ_MAX_LANG_ID) { fprintf(flog, "Invalid language ID\n"); return -1; } if (lang->id >= total) total = lang->id + 1; } sstate->lang_a = 0; sstate->langs = 0; sstate->loc_cs_map = 0; sstate->lang_opts = 0; sstate->lang_flags = 0; if (total > 0) { sstate->lang_a = 4; while (total > sstate->lang_a) sstate->lang_a *= 2; XCALLOC(sstate->langs, sstate->lang_a); XCALLOC(sstate->loc_cs_map, sstate->lang_a); XCALLOC(sstate->lang_opts, sstate->lang_a); XCALLOC(sstate->lang_flags, sstate->lang_a); for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "language") != 0) continue; lang = (struct section_language_data*) pg; if (sstate->langs[lang->id]) { fprintf(flog, "Duplicated language ID %d\n", lang->id); return -1; } sstate->langs[lang->id] = lang; } } // load the compilation server state and establish correspondence if (super_load_cs_languages(config, sstate, global->extra_compile_dirs, 0, cs_conf_file, sizeof(cs_conf_file)) < 0) { fprintf(flog, "Failed to load compilation server configuration\n"); return -1; } for (i = 1; i < sstate->lang_a; i++) { if (!(lang = sstate->langs[i])) continue; if (!lang->compile_id) lang->compile_id = lang->id; if (prepare_check_forbidden_lang(flog, lang) < 0) return -1; /* if (lang->compile_id <= 0 || lang->compile_id >= sstate->cs_lang_total || !sstate->cs_langs[lang->compile_id]) { } */ // improve error messaging if (lang->compile_id > 0 && lang->compile_id < sstate->cs_lang_total && sstate->cs_langs[lang->compile_id] && strcmp(lang->short_name, sstate->cs_langs[lang->compile_id]->short_name) != 0) { fprintf(flog, "contest configuration file '%s' specifies language short name '%s' for language %d\n" "and it is different from language short name '%s' in compilation configuration file '%s'\n", path, lang->short_name, lang->compile_id, sstate->cs_langs[lang->compile_id]->short_name, cs_conf_file); return -1; } if (lang->compile_id <= 0 || lang->compile_id >= sstate->cs_lang_total || !sstate->cs_langs[lang->compile_id] || strcmp(lang->short_name, sstate->cs_langs[lang->compile_id]->short_name) != 0) { lang->compile_id = 0; } for (int j = 1; j < sstate->cs_lang_total; ++j) { if (sstate->cs_langs[j] && !strcmp(lang->short_name, sstate->cs_langs[j]->short_name)) { lang->compile_id = j; break; } } if (lang->compile_id <= 0) { fprintf(flog, "Invalid compile_id\n"); return -1; } sstate->loc_cs_map[lang->id] = lang->compile_id; sstate->cs_loc_map[lang->compile_id] = lang->id; fuh = open_memstream(&fuh_text, &fuh_size); prepare_unparse_unhandled_lang(fuh, lang); close_memstream(fuh); fuh = 0; if (fuh_text && *fuh_text) { lang->unhandled_vars = fuh_text; } else { xfree(fuh_text); } fuh_text = 0; fuh_size = 0; if (lang->compiler_env) { for (j = 0; lang->compiler_env[j]; j++) { if (!strncmp(lang->compiler_env[j], "EJUDGE_FLAGS=", 13)) { sstate->lang_opts[lang->id] = xstrmerge1(sstate->lang_opts[lang->id], lang->compiler_env[j] + 13); } } for (--j; j >= 0; --j) { if (!strncmp(lang->compiler_env[j], "EJUDGE_FLAGS=", 13)) { xfree(lang->compiler_env[j]); lang->compiler_env[j] = 0; for (k = j + 1; lang->compiler_env[k]; k++) { lang->compiler_env[k - 1] = lang->compiler_env[k]; } lang->compiler_env[k - 1] = lang->compiler_env[k]; } } } } // collect abstract problems for (pg = sstate->cfg, total = 0; pg; pg = pg->next) { if (!strcmp(pg->name, "problem") && (prob = (struct section_problem_data*) pg)->abstract) total++; } sstate->aprob_a = 0; sstate->aprob_u = 0; sstate->aprobs = 0; sstate->aprob_flags = 0; if (total) { sstate->aprob_a = 4; while (total > sstate->aprob_a) sstate->aprob_a *= 2; XCALLOC(sstate->aprobs, sstate->aprob_a); XCALLOC(sstate->aprob_flags, sstate->aprob_a); for (pg = sstate->cfg, i = 0; pg; pg = pg->next) { if (strcmp(pg->name, "problem") != 0) continue; prob = (struct section_problem_data*) pg; if (!prob->abstract) continue; sstate->aprobs[i++] = prob; if (!prob->short_name[0]) { fprintf(flog, "Abstract problem must have `short_name' field set\n"); return -1; } if (prob->super[0]) { fprintf(flog, "Abstract problem must not have a superproblem\n"); return -1; } if (prepare_check_forbidden_prob(flog, prob) < 0) return -1; prepare_set_abstr_problem_defaults(prob, global); fuh = open_memstream(&fuh_text, &fuh_size); prepare_unparse_unhandled_prob(fuh, prob, global); close_memstream(fuh); fuh = 0; if (fuh_text && *fuh_text) { prob->unhandled_vars = fuh_text; } else { xfree(fuh_text); } fuh_text = 0; fuh_size = 0; } ASSERT(i == total); sstate->aprob_u = total; } // collect concrete problems total = 0; cur_id = 0; for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "problem") != 0) continue; prob = (struct section_problem_data*) pg; if (prob->abstract) continue; if (!prob->id) prob->id = cur_id + 1; cur_id = prob->id; if (prob->id <= 0 || prob->id > EJ_MAX_PROB_ID) { fprintf(flog, "Invalid problem ID\n"); return -1; } if (prob->id >= total) total = prob->id + 1; } sstate->probs = 0; sstate->prob_a = 0; sstate->prob_flags = 0; if (total > 0) { sstate->prob_a = 4; while (total > sstate->prob_a) sstate->prob_a *= 2; XCALLOC(sstate->probs, sstate->prob_a); XCALLOC(sstate->prob_flags, sstate->prob_a); XALLOCAZ(prob_no_any, sstate->prob_a); for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "problem") != 0) continue; prob = (struct section_problem_data*) pg; if (prob->abstract) continue; if (sstate->probs[prob->id]) { fprintf(flog, "Duplicated problem id %d\n", prob->id); return -1; } sstate->probs[prob->id] = prob; if (prob->super[0]) { for (i = 0; i < sstate->aprob_u; i++) if (!strcmp(prob->super, sstate->aprobs[i]->short_name)) break; if (i == sstate->aprob_u) { fprintf(flog, "Abstract problem `%s' not found\n", prob->super); return -1; } } if (prepare_check_forbidden_prob(flog, prob) < 0) return -1; prepare_set_concr_problem_defaults(prob, global); fuh = open_memstream(&fuh_text, &fuh_size); prepare_unparse_unhandled_prob(fuh, prob, global); close_memstream(fuh); fuh = 0; if (fuh_text && *fuh_text) { prob->unhandled_vars = fuh_text; } else { xfree(fuh_text); } fuh_text = 0; fuh_size = 0; } } // collect abstract testers total = 0; for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "tester")) continue; tst = (struct section_tester_data*) pg; if (!tst->abstract) continue; // check, that we know such abstract tester if ((arch = prepare_unparse_is_supported_tester(tst->name)) < 0) { fprintf(flog, "Unsupported abstract tester `%s'\n", tst->name); return -1; } if ((i = prepare_unparse_is_supported_arch(tst->arch)) < 0) { fprintf(flog, "Unsupported tester architecture `%s'\n", tst->arch); return -1; } if (i != arch) { fprintf(flog, "Abstract tester name does not match tester arch\n"); return -1; } if (tst->id) { fprintf(flog, "Abstract tester must not define tester ID\n"); return -1; } if (tst->problem_name[0]) { fprintf(flog, "Abstract tester must not define problem name\n"); return -1; } if (tst->problem) { fprintf(flog, "Abstract tester must not define problem ID\n"); return -1; } total++; } /* Relax, try to work without testers... */ /* if (!total) { fprintf(flog, "No abstract testers defined\n"); return -1; } */ sstate->atester_total = total; if (total > 0) { XCALLOC(sstate->atesters, sstate->atester_total); for (pg = sstate->cfg, i = 0; pg; pg = pg->next) { if (strcmp(pg->name, "tester")) continue; tst = (struct section_tester_data*) pg; if (!tst->abstract) continue; sstate->atesters[i++] = tst; // FIXME: check for unhandled fields } } // collect concrete testers, attempting to recover vm limit, stack limit // and checker name total = 0; cur_id = 0; for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "tester") != 0) continue; tst = (struct section_tester_data*) pg; if (tst->abstract) continue; if (!tst->id) tst->id = cur_id + 1; cur_id = tst->id; if (tst->id <= 0 || tst->id > EJ_MAX_TESTER) { fprintf(flog, "Invalid tester ID\n"); return -1; } if (tst->id >= total) total = tst->id + 1; } sstate->tester_total = total; if (total > 0) { XCALLOC(sstate->testers, sstate->tester_total); } for (pg = sstate->cfg; pg; pg = pg->next) { if (strcmp(pg->name, "tester") != 0) continue; tst = (struct section_tester_data*) pg; if (tst->abstract) continue; if (sstate->testers[tst->id]) { fprintf(flog, "Duplicated tester ID %d\n", tst->id); return -1; } sstate->testers[tst->id] = tst; if (tst->super && tst->super[0] && tst->super[1]) { fprintf(flog, "Tester %d has several supertesters\n", tst->id); return -1; } atst = 0; if (tst->super) { for (i = 0; i < sstate->atester_total; i++) if (!strcmp(sstate->atesters[i]->name, tst->super[0])) break; if (i == sstate->atester_total) { fprintf(flog, "Abstract tester `%s' not found\n", tst->super[0]); return -1; } atst = sstate->atesters[i]; } if (tst->any) { continue; } prob = 0; if (tst->problem && tst->problem_name[0]) { fprintf(flog, "Both problem and problem_name fields cannot be set\n"); return -1; } else if (tst->problem) { if (tst->problem <= 0 || tst->problem >= sstate->prob_a || !sstate->probs[tst->problem]) { fprintf(flog, "problem %d is invalid\n", tst->problem); return -1; } prob = sstate->probs[tst->problem]; } else if (tst->problem_name[0]) { for (i = 1; i < sstate->prob_a; i++) if (sstate->probs[i] && !strcmp(sstate->probs[i]->short_name, tst->problem_name)) break; if (i == sstate->prob_a) { fprintf(flog, "Problem `%s' does not exist\n", tst->problem_name); return -1; } prob = sstate->probs[i]; } else { fprintf(flog, "Neither problem not problem_name are set\n"); return -1; } prob_no_any[prob->id] = 1; vm_size = tst->max_vm_size; if (vm_size == -1L && atst) vm_size = atst->max_vm_size; st_size = tst->max_stack_size; if (st_size == -1L && atst) st_size = atst->max_stack_size; if (vm_size != -1L) { if (prob->max_vm_size == -1L) prob->max_vm_size = vm_size; if (prob->max_vm_size != vm_size) { fprintf(flog, "Conflicting max_vm_size specifications for problem `%s'\n", prob->short_name); return -1; } } if (st_size != -1L) { if (prob->max_stack_size == -1L) prob->max_stack_size = st_size; if (prob->max_stack_size != st_size) { fprintf(flog, "Conflicting max_stack_size specifications for problem `%s'\n", prob->short_name); return -1; } } } for (i = 0; i < sstate->tester_total; i++) { if (!(tst = sstate->testers[i])) continue; atst = 0; if (tst->super) { for (j = 0; j < sstate->atester_total; j++) if (!strcmp(sstate->atesters[j]->name, tst->super[0])) break; if (j == sstate->atester_total) { fprintf(flog, "Abstract tester `%s' not found\n", tst->super[0]); return -1; } atst = sstate->atesters[j]; } if (!tst->any) continue; for (j = 0; j < sstate->prob_a; j++) { if (!(prob = sstate->probs[j])) continue; if (prob_no_any[j]) continue; vm_size = tst->max_vm_size; if (vm_size == -1L && atst) vm_size = atst->max_vm_size; st_size = tst->max_stack_size; if (st_size == -1L && atst) st_size = atst->max_stack_size; if (vm_size != -1L) { if (prob->max_vm_size == -1L) prob->max_vm_size = vm_size; if (prob->max_vm_size != vm_size) { fprintf(flog, "Conflicting max_vm_size specifications for problem `%s'\n", prob->short_name); return -1; } } if (st_size != -1L) { if (prob->max_stack_size == -1L) prob->max_stack_size = st_size; if (prob->max_stack_size != st_size) { fprintf(flog, "Conflicting max_stack_size specifications for problem `%s'\n", prob->short_name); return -1; } } } } XALLOCA(mem_lims, sstate->prob_a); XALLOCA(st_lims, sstate->prob_a); XALLOCA(mem_cnt, sstate->prob_a); XALLOCA(st_cnt, sstate->prob_a); // propagate most used memory limit to superproblem /* for (i = 0; i < sstate->aprob_u; i++) { aprob = sstate->aprobs[i]; mem_u = 0; st_u = 0; XMEMZERO(mem_cnt, sstate->prob_a); XMEMZERO(st_cnt, sstate->prob_a); for (j = 1; j < sstate->prob_a; j++) { if (!(prob = sstate->probs[j]) || !prob->super[0] || strcmp(prob->super, aprob->short_name)) continue; if (prob->max_vm_size != -1L) { for (k = 0; k < mem_u; k++) if (mem_lims[k] == prob->max_vm_size) break; if (k == mem_u) mem_u++; mem_lims[k] = prob->max_vm_size; mem_cnt[k]++; } if (prob->max_stack_size != -1L) { for (k = 0; k < st_u; k++) if (st_lims[k] == prob->max_stack_size) break; if (k == st_u) st_u++; st_lims[k] = prob->max_stack_size; st_cnt[k]++; } } if (mem_u > 0) { max_i = 0; for (i = 1; i < mem_u; i++) if (mem_cnt[i] > mem_cnt[max_i]) max_i = i; aprob->max_vm_size = mem_lims[max_i]; for (j = 1; j < sstate->prob_a; j++) { if (!(prob = sstate->probs[j]) || !prob->super[0] || strcmp(prob->super, aprob->short_name)) continue; if (prob->max_vm_size == -1L) { prob->max_vm_size = 0; } else if (prob->max_vm_size == aprob->max_vm_size) { prob->max_vm_size = -1L; } } } if (st_u > 0) { max_i = 0; for (i = 1; i < st_u; i++) if (st_cnt[i] > st_cnt[max_i]) max_i = i; aprob->max_stack_size = st_lims[max_i]; for (j = 1; j < sstate->prob_a; j++) { if (!(prob = sstate->probs[j]) || !prob->super[0] || strcmp(prob->super, aprob->short_name)) continue; if (prob->max_stack_size == -1L) { prob->max_stack_size = 0; } else if (prob->max_stack_size == aprob->max_stack_size) { prob->max_stack_size = -1L; } } } } */ // assign this check_cmd to all abstract problems without check_cmd for (i = 0; i < sstate->aprob_u; i++) if (!(aprob = sstate->aprobs[i])->check_cmd[0]) snprintf(aprob->check_cmd, sizeof(aprob->check_cmd), "%s", check_cmd); sstate->contest_start_cmd_text = do_load_file(conf_dir, global->contest_start_cmd); sstate->contest_stop_cmd_text = do_load_file(conf_dir, global->contest_stop_cmd); sstate->stand_header_text = do_load_file(conf_dir, global->stand_header_file); sstate->stand_footer_text = do_load_file(conf_dir, global->stand_footer_file); sstate->stand2_header_text = do_load_file(conf_dir, global->stand2_header_file); sstate->stand2_footer_text = do_load_file(conf_dir, global->stand2_footer_file); sstate->plog_header_text = do_load_file(conf_dir, global->plog_header_file); sstate->plog_footer_text = do_load_file(conf_dir, global->plog_footer_file); return 0; }
static void cmd_http_request(struct server_framework_state *state, struct client_state *p, size_t pkt_size, const struct new_server_prot_packet *pkt_gen) { enum { MAX_PARAM_NUM = 10000, MAX_PARAM_SIZE = 128 * 1024 * 1024, }; const struct new_server_prot_http_request *pkt; size_t in_size; const ej_size_t *arg_sizes, *env_sizes, *param_name_sizes, *param_sizes; unsigned long bptr; const unsigned char ** args; const unsigned char ** envs; const unsigned char ** param_names; const unsigned char ** params; size_t *my_param_sizes; int i; char *out_txt = 0; size_t out_size = 0; FILE *out_f = 0; struct http_request_info hr; memset(&hr, 0, sizeof(hr)); hr.id = p->id; hr.client_state = p; hr.fw_state = state; gettimeofday(&hr.timestamp1, 0); if (pkt_size < sizeof(*pkt)) return nsf_err_packet_too_small(state, p, pkt_size, sizeof(*pkt)); pkt = (const struct new_server_prot_http_request *) pkt_gen; if (pkt->arg_num < 0 || pkt->arg_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); if (pkt->env_num < 0 || pkt->env_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); if (pkt->param_num < 0 || pkt->param_num > MAX_PARAM_NUM) return nsf_err_protocol_error(state, p); in_size = sizeof(*pkt); in_size += pkt->arg_num * sizeof(ej_size_t); in_size += pkt->env_num * sizeof(ej_size_t); in_size += pkt->param_num * 2 * sizeof(ej_size_t); if (pkt_size < in_size) return nsf_err_packet_too_small(state, p, pkt_size, in_size); XALLOCAZ(args, pkt->arg_num); XALLOCAZ(envs, pkt->env_num); XALLOCAZ(param_names, pkt->param_num); XALLOCAZ(params, pkt->param_num); XALLOCAZ(my_param_sizes, pkt->param_num); bptr = (unsigned long) pkt; bptr += sizeof(*pkt); arg_sizes = (const ej_size_t *) bptr; bptr += pkt->arg_num * sizeof(ej_size_t); env_sizes = (const ej_size_t *) bptr; bptr += pkt->env_num * sizeof(ej_size_t); param_name_sizes = (const ej_size_t *) bptr; bptr += pkt->param_num * sizeof(ej_size_t); param_sizes = (const ej_size_t *) bptr; bptr += pkt->param_num * sizeof(ej_size_t); for (i = 0; i < pkt->arg_num; i++) { if (arg_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += arg_sizes[i] + 1; } for (i = 0; i < pkt->env_num; i++) { if (env_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += env_sizes[i] + 1; } for (i = 0; i < pkt->param_num; i++) { if (param_name_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); if (param_sizes[i] > MAX_PARAM_SIZE) return nsf_err_protocol_error(state, p); in_size += param_name_sizes[i] + 1; in_size += param_sizes[i] + 1; } if (pkt_size != in_size) return nsf_err_bad_packet_length(state, p, pkt_size, in_size); for (i = 0; i < pkt->arg_num; i++) { args[i] = (const unsigned char*) bptr; bptr += arg_sizes[i] + 1; if (strlen(args[i]) != arg_sizes[i]) return nsf_err_protocol_error(state, p); } for (i = 0; i < pkt->env_num; i++) { envs[i] = (const unsigned char*) bptr; bptr += env_sizes[i] + 1; if (strlen(envs[i]) != env_sizes[i]) return nsf_err_protocol_error(state, p); } for (i = 0; i < pkt->param_num; i++) { param_names[i] = (const unsigned char*) bptr; bptr += param_name_sizes[i] + 1; if (strlen(param_names[i]) != param_name_sizes[i]) return nsf_err_protocol_error(state, p); params[i] = (const unsigned char *) bptr; my_param_sizes[i] = param_sizes[i]; bptr += param_sizes[i] + 1; } hr.arg_num = pkt->arg_num; hr.args = args; hr.env_num = pkt->env_num; hr.envs = envs; hr.param_num = pkt->param_num; hr.param_names = param_names; hr.param_sizes = my_param_sizes; hr.params = params; // ok, generate HTML out_f = open_memstream(&out_txt, &out_size); ns_handle_http_request(state, p, out_f, &hr); close_memstream(out_f); out_f = 0; // no reply now if (hr.no_reply) goto cleanup; if (hr.protocol_reply) { xfree(out_txt); out_txt = 0; info("HTTP_REQUEST -> %d", hr.protocol_reply); nsf_close_client_fds(p); nsf_send_reply(state, p, hr.protocol_reply); goto cleanup; } if (!out_txt || !*out_txt) { xfree(out_txt); out_txt = 0; if (hr.allow_empty_output) { info("HTTP_REQUEST -> OK"); nsf_close_client_fds(p); nsf_send_reply(state, p, NEW_SRV_RPL_OK); goto cleanup; } out_f = open_memstream(&out_txt, &out_size); ns_html_err_internal_error(out_f, &hr, 0, "empty output generated"); close_memstream(out_f); out_f = 0; xfree(out_txt); out_txt = 0; } nsf_new_autoclose(state, p, out_txt, out_size); info("HTTP_REQUEST -> OK, %zu", out_size); nsf_send_reply(state, p, NEW_SRV_RPL_OK); cleanup: xfree(hr.login); xfree(hr.name); xfree(hr.name_arm); xfree(hr.script_part); xfree(hr.body_attr); }