View file fmget-server/loader.php

File size: 7.5Kb
<?php
# FMGET ver. 1.1
# © Alex Extend, 2008
# 
# Данная программа является свободным программным обеспечением. Вы вправе
# распространять ее и/или модифицировать в соответствии с условиями версии 2 либо
# по вашему выбору с условиями более поздней версии Стандартной Общественной
# Лицензии GNU, опубликованной Free Software Foundation.
# 
# Мы распространяем данную программу в надежде на то, что она будет вам полезной
# однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ, в том числе ГАРАНТИИ ТОВАРНОГО
# СОСТОЯНИЯ ПРИ ПРОДАЖЕ и ПРИГОДНОСТИ ДЛЯ ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ. Для
# получения более подробной информации ознакомьтесь со Стандартной Общественной
# Лицензией GNU.

// обработчик файлов (загрузка, отправка). Запускается из req.php
@set_time_limit(0);
ini_set('max_execution_time', 0);
include ('conf.php');
include ('class.phpmailer.php');
$inloader=true;

if (empty($_GET['email']) or empty($_GET['rid'])) exit;
// email получателя
$email=$_GET['email'];
// ид запроса
$rid=$_GET['rid'];
// ид сессии
$sid=$_GET['sid'];
// список пользователей
$users=unserialize(file_get_contents('users.txt'));
if ($users[$email]['rid']!=$rid) perror("bad rid $rid for user $email");
// проверка sid. Необходима, чтобы избежать запуск нескольких обработчиков
if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) perror("bad sid $sid for user $email");
plog("starting loader for user $email rid $rid sid $sid");
$smtphost=$users[$email]['smtphost'];
$smtplogin=$users[$email]['smtplogin'];
$smtppass=$users[$email]['smtppass'];

// основной цикл
while(1) {
	// заргузка информации о файле
	$info=unserialize(file_get_contents("$basedir/users/$email/info.txt"));
	extract($info);
	// номер части, с которой начинать загрузку
	$lstart=-1;
	// количество частей, сохраненных на сервере и ожидающих отправки
	$scount=0;
	// максимально допустимое количество частей для хранения на сервере
	$fpartcount=round($fusersize/$partsize);
	
	foreach ($parts as $pinfo) {
		if (($pinfo['status']=='no') and ($lstart==-1)) $lstart=$pinfo['num'];
		if (($pinfo['status']=='wait') or ($pinfo['status']=='sended')) $scount++;
	}
	
	// оприделяем количество частей, которые будут загружены за этот вызов
	if ($lstart==-1) {
		$acount=-1;
	} else {
		$acount=$fpartcount-$scount;
	}
	
	// позиция начала первой части
	$rstart=@$parts[$lstart]['n1'];
	// формировка запроса и подключение к серверу
	preg_match('|^http://([a-z0-9\.\-]+)(/.+)$|i', $url, $m);
	$host=$m[1];
	$uri=$m[2];
	$r="GET $uri HTTP/1.1\r\n";
	$r.="Host: $host\r\n";
	$r.="Range: bytes=$rstart-\r\n";
	$r.="Connection: close\r\n\r\n";
	
	$s=fsockopen($host, 80, $errno, $errstr);
	if (!$s) perror("$errno $errstr url $url");
	fwrite($s, $r);
	// чтение заголовков
	$h="";
	
	while (!strstr($h, "\r\n\r\n")) $h.=fread($s, 1);
	
	// цикл загрузки
	for ($num=$lstart; $num<$acount+$lstart; $num++) {
		$info=unserialize(file_get_contents("$basedir/users/$email/info.txt"));
		extract($info);
		if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
		// записываем статус обработчика
		$info['loaderstatus']='load';
		$info['loadnum']=$num;
		file_put_contents("$basedir/users/$email/info.txt", serialize($info));
		if (empty($parts[$num])) {
			plog("download finished. total parts $num $url");
			break;
		}
		
		// чтение из сокета в будер
		$buf="";
		for ($i=0; $i<$parts[$num]['psize']; $i++) {
			$buf.=fread($s, 1);
		}
		if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
		// запись в файл
		file_put_contents("$basedir/users/$email/$num.part", $buf);
		unset($buf);
		// проверка размера
		$testsize=filesize("$basedir/users/$email/$num.part");
		if ($testsize!=$parts[$num]['psize']) perror("size $num $testsize");
		// расчет md5
		$md5=md5_file("$basedir/users/$email/$num.part");
		$parts[$num]['status']='wait';
		$parts[$num]['md5']=$md5;
		$info['parts']=$parts;
		// запись информации о файле
		file_put_contents("$basedir/users/$email/info.txt", serialize($info));
	}
	fclose($s);
	
	// цикл отправки
	while(1) {
		// записываем статус обработчика
		if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
		$info['loaderstatus']='send';
		$info['loadnum']=0;
		file_put_contents("$basedir/users/$email/info.txt", serialize($info));
		$info=unserialize(file_get_contents("$basedir/users/$email/info.txt"));
		extract($info);
		// определяем номер части, с которого начинать отправку
		$num=-1;
		foreach ($parts as $pinfo) {
			if ($pinfo['status']=='wait') {
				$num=$pinfo['num'];
				break;
			}
		}
		
		if ($num==-1) break;
		
		// инициализация PHPMailer, упаковка файла и отправка
		$mail=new PHPMailer();
		$mail->IsSMTP();
		$mail->Host=$smtphost;
		if (!empty($smtplogin)) {
			$mail->SMTPAuth=true;
			$mail->Username=$smtplogin;
			$mail->Password=$smtppass;
		}
		$mail->From=$fromemail;
		$mail->FromName=$fromname;
		$mail->Subject="fmail request $num $rid $filename";
		$mail->Body="fmail:begin\r\n\r\n".base64_encode(file_get_contents("$basedir/users/$email/$num.part"))."\r\n\r\nfmail:end\nmd5: ".$parts[$num]['md5'];
		$mail->AddAddress($email, "Viktor Andreev");
		if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
		
		if(!$mail->Send()) {
			perror("Mailer Error: " . $mail->ErrorInfo);
		}
		plog("sended $num $rid $filename to $email");
		unset($mail);
		
		// установка статуса части sended
		$parts[$num]['status']='sended';
		$info['parts']=$parts;
		file_put_contents("$basedir/users/$email/info.txt", serialize($info));
		
		// ожидание принятия части клиентом
		$etime=time()+1200;
		while ($parts[$num]['status']=='sended') {
			if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
			if (time()>$etime) perror("loader sid $sid $email timeout");
			sleep(2);
			$info=unserialize(file_get_contents("$basedir/users/$email/info.txt"));
			extract($info);
		}
		if ($sid!=file_get_contents("$basedir/users/$email/sid.txt")) {plog("loader sid $sid $email terminated");exit;}
		if ($num==count($parts)-1) {
			plog("sended finished $url");
			exit;
		}
	}
}
?>