コード例 #1
0
ファイル: printing.c プロジェクト: stden/ejudge
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;
}
コード例 #2
0
ファイル: execute.c プロジェクト: mezun7/ejudge
static int
run_program(int argc, char *argv[], long *p_cpu_time, long *p_real_time)
{
  tTask *tsk = 0;
  int i;
  int retcode = RUN_CHECK_FAILED;
  struct testinfo_struct tinfo;
  unsigned char input_path[PATH_MAX];
  unsigned char output_path[PATH_MAX];
  unsigned char error_path[PATH_MAX];
  unsigned char buf[1024];
  long used_vm_size;

  memset(&tinfo, 0, sizeof(tinfo));
  input_path[0] = 0;
  output_path[0] = 0;
  error_path[0] = 0;

  if (!all_tests) {
    if (test_file && test_file[0] && test_pattern && test_pattern[0]) {
      // guess test_num from test_file and test_pat
      // FIXME: dumb!
      i = 0;
      do {
        ++i;
        snprintf(buf, sizeof(buf), test_pattern, i);
      } while (i < 1000 && strcmp(buf, test_file) != 0);
      if (i >= 1000) {
        fatal("failed to guess test_num from test_file and test_pattern");
      }
      test_num = i;
      test_file = NULL;
    }

    if (test_num > 0) {
      if (test_pattern && test_pattern[0]) {
        snprintf(buf, sizeof(buf), test_pattern, test_num);
        test_file = strdup(buf);
      }
      if (corr_pattern && corr_pattern[0]) {
        snprintf(buf, sizeof(buf), corr_pattern, test_num);
        corr_file = strdup(buf);
      }
      if (info_pattern && info_pattern[0]) {
        snprintf(buf, sizeof(buf), info_pattern, test_num);
        info_file = strdup(buf);
      }
      if (tgzdir_pattern && tgzdir_pattern[0]) {
        snprintf(buf, sizeof(buf), tgzdir_pattern, test_num);
        tgzdir_file = strdup(buf);
      }
    }
  }

  if (info_file && (i = testinfo_parse(info_file, &tinfo, NULL)) < 0) {
    fatal("testinfo file parse error: %s", testinfo_strerror(-i));
  }

  if (test_file) {
    if (!input_file || !input_file[0]) input_file = DEFAULT_INPUT_FILE_NAME;
    if (working_dir && working_dir[0]) {
      snprintf(input_path, sizeof(input_path), "%s/%s", working_dir, input_file);
    } else {
      snprintf(input_path, sizeof(input_path), "%s", input_file);
    }
  }

  if (corr_file) {
    if (!output_file || !output_file[0]) output_file = DEFAULT_OUTPUT_FILE_NAME;
    if (working_dir && working_dir[0]) {
      snprintf(output_path, sizeof(output_path), "%s/%s", working_dir, output_file);
    } else {
      snprintf(output_path, sizeof(output_path), "%s", output_file);
    }
  }

  if (info_file && tinfo.check_stderr > 0) {
    error_file = DEFAULT_ERROR_FILE_NAME;
    if (working_dir && working_dir[0]) {
      snprintf(error_path, sizeof(error_path), "%s/%s", working_dir, error_file);
    } else {
      snprintf(error_path, sizeof(error_path), "%s", error_file);
    }
  }

  if (!(tsk = task_New())) fatal("cannot create task");
  task_SetQuietFlag(tsk);
  task_pnAddArgs(tsk, argc, argv);
  task_pnAddArgs(tsk, tinfo.cmd_argc, tinfo.cmd_argv);
  task_SetPathAsArg0(tsk);
  if (working_dir) task_SetWorkingDir(tsk, working_dir);
  if (test_file) {
    if (copy_file(NULL, test_file, working_dir, input_file, -1, -1) < 0)
      fatal("copy failed");
    if (use_stdin) task_SetRedir(tsk, 0, TSR_FILE, input_path, TSK_READ);
  } else {
    if (stdin_file) task_SetRedir(tsk, 0, TSR_FILE, stdin_file, TSK_READ);
  }
  if (corr_file) {
    if (use_stdout) task_SetRedir(tsk, 1, TSR_FILE, output_path, TSK_REWRITE, TSK_FULL_RW);
  } else {
    if (stdout_file)
      task_SetRedir(tsk, 1, TSR_FILE, stdout_file, TSK_REWRITE, TSK_FULL_RW);
  }
  if (info_file && tinfo.check_stderr > 0) {
    task_SetRedir(tsk, 2, TSR_FILE, error_path, TSK_REWRITE, TSK_FULL_RW);
  } else {
    if (stderr_file)
      task_SetRedir(tsk, 2, TSR_FILE, stderr_file, TSK_REWRITE, TSK_FULL_RW);
  }
  if (clear_env_flag) task_ClearEnv(tsk);
  for (i = 0; i < env_vars.u; i++)
    task_PutEnv(tsk, env_vars.v[i]);
  for (i = 0; i < tinfo.env_u; ++i) {
    task_PutEnv(tsk, tinfo.env_v[i]);
  }
  if (time_limit_millis > 0)
    if (task_SetMaxTimeMillis(tsk, time_limit_millis) < 0)
      fatal("--time-limit-millis is not supported");
  if (time_limit > 0) task_SetMaxTime(tsk, time_limit);
  if (real_time_limit > 0) task_SetMaxRealTime(tsk, real_time_limit);
  if (kill_signal)
    if (task_SetKillSignal(tsk, kill_signal) < 0)
      fatal("invalid value for --kill-signal option");
  if (no_core_dump) task_DisableCoreDump(tsk);
  if (max_vm_size) task_SetVMSize(tsk, max_vm_size);
  if (max_stack_size) task_SetStackSize(tsk, max_stack_size);
  if (max_data_size) task_SetDataSize(tsk, max_data_size);
  if (memory_limit)
    if (task_EnableMemoryLimitError(tsk) < 0)
      fatal("--memory-limit is not supported");
  if (secure_exec)
    if (task_EnableSecureExec(tsk) < 0)
      fatal("--secure-exec is not supported");
  if (security_violation)
    if (task_EnableSecurityViolationError(tsk) < 0)
      fatal("--security-violation is not supported");

  task_PrintArgs(tsk);

  if (task_Start(tsk) < 0) {
    fprintf(stderr, "Status: CF\n"
            "Description: cannot start task: %s\n", task_GetErrorMessage(tsk));
    retcode = RUN_CHECK_FAILED;
    goto cleanup;
  }
  task_NewWait(tsk);
  if (memory_limit && task_IsMemoryLimit(tsk)) {
    if (all_tests <= 0) {
      fprintf(stderr, "Status: ML\n"
              "Description: memory limit exceeded\n");
    }
    retcode = RUN_MEM_LIMIT_ERR;
  } else if (security_violation && task_IsSecurityViolation(tsk)) {
    if (all_tests <= 0) {
      fprintf(stderr, "Status: SV\n"
              "Description: security violation\n");
    }
    retcode = RUN_SECURITY_ERR;
  } else if (task_IsTimeout(tsk)) {
    if (all_tests <= 0) {
      fprintf(stderr, "Status: TL\n"
              "Description: time limit exceeded\n");
    }
    retcode = RUN_TIME_LIMIT_ERR;
  } else if (task_IsAbnormal(tsk)
             && (!info_file || tinfo.exit_code <= 0 || task_Status(tsk) != TSK_EXITED
                 || task_ExitCode(tsk) != tinfo.exit_code)) {
    if (all_tests <= 0) {
      fprintf(stderr, "Status: RT\n");
      if (task_Status(tsk) == TSK_SIGNALED) {
        fprintf(stderr, "Signal: %d\n", task_TermSignal(tsk));
      } else {
        fprintf(stderr, "Exitcode: %d\n", task_ExitCode(tsk));
      }
      fprintf(stderr, "Description: run-time error\n");
    }
    retcode = RUN_RUN_TIME_ERR;
  } else {
    if (info_file && tinfo.check_stderr > 0) {
      if (copy_file(working_dir, error_file, NULL, corr_file, group, mode) < 0) {
        fprintf(stderr, "Status: PE\n");
      } else {
        if (quiet_flag <= 0 && all_tests <= 0) fprintf(stderr, "Status: OK\n");
        retcode = 0;
      }
    } else if (corr_file && update_corr > 0) {
      if (copy_file(working_dir, output_file, NULL, corr_file, group, mode) < 0) {
        fprintf(stderr, "Status: PE\n");
      } else {
        if (quiet_flag <= 0 && all_tests <= 0) fprintf(stderr, "Status: OK\n");
        retcode = 0;
      }
    } else {
      if (quiet_flag <= 0 && all_tests <= 0) fprintf(stderr, "Status: OK\n");
      retcode = 0;
    }
  }
  if (quiet_flag <= 0 && all_tests <= 0) {
    fprintf(stderr, "CPUTime: %ld\n", task_GetRunningTime(tsk));
    fprintf(stderr, "RealTime: %ld\n", task_GetRealTime(tsk));
    used_vm_size = task_GetMemoryUsed(tsk);
    if (used_vm_size > 0) {
      fprintf(stderr, "VMSize: %ld\n", used_vm_size);
    }
  }
  if (p_cpu_time) *p_cpu_time = task_GetRunningTime(tsk);
  if (p_real_time) *p_real_time = task_GetRealTime(tsk);

cleanup:
  task_Delete(tsk); tsk = NULL;
  if (input_path[0]) unlink(input_path);
  if (output_path[0]) unlink(output_path);
  if (error_path[0]) unlink(error_path);

  return retcode;
}