2011-05-12 04:11:40 +00:00
|
|
|
#! /usr/bin/env php
|
|
|
|
|
|
|
|
<?php
|
2012-10-15 18:47:55 +00:00
|
|
|
// This file is part of BOINC.
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2012 University of California
|
|
|
|
//
|
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
// script to create application versions,
|
|
|
|
// and stage their files in the download dir.
|
|
|
|
// See http://boinc.berkeley.edu/trac/wiki/AppVersionNew
|
|
|
|
|
2011-05-12 04:11:40 +00:00
|
|
|
|
|
|
|
require_once("html/inc/boinc_db.inc");
|
|
|
|
require_once("html/inc/util_basic.inc");
|
|
|
|
|
|
|
|
$apps = BoincApp::enum("");
|
|
|
|
$platforms = BoincPlatform::enum("");
|
|
|
|
|
|
|
|
$config = file_get_contents("config.xml");
|
|
|
|
$download_url = parse_element($config, "<download_url>");
|
|
|
|
$download_dir = parse_element($config, "<download_dir>");
|
|
|
|
$fanout = parse_element($config, "<uldl_dir_fanout>");
|
|
|
|
|
|
|
|
function lookup_app($name) {
|
|
|
|
global $apps;
|
|
|
|
foreach ($apps as $app) {
|
|
|
|
if ($app->name == $name) return $app;
|
|
|
|
}
|
2011-08-07 04:32:02 +00:00
|
|
|
die("app not found: $name\n");
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function lookup_platform($p) {
|
|
|
|
global $platforms;
|
|
|
|
foreach ($platforms as $platform) {
|
|
|
|
if ($platform->name == $p) return $platform;
|
|
|
|
}
|
2011-08-07 04:32:02 +00:00
|
|
|
die("platform not found: $p\n");
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function readdir_aux($d) {
|
|
|
|
while ($f = readdir($d)) {
|
2011-08-02 17:20:18 +00:00
|
|
|
if (substr($f, 0, 1) == ".") continue;
|
2011-05-12 04:11:40 +00:00
|
|
|
return $f;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Data structures:
|
|
|
|
// Files are described by objects with fields
|
|
|
|
// physical_name
|
|
|
|
// logical_name
|
|
|
|
// main_program
|
|
|
|
// url
|
|
|
|
// etc.
|
|
|
|
// This are parsed from version.xml, or created by us
|
|
|
|
//
|
|
|
|
// Variables named $fd refer to such objects
|
|
|
|
//
|
|
|
|
|
|
|
|
// return a <file_info> element for the file
|
|
|
|
//
|
|
|
|
function file_info_xml($fd) {
|
|
|
|
$xml =
|
|
|
|
"<file_info>\n".
|
|
|
|
" <name>".$fd->physical_name."</name>\n"
|
|
|
|
;
|
|
|
|
if (is_array($fd->url)) {
|
|
|
|
foreach ($fd->url as $url) {
|
|
|
|
$xml .= " <url>$url</url>\n";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$xml .= " <url>$fd->url</url>\n";
|
- client: add a mechanism for restartable download of compressed files.
(It turns out that the compression schemes supported by
Apache and libcurl, suprisingly, aren't restartable.)
if a <file_info> from the server contains <gzipped_url> tags,
use those instead of the <url> tags,
and flag the file as "download_gzipped".
If this is the case, download NAME.gz and save it as NAME.gzt.
When the download is complete, rename NAME.gzt to NAME.gz,
and uncompress it to NAME.
(this ensures that if NAME.gz is present, it's complete).
Also do the uncompression, if needed, in verify_file().
This ensures that the uncompression will eventually get done
even if the client quits are crashes in the middle.
- update_versions: if <gzip> is present in a <file_info>,
add a gzipped copy in the download directory
and add a <gzipped_url> elements to the app version's xml_doc.
svn path=/trunk/boinc/; revision=25112
2012-01-20 23:34:15 +00:00
|
|
|
if ($fd->gzip) {
|
2012-01-21 01:36:53 +00:00
|
|
|
$xml .= " <gzipped_url>$fd->url.gz</gzipped_url>\n";
|
- client: add a mechanism for restartable download of compressed files.
(It turns out that the compression schemes supported by
Apache and libcurl, suprisingly, aren't restartable.)
if a <file_info> from the server contains <gzipped_url> tags,
use those instead of the <url> tags,
and flag the file as "download_gzipped".
If this is the case, download NAME.gz and save it as NAME.gzt.
When the download is complete, rename NAME.gzt to NAME.gz,
and uncompress it to NAME.
(this ensures that if NAME.gz is present, it's complete).
Also do the uncompression, if needed, in verify_file().
This ensures that the uncompression will eventually get done
even if the client quits are crashes in the middle.
- update_versions: if <gzip> is present in a <file_info>,
add a gzipped copy in the download directory
and add a <gzipped_url> elements to the app version's xml_doc.
svn path=/trunk/boinc/; revision=25112
2012-01-20 23:34:15 +00:00
|
|
|
}
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
2011-05-24 19:16:54 +00:00
|
|
|
if ($fd->executable || $fd->main_program) {
|
2011-05-12 04:11:40 +00:00
|
|
|
$xml .= " <executable/>\n";
|
|
|
|
}
|
|
|
|
$xml .= " <file_signature>\n";
|
|
|
|
$xml .= $fd->signature;
|
|
|
|
$xml .=
|
|
|
|
" </file_signature>\n".
|
2012-01-26 08:39:51 +00:00
|
|
|
" <nbytes>".$fd->nbytes."</nbytes>\n"
|
2011-05-12 04:11:40 +00:00
|
|
|
;
|
2012-01-26 08:39:51 +00:00
|
|
|
if ($fd->gzip) {
|
|
|
|
$xml .= " <gzipped_nbytes>".$fd->gzipped_nbytes."</gzipped_nbytes>\n";
|
|
|
|
}
|
|
|
|
$xml .= "</file_info>\n";
|
2011-05-12 04:11:40 +00:00
|
|
|
return $xml;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return a <file_ref> element for the file
|
|
|
|
//
|
|
|
|
function file_ref_xml($fd) {
|
|
|
|
$xml =
|
|
|
|
"<file_ref>\n".
|
|
|
|
" <file_name>".$fd->physical_name."</file_name>\n"
|
|
|
|
;
|
|
|
|
if (isset($fd->logical_name) && strlen($fd->logical_name)) {
|
|
|
|
$xml .= " <open_name>$fd->logical_name</open_name>\n";
|
|
|
|
}
|
2011-05-18 16:59:15 +00:00
|
|
|
if ($fd->copy_file) {
|
|
|
|
$xml .= " <copy_file/>\n";
|
|
|
|
}
|
2011-05-12 04:11:40 +00:00
|
|
|
if ($fd->main_program) {
|
|
|
|
$xml .= " <main_program/>\n";
|
|
|
|
}
|
2011-05-17 16:00:23 +00:00
|
|
|
$xml .= "</file_ref>\n";
|
2011-05-12 04:11:40 +00:00
|
|
|
return $xml;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function lookup_file($fds, $name) {
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
if ($fd->physical_name == $name) return $fd;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// update file in list, or add to list
|
|
|
|
//
|
|
|
|
function update_file($fds, $fd) {
|
|
|
|
for ($i=0; $i<sizeof($fds); $i++) {
|
|
|
|
if ($fds[$i]->physical_name == $fd->physical_name) {
|
|
|
|
$fds[$i] = $fd;
|
|
|
|
return $fds;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$fds[] = $fd;
|
|
|
|
return $fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
// move file to download dir, check immutability, fill in $fd->url
|
|
|
|
//
|
|
|
|
function stage_file($a, $v, $p, $fd) {
|
|
|
|
global $download_url, $download_dir;
|
|
|
|
|
|
|
|
$name = $fd->physical_name;
|
2011-05-12 04:14:53 +00:00
|
|
|
$path = "apps/$a/$v/$p/$name";
|
2011-05-12 04:11:40 +00:00
|
|
|
$dl_path = "$download_dir/$name";
|
|
|
|
if (is_file($dl_path)) {
|
|
|
|
if (md5_file($path) != md5_file($dl_path)) {
|
|
|
|
die ("Error: files $path and $dl_path differ.\nBOINC files are immutable.\nIf you change a file, you must give it a new name.\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
echo("cp $path $dl_path\n");
|
|
|
|
system("cp $path $dl_path");
|
|
|
|
}
|
|
|
|
|
|
|
|
$fd->url = "$download_url/$name";
|
2012-01-26 08:39:51 +00:00
|
|
|
if ($fd->gzip) {
|
|
|
|
if (!file_exists("$dl_path.gz")) {
|
|
|
|
$tmp = "$dl_path.tmp";
|
|
|
|
system("cp $dl_path $tmp");
|
|
|
|
system("gzip $dl_path");
|
|
|
|
system("mv $tmp $dl_path");
|
|
|
|
}
|
|
|
|
$stat = stat("$dl_path.gz");
|
|
|
|
$fd->gzipped_nbytes = $stat['size'];
|
2011-08-02 07:38:45 +00:00
|
|
|
}
|
2011-05-12 04:11:40 +00:00
|
|
|
return $fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_api_version($a, $v, $p, $fds) {
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
if ($fd->main_program) {
|
2011-05-12 04:14:53 +00:00
|
|
|
$path = "apps/$a/$v/$p/$fd->physical_name";
|
2011-05-12 04:11:40 +00:00
|
|
|
$handle = popen("strings $path | grep API_VERSION", "r");
|
|
|
|
$x = fread($handle, 8192);
|
|
|
|
pclose($handle);
|
|
|
|
$x = strstr($x, "API_VERSION_");
|
|
|
|
return trim(substr($x, strlen("API_VERSION_")));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
$sig_gen_confirmed = false;
|
|
|
|
|
|
|
|
function confirm_sig_gen($name) {
|
|
|
|
global $sig_gen_confirmed;
|
|
|
|
|
|
|
|
if ($sig_gen_confirmed) return true;
|
|
|
|
|
|
|
|
echo "
|
|
|
|
NOTICE: You have not provided a signature file for $name,
|
|
|
|
and your project's code-signing private key is on your server.
|
|
|
|
|
|
|
|
IF YOUR PROJECT IS PUBLICLY ACCESSABLE, THIS IS A SECURITY VULNERABILITY.
|
|
|
|
PLEASE STOP YOUR PROJECT IMMEDIATELY AND READ:
|
|
|
|
http://boinc.berkeley.edu/trac/wiki/CodeSigning
|
|
|
|
|
|
|
|
Continue (y/n)? ";
|
|
|
|
|
2011-06-11 15:30:10 +00:00
|
|
|
$x = trim(fgets(STDIN));
|
2011-05-12 04:11:40 +00:00
|
|
|
if ($x != "y") {
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
$sig_gen_confirmed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// process a file
|
|
|
|
//
|
|
|
|
function process_file($a, $v, $p, $name, $fds) {
|
|
|
|
$fd = lookup_file($fds, $name);
|
|
|
|
if (!$fd) {
|
|
|
|
$fd = null;
|
|
|
|
$fd->physical_name = $name;
|
2011-08-07 04:32:02 +00:00
|
|
|
$fd->logical_name = null;
|
2011-05-12 04:11:40 +00:00
|
|
|
$fd->url = array();
|
2011-08-07 04:32:02 +00:00
|
|
|
$fd->main_program = false;
|
|
|
|
$fd->copy_file = false;
|
|
|
|
$fd->gzip = false;
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
2011-05-12 04:14:53 +00:00
|
|
|
$path = "apps/$a/$v/$p/$name";
|
2011-05-12 04:11:40 +00:00
|
|
|
|
|
|
|
$stat = stat($path);
|
|
|
|
$fd->nbytes = $stat['size'];
|
|
|
|
|
2011-05-12 04:14:53 +00:00
|
|
|
$sigpath = "apps/$a/$v/$p/$name.sig";
|
2011-05-12 04:11:40 +00:00
|
|
|
if (is_file($sigpath)) {
|
|
|
|
$fd->signature = file_get_contents($sigpath);
|
|
|
|
} else {
|
|
|
|
$keypath = "keys/code_sign_private";
|
|
|
|
if (is_file($keypath)) {
|
|
|
|
confirm_sig_gen($name);
|
|
|
|
$handle = popen("bin/sign_executable $path $keypath", "r");
|
|
|
|
$fd->signature = fread($handle, 8192);
|
|
|
|
pclose($handle);
|
|
|
|
} else {
|
|
|
|
die(" Error: no .sig file for $name, and no code signing private key\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sizeof($fd->url)) {
|
|
|
|
$fd = stage_file($a, $v, $p, $fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isset($fd->executable)) {
|
|
|
|
$perms = fileperms($path);
|
|
|
|
$fd->executable = ($perms & 0x0040)?true:false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$fd->present = true;
|
|
|
|
$fds = update_file($fds, $fd);
|
|
|
|
return $fds;
|
|
|
|
}
|
|
|
|
|
2011-08-07 04:32:02 +00:00
|
|
|
// scan the directory, and process files.
|
|
|
|
// "fds" is the list of files described in version.xml;
|
|
|
|
// return this list, augmented with any files not in version.xml
|
|
|
|
//
|
2011-05-12 04:11:40 +00:00
|
|
|
//
|
|
|
|
function process_files($a, $v, $p, $fds) {
|
2011-05-12 04:14:53 +00:00
|
|
|
$d = opendir("apps/$a/$v/$p");
|
2011-05-12 04:11:40 +00:00
|
|
|
while ($f = readdir_aux($d)) {
|
|
|
|
if ($f == "version.xml") continue;
|
|
|
|
if (strstr($f, ".sig") == ".sig") continue;
|
|
|
|
$fds = process_file($a, $v, $p, $f, $fds);
|
|
|
|
}
|
|
|
|
return $fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
function parse_platform_name($p, &$platform, &$plan_class) {
|
|
|
|
$x = explode("__", $p);
|
|
|
|
$platform = $x[0];
|
|
|
|
if (sizeof($x) > 1) {
|
|
|
|
$plan_class = $x[1];
|
|
|
|
} else {
|
|
|
|
$plan_class = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function parse_version($v) {
|
|
|
|
$x = explode(".", $v);
|
|
|
|
if (!is_numeric($x[0])) return -1;
|
|
|
|
if (sizeof($x) > 1) {
|
|
|
|
if (!is_numeric($x[1])) return -1;
|
2011-05-17 15:53:06 +00:00
|
|
|
return $x[1] + 100*$x[0];
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
return (int)$x[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
function already_exists($a, $v, $platform, $plan_class) {
|
|
|
|
$app = lookup_app($a);
|
|
|
|
$plat = lookup_platform($platform);
|
|
|
|
$vnum = parse_version($v);
|
|
|
|
$av = BoincAppVersion::lookup("appid=$app->id and version_num=$vnum and platformid=$plat->id and plan_class='$plan_class'");
|
|
|
|
if ($av) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function missing_files($fds) {
|
|
|
|
$missing = false;
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
if (!$fd->present) {
|
|
|
|
echo " File $fd->physical_name is listed in version.xml but not present\n";
|
|
|
|
$missing = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $missing;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check whether there's a main program
|
|
|
|
//
|
|
|
|
function check_main_program($fds) {
|
|
|
|
$n = 0;
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
if ($fd->main_program) $n++;
|
|
|
|
}
|
|
|
|
if ($n == 0) {
|
2011-08-07 04:32:02 +00:00
|
|
|
die(" No file was marked as the main program.\n");
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
if ($n > 1) {
|
2011-08-07 04:32:02 +00:00
|
|
|
die(" More than one file was marked as the main program.\n");
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function confirm($fds) {
|
|
|
|
echo " Files:\n";
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
echo " $fd->physical_name";
|
|
|
|
if ($fd->main_program) {
|
|
|
|
echo " (main program)";
|
|
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
}
|
|
|
|
echo " Do you want to add this application version (y/n)? ";
|
2011-06-11 15:30:10 +00:00
|
|
|
$x = trim(fgets(STDIN));
|
2011-05-12 04:11:40 +00:00
|
|
|
return ($x == "y");
|
|
|
|
}
|
|
|
|
|
2011-08-03 18:14:45 +00:00
|
|
|
function get_bool($xml_element, $name) {
|
|
|
|
foreach($xml_element->xpath($name) as $x) {
|
|
|
|
$s = trim((string) $x);
|
|
|
|
if ($s == "" || int($s)>0) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-05-12 04:11:40 +00:00
|
|
|
// convert SimpleXMLElement object to a standard object
|
|
|
|
//
|
|
|
|
function convert_simplexml($x) {
|
|
|
|
$fds = array();
|
|
|
|
$fxs = $x->xpath('file');
|
|
|
|
foreach ($fxs as $fx) {
|
|
|
|
//echo "fx: "; print_r($fx);
|
|
|
|
$fd = null;
|
|
|
|
|
2011-05-21 06:22:15 +00:00
|
|
|
$fd->present = false;
|
|
|
|
$fd->physical_name = trim((string) $fx->physical_name);
|
|
|
|
$fd->logical_name = trim((string) $fx->logical_name);
|
2011-05-12 04:11:40 +00:00
|
|
|
$fd->url = array();
|
|
|
|
foreach($fx->xpath('url') as $url) {
|
2011-05-21 06:22:15 +00:00
|
|
|
$fd->url[] = trim((string) $url);
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
2011-08-03 18:14:45 +00:00
|
|
|
$fd->main_program = get_bool($fx, "main_program");
|
|
|
|
$fd->copy_file = get_bool($fx, "copy_file");
|
|
|
|
$fd->gzip = get_bool($fx, "gzip");
|
2011-05-12 04:11:40 +00:00
|
|
|
|
|
|
|
$fds[] = $fd;
|
|
|
|
}
|
2011-08-03 18:14:45 +00:00
|
|
|
$v = null;
|
|
|
|
$v->files = $fds;
|
|
|
|
$v->dont_throttle = get_bool($x, "dont_throttle");
|
2011-12-26 06:03:50 +00:00
|
|
|
$v->needs_network = get_bool($x, "needs_network");
|
2011-08-03 18:14:45 +00:00
|
|
|
$v->file_prefix = (string)$x->file_prefix;
|
|
|
|
return $v;
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function process_version($a, $v, $p) {
|
|
|
|
echo "Found application version: $a $v $p\n";
|
|
|
|
$app = lookup_app($a);
|
|
|
|
parse_platform_name($p, $platform, $plan_class);
|
|
|
|
if (already_exists($a, $v, $platform, $plan_class)) {
|
|
|
|
echo " This app version already exists\n";
|
|
|
|
return;
|
|
|
|
}
|
2011-05-12 04:14:53 +00:00
|
|
|
$vfile = "apps/$a/$v/$p/version.xml";
|
2011-05-12 04:11:40 +00:00
|
|
|
if (is_file($vfile)) {
|
|
|
|
$x = simplexml_load_file($vfile);
|
|
|
|
if (!$x) {
|
|
|
|
die("Can't load XML file apps/$a/$v/$p. Check that it exists and is valid.");
|
|
|
|
}
|
2011-08-03 18:14:45 +00:00
|
|
|
$vers = convert_simplexml($x);
|
2011-05-12 04:11:40 +00:00
|
|
|
} else {
|
2011-08-03 18:14:45 +00:00
|
|
|
$vers = null;
|
|
|
|
$vers->files = array();
|
2012-04-24 19:24:31 +00:00
|
|
|
$vers->dont_throttle = false;
|
|
|
|
$vers->needs_network = false;
|
|
|
|
$vers->file_prefix = false;
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
|
2011-08-03 18:14:45 +00:00
|
|
|
$fds = process_files($a, $v, $p, $vers->files);
|
2011-05-12 04:11:40 +00:00
|
|
|
|
|
|
|
if (missing_files($fds)) return;
|
2011-08-03 18:14:45 +00:00
|
|
|
if (sizeof($fds) == 1) {
|
|
|
|
$fds[0]->main_program = true;
|
|
|
|
}
|
2011-08-07 04:32:02 +00:00
|
|
|
check_main_program($fds);
|
2011-05-12 04:11:40 +00:00
|
|
|
$api_version = get_api_version($a, $v, $p, $fds);
|
|
|
|
|
|
|
|
if (!confirm($fds)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$xml = "";
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
$xml .= file_info_xml($fd);
|
|
|
|
}
|
|
|
|
$xml .=
|
|
|
|
"<app_version>\n".
|
|
|
|
" <app_name>".$app->name."</app_name>\n".
|
2011-07-05 17:45:24 +00:00
|
|
|
" <version_num>".parse_version($v)."</version_num>\n".
|
2011-05-12 04:11:40 +00:00
|
|
|
" <api_version>$api_version</api_version>\n"
|
|
|
|
;
|
|
|
|
foreach ($fds as $fd) {
|
|
|
|
$xml .= file_ref_xml($fd);
|
|
|
|
}
|
2011-08-03 18:14:45 +00:00
|
|
|
if ($vers->dont_throttle) {
|
|
|
|
$xml .= " <dont_throttle/>\n";
|
|
|
|
}
|
2011-12-26 06:03:50 +00:00
|
|
|
if ($vers->needs_network) {
|
|
|
|
$xml .= " <needs_network/>\n";
|
|
|
|
}
|
2011-08-03 18:14:45 +00:00
|
|
|
if ($vers->file_prefix != "") {
|
|
|
|
$xml .= " <file_prefix>$vers->file_prefix</file_prefix>\n";
|
|
|
|
}
|
2011-05-12 04:11:40 +00:00
|
|
|
$xml .= "</app_version>\n";
|
|
|
|
|
|
|
|
$now = time();
|
|
|
|
$vnum = parse_version($v);
|
|
|
|
$plat = lookup_platform($platform);
|
|
|
|
$query = "set create_time=$now, appid=$app->id, version_num=$vnum, platformid=$plat->id , xml_doc='$xml', plan_class='$plan_class'";
|
|
|
|
|
|
|
|
$id = BoincAppVersion::insert($query);
|
|
|
|
if ($id) {
|
|
|
|
echo " Application version added successfully; ID=$id\n";
|
|
|
|
} else {
|
|
|
|
echo " Error; application version not added\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function scan_version_dir($a, $v) {
|
2011-05-12 04:14:53 +00:00
|
|
|
$d = opendir("apps/$a/$v");
|
2011-05-12 04:11:40 +00:00
|
|
|
while ($p = readdir_aux($d)) {
|
|
|
|
process_version($a, $v, $p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function scan_app_dir($a) {
|
2011-05-12 04:14:53 +00:00
|
|
|
$d = opendir("apps/$a");
|
2011-05-12 04:11:40 +00:00
|
|
|
while ($v = readdir_aux($d)) {
|
|
|
|
if (parse_version($v) < 0) {
|
|
|
|
echo "$v is not a version number; skipping\n";
|
2005-01-27 23:09:19 +00:00
|
|
|
continue;
|
2011-05-12 04:11:40 +00:00
|
|
|
}
|
|
|
|
scan_version_dir($a, $v);
|
|
|
|
}
|
|
|
|
closedir($d);
|
|
|
|
}
|
|
|
|
|
|
|
|
function scan_apps() {
|
2011-05-12 04:14:53 +00:00
|
|
|
$d = opendir("apps");
|
2011-05-12 04:11:40 +00:00
|
|
|
while ($a = readdir_aux($d)) {
|
|
|
|
if (!lookup_app($a)) {
|
|
|
|
echo "$a is not an app\n";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
scan_app_dir($a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
scan_apps();
|
2011-10-21 20:14:54 +00:00
|
|
|
touch("reread_db"); // if feeder is running, tell it to reread DB
|
2011-05-12 04:11:40 +00:00
|
|
|
|
|
|
|
?>
|