#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include <mysql/mysql.h>
#include <assert.h>
#include "okcalls.h"
#define STD_MB 1048576
#define STD_T_LIM 2
#define STD_F_LIM (STD_MB<<5)
#define STD_M_LIM (STD_MB<<7)
#define BUFFER_SIZE 512
#define OJ_WT0 0
#define OJ_WT1 1
#define OJ_CI 2
#define OJ_RI 3
#define OJ_AC 4
#define OJ_PE 5
#define OJ_WA 6
#define OJ_TL 7
#define OJ_ML 8
#define OJ_OL 9
#define OJ_RE 10
#define OJ_CE 11
#define OJ_CO 12
#define OJ_TR 13
#ifdef __i386
#define REG_SYSCALL orig_eax
#define REG_RET eax
#define REG_ARG0 ebx
#define REG_ARG1 ecx
#else
#define REG_SYSCALL orig_rax
#define REG_RET rax
#define REG_ARG0 rdi
#define REG_ARG1 rsi
#endif
static int DEBUG = 0;
static char host_name[BUFFER_SIZE];
static char user_name[BUFFER_SIZE];
static char password[BUFFER_SIZE];
static char db_name[BUFFER_SIZE];
static char oj_home[BUFFER_SIZE];
static int port_number;
static int max_running;
static int sleep_time;
static int java_time_bonus = 5;
static int java_memory_bonus = 512;
static char java_xms[BUFFER_SIZE];
static char java_xmx[BUFFER_SIZE];
static int sim_enable = 0;
static int oi_mode = 0;
static int use_max_time = 0;
static int http_judge = 0;
static char http_baseurl[BUFFER_SIZE];
static char http_username[BUFFER_SIZE];
static char http_password[BUFFER_SIZE];
static int shm_run = 0;
static char record_call = 0;
#define ZOJ_COM
MYSQL *conn;
static char lang_ext[13][8] = { "c", "cc", "pas", "java", "rb", "sh", "py",
"php", "pl", "cs", "m", "bas", "scm" };
long get_file_size(const char * filename) {
struct stat f_stat;
if (stat(filename, &f_stat) == -1) {
return 0;
}
return (long) f_stat.st_size;
}
void write_log(const char *fmt, ...) {
va_list ap;
char buffer[4096];
sprintf(buffer, "%s/log/client.log", oj_home);
FILE *fp = fopen(buffer, "a+");
if (fp == NULL) {
fprintf(stderr, "openfile error!\n");
system("pwd");
}
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
fprintf(fp, "%s\n", buffer);
if (DEBUG)
printf("%s\n", buffer);
va_end(ap);
fclose(fp);
}
int execute_cmd(const char * fmt, ...) {
char cmd[BUFFER_SIZE];
int ret = 0;
va_list ap;
va_start(ap, fmt);
vsprintf(cmd, fmt, ap);
ret = system(cmd);
va_end(ap);
return ret;
}
const int call_array_size = 512;
int call_counter[call_array_size] = { 0 };
static char LANG_NAME[BUFFER_SIZE];
void init_syscalls_limits(int lang) {
int i;
memset(call_counter, 0, sizeof(call_counter));
if (DEBUG)
write_log("init_call_counter:%d", lang);
if (record_call) {
for (i = 0; i < call_array_size; i++) {
call_counter[i] = 0;
}
} else if (lang <= 1) {
for (i = 0; i==0||LANG_CV[i]; i++) {
call_counter[LANG_CV[i]] = HOJ_MAX_LIMIT;
}
} else if (lang == 2) {
for (i = 0; i==0||LANG_PV[i]; i++)
call_counter[LANG_PV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 3) {
for (i = 0; i==0||LANG_JV[i]; i++)
call_counter[LANG_JV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 4) {
for (i = 0; i==0||LANG_RV[i]; i++)
call_counter[LANG_RV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 5) {
for (i = 0; i==0||LANG_BV[i]; i++)
call_counter[LANG_BV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 6) {
for (i = 0; i==0||LANG_YV[i]; i++)
call_counter[LANG_YV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 7) {
for (i = 0; i==0||LANG_PHV[i]; i++)
call_counter[LANG_PHV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 8) {
for (i = 0; i==0||LANG_PLV[i]; i++)
call_counter[LANG_PLV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 9) {
for (i = 0; i==0||LANG_CSV[i]; i++)
call_counter[LANG_CSV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 10) {
for (i = 0; i==0||LANG_OV[i]; i++)
call_counter[LANG_OV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 11) {
for (i = 0; i==0||LANG_BASICV[i]; i++)
call_counter[LANG_BASICV[i]] = HOJ_MAX_LIMIT;
} else if (lang == 12) {
for (i = 0; i==0||LANG_SV[i]; i++)
call_counter[LANG_SV[i]] = HOJ_MAX_LIMIT;
}
}
int after_equal(char * c) {
int i = 0;
for (; c[i] != '\0' && c[i] != '='; i++)
;
return ++i;
}
void trim(char * c) {
char buf[BUFFER_SIZE];
char * start, *end;
strcpy(buf, c);
start = buf;
while (isspace(*start))
start++;
end = start;
while (!isspace(*end))
end++;
*end = '\0';
strcpy(c, start);
}
bool read_buf(char * buf, const char * key, char * value) {
if (strncmp(buf, key, strlen(key)) == 0) {
strcpy(value, buf + after_equal(buf));
trim(value);
if (DEBUG)
printf("%s\n", value);
return 1;
}
return 0;
}
void read_int(char * buf, const char * key, int * value) {
char buf2[BUFFER_SIZE];
if (read_buf(buf, key, buf2))
sscanf(buf2, "%d", value);
}
void init_mysql_conf() {
FILE *fp = NULL;
char buf[BUFFER_SIZE];
host_name[0] = 0;
user_name[0] = 0;
password[0] = 0;
db_name[0] = 0;
port_number = 3306;
max_running = 3;
sleep_time = 3;
strcpy(java_xms, "-Xms32m");
strcpy(java_xmx, "-Xmx256m");
sprintf(buf, "%s/etc/judge.conf", oj_home);
fp = fopen("./etc/judge.conf", "r");
if (fp != NULL) {
while (fgets(buf, BUFFER_SIZE - 1, fp)) {
read_buf(buf, "OJ_HOST_NAME", host_name);
read_buf(buf, "OJ_USER_NAME", user_name);
read_buf(buf, "OJ_PASSWORD", password);
read_buf(buf, "OJ_DB_NAME", db_name);
read_int(buf, "OJ_PORT_NUMBER", &port_number);
read_int(buf, "OJ_JAVA_TIME_BONUS", &java_time_bonus);
read_int(buf, "OJ_JAVA_MEMORY_BONUS", &java_memory_bonus);
read_int(buf, "OJ_SIM_ENABLE", &sim_enable);
read_buf(buf, "OJ_JAVA_XMS", java_xms);
read_buf(buf, "OJ_JAVA_XMX", java_xmx);
read_int(buf, "OJ_HTTP_JUDGE", &http_judge);
read_buf(buf, "OJ_HTTP_BASEURL", http_baseurl);
read_buf(buf, "OJ_HTTP_USERNAME", http_username);
read_buf(buf, "OJ_HTTP_PASSWORD", http_password);
read_int(buf, "OJ_OI_MODE", &oi_mode);
read_int(buf, "OJ_SHM_RUN", &shm_run);
read_int(buf, "OJ_USE_MAX_TIME", &use_max_time);
}
}
}
int isInFile(const char fname[]) {
int l = strlen(fname);
if (l <= 3 || strcmp(fname + l - 3, ".in") != 0)
return 0;
else
return l - 3;
}
void find_next_nonspace(int & c1, int & c2, FILE *& f1, FILE *& f2, int & ret) {
while ((isspace(c1)) || (isspace(c2))) {
if (c1 != c2) {
if (c2 == EOF) {
do {
c1 = fgetc(f1);
} while (isspace(c1));
continue;
} else if (c1 == EOF) {
do {
c2 = fgetc(f2);
} while (isspace(c2));
continue;
} else if ((c1 == '\r' && c2 == '\n')) {
c1 = fgetc(f1);
} else if ((c2 == '\r' && c1 == '\n')) {
c2 = fgetc(f2);
} else {
if (DEBUG)
printf("%d=%c\t%d=%c", c1, c1, c2, c2);
;
ret = OJ_PE;
}
}
if (isspace(c1)) {
c1 = fgetc(f1);
}
if (isspace(c2)) {
c2 = fgetc(f2);
}
}
}
const char * getFileNameFromPath(const char * path) {
for (int i = strlen(path); i >= 0; i--) {
if (path[i] == '/')
return &path[i];
}
return path;
}
void make_diff_out(FILE *f1, FILE *f2, int c1, int c2, const char * path) {
FILE *out;
char buf[45];
out = fopen("diff.out", "a+");
fprintf(out, "=================%s\n", getFileNameFromPath(path));
fprintf(out, "Right:\n%c", c1);
if (fgets(buf, 44, f1)) {
fprintf(out, "%s", buf);
}
fprintf(out, "\n-----------------\n");
fprintf(out, "Your:\n%c", c2);
if (fgets(buf, 44, f2)) {
fprintf(out, "%s", buf);
}
fprintf(out, "\n=================\n");
fclose(out);
}
int compare_zoj(const char *file1, const char *file2) {
int ret = OJ_AC;
int c1, c2;
FILE * f1, *f2;
f1 = fopen(file1, "r");
f2 = fopen(file2, "r");
if (!f1 || !f2) {
ret = OJ_RE;
} else
for (;;) {
c1 = fgetc(f1);
c2 = fgetc(f2);
find_next_nonspace(c1, c2, f1, f2, ret);
for (;;) {
while ((!isspace(c1) && c1) || (!isspace(c2) && c2)) {
if (c1 == EOF && c2 == EOF) {
goto end;
}
if (c1 == EOF || c2 == EOF) {
break;
}
if (c1 != c2) {
ret = OJ_WA;
goto end;
}
c1 = fgetc(f1);
c2 = fgetc(f2);
}
find_next_nonspace(c1, c2, f1, f2, ret);
if (c1 == EOF && c2 == EOF) {
goto end;
}
if (c1 == EOF || c2 == EOF) {
ret = OJ_WA;
goto end;
}
if ((c1 == '\n' || !c1) && (c2 == '\n' || !c2)) {
break;
}
}
}
end: if (ret == OJ_WA)
make_diff_out(f1, f2, c1, c2, file1);
if (f1)
fclose(f1);
if (f2)
fclose(f2);
return ret;
}
void delnextline(char s[]) {
int L;
L = strlen(s);
while (L > 0 && (s[L - 1] == '\n' || s[L - 1] == '\r'))
s[--L] = 0;
}
int compare(const char *file1, const char *file2) {
#ifdef ZOJ_COM
return compare_zoj(file1, file2);
#endif
#ifndef ZOJ_COM
FILE *f1,*f2;
char *s1,*s2,*p1,*p2;
int PEflg;
s1=new char[STD_F_LIM+512];
s2=new char[STD_F_LIM+512];
if (!(f1=fopen(file1,"r")))
return OJ_AC;
for (p1=s1;EOF!=fscanf(f1,"%s",p1);)
while (*p1) p1++;
fclose(f1);
if (!(f2=fopen(file2,"r")))
return OJ_RE;
for (p2=s2;EOF!=fscanf(f2,"%s",p2);)
while (*p2) p2++;
fclose(f2);
if (strcmp(s1,s2)!=0) {
delete[] s1;
delete[] s2;
return OJ_WA;
} else {
f1=fopen(file1,"r");
f2=fopen(file2,"r");
PEflg=0;
while (PEflg==0 && fgets(s1,STD_F_LIM,f1) && fgets(s2,STD_F_LIM,f2)) {
delnextline(s1);
delnextline(s2);
if (strcmp(s1,s2)==0) continue;
else PEflg=1;
}
delete [] s1;
delete [] s2;
fclose(f1);fclose(f2);
if (PEflg) return OJ_PE;
else return OJ_AC;
}
#endif
}
FILE * read_cmd_output(const char * fmt, ...) {
char cmd[BUFFER_SIZE];
FILE * ret = NULL;
va_list ap;
va_start(ap, fmt);
vsprintf(cmd, fmt, ap);
va_end(ap);
if (DEBUG)
printf("%s\n", cmd);
ret = popen(cmd, "r");
return ret;
}
bool check_login() {
const char * cmd =
" wget --post-data=\"checklogin=1\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
int ret = 0;
FILE * fjobs = read_cmd_output(cmd, http_baseurl);
fscanf(fjobs, "%d", &ret);
pclose(fjobs);
return ret;
}
void login() {
if (!check_login()) {
const char * cmd =
"wget --post-data=\"user_id=%s&password=%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/login.php\"";
FILE * fjobs = read_cmd_output(cmd, http_username, http_password,
http_baseurl);
pclose(fjobs);
}
}
void _update_solution_mysql(int solution_id, int result, int time, int memory,
int sim, int sim_s_id, double pass_rate) {
char sql[BUFFER_SIZE];
if (oi_mode) {
sprintf(sql,
"UPDATE solution SET result=%d,time=%d,memory=%d,judgetime=NOW(),pass_rate=%f WHERE solution_id=%d LIMIT 1%c",
result, time, memory, pass_rate, solution_id, 0);
} else {
sprintf(sql,
"UPDATE solution SET result=%d,time=%d,memory=%d,judgetime=NOW() WHERE solution_id=%d LIMIT 1%c",
result, time, memory, solution_id, 0);
}
if (mysql_real_query(conn, sql, strlen(sql))) {
}
if (sim) {
sprintf(sql,
"insert into sim(s_id,sim_s_id,sim) values(%d,%d,%d) on duplicate key update sim_s_id=%d,sim=%d",
solution_id, sim_s_id, sim, sim_s_id, sim);
if (mysql_real_query(conn, sql, strlen(sql))) {
}
}
}
void _update_solution_http(int solution_id, int result, int time, int memory,
int sim, int sim_s_id, double pass_rate) {
const char * cmd =
" wget --post-data=\"update_solution=1&sid=%d&result=%d&time=%d&memory=%d&sim=%d&simid=%d&pass_rate=%f\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, solution_id, result, time, memory, sim,
sim_s_id, pass_rate, http_baseurl);
pclose(fjobs);
}
void update_solution(int solution_id, int result, int time, int memory, int sim,
int sim_s_id, double pass_rate) {
if (result == OJ_TL && memory == 0)
result = OJ_ML;
if (http_judge) {
_update_solution_http(solution_id, result, time, memory, sim, sim_s_id,
pass_rate);
} else {
_update_solution_mysql(solution_id, result, time, memory, sim, sim_s_id,
pass_rate);
}
}
void _addceinfo_mysql(int solution_id) {
char sql[(1 << 16)], *end;
char ceinfo[(1 << 16)], *cend;
FILE *fp = fopen("ce.txt", "r");
snprintf(sql, (1 << 16) - 1, "DELETE FROM compileinfo WHERE solution_id=%d",
solution_id);
mysql_real_query(conn, sql, strlen(sql));
cend = ceinfo;
while (fgets(cend, 1024, fp)) {
cend += strlen(cend);
if (cend - ceinfo > 40000)
break;
}
cend = 0;
end = sql;
strcpy(end, "INSERT INTO compileinfo VALUES(");
end += strlen(sql);
*end++ = '\'';
end += sprintf(end, "%d", solution_id);
*end++ = '\'';
*end++ = ',';
*end++ = '\'';
end += mysql_real_escape_string(conn, end, ceinfo, strlen(ceinfo));
*end++ = '\'';
*end++ = ')';
*end = 0;
if (mysql_real_query(conn, sql, end - sql))
printf("%s\n", mysql_error(conn));
fclose(fp);
}
char from_hex(char ch) {
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}
char to_hex(char code) {
static char hex[] = "0123456789abcdef";
return hex[code & 15];
}
char *url_encode(char *str) {
char *pstr = str, *buf = (char *) malloc(strlen(str) * 3 + 1), *pbuf = buf;
while (*pstr) {
if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.'
|| *pstr == '~')
*pbuf++ = *pstr;
else if (*pstr == ' ')
*pbuf++ = '+';
else
*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(
*pstr & 15);
pstr++;
}
*pbuf = '\0';
return buf;
}
void _addceinfo_http(int solution_id) {
char ceinfo[(1 << 16)], *cend;
char * ceinfo_encode;
FILE *fp = fopen("ce.txt", "r");
cend = ceinfo;
while (fgets(cend, 1024, fp)) {
cend += strlen(cend);
if (cend - ceinfo > 40000)
break;
}
fclose(fp);
ceinfo_encode = url_encode(ceinfo);
FILE * ce = fopen("ce.post", "w");
fprintf(ce, "addceinfo=1&sid=%d&ceinfo=%s", solution_id, ceinfo_encode);
fclose(ce);
free(ceinfo_encode);
const char * cmd =
" wget --post-file=\"ce.post\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, http_baseurl);
pclose(fjobs);
}
void addceinfo(int solution_id) {
if (http_judge) {
_addceinfo_http(solution_id);
} else {
_addceinfo_mysql(solution_id);
}
}
void _addreinfo_mysql(int solution_id, const char * filename) {
char sql[(1 << 16)], *end;
char reinfo[(1 << 16)], *rend;
FILE *fp = fopen(filename, "r");
snprintf(sql, (1 << 16) - 1, "DELETE FROM runtimeinfo WHERE solution_id=%d",
solution_id);
mysql_real_query(conn, sql, strlen(sql));
rend = reinfo;
while (fgets(rend, 1024, fp)) {
rend += strlen(rend);
if (rend - reinfo > 40000)
break;
}
rend = 0;
end = sql;
strcpy(end, "INSERT INTO runtimeinfo VALUES(");
end += strlen(sql);
*end++ = '\'';
end += sprintf(end, "%d", solution_id);
*end++ = '\'';
*end++ = ',';
*end++ = '\'';
end += mysql_real_escape_string(conn, end, reinfo, strlen(reinfo));
*end++ = '\'';
*end++ = ')';
*end = 0;
if (mysql_real_query(conn, sql, end - sql))
printf("%s\n", mysql_error(conn));
fclose(fp);
}
void _addreinfo_http(int solution_id, const char * filename) {
char reinfo[(1 << 16)], *rend;
char * reinfo_encode;
FILE *fp = fopen(filename, "r");
rend = reinfo;
while (fgets(rend, 1024, fp)) {
rend += strlen(rend);
if (rend - reinfo > 40000)
break;
}
fclose(fp);
reinfo_encode = url_encode(reinfo);
FILE * re = fopen("re.post", "w");
fprintf(re, "addreinfo=1&sid=%d&reinfo=%s", solution_id, reinfo_encode);
fclose(re);
free(reinfo_encode);
const char * cmd =
" wget --post-file=\"re.post\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, http_baseurl);
pclose(fjobs);
}
void addreinfo(int solution_id) {
if (http_judge) {
_addreinfo_http(solution_id, "error.out");
} else {
_addreinfo_mysql(solution_id, "error.out");
}
}
void adddiffinfo(int solution_id) {
if (http_judge) {
_addreinfo_http(solution_id, "diff.out");
} else {
_addreinfo_mysql(solution_id, "diff.out");
}
}
void addcustomout(int solution_id) {
if (http_judge) {
_addreinfo_http(solution_id, "user.out");
} else {
_addreinfo_mysql(solution_id, "user.out");
}
}
void _update_user_mysql(char * user_id) {
char sql[BUFFER_SIZE];
sprintf(sql,
"UPDATE `users` SET `solved`=(SELECT count(DISTINCT `problem_id`) FROM `solution` WHERE `user_id`=\'%s\' AND `result`=\'4\') WHERE `user_id`=\'%s\'",
user_id, user_id);
if (mysql_real_query(conn, sql, strlen(sql)))
write_log(mysql_error(conn));
sprintf(sql,
"UPDATE `users` SET `submit`=(SELECT count(*) FROM `solution` WHERE `user_id`=\'%s\') WHERE `user_id`=\'%s\'",
user_id, user_id);
if (mysql_real_query(conn, sql, strlen(sql)))
write_log(mysql_error(conn));
}
void _update_user_http(char * user_id) {
const char * cmd =
" wget --post-data=\"updateuser=1&user_id=%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, user_id, http_baseurl);
pclose(fjobs);
}
void update_user(char * user_id) {
if (http_judge) {
_update_user_http(user_id);
} else {
_update_user_mysql(user_id);
}
}
void _update_problem_http(int pid) {
const char * cmd =
" wget --post-data=\"updateproblem=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, pid, http_baseurl);
pclose(fjobs);
}
void _update_problem_mysql(int p_id) {
char sql[BUFFER_SIZE];
sprintf(sql,
"UPDATE `problem` SET `accepted`=(SELECT count(*) FROM `solution` WHERE `problem_id`=\'%d\' AND `result`=\'4\') WHERE `problem_id`=\'%d\'",
p_id, p_id);
if (mysql_real_query(conn, sql, strlen(sql)))
write_log(mysql_error(conn));
sprintf(sql,
"UPDATE `problem` SET `submit`=(SELECT count(*) FROM `solution` WHERE `problem_id`=\'%d\') WHERE `problem_id`=\'%d\'",
p_id, p_id);
if (mysql_real_query(conn, sql, strlen(sql)))
write_log(mysql_error(conn));
}
void update_problem(int pid) {
if (http_judge) {
_update_problem_http(pid);
} else {
_update_problem_mysql(pid);
}
}
int compile(int lang) {
int pid;
const char * CP_C[] = { "gcc", "Main.c", "-o", "Main", "-fno-asm", "-Wall",
"-lm", "--static", "-std=c99", "-DONLINE_JUDGE", NULL };
const char * CP_X[] = { "g++", "Main.cc", "-o", "Main", "-fno-asm", "-Wall",
"-lm", "--static", "-std=c++0x", "-DONLINE_JUDGE", NULL };
const char * CP_P[] =
{ "fpc", "Main.pas", "-O2", "-Co", "-Ct", "-Ci", NULL };
const char * CP_R[] = { "ruby", "-c", "Main.rb", NULL };
const char * CP_B[] = { "chmod", "+rx", "Main.sh", NULL };
const char * CP_Y[] = { "python", "-c",
"import py_compile; py_compile.compile(r'Main.py')", NULL };
const char * CP_PH[] = { "php", "-l", "Main.php", NULL };
const char * CP_PL[] = { "perl", "-c", "Main.pl", NULL };
const char * CP_CS[] = { "gmcs", "-warn:0", "Main.cs", NULL };
const char * CP_OC[] = { "gcc", "-o", "Main", "Main.m",
"-fconstant-string-class=NSConstantString", "-I",
"/usr/include/GNUstep/", "-L", "/usr/lib/GNUstep/Libraries/",
"-lobjc", "-lgnustep-base", NULL };
const char * CP_BS[] = { "fbc", "Main.bas", NULL };
char javac_buf[7][16];
char *CP_J[7];
for (int i = 0; i < 7; i++)
CP_J[i] = javac_buf[i];
sprintf(CP_J[0], "javac");
sprintf(CP_J[1], "-J%s", java_xms);
sprintf(CP_J[2], "-J%s", java_xmx);
sprintf(CP_J[3], "-encoding");
sprintf(CP_J[4], "UTF-8");
sprintf(CP_J[5], "Main.java");
CP_J[6] = (char *) NULL;
pid = fork();
if (pid == 0) {
struct rlimit LIM;
LIM.rlim_max = 60;
LIM.rlim_cur = 60;
setrlimit(RLIMIT_CPU, &LIM);
alarm(60);
LIM.rlim_max = 100 * STD_MB;
LIM.rlim_cur = 100 * STD_MB;
setrlimit(RLIMIT_FSIZE, &LIM);
if(lang==3){
LIM.rlim_max = STD_MB << 11;
LIM.rlim_cur = STD_MB << 11;
}else{
LIM.rlim_max = STD_MB << 10;
LIM.rlim_cur = STD_MB << 10;
}
setrlimit(RLIMIT_AS, &LIM);
if (lang != 2 && lang != 11) {
freopen("ce.txt", "w", stderr);
} else {
freopen("ce.txt", "w", stdout);
}
execute_cmd("chown judge *");
while(setgid(1536)!=0) sleep(1);
while(setuid(1536)!=0) sleep(1);
while(setresuid(1536, 1536, 1536)!=0) sleep(1);
switch (lang) {
case 0:
execvp(CP_C[0], (char * const *) CP_C);
break;
case 1:
execvp(CP_X[0], (char * const *) CP_X);
break;
case 2:
execvp(CP_P[0], (char * const *) CP_P);
break;
case 3:
execvp(CP_J[0], (char * const *) CP_J);
break;
case 4:
execvp(CP_R[0], (char * const *) CP_R);
break;
case 5:
execvp(CP_B[0], (char * const *) CP_B);
break;
case 6:
execvp(CP_Y[0], (char * const *) CP_Y);
break;
case 7:
execvp(CP_PH[0], (char * const *) CP_PH);
break;
case 8:
execvp(CP_PL[0], (char * const *) CP_PL);
break;
case 9:
execvp(CP_CS[0], (char * const *) CP_CS);
break;
case 10:
execvp(CP_OC[0], (char * const *) CP_OC);
break;
case 11:
execvp(CP_BS[0], (char * const *) CP_BS);
break;
default:
printf("nothing to do!\n");
}
if (DEBUG)
printf("compile end!\n");
exit(0);
} else {
int status = 0;
waitpid(pid, &status, 0);
if (lang > 3 && lang < 7)
status = get_file_size("ce.txt");
if (DEBUG)
printf("status=%d\n", status);
return status;
}
}
int get_proc_status(int pid, const char * mark) {
FILE * pf;
char fn[BUFFER_SIZE], buf[BUFFER_SIZE];
int ret = 0;
sprintf(fn, "/proc/%d/status", pid);
pf = fopen(fn, "r");
int m = strlen(mark);
while (pf && fgets(buf, BUFFER_SIZE - 1, pf)) {
buf[strlen(buf) - 1] = 0;
if (strncmp(buf, mark, m) == 0) {
sscanf(buf + m + 1, "%d", &ret);
}
}
if (pf)
fclose(pf);
return ret;
}
int init_mysql_conn() {
conn = mysql_init(NULL);
const char timeout = 30;
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
if (!mysql_real_connect(conn, host_name, user_name, password, db_name,
port_number, 0, 0)) {
write_log("%s", mysql_error(conn));
return 0;
}
const char * utf8sql = "set names utf8";
if (mysql_real_query(conn, utf8sql, strlen(utf8sql))) {
write_log("%s", mysql_error(conn));
return 0;
}
return 1;
}
void _get_solution_mysql(int solution_id, char * work_dir, int lang) {
char sql[BUFFER_SIZE], src_pth[BUFFER_SIZE];
MYSQL_RES *res;
MYSQL_ROW row;
sprintf(sql, "SELECT source FROM source_code WHERE solution_id=%d",
solution_id);
mysql_real_query(conn, sql, strlen(sql));
res = mysql_store_result(conn);
row = mysql_fetch_row(res);
sprintf(src_pth, "Main.%s", lang_ext[lang]);
if (DEBUG)
printf("Main=%s", src_pth);
FILE *fp_src = fopen(src_pth, "w");
fprintf(fp_src, "%s", row[0]);
mysql_free_result(res);
fclose(fp_src);
}
void _get_solution_http(int solution_id, char * work_dir, int lang) {
char src_pth[BUFFER_SIZE];
sprintf(src_pth, "Main.%s", lang_ext[lang]);
if (DEBUG)
printf("Main=%s", src_pth);
const char * cmd2 =
"wget --post-data=\"getsolution=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O %s \"%s/admin/problem_judge.php\"";
FILE * pout = read_cmd_output(cmd2, solution_id, src_pth, http_baseurl);
pclose(pout);
}
void get_solution(int solution_id, char * work_dir, int lang) {
if (http_judge) {
_get_solution_http(solution_id, work_dir, lang);
} else {
_get_solution_mysql(solution_id, work_dir, lang);
}
}
void _get_custominput_mysql(int solution_id, char * work_dir) {
char sql[BUFFER_SIZE], src_pth[BUFFER_SIZE];
MYSQL_RES *res;
MYSQL_ROW row;
sprintf(sql, "SELECT input_text FROM custominput WHERE solution_id=%d",
solution_id);
mysql_real_query(conn, sql, strlen(sql));
res = mysql_store_result(conn);
row = mysql_fetch_row(res);
if (row != NULL) {
sprintf(src_pth, "data.in");
FILE *fp_src = fopen(src_pth, "w");
fprintf(fp_src, "%s", row[0]);
fclose(fp_src);
}
mysql_free_result(res);
}
void _get_custominput_http(int solution_id, char * work_dir) {
char src_pth[BUFFER_SIZE];
sprintf(src_pth, "data.in");
const char * cmd2 =
"wget --post-data=\"getcustominput=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O %s \"%s/admin/problem_judge.php\"";
FILE * pout = read_cmd_output(cmd2, solution_id, src_pth, http_baseurl);
pclose(pout);
}
void get_custominput(int solution_id, char * work_dir) {
if (http_judge) {
_get_custominput_http(solution_id, work_dir);
} else {
_get_custominput_mysql(solution_id, work_dir);
}
}
void _get_solution_info_mysql(int solution_id, int & p_id, char * user_id,
int & lang) {
MYSQL_RES *res;
MYSQL_ROW row;
char sql[BUFFER_SIZE];
sprintf(sql,
"SELECT problem_id, user_id, language FROM solution where solution_id=%d",
solution_id);
mysql_real_query(conn, sql, strlen(sql));
res = mysql_store_result(conn);
row = mysql_fetch_row(res);
p_id = atoi(row[0]);
strcpy(user_id, row[1]);
lang = atoi(row[2]);
mysql_free_result(res);
}
void _get_solution_info_http(int solution_id, int & p_id, char * user_id,
int & lang) {
login();
const char * cmd =
"wget --post-data=\"getsolutioninfo=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * pout = read_cmd_output(cmd, solution_id, http_baseurl);
fscanf(pout, "%d", &p_id);
fscanf(pout, "%s", user_id);
fscanf(pout, "%d", &lang);
pclose(pout);
}
void get_solution_info(int solution_id, int & p_id, char * user_id,
int & lang) {
if (http_judge) {
_get_solution_info_http(solution_id, p_id, user_id, lang);
} else {
_get_solution_info_mysql(solution_id, p_id, user_id, lang);
}
}
void _get_problem_info_mysql(int p_id, int & time_lmt, int & mem_lmt,
int & isspj) {
char sql[BUFFER_SIZE];
MYSQL_RES *res;
MYSQL_ROW row;
sprintf(sql,
"SELECT time_limit,memory_limit,spj FROM problem where problem_id=%d",
p_id);
mysql_real_query(conn, sql, strlen(sql));
res = mysql_store_result(conn);
row = mysql_fetch_row(res);
time_lmt = atoi(row[0]);
mem_lmt = atoi(row[1]);
isspj = (row[2][0] == '1');
mysql_free_result(res);
}
void _get_problem_info_http(int p_id, int & time_lmt, int & mem_lmt,
int & isspj) {
const char * cmd =
"wget --post-data=\"getprobleminfo=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * pout = read_cmd_output(cmd, p_id, http_baseurl);
fscanf(pout, "%d", &time_lmt);
fscanf(pout, "%d", &mem_lmt);
fscanf(pout, "%d", &isspj);
pclose(pout);
}
void get_problem_info(int p_id, int & time_lmt, int & mem_lmt, int & isspj) {
if (http_judge) {
_get_problem_info_http(p_id, time_lmt, mem_lmt, isspj);
} else {
_get_problem_info_mysql(p_id, time_lmt, mem_lmt, isspj);
}
}
void prepare_files(char * filename, int namelen, char * infile, int & p_id,
char * work_dir, char * outfile, char * userfile, int runner_id) {
char fname[BUFFER_SIZE];
strncpy(fname, filename, namelen);
fname[namelen] = 0;
sprintf(infile, "%s/data/%d/%s.in", oj_home, p_id, fname);
execute_cmd("/bin/cp %s %s/data.in", infile, work_dir);
execute_cmd("/bin/cp %s/data/%d/*.dic %s/", oj_home, p_id, work_dir);
sprintf(outfile, "%s/data/%d/%s.out", oj_home, p_id, fname);
sprintf(userfile, "%s/run%d/user.out", oj_home, runner_id);
}
void copy_shell_runtime(char * work_dir) {
execute_cmd("/bin/mkdir %s/lib", work_dir);
execute_cmd("/bin/mkdir %s/lib64", work_dir);
execute_cmd("/bin/mkdir %s/bin", work_dir);
execute_cmd("/bin/cp /lib/* %s/lib/", work_dir);
execute_cmd("/bin/cp -a /lib/i386-linux-gnu %s/lib/", work_dir);
execute_cmd("/bin/cp -a /lib/x86_64-linux-gnu %s/lib/", work_dir);
execute_cmd("/bin/cp /lib64/* %s/lib64/", work_dir);
execute_cmd("/bin/cp -a /lib32 %s/", work_dir);
execute_cmd("/bin/cp /bin/busybox %s/bin/", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/sh", work_dir);
execute_cmd("/bin/cp /bin/bash %s/bin/bash", work_dir);
}
void copy_objc_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir -p %s/proc", work_dir);
execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
execute_cmd("/bin/mkdir -p %s/lib/", work_dir);
execute_cmd(
"/bin/cp -aL /lib/libdbus-1.so.3 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/libgcc_s.so.1 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/libgcrypt.so.11 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/libgpg-error.so.0 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/libz.so.1 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/libc.so.6 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/libdl.so.2 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/libm.so.6 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/libnsl.so.1 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/libpthread.so.0 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /lib/tls/i686/cmov/librt.so.1 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libavahi-client.so.3 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libavahi-common.so.3 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libdns_sd.so.1 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libffi.so.5 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libgnustep-base.so.1.19 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libgnutls.so.26 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libobjc.so.2 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libtasn1.so.3 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libxml2.so.2 %s/lib/ ",
work_dir);
execute_cmd(
"/bin/cp -aL /usr/lib/libxslt.so.1 %s/lib/ ",
work_dir);
}
void copy_bash_runtime(char * work_dir) {
//const char * ruby_run="/usr/bin/ruby";
copy_shell_runtime(work_dir);
execute_cmd("/bin/cp `which bc` %s/bin/", work_dir);
execute_cmd("busybox dos2unix Main.sh", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/grep", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/awk", work_dir);
execute_cmd("/bin/cp /bin/sed %s/bin/sed", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/cut", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/sort", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/join", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/wc", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/tr", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/dc", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/dd", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/cat", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/tail", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/head", work_dir);
execute_cmd("/bin/ln -s /bin/busybox %s/bin/xargs", work_dir);
execute_cmd("chmod +rx %s/Main.sh", work_dir);
}
void copy_ruby_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir %s/usr", work_dir);
execute_cmd("/bin/mkdir %s/usr/lib", work_dir);
execute_cmd("/bin/cp /usr/lib/libruby* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp -a /usr/lib/ruby %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/bin/ruby* %s/", work_dir);
}
void copy_guile_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir -p %s/proc", work_dir);
execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/lib", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/share", work_dir);
execute_cmd("/bin/cp -a /usr/share/guile %s/usr/share/", work_dir);
execute_cmd("/bin/cp /usr/lib/libguile* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libgc* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libffi* %s/usr/lib/",
work_dir);
execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libunistring* %s/usr/lib/",
work_dir);
execute_cmd("/bin/cp /usr/lib/*/libgmp* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libgmp* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libltdl* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libltdl* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/bin/guile* %s/", work_dir);
}
void copy_python_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir -p %s/usr/include", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/lib", work_dir);
execute_cmd("/bin/cp /usr/bin/python* %s/", work_dir);
execute_cmd("/bin/cp -a /usr/lib/python* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp -a /usr/include/python* %s/usr/include/", work_dir);
execute_cmd("/bin/cp -a /usr/lib/libpython* %s/usr/lib/", work_dir);
}
void copy_php_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir %s/usr", work_dir);
execute_cmd("/bin/mkdir %s/usr/lib", work_dir);
execute_cmd("/bin/cp /usr/lib/libedit* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libdb* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libgssapi_krb5* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libkrb5* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libk5crypto* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libedit* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libdb* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libgssapi_krb5* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libkrb5* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/*/libk5crypto* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/libxml2* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libxml2.so* %s/usr/lib/",
work_dir);
execute_cmd("/bin/cp /usr/bin/php* %s/", work_dir);
execute_cmd("chmod +rx %s/Main.php", work_dir);
}
void copy_perl_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir %s/usr", work_dir);
execute_cmd("/bin/mkdir %s/usr/lib", work_dir);
execute_cmd("/bin/cp /usr/lib/libperl* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /usr/bin/perl* %s/", work_dir);
}
void copy_freebasic_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir -p %s/usr/local/lib", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/local/bin", work_dir);
execute_cmd("/bin/cp /usr/local/lib/freebasic %s/usr/local/lib/", work_dir);
execute_cmd("/bin/cp /usr/local/bin/fbc %s/", work_dir);
execute_cmd("/bin/cp -a /lib32/* %s/lib/", work_dir);
}
void copy_mono_runtime(char * work_dir) {
copy_shell_runtime(work_dir);
execute_cmd("/bin/mkdir %s/usr", work_dir);
execute_cmd("/bin/mkdir %s/proc", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/lib/mono/2.0", work_dir);
execute_cmd("/bin/cp -a /usr/lib/mono %s/usr/lib/", work_dir);
execute_cmd("/bin/mkdir -p %s/usr/lib64/mono/2.0", work_dir);
execute_cmd("/bin/cp -a /usr/lib64/mono %s/usr/lib64/", work_dir);
execute_cmd("/bin/cp /usr/lib/libgthread* %s/usr/lib/", work_dir);
execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
execute_cmd("/bin/cp /usr/bin/mono* %s/", work_dir);
execute_cmd("/bin/cp /usr/lib/libgthread* %s/usr/lib/", work_dir);
execute_cmd("/bin/cp /lib/libglib* %s/lib/", work_dir);
execute_cmd("/bin/cp /lib/tls/i686/cmov/lib* %s/lib/tls/i686/cmov/",
work_dir);
execute_cmd("/bin/cp /lib/libpcre* %s/lib/", work_dir);
execute_cmd("/bin/cp /lib/ld-linux* %s/lib/", work_dir);
execute_cmd("/bin/cp /lib64/ld-linux* %s/lib64/", work_dir);
execute_cmd("/bin/mkdir -p %s/home/judge", work_dir);
execute_cmd("/bin/chown judge %s/home/judge", work_dir);
execute_cmd("/bin/mkdir -p %s/etc", work_dir);
execute_cmd("/bin/grep judge /etc/passwd>%s/etc/passwd", work_dir);
}
void run_solution(int & lang, char * work_dir, int & time_lmt, int & usedtime,
int & mem_lmt) {
nice(19);
chdir(work_dir);
freopen("data.in", "r", stdin);
freopen("user.out", "w", stdout);
freopen("error.out", "a+", stderr);
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
if (lang != 3)
chroot(work_dir);
while (setgid(1536) != 0)
sleep(1);
while (setuid(1536) != 0)
sleep(1);
while (setresuid(1536, 1536, 1536) != 0)
sleep(1);
struct rlimit LIM;
if (oi_mode)
LIM.rlim_cur = time_lmt + 1;
else
LIM.rlim_cur = (time_lmt - usedtime / 1000) + 1;
LIM.rlim_max = LIM.rlim_cur;
setrlimit(RLIMIT_CPU, &LIM);
alarm(0);
alarm(time_lmt * 10);
LIM.rlim_max = STD_F_LIM + STD_MB;
LIM.rlim_cur = STD_F_LIM;
setrlimit(RLIMIT_FSIZE, &LIM);
switch (lang) {
case 3:
case 12:
LIM.rlim_cur = LIM.rlim_max = 50;
break;
case 5:
LIM.rlim_cur = LIM.rlim_max = 3;
break;
case 9:
LIM.rlim_cur = LIM.rlim_max = 50;
break;
default:
LIM.rlim_cur = LIM.rlim_max = 1;
}
setrlimit(RLIMIT_NPROC, &LIM);
LIM.rlim_cur = STD_MB << 6;
LIM.rlim_max = STD_MB << 6;
setrlimit(RLIMIT_STACK, &LIM);
LIM.rlim_cur = STD_MB * mem_lmt / 2 * 3;
LIM.rlim_max = STD_MB * mem_lmt * 2;
if (lang < 3)
setrlimit(RLIMIT_AS, &LIM);
switch (lang) {
case 0:
case 1:
case 2:
case 10:
case 11:
execl("./Main", "./Main", (char *) NULL);
break;
case 3:
execl("/usr/bin/java", "/usr/bin/java", java_xms, java_xmx,
"-Djava.security.manager",
"-Djava.security.policy=./java.policy", "Main", (char *) NULL);
break;
case 4:
execl("/ruby", "/ruby", "Main.rb", (char *) NULL);
break;
case 5:
execl("/bin/bash", "/bin/bash", "Main.sh", (char *) NULL);
break;
case 6:
execl("/python", "/python", "Main.py", (char *) NULL);
break;
case 7:
execl("/php", "/php", "Main.php", (char *) NULL);
break;
case 8:
execl("/perl", "/perl", "Main.pl", (char *) NULL);
break;
case 9:
execl("/mono", "/mono", "--debug", "Main.exe", (char *) NULL);
break;
case 12:
execl("/guile", "/guile", "Main.scm", (char *) NULL);
break;
}
exit(0);
}
int fix_java_mis_judge(char *work_dir, int & ACflg, int & topmemory,
int mem_lmt) {
int comp_res = OJ_AC;
if (DEBUG)
execute_cmd("cat %s/error.out", work_dir);
comp_res = execute_cmd("/bin/grep 'Exception' %s/error.out", work_dir);
if (!comp_res) {
printf("Exception reported\n");
ACflg = OJ_RE;
}
comp_res = execute_cmd(
"/bin/grep 'java.lang.OutOfMemoryError' %s/error.out", work_dir);
if (!comp_res) {
printf("JVM need more Memory!");
ACflg = OJ_ML;
topmemory = mem_lmt * STD_MB;
}
comp_res = execute_cmd(
"/bin/grep 'java.lang.OutOfMemoryError' %s/user.out", work_dir);
if (!comp_res) {
printf("JVM need more Memory or Threads!");
ACflg = OJ_ML;
topmemory = mem_lmt * STD_MB;
}
comp_res = execute_cmd("/bin/grep 'Could not create' %s/error.out",
work_dir);
if (!comp_res) {
printf("jvm need more resource,tweak -Xmx(OJ_JAVA_BONUS) Settings");
ACflg = OJ_RE;
}
return comp_res;
}
int special_judge(char* oj_home, int problem_id, char *infile, char *outfile,
char *userfile) {
pid_t pid;
printf("pid=%d\n", problem_id);
pid = fork();
int ret = 0;
if (pid == 0) {
while (setgid(1536) != 0)
sleep(1);
while (setuid(1536) != 0)
sleep(1);
while (setresuid(1536, 1536, 1536) != 0)
sleep(1);
struct rlimit LIM;
LIM.rlim_cur = 5;
LIM.rlim_max = LIM.rlim_cur;
setrlimit(RLIMIT_CPU, &LIM);
alarm(0);
alarm(10);
LIM.rlim_max = STD_F_LIM + STD_MB;
LIM.rlim_cur = STD_F_LIM;
setrlimit(RLIMIT_FSIZE, &LIM);
ret = execute_cmd("%s/data/%d/spj %s %s %s", oj_home, problem_id,
infile, outfile, userfile);
if (DEBUG)
printf("spj1=%d\n", ret);
if (ret)
exit(1);
else
exit(0);
} else {
int status;
waitpid(pid, &status, 0);
ret = WEXITSTATUS(status);
if (DEBUG)
printf("spj2=%d\n", ret);
}
return ret;
}
void judge_solution(int & ACflg, int & usedtime, int time_lmt, int isspj,
int p_id, char * infile, char * outfile, char * userfile, int & PEflg,
int lang, char * work_dir, int & topmemory, int mem_lmt,
int solution_id, double num_of_test) {
int comp_res;
if (!oi_mode)
num_of_test = 1.0;
if (ACflg == OJ_AC
&& usedtime > time_lmt * 1000 * (use_max_time ? 1 : num_of_test))
ACflg = OJ_TL;
if (topmemory > mem_lmt * STD_MB)
ACflg = OJ_ML;
if (ACflg == OJ_AC) {
if (isspj) {
comp_res = special_judge(oj_home, p_id, infile, outfile, userfile);
if (comp_res == 0)
comp_res = OJ_AC;
else {
if (DEBUG)
printf("fail test %s\n", infile);
comp_res = OJ_WA;
}
} else {
comp_res = compare(outfile, userfile);
}
if (comp_res == OJ_WA) {
ACflg = OJ_WA;
if (DEBUG)
printf("fail test %s\n", infile);
} else if (comp_res == OJ_PE)
PEflg = OJ_PE;
ACflg = comp_res;
}
if (lang == 3) {
comp_res = fix_java_mis_judge(work_dir, ACflg, topmemory, mem_lmt);
}
}
int get_page_fault_mem(struct rusage & ruse, pid_t & pidApp) {
int m_vmpeak, m_vmdata, m_minflt;
m_minflt = ruse.ru_minflt * getpagesize();
if (0 && DEBUG) {
m_vmpeak = get_proc_status(pidApp, "VmPeak:");
m_vmdata = get_proc_status(pidApp, "VmData:");
printf("VmPeak:%d KB VmData:%d KB minflt:%d KB\n", m_vmpeak, m_vmdata,
m_minflt >> 10);
}
return m_minflt;
}
void print_runtimeerror(char * err) {
FILE *ferr = fopen("error.out", "a+");
fprintf(ferr, "Runtime Error:%s\n", err);
fclose(ferr);
}
void clean_session(pid_t p) {
const char *pre = "ps awx -o \"\%p \%P\"|grep -w ";
const char *post = " | awk \'{ print $1 }\'|xargs kill -9";
execute_cmd("%s %d %s", pre, p, post);
execute_cmd("ps aux |grep \\^judge|awk '{print $2}'|xargs kill");
}
void watch_solution(pid_t pidApp, char * infile, int & ACflg, int isspj,
char * userfile, char * outfile, int solution_id, int lang,
int & topmemory, int mem_lmt, int & usedtime, int time_lmt, int & p_id,
int & PEflg, char * work_dir) {
int tempmemory;
if (DEBUG)
printf("pid=%d judging %s\n", pidApp, infile);
int status, sig, exitcode;
struct user_regs_struct reg;
struct rusage ruse;
while (1) {
wait4(pidApp, &status, 0, &ruse);
if (lang == 3) {
tempmemory = get_page_fault_mem(ruse, pidApp);
} else {
tempmemory = get_proc_status(pidApp, "VmPeak:") << 10;
}
if (tempmemory > topmemory)
topmemory = tempmemory;
if (topmemory > mem_lmt * STD_MB) {
if (DEBUG)
printf("out of memory %d\n", topmemory);
if (ACflg == OJ_AC)
ACflg = OJ_ML;
ptrace(PTRACE_KILL, pidApp, NULL, NULL);
break;
}
if (WIFEXITED(status))
break;
if ((lang < 4 || lang == 9) && get_file_size("error.out") && !oi_mode) {
ACflg = OJ_RE;
ptrace(PTRACE_KILL, pidApp, NULL, NULL);
break;
}
if (!isspj
&& get_file_size(userfile)
> get_file_size(outfile) * 2 + 1024) {
ACflg = OJ_OL;
ptrace(PTRACE_KILL, pidApp, NULL, NULL);
break;
}
exitcode = WEXITSTATUS(status);
if ((lang >= 3 && exitcode == 17) || exitcode == 0x05 || exitcode == 0)
;
else {
if (DEBUG) {
printf("status>>8=%d\n", exitcode);
}
if (ACflg == OJ_AC) {
switch (exitcode) {
case SIGCHLD:
case SIGALRM:
alarm(0);
case SIGKILL:
case SIGXCPU:
ACflg = OJ_TL;
break;
case SIGXFSZ:
ACflg = OJ_OL;
break;
default:
ACflg = OJ_RE;
}
print_runtimeerror(strsignal(exitcode));
}
ptrace(PTRACE_KILL, pidApp, NULL, NULL);
break;
}
if (WIFSIGNALED(status)) {
sig = WTERMSIG(status);
if (DEBUG) {
printf("WTERMSIG=%d\n", sig);
psignal(sig, NULL);
}
if (ACflg == OJ_AC) {
switch (sig) {
case SIGCHLD:
case SIGALRM:
alarm(0);
case SIGKILL:
case SIGXCPU:
ACflg = OJ_TL;
break;
case SIGXFSZ:
ACflg = OJ_OL;
break;
default:
ACflg = OJ_RE;
}
print_runtimeerror(strsignal(sig));
}
break;
}
ptrace(PTRACE_GETREGS, pidApp, NULL, ®);
if (call_counter[reg.REG_SYSCALL] ){
}else if (record_call) {
call_counter[reg.REG_SYSCALL] = 1;
}else {
ACflg = OJ_RE;
char error[BUFFER_SIZE];
sprintf(error,
"[ERROR] A Not allowed system call: runid:%d callid:%ld\n TO FIX THIS , ask admin to add the CALLID into corresponding LANG_XXV[] located at okcalls32/64.h ,and recompile judge_client",
solution_id, (long)reg.REG_SYSCALL);
write_log(error);
print_runtimeerror(error);
ptrace(PTRACE_KILL, pidApp, NULL, NULL);
}
ptrace(PTRACE_SYSCALL, pidApp, NULL, NULL);
}
usedtime += (ruse.ru_utime.tv_sec * 1000 + ruse.ru_utime.tv_usec / 1000);
usedtime += (ruse.ru_stime.tv_sec * 1000 + ruse.ru_stime.tv_usec / 1000);
}
void clean_workdir(char * work_dir) {
execute_cmd("/bin/umount %s/proc", work_dir);
if (DEBUG) {
execute_cmd("/bin/mv %s/* %slog/", work_dir, work_dir);
} else {
execute_cmd("/bin/rm -Rf %s/*", work_dir);
}
}
//runidstr : solution_id 的字符串 参数1
//buf : clientid 也就是进程id字符串
//oj_home : /home/judge
//execl("/usr/bin/judge_client", "/usr/bin/judge_client", runidstr, buf,
// oj_home, (char *) NULL);
//argv[0] 指向程序运行的全路径名
//argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
//argv[2] 指向执行程序名后的第二个字符串
void init_parameters(int argc, char ** argv, int & solution_id,
int & runner_id) {
if (argc < 3) {//如果参数小于3个,则报错退出
fprintf(stderr, "Usage:%s solution_id runner_id.\n", argv[0]);
fprintf(stderr, "Multi:%s solution_id runner_id judge_base_path.\n",
argv[0]);
fprintf(stderr,
"Debug:%s solution_id runner_id judge_base_path debug.\n",
argv[0]);
exit(1);
}
//参数大于4个则启用调试???? ,默认4个所以0
DEBUG = (argc > 4);
record_call = (argc > 5);//这个不懂???
if (argc > 5) {//第6个参数,评测语言
strcpy(LANG_NAME, argv[5]);
}
if (argc > 3) //第4个参数,评测目录
strcpy(oj_home, argv[3]);
else//否则默认目录设置为/home/judge
strcpy(oj_home, "/home/judge");
//切换当前默认目录为/home/judge
chdir(oj_home); // change the dir// init our work
solution_id = atoi(argv[1]);
runner_id = atoi(argv[2]);
}
int get_sim(int solution_id, int lang, int pid, int &sim_s_id) {
char src_pth[BUFFER_SIZE];
//char cmd[BUFFER_SIZE];
sprintf(src_pth, "Main.%s", lang_ext[lang]);
int sim = execute_cmd("/usr/bin/sim.sh %s %d", src_pth, pid);
if (!sim) {
execute_cmd("/bin/mkdir ../data/%d/ac/", pid);
execute_cmd("/bin/cp %s ../data/%d/ac/%d.%s", src_pth, pid, solution_id,
lang_ext[lang]);
//c cpp will
if (lang == 0)
execute_cmd("/bin/ln ../data/%d/ac/%d.%s ../data/%d/ac/%d.%s", pid,
solution_id, lang_ext[lang], pid, solution_id,
lang_ext[lang + 1]);
if (lang == 1)
execute_cmd("/bin/ln ../data/%d/ac/%d.%s ../data/%d/ac/%d.%s", pid,
solution_id, lang_ext[lang], pid, solution_id,
lang_ext[lang - 1]);
} else {
FILE * pf;
pf = fopen("sim", "r");
if (pf) {
fscanf(pf, "%d%d", &sim, &sim_s_id);
fclose(pf);
}
}
if (solution_id <= sim_s_id)
sim = 0;
return sim;
}
void mk_shm_workdir(char * work_dir) {
char shm_path[BUFFER_SIZE];
sprintf(shm_path, "/dev/shm/hustoj/%s", work_dir);
execute_cmd("/bin/mkdir -p %s", shm_path);
execute_cmd("/bin/rm -rf %s", work_dir);
execute_cmd("/bin/ln -s %s %s/", shm_path, oj_home);
execute_cmd("/bin/chown judge %s ", shm_path);
execute_cmd("chmod 755 %s ", shm_path);
//sim need a soft link in shm_dir to work correctly
sprintf(shm_path, "/dev/shm/hustoj/%s/", oj_home);
execute_cmd("/bin/ln -s %s/data %s", oj_home, shm_path);
}
int count_in_files(char * dirpath) {
const char * cmd = "ls -l %s/*.in|wc -l";
int ret = 0;
FILE * fjobs = read_cmd_output(cmd, dirpath);
fscanf(fjobs, "%d", &ret);
pclose(fjobs);
return ret;
}
int get_test_file(char* work_dir, int p_id) {
char filename[BUFFER_SIZE];
char localfile[BUFFER_SIZE];
int ret = 0;
const char * cmd =
" wget --post-data=\"gettestdatalist=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * fjobs = read_cmd_output(cmd, p_id, http_baseurl);
while (fgets(filename, BUFFER_SIZE - 1, fjobs) != NULL) {
sscanf(filename, "%s", filename);
sprintf(localfile, "%s/data/%d/%s", oj_home, p_id, filename);
if (DEBUG)
printf("localfile[%s]\n", localfile);
const char * check_file_cmd =
" wget --post-data=\"gettestdatadate=1&filename=%d/%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s/admin/problem_judge.php\"";
FILE * rcop = read_cmd_output(check_file_cmd, p_id, filename,
http_baseurl);
time_t remote_date, local_date;
fscanf(rcop, "%ld", &remote_date);
fclose(rcop);
struct stat fst;
stat(localfile, &fst);
local_date = fst.st_mtime;
if (access(localfile, 0) == -1 || local_date < remote_date) {
if (strcmp(filename, "spj") == 0)
continue;
execute_cmd("/bin/mkdir -p %s/data/%d", oj_home, p_id);
const char * cmd2 =
" wget --post-data=\"gettestdata=1&filename=%d/%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O \"%s\" \"%s/admin/problem_judge.php\"";
execute_cmd(cmd2, p_id, filename, localfile, http_baseurl);
ret++;
if (strcmp(filename, "spj.c") == 0) {
if (access(localfile, 0) == 0) {
const char * cmd3 = "gcc -o %s/data/%d/spj %s/data/%d/spj.c";
execute_cmd(cmd3, oj_home, p_id, oj_home, p_id);
}
}
if (strcmp(filename, "spj.cc") == 0) {
// sprintf(localfile,"%s/data/%d/spj.cc",oj_home,p_id);
if (access(localfile, 0) == 0) {
const char * cmd4 =
"g++ -o %s/data/%d/spj %s/data/%d/spj.cc";
execute_cmd(cmd4, oj_home, p_id, oj_home, p_id);
}
}
}
}
pclose(fjobs);
return ret;
}
void print_call_array() {
printf("int LANG_%sV[256]={", LANG_NAME);
int i = 0;
for (i = 0; i < call_array_size; i++) {
if (call_counter[i]) {
printf("%d,", i);
}
}
printf("0};\n");
printf("int LANG_%sC[256]={", LANG_NAME);
for (i = 0; i < call_array_size; i++) {
if (call_counter[i]) {
printf("HOJ_MAX_LIMIT,");
}
}
printf("0};\n");
}
//在judge.cc中调用参数
//runidstr : solution_id 的字符串 参数1
//buf : clientid 也就是进程id字符串
//oj_home : /home/judge
//execl("/usr/bin/judge_client", "/usr/bin/judge_client", runidstr, buf,
// oj_home, (char *) NULL);
//argv[0] 指向程序运行的全路径名
//argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
//argv[2] 指向执行程序名后的第二个字符串
int main(int argc, char** argv) {
char work_dir[BUFFER_SIZE]; //工作目录
//char cmd[BUFFER_SIZE];
char user_id[BUFFER_SIZE]; //用户id
int solution_id = 1000; //题目id
int runner_id = 0; //进程id
int p_id, time_lmt, mem_lmt, lang, isspj, sim, sim_s_id, max_case_time = 0;
//初始化参数,代评测id, 进程id ,评测目录 ,DEBUG,RECORD_CALL
init_parameters(argc, argv, solution_id, runner_id);
//初始化数据库链接信息,读取/home/judge/etc/judge.conf,初始化conn
init_mysql_conf();
//如果是轮询数据库,并且数据库链接失败,那么退出
if (!http_judge && !init_mysql_conn()) {
exit(0); //exit if mysql is down
}
//set work directory to start running & judging
//work_dir : /home/judge/run0
sprintf(work_dir, "%s/run%s/", oj_home, argv[2]);
//shm_run默认0 不知道什么作用还????
if (shm_run)
mk_shm_workdir(work_dir);
//进入/home/judge/run0 并设置为当前工作 目录
chdir(work_dir);
if (!DEBUG)//因为DEBUG = (argc>4) :0 所以工作前先清除下该目录
clean_workdir(work_dir);
if (http_judge)
system("/bin/ln -s ../cookie ./");
//读取数据库solution表依据solution_id,初始化p_id问题id,user_id用户id,lang编程语言编码
get_solution_info(solution_id, p_id, user_id, lang);
//get the limit
//读取运行时间、内存限制,如果是test则默认值
if (p_id == 0) {
time_lmt = 5;
mem_lmt = 128;
isspj = 0;
} else {
get_problem_info(p_id, time_lmt, mem_lmt, isspj);
}
//copy source file
//根据情况读取源程序代码
//默认是将源码从数据库中读取到/home/judge/run0/ 建立Main.c
get_solution(solution_id, work_dir, lang);
//独立处理java
//java is lucky
if (lang >= 3) {
// the limit for java
time_lmt = time_lmt + java_time_bonus;
mem_lmt = mem_lmt + java_memory_bonus;
// copy java.policy
execute_cmd("/bin/cp %s/etc/java0.policy %s/java.policy", oj_home,
work_dir);
}
//对时间内存做出最大上限
//never bigger than judged set value;
if (time_lmt > 300 || time_lmt < 1)
time_lmt = 300;
if (mem_lmt > 1024 || mem_lmt < 1)
mem_lmt = 1024;
if (DEBUG)
printf("time: %d mem: %d\n", time_lmt, mem_lmt);
// compile
// printf("%s\n",cmd);
// set the result to compiling
//编译程序
int Compile_OK;
Compile_OK = compile(lang);//编译是否完成,成功默认返回0;否则返回错误文件ce.txt的大小
if (Compile_OK != 0) {//编译失败则推出判题进程不需后续执行了
addceinfo(solution_id);
update_solution(solution_id, OJ_CE, 0, 0, 0, 0, 0.0);
update_user(user_id);
update_problem(p_id);
if (!http_judge)
mysql_close(conn);
if (!DEBUG)
clean_workdir(work_dir);
else
write_log("compile error");
exit(0);
} else {//如果是除了"rb", "sh", "py",这三种以外的语言,更新表solution
update_solution(solution_id, OJ_RI, 0, 0, 0, 0, 0.0);
}
//exit(0);
// run
//执行编译后程序
char fullpath[BUFFER_SIZE];///home/judge/data/1000 完整的测试数据目录
char infile[BUFFER_SIZE];
char outfile[BUFFER_SIZE];
char userfile[BUFFER_SIZE];
sprintf(fullpath, "%s/data/%d", oj_home, p_id); // the fullpath of data dir
// open DIRs
DIR *dp;
dirent *dirp;
// using http to get remote test data files
if (p_id > 0 && http_judge)
get_test_file(work_dir, p_id);
//默认采用的这种,读取目录文件失败则判题子程序退出,-1
if (p_id > 0 && (dp = opendir(fullpath)) == NULL) {
write_log("No such dir:%s!\n", fullpath);
if (!http_judge)
mysql_close(conn);
exit(-1);
}
int ACflg, PEflg;
ACflg = PEflg = OJ_AC;
int namelen;
int usedtime = 0, topmemory = 0;
//create chroot for ruby bash python
if (lang == 4)
copy_ruby_runtime(work_dir);
if (lang == 5)
copy_bash_runtime(work_dir);
if (lang == 6)
copy_python_runtime(work_dir);
if (lang == 7)
copy_php_runtime(work_dir);
if (lang == 8)
copy_perl_runtime(work_dir);
if (lang == 9)
copy_mono_runtime(work_dir);
if (lang == 10)
copy_objc_runtime(work_dir);
if (lang == 11)
copy_freebasic_runtime(work_dir);
if (lang == 12)
copy_guile_runtime(work_dir);
// read files and run
// read files and run
// read files and run
double pass_rate = 0.0;
int num_of_test = 0;
int finalACflg = ACflg;
//网页点击的测试,
if (p_id == 0) {} //custom input runnin
printf("running a custom input...\n");
get_custominput(solution_id, work_dir);
init_syscalls_limits(lang);
pid_t pidApp = fork();
if (pidApp == 0) {
run_solution(lang, work_dir, time_lmt, usedtime, mem_lmt);
} else {
watch_solution(pidApp, infile, ACflg, isspj, userfile, outfile,
solution_id, lang, topmemory, mem_lmt, usedtime, time_lmt,
p_id, PEflg, work_dir);
}
if (ACflg == OJ_TL) {
usedtime = time_lmt * 1000;
}
if (ACflg == OJ_RE) {
if (DEBUG)
printf("add RE info of %d..... \n", solution_id);
addreinfo(solution_id);
} else {
addcustomout(solution_id);
}
update_solution(solution_id, OJ_TR, usedtime, topmemory >> 10, 0, 0, 0);
exit(0);
}
//真正的submit执行测试
for (; (oi_mode || ACflg == OJ_AC) && (dirp = readdir(dp)) != NULL;) {
//遍历/home/judge/data/1000下的sample.in sample.out test.in test.out
namelen = isInFile(dirp->d_name); // check if the file is *.in or not
if (namelen == 0)
continue;
//准备好测试数据,初始化,outfile,userfile
prepare_files(dirp->d_name, namelen, infile, p_id, work_dir, outfile,
userfile, runner_id);
//这是什么限制???????
init_syscalls_limits(lang);
//又要创建执行子进程了。。。。
pid_t pidApp = fork();
if (pidApp == 0) {//如果是子进程在执行
//执行程序,在/run0/下生成user.out结果文件
run_solution(lang, work_dir, time_lmt, usedtime, mem_lmt);
} else {
//父进程,创建的执行子进程数量+1,这里是不是没有处理如果子进程创建失败该如何?????????
num_of_test++;
//这里没有采用 waitpid()方式,而是采用监视子进程方式ptrace()
//为什么这样用呢??????????
//监视子进程,看齐是否能完整无误执行下来,随时修改ACflg
watch_solution(pidApp, infile, ACflg, isspj, userfile, outfile,
solution_id, lang, topmemory, mem_lmt, usedtime, time_lmt,
p_id, PEflg, work_dir);
//到这里执行子进程应该是结束了,开始进行结果的判断匹配
judge_solution(ACflg, usedtime, time_lmt, isspj, p_id, infile,
outfile, userfile, PEflg, lang, work_dir, topmemory,
mem_lmt, solution_id, num_of_test);
if (use_max_time) {
max_case_time =
usedtime > max_case_time ? usedtime : max_case_time;
usedtime = 0;
}
//clean_session(pidApp);
}
if (oi_mode) {
if (ACflg == OJ_AC) {
++pass_rate;
}
if (finalACflg < ACflg) {
finalACflg = ACflg;
}
ACflg = OJ_AC;
}
}
if (ACflg == OJ_AC && PEflg == OJ_PE)
ACflg = OJ_PE;
if (sim_enable && ACflg == OJ_AC && (!oi_mode || finalACflg == OJ_AC)
&& lang < 5) { //bash don't supported
sim = get_sim(solution_id, lang, p_id, sim_s_id);
} else {
sim = 0;
}
//if(ACflg == OJ_RE)addreinfo(solution_id);
if ((oi_mode && finalACflg == OJ_RE) || ACflg == OJ_RE) {
if (DEBUG)
printf("add RE info of %d..... \n", solution_id);
addreinfo(solution_id);
}
if (use_max_time) {
usedtime = max_case_time;
}
if (ACflg == OJ_TL) {
usedtime = time_lmt * 1000;
}
if (oi_mode) {
if (num_of_test > 0)
pass_rate /= num_of_test;
update_solution(solution_id, finalACflg, usedtime, topmemory >> 10, sim,
sim_s_id, pass_rate);
} else {
update_solution(solution_id, ACflg, usedtime, topmemory >> 10, sim,
sim_s_id, 0);
}
if ((oi_mode && finalACflg == OJ_WA) || ACflg == OJ_WA) {
if (DEBUG)
printf("add diff info of %d..... \n", solution_id);
if (!isspj)
adddiffinfo(solution_id);
}
update_user(user_id);
update_problem(p_id);
clean_workdir(work_dir);
if (DEBUG)
write_log("result=%d", oi_mode ? finalACflg : ACflg);
if (!http_judge)
mysql_close(conn);
if (record_call) {
print_call_array();
}
closedir(dp);
return 0;
}