Removed outdated files which are now kept in Mercurial repository for CTDB server
@@ -1,8 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
<body>disc not present in database
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php include 'logo_start.php'; ?>
|
||||
<h2>What's it for?</h2>
|
||||
You probably heard about <a href=http://www.accuraterip.com/>AccurateRip</a>, a wonderfull database of CD rip checksums, which helps you make sure your CD rip is an exact copy of original CD. What it can tell you is how many other people got the same data when copying this CD.
|
||||
|
||||
CUETools Database is an extension of this idea.
|
||||
|
||||
<h2>What are the advantages?</h2>
|
||||
<ul>
|
||||
<li>The most important feature is the ability not only to detect, but also correct small amounts of errors that occured in the ripping process.
|
||||
<li>It's free of the offset problems. You don't even need to set up offset correction for your CD drive to be able to verify and what's more important, submit rips to the database. Different pressings of the same CD are treated as the same disc by the database, it doesn't care.
|
||||
<li>Verification results are easier to deal with. There are exactly three possible outcomes: rip is correct, rip contains correctable errors, rip is unknown (or contains errors beyond repair).
|
||||
<li>If there's a match, you can be certain it's really a match, because in addition to recovery record database uses a well-known CRC32 checksum of the whole CD image (except for 10*588 offset samples in the first and last seconds of the disc). This checksum is used as a rip ID in CTDB.
|
||||
</ul>
|
||||
<h2>What are the downsides and limitations?</h2>
|
||||
<ul>
|
||||
<li>CUETools DB doesn't bother with tracks. Your rip as a whole is either good/correctable, or it isn't. If one of the tracks is damaged beyound repair, CTDB cannot tell which one.
|
||||
<li>If your rip contains errors, verification/correction process will involve downloading about 200kb of data, which is much more than it takes for AccurateRp.
|
||||
<li>Verification process is slower than with AR.
|
||||
<li>Database was just born and at the moment contains much less CDs than AR.
|
||||
</ul>
|
||||
<h2>How many errors can a rip contain and still be repairable?</h2>
|
||||
<ul>
|
||||
<li>That depends. The best case scenario is when there's one continuous damaged area up to 30-40 sectors (about half a second) long.
|
||||
<li>The worst case scenario is 4 non-continuous damaged sectors in (very) unlucky positions.
|
||||
</ul>
|
||||
<h2>What information does the database contain per each submission?</h2>
|
||||
<ul>
|
||||
<li>CD TOC (Table Of Contents), i.e. length of every track.
|
||||
<li>Offset-finding checksum, i.e. small (16 byte) recovery record for a set of samples throughout the CD, which allows to detect the offset difference between the rip in database and your rip, even if your rip contains some errors.
|
||||
<li>CRC32 of the whole disc (except for some leadin/leadout samples).
|
||||
<li>Submission date, artist, title.
|
||||
<li>180kb recovery record, which is stored separately and accessed only when verifying a broken rip or repairing it.
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 293 B |
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
include 'logo_start.php';
|
||||
require_once( 'phpmb/mbQuery.php' );
|
||||
require_once( 'phpctdb/ctdb.php' );
|
||||
|
||||
//$dbconn = pg_connect("dbname=ctdb user=ctdb_user")
|
||||
// or die('Could not connect: ' . pg_last_error());
|
||||
|
||||
$count = 20;
|
||||
$query = 'SELECT * FROM submissions';
|
||||
$term = ' WHERE ';
|
||||
$url = '';
|
||||
$where_discid=@$_GET['discid'];
|
||||
if ($where_discid != '')
|
||||
{
|
||||
$query = $query . $term . "discid='" . pg_escape_string($where_discid) . "'";
|
||||
$term = ' AND ';
|
||||
$url = $url . '&discid=' . urlencode($where_discid);
|
||||
}
|
||||
$where_artist=@$_GET['artist'];
|
||||
if ($where_artist != '')
|
||||
{
|
||||
$query = $query . $term . "artist ilike '%" . pg_escape_string($where_artist) . "%'";
|
||||
$term = ' AND ';
|
||||
$url = $url . '&artist=' . urlencode($where_artist);
|
||||
}
|
||||
$where_uid=@$_GET['uid'];
|
||||
if ($where_uid != '')
|
||||
{
|
||||
$query = $query . $term . "userid='" . pg_escape_string($where_uid) . "'";
|
||||
$term = ' AND ';
|
||||
$url = $url . '&uid=' . urlencode($where_uid);
|
||||
}
|
||||
$query = $query . " ORDER BY id";
|
||||
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
|
||||
$start = @$_GET['start'];
|
||||
if (pg_num_rows($result) == 0)
|
||||
die('nothing found');
|
||||
if ($count > pg_num_rows($result))
|
||||
$count = pg_num_rows($result);
|
||||
if ($start == '') $start = pg_num_rows($result) - $count;
|
||||
|
||||
printf("<center><h3>Recent additions:</h3>");
|
||||
include 'list.php';
|
||||
pg_free_result($result);
|
||||
printf("</center>");
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
include 'table_start.php';
|
||||
?>
|
||||
<table class=classy_table cellpadding=3 cellspacing=0><tr bgcolor=#D0D0D0><th>Artist</th><th>Album</th><th>Disc Id</th><th>CTDB Id</th><th>AR</th></tr>
|
||||
<?php
|
||||
for($i = $start + $count - 1; $i >= $start; $i--) {
|
||||
$record = pg_fetch_array($result, $i);
|
||||
printf('<tr><td class=td_artist><a href=?artist=%s>%s</a></td><td class=td_album>%s</td><td class=td_discid><a href="?discid=%s">%s</a></td><td class=td_ctdbid><a href=show.php?discid=%s&ctdbid=%08x>%08x</a></td><td class=td_ar>%d</td></tr>', urlencode($record['artist']), $record['artist'], $record['title'], $record['discid'], $record['discid'], $record['discid'], $record['ctdbid'], $record['ctdbid'], $record['confidence']);
|
||||
}
|
||||
if ($start > 0) printf('<tr><td colspan=5 align=right><a class=style1 href="?start=%d%s">More</a></td></tr>', $count * floor(($start - 1) / $count), $url);
|
||||
printf("</table>");
|
||||
include 'table_end.php' ;
|
||||
?>
|
||||
@@ -1,81 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CUETools DB</title>
|
||||
<style type="text/css">
|
||||
.style1 {
|
||||
font-size: x-small;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.style_fixed {
|
||||
#font-size: x-small;
|
||||
font-family: Courier;
|
||||
}
|
||||
.style_logo {
|
||||
font-size: x-large;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.td_status {
|
||||
font-size: x-small;
|
||||
text-align: center;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.td_artist {
|
||||
padding: 1px 10px;
|
||||
}
|
||||
.td_album {
|
||||
padding: 1px 10px;
|
||||
}
|
||||
.td_discid {
|
||||
padding: 1px 5px;
|
||||
font-family: Courier;
|
||||
}
|
||||
.td_ctdbid {
|
||||
padding: 1px 5px;
|
||||
font-family: Courier;
|
||||
}
|
||||
.td_ar {
|
||||
padding: 1px 5px;
|
||||
text-align: right;
|
||||
font-family: Courier;
|
||||
}
|
||||
.classy_table {
|
||||
border-style:none;
|
||||
# border-color-right: #D0D0D0
|
||||
# border-color-left: #D0D0D0
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table border=0 cellspacing=0 cellpadding=3 align=center>
|
||||
<tr>
|
||||
<td rowspan=3><img width=128 height=128 border=0 alt="" src=ctdb.png></td>
|
||||
<td class=td_status>
|
||||
<?php
|
||||
$dbconn = pg_connect("dbname=ctdb user=ctdb_user")
|
||||
or die('Could not connect: ' . pg_last_error());
|
||||
$dbresult = pg_query('SELECT * FROM submissions');
|
||||
printf("%d unique discs", pg_num_rows($dbresult));
|
||||
pg_free_result($dbresult);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr align=center height=34%>
|
||||
<td class=style_logo>CUETools Database</td>
|
||||
</tr>
|
||||
<tr align=center height=33%>
|
||||
<td>
|
||||
<?php include 'table_start.php'; ?>
|
||||
<table width=300 border=0 cellspacing=8 cellpadding=0 align=center>
|
||||
<tr align=center>
|
||||
<td><a href=/>Home</a></td>
|
||||
<td><a href=/top.php>Popular</a></td>
|
||||
<td><a href=/about.php>About</a></td>
|
||||
<td><a href=http://www.cuetools.net>CUETools</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php include 'table_end.php'; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br clear=all>
|
||||
@@ -1,370 +0,0 @@
|
||||
<?php
|
||||
|
||||
class phpCTDB{
|
||||
|
||||
private $fp;
|
||||
private $fpstats;
|
||||
private $atoms;
|
||||
public $db;
|
||||
public $fulltoc;
|
||||
|
||||
function __construct($target_file) {
|
||||
$this->fp = fopen($target_file, 'rb');
|
||||
$this->fpstats = fstat($this->fp);
|
||||
$this->atoms = $this->parse_container_atom(0, $this->fpstats['size']);
|
||||
$this->db = false;
|
||||
foreach ($this->atoms as $entry) if($entry['name'] == 'CTDB') $this->db = $entry;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
fclose($this->fp);
|
||||
}
|
||||
|
||||
function ParseTOC()
|
||||
{
|
||||
$disc = $this->db['discs'][0];
|
||||
$this->fulltoc = '';
|
||||
$totalcount = 0;
|
||||
$firstaudio = 0;
|
||||
$lastaudio = 0;
|
||||
foreach ($disc['TOC ']['subatoms'] as $track)
|
||||
{
|
||||
if ($track['name']=='INFO') {
|
||||
$trackcount = phpCTDB::BigEndian2Int(substr($track['value'],0,4));
|
||||
$pregap = phpCTDB::BigEndian2Int(substr($track['value'],4,4));
|
||||
$pos = $pregap + 150;
|
||||
}
|
||||
if ($track['name']=='TRAK') {
|
||||
$isaudio = phpCTDB::BigEndian2Int(substr($track['value'],0,4));
|
||||
$length = phpCTDB::BigEndian2Int(substr($track['value'],4,4));
|
||||
if ($isaudio == 0 && $totalcount!=0)
|
||||
$pos += 11400;
|
||||
$this->fulltoc = sprintf('%s %d', $this->fulltoc, $pos);
|
||||
$pos += $length;
|
||||
$totalcount ++;
|
||||
if ($isaudio != 0)
|
||||
$lastaudio = $totalcount;
|
||||
if ($isaudio != 0 && $firstaudio == 0)
|
||||
$firstaudio = $totalcount;
|
||||
}
|
||||
}
|
||||
if ($trackcount != $totalcount)
|
||||
die('wrong trackcount');
|
||||
$this->fulltoc = sprintf('%d %d %d %d%s', $firstaudio, $lastaudio, $totalcount, $pos, $this->fulltoc);
|
||||
}
|
||||
|
||||
static function toc2mbtoc($fulltoc)
|
||||
{
|
||||
$ids = explode(' ', $fulltoc);
|
||||
$mbtoc = sprintf('%d %d', $ids[0], $ids[1]);
|
||||
if ($ids[1] == $ids[2])
|
||||
{
|
||||
for ($tr = 3; $tr < count($ids); $tr++)
|
||||
$mbtoc = sprintf('%s %d', $mbtoc, $ids[$tr]);
|
||||
} else // Enhanced CD
|
||||
{
|
||||
$mbtoc = sprintf('%s %d', $mbtoc, $ids[$ids[1] + 4] - 11400);
|
||||
for ($tr = 4; $tr < $ids[1] + 4; $tr++)
|
||||
$mbtoc = sprintf('%s %d', $mbtoc, $ids[$tr]);
|
||||
}
|
||||
return $mbtoc;
|
||||
}
|
||||
|
||||
static function toc2mbid($fulltoc)
|
||||
{
|
||||
$ids = explode(' ', $fulltoc);
|
||||
$mbtoc = sprintf('%02X%02X', $ids[0], $ids[1]);
|
||||
if ($ids[1] == $ids[2])
|
||||
{
|
||||
for ($tr = 3; $tr < count($ids); $tr++)
|
||||
$mbtoc = sprintf('%s%08X', $mbtoc, $ids[$tr]);
|
||||
} else // Enhanced CD
|
||||
{
|
||||
$mbtoc = sprintf('%s%08X', $mbtoc, $ids[$ids[1] + 4] - 11400);
|
||||
for ($tr = 4; $tr < $ids[1] + 4; $tr++)
|
||||
$mbtoc = sprintf('%s%08X', $mbtoc, $ids[$tr]);
|
||||
}
|
||||
// echo $fulltoc . ':' . $mbtoc . '<br>';
|
||||
$mbtoc = str_pad($mbtoc,804,'0');
|
||||
$mbid = str_replace('+', '.', str_replace('/', '_', str_replace('=', '-', base64_encode(pack("H*" , sha1($mbtoc))))));
|
||||
return $mbid;
|
||||
}
|
||||
|
||||
static function mblookup($mbid)
|
||||
{
|
||||
$mbconn = pg_connect("dbname=musicbrainz_db user=musicbrainz_user");
|
||||
if (!$mbconn)
|
||||
return false;
|
||||
$mbresult = pg_query_params('SELECT DISTINCT album'
|
||||
. ' FROM album_cdtoc, cdtoc'
|
||||
. ' WHERE album_cdtoc.cdtoc = cdtoc.id'
|
||||
. ' AND cdtoc.discid = $1',
|
||||
array($mbid)
|
||||
);
|
||||
$mbmeta = false;
|
||||
while(true == ($mbrecord = pg_fetch_array($mbresult)))
|
||||
{
|
||||
$mbresult2 = pg_query_params('SELECT a.name as albumname, ar.name as artistname, coverarturl'
|
||||
. ' FROM album a INNER JOIN albummeta m ON m.id = a.id, artist ar'
|
||||
. ' WHERE a.id = $1'
|
||||
. ' AND ar.id = a.artist',
|
||||
array($mbrecord[0]));
|
||||
$mbmeta[] = pg_fetch_array($mbresult2);
|
||||
pg_free_result($mbresult2);
|
||||
}
|
||||
pg_free_result($mbresult);
|
||||
return $mbmeta;
|
||||
}
|
||||
|
||||
function ctdb2pg($discid)
|
||||
{
|
||||
$disc = $this->db['discs'][0];
|
||||
$record = false;
|
||||
$record['discid'] = $discid;
|
||||
$record['ctdbid'] = $disc['CRC ']['int'];
|
||||
$record['confidence'] = $disc['CONF']['int'];
|
||||
$record['parity'] = base64_encode($this->read($disc['PAR ']['offset'], 16));
|
||||
$record['fulltoc'] = $this->fulltoc;
|
||||
$record['userid'] = $disc['USER']['value'];
|
||||
$record['agent'] = $disc['TOOL']['value'];
|
||||
$record['time'] = date ("Y-m-d H:i:s");
|
||||
$record['artist'] = @$disc['ART ']['value'];
|
||||
$record['title'] = @$disc['nam ']['value'];
|
||||
return $record;
|
||||
}
|
||||
|
||||
static function pg2ctdb($dbconn, $id)
|
||||
{
|
||||
$target_path = phpCTDB::discid2path($id);
|
||||
|
||||
$result = pg_query_params($dbconn, "SELECT * FROM submissions WHERE discid=$1", array($id))
|
||||
or die('Query failed: ' . pg_last_error());
|
||||
if (pg_num_rows($result) < 1) die('not found');
|
||||
|
||||
$totalconf = 0;
|
||||
$newctdb = false;
|
||||
$newctdb['name'] = 'CTDB';
|
||||
$newhead = false;
|
||||
$newhead['name'] = 'HEAD';
|
||||
$newtotal = false;
|
||||
$newtotal['name'] = 'TOTL';
|
||||
$newtotal['value'] = phpCTDB::BigEndian2String($totalconf,4);
|
||||
$newhead['subatoms'][] = $newtotal;
|
||||
$newctdb['subatoms'][] = $newhead;
|
||||
|
||||
while (TRUE == ($record = pg_fetch_array($result)))
|
||||
{
|
||||
$totalconf += $record['confidence'];
|
||||
$newdisc = false;
|
||||
$newdisc['name'] = 'DISC';
|
||||
|
||||
$newatom = false;
|
||||
$newatom['name'] = 'CRC ';
|
||||
$newatom['value'] = phpCTDB::Hex2String(sprintf('%08x',$record['ctdbid']));
|
||||
$newdisc['subatoms'][] = $newatom;
|
||||
|
||||
$newatom = false;
|
||||
$newatom['name'] = 'NPAR';
|
||||
$newatom['value'] = phpCTDB::BigEndian2String(8,4);
|
||||
$newdisc['subatoms'][] = $newatom;
|
||||
|
||||
$newatom = false;
|
||||
$newatom['name'] = 'CONF';
|
||||
$newatom['value'] = phpCTDB::BigEndian2String((int)($record['confidence']),4);
|
||||
$newdisc['subatoms'][] = $newatom;
|
||||
|
||||
$newatom = false;
|
||||
$newatom['name'] = 'PAR ';
|
||||
$newatom['value'] = base64_decode($record['parity']);
|
||||
$newdisc['subatoms'][] = $newatom;
|
||||
|
||||
$newctdb['subatoms'][] = $newdisc;
|
||||
}
|
||||
|
||||
pg_free_result($result);
|
||||
|
||||
$newctdb['subatoms'][0]['subatoms'][0]['value'] = phpCTDB::BigEndian2String($totalconf,4);
|
||||
|
||||
$ftyp=false;
|
||||
$ftyp['name'] = 'ftyp';
|
||||
$ftyp['value'] = 'CTDB';
|
||||
|
||||
$tname = sprintf("%s/ctdb.tmp", $target_path);
|
||||
$tfp = fopen($tname, 'wb');
|
||||
phpCTDB::unparse_atom($tfp,$ftyp);
|
||||
phpCTDB::unparse_atom($tfp,$newctdb);
|
||||
fclose($tfp);
|
||||
if(!rename($tname,sprintf("%s/ctdb.bin", $target_path)))
|
||||
die('error uploading file ' . $target_path);
|
||||
}
|
||||
|
||||
static function Hex2Int($hex_word, $signed = false)
|
||||
{
|
||||
$int_value = 0;
|
||||
$byte_wordlen = strlen($hex_word);
|
||||
for ($i = 0; $i < $byte_wordlen; $i++) {
|
||||
sscanf($hex_word{$i}, "%x", $digit);
|
||||
$int_value += $digit * pow(16, ($byte_wordlen - 1 - $i));
|
||||
}
|
||||
if ($signed) {
|
||||
$sign_mask_bit = 0x80 << 24;
|
||||
if ($int_value & $sign_mask_bit) {
|
||||
$int_value = 0 - ($int_value & ($sign_mask_bit - 1));
|
||||
}
|
||||
}
|
||||
return $int_value;
|
||||
}
|
||||
|
||||
static function BigEndian2Int($byte_word, $signed = false) {
|
||||
|
||||
$int_value = 0;
|
||||
$byte_wordlen = strlen($byte_word);
|
||||
|
||||
for ($i = 0; $i < $byte_wordlen; $i++) {
|
||||
$int_value += ord($byte_word{$i}) * pow(256, ($byte_wordlen - 1 - $i));
|
||||
}
|
||||
|
||||
if ($signed) {
|
||||
$sign_mask_bit = 0x80 << (8 * ($byte_wordlen - 1));
|
||||
if ($int_value & $sign_mask_bit) {
|
||||
$int_value = 0 - ($int_value & ($sign_mask_bit - 1));
|
||||
}
|
||||
}
|
||||
|
||||
return $int_value;
|
||||
}
|
||||
|
||||
static function Hex2String($number)
|
||||
{
|
||||
$intstring = '';
|
||||
$hex_word = str_pad($number, 8, '0', STR_PAD_LEFT);
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
sscanf(substr($hex_word, $i*2, 2), "%x", $number);
|
||||
$intstring = $intstring.chr($number);
|
||||
}
|
||||
return $intstring;
|
||||
}
|
||||
|
||||
static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
|
||||
$intstring = '';
|
||||
while ($number > 0) {
|
||||
if ($synchsafe) {
|
||||
$intstring = $intstring.chr($number & 127);
|
||||
$number >>= 7;
|
||||
} else {
|
||||
$intstring = $intstring.chr($number & 255);
|
||||
$number >>= 8;
|
||||
}
|
||||
}
|
||||
return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
|
||||
static function BigEndian2String($number, $minbytes=1, $synchsafe=false) {
|
||||
return strrev(phpCTDB::LittleEndian2String($number, $minbytes, $synchsafe));
|
||||
}
|
||||
|
||||
static function discid2path($id)
|
||||
{
|
||||
$err = sscanf($id, "%03d-%04x%04x-%04x%04x-%04x%04x", $tracks, $id1a, $id1b, $id2a, $id2b, $cddbida, $cddbidb);
|
||||
$parsedid = sprintf("%03d-%04x%04x-%04x%04x-%04x%04x", $tracks, $id1a, $id1b, $id2a, $id2b, $cddbida, $cddbidb);
|
||||
if ($id != $parsedid)
|
||||
die("bad id ". $id);
|
||||
return sprintf("parity/%x/%x/%x/%s", $id1b & 15, ($id1b >> 4) & 15, ($id1b >> 8) & 15, $parsedid);
|
||||
}
|
||||
|
||||
static function ctdbid2path($discid, $ctdbid)
|
||||
{
|
||||
$path = phpCTDB::discid2path($discid);
|
||||
sscanf($ctdbid, "%04x%04x", $ctdbida, $ctdbidb);
|
||||
$parsedctdbid = sprintf("%04x%04x", $ctdbida, $ctdbidb);
|
||||
if ($ctdbid != $parsedctdbid)
|
||||
die("bad id ". $ctdbid);
|
||||
return sprintf("%s/%s.bin", $path, $ctdbid);
|
||||
}
|
||||
|
||||
static function unparse_atom($fp, $atom)
|
||||
{
|
||||
// printf('unparse_atom(%s)<br>', $atom['name']);
|
||||
$offset = ftell($fp);
|
||||
fwrite($fp, phpCTDB::BigEndian2String(0, 4));
|
||||
fwrite($fp, $atom['name']);
|
||||
if (@$atom['subatoms'])
|
||||
foreach ($atom['subatoms'] as $subatom)
|
||||
phpCTDB::unparse_atom($fp, $subatom);
|
||||
else if ($atom['value'])
|
||||
fwrite($fp, $atom['value']);
|
||||
else
|
||||
die(sprintf("couldn't write long atom %s: size %d", $atom['name'], $atom['size']));
|
||||
$pos = ftell($fp);
|
||||
fseek($fp, $offset, SEEK_SET);
|
||||
fwrite($fp, phpCTDB::BigEndian2String($pos - $offset, 4));
|
||||
fseek($fp, $pos, SEEK_SET);
|
||||
}
|
||||
|
||||
function read($offset, $len)
|
||||
{
|
||||
fseek($this->fp, $offset, SEEK_SET);
|
||||
return fread($this->fp, $len);
|
||||
}
|
||||
|
||||
function parse_container_atom($offset, $len)
|
||||
{
|
||||
// printf('parse_container_atom(%d, %d)<br>', $offset, $len);
|
||||
$atoms = false;
|
||||
$fin = $offset + $len;
|
||||
while ($offset < $fin) {
|
||||
fseek($this->fp, $offset, SEEK_SET);
|
||||
$atom_header = fread($this->fp, 8);
|
||||
$atom_size = phpCTDB::BigEndian2Int(substr($atom_header, 0, 4));
|
||||
$atom_name = substr($atom_header, 4, 4);
|
||||
$atom['name'] = $atom_name;
|
||||
$atom['size'] = $atom_size - 8;
|
||||
$atom['offset'] = $offset + 8;
|
||||
if ($atom_size - 8 <= 256)
|
||||
$atom['value'] = fread($this->fp, $atom_size - 8);
|
||||
else
|
||||
$atom['value'] = false;
|
||||
// echo $len, ':', $offset, ":", $atom_size, ":", $atom_name, '<br>';
|
||||
if ($atom_name == 'CTDB' || $atom_name == 'DISC' || $atom_name == 'TOC ' || ($atom_name == 'HEAD' && ($atom_size != 28 || 256 != phpCTDB::BigEndian2Int(substr($atom['value'],0,4)))))
|
||||
{
|
||||
$atom['subatoms'] = $this->parse_container_atom($offset + 8, $atom_size - 8);
|
||||
foreach ($atom['subatoms'] as $param)
|
||||
switch ($param['name']) {
|
||||
case 'HEAD':
|
||||
case 'TOC ':
|
||||
case 'CRC ':
|
||||
case 'USER':
|
||||
case 'TOOL':
|
||||
case 'MBID':
|
||||
case 'ART ':
|
||||
case 'nam ':
|
||||
case 'NPAR':
|
||||
case 'CONF':
|
||||
case 'TOTL':
|
||||
case 'PAR ':
|
||||
$atom[$param['name']] = $param;
|
||||
break;
|
||||
case 'DISC':
|
||||
$atom['discs'][] = $param;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
$atom['subatoms'] = false;
|
||||
switch ($atom_name)
|
||||
{
|
||||
case 'CRC ':
|
||||
case 'NPAR':
|
||||
case 'CONF':
|
||||
case 'TOTL':
|
||||
$atom['int'] = phpCTDB::BigEndian2Int($atom['value']);
|
||||
break;
|
||||
}
|
||||
$offset += $atom_size;
|
||||
$atoms[] = $atom;
|
||||
}
|
||||
if ($offset > $fin)
|
||||
die(printf("bad atom: offset=%d, fin=%d", $offset, $fin));
|
||||
return $atoms;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
Disallow: /show.php
|
||||
Disallow: /top.php
|
||||
Disallow: /parity/
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
//mb_http_output('UTF-8');
|
||||
//mb_internal_encoding('UTF-8');
|
||||
include 'logo_start.php';
|
||||
//require_once( 'phpmb/mbQuery.php' );
|
||||
require_once( 'phpctdb/ctdb.php' );
|
||||
|
||||
$discid = $_GET['discid'];
|
||||
$ctdbid = $_GET['ctdbid'];
|
||||
$path = phpCTDB::ctdbid2path($discid, $ctdbid);
|
||||
|
||||
$last_modified_time = filemtime($path);
|
||||
$etag = md5_file($path);
|
||||
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
|
||||
header("ETag: $etag");
|
||||
|
||||
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||
|
||||
@trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = pg_query_params($dbconn, "SELECT * FROM submissions WHERE discid=$1 AND ctdbid=$2", array($discid, (int)phpCTDB::Hex2Int($ctdbid)))
|
||||
or die('Query failed: ' . pg_last_error());
|
||||
if (pg_num_rows($result) < 1) die('not found');
|
||||
if (pg_num_rows($result) > 1) die('not unique');
|
||||
$record = pg_fetch_array($result);
|
||||
pg_free_result($result);
|
||||
|
||||
$mbid = phpCTDB::toc2mbid($record['fulltoc']);
|
||||
$mbmeta = phpCTDB::mblookup($mbid);
|
||||
|
||||
printf('<center>');
|
||||
$imgfound = false;
|
||||
if ($mbmeta)
|
||||
foreach ($mbmeta as $mbr)
|
||||
if ($mbr['coverarturl'])
|
||||
{
|
||||
if (!$imgfound) include 'table_start.php';
|
||||
printf('<img src="%s">', $mbr['coverarturl']);
|
||||
$imgfound = true;
|
||||
}
|
||||
if ($imgfound) {
|
||||
include 'table_end.php';
|
||||
printf('<br><br>');
|
||||
}
|
||||
include 'table_start.php';
|
||||
?>
|
||||
<table border=0 cellspacing=0 cellpadding=6>
|
||||
<?php
|
||||
printf('<tr><td>Disc ID</td><td>%s</td></tr>', $discid);
|
||||
printf('<tr><td>CTDB ID</td><td>%s</td></tr>', $ctdbid);
|
||||
printf('<tr><td>Musicbrainz ID</td><td><a href="http://musicbrainz.org/bare/cdlookup.html?toc=%s">%s</a> (%s)</tr>', phpCTDB::toc2mbtoc($record['fulltoc']), $mbid, $mbmeta ? count($mbmeta) : "-");
|
||||
//printf('<tr><td>Full TOC</td><td>%s</td></tr>', $record['fulltoc']);
|
||||
printf('<tr><td colspan=2>');
|
||||
?>
|
||||
<table width=100% class=classy_table cellpadding=3 cellspacing=0><tr bgcolor=#D0D0D0><th>Track</th><th>Start</th><th>Length</th><th>Start sector</th><th>End sector</th></tr>
|
||||
<?php
|
||||
function TimeToString($time)
|
||||
{
|
||||
$frame = $time % 75;
|
||||
$time = floor($time/75);
|
||||
$sec = $time % 60;
|
||||
$time = floor($time/60);
|
||||
$min = $time;
|
||||
return sprintf('%d:%02d.%02d',$min,$sec,$frame);
|
||||
}
|
||||
$ids = explode(' ', $record['fulltoc']);
|
||||
for ($tr = 4; $tr < count($ids); $tr++)
|
||||
{
|
||||
$trno = $tr + $ids[0] - 4;
|
||||
$trstart = $ids[$tr] - 150;
|
||||
$trend = (($tr + 1) < count($ids) ? $ids[$tr+1] : $ids[3]) - 151;
|
||||
$trstartmsf = TimeToString($trstart);
|
||||
$trlenmsf = TimeToString($trend + 1 - $trstart);
|
||||
printf('<tr><td class=td_ar>%d</td><td class=td_ar>%s</td><td class=td_ar>%s</td><td class=td_ar>%d</td><td class=td_ar>%d</td></tr>', $trno, $trstartmsf, $trlenmsf, $trstart, $trend);
|
||||
}
|
||||
printf("</table>");
|
||||
printf('</td></tr>');
|
||||
if ($record['artist'] != '')
|
||||
printf('<tr><td>Artist</td><td>%s</td></tr>', $record['artist']);
|
||||
if ($mbmeta)
|
||||
foreach ($mbmeta as $mbr)
|
||||
if ($mbr['artistname'] != $record['artist'])
|
||||
printf('<tr><td>Artist (MB)</td><td>%s</td></tr>', $mbr['artistname']);
|
||||
if ($record['title'] != '')
|
||||
printf('<tr><td>Title</td><td>%s</td></tr>', $record['title']);
|
||||
if ($mbmeta)
|
||||
foreach ($mbmeta as $mbr)
|
||||
if ($mbr['albumname'] != $record['title'])
|
||||
printf('<tr><td>Title (MB)</td><td>%s</td></tr>', $mbr['albumname']);
|
||||
?>
|
||||
</table>
|
||||
<?php include 'table_end.php'; ?>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once( 'phpctdb/ctdb.php' );
|
||||
|
||||
/**
|
||||
* Convert php.ini shorthands to byte
|
||||
*
|
||||
* @author <gilthans dot NO dot SPAM at gmail dot com>
|
||||
* @link http://de3.php.net/manual/en/ini.core.php#79564
|
||||
*/
|
||||
function php_to_byte($v){
|
||||
$l = substr($v, -1);
|
||||
$ret = substr($v, 0, -1);
|
||||
switch(strtoupper($l)){
|
||||
case 'P':
|
||||
$ret *= 1024;
|
||||
case 'T':
|
||||
$ret *= 1024;
|
||||
case 'G':
|
||||
$ret *= 1024;
|
||||
case 'M':
|
||||
$ret *= 1024;
|
||||
case 'K':
|
||||
$ret *= 1024;
|
||||
break;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Return the human readable size of a file
|
||||
// @param int $size a file size
|
||||
// @param int $dec a number of decimal places
|
||||
|
||||
function filesize_h($size, $dec = 1)
|
||||
{
|
||||
$sizes = array('byte(s)', 'kb', 'mb', 'gb');
|
||||
$count = count($sizes);
|
||||
$i = 0;
|
||||
|
||||
while ($size >= 1024 && ($i < $count - 1)) {
|
||||
$size /= 1024;
|
||||
$i++;
|
||||
}
|
||||
|
||||
return round($size, $dec) . ' ' . $sizes[$i];
|
||||
}
|
||||
|
||||
$file = $_FILES['uploadedfile'];
|
||||
|
||||
//echo $file['name'], ini_get('upload_max_filesize');
|
||||
|
||||
// give info on PHP catched upload errors
|
||||
if($file['error']) switch($file['error']){
|
||||
case 1:
|
||||
case 2:
|
||||
echo sprintf($lang['uploadsize'],
|
||||
filesize_h(php_to_byte(ini_get('upload_max_filesize'))));
|
||||
echo "Error ", $file['error'];
|
||||
return;
|
||||
default:
|
||||
echo $lang['uploadfail'];
|
||||
echo "Error ", $file['error'];
|
||||
}
|
||||
|
||||
//if ($_SERVER['HTTP_USER_AGENT'] != "CUETools 205") {
|
||||
// echo "user agent ", $_SERVER['HTTP_USER_AGENT'], " is not allowed";
|
||||
// return;
|
||||
//}
|
||||
|
||||
$tmpname = $file['tmp_name'];
|
||||
$size = (@file_exists($tmpname)) ? filesize($tmpname) : 0;
|
||||
if ($size == 0) {
|
||||
echo "no file uploaded";
|
||||
return;
|
||||
}
|
||||
|
||||
$dbconn = pg_connect("dbname=ctdb user=ctdb_user")
|
||||
or die('Could not connect: ' . pg_last_error());
|
||||
|
||||
$id = $_POST['id'];
|
||||
$target_path = phpCTDB::discid2path($id);
|
||||
@mkdir($target_path, 0777, true);
|
||||
$target_file = sprintf("%s/ctdb.bin", $target_path);
|
||||
|
||||
$ctdb = new phpCTDB($tmpname);
|
||||
$merging = @file_exists($target_file);
|
||||
$ctdb->ParseTOC();
|
||||
$record = $ctdb->ctdb2pg($id);
|
||||
unset($ctdb);
|
||||
|
||||
$destname = sprintf("%s/%08x.bin", $target_path, $record['ctdbid']);
|
||||
if(!move_uploaded_file($tmpname, $destname))
|
||||
die('error uploading file ' . $tmpname . ' to ' . $destname);
|
||||
|
||||
$subres = pg_insert($dbconn, 'submissions', $record);
|
||||
|
||||
phpCTDB::pg2ctdb($dbconn, $id);
|
||||
|
||||
if ($merging)
|
||||
printf("%s has been updated", $id);
|
||||
else
|
||||
printf("%s has been uploaded", $id);
|
||||
?>
|
||||
@@ -1,9 +0,0 @@
|
||||
</td>
|
||||
<td background="img/bg_right_border.jpg"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="4" height="4"><img src="img/bottom_left_corner.jpg" width="4" height="4"></td>
|
||||
<td background="img/bg_bottom.jpg"></td>
|
||||
<td width="4" height="4"><img src="img/bottom_right_corner.jpg" width="4" height="4"></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -1,10 +0,0 @@
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td width="4" height="4"><img src="img/top_left_corner.jpg" width="4" height="4"></td>
|
||||
<td background="img/bg_top_border.jpg"></td>
|
||||
<td width="4" height="4"><img src="img/top_right_corner.jpg" width="4" height="4"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="4" background="img/bg_left_border.jpg"></td>
|
||||
<td align="center" valign="middle">
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
include 'logo_start.php';
|
||||
require_once( 'phpmb/mbQuery.php' );
|
||||
require_once( 'phpctdb/ctdb.php' );
|
||||
|
||||
//$dbconn = pg_connect("dbname=ctdb user=ctdb_user")
|
||||
// or die('Could not connect: ' . pg_last_error());
|
||||
|
||||
$count = 20;
|
||||
$query = 'SELECT * FROM submissions';
|
||||
$term = ' WHERE ';
|
||||
$url = '';
|
||||
|
||||
$where_discid=@$_GET['discid'];
|
||||
if ($where_discid != '')
|
||||
{
|
||||
$query = $query . $term . "discid='" . pg_escape_string($where_discid) . "'";
|
||||
$term = ' AND ';
|
||||
$url = $url . '&discid=' . urlencode($where_discid);
|
||||
}
|
||||
$where_artist=@$_GET['artist'];
|
||||
if ($where_artist != '')
|
||||
{
|
||||
$query = $query . $term . "artist ilike '" . pg_escape_string($where_artist) . "'";
|
||||
$term = ' AND ';
|
||||
$url = $url . '&artist=' . urlencode($where_artist);
|
||||
}
|
||||
if ($term == ' WHERE ')
|
||||
{
|
||||
$query = $query . $term . "confidence>=100";
|
||||
$term = ' AND ';
|
||||
}
|
||||
$query = $query . " ORDER BY confidence";
|
||||
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
|
||||
$start = @$_GET['start'];
|
||||
if (pg_num_rows($result) == 0)
|
||||
die('nothing found');
|
||||
if ($count > pg_num_rows($result))
|
||||
$count = pg_num_rows($result);
|
||||
if ($start == '') $start = pg_num_rows($result) - $count;
|
||||
|
||||
printf("<center><h3>Popular discs:</h3>");
|
||||
include 'list.php';
|
||||
pg_free_result($result);
|
||||
printf("</center>");
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,355 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Convert php.ini shorthands to byte
|
||||
*
|
||||
* @author <gilthans dot NO dot SPAM at gmail dot com>
|
||||
* @link http://de3.php.net/manual/en/ini.core.php#79564
|
||||
*/
|
||||
function php_to_byte($v){
|
||||
$l = substr($v, -1);
|
||||
$ret = substr($v, 0, -1);
|
||||
switch(strtoupper($l)){
|
||||
case 'P':
|
||||
$ret *= 1024;
|
||||
case 'T':
|
||||
$ret *= 1024;
|
||||
case 'G':
|
||||
$ret *= 1024;
|
||||
case 'M':
|
||||
$ret *= 1024;
|
||||
case 'K':
|
||||
$ret *= 1024;
|
||||
break;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Return the human readable size of a file
|
||||
// @param int $size a file size
|
||||
// @param int $dec a number of decimal places
|
||||
|
||||
function filesize_h($size, $dec = 1)
|
||||
{
|
||||
$sizes = array('byte(s)', 'kb', 'mb', 'gb');
|
||||
$count = count($sizes);
|
||||
$i = 0;
|
||||
|
||||
while ($size >= 1024 && ($i < $count - 1)) {
|
||||
$size /= 1024;
|
||||
$i++;
|
||||
}
|
||||
|
||||
return round($size, $dec) . ' ' . $sizes[$i];
|
||||
}
|
||||
|
||||
function BigEndian2Int($byte_word, $signed = false) {
|
||||
|
||||
$int_value = 0;
|
||||
$byte_wordlen = strlen($byte_word);
|
||||
|
||||
for ($i = 0; $i < $byte_wordlen; $i++) {
|
||||
$int_value += ord($byte_word{$i}) * pow(256, ($byte_wordlen - 1 - $i));
|
||||
}
|
||||
|
||||
if ($signed) {
|
||||
$sign_mask_bit = 0x80 << (8 * ($byte_wordlen - 1));
|
||||
if ($int_value & $sign_mask_bit) {
|
||||
$int_value = 0 - ($int_value & ($sign_mask_bit - 1));
|
||||
}
|
||||
}
|
||||
|
||||
return $int_value;
|
||||
}
|
||||
|
||||
function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
|
||||
$intstring = '';
|
||||
while ($number > 0) {
|
||||
if ($synchsafe) {
|
||||
$intstring = $intstring.chr($number & 127);
|
||||
$number >>= 7;
|
||||
} else {
|
||||
$intstring = $intstring.chr($number & 255);
|
||||
$number >>= 8;
|
||||
}
|
||||
}
|
||||
return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
|
||||
function BigEndian2String($number, $minbytes=1, $synchsafe=false) {
|
||||
return strrev(LittleEndian2String($number, $minbytes, $synchsafe));
|
||||
}
|
||||
|
||||
function unparse_atom($fp, $atom)
|
||||
{
|
||||
// printf('unparse_atom(%s)<br>', $atom['name']);
|
||||
$offset = ftell($fp);
|
||||
fwrite($fp, BigEndian2String(0, 4));
|
||||
fwrite($fp, $atom['name']);
|
||||
if ($atom['subatoms'])
|
||||
foreach ($atom['subatoms'] as $subatom)
|
||||
unparse_atom($fp, $subatom);
|
||||
else if ($atom['value'])
|
||||
fwrite($fp, $atom['value']);
|
||||
else
|
||||
die(sprintf("couldn't write long atom %s: size %d", $atom['name'], $atom['size']));
|
||||
$pos = ftell($fp);
|
||||
fseek($fp, $offset, SEEK_SET);
|
||||
fwrite($fp, BigEndian2String($pos - $offset, 4));
|
||||
fseek($fp, $pos, SEEK_SET);
|
||||
}
|
||||
|
||||
function parse_container_atom($fp, $offset, $len)
|
||||
{
|
||||
// printf('parse_container_atom(%d, %d)<br>', $offset, $len);
|
||||
$atoms = false;
|
||||
$fin = $offset + $len;
|
||||
while ($offset < $fin) {
|
||||
fseek($fp, $offset, SEEK_SET);
|
||||
$atom_header = fread($fp, 8);
|
||||
$atom_size = BigEndian2Int(substr($atom_header, 0, 4));
|
||||
$atom_name = substr($atom_header, 4, 4);
|
||||
$atom['name'] = $atom_name;
|
||||
$atom['size'] = $atom_size - 8;
|
||||
$atom['offset'] = $offset + 8;
|
||||
if ($atom_size - 8 <= 32)
|
||||
$atom['value'] = fread($fp, $atom_size - 8);
|
||||
else
|
||||
$atom['value'] = false;
|
||||
// echo $offset, ":", $atom_size, ":", $atom_name, '<br>';
|
||||
if ($atom_name == 'CTDB' || $atom_name == 'DISC' || $atom_name == 'TOC ')
|
||||
{
|
||||
$atom['subatoms'] = parse_container_atom($fp, $offset + 8, $atom_size - 8);
|
||||
foreach ($atom['subatoms'] as $param)
|
||||
switch ($param['name']) {
|
||||
case 'HEAD':
|
||||
case 'CRC ':
|
||||
case 'NPAR':
|
||||
case 'CONF':
|
||||
case 'PAR ':
|
||||
$atom[$param['name']] = $param;
|
||||
break;
|
||||
case 'DISC':
|
||||
$atom['discs'][] = $param;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
$atom['subatoms'] = false;
|
||||
switch ($atom_name)
|
||||
{
|
||||
case 'CRC ':
|
||||
case 'NPAR':
|
||||
case 'CONF':
|
||||
$atom['int'] = BigEndian2Int($atom['value']);
|
||||
break;
|
||||
}
|
||||
$offset += $atom_size;
|
||||
$atoms[] = $atom;
|
||||
}
|
||||
if ($offset > $fin)
|
||||
die("bad atom");
|
||||
return $atoms;
|
||||
}
|
||||
|
||||
function get_chunk_offset($fp, $offset, $maxlen, $names, $namepos, &$res, &$len)
|
||||
{
|
||||
// printf('get_chunk_offset(%d, %d, [%d]%s)<br>', $offset, $maxlen, $namepos, $names[$namepos]);
|
||||
$subatoms = parse_container_atom($fp, $offset, $maxlen);
|
||||
if (!$subatoms) return -1;
|
||||
foreach($subatoms as $atom)
|
||||
if ($atom['name'] == $names[$namepos])
|
||||
{
|
||||
if ($namepos + 1 >= count($names))
|
||||
{
|
||||
$res = $atom['offset'];
|
||||
$len = $atom['size'];
|
||||
return 0;
|
||||
}
|
||||
return get_chunk_offset($fp, $atom['offset'], $atom['size'], $names, $namepos + 1, $res, $len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function chunk_offset($fp, $offset, $maxlen, $path, &$res, &$len)
|
||||
{
|
||||
// printf('chunk_offset(%d, %d, %s)<br>', $offset, $maxlen, $path);
|
||||
return get_chunk_offset($fp, $offset, $maxlen, explode(".", $path), 0, $res, $len);
|
||||
}
|
||||
|
||||
function read_chunk($fp, $offset, $maxlen, $path, $len = 32)
|
||||
{
|
||||
// printf('read_chunk(%d, %d, %s)<br>', $offset, $maxlen, $path);
|
||||
if (chunk_offset($fp, $offset, $maxlen, $path, $chunk_offset, $chunk_length) < 0) return;
|
||||
if ($chunk_length > $len) return;
|
||||
fseek($fp, $chunk_offset, SEEK_SET);
|
||||
return fread($fp, $chunk_length);
|
||||
}
|
||||
|
||||
function read_int($fp, $offset, $len, $path)
|
||||
{
|
||||
// printf('read_int(%d, %d, %s)<br>', $offset, $len, $path);
|
||||
return BigEndian2Int(read_chunk($fp, $offset, $len, $path, 4));
|
||||
}
|
||||
|
||||
function copy_data($srcfp, $srcoffset, $dstfp, $dstoffset, $length)
|
||||
{
|
||||
fseek($srcfp, $srcoffset, SEEK_SET);
|
||||
fseek($dstfp, $dstoffset, SEEK_SET);
|
||||
fwrite($dstfp, fread($srcfp, $length));
|
||||
}
|
||||
|
||||
$file = $_FILES['uploadedfile'];
|
||||
|
||||
//echo $file['name'], ini_get('upload_max_filesize');
|
||||
|
||||
// give info on PHP catched upload errors
|
||||
if($file['error']) switch($file['error']){
|
||||
case 1:
|
||||
case 2:
|
||||
echo sprintf($lang['uploadsize'],
|
||||
filesize_h(php_to_byte(ini_get('upload_max_filesize'))));
|
||||
echo "Error ", $file['error'];
|
||||
return;
|
||||
default:
|
||||
echo $lang['uploadfail'];
|
||||
echo "Error ", $file['error'];
|
||||
}
|
||||
|
||||
//if ($_SERVER['HTTP_USER_AGENT'] != "CUETools 205") {
|
||||
// echo "user agent ", $_SERVER['HTTP_USER_AGENT'], " is not allowed";
|
||||
// return;
|
||||
//}
|
||||
|
||||
$tmpname = $file['tmp_name'];
|
||||
$size = (@file_exists($tmpname)) ? filesize($tmpname) : 0;
|
||||
if ($size == 0) {
|
||||
echo "no file uploaded";
|
||||
return;
|
||||
}
|
||||
|
||||
$id = $_POST['id'];
|
||||
$err = sscanf($id, "%03d-%04x%04x-%04x%04x-%04x%04x", $tracks, $id1a, $id1b, $id2a, $id2b, $cddbida, $cddbidb);
|
||||
$parsedid = sprintf("%03d-%04x%04x-%04x%04x-%04x%04x", $tracks, $id1a, $id1b, $id2a, $id2b, $cddbida, $cddbidb);
|
||||
if ($id != $parsedid) {
|
||||
echo "bad id ", $id;
|
||||
return;
|
||||
}
|
||||
|
||||
$fp = fopen($tmpname, 'rb');
|
||||
if (chunk_offset($fp, 0, $size, 'CTDB.DISC', $disc_offset, $disc_length) < 0)
|
||||
die("bad file");
|
||||
$head = read_chunk($fp, 0, $size, 'CTDB.HEAD', 20);
|
||||
$crc = read_int($fp, $disc_offset, $disc_length, 'CRC ');
|
||||
$npar = read_int($fp, $disc_offset, $disc_length, 'NPAR');
|
||||
$tool = read_chunk($fp, $disc_offset, $disc_length, 'TOOL');
|
||||
$version = BigEndian2Int(substr($head,0,4));
|
||||
$disccount = BigEndian2Int(substr($head,4,4));
|
||||
$total = BigEndian2Int(substr($head,8,4));
|
||||
fclose($fp);
|
||||
|
||||
$target_path = sprintf("parity/%x/%x/%x", $id1b & 15, ($id1b >> 4) & 15, ($id1b >> 8) & 15);
|
||||
$target_file = sprintf("%s/dBCT-%s.bin", $target_path, $parsedid);
|
||||
|
||||
@mkdir($target_path, 0777, true);
|
||||
|
||||
if ($npar < 8 || $npar > 16 || $version != 256 || $disccount != 1) {
|
||||
printf("bad file: version=%d, disccount=%d, total=%d, npar=%d, tool=%s",
|
||||
$version, $disccount, $total, $npar, $tool);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!@file_exists($target_file)) {
|
||||
if(!move_uploaded_file($tmpname, $target_file)) {
|
||||
echo "there was an error uploading the file, please try again!";
|
||||
return;
|
||||
}
|
||||
printf("%s has been uploaded", $parsedid);
|
||||
return;
|
||||
}
|
||||
|
||||
$fp = fopen($tmpname, 'rb');
|
||||
$fpstats = fstat($fp);
|
||||
$db = parse_container_atom($fp, 0, $fpstats['size']);
|
||||
foreach ($db as $entry) if($entry['name'] == 'CTDB') $ctdb = $entry;
|
||||
|
||||
if (@file_exists($target_file)) {
|
||||
$fp1 = fopen($target_file, 'rb');
|
||||
$fp1stats = fstat($fp1);
|
||||
$db1 = parse_container_atom($fp1, 0, $fp1stats['size']);
|
||||
foreach ($db1 as $entry) if($entry['name'] == 'CTDB') $ctdb1 = $entry;
|
||||
}
|
||||
|
||||
$ftyp['name'] = 'ftyp';
|
||||
$ftyp['value'] = 'CTDB';
|
||||
|
||||
$newctdb['name'] = 'CTDB';
|
||||
$newhead['name'] = 'HEAD';
|
||||
$newtotal['name'] = 'TOTL';
|
||||
$newtotal['value'] = $ctdb1 ? BigEndian2String(BigEndian2Int(substr($ctdb1['HEAD']['value'],8,4)) + 1,4) : substr($ctdb['HEAD']['value'],8,4);
|
||||
$newhead['subatoms'][] = $newtotal;
|
||||
$newctdb['subatoms'][] = $newhead;
|
||||
$discs = 0;
|
||||
foreach ($ctdb['subatoms'] as $disc)
|
||||
if ($disc['name'] == 'DISC')
|
||||
{
|
||||
$crc = $disc['CRC ']['value'];
|
||||
|
||||
$newdisc = false;
|
||||
$newdisc['name'] = 'DISC';
|
||||
$newdisc['subatoms'][] = $disc['CRC '];
|
||||
$newdisc['subatoms'][] = $disc['NPAR'];
|
||||
$newdisc['subatoms'][] = $disc['CONF'];
|
||||
fseek($fp, $disc['PAR ']['offset']);
|
||||
$newpar['name'] = 'PAR ';
|
||||
$newpar['value'] = fread($fp, 16);
|
||||
$newdisc['subatoms'][] = $newpar;
|
||||
$newctdb['subatoms'][] = $newdisc;
|
||||
$discs++;
|
||||
}
|
||||
if ($discs > 1)
|
||||
die('One disc at a time, please');
|
||||
if ($discs < 1)
|
||||
die('No disc records found');
|
||||
if ($ctdb1)
|
||||
foreach ($ctdb1['subatoms'] as $disc)
|
||||
if ($disc['name'] == 'DISC')
|
||||
{
|
||||
if ($crc == $disc['CRC ']['value'])
|
||||
die("duplicate entry");
|
||||
|
||||
$newdisc = false;
|
||||
$newdisc['name'] = 'DISC';
|
||||
$newdisc['subatoms'][] = $disc['CRC '];
|
||||
$newdisc['subatoms'][] = $disc['NPAR'];
|
||||
$newdisc['subatoms'][] = $disc['CONF'];
|
||||
fseek($fp1, $disc['PAR ']['offset']);
|
||||
$newpar['name'] = 'PAR ';
|
||||
$newpar['value'] = fread($fp1, 16);
|
||||
$newdisc['subatoms'][] = $newpar;
|
||||
$newctdb['subatoms'][] = $newdisc;
|
||||
}
|
||||
|
||||
|
||||
$destpath = sprintf("%s/%s/", $target_path, $parsedid);
|
||||
@mkdir($destpath, 0777, true);
|
||||
|
||||
$tname = sprintf("%s/ctdb.tmp", $destpath);
|
||||
$tfp = fopen($tname, 'wb');
|
||||
unparse_atom($tfp,$ftyp);
|
||||
unparse_atom($tfp,$newctdb);
|
||||
fclose($tfp);
|
||||
|
||||
$crca = BigEndian2Int(substr($crc,0,2));
|
||||
$crcb = BigEndian2Int(substr($crc,2,2));
|
||||
$destname = sprintf("%s/%04x%04x.bin", $destpath, $crca, $crcb);
|
||||
if(!move_uploaded_file($tmpname, $destname))
|
||||
die('error uploading file');
|
||||
|
||||
if(!rename($tname,sprintf("%s/ctdb.bin", $destpath)))
|
||||
die('error uploading file');
|
||||
|
||||
fclose($fp);
|
||||
if ($fp1) fclose($fp1);
|
||||
|
||||
printf("%s has been updated", $parsedid);
|
||||
?>
|
||||