Example #1
0
static int
do_print_run(const serve_state_t state, int run_id,
             int is_privileged, int user_id)
{
  const struct section_global_data *global = state->global;
  unsigned char *banner_path = 0;
  unsigned char *ps_path = 0;
  unsigned char *log_path = 0;
  unsigned char *sfx = "";
  int arch_flags = 0, pages_num = -1, x, i;
  path_t run_arch;
  struct run_entry info;
  tpTask tsk = 0;
  unsigned char in_buf[1024];
  size_t in_buf_len;
  FILE *f = 0;
  int errcode = -SRV_ERR_SYSTEM_ERROR;
  struct teamdb_export teaminfo;
  const unsigned char *printer_name = 0, *user_name = 0, *location = 0;
  const struct userlist_user_info *ui = 0;
  unsigned char program_path[PATH_MAX];

  program_path[0] = 0;

  if (run_id < 0 || run_id >= run_get_total(state->runlog_state)) {
    errcode = -SRV_ERR_BAD_RUN_ID;
    goto cleanup;
  }
  run_get_entry(state->runlog_state, run_id, &info);
  if (info.status == RUN_VIRTUAL_START
      || info.status == RUN_VIRTUAL_STOP
      || info.status == RUN_EMPTY) {
    errcode = -SRV_ERR_BAD_RUN_ID;
    goto cleanup;
  }
  if (!is_privileged) {
    if (info.user_id != user_id) {
      errcode = -SRV_ERR_NO_PERMS;
      goto cleanup;
    }
    if (!global->enable_printing) {
      errcode = -SRV_ERR_NO_PERMS;
      goto cleanup;
    }
    if (info.pages > 0) {
      errcode = -SRV_ERR_ALREADY_PRINTED;
      goto cleanup;
    }
  }

  if (teamdb_export_team(state->teamdb_state, info.user_id, &teaminfo) < 0)
    return -1;
  if (teaminfo.user) ui = teaminfo.user->cnts0;

  if (!is_privileged) {
    if (ui && ui->printer_name)
      printer_name = ui->printer_name;
  }

  if (global->disable_banner_page <= 0) {
    banner_path = (unsigned char*) alloca(strlen(global->print_work_dir) + 64);
    sprintf(banner_path, "%s/%06d.txt", global->print_work_dir, run_id);
    if (print_banner_page(state, banner_path, run_id, user_id,
                          is_privileged) < 0) {
      goto cleanup;
    }
  }

  if (global->disable_banner_page > 0) {
    if (state->langs[info.lang_id]) sfx = state->langs[info.lang_id]->src_sfx;
    if (global->printout_uses_login > 0) {
      user_name = teamdb_get_login(state->teamdb_state, info.user_id);
    } else {
      user_name = teamdb_get_name_2(state->teamdb_state, info.user_id);
    }
    if (!user_name) user_name = "";
    location = "";
    if (ui && ui->location)
      location = ui->location;
    unsigned char fixed_user_name[PATH_MAX];
    unsigned char fixed_location[PATH_MAX];
    fix_path_component(fixed_user_name, sizeof(fixed_user_name), user_name);
    fix_path_component(fixed_location, sizeof(fixed_location), location);

    snprintf(program_path, sizeof(program_path),
             "%s/%06d_%s_%s%s", global->print_work_dir, run_id,
             fixed_user_name, fixed_location, sfx);
  } else {
    if (state->langs[info.lang_id]) sfx = state->langs[info.lang_id]->src_sfx;
    snprintf(program_path, sizeof(program_path),
             "%s/%06d%s", global->print_work_dir, run_id, sfx);
  }

  arch_flags = serve_make_source_read_path(state, run_arch, sizeof(run_arch), &info);
  if (arch_flags < 0) {
    goto cleanup;
  }
  if (generic_copy_file(arch_flags, 0, run_arch, "", 0, 0, program_path, 0) < 0) {
    goto cleanup;
  }

  ps_path = (unsigned char*) alloca(strlen(global->print_work_dir) + 64);
  sprintf(ps_path, "%s/%06d.ps", global->print_work_dir, run_id);

  log_path = (unsigned char*) alloca(strlen(global->print_work_dir) + 64);
  sprintf(log_path, "%s/%06d.out", global->print_work_dir, run_id);

  if (!(tsk = task_New())) goto cleanup;
  task_AddArg(tsk, global->a2ps_path);
  if (global->a2ps_args) {
    for (i = 0; global->a2ps_args[i]; i++)
      task_AddArg(tsk, global->a2ps_args[i]);
  } else {
    task_AddArg(tsk, "-1");
    task_AddArg(tsk, "-E");
    /*
    task_AddArg(tsk, "-X");
    task_AddArg(tsk, "koi8-r");
    */
  }
  task_AddArg(tsk, "-o");
  task_AddArg(tsk, ps_path);
  if (global->disable_banner_page <= 0) {
    task_AddArg(tsk, banner_path);
  }
  task_AddArg(tsk, program_path);
  task_SetPathAsArg0(tsk);
  task_SetRedir(tsk, 2, TSR_FILE, log_path, O_WRONLY|O_CREAT|O_TRUNC, 0777);
  task_ClearEnv(tsk);
  if (task_Start(tsk) < 0) goto cleanup;
  task_Wait(tsk);
  task_Delete(tsk);
  tsk = 0;

  if (!(f = fopen(log_path, "r"))) goto cleanup;
  while (fgets(in_buf, sizeof(in_buf), f)) {
    in_buf_len = strlen(in_buf);
    if (in_buf_len > sizeof(in_buf) - 5) continue;
    if (!strncmp(in_buf, "[Total:", 7)) {
      if (sscanf(in_buf, "[Total: %d pages", &x) == 1 && x >= 1 && x < 100000) {
        pages_num = x;
        break;
      } 
    }
  }
  fclose(f);
  f = 0;
  if (pages_num <= 0) goto cleanup;

  if (!is_privileged) {
    if (pages_num + run_get_total_pages(state->runlog_state, info.user_id) > global->team_page_quota) {
      errcode = -SRV_ERR_PAGES_QUOTA;
      goto cleanup;
    }
    run_set_pages(state->runlog_state, run_id, pages_num);
  }

  if (!(tsk = task_New())) goto cleanup;
  task_AddArg(tsk, global->lpr_path);
  if (global->lpr_args) {
    for (i = 0; global->lpr_args[i]; i++)
      task_AddArg(tsk, global->lpr_args[i]);
  }
  if (printer_name) {
    task_AddArg(tsk, "-P");
    task_AddArg(tsk, printer_name);
  }
  task_AddArg(tsk, ps_path);
  task_SetPathAsArg0(tsk);
  if (task_Start(tsk) < 0) goto cleanup;
  task_Wait(tsk);
  task_Delete(tsk); tsk = 0;

  unlink(banner_path);
  unlink(program_path);
  unlink(ps_path);
  unlink(log_path);
  return pages_num;

 cleanup:
  if (tsk) task_Delete(tsk);
  if (banner_path) unlink(banner_path);
  if (program_path[0]) unlink(program_path);
  if (ps_path) unlink(ps_path);
  if (log_path) unlink(log_path);
  return errcode;
}
Example #2
0
static int
print_banner_page(const serve_state_t state,
                  const unsigned char *banner_path, int run_id,
                  int user_id, int is_privileged)
{
  struct run_entry info;
  FILE *f = 0;
  time_t start_time;
  unsigned char *s;
  int i, variant, virt_variant;
  struct teamdb_export teaminfo;

  if (run_id < 0 || run_id >= run_get_total(state->runlog_state)) goto cleanup;
  run_get_entry(state->runlog_state, run_id, &info);
  if (info.status == RUN_VIRTUAL_START
      || info.status == RUN_VIRTUAL_STOP
      || info.status == RUN_EMPTY) {
    return -1;
  }
  if (teamdb_export_team(state->teamdb_state, info.user_id, &teaminfo) < 0)
    return -1;
  start_time = run_get_start_time(state->runlog_state);

  if (!(f = fopen(banner_path, "w"))) goto cleanup;
  fprintf(f, "\n\n\n\n\n\n\n\n\n\n");
  fprintf(f, "Run ID:           %d\n", info.run_id);
  fprintf(f, "Submission time:  %s\n",
          duration_str(1, info.time, start_time, 0, 0));
  fprintf(f, "Contest time:     %s\n",
          duration_str(0, info.time, start_time, 0, 0));
  if (is_privileged) {
    fprintf(f, "Originator IP:    %s\n", xml_unparse_ip(info.a.ip));
  }
  fprintf(f, "Size:             %u\n", info.size);
  if (is_privileged) {
    fprintf(f, "Hash code (SHA1): ");
    s = (unsigned char *) &info.sha1;
    for (i = 0; i < 20; i++) fprintf(f, "%02x", *s++);
    fprintf(f, "\n");
  }
  fprintf(f, "User ID:          %d\n", info.user_id);
  fprintf(f, "User login:       %s\n", teamdb_get_login(state->teamdb_state,
                                                        info.user_id));
  fprintf(f, "User name:        %s\n", teamdb_get_name(state->teamdb_state,
                                                       info.user_id));
  fprintf(f, "Problem:          %s\n", state->probs[info.prob_id]->short_name);
  if (state->probs[info.prob_id]->variant_num > 0) {
    variant = info.variant;
    if (!variant) {
      variant = find_variant(state, info.user_id, info.prob_id,
                             &virt_variant);
    }
    if (is_privileged && virt_variant != variant) {
      fprintf(f, "Variant:          %d (%d)\n", virt_variant, variant);
    } else {
      fprintf(f, "Variant:          %d\n", virt_variant);
    }
  }
  fprintf(f, "Language:         %s\n",
          (state->langs[info.lang_id])?((char*)state->langs[info.lang_id]->short_name):"");
  if (teaminfo.user && teaminfo.user->cnts0 && teaminfo.user->cnts0->location) {
    fprintf(f, "Location:         %s\n", teaminfo.user->cnts0->location);
  }
  fprintf(f, "Status:           %s\n", run_status_str(info.status, 0, 0, 0, 0));
  fclose(f);

  return 0;

 cleanup:
  if (f) fclose(f);
  return -1;
}
Example #3
0
void
write_runs_dump(const serve_state_t state, FILE *f, const unsigned char *url,
                unsigned char const *charset)
{
  int total_runs, i, j;
  struct run_entry re;
  struct tm *pts;
  time_t start_time, dur;
  unsigned char *s;
  unsigned char statstr[128];
  time_t tmp_time;

  if (url && *url) {
    fprintf(f, "Content-type: text/plain; charset=%s\n\n", charset);
  }

  fprintf(f,
          "Run_Id"
          ";Time;Nsec;Time2;Date;Year;Mon;Day;Hour;Min;Sec"
          ";Dur;Dur_Day;Dur_Hour;Dur_Min;Dur_Sec"
          ";Size"
          ";IPV6_Flag;IP;SSL_Flag"
          ";Sha1"
          ";User_Id;User_Login;User_Name"
          ";User_Inv;User_Ban;User_Lock"
          ";Prob;Variant"
          ";Lang;Content_Type"
          ";Stat_Short;Status;Score;Score_Adj;Test"
          ";Import_Flag;Hidden_Flag;RO_Flag;Locale_Id;Pages;Judge_Id"
          "\n");

  total_runs = run_get_total(state->runlog_state);
  start_time = run_get_start_time(state->runlog_state);
  for (i = 0; i < total_runs; i++) {
    if (run_get_entry(state->runlog_state, i, &re) < 0) {
      fprintf(f, "%d;Cannot read entry!\n", i);
      continue;
    }
    if (!run_is_valid_status(re.status)) {
      fprintf(f, "%d;Invalid status %d!\n", i, re.status);
      continue;
    }
    if (re.status == RUN_EMPTY) continue;

    fprintf(f, "%d;", i);
    fprintf(f, "%lld;%09d;", re.time, re.nsec);
    tmp_time = re.time;
    pts = localtime(&tmp_time);
    fprintf(f, "%04d%02d%02d%02d%02d%02d;",
            pts->tm_year + 1900,
            pts->tm_mon + 1,
            pts->tm_mday,
            pts->tm_hour,
            pts->tm_min,
            pts->tm_sec);
    fprintf(f, "%04d%02d%02d;",
            pts->tm_year + 1900,
            pts->tm_mon + 1,
            pts->tm_mday);
    fprintf(f, "%04d;%02d;%02d;%02d;%02d;%02d;",
            pts->tm_year + 1900,
            pts->tm_mon + 1,
            pts->tm_mday,
            pts->tm_hour,
            pts->tm_min,
            pts->tm_sec);
    if (state->global->is_virtual) {
      start_time = run_get_virtual_start_time(state->runlog_state, re.user_id);
    }

    dur = re.time - start_time;
    if (dur < 0) dur = 0;
    fprintf(f, "%ld;", dur);
    pts->tm_sec = dur % 60;
    dur /= 60;
    pts->tm_min = dur % 60;
    dur /= 60;
    pts->tm_hour = dur % 24;
    dur /= 24;
    fprintf(f, "%ld;%02d;%02d;%02d;",
            dur, pts->tm_hour, pts->tm_min, pts->tm_sec);

    fprintf(f, "%u;", re.size);
    fprintf(f, "%d;%s;%d;", re.ipv6_flag, xml_unparse_ip(re.a.ip), re.ssl_flag);

    s = (unsigned char*) re.sha1;
    for (j = 0; j < 20; j++) fprintf(f, "%02x", *s++);
    fprintf(f, ";");

    fprintf(f, "%d;", re.user_id);
    if (!(s = teamdb_get_login(state->teamdb_state, re.user_id))) {
      fprintf(f, "!INVALID TEAM!;");
    } else {
      fprintf(f, "%s;", s);
    }
    if (!(s = teamdb_get_name(state->teamdb_state, re.user_id))) {
      fprintf(f, "!INVALID TEAM!;");
    } else {
      fprintf(f, "%s;", s);
    }
    j = teamdb_get_flags(state->teamdb_state, re.user_id);
    s = "";
    if ((j & TEAM_INVISIBLE)) s = "I";
    fprintf(f, "%s;", s);
    s = "";
    if ((j & TEAM_BANNED)) s = "B";
    fprintf(f, "%s;", s);
    s = "";
    if ((j & TEAM_LOCKED)) s = "L";
    fprintf(f, "%s;", s);

    if (re.status == RUN_VIRTUAL_START || re.status == RUN_VIRTUAL_STOP) {
      //fprintf(f, "<problem>;<variant>;<lang_short>;<mime_type>;<short_status>;<status>;<score>;<score_adj>;<test>;<is_imported>;<is_hidden>;<is_readonly>;<locale_id>;<pages>;<judge_id>\n");
      fprintf(f, ";;;;");
      run_status_to_str_short(statstr, sizeof(statstr), re.status);
      fprintf(f, "%s;", statstr);
      run_status_str(re.status, statstr, sizeof(statstr), 0, 0);
      fprintf(f, "%s;", statstr);
      fprintf(f, ";;;;;;;;\n");
      continue;
    }

    if (re.prob_id > 0 && re.prob_id <= state->max_prob
        && state->probs[re.prob_id] && state->probs[re.prob_id]->short_name) {
      fprintf(f, "%s;", state->probs[re.prob_id]->short_name);
    } else {
      fprintf(f, "!INVALID PROBLEM %d!;", re.prob_id);
    }
    fprintf(f, "%d;", re.variant);

    if (!re.lang_id) {
      fprintf(f, ";%s;", mime_type_get_type(re.mime_type));
    } else if (re.lang_id > 0 && re.lang_id <= state->max_lang
        && state->langs[re.lang_id] && state->langs[re.lang_id]->short_name) {
      fprintf(f, "%s;;", state->langs[re.lang_id]->short_name);
    } else {
      fprintf(f, "!INVALID LANGUAGE %d!;", re.lang_id);
    }

    run_status_to_str_short(statstr, sizeof(statstr), re.status);
    fprintf(f, "%s;", statstr);
    run_status_str(re.status, statstr, sizeof(statstr), 0, 0);
    fprintf(f, "%s;", statstr);
    fprintf(f, "%d;%d;", re.score, re.score_adj);
    fprintf(f, "%d;", re.test);
    fprintf(f, "%d;", (re.passed_mode > 0));
    fprintf(f, "%d;", re.is_imported);
    fprintf(f, "%d;", re.is_hidden);
    fprintf(f, "%d;", re.is_readonly);
    fprintf(f, "%d;%d;%d", re.locale_id, re.pages, re.judge_id);

    fprintf(f, "\n");
  }
}