\n" . $extra_message;
die();
};
$work_dir = dirname(dirname(__FILE__)) . '/work/';
if (isset($_GET['r'])) {
if (base64_decode($_GET['r'],true)===false)
throw_http_error(400, 'Invalid base64');
if (!isset($_GET['t']))
throw_http_error(400, 'Repository type not given');
if (($_GET['t']!='git') &&
($_GET['t']!='hg'))
throw_http_error(501, 'Repository type not implemented');
if (!is_dir($work_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'])) {
$wish_list = fopen($work_dir . 'wish-list','a');
if ($wish_list === false)
throw_http_error(500, 'Internal Server Error' , 'Cannot open wish-list');
fwrite($wish_list, $_GET['t'] . " " . $_GET['r'] . "\n");
fclose($wish_list);
throw_http_error(503, 'Service Unavailable', 'I put repository onto wish-list');
}
if (isset($_GET['tag'])) {
if (base64_decode($_GET['tag'],true)===false)
$_GET['tag'] = base64_encode($_GET['tag']);
$commit_identifier = '$(' .
'echo "' . $_GET['tag'] . '" | ' .
'base64 -d' .
')';
} elseif (($_GET['t']=='git') && isset($_GET['commit'])) {
if (!preg_match('/^[A-Fa-f0-9]{40}$/', $_GET['commit']))
throw_http_error(400, 'The given commit does not have exactly 40 hex digits');
$commit_identifier = $_GET['commit'];
}
function expand_key($key) {
if (preg_match('/^[A-Fa-f0-9]{16}$/', $key))
return '.\{24\}' . $key;
elseif (preg_match('/^[A-Fa-f0-9]{40}$/', $key))
return $key;
else
throw_http_error(400, 'The given key does not have exactly 16 or 40 hex digits');
}
if (isset($commit_identifier)) {
if (isset($_GET['valid_keys'])) {
$key_regex = '\(' . implode(
'\|',
array_map(
'expand_key',
explode(
',',
$_GET['valid_keys']
)
)
) . '\)';
shell_exec(
'GNUPGHOME="' . $work_dir . 'gnupg" gpg ' .
'--keyserver=hkp://keys.gnupg.net ' .
'--recv-keys ' . implode(' ',explode(',',$_GET['valid_keys']))
);
if ($_GET['t']=='git') {
if (trim(shell_exec(
'GNUPGHOME="' . $work_dir . 'gnupg" git -C "' . $work_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'] . '" verify-tag --raw "' . $commit_identifier . '" 2>&1 | ' .
'grep -c "\[GNUPG:\] VALIDSIG ' . $key_regex . ' "'
)) == '0')
throw_http_error(409, 'Commit ' . $commit_identifier . ' is not signed by ' . $_GET['valid_keys']);
} else
throw_http_error(400, 'Checking signatures is not implemented for ' . $_GET['t'] . ' repositories');
}
if (isset($_GET['p'])) {
if (base64_decode($_GET['p'],true)===false)
throw_http_error(400, 'Invalid base64');
$prefix = ' --prefix="$(' .
'echo "' . $_GET['p'] . '" | ' .
'base64 -d' .
')"';
} else {
$prefix = '';
}
if ($_GET['t']=='git')
$handle = popen(
'git -C "' . $wok_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'] . '"' .
' archive' .
$prefix .
' "' . $commit_identifier . '" | ' .
'gzip -nc',
'r'
);
elseif ($_GET['t']=='hg')
$handle = popen(
'hg archive' .
' -t tgz' .
$prefix .
' -R "' . $work_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'] . '"' .
' -r "' . $commit_identifier . '"' .
' /dev/stdout',
'r'
);
else
$handle = false;
if ($handle === false)
throw_http_error(500, 'Unable to create archive');
header('Content-type: application/x-gzip');
header('Content-Disposition: attachment; filename="archive.tar.gz"');
fpassthru($handle);
pclose($handle);
die();
}
throw_http_error(501, 'Not implemented');
}
print 'Hi, this is an archive server!
' . "\n";
print 'I provide archives of these upstreams:
' . "\n";
print
implode(
"
\n",
array_map(
"base64_decode",
explode(
"\n",
shell_exec(
'find "' . $work_dir . 'repositories" -mindepth 2 -maxdepth 2 -printf "%f\n" | sort'
)
)
)
);
die();