⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ojserver.c

📁 一个完整的程序设计类在线评测系统(online judge)服务器端源程序 操作系统:Redhatlinux 9.0 数据库:Mysql 4.0 服务器:Apache 5.0 编译器:gcc
💻 C
字号:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <sys/wait.h>
#include "/usr/include/mysql/mysql.h"

//#include "config.h"

#define RF        -996
#define CE        -997
#define Compiling -998
#define SIGRUNNING -999
#define SIGWA -1000
#define SIGOLE -1001
#define SIGAC -1002
#define SIGPE -1003
#define SIGTLE 24

MYSQL mysql;
char Author[50];
int Exeid;
int QuerryDB();
int Compile(int Runid);
int Run(int Runid);
// Deal with TLE that give up the usage of CPU

pid_t TLEPID;
int TLERunid,TLETimelimit;

int WriteMysql(int Runid,int status,float passtime,int mem)
{
 char tmp[200];
 sprintf(tmp,"update Status set Judgestatus =%d ,Runtime =%f ,Memory =%d where Runid=%d;",status,passtime,mem,Runid);
 // printf("%s\n",tmp);
 mysql_query(&mysql,tmp);
 return 0;
}

void TLEHANDLER(int i)
{
  int status;
  rusage TLEUsage;
  kill(TLEPID,9);
  wait(&status);     
  getrusage(RUSAGE_CHILDREN, &TLEUsage);  
  WriteMysql(TLERunid,24,TLETimelimit,TLEUsage.ru_minflt*4);
  exit(24);
}
int main(int argc, char **argv)
{
 mysql_init(&mysql);
 mysql_connect(&mysql,"localhost","root","pwd");
 
      int Runid=QuerryDB();
      if(Runid==-1)
      return -1;
      if(Compile(Runid)==-1)
      return -1;
      Run(Runid);
 mysql_close(&mysql);
    return 0;
}

int QuerryDB()
{
 	mysql_select_db(&mysql,"OJS");
	char tmp[200];
	int Runid;
	sprintf(tmp,"select * from Queue order by Runid asc;");
	MYSQL_RES *res;
	MYSQL_ROW row;
	mysql_query(&mysql,tmp);
	res = mysql_store_result(&mysql);
	row = mysql_fetch_row(res);
	if(row==NULL)
	return -1;
	sscanf(row[0],"%d",&Runid);
	mysql_free_result(res);
        sprintf(tmp,"delete from Queue where Runid=%d;",Runid);
	if(mysql_query(&mysql,tmp)==0)
	{
	return Runid;
	}
	return -1;

}

int Compile(int Runid)
{
 char tmp[200];
 int Proid;
 MYSQL_RES *res;
 MYSQL_ROW row;
 
 sprintf(tmp,"select * from Status where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);
 res = mysql_store_result(&mysql);
 row = mysql_fetch_row(res);
 if(row==NULL)
 {
 fprintf(stderr,"Wrong Runid !\n");
 return 0;
 }
 sscanf(row[1],"%d",&Proid);
 sscanf(row[6],"%s",Author);
 mysql_free_result(res);
 sprintf(tmp,"update Problems set Totalsubmit =Totalsubmit+1 where Proid=%d;",Proid);
 mysql_query(&mysql,tmp);
 
 sprintf(tmp,"Update Users set Totalsubmit=Totalsubmit+1 where Name=\"%s\";",Author);
 mysql_query(&mysql,tmp);
 
 sprintf(tmp,"update Status set Judgestatus =-998 where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);
 Exeid=rand()%1000;
 sprintf(tmp,"g++ /acm/ojs/tmp/%d.cpp -o /acm/ojs/tmp/%d -ansi -fno-asm -Wall -lm -DONLINE_JUDGE --static  2> /acm/ojs/err/%d.txt",Runid,Exeid,Runid);
 if(system(tmp)!=0)
 {
 sprintf(tmp,"update Status set Judgestatus =-997 where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);
 return -1;
 }
 sprintf(tmp,"g++ /acm/ojs/tmp/RF%d.cpp -o /acm/ojs/tmp/RF%d -ansi -fno-asm -Wall -lm  -DONLINE_JUDGE --static  2> /acm/ojs/err/%d.txt",Runid,Exeid,Runid);
 if(system(tmp)!=0)
 {
 sprintf(tmp,"update Status set Judgestatus =-996 where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);
 return -1;
 }

 sprintf(tmp,"rm -f /acm/ojs/err/%d.txt",Runid);
 system(tmp);
 return 0;
}

bool IsIdentified(char a)
{
 if(a=='\n'||a=='\t'||a=='\b'||a==' ')
   return false;
 return true;
}

int Run(int Runid)          // Exe is Exeid, find Problem information from Runid
{

 MYSQL_RES *res;
 MYSQL_ROW row;
 int Timelimit,Memlimit,Proid;
 rlimit memlim,timlim;
 char tmp[200];

// Find Proid
 sprintf(tmp,"select * from Status where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);
 res = mysql_store_result(&mysql);
 row = mysql_fetch_row(res);
 if(row==NULL)
 {
 fprintf(stderr,"Wrong Runid !\n");
 return 0;
 }
 sscanf(row[1],"%d",&Proid);
 mysql_free_result(res);

 //Find Limit

 sprintf(tmp,"select * from Problems where Proid=%d;",Proid);
 mysql_query(&mysql,tmp);
 res = mysql_store_result(&mysql);
 row = mysql_fetch_row(res);

 sscanf(row[1],"%d",&Timelimit);        // Time limit is measured by seconds
 sscanf(row[2],"%d",&Memlimit);         // Memory limit is measured by Megabytes;
 Memlimit=Memlimit+1;
 mysql_free_result(res);

 // Time limit & Memory limit

 memlim.rlim_cur=Memlimit*1024*1024;
 timlim.rlim_cur=Timelimit;
 //Running

 sprintf(tmp,"update Status set Judgestatus =-999 where Runid=%d;",Runid);
 mysql_query(&mysql,tmp);

 if(fork()!=0)
 {
  int wt;
  waitpid(0,&wt,0);
  return 0;
 }

int pipefds[2];
 pipe(pipefds);

 pid_t pid=fork();
 
if(pid==0)  //Children
  {
   char tmp[100];
   sprintf(tmp,"/acm/ojs/data/%d.in",Proid);
   freopen(tmp,"r",stdin);

   close(1);
   dup(pipefds[1]);
   close(pipefds[0]);
   close(pipefds[1]);

   setrlimit( RLIMIT_CPU,&timlim);
   setrlimit( RLIMIT_AS,&memlim);
   sprintf(tmp,"/%d",Exeid);
   char tmp2[100];
   sprintf(tmp2,"./%d",Exeid);
   chroot("/acm/ojs/tmp/");
   setuid(99);
   setgid(99);
   execlp(tmp,tmp2,NULL);
   return 0;

  }

 int status;
 bool WA=false,AC=false,PE=false;
 bool Fend=false,Pend=false;

 rusage usage;
 close(0);
 dup(pipefds[0]);
 close(pipefds[0]);
 close(pipefds[1]);
FILE *p;
 char path[50];
 sprintf(path,"/acm/ojs/data/%d.out",Proid);
 p=fopen(path,"r");
 char Petmp[1000],Ftmp[1000];
 bool ACenable=true;
 // Deal with TLE that give up the usage of CPU
 TLERunid=Runid;
 TLEPID=pid;
 TLETimelimit=Timelimit;
 alarm(TLETimelimit);
 signal(SIGALRM,&TLEHANDLER);

 while(true)
 {

   char a,b;
   if(fscanf(p,"%c",&a)==EOF)
     { a=' '; Fend=true; }
   if(scanf("%c",&b)==EOF)
     { b=' '; Pend=true; }
   if(Fend&&Pend)
   {
   if(ACenable)
   AC=true;
   else PE=true;
   break;
   }
	if(a!=b)
	{
		ACenable=false;
		if( IsIdentified(a)&&IsIdentified(b) )
		{
		WA=true;
		kill(pid,9);
		break;
		}
		if( IsIdentified(a))
		{
			while(true)
			{
				if(scanf("%c",&b)==EOF)
				{ Pend=true; WA=true; break; }
				if(IsIdentified(b))
				break;
			}
			if(Pend)
				break;
			if(a==b)
			continue;
			else { WA=true; kill(pid,9); break; }
		}
		else if(IsIdentified(b))
		{
			while(true)
			{  if(fscanf(p,"%c",&a)==EOF)
				{ Fend=true; WA=true;  break; }
			   if(IsIdentified(a))
				break;
			}
			if(Fend)
				break;
			if(a==b)
			continue;
			else { WA=true; kill(pid,9); break; }
		}

	}

}

  wait(&status);
  getrusage(RUSAGE_CHILDREN, &usage);
 // printf("status ===  %d\n",status);

  float passtime;
  passtime=usage.ru_utime.tv_sec+usage.ru_stime.tv_sec+(float)(usage.ru_stime.tv_usec+usage.ru_utime.tv_usec)/1000000;

 if(passtime>Timelimit)
        status=24;
 if(usage.ru_minflt*4>(Memlimit-1)*1024)
        status=6;

 if(status==24 || status==11 ||status==8 || status==6 )
        {
	if(status==6 && usage.ru_minflt*4 < (Memlimit-1)*1024 )
		usage.ru_minflt= Memlimit*1024/4;
	WriteMysql(Runid,status,passtime,usage.ru_minflt*4);
        return 0;
	}
 if(AC)
        {
        WriteMysql(Runid,SIGAC,passtime,usage.ru_minflt*4);
	sprintf(tmp,"update Problems set Accepted=Accepted+1 where Proid=%d;",Proid);
	mysql_query(&mysql,tmp);
	sprintf(tmp,"select * from Acs where Proid=%d and Author=\"%s\";",Proid,Author);
	mysql_query(&mysql,tmp);
	res = mysql_store_result(&mysql);
        row = mysql_fetch_row(res);
	
        if(row==NULL)
        {
        sprintf(tmp,"insert into Acs values(-100,%d,\"Undifined\",1002,%lf,%d,\"%s\");",Proid,passtime,usage.ru_minflt*4,Author);
	mysql_query(&mysql,tmp);
	sprintf(tmp,"update Users set Accepted=Accepted+1 where Name=\"%s\";",Author);
	mysql_query(&mysql,tmp);
        sprintf(tmp,"cp -f /acm/ojs/tmp/%d.cpp /acm/ojs/src/%s.%d",Runid,Author,Proid);
	system(tmp);
        }
        else
        {
         float Actime;
         int Acmemory;
         sscanf(row[4],"%f",&Actime);	
         sscanf(row[5],"%d",&Acmemory);	        	
         bool upd=false;
         if(Actime>passtime)
         	upd=true;
         if(Actime==passtime && Acmemory > usage.ru_minflt*4 )
                upd=true;   
     
         sprintf(tmp,"/acm/ojs/src/%s.%d",Author,Proid);
            if(access(tmp,F_OK)!=0)
             upd = true;

         if(upd)
         {
         sprintf(tmp,"update Acs set Runtime=%f,Memory=%d where Proid=%d and Author=\"%s\";",passtime,usage.ru_minflt*4,Proid,Author);
	 mysql_query(&mysql,tmp);
	 sprintf(tmp,"cp -f /acm/ojs/tmp/%d.cpp /acm/ojs/src/%s.%d",Runid,Author,Proid);
	 system(tmp);

         }
        return 0;
	}
        }
if(PE)
 	{
	WriteMysql(Runid,SIGPE,passtime,usage.ru_minflt*4);
        return 0;
	}
 if(WA)
  	{
	WriteMysql(Runid,SIGWA,passtime,usage.ru_minflt*4);
        return 0;
	}
 if(status)
 	{
	WriteMysql(Runid,status,passtime,usage.ru_minflt*4);
 	return 0;
 	}

 return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -