Example #1
0
function module_download($modulename, $force = false, $progress_callback = null, $override_svn = false, $override_xml = false)
{
    global $amp_conf;
    if ($time_limit = ini_get('max_execution_time')) {
        set_time_limit($time_limit);
    }
    // size of download blocks to fread()
    // basically, this controls how often progress_callback is called
    $download_chunk_size = 12 * 1024;
    // invoke progress callback
    if (function_exists($progress_callback)) {
        $progress_callback('getinfo', array('module' => $modulename));
    }
    $res = module_getonlinexml($modulename, $override_xml);
    if ($res == null) {
        return array(_("Module not found in repository"));
    }
    $file = basename($res['location']);
    $filename = $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/" . $file;
    // if we're not forcing the download, and a file with the target name exists..
    if (!$force && file_exists($filename)) {
        // We might already have it! Let's check the MD5.
        $filedata = "";
        if ($fh = @fopen($filename, "r")) {
            while (!feof($fh)) {
                $filedata .= fread($fh, 8192);
            }
            fclose($fh);
        }
        if (isset($res['md5sum']) && $res['md5sum'] == md5($filedata)) {
            // Note, if there's no MD5 information, it will redownload
            // every time. Otherwise theres no way to avoid a corrupt
            // download
            // invoke progress callback
            if (function_exists($progress_callback)) {
                $progress_callback('untar', array('module' => $modulename, 'size' => filesize($filename)));
            }
            /* We will explode the tarball in the cache directory and then once successful, remove the old module before before
             * moving the new one over. This way, things like removed files end up being removed instead of laying around
             *
             * TODO: save old module being replaced, if there is an old one.
             */
            exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not remove %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/' . $modulenam));
            }
            exec("tar zxf " . escapeshellarg($filename) . " -C " . escapeshellarg($amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/'), $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not untar %s to %s'), $filename, $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache'));
            }
            exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not remove old module %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename));
            }
            exec("mv " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename} " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not move %s to %s'), $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $amp_conf['AMPWEBROOT'] . '/admin/modules/'));
            }
            // invoke progress_callback
            if (function_exists($progress_callback)) {
                $progress_callback('done', array('module' => $modulename));
            }
            return true;
        } else {
            unlink($filename);
        }
    }
    if ($override_svn) {
        $url = $override_svn . $res['location'];
    } else {
        $url = "http://mirror.freepbx.org/modules/" . $res['location'];
    }
    if (!($fp = @fopen($filename, "w"))) {
        return array(sprintf(_("Error opening %s for writing"), $filename));
    }
    $headers = get_headers_assoc($url);
    $totalread = 0;
    // invoke progress_callback
    if (function_exists($progress_callback)) {
        $progress_callback('downloading', array('module' => $modulename, 'read' => $totalread, 'total' => $headers['content-length']));
    }
    // Check MODULEADMINWGET first so we don't execute the fopen() if set
    //
    if ($amp_conf['MODULEADMINWGET'] || !($dp = @fopen($url, 'r'))) {
        exec("wget -O {$filename} {$url} 2> /dev/null", $filedata, $retcode);
        if ($retcode != 0) {
            return array(sprintf(_("Error opening %s for reading"), $url));
        } else {
            if (!($dp = @fopen($filename, 'r'))) {
                return array(sprintf(_("Error opening %s for reading"), $url));
            }
        }
    }
    $filedata = '';
    while (!feof($dp)) {
        $data = fread($dp, $download_chunk_size);
        $filedata .= $data;
        $totalread += strlen($data);
        if (function_exists($progress_callback)) {
            $progress_callback('downloading', array('module' => $modulename, 'read' => $totalread, 'total' => $headers['content-length']));
        }
    }
    fwrite($fp, $filedata);
    fclose($dp);
    fclose($fp);
    if (is_readable($filename) !== TRUE) {
        return array(sprintf(_('Unable to save %s'), $filename));
    }
    // Check the MD5 info against what's in the module's XML
    if (!isset($res['md5sum']) || empty($res['md5sum'])) {
        //echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>";
    } else {
        if ($res['md5sum'] != md5($filedata)) {
            unlink($filename);
            return array(sprintf(_('File Integrity failed for %s - aborting'), $filename));
        }
    }
    // invoke progress callback
    if (function_exists($progress_callback)) {
        $progress_callback('untar', array('module' => $modulename, 'size' => filesize($filename)));
    }
    /* We will explode the tarball in the cache directory and then once successful, remove the old module before before
     * moving the new one over. This way, things like removed files end up being removed instead of laying around
     *
     * TODO: save old module being replaced, if there is an old one.
     *
     */
    exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not remove %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/' . $modulenam));
    }
    exec("tar zxf " . escapeshellarg($filename) . " -C " . escapeshellarg($amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/'), $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not untar %s to %s'), $filename, $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache'));
    }
    exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not remove old module %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename));
    }
    exec("mv " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename} " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not move %s to %s'), $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $amp_conf['AMPWEBROOT'] . '/admin/modules/'));
    }
    // invoke progress_callback
    if (function_exists($progress_callback)) {
        $progress_callback('done', array('module' => $modulename));
    }
    return true;
}
 function url_get_contents($url, $request, $verb = 'get', $params = array())
 {
     $params['sv'] = 2;
     global $amp_conf;
     $verb = strtolower($verb);
     $contents = null;
     if (!$amp_conf['MODULEADMINWGET']) {
         $pest = new Pest($url);
         try {
             $contents = $pest->{$verb}($url . $request, $params);
             if (isset($pest->last_headers['x-regenerate-id'])) {
                 $this->_regenerate_unique_id();
             }
             return $contents;
         } catch (Exception $e) {
             freepbx_log(FPBX_LOG_ERROR, sprintf(_('Failed to get remote file, error was:'), (string) $e->getMessage()));
         }
     }
     $fn = $url . $request;
     if (empty($contents)) {
         $fn2 = str_replace('&', '\\&', $fn);
         $p = !empty($params) ? "--post-data '" . http_build_query($params) . "'" : "";
         exec("wget --tries=1 --timeout=30 {$p} -O - {$fn2} 2>> /dev/null", $data_arr, $retcode);
         if ($retcode) {
             // if server isn't available for some reason should return non-zero
             // so we return and we don't set the flag below
             freepbx_log(FPBX_LOG_ERROR, sprintf(_('Failed to get remote file, mirror site may be down: %s'), $fn));
             // We are here if contents were blank. It's possible that whatever we were getting were suppose to be blank
             // so we only auto set the WGET var if we received something so as to not false trigger. If there are issues
             // with content filters that this is designed to get around, we will eventually get a non-empty file which
             // will trigger this for now and the future.
             return null;
         } elseif (!empty($data_arr) && !$amp_conf['MODULEADMINWGET']) {
             $freepbx_conf =& freepbx_conf::create();
             $freepbx_conf->set_conf_values(array('MODULEADMINWGET' => true), true);
             $nt =& notifications::create($db);
             $text = sprintf(_("Forced %s to true"), 'MODULEADMINWGET');
             $extext = sprintf(_("The system detected a problem trying to access external server data and changed internal setting %s (Use wget For Module Admin) to true, see the tooltip in Advanced Settings for more details."), 'MODULEADMINWGET');
             $nt->add_warning('freepbx', 'MODULEADMINWGET', $text, $extext, '', false, true);
         }
         $headers = get_headers_assoc($fn2);
         if (isset($headers['x-regenerate-id'])) {
             $this->_regenerate_unique_id();
         }
         $contents = implode("\n", $data_arr);
         return $contents;
     }
 }
Example #3
0
function module_download($modulename, $force = false, $progress_callback = null, $override_svn = false, $override_xml = false)
{
    global $amp_conf;
    if ($time_limit = ini_get('max_execution_time')) {
        set_time_limit($time_limit);
    }
    // size of download blocks to fread()
    // basically, this controls how often progress_callback is called
    $download_chunk_size = 12 * 1024;
    // invoke progress callback
    if (function_exists($progress_callback)) {
        $progress_callback('getinfo', array('module' => $modulename));
    }
    $res = module_getonlinexml($modulename, $override_xml);
    if ($res == null) {
        return array(_("Module not found in repository"));
    }
    $file = basename($res['location']);
    $filename = $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/" . $file;
    // if we're not forcing the download, and a file with the target name exists..
    if (!$force && file_exists($filename)) {
        // We might already have it! Let's check the MD5.
        $filedata = "";
        if ($fh = @fopen($filename, "r")) {
            while (!feof($fh)) {
                $filedata .= fread($fh, 8192);
            }
            fclose($fh);
        }
        if (isset($res['md5sum']) && $res['md5sum'] == md5($filedata)) {
            // Note, if there's no MD5 information, it will redownload
            // every time. Otherwise theres no way to avoid a corrupt
            // download
            // invoke progress callback
            if (function_exists($progress_callback)) {
                $progress_callback('untar', array('module' => $modulename, 'size' => filesize($filename)));
            }
            /* We will explode the tarball in the cache directory and then once successful, remove the old module before before
             * moving the new one over. This way, things like removed files end up being removed instead of laying around
             *
             * TODO: save old module being replaced, if there is an old one.
             */
            exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not remove %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/' . $modulename));
            }
            exec("tar zxf " . escapeshellarg($filename) . " -C " . escapeshellarg($amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/'), $output, $exitcode);
            if ($exitcode != 0) {
                freepbx_log(FPBX_LOG_ERROR, sprintf(_("failed to open %s module archive into _cache directory."), $filename));
                return array(sprintf(_('Could not untar %s to %s'), $filename, $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache'));
            } else {
                // since untarring was successful, remvove the tarball so they do not accumulate
                if (unlink($filename) === false) {
                    freepbx_log(FPBX_LOG_WARNING, sprintf(_("failed to delete %s from cache directory after opening module archive."), $filename));
                }
            }
            exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not remove old module %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename));
            }
            exec("mv " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename} " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
            if ($exitcode != 0) {
                return array(sprintf(_('Could not move %s to %s'), $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $amp_conf['AMPWEBROOT'] . '/admin/modules/'));
            }
            // invoke progress_callback
            if (function_exists($progress_callback)) {
                $progress_callback('done', array('module' => $modulename));
            }
            return true;
        } else {
            unlink($filename);
        }
    }
    if (!($fp = @fopen($filename, "w"))) {
        return array(sprintf(_("Error opening %s for writing"), $filename));
    }
    if ($override_svn) {
        $url_list = array($override_svn . $res['location']);
    } else {
        $url_list = generate_module_repo_url("/modules/" . $res['location'], true);
    }
    // Check each URL until get_headers_assoc() returns something intelligible. We then use
    // that URL and hope the file is there, we won't check others.
    //
    $headers = false;
    foreach ($url_list as $u) {
        $headers = get_headers_assoc($u);
        if (!empty($headers)) {
            $url = $u;
            break;
        }
        freepbx_log(FPBX_LOG_ERROR, sprintf(_('Failed download module tarball from %s, server may be down'), $u));
    }
    if (!$headers || !$url) {
        return array(sprintf(_("Unable to connect to servers from URLs provided: %s"), implode(',', $url_list)));
    }
    // TODO: do we want to make more robust past this point:
    // At this point we have settled on a specific URL that we can reach, if the file isn't there we won't try
    // other servers to check for it. The assumption is that no backup server will have it either at this point
    // If we wanted to make this more robust we could go back and try other servers. This code is a bit tangled
    // so some better factoring might help.
    //
    $totalread = 0;
    // invoke progress_callback
    if (function_exists($progress_callback)) {
        $progress_callback('downloading', array('module' => $modulename, 'read' => $totalread, 'total' => $headers['content-length']));
    }
    // Check MODULEADMINWGET first so we don't execute the fopen() if set
    //
    if ($amp_conf['MODULEADMINWGET'] || !($dp = @fopen($url, 'r'))) {
        exec("wget --tries=1 --timeout=600 -O {$filename} {$url} 2> /dev/null", $filedata, $retcode);
        if ($retcode != 0) {
            return array(sprintf(_("Error opening %s for reading"), $url));
        } else {
            if (!($dp = @fopen($filename, 'r'))) {
                return array(sprintf(_("Error opening %s for reading"), $url));
            }
        }
    }
    $filedata = '';
    while (!feof($dp)) {
        $data = fread($dp, $download_chunk_size);
        $filedata .= $data;
        $totalread += strlen($data);
        if (function_exists($progress_callback)) {
            $progress_callback('downloading', array('module' => $modulename, 'read' => $totalread, 'total' => $headers['content-length']));
        }
    }
    fwrite($fp, $filedata);
    fclose($dp);
    fclose($fp);
    if (is_readable($filename) !== TRUE) {
        return array(sprintf(_('Unable to save %s'), $filename));
    }
    // Check the MD5 info against what's in the module's XML
    if (!isset($res['md5sum']) || empty($res['md5sum'])) {
        //echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>";
    } else {
        if ($res['md5sum'] != md5($filedata)) {
            unlink($filename);
            return array(sprintf(_('File Integrity failed for %s - aborting'), $filename));
        }
    }
    // invoke progress callback
    if (function_exists($progress_callback)) {
        $progress_callback('untar', array('module' => $modulename, 'size' => filesize($filename)));
    }
    /* We will explode the tarball in the cache directory and then once successful, remove the old module before before
     * moving the new one over. This way, things like removed files end up being removed instead of laying around
     *
     * TODO: save old module being replaced, if there is an old one.
     *
     */
    exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not remove %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/' . $modulename));
    }
    exec("tar zxf " . escapeshellarg($filename) . " -C " . escapeshellarg($amp_conf['AMPWEBROOT'] . '/admin/modules/_cache/'), $output, $exitcode);
    if ($exitcode != 0) {
        freepbx_log(FPBX_LOG_ERROR, sprintf(_("failed to open %s module archive into _cache directory."), $filename));
        return array(sprintf(_('Could not untar %s to %s'), $filename, $amp_conf['AMPWEBROOT'] . '/admin/modules/_cache'));
    } else {
        // since untarring was successful, remvove the tarball so they do not accumulate
        if (unlink($filename) === false) {
            freepbx_log(FPBX_LOG_WARNING, sprintf(_("failed to delete %s from cache directory after opening module archive."), $filename));
        }
    }
    exec("rm -rf " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not remove old module %s to install new version'), $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename));
    }
    exec("mv " . $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename} " . $amp_conf['AMPWEBROOT'] . "/admin/modules/{$modulename}", $output, $exitcode);
    if ($exitcode != 0) {
        return array(sprintf(_('Could not move %s to %s'), $amp_conf['AMPWEBROOT'] . "/admin/modules/_cache/{$modulename}", $amp_conf['AMPWEBROOT'] . '/admin/modules/'));
    }
    // invoke progress_callback
    if (function_exists($progress_callback)) {
        $progress_callback('done', array('module' => $modulename));
    }
    return true;
}