309 lines
11 KiB
PHP
309 lines
11 KiB
PHP
|
<?php
|
||
|
/*
|
||
|
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
|
||
|
* create un archive for a set of file or update file deadline
|
||
|
|
||
|
a.php?u=month&h=HHHHHHHH => deadline
|
||
|
a.php?g=l~k => zip
|
||
|
a.php?s=mel@domain.org => send status e-mail
|
||
|
*/
|
||
|
|
||
|
|
||
|
define('JIRAFEAU_ROOT', dirname(__FILE__) . '/');
|
||
|
|
||
|
require(JIRAFEAU_ROOT . 'lib/settings.php');
|
||
|
require(JIRAFEAU_ROOT . 'lib/functions.php');
|
||
|
require(JIRAFEAU_ROOT . 'lib/lang.php');
|
||
|
|
||
|
/* Operations may take a long time.
|
||
|
* Be sure PHP's safe mode is off.
|
||
|
*/
|
||
|
@set_time_limit (0);
|
||
|
/* Remove errors. */
|
||
|
@error_reporting (0);
|
||
|
|
||
|
$do_update = false;
|
||
|
if (isset ($_REQUEST['u']) && !empty ($_REQUEST['u'])) {
|
||
|
$do_update = true;
|
||
|
}
|
||
|
|
||
|
$do_download = false;
|
||
|
if (isset ($_REQUEST['g']) && !empty ($_REQUEST['g'])) {
|
||
|
$do_download = true;
|
||
|
}
|
||
|
|
||
|
// ========================================
|
||
|
function return_error ($msg) {
|
||
|
require (JIRAFEAU_ROOT.'lib/template/header.php');
|
||
|
echo '<div class="error"><p>' . $msg . '</p></div>';
|
||
|
require (JIRAFEAU_ROOT.'lib/template/footer.php');
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
// ========================================
|
||
|
/** Update link
|
||
|
* @param $link the link's name (hash)
|
||
|
* @param $update_period the periode (i.e in : "month")
|
||
|
*/
|
||
|
function jirafeau_update_link ($link_name, $link, $update_period) {
|
||
|
$time_max = $link ['time'];
|
||
|
$time_up = time () + $update_period;
|
||
|
$time_more = $time_up + JIRAFEAU_HOUR;
|
||
|
if ($time_max < 0 || $time_up < $time_max)
|
||
|
return $time_max;
|
||
|
$link ['time'] = $time_more;
|
||
|
$link_tmp_name = VAR_LINKS . $link['hash'] . rand (0, 10000) . '.tmp';
|
||
|
$handle = fopen ($link_tmp_name, 'w');
|
||
|
fwrite ($handle,
|
||
|
$link['file_name'] .NL. $link['mime_type'] .NL. $link['file_size'] .NL. $link['key'] .NL. $link['time'] .NL.
|
||
|
$link['hash'] .NL. $link['onetime'] .' '.JIRAFEAU_MONTH . ' '. JIRAFEAU_DAY .NL. $link['upload_date'] .NL.
|
||
|
$link['ip'] .NL. $link['link_code'] .NL. $link['crypted']);
|
||
|
fclose ($handle);
|
||
|
$link_file = VAR_LINKS . s2p("$link_name") . $link_name;
|
||
|
rename ($link_tmp_name, $link_file);
|
||
|
return $time_more;
|
||
|
}
|
||
|
|
||
|
// ========================================
|
||
|
function read_archive_info ($link) {
|
||
|
$p = s2p ($link ['hash']);
|
||
|
// read archive info
|
||
|
$result=[];
|
||
|
foreach (file (VAR_FILES . $p . $link['hash']) as $line) {
|
||
|
switch (true) {
|
||
|
case preg_match ("/^\s*src:\s*(([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6})\s*$/i", $line, $matches):
|
||
|
$result['sender'] = $matches[1];
|
||
|
break;
|
||
|
case preg_match ("/^\s*time:\s*(\d{4}([:-]\d{2}){5})\s*$/i", $line, $matches):
|
||
|
$result['timestamp'] = $matches[1];
|
||
|
break;
|
||
|
case preg_match ("/^\s*old:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches):
|
||
|
$result['old'][] = [$matches[1], $matches[2]];
|
||
|
break;
|
||
|
case preg_match ("/^\s*new:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches):
|
||
|
$result['new'][] = [$matches[1], $matches[2]];
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ========================================
|
||
|
if ($do_update) {
|
||
|
$update_period = JIRAFEAU_MONTH;
|
||
|
switch ($_REQUEST['u']) {
|
||
|
case 'minute':
|
||
|
$update_period = JIRAFEAU_MINUTE;
|
||
|
break;
|
||
|
case 'hour':
|
||
|
$update_period = JIRAFEAU_HOUR;
|
||
|
break;
|
||
|
case 'day':
|
||
|
$update_period = JIRAFEAU_DAY;
|
||
|
break;
|
||
|
case 'week':
|
||
|
$update_period = JIRAFEAU_WEEK;
|
||
|
break;
|
||
|
case 'month':
|
||
|
$update_period = JIRAFEAU_MONTH;
|
||
|
break;
|
||
|
case 'quarter':
|
||
|
$update_period = JIRAFEAU_QUARTER;
|
||
|
break;
|
||
|
case 'year':
|
||
|
$update_period = JIRAFEAU_YEAR;
|
||
|
break;
|
||
|
default:
|
||
|
return_error (t('ERR_OCC') . ' (update_period)');
|
||
|
}
|
||
|
$link_name = $_GET['h'];
|
||
|
if (!preg_match('/[0-9a-zA-Z_-]+$/', $link_name))
|
||
|
return_error (t('FILE_404'));
|
||
|
$link = jirafeau_get_link($link_name);
|
||
|
if (count($link) == 0)
|
||
|
return_error (t('FILE_404'));
|
||
|
$time = jirafeau_update_link($link_name, $link, $update_period);
|
||
|
$content = '' . $time . NL;
|
||
|
header('HTTP/1.0 200 OK');
|
||
|
header('Content-Length: ' . strlen ($content));
|
||
|
header('Content-Type: text/plain');
|
||
|
echo $content;
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
// ========================================
|
||
|
if ($do_download) {
|
||
|
// check archive exist
|
||
|
$couple = explode ("~", $_REQUEST['g'], 2);
|
||
|
if (count ($couple) == 0)
|
||
|
return_error ("bad archive name format : ".$_REQUEST['g']);
|
||
|
$link_name = $couple [0];
|
||
|
if (!$link_name || !preg_match ('/[0-9a-zA-Z_-]+$/', $link_name))
|
||
|
return_error ("bad archive name format : ".$_REQUEST['g']);
|
||
|
$crypt_key = count ($couple) == 2 ? $couple [1] : "";
|
||
|
$link = jirafeau_get_link ($link_name);
|
||
|
if (count ($link) == 0)
|
||
|
return_error (t ('FILE_404'));
|
||
|
$key = $link['key'];
|
||
|
if ($key && (empty ($crypt_key) || $key != $crypt_key))
|
||
|
return_error (t ('BAD_PSW'));
|
||
|
|
||
|
$archive_info = read_archive_info ($link);
|
||
|
|
||
|
// check entries
|
||
|
$archive_content = [];
|
||
|
$modif = false;
|
||
|
foreach (["old", "new"] as $cat) {
|
||
|
$single_name = [];
|
||
|
if (isset ($archive_info[$cat]))
|
||
|
foreach ($archive_info[$cat] as [$link_name, $crypt_key]) {
|
||
|
$link = jirafeau_get_link ($link_name);
|
||
|
if (count ($link) == 0) {
|
||
|
++$archive_content[$cat]['not_found'];
|
||
|
$modif = true;
|
||
|
continue;
|
||
|
}
|
||
|
$key = $link['key'];
|
||
|
if ($key && (empty ($crypt_key) || $key != $crypt_key)) {
|
||
|
++$archive_content[$cat]['bad_pass'];
|
||
|
$modif = true;
|
||
|
continue;
|
||
|
}
|
||
|
$src_name = $dst_name = $link['file_name'];
|
||
|
if (in_array ($src_name, $single_name))
|
||
|
for ($i = 0; $i < 10000; ++$i) {
|
||
|
$dst_name = sprintf ("%s-%2d", $src_name, $i);
|
||
|
if (!in_array ($dst_name, $single_name)) {
|
||
|
++$archive_content[$cat]['rename'];
|
||
|
$modif = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
$single_name [] = $dst_name;
|
||
|
$archive_content[$cat]['entries'][] = ['hash' => $link['hash'], 'file_name' => $dst_name, 'crypt_key' => $crypt_key, 'crypted' => $link['crypted']];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// build zip
|
||
|
$dirname = (isset ($archive_info['sender']) && !empty ($archive_info['sender']))
|
||
|
? $archive_info['sender'] : "kaz";
|
||
|
$dirname .= "-" . (isset ($archive_info['timestamp']) && !empty ($archive_info['timestamp']))
|
||
|
? $archive_info['timestamp'] : date ("Ymd-His");
|
||
|
$tmpFileName = tempnam (sys_get_temp_dir (), $dirname."-");
|
||
|
$zip = new ZipArchive;
|
||
|
if (!$zip)
|
||
|
return_error ("can't create zip");
|
||
|
if ($zip->open ($tmpFileName.".zip", ZipArchive::CREATE) !== TRUE)
|
||
|
return_error ("can't open zip");
|
||
|
|
||
|
// create info XXX
|
||
|
if ($modif) {
|
||
|
$info = '';
|
||
|
$not_found = $bad_pass = $rename = 0;
|
||
|
foreach (["old", "new"] as $cat) {
|
||
|
if (isset ($archive_info[$cat]['not_found']))
|
||
|
$not_found += $archive_info[$cat]['not_found'];
|
||
|
if (isset ($archive_info[$cat]['bad_pass']))
|
||
|
$bad_pass += $archive_info[$cat]['bad_pass'];
|
||
|
if (isset ($archive_info[$cat]['rename']))
|
||
|
$rename += $archive_info[$cat]['rename'];
|
||
|
}
|
||
|
if ($not_found)
|
||
|
$info .= $not_found. ($not_found ? " fichier est expiré." : " fichiers sont expirés.").NL;
|
||
|
if ($bad_pass)
|
||
|
$info .= "Mauvaise clef pour ". $bad_pass. ($bad_pass ? " fichier" : " fichiers.").NL;
|
||
|
if ($rename)
|
||
|
$info .= $rename. ($rename ? " fichier renommé." : " fichiers sont renommés.").NL;
|
||
|
$zip->addFromString ($dirname."-Avertissement.txt", $info);
|
||
|
}
|
||
|
foreach (["old", "new"] as $cat)
|
||
|
if (isset ($archive_info [$cat])) {
|
||
|
$subdir = $dirname . ($cat == "new" ? "" : "/origine");
|
||
|
foreach ($archive_content [$cat]['entries'] as $entry) {
|
||
|
$p = s2p ($entry ['hash']);
|
||
|
if ($entry['crypted']) {
|
||
|
$m = mcrypt_module_open ('rijndael-256', '', 'ofb', '');
|
||
|
$md5_key = md5 ($entry['crypt_key']);
|
||
|
$iv = jirafeau_crypt_create_iv ($md5_key, mcrypt_enc_get_iv_size ($m));
|
||
|
mcrypt_generic_init ($m, $md5_key, $iv);
|
||
|
$r = fopen (VAR_FILES . $p . $entry['hash'], 'r');
|
||
|
$content = "";
|
||
|
while (!feof ($r)) {
|
||
|
$dec = mdecrypt_generic ($m, fread ($r, 1024));
|
||
|
$content .= $dec;
|
||
|
ob_flush ();
|
||
|
}
|
||
|
fclose ($r);
|
||
|
$zip->addFromString ($subdir."/".$entry['file_name'], $content);
|
||
|
mcrypt_generic_deinit ($m);
|
||
|
mcrypt_module_close ($m);
|
||
|
continue;
|
||
|
}
|
||
|
$zip->addFile (VAR_FILES.$p.$entry['hash'], $subdir."/".$entry['file_name']);
|
||
|
}
|
||
|
}
|
||
|
$zip->close ();
|
||
|
|
||
|
|
||
|
if (!is_file ($tmpFileName.".zip"))
|
||
|
return_error ("can't retreive tmp");
|
||
|
|
||
|
if (false) {
|
||
|
// log
|
||
|
$content = print_r ($archive_info, 1);
|
||
|
$content .= print_r ($archive_content, 1);
|
||
|
|
||
|
header('HTTP/1.0 200 OK');
|
||
|
header('Content-Length: ' . strlen ($content));
|
||
|
header('Content-Type: text/plain');
|
||
|
echo $content;
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
header ("Content-Type: application/zip");
|
||
|
header ('Content-Disposition: filename="'.$dirname.'.zip"');
|
||
|
$r = fopen($tmpFileName.".zip", 'r');
|
||
|
while (!feof ($r)) {
|
||
|
print fread ($r, 1024);
|
||
|
ob_flush ();
|
||
|
}
|
||
|
fclose ($r);
|
||
|
|
||
|
unlink ($tmpFileName.".zip");
|
||
|
unlink ($tmpFileName);
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
// ========================================
|
||
|
// XXX form send
|
||
|
$content = "TODO send form".NL;
|
||
|
|
||
|
if (isset ($_REQUEST['s']) && !empty ($_REQUEST['s'])) {
|
||
|
$sender=$_REQUEST ['s'];
|
||
|
if (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $sender))
|
||
|
return_error ("bad dir name format : ".$sender);
|
||
|
|
||
|
$content = "${sender}".NL;
|
||
|
}
|
||
|
|
||
|
|
||
|
// XXX find
|
||
|
// add link : name / time / download / delete
|
||
|
// sort by name ?
|
||
|
|
||
|
// $tmpFileName = tempnam (sys_get_temp_dir (), $dirname."-");
|
||
|
// $fd = fopen ($tmpFileName, "w");
|
||
|
// if (!$fd)
|
||
|
// return_error ("Unable to open tmp file!");
|
||
|
// fwrite ($fd, $content);
|
||
|
// fclose ($fd);
|
||
|
|
||
|
header('HTTP/1.0 200 OK');
|
||
|
header('Content-Length: ' . strlen ($content));
|
||
|
header('Content-Type: text/plain');
|
||
|
echo $content;
|
||
|
?>
|