struct regex * compile_regex(struct buffer *b, int flags, int needed_sub) { struct regex *new_regex; size_t re_len; /* // matches the last RE */ if (size_buffer(b) == 0) { if (flags > 0) bad_prog(_(BAD_MODIF)); return NULL; } re_len = size_buffer(b); new_regex = ck_malloc(sizeof (struct regex) + re_len - 1); new_regex->flags = flags; memcpy (new_regex->re, get_buffer(b), re_len); #ifdef REG_PERL new_regex->sz = re_len; #else /* GNU regex does not process \t & co. */ new_regex->sz = normalize_text(new_regex->re, re_len, TEXT_REGEX); #endif compile_regex_1 (new_regex, needed_sub); return new_regex; }
static int process_contest(int contest_id) { const struct contest_desc *cnts = 0; unsigned char config_path[PATH_MAX]; unsigned char out_config_path[PATH_MAX]; unsigned char old_config_path[PATH_MAX]; const unsigned char *conf_dir = 0; struct stat stbuf; serve_state_t state = 0; struct section_global_data *global = 0; int lang_id; struct section_language_data *lang, *cs_lang_by_short, *cs_lang_by_id, *cs_lang; int compile_id; int i; int has_to_convert = 0, has_errors = 0; int *lang_map = 0; unsigned char **lang_shorts = 0; unsigned char short_name[1024]; struct textfile config_text; FILE *config_file = NULL; FILE *out_config_file = NULL; unsigned char cmd_buf[PATH_MAX]; memset(&config_text, 0, sizeof(config_text)); fprintf(stderr, "Processing contest %d\n", contest_id); if (contests_get(contest_id, &cnts) < 0 || !cnts) { error("cannot read contest XML for contest %d", contest_id); goto failure; } if (cnts->conf_dir && os_IsAbsolutePath(cnts->conf_dir)) { snprintf(config_path, sizeof(config_path), "%s/serve.cfg", cnts->conf_dir); } else { if (!cnts->root_dir) { error("contest %d root_dir is not set", contest_id); goto failure; } else if (!os_IsAbsolutePath(cnts->root_dir)) { error("contest %d root_dir %s is not absolute", contest_id, cnts->root_dir); goto failure; } if (!(conf_dir = cnts->conf_dir)) conf_dir = "conf"; snprintf(config_path, sizeof(config_path), "%s/%s/serve.cfg", cnts->root_dir, conf_dir); } if (stat(config_path, &stbuf) < 0) { error("contest %d config file %s does not exist", contest_id, config_path); goto failure; } if (!S_ISREG(stbuf.st_mode)) { error("contest %d config file %s is not a regular file", contest_id, config_path); goto failure; } if (access(config_path, R_OK) < 0) { error("contest %d config file %s is not readable", contest_id, config_path); goto failure; } state = serve_state_init(contest_id); state->config_path = xstrdup(config_path); state->current_time = time(0); state->load_time = state->current_time; if (prepare(NULL, state, state->config_path, 0, PREPARE_SERVE, "", 1, 0, 0) < 0) goto failure; global = state->global; if (!global) { error("contest %d has no global section", contest_id); goto failure; } if (strcmp(global->rundb_plugin, "mysql") != 0) { fprintf(stderr, "contest %d does not use mysql\n", contest_id); goto failure; } if (state->max_lang >= 0) { XCALLOC(lang_map, state->max_lang + 1); XCALLOC(lang_shorts, state->max_lang + 1); } for (lang_id = 1; lang_id <= state->max_lang; ++lang_id) { if (!(lang = state->langs[lang_id])) continue; compile_id = lang->compile_id; if (compile_id <= 0) compile_id = lang->id; if (lang->id > 1000) { fprintf(stderr, " language %s id > 1000 (%d)\n", lang->short_name, lang->id); has_errors = 1; continue; } snprintf(short_name, sizeof(short_name), "%s", lang->short_name); map_lang_aliases(short_name, sizeof(short_name)); /* search the language in the compilation server by short_name and by id */ cs_lang_by_short = 0; cs_lang_by_id = 0; for (i = 1; i < cs_lang_total; ++i) { if ((cs_lang = cs_langs[i]) && cs_lang->id == compile_id) { cs_lang_by_id = cs_lang; break; } } for (i = 1; i < cs_lang_total; ++i) { if ((cs_lang = cs_langs[i]) && !strcmp(cs_lang->short_name, short_name)) { cs_lang_by_short = cs_lang; break; } } /* condition to convert: 1) contest language id does not match to compilation server language id; 2) contest language short name, compilation server language short name match. */ if (lang->id != compile_id && cs_lang_by_short != NULL && cs_lang_by_short == cs_lang_by_id) { has_to_convert = 1; fprintf(stderr, " language %s id %d to be changed to %d\n", lang->short_name, lang->id, compile_id); lang_map[lang_id] = compile_id; lang_shorts[lang_id] = xstrdup(lang->short_name); } else if (lang->id == compile_id && cs_lang_by_short != NULL && cs_lang_by_short == cs_lang_by_id) { /* condition to do nothing: 1) contest language id match compilation server language id; 2) contest language short name, compilation server language short name match. */ } else { has_errors = 1; fprintf(stderr, " unexpected language %s, id %d, compile id %d\n", lang->short_name, lang->id, lang->compile_id); if (cs_lang_by_id) { fprintf(stderr, " CS lang by id: id %d, short %s\n", cs_lang_by_id->id, cs_lang_by_id->short_name); } else { fprintf(stderr, " CS lang by id: NULL\n"); } if (cs_lang_by_short) { fprintf(stderr, " CS lang by short name: id %d, short %s\n", cs_lang_by_short->id, cs_lang_by_short->short_name); } else { fprintf(stderr, " CS lang by short name: NULL\n"); } } } if (has_errors) { fprintf(stderr, "contest %d cannot be converted\n", contest_id); return 0; } if (!has_to_convert) { fprintf(stderr, "contest %d is ok\n", contest_id); return 0; } config_file = fopen(config_path, "r"); if (!config_file) { fprintf(stderr, "cannot open %s\n", config_path); return 0; } if (gettextfile(config_file, &config_text) <= 0) { fprintf(stderr, "configuration file %s is empty\n", config_path); return 0; } fclose(config_file); config_file = NULL; normalize_text(&config_text); process_text(&config_text, state->max_lang + 1, lang_map, lang_shorts); snprintf(out_config_path, sizeof(out_config_path), "%s.out", config_path); out_config_file = fopen(out_config_path, "w"); if (!out_config_file) { fprintf(stderr, "cannot open %s\n", out_config_path); return 0; } puttext(out_config_file, &config_text); fclose(out_config_file); out_config_file = NULL; snprintf(cmd_buf, sizeof(cmd_buf), "diff -u %s %s", config_path, out_config_path); //fprintf(stderr, ">>%s\n", cmd_buf); system(cmd_buf); process_db(contest_id, state->max_lang + 1, lang_map); snprintf(old_config_path, sizeof(old_config_path), "%s.old", config_path); fprintf(stderr, "Rename: %s->%s, %s->%s\n", config_path, old_config_path, out_config_path, config_path); if (rename(config_path, old_config_path) < 0) { fprintf(stderr, "Rename: %s->%s failed\n", config_path, old_config_path); } if (rename(out_config_path, config_path) < 0) { fprintf(stderr, "Rename: %s->%s failed\n", out_config_path, config_path); } return 0; failure: return 1; }