summaryrefslogtreecommitdiffstats
path: root/apis/download.inc.php
blob: 898e34fffb9b956360d9fd4a030bfb24e7868d98 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

User::load();

if (!User::hasPermission('superadmin')) die('No permission');

require_once('inc/render.inc.php');

if (!isset($_REQUEST['file'])) die('No file');
if (!isset($_REQUEST['id'])) die('No id');
$file = preg_replace('/[^a-z0-9\.\-_]/is', '', $_REQUEST['file']);
$id = $_REQUEST['id'];

// Progress update only

if (isset($_REQUEST['progress'])) {
	$progress = preg_replace('/[^a-z0-9\-]/', '', $_REQUEST['progress']);
	$pid = (isset($_REQUEST['pid']) ? (int)$_REQUEST['pid'] : 0);
	$log = '/tmp/' . $progress . '.log';
	if (!file_exists($log)) {
		echo Render::parse('download-error', array('file' => $file));
		exit(0);
	}
	$error = false;
	$percent = 0;
	$fh = fopen($log, 'r');
	while (!feof($fh)) {
		$line = fgets($fh);
		if (preg_match('/ ERROR (\d{3}):/', $line, $out)) {
			$error = $out[1];
			break;
		}
		if (preg_match('/ (\d+)% /', $line, $out)) {
			$percent = $out[1];
		}
	}
	fclose($fh);
	if ($error === false && $pid > 0 && $percent != 100 && !posix_kill($pid, 0)) $error = "Process $pid died - " . file_get_contents($log);
	if ($error !== false) {
		echo Render::parse('download-error', array('file' => $file, 'code' => $error));
		unlink($log);
		exit(0);
	}
	if ($percent == 100) {
		echo Render::parse('download-complete' ,array('file' => $file));
		unlink($log);
	} else {
		echo Render::parse('download-progress' ,array('file' => $file, 'progress' => $progress, 'id' => $id, 'percent' => $percent, 'pid' => $pid));
	}
	exit(0);
}

// Actual download request

if (!isset($_REQUEST['type'])) die('No type');


$type = $_REQUEST['type'];
$directExec = true;
$overwrite = isset($_REQUEST['exec']);

switch ($type) {
case 'tgz':
	$remote = CONFIG_REMOTE_TGZ;
	$local = CONFIG_TGZ_LIST_DIR;
	break;
case 'ml':
	$remote = CONFIG_REMOTE_ML;
	$local = CONFIG_HTTP_DIR . '/default';
	$directExec = false;
	$overwrite = true;
	break;
default:
	die('Invalid download type');
}
@mkdir($local, 0755, true);

if (file_exists($local . '/' . $file) && !$overwrite) {
	echo Render::parse('download-overwrite', array('file' => $file, 'id' => $id, 'query' => $_SERVER['REQUEST_URI']));
	exit(0);
}

if (file_exists($local . '/' . $file) && !is_writable($local . '/' . $file)) {
		echo Render::parse('download-error', array('file' => $local . '/' . $file, 'remote' => $remote, 'code' => 'Local file is not writable'));
		exit(0);
}

if ($directExec) {
	// Blocking inline download
	$ret = Util::downloadToFile($local . '/' . $file, $remote . '/' . $file, 20, $code);
	if ($ret === false || $code < 200 || $code >= 300) {
		@unlink($local . '/' . $file);
		echo Render::parse('download-error', array('file' => $file, 'remote' => $remote, 'code' => $code));
		exit(0);
	}
	
	// No execution - just return dialog
	echo Render::parse('download-complete', array('file' => $file));
} else {
	// Use WGET
	$logfile = 'slx-' . mt_rand() . '-' . time();
	exec("wget --timeout=10 -O $local/$file -o /tmp/${logfile}.log -b $remote/$file", $retstr, $retval);
	unlink("$local/${file}.md5");
	if ($retval != 0) {
		echo Render::parse('download-error', array('file' => $destination, 'remote' => $source, 'code' => implode(' // ', $retstr) . ' - ' . $retval));
		exit(0);
	}
	$pid = 0;
	foreach ($retstr as $line) if (preg_match('/ (\d+)([,\.\!\:]|$)/', $line, $out)) $pid = $out[1];
	file_put_contents("$local/${file}.lck", $pid . ' ' . $logfile);
	echo Render::parse('download-progress', array('file' => $file, 'progress' => $logfile, 'id' => $id, 'percent' => '0', 'pid' => $pid));
}