기존 qmail 의 pop3d 데몬을 다른 걸로 변경하기 위해
daemontools 이용하여 사용하려 했으나 ㅠㅠ
php 가 메모리에 적재되지 않고 실행이 되지 않더군요 되면 좋았을텐데 ㅠㅠ;
할수없이 php 로 pop3 데몬을 만들었습니다.
주 목적은 파일기반의 메일서버를 디비기반의 메일서버로 변경하여,
pop3 에서 사용자가 메일을 긁어가버리면 실시간 동기화가 되지 않기에.....
php 로 pop3 데몬을 작성하여 웹메일과 완전 동기화를 시키는 목적입니다.
http://wiki.jinoos.com 사이트의 소스를 많이 참조하였습니다.
socket_close 앞에 socket_shutdown 을 사용한것은 커넥션이 즉각 끊어지지 않아서 명시적으로 쓴것입니다.
user ,pass , quit 외에 나머지 명령어는 스스로 ^^;
list
stat
retr
dele
noop
apop
의 명령어가 있습닌다.
아래부터 소스.......
#!/usr/local/php/bin/php -q
<?
$cSock = array();
$cInfo = array();
$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sSock, 0, 110);
socket_listen($sSock);
$err = '-ERR ';
$errsyntax = '-ERR syntax error';
while (true) {
$sockArr = array_merge(array($sSock), $cSock);
if (socket_select($sockArr, $tWrite = null, $tExcept = null, 0) > 0) {
foreach ($sockArr as $sock) {
// 서버소켓에 이벤트가 발생할 경우
if ($sock == $sSock) {
$tSock = socket_accept($sSock);
socket_getpeername($tSock, $ip, $port);
$cSock[$tSock] = $tSock;
$cInfo[$tSock] = array('ip'=>$ip, 'port'=>$port);
msg($tSock, "+OK <".$port.".".time()."@abc.co.kr>");
}
// 서버소켓의 이벤트가 아닐 경우
else {
$buf = socket_read($sock, 4096);
if (!$buf) {
exceptSocket(&$cSock, &$cInfo, $sock);
}
else {
// 개행 문자가 들어오기전까지 받아둔다.
$buffer[$sock]['buf'] .= $buf;
if (ereg("\n|\r|\r\n", $buffer[$sock]['buf'])) {
$thisSockInfo = $cInfo[$sock];
$cmd = trim(substr($buffer[$sock]['buf'], 0, 5));
$tmp = trim(substr($buffer[$sock]['buf'], 5));
$buffer[$sock]['buf'] = null;
switch (strtolower($cmd)) {
case 'user':
if ($tmp) { $buffer[$sock]['login_id'] = $tmp; msg($sock, '+OK'); }
else { msg($sock, $errsyntax); }
break;
case 'pass':
if ($tmp) {
if ($buffer[$sock]['login_id']) {
if (login_check($buffer[$sock]['login_id'], $tmp) =
= true) {
$buffer[$sock]['pass'] = $tmp;
msg($sock, '+OK');
}
else {
msg($sock, $err.'authorization failed');
@socket_shutdown($sock);
@socket_close($sock);
}
}
else {
msg($sock, $err.'USER first');
}
}
else { msg($sock, $errsyntax); }
break;
case 'list':
break;
case 'stat':
break;
case 'retr':
break;
case 'dele':
break;
case 'noop':
break;
case 'apop':
break;
case 'quit':
msg($sock, '+OK');
@socket_shutdown($sock);
@socket_close($sock);
exceptSocket(&$cSock, &$cInfo, $sock);
break;
default:
msg($sock, $err.'syntax error');
break;
}
// switch
}
// 개행 문자가 들어올때까지 받아둔다.
}
// buf 가 있을 경우
}
// 소켓이 서버 소켓이 아닐 경우
}
// foreach
}
// 이벤트가 발생한 경우
usleep(500000);
}
// while end
function msg($fd = '', $str) {
// $str = str_replace("\r\n", "", $str);
// $str = str_replace("\n", "", $str);
if ($fd)
socket_write($fd, $str . chr(13). chr(10));
else
echo $str . chr(13) . chr(10);
}
function exceptSocket(&$sockSet, &$infoSet, $sock) {
unset($sockSet[$sock]);
unset($infoSet[$sock]);
// array_merge 함수에서 erro 발생을 막기 위한 처리
if (sizeof($sockSet) == 0) {
$sockSet = array();
$infoSet = array();
}
}
function login_check($u_id, $pass) {
$connect = mysql_connect("localhost", "xxx", "xxxxx") or Die();
@mysql_select_db("db", $connect);
$query = "select passwd from member_table where user = '$u_id'";
$result = mysql_query($query, $connect);
$rowpass = mysql_result($result, 0);
mysql_close($connect);
if ($rowpass == $pass) return true;
else return false;
}
?>
/************************************************************************/
* 위 코드를 이용하여 생긴 서버 장애 및 데이터 손실은 본인에게 책임이 없음을 알려드립니다. *
* 불안하시면 직접 만들어 쓰시길 권해드립니다. *
/************************************************************************/
daemontools 이용하여 사용하려 했으나 ㅠㅠ
php 가 메모리에 적재되지 않고 실행이 되지 않더군요 되면 좋았을텐데 ㅠㅠ;
할수없이 php 로 pop3 데몬을 만들었습니다.
주 목적은 파일기반의 메일서버를 디비기반의 메일서버로 변경하여,
pop3 에서 사용자가 메일을 긁어가버리면 실시간 동기화가 되지 않기에.....
php 로 pop3 데몬을 작성하여 웹메일과 완전 동기화를 시키는 목적입니다.
http://wiki.jinoos.com 사이트의 소스를 많이 참조하였습니다.
socket_close 앞에 socket_shutdown 을 사용한것은 커넥션이 즉각 끊어지지 않아서 명시적으로 쓴것입니다.
user ,pass , quit 외에 나머지 명령어는 스스로 ^^;
list
stat
retr
dele
noop
apop
의 명령어가 있습닌다.
아래부터 소스.......
#!/usr/local/php/bin/php -q
<?
$cSock = array();
$cInfo = array();
$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sSock, 0, 110);
socket_listen($sSock);
$err = '-ERR ';
$errsyntax = '-ERR syntax error';
while (true) {
$sockArr = array_merge(array($sSock), $cSock);
if (socket_select($sockArr, $tWrite = null, $tExcept = null, 0) > 0) {
foreach ($sockArr as $sock) {
// 서버소켓에 이벤트가 발생할 경우
if ($sock == $sSock) {
$tSock = socket_accept($sSock);
socket_getpeername($tSock, $ip, $port);
$cSock[$tSock] = $tSock;
$cInfo[$tSock] = array('ip'=>$ip, 'port'=>$port);
msg($tSock, "+OK <".$port.".".time()."@abc.co.kr>");
}
// 서버소켓의 이벤트가 아닐 경우
else {
$buf = socket_read($sock, 4096);
if (!$buf) {
exceptSocket(&$cSock, &$cInfo, $sock);
}
else {
// 개행 문자가 들어오기전까지 받아둔다.
$buffer[$sock]['buf'] .= $buf;
if (ereg("\n|\r|\r\n", $buffer[$sock]['buf'])) {
$thisSockInfo = $cInfo[$sock];
$cmd = trim(substr($buffer[$sock]['buf'], 0, 5));
$tmp = trim(substr($buffer[$sock]['buf'], 5));
$buffer[$sock]['buf'] = null;
switch (strtolower($cmd)) {
case 'user':
if ($tmp) { $buffer[$sock]['login_id'] = $tmp; msg($sock, '+OK'); }
else { msg($sock, $errsyntax); }
break;
case 'pass':
if ($tmp) {
if ($buffer[$sock]['login_id']) {
if (login_check($buffer[$sock]['login_id'], $tmp) =
= true) {
$buffer[$sock]['pass'] = $tmp;
msg($sock, '+OK');
}
else {
msg($sock, $err.'authorization failed');
@socket_shutdown($sock);
@socket_close($sock);
}
}
else {
msg($sock, $err.'USER first');
}
}
else { msg($sock, $errsyntax); }
break;
case 'list':
break;
case 'stat':
break;
case 'retr':
break;
case 'dele':
break;
case 'noop':
break;
case 'apop':
break;
case 'quit':
msg($sock, '+OK');
@socket_shutdown($sock);
@socket_close($sock);
exceptSocket(&$cSock, &$cInfo, $sock);
break;
default:
msg($sock, $err.'syntax error');
break;
}
// switch
}
// 개행 문자가 들어올때까지 받아둔다.
}
// buf 가 있을 경우
}
// 소켓이 서버 소켓이 아닐 경우
}
// foreach
}
// 이벤트가 발생한 경우
usleep(500000);
}
// while end
function msg($fd = '', $str) {
// $str = str_replace("\r\n", "", $str);
// $str = str_replace("\n", "", $str);
if ($fd)
socket_write($fd, $str . chr(13). chr(10));
else
echo $str . chr(13) . chr(10);
}
function exceptSocket(&$sockSet, &$infoSet, $sock) {
unset($sockSet[$sock]);
unset($infoSet[$sock]);
// array_merge 함수에서 erro 발생을 막기 위한 처리
if (sizeof($sockSet) == 0) {
$sockSet = array();
$infoSet = array();
}
}
function login_check($u_id, $pass) {
$connect = mysql_connect("localhost", "xxx", "xxxxx") or Die();
@mysql_select_db("db", $connect);
$query = "select passwd from member_table where user = '$u_id'";
$result = mysql_query($query, $connect);
$rowpass = mysql_result($result, 0);
mysql_close($connect);
if ($rowpass == $pass) return true;
else return false;
}
?>
/************************************************************************/
* 위 코드를 이용하여 생긴 서버 장애 및 데이터 손실은 본인에게 책임이 없음을 알려드립니다. *
* 불안하시면 직접 만들어 쓰시길 권해드립니다. *
/************************************************************************/
'인터넷관련' 카테고리의 다른 글
nuSoap을 이용한 서버간의 파일전송 (0) | 2008.02.16 |
---|---|
런타임으로 자바스크립트 화일 열기 (0) | 2008.02.16 |
마우스 오버시 테이블 한줄 색깔 바꾸기 (0) | 2008.02.16 |
간단한 php 달력 (0) | 2008.02.16 |
select 박스 제어하기 (0) | 2008.02.16 |
이미지 없이 모서리 없는 둥근 테이블 만들기 (0) | 2008.02.16 |
fsockopen으로 제작한 http확장클래스 (0) | 2008.02.16 |
HTML 4.01 엔티티(Entities) (0) | 2008.02.16 |