아직미분류2011. 4. 24. 02:02

설치 방법은 http://noexists.tistory.com/193 참고

일부 언어만 허용하고 싶은 경우가 있다. 여기서는 C 언어만 허용하는 상황을 예로 들어 보겠다.

static $OJ_LANGMASK=126; // C 언어만 허용.

이렇게 LANGMASK 설정만 해서 모든 것이 완벽하면 좋겠지만 그렇지 않다.

submitpage.php
C 언어만 받도록 하기 위해 $langmask=126을 추가한다. 위치가 중요한데, "$lang=(~((int)$langmask))&127;"의 바로 위에 넣어야 한다. 왜냐하면 $langmask=$_GET['langmask'];을 통해 덮어 씌우는 일을 막아야 하기 때문이다. (GET이라는 것은 a.php?langmask=1처럼 url로 변수를 전달하는 것이다.) 사실, contest에서는 LANGMASK 설정이 따로 있어서 이런 식으로 된 것 같다. 그러나 사용자가 직접 url을 수정해서 langmask를 바꾸면 어쩌려고 그러나? 코드를 읽다보면 이런 식으로 url 공격에 취약(?)한 부분이 보인다.

이렇게 해도 아직 완벽하지 않다. 사용자에게 보여지는 페이지는 사용자가 조작이 가능하기 때문이다. (그리스몽키 등으로 option 태그를 바꿔버리는 방법 등이 있다.) 안전하게 하려면 submit.php에서 한 번 더 language가 허용되는 language인지 확인해야 한다.

Posted by asdfzxcv
아직미분류2011. 4. 24. 01:57

이 글은 http://noexists.tistory.com/193에서 이어진다.

admin/msg.txt
공백으로 만들자.

oj-header.php
가장 뒤의 <script ...> 두 줄을 제거하자. 이상한 것이 자꾸 뜬다.

oj-footer.php
언어를 고를 수 있는데, 한국어와 영어 등 필요한 것만 남겨두고 제거하자.
불필요한 메시지를 삭제하자.

관리자 아이디 만들기
일단 보통 회원으로 가입한다.
mysql을 실행하고 "use my_oj;"까지 잘 한 뒤에, 다음 명령을 내리자.

INSERT INTO privilege(user_id,rightstr) VALUES('my_id','administrator');

여기서 administrator는 그냥 그대로 치라는 소리다. (id는 물론 상황에 맞게 바꿈.)
최초의 관리자만 이렇게 어렵게 만들고 다음부터는 관리자 페이지를 이용할 수 있다.
참고로 남의 소스를 보려면 source_browser 권한도 있어야 한다.

문제 만들기 TIP
테스트 입력이 없어도 뭔가 아무거나 적어야 채점 프로그램이 동작한다.

잘 안 될 때
/home/judge로 이동한다. (물론 설치 시 id를 다른 걸로 했으면 그것으로 사용)
/home/judge/etc/judge.conf의 설정을 확인한다.
sudo pkill judged && judged
이제 다시 시도해보자.
이래도 안 되면 run? 디렉토리들의 퍼미션을 771로 해준다.
sudo pkill judged && judged
이제 다시 시도해보자.

유사도 적발 기능이 작동하지 않을 때
특정 64-bit 리눅스에서 sim_c가 작동하지 않는 경우가 있다. 간단하게 bash에서 sim_c 명령을 내려보자. 만약 그런 명령이 없다고 나온다면, hustoj 최신 버전을 받은 후, hustoj-read-only/core/sim만 재설치를 시도하자.

hustoj 관련 다른 글
2011/04/24 - [분류 전체보기] - hustoj에서 일부 언어만 허용 (LANGMASK)
2011/04/24 - [분류 전체보기] - hustoj 기타 수정

Posted by asdfzxcv
아직미분류2011. 4. 24. 00:54

얼마 전에 hustoj를 설치했다. 아주 최근에 설치한 것은 아니고, 얼마 전에 설치한 것이라 최신 버전과 다른 부분도 있겠지만 많이 다르지는 않을 것이다. 우분투 리눅스 기준으로 설명했지만, 패키지 설치 방법만 제외하면 다른 리눅스라도 거의 비슷할 것이다.
http://code.google.com/p/hustoj/

제 1 단계: 패키지 설치

install.sh에 패키지 설치 코드가 있지만, 사용 환경에 따라서 이게 잘 안 될수도 있다. 예를 들면, 사용 환경에 svn이 없으면 설치 스크립트의 제일 처음에 나오는 svn checkout부터 안 될 수가 있다. 패키지를 설치하려면 subversion도 설치했어야 하는 거 아닌가? 그리고 인스톨 스크립트에 apt-get하고 yum이 같이 적힌 이유도 잘 모르겠다.

$ sudo apt-get update
$ sudo apt-get install subversion
$ sudo apt-get install g++ libmysql++-dev php5 apache2 mysql-server php5-mysql

제 2 단계: mysql 계정 만들기

일단 mysql 계정을 하나 만드는 것이 좋다. 쓸데 없이 root 계정을 쓰는 것은 보안상 안 좋을 수도 있으니까. 그리고 기본적으로는 jol 데이타베이스를 쓰도록 되어 있지만, 필요에 따라 데이타베이스를 다른 이름으로 해야하는 경우도 있다.

$ mysql -uroot -p
Enter password: (암호 입력)
mysql> set names utf8;
mysql> create database my_oj;
mysql> grant usage on *.* to 'db_id' identified by 'db_password';
mysql> grant all on my_oj.* to 'db_id';

제 3 단계: judge 계정 생성

채점 데몬이 실행되는 계정을 만들어야 한다. 사실, install.sh를 보면 계정 생성 명령이 있지만, uid가 겹쳐서 문제가 되는 경우도 있을 수 있다. 그러므로 안전하게 직접 설치하는 방법을 택하자. 여기서 uid를 무엇으로 하든, 그 uid가 뭔지는 알아야 한다. 사실 1536 말고 다른 uid는 안 써봤는데, 만약 uid까지 달라지면 소스 코드를 수정해야 하므로 매우 귀찮아진다. (소스 파일에서 setuid나 setresuid 부분을 수정해야 한다.)

$ sudo useradd -m -u 1536 judge

제 4 단계: 데이타베이스 테이블 생성

먼저 db.sql을 편집기로 열고 jol을 찾아서, my_oj로 고치자. 자칫 잘못하면 가장 위의 두 줄만 수정하고 넘어가기 쉬운데, 파일 아래쪽에도 jol이 등장하니 찾아서 전부 고쳐야 한다.

  • Line 2: 주석처리.
  • Line 3: use my_oj;
  • Line 295
  • Line 298

편집이 잘 된 것 같으면, "mysql -u$ID -p < db.sql"를 실행하자. ($ID는 적절히 대체.)

제 5 단계: 본격적인 설치

먼저 judge.conf를 열고 적절히 고치자.

  • OJ_HOST_NAME은 알아서 고치자.
  • OJ_USER_NAME, OJ_PASSWORD는 mysql 계정이다.
  • OJ_DB_NAME은 제 4 단계에서 생성한 것으로 고치자.
  • OJ_SIM_ENABLE은 코드 유사도 적발 기능이 필요한 경우 1로 하면 된다.

이제 install.sh를 편집기로 열고, 고쳐야 할 것들을 찾아서 고쳐야 한다.

  • 앞선 단계에서 이미 처리한 명령은 주석처리하자.
  • WEBBASE를 적절히 수정하자. 우분투 기본 설정에서는 수정할 필요가 없다.
  • DBUSER, DBPASS를 수정하자.
  • Line 24에 "cd ../.."을 추가해서 make 이후에 원래 경로로 돌아오도록 고치자.
  • 곳곳의 chown, chgrp 명령에서 www-data는 배포판에 따라 알맞게 수정하자.
  • 혹시, 제 3 단계에서 다른 계정명을 생성했다면, 알아서 적질히 고치자.

이제 드디어 "./install.sh"를 하면 된다.

제 6 단계: php 파일 고치기

이제 "/var/www" 디렉토리로 이동하자. 그리고 "JudgeOnline" 디렉토리를 마음에 드는 이름으로 고치고, 그 안으로 이동하자. 여기서 "./include/db_info.inc.php"를 열어 보면 설정할 것들이 남아 있다. 가장 중요한 설정만 적으면 다음과 같다.

static $DB_HOST="127.0.0.1";
static $DB_NAME="my_oj";
static $DB_USER="db_id";
static $DB_PASS="db_password";
static $OJ_NAME="My OJ";
static $OJ_HOME="http://server/path";
static $OJ_ADMIN="mail@server";
static $OJ_DATA="/home/judge/data"; // 혹시 계정명을 다르게 한 경우 수정.
static $OJ_LANG="ko"; // 한국어를 기본으로 한다.
static $OJ_SIM=true; // 카피 적발 기능.
static $OJ_DICT=false; // 이상한 사전이므로 제거하자.

그리고 필요에 따라 아파치 서버를 재시작하고 접속해서 테스트해보자.

다음 글에서 계속: 
2011/04/24 - [분류 전체보기] - hustoj 설치 (2)

hustoj 관련 다른 글
2011/04/24 - [분류 전체보기] - hustoj에서 일부 언어만 허용 (LANGMASK)
2011/04/24 - [분류 전체보기] - hustoj 기타 수정

Posted by asdfzxcv
Linux2011. 4. 22. 23:16
간단하게 wol 패키지를 설치하고,
wol -i <IP address> <MAC address>
하면 된다. IP 주소는 끝을 255로 해서 broadcasting 시키고, MAC 주소는 :로 구분해서 입력한다.

unicast vs. subnet directed broadcast
http://technet.microsoft.com/en-us/library/bb632911.aspx
 
Posted by asdfzxcv
web2011. 4. 16. 11:42
2008-03-18에 작성한 글 업데이트.

1.
비공개한 글도 태그는 보인다. 해당 태그를 가진 글이 전부 비공개인데도 태그가 태그 목록에 나온다는 뜻이다. 이 경우 태그를 클릭하면 해당되는 글이 0개라고 나온다.

2.
[CODE][/CODE]가 작동하지 않는다. 태터툴스 게시판을 검색했으나 결론을 얻지 못했다. 플러그인을 설치해애된다는 말도 있는데, 그 사림이 가르쳐 준 링크가 깨졌다.


3.
태그와 관련하여 다음과 같은 버그가 있다.
  1. 어떤 글의 태그를 "gentoo"로 등록했다.
  2. 나중에 "gentoo"를 "Gentoo"로 바꾸고 싶어서 "gentoo" 태그를 모든 글에서 지웠다.
  3. 태그 목록에는 "gentoo"가 남아있다.
  4. 글 하나에 "Gentoo" 태그를 붙였다.
  5. 그런데 그 태그가 "gentoo"로 붙게 된다.
  6. 글 수정을 누르고 "gentoo"를 "Gentoo"로 고쳐 저장했다.
  7. 그러면 그 글에는 "gentoo" 태그도 "Gentoo" 태그도 붙지 않는다.
  8. 그리고 태그 목록에는 여전히 "gentoo"가 남아있다.
카테고리 명에 "Gentoo"가 있는데, 이것과 태그 이름이 충돌하는지 여부는 확인하지 않았다.

4. 스킨 오류들
CSS에서 #transparent는 뭔가? #transperant는 또 뭔가?
background-image에서 url('...')을 쓸 때 닫는 괄호가 빠짐.
스킨위자드에서 치환할 것이 없으면, none이라든가, no-repeat이라든가, 이런 속성을 넣어야 하는데, 안 넣음. 이 경우 스킨위자드에서 다른 옵션을 선택했다가, 안 넣는 옵션으로 다시 바꾸면 그 때는 속성을 넣어 줌.
폰트 이름을 적을 때 따옴표를 안 씀.
스킨 구조가 <ul>이나 <li>안에 <li>가 없는 경우를 처리 못 함.
호환성을 위한 몇몇 에러가 몇 개 더 있으나 이건 일단 넘어가자.

5. 기타
너무 긴 자바스크립트나, css는 external script, css로 처리했으면 좋을텐데.
Posted by asdfzxcv
Linux2011. 4. 16. 01:12
http://en.wikipedia.org/wiki/Magic_SysRq_key

신기해서 스크랩. 사실 자세히 읽어보진 않았다.

echo e > /proc/sysrq-trigger
로 SIGTERM을 날린다거나... 
Posted by asdfzxcv
프로그래밍/C/C++2011. 4. 14. 23:38
가장 쉬워보이는 방법인
A ## __LINE__
은 (적어도 gcc를 포함한) 여러 컴파일러에서 원하는 대로 작동하지 않는다. 그럼 어떻게 해야 하느냐? 구글링을 해봤다.

http://stackoverflow.com/questions/3580533/c-preprocessor-magic

아직 이렇게 되는 원리를 이해할 수 없다. 아무튼 저걸 성공한 저 분에게 경의를 표한다.
(http://stackoverflow.com/users/15168/jonathan-leffler)
설명을 적어준 분에게도.
(http://stackoverflow.com/users/187690/andreyt)
#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__

#define DECLARE11(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE10(x) DECLARE11(x, __LINE__)

#define DECLARE23(line) _LINE_ ## line
#define DECLARE22(x) _DECLARED_VARIABLE_ ## x
#define DECLARE21(x, line) DECLARE22(x) ## DECLARE23(line)
#define DECLARE20(x) DECLARE21(x, __LINE__)

#define DECLARE32(line) _LINE_ ## line
#define DECLARE31(x, line) _DECLARED_VARIABLE_ ## x ## DECLARE32(line)
#define DECLARE30(x) DECLARE31(x, __LINE__)

#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)

int DECLARE(y);
int DECLARE10(z) = 12;
int DECLARE20(a) = 37;
int DECLARE30(b) = 91;
int DECLARE40(c) = 129;
이 많은 코드 중 (아마도) DECLARE40만 원하는 대로 동작할 것이다. (컴파일러에 따라 다를 수도 있다.) 컴파일이 안 되는 DECLARE20과 DECLARE30을 제외하고 나머지의 결과는 다음과 같다.
int _DECLARED_VARIABLE_y_LINE___LINE__;
int _DECLARED_VARIABLE_z_LINE___LINE__ = 12;
int _DECLARED_VARIABLE_c_LINE_23 = 129;
결론적으로 다음과 같이 사용하면 된다. Static assert의 경우 크기가 음수인 배열을 typedef로 선언하면서 컴파일 에러를 발생시키는 방식이다. 이건 (http://stackoverflow.com/questions/1597704/verifying-that-c-c-signed-right-shift-is-arithmetic-for-a-particular-compiler)에서 본 것.
#define LINE2(x, line) x ## line
#define LINE1(x, line) LINE2(x, line)
#define LINE(x) LINE1(x, __LINE__)
#define MY_STATIC_ASSERT2(x, line) \
        typedef int MyStaticAssert_line_ ## line[(x) ? 1 : -1]
#define MY_STATIC_ASSERT1(x, line) MY_STATIC_ASSERT2(x, line)
#define MY_STATIC_ASSERT(x) MY_STATIC_ASSERT1(x, __LINE__)
그 외에 참고할 만한 곳
http://en.wikibooks.org/wiki/C_Programming/Preprocessor
Posted by asdfzxcv
LaTeX2011. 4. 14. 21:49
\newcommand\sgn{\mathop{\mathrm{sgn}}\nolimits}
\DeclareMathOperator\sgn{sgn}
\newcommand{\sgn}{\operatorname{sgn}}
http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/Archives/Mathematics/2011_January_18
Posted by asdfzxcv
프로그래밍2011. 4. 14. 20:13
프로그래밍 언어에서 나머지 연산을 할 때 결과가 세 종류 이상 있다.
편의상 p = q * n + r의 표기를 따르자. p가 피제수, n이 제수, q가 몫, r이 나머지.

http://en.wikipedia.org/wiki/Modulo_operation
위키에는 truncated division, floored division, Euclidean definition 방식을 설명하고 있다. 이것이 일반적으로 사용되는 용어인지는 불확실하다. 아무튼 간략하게 요약하면,
방식 q sgn(r)
Truncated round toward zero sgn(p)
Floored round toward negative infinity sgn(n)
Euclidean \(\mathop{\mathrm{sgn}}\nolimits(n) \left\lfloor \frac{p}{\left|n\right|} \right\rfloor\) \( \geq 0 \)
 
그리고 toward positive infinity는 쓰는 경우가 있는지 모르겠다.

개인적으로는 floored division 또는 Euclidean definition 방식이 수학적으로 아름답다고 느끼지만 --- 사실 다른 사람도 그렇게 주장한다. --- 프로그래밍 언어에서는 그냥 truncated division 방식을 쓰는 경우가 많다. 자세한 것은 위키를 읽어보자.

C 언어에서 2로 나누는 것을 floored division으로 하고 싶으면, arithmetic shift를 써야 하는데, 문제는 C 언어에서 음수에 대한 >>가 implementation defined이다. 그래서 컴파일러가 >>를 어떻게 처리하는지 알아야 하는 경우가 있다.
http://stackoverflow.com/questions/1597704/verifying-that-c-c-signed-right-shift-is-arithmetic-for-a-particular-compiler
헐, 크기가 음수인 array를 만들어서 컴파일 에러를 발생시키다니 천재적인 방법인 듯. 이런 식으로도 compiler time assert가 가능하구나. 하지만 문제가 하나 있는데, __LINE__이 치환되지 않고 그냥 __LINE__으로 들어간다는 것이다. 이 문제는 글을 새로 작성했다. (http://noexists.tistory.com/183)
#define RIGHT_SHIFT_IS_ARITHMETIC \
    ( (((signed int)-1)>>1) == ((signed int)-1) )
MY_STATIC_ASSERT(RIGHT_SHIFT_IS_ARITHMETIC);
Posted by asdfzxcv
web2011. 4. 14. 00:32
#177
크롬에서 세로 스크롤이 나타나요.
https://bitbucket.org/alexg/syntaxhighlighter/issue/177/superfluous-vertical-scrollbars-in-chrome
패치 자체 적용 완료.

#251
https://bitbucket.org/alexg/syntaxhighlighter/issue/251/major-bug-found-and-fixed-solves-many
흥미로운 버그인데, C 언어에서는 또 문제가 안 된다. 자바스크립트 brush의 경우 string을 찾은 뒤, comment를 찾지만, C brush는 그 반대이기 때문인 것 같다.
// http://jmrware.com/articles/2011/sh-bug/SyntaxHighlighterBug.html
// Commenting won't get you anywhere
'single' line with more 'single' line with more 'single' line with more
"double" line with more "double" line with more "double" line with more

#?
#define asdf sdfsdf\
                   adfsdfas
int main()
{
return 0;
}
정규식으로 패턴을 찾는 방식이라, 정규식이 완벽하지 않으면 문제가 발생한다. 바로 위의 예제 같은 경우 <와 > 사이에 \가 들어가는 건 또 제외해야 하는 것으로 알고 있다. 이처럼 하지만 완벽하게 만드는 것은 쉬운일이 아니다.

참고로 vim에서는 syntax/c.vim이 300 lines가 넘고, shBrushCpp.js는 100 lines 정도이다. 흠, vim의 synstax를 조금만 수정해서 가져다 쓰는 것이 가능하면 좋을 것 같은데...

########################################
비록 버그가 조금 있지만, 자바스크립트로 이 정도라도 만든 것이 어딘가! 버그를 고칠 실력이나 시간이 부족하다면, 그냥 "제작자님 감사요"하고 가져다 쓰자.
Posted by asdfzxcv