#!/usr/bin/php toString()."\n"); //var_dump($message->getUserInfo()); fclose($handle); } } } function checkForPhpScript($pf, $content = NULL) { if(get_class($pf) == "PEAR_PackageFile_v1") { $filelist = $pf->getFilelist(); foreach($filelist as $item) { if($item['role'] == 'script') { return 1; } } return 0; } elseif(get_class($pf) == "PEAR_PackageFile_v2") { if ($content === NULL) { $content = $pf->getContents(); } foreach($content as $name=>$item) { if($name == 'dir') { return checkForPhpScript($pf, $item); } elseif($name == 'file') { foreach($item as $file) { if(isset($file['attribs']) && ($file['attribs']['role'] == 'script')) { return 1; } } } } return 0; } else { printLog("Unknown PEAR_PackageFile version"); exit(1); } } function pearPackageNameToDebianPackageNameOverridesFile($overrides_file, $channel_url, $package_name, $composer = false) { if (file_exists($overrides_file)) { $fh = fopen($overrides_file, 'r'); if ($fh === false) { printLog("Unable to open '$overrides_file'"); exit(1); } if ($channel_url == 'pecl.php.net') { $channel_url = 'extension'; } while (($line = fgets($fh)) !== false) { $fields = preg_split("/[\s]+/", $line); if (count($fields) < 3) { printLog("Ignoring line, too short: '$line'"); continue; } if ($fields[0] == 'pecl.php.net') { $fields[0] = 'extension'; } if ( ((strcasecmp($fields[0], $channel_url) == 0) && (strcasecmp($fields[1], $package_name) == 0)) || ($composer && preg_match('/(^|\.)'.$channel_url.'($|\.)/i', $fields[0]) && (strcasecmp($package_name, str_replace('_', '-', $fields[1]))==0)) ) { printLog("Overriding:'$channel_url' '$package_name' -> '{$fields[2]}'"); return $fields[2]; } } if (!feof($fh)) { printLog("Unable to read '$overrides_file'"); exit(1); } fclose($fh); } return false; } function pearPackageNameToDebianPackageNameOverrides($channel_url, $package_name, $composer = false) { $overrides = pearPackageNameToDebianPackageNameOverridesFile('debian/pkg-php-tools-overrides', $channel_url, $package_name, $composer); if ($overrides) { return $overrides; } $overrides_dir = '/usr/share/pkg-php-tools/overrides/'; if (is_dir($overrides_dir)) { if ($dh = opendir($overrides_dir)) { while (($file = readdir($dh)) !== false) { if (($file == '.') || ($file == '..')) { continue; } $overrides = pearPackageNameToDebianPackageNameOverridesFile($overrides_dir.$file, $channel_url, $package_name, $composer); if ($overrides) { return $overrides; } } closedir($dh); } else { printLog("Unable to open '$overrides_dir'"); exit(1); } } return false; } function pearPackageNameToDebianPackageName($channel_url, $package_name, $prefix = NULL, $shift_from_url = Array("pear", "pecl", "www")) { global $builtin_extensions; $overriden = pearPackageNameToDebianPackageNameOverrides($channel_url, $package_name); if ($overriden) { return $overriden; } //put everything lowercase $package_name = strtolower($package_name); $channel_url = strtolower($channel_url); // split channel url by dots: $urlc = explode(".", $channel_url); // split package name by underscores: $packagec = explode("_", $package_name); // drop last part of url (TLD): array_pop($urlc); // drop first part of url if equal to pear or www if (isset($urlc[0]) && in_array($urlc[0], $shift_from_url)) { if (($urlc[0] == "pecl") && ($prefix === NULL)) { $channel_url = 'extension'; // Wild guess } array_shift($urlc); } if ($channel_url == 'extension') { if (in_array(strtolower($package_name), $builtin_extensions)) { return 'builtin'; } $prefix = "php5-"; } // drop first part of url if equal to php if (isset($urlc[0]) && ($urlc[0] == "php")) { array_shift($urlc); } // drop first part of package if equal to last part of url (should be done several times?) if (end($urlc) == $packagec[0]) { array_shift($packagec); } //merge the result return (($prefix === NULL) ? "php-" : $prefix) .implode('-', array_merge($urlc, $packagec)); } function pearVersionToDebianVersion($version) { $debian_version = ""; $tmp = explode(".",strtolower($version)); foreach($tmp as $component) { if (preg_match('/^\d+$/', $component)) { $debian_version .= "$component."; } elseif (preg_match('/^(\d+)(alpha\d*|a\d*|beta\d*|b\d*|rc\d*)$/', $component, $matches)) { $debian_version .= "$matches[1]~$matches[2]."; } else { $debian_version .= "?not supported($component)?."; # TODO } } return substr($debian_version, 0, -1); } function loadPackageFile($packagefilename) { $config = new PEAR_Config(); if ($config instanceof PEAR_Error) { printLog($config); exit(1); } $pkg = new PEAR_PackageFile($config); if ($pkg instanceof PEAR_Error) { printLog($pkg); exit(1); } // Check first for package.xml or package2.xml in subdirs, to have correct relative dirs if (is_dir($packagefilename)) { $dir_name = realpath($packagefilename); $d = dir($dir_name); while (false !== ($entry = $d->read())) { if ($entry != "." && $entry != ".." && is_dir("$dir_name/$entry")) { if (is_file("$dir_name/$entry/package2.xml")) { $packagefilename = "$dir_name/$entry/package2.xml"; } elseif (is_file("$dir_name/$entry/package.xml")) { $packagefilename = "$dir_name/$entry/package.xml"; } } } $d->close(); } $pf = $pkg->fromAnyFile($packagefilename, 0); if ($pf instanceof PEAR_Error) { printLog($pf); exit(1); } return $pf; } function loadChannelFile($channelfilename) { $config = new PEAR_Config(); if ($config instanceof PEAR_Error) { printLog($config); exit(1); } $chan = new PEAR_ChannelFile($config); if ($chan instanceof PEAR_Error) { printLog($chan); exit(1); } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $result = $chan->fromXmlFile($channelfilename); PEAR::staticPopErrorHandling(); if (!$result) { $exit = false; if (count($errors = $chan->getErrors(true))) { foreach ($errors as $error) { printLog(ucfirst($error['level'] . ': ' . $error['message'])); if (!$exit) { $exit = $error['level'] == 'error' ? true : false; } } if ($exit) { printLog('Exiting: invalid channel.xml file'); exit(1); } } } return $chan; } function loadComposerFile($composerfilename) { if (is_dir($composerfilename)) { $composerfilename = "$composerfilename/composer.json"; } if (!is_readable($composerfilename)) { printLog("File not readable: '$composerfilename'"); exit(1); } if (($composerfilecontent = file_get_contents($composerfilename)) === FALSE) { printLog("File content not readable: '$composerfilename'"); exit(1); } if (($json = json_decode($composerfilecontent)) === NULL) { if (function_exists('json_last_error_msg')) { // PHP >= 5.5 printLog("JSON error: '".json_last_error_msg()."' (".json_last_error().") on file '$composerfilename'"); } elseif (function_exists('json_last_error')) { // PHP >= 5.3 printLog("JSON error: code=".json_last_error()." on file '$composerfilename'"); } else { printLog("JSON error on file '$composerfilename'"); } exit(1); } return $json; } function composerPackageLink($infos) { $ret = ''; foreach ($infos as $pkg => $version) { $ret.= "$pkg ($version), "; } return substr($ret, 0, -2); } function composerDebianName($pkg) { if ($pkg == 'php') { return 'php5-common'; } if (substr($pkg, 0, 4) == 'ext-') { # PHP extension return pearPackageNameToDebianPackageName('extension', substr($pkg, 4)); } list($vendor_name, $project_name) = explode('/', $pkg); if (substr($vendor_name, 0, 5) == 'pear-') { # PEAR package return pearPackageNameToDebianPackageName(substr($vendor_name, 5), $project_name); } $overriden = pearPackageNameToDebianPackageNameOverrides($vendor_name, $project_name, true); if ($overriden) { return $overriden; } if (strpos($project_name, $vendor_name) === 0) { return "php-$project_name"; } return "php-$vendor_name-$project_name"; } function composerDebianVersionCompose(&$value, $key, $suffix) { $value = "$value$suffix"; } function composerDebianVersion($pkg, $version, $link) { $pkg = composerDebianName($pkg); if ($pkg === NULL || in_array($pkg, Array('builtin', 'none'))) { return NULL; } if (!is_array($pkg)) { $pkg = Array($pkg); } if ($link == 'suggest') { // suggest "version" is a comment return implode(' | ', $pkg); } $version = trim($version); if (preg_match('/^'. '(>|>=|<|<=|!=|~)?'. # Operator '\s*'. # Optional spaces 'v?(([\d*]+)(\.[\d*]+)?(\.[\d*]+)?(\.[\d*]+)?)'. # version '-?((?i)alpha\d*|a\d*|beta\d*|b\d*|rc\d*(?-i))?'. # wip '(@(stable|RC|beta|alpha|dev))?'. # stability '(\s+as +([^,\s]+))?$/', # "as ..." $version, $match) ) { $operator = isset($match[1]) ? $match[1] : NULL; $short_version = isset($match[2]) ? $match[2] : NULL; if (strpos($short_version, '*') === false) { $short_version .= isset($match[7]) ? '~'.strtolower($match[7]) : NULL; } $short_version_array = explode('.', $short_version); $stability = isset($match[8]) ? $match[8] : NULL; $as = isset($match[10]) ? $match[10] : NULL; switch($operator) { case '': if ($short_version == '*') { return implode(' | ', $pkg); } if (strpos($short_version, '*') === false) { array_walk($pkg, 'composerDebianVersionCompose', " (= $short_version)"); return implode(' | ', $pkg); } else { $base_version_array = $short_version_array; if (array_pop($base_version_array) !== '*') { printLog('Version with wildcard not at the end is forbidden ('.$short_version.')'); array_walk($pkg, 'composerDebianVersionCompose', " (ERROR:wilcard-misplaced $short_version)"); return implode(' | ', $pkg); } $base_version = implode('.', $base_version_array); $next_version_array = $base_version_array; $tmp = array_pop($next_version_array); array_push($next_version_array, $tmp+1); $next_version = implode('.', $next_version_array); $pkg_base = $pkg; array_walk($pkg_base, 'composerDebianVersionCompose', " (>= $base_version)"); $pkg_next = $pkg; array_walk($pkg_next, 'composerDebianVersionCompose', " (<< $next_version~)"); return implode(' | ', $pkg_base).', '.implode(' | ', $pkg_next); } case '>': case '<': if (strpos($short_version, '*') === false) { array_walk($pkg, 'composerDebianVersionCompose', " ($operator$operator $short_version)"); return implode(' | ', $pkg); } else { printLog('Version constraints combining comparisons and wildcards is forbidden ('.$version.')'); array_walk($pkg, 'composerDebianVersionCompose', " (ERROR:comparisons-and-wildcards $operator$operator $short_version)"); return implode(' | ', $pkg); } case '>=': case '<=': if (strpos($short_version, '*') === false) { array_walk($pkg, 'composerDebianVersionCompose', " ($operator $short_version)"); return implode(' | ', $pkg); } else { printLog('Version constraints combining comparisons and wildcards is forbidden ('.$version.')'); array_walk($pkg, 'composerDebianVersionCompose', " (ERROR:comparisons-and-wildcards $operator $short_version)"); return implode(' | ', $pkg); } case '!=': $pkg_lower = $pkg; array_walk($pkg_lower, 'composerDebianVersionCompose', " (<< $short_version)"); $pkg_upper = $pkg; array_walk($pkg_upper, 'composerDebianVersionCompose', " (>> $short_version)"); return implode(' | ', $pkg_lower).' | '.implode(' | ', $pkg_upper); case '~': // Next significant release $next_significant_array = $short_version_array; array_pop($next_significant_array); $tmp = array_pop($next_significant_array); array_push($next_significant_array, $tmp+1); $next_significant = implode('.', $next_significant_array); $pkg_lower = $pkg; array_walk($pkg_lower, 'composerDebianVersionCompose', " (>= $short_version)"); $pkg_upper = $pkg; array_walk($pkg_upper, 'composerDebianVersionCompose', " (<< $next_significant~)"); return implode(' | ', $pkg_lower).', '.implode(' | ', $pkg_upper); } } elseif ($version == 'self.version') { array_walk($pkg, 'composerDebianVersionCompose', ' (= ${binary:Version})'); return implode(' | ', $pkg); } printLog('Unable to parse version ('.$version.')'); array_walk($pkg, 'composerDebianVersionCompose', " (ERROR:parsing ? $version)"); return implode(' | ', $pkg); } function composerDebianDependencies($link, $infos) { $ret = ''; foreach ($infos as $pkg => $version) { if ((!preg_match ('/\s+as +[^,\s]+$/', $version)) and (strpos ($version, ','))) { $versions = explode(',', $version); foreach ($versions as $version) { $dep = composerDebianVersion($pkg, $version, $link); if ($dep !== NULL) { $ret.= $dep.', '; } } } else { $dep = composerDebianVersion($pkg, $version, $link); if ($dep !== NULL) { $ret.= $dep.', '; } } } return substr($ret, 0, -2); } $debug = false; $builtin_extensions = Array( // (extensions are lower-cased, see #696743) // Compiled in extensions (static) 'bcmath', 'bz2', 'calendar', 'core', 'ctype', 'date', 'dba', 'dom', 'ereg', 'exif', 'fileinfo', 'filter', 'ftp', 'gettext', 'hash', 'iconv', 'libxml', 'mbstring', 'openssl', 'pcre', 'phar', 'posix', 'reflection', 'session', 'shmop', 'simplexml', 'soap', 'sockets', 'spl', 'standard', 'sysvmsg', 'sysvsem', 'sysvshm', 'tokenizer', 'wddx', 'xml', 'xmlreader', 'xmlwriter', 'zip', 'zlib', // Other compiled extensions (dynamic) 'pdo', // Has provide/No longer builtin //'mhash', 'json', ); $args = $_SERVER["argv"]; array_shift($args); // script name if (!empty($args[0]) && ($args[0] == "-d")) { $debug = true; array_shift($args); } if(count($args) < 2) { usage(); exit; } $command = array_shift($args); switch($command) { case "package": $pf = loadPackageFile($args[0]); echo $pf->getPackage(); break; case "package_type": $pf = loadPackageFile($args[0]); echo $pf->getPackageType(); break; case "channel": $pf = loadPackageFile($args[0]); echo $pf->getChannel(); break; case "summary": $pf = loadPackageFile($args[0]); echo $pf->getSummary(); break; case "description": $pf = loadPackageFile($args[0]); echo $pf->getDescription(); break; case "maintainers": $pf = loadPackageFile($args[0]); $tmp = Array(); foreach($pf->getMaintainers() as $maintainer) { if (in_array($maintainer["role"], Array("lead", "developer"))) { $tmp[] = $maintainer["name"]; } } print implode(", ", $tmp); break; case "date": $pf = loadPackageFile($args[0]); echo $pf->getDate(); break; case "version": $pf = loadPackageFile($args[0]); echo $pf->getVersion(); break; case "license": $pf = loadPackageFile($args[0]); echo $pf->getLicense(); break; case "changelog": $pf = loadPackageFile($args[0]); echo "Version ".$pf->getVersion()." - ".$pf->getDate()." (".$pf->getState().")\n"; echo "----------------------------------------\n"; echo "Notes:\n"; echo " ".str_replace("\n", "\n ", wordwrap(ereg_replace("[[:space:]]+", " ", $pf->getNotes())))."\n\n"; if(get_class($pf) == "PEAR_PackageFile_v1") { foreach($pf->_packageInfo["changelog"] as $changelog) { echo "Version ".$changelog["version"]." - ".$changelog["release_date"]." (".$changelog["release_state"].")\n"; echo "----------------------------------------\n"; echo "Notes:\n"; echo " ".str_replace("\n", "\n ", wordwrap(ereg_replace("[[:space:]]+", " ", $changelog["release_notes"])))."\n\n"; } } elseif( get_class($pf) == "PEAR_PackageFile_v2") { if(isset($pf->_packageInfo["changelog"])){ $tmparr = $pf->_packageInfo["changelog"]["release"]; if(array_key_exists("version", $tmparr)) { $tmparr = Array($tmparr); } $tmparr = array_reverse($tmparr); foreach($tmparr as $changelog) { echo "Version ".$changelog["version"]["release"]." - ".$changelog["date"]." (".$changelog["stability"]["release"].")\n"; echo "----------------------------------------\n"; echo "Notes:\n"; echo " ".str_replace("\n", "\n ", wordwrap(ereg_replace("[[:space:]]+", " ", $changelog["notes"])))."\n\n"; } } } else { printLog("Unknown PEAR_PackageFile version"); exit(1); } break; case "all": $pf = loadPackageFile($args[0]); print_r($pf->_packageInfo); break; case "hasphpscript": $pf = loadPackageFile($args[0]); echo checkForPhpScript($pf); break; case "debian_deps": $pf = loadPackageFile($args[0]); $deps = Array(); if(get_class($pf) == "PEAR_PackageFile_v1") { if ($pf->hasDeps()) { printLog("debian_deps is not supported for package.xml version 1.0"); } } elseif( get_class($pf) == "PEAR_PackageFile_v2") { if (checkForPhpScript($pf)) { $deps['required'][] = 'php5-cli'; } $dependencies = &$pf->getDependencies(); foreach($dependencies as $level => $dep) { foreach($dep as $type => $tmp) { if (($level == "required") or ($level == "optional")) { if (key($tmp) !== 0) { $tmp = Array($tmp); } foreach($tmp as $infos) { if (!array_key_exists("exclude", $infos)) { $infos["exclude"] = Array(); } elseif (!is_array($infos["exclude"])) { $infos["exclude"] = Array($infos["exclude"]); } switch($type) { case "pearinstaller": // skip continue 2; case "php": $package = "php5-common"; break; case "package": $package = pearPackageNameToDebianPackageName($infos["channel"], $infos["name"]); break; case "extension": $package = pearPackageNameToDebianPackageName('extension', $infos["name"]); break; case "subpackage": case "os": case "arch": default: printLog("Tag '$type' not supported in $level $type: ".print_r($infos, true)); continue 2; } if (($package === 'builtin') || ($package === 'none')) { continue; } if (array_key_exists("min", $infos) || array_key_exists("max", $infos)) { $tmp2 = $package; if (array_key_exists("min", $infos)) { if (in_array($infos["min"], $infos["exclude"])) { $operator = ">>"; $infos["exclude"] = array_diff($infos["exclude"], Array($infos["min"])); } else { $operator = ">="; } $package = "$tmp2 ($operator ". pearVersionToDebianVersion($infos["min"]). ")"; } if (array_key_exists("max", $infos)) { if (!empty($package)) { $package = "$package, "; } if (in_array($infos["max"], $infos["exclude"])) { $operator = "<<"; $infos["exclude"] = array_diff($infos["exclude"], Array($infos["max"])); } else { $operator = "<="; } $package = "$package$tmp2 ($operator ". pearVersionToDebianVersion($infos["max"]). ")"; } } # TODO: recommended if (!empty($infos["recommended"])) { printLog("Tag 'recommended' not supported in $level $type $package: ".print_r($infos["recommended"], true)); } # TODO: exclude if (!empty($infos["exclude"])) { printLog("Tag 'exclude' not supported in $level $type $package: ".print_r($infos["exclude"], true)); } if (array_key_exists("conflicts", $infos)) { $deps["conflicts"][] = $package; } else { $deps[$level][] = $package; } } } } } } else { printLog("Unknown PEAR_PackageFile version"); exit(1); } # PHP API if ($pf->getPackageType() == 'extsrc') { $deps["required"][] = rtrim('phpapi-'.`/usr/bin/php-config --phpapi`); } if (array_key_exists("required", $deps)) { print "Depends: ".implode(", ", $deps["required"])."\n"; } if (array_key_exists("optional", $deps)) { print "Recommends: ".implode(", ", $deps["optional"])."\n"; } if (array_key_exists("conflicts", $deps)) { print "Breaks: ".implode(", ", $deps["conflicts"])."\n"; } break; case "debian_pkgname": if(count($args) != 2) { usage(); exit; } $pkg = pearPackageNameToDebianPackageName($args[0], $args[1]); if (($pkg === 'builtin') || ($pkg === 'none')) { $pkg = ''; } echo $pkg; exit; break; case "debian_version": if(count($args) != 1) { usage(); exit; } echo pearVersionToDebianVersion($args[0]); exit; break; case "channel_name": if(count($args) != 1) { usage(); exit; } $cf = loadChannelFile($args[0]); echo $cf->getName(); exit; break; case "channel_summary": if(count($args) != 1) { usage(); exit; } $cf = loadChannelFile($args[0]); echo $cf->getSummary(); exit; break; case "channel_alias": if(count($args) != 1) { usage(); exit; } $cf = loadChannelFile($args[0]); echo $cf->getAlias(); exit; break; // COMPOSER case "composer_name": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->name) ? $cf->name : ''; exit; case "composer_description": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->description) ? $cf->description : ''; exit; break; case "composer_version": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->version) ? $cf->version : ''; exit; break; case "composer_type": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->type) ? $cf->type : 'library'; exit; break; case "composer_keywords": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->keywords) ? implode(',', $cf->keywords) : ''; exit; break; case "composer_homepage": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->homepage) ? $cf->homepage : ''; exit; break; case "composer_time": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->time) ? $cf->time : ''; exit; break; case "composer_license": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); if (isset($cf->license)) { if (is_array($cf->license)) { echo implode(',', $cf->license); } else { echo $cf->license; } } exit; break; case "composer_authors": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); if (isset($cf->authors)) { foreach($cf->authors as $author) { echo $author->name; if (isset($author->email)) { echo ' <'.$author->email.'>'; } if (isset($author->homepage)) { echo ' ('.$author->homepage.')'; } if (isset($author->role)) { echo ', '.$author->role; } echo "\n"; } } exit; break; case "composer_support": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); if ( isset($cf->support)) { foreach($cf->support as $type => $support) { echo $type.': '.$support."\n"; } } exit; break; case "composer_require": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->require) ? composerPackageLink($cf->require) : ''; exit; break; case "composer_require_dev": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->{'require-dev'}) ? composerPackageLink($cf->{'require-dev'}) : ''; exit; break; case "composer_conflict": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->conflict) ? composerPackageLink($cf->conflict) : ''; exit; break; case "composer_replace": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->replace) ? composerPackageLink($cf->replace) : ''; exit; break; case "composer_provide": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->provide) ? composerPackageLink($cf->provide) : ''; exit; break; case "composer_suggest": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); echo isset($cf->suggest) ? composerPackageLink($cf->suggest) : ''; exit; break; //case "composer_autoload": TODO case "composer_config": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); if ( isset($cf->config)) { foreach($cf->config as $k => $v) { echo $k.': '.$v."\n"; } } exit; break; case "composer_substvars": if(count($args) != 1) { usage(); exit; } $cf = loadComposerFile($args[0]); foreach($cf as $k => $v) { switch($k) { case 'name': case 'description': echo "$k: $v\n"; break; case 'require': case 'require-dev': case 'conflict': case 'replace': case 'provide': case 'suggest': echo "Debian-$k: ".composerDebianDependencies($k, $v)."\n"; break; } } exit; break; // Default default: printLog("Unknown command $command"); exit(1); } ?>