int unafs(int argc, char **argv)
{
	FILE *file;

	if (argc != 3) {
		puts("Usage: unafs DATABASE-FILE CELL-NAME");

		if (argc <= 1)
			return 0;
		else
			error();
	}

	if (!(file = fopen(argv[1], "rb")))
		pexit("fopen: %s", argv[1]);

	if (process_db(file, argv[2]))
		if (!ferror(file)) {
			fprintf(stderr, "fread: Unexpected EOF\n");
			error();
		}

	if (ferror(file))
		pexit("fread");

	if (fclose(file))
		pexit("fclose");

	return 0;
}
Beispiel #2
0
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;
}