Esempio n. 1
0
/**
 * Charger un tgz à partir d'un tableau d'options descriptives
 *
 * @param array $quoi
 *     Tableau d'options
 * @return array|bool|int|string
 *     En cas de réussite, Tableau décrivant le zip, avec les index suivant :
 *     - files : la liste des fichiers présents dans le zip,
 *     - size : la taille décompressée
 *     - compressed_size : la taille compressée
 *     - dirname : répertoire où les fichiers devront être décompréssés
 *     - tmpname : répertoire temporaire où les fichiers sont décompressés
 *     - target : cible sur laquelle décompresser les fichiers...
 */
function teleporter_http_charger_tgz($quoi = array())
{
    if (!$quoi) {
        return false;
    }
    foreach (array('remove' => '', 'rename' => array(), 'edit' => array(), 'root_extract' => false, 'tmp' => sous_repertoire(_DIR_CACHE, 'chargeur')) as $opt => $def) {
        isset($quoi[$opt]) || ($quoi[$opt] = $def);
    }
    if (!@file_exists($fichier = $quoi['fichier'])) {
        return 0;
    }
    include_spip('inc/pcltar');
    $racine = '';
    if ($list = PclTarList($fichier)) {
        $racine = http_deballe_recherche_racine($list);
        $quoi['remove'] = $racine;
    } else {
        spip_log('charger_decompresser erreur lecture liste tar ' . PclErrorString() . ' pour paquet: ' . $quoi['archive'], "teleport" . _LOG_ERREUR);
        return PclErrorString();
    }
    // si pas de racine commune, reprendre le nom du fichier zip
    // en lui enlevant la racine h+md5 qui le prefixe eventuellement
    // cf action/charger_plugin L74
    if (!strlen($nom = basename($racine))) {
        $nom = preg_replace(",^h[0-9a-f]{8}-,i", "", basename($fichier, '.zip'));
    }
    $dir_export = $quoi['root_extract'] ? $quoi['dest'] : $quoi['dest'] . $nom;
    $dir_export = rtrim($dir_export, '/') . '/';
    $tmpname = $quoi['tmp'] . $nom . '/';
    // choisir la cible selon si on veut vraiment extraire ou pas
    $target = $quoi['extract'] ? $dir_export : $tmpname;
    // ici, il faut vider le rep cible si il existe deja, non ?
    if (is_dir($target)) {
        supprimer_repertoire($target);
    }
    $ok = PclTarExtract($fichier, $target, $quoi['remove']);
    if ($ok == 0) {
        spip_log('charger_decompresser erreur tar ' . PclErrorString() . ' pour paquet: ' . $quoi['archive'], "teleport" . _LOG_ERREUR);
        return PclErrorString();
    }
    spip_log('charger_decompresser OK pour paquet: ' . $quoi['archive'], "teleport");
    $size = $compressed_size = 0;
    $removex = ',^' . preg_quote($quoi['remove'], ',') . ',';
    foreach ($list as $a => $f) {
        $size += $f['size'];
        $compressed_size += $f['compressed_size'];
        $list[$a] = preg_replace($removex, '', $f['filename']);
    }
    // Indiquer par un fichier install.log
    // a la racine que c'est chargeur qui a installe ce plugin
    ecrire_fichier($target . 'install.log', "installation: charger_plugin\n" . "date: " . gmdate('Y-m-d\\TH:i:s\\Z', time()) . "\n" . "source: " . $quoi['archive'] . "\n");
    return array('files' => $list, 'size' => $size, 'compressed_size' => $compressed_size, 'dirname' => $dir_export, 'tmpname' => $tmpname, 'target' => $target);
}
 /**
  * Télécharge un paquet
  *
  * Supprime les fichiers obsolètes (si présents)
  *
  * @param int|array $id_or_row
  *     Identifiant du paquet ou description ligne SQL du paquet
  * @param string $dest_ancien
  *     Chemin vers l'ancien répertoire (pour les mises à jour par VCS)
  * @return bool|array
  *     False si erreur.
  *     Tableau de 2 index sinon :
  *     - dir : Chemin du paquet téléchargé depuis la racine
  *     - dossier : Chemin du paquet téléchargé, depuis _DIR_PLUGINS
  */
 public function get_paquet_id($id_or_row, $dest_ancien = "")
 {
     // on peut passer direct le row sql...
     if (!is_array($id_or_row)) {
         $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($id_or_row));
     } else {
         $i = $id_or_row;
     }
     unset($id_or_row);
     if ($i['nom_archive'] and $i['id_depot']) {
         $this->log("Recuperer l'archive : " . $i['nom_archive']);
         // on récupère les informations intéressantes du dépot :
         // - url des archives
         // - éventuellement : type de serveur (svn, git) et url de la racine serveur (svn://..../)
         $adresses = sql_fetsel(array('url_archives', 'type', 'url_serveur'), 'spip_depots', 'id_depot=' . sql_quote($i['id_depot']));
         if ($adresses and $adresse = $adresses['url_archives']) {
             // destination : auto/prefixe/version (sinon auto/nom_archive/version)
             $prefixe = sql_getfetsel('pl.prefixe', array('spip_paquets AS pa', 'spip_plugins AS pl'), array('pa.id_plugin = pl.id_plugin', 'pa.id_paquet=' . sql_quote($i['id_paquet'])));
             // prefixe
             $base = $prefixe ? strtolower($prefixe) : substr($i['nom_archive'], 0, -4);
             // enlever .zip ...
             // prefixe/version
             $dest_future = $base . '/v' . denormaliser_version($i['version']);
             // Nettoyer les vieux formats dans auto/
             if ($this->tester_repertoire_destination_ancien_format(_DIR_PLUGINS_AUTO . $base)) {
                 supprimer_repertoire(_DIR_PLUGINS_AUTO . $base);
             }
             // l'url est différente en fonction du téléporteur
             $teleporteur = $this->choisir_teleporteur($adresses['type']);
             if ($teleporteur == 'http') {
                 $url = $adresse . '/' . $i['nom_archive'];
                 $dest = $dest_future;
             } else {
                 $url = $adresses['url_serveur'] . '/' . $i['src_archive'];
                 $dest = $dest_ancien ? $dest_ancien : $dest_future;
             }
             // on recupere la mise a jour...
             include_spip('action/teleporter');
             $teleporter_composant = charger_fonction('teleporter_composant', 'action');
             $ok = $teleporter_composant($teleporteur, $url, _DIR_PLUGINS_AUTO . $dest);
             if ($ok === true) {
                 // pour une mise à jour via VCS, il faut rebasculer sur le nouveau nom de repertoire
                 if ($dest != $dest_future) {
                     rename(_DIR_PLUGINS_AUTO . $dest, _DIR_PLUGINS_AUTO . $dest_future);
                 }
                 return array('dir' => _DIR_PLUGINS_AUTO . $dest, 'dossier' => 'auto/' . $dest);
             }
             $this->err($ok);
             $this->log("Téléporteur en erreur : " . $ok);
         } else {
             $this->log("Aucune adresse pour le dépot " . $i['id_depot']);
         }
     }
     return false;
 }
Esempio n. 3
0
 /**
  * Télécharge un paquet
  * 
  * Supprime les fichiers obsolètes (si présents)
  *
  * @param int|array $id_or_row
  *     Identifiant du paquet ou description ligne SQL du paquet
  * @return bool|array
  *     False si erreur.
  *     Tableau de 2 index sinon :
  *     - dir : Chemin du paquet téléchargé depuis la racine
  *     - dossier : Chemin du paquet téléchargé, depuis _DIR_PLUGINS
  */
 function get_paquet_id($id_or_row)
 {
     // on peut passer direct le row sql...
     if (!is_array($id_or_row)) {
         $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($id_or_row));
     } else {
         $i = $id_or_row;
     }
     unset($id_or_row);
     if ($i['nom_archive'] and $i['id_depot']) {
         $this->log("Recuperer l'archive : " . $i['nom_archive']);
         if ($adresse = sql_getfetsel('url_archives', 'spip_depots', 'id_depot=' . sql_quote($i['id_depot']))) {
             $zip = $adresse . '/' . $i['nom_archive'];
             // destination : auto/prefixe/version (sinon auto/nom_archive/version)
             $prefixe = sql_getfetsel('pl.prefixe', array('spip_paquets AS pa', 'spip_plugins AS pl'), array('pa.id_plugin = pl.id_plugin', 'pa.id_paquet=' . sql_quote($i['id_paquet'])));
             // prefixe
             $base = $prefixe ? strtolower($prefixe) : substr($i['nom_archive'], 0, -4);
             // enlever .zip ...
             // prefixe/version
             $dest = $base . '/v' . denormaliser_version($i['version']);
             // si on tombe sur un auto/X ayant des fichiers (et pas uniquement des dossiers)
             // ou un dossier qui ne commence pas par 'v'
             // c'est que auto/X n'était pas chargé avec SVP
             // ce qui peut arriver lorsqu'on migre de SPIP 2.1 à 3.0
             // dans ce cas, on supprime auto X pour mettre notre nouveau paquet.
             $ecraser_base = false;
             if (is_dir(_DIR_PLUGINS_AUTO . $base)) {
                 $base_files = scandir(_DIR_PLUGINS_AUTO . $base);
                 if (is_array($base_files)) {
                     $base_files = array_diff($base_files, array('.', '..'));
                     foreach ($base_files as $f) {
                         if ($f[0] != '.' and $f[0] != 'v' or $f[0] != '.' and !is_dir(_DIR_PLUGINS_AUTO . $base . '/' . $f)) {
                             // commence par v mais pas repertoire
                             $ecraser_base = true;
                             break;
                         }
                     }
                 }
             }
             if ($ecraser_base) {
                 supprimer_repertoire(_DIR_PLUGINS_AUTO . $base);
             }
             // on recupere la mise a jour...
             include_spip('action/teleporter');
             $teleporter_composant = charger_fonction('teleporter_composant', 'action');
             $ok = $teleporter_composant('http', $zip, _DIR_PLUGINS_AUTO . $dest);
             if ($ok === true) {
                 return array('dir' => _DIR_PLUGINS_AUTO . $dest, 'dossier' => 'auto/' . $dest);
             }
             $this->err($ok);
             $this->log("Téléporteur en erreur : " . $ok);
         } else {
             $this->log("Aucune adresse pour le dépot " . $i['id_depot']);
         }
     }
     return false;
 }
Esempio n. 4
0
/**
 * Suppression complete d'un repertoire.
 *
 * @link http://www.php.net/manual/en/function.rmdir.php#92050
 *
 * @param string $dir Chemin du repertoire
 * @return bool Suppression reussie.
 */
function supprimer_repertoire($dir)
{
    if (!file_exists($dir)) {
        return true;
    }
    if (!is_dir($dir) || is_link($dir)) {
        return @unlink($dir);
    }
    foreach (scandir($dir) as $item) {
        if ($item == '.' || $item == '..') {
            continue;
        }
        if (!supprimer_repertoire($dir . "/" . $item)) {
            @chmod($dir . "/" . $item, 0777);
            if (!supprimer_repertoire($dir . "/" . $item)) {
                return false;
            }
        }
    }
    return @rmdir($dir);
}
Esempio n. 5
0
/**
 * Déplace un répertoire pour libérer l'emplacement.
 *
 * Si le répertoire donné existe, le déplace dans un répertoire de backup.
 * Si ce backup existe déjà, il est supprimé auparavant.
 * Retourne le nouveau chemin du répertoire.
 * 
 * @param string $dest
 *     Chemin du répertoire à déplacer
 * @return string
 *     Nouveau chemin du répertoire s'il existait,
 *     Chaîne vide sinon
**/
function teleporter_nettoyer_vieille_version($dest)
{
    $old = "";
    if (is_dir($dest)) {
        $dir = dirname($dest);
        $base = basename($dest);
        $old = "{$dir}/.{$base}.bck";
        if (is_dir($old)) {
            supprimer_repertoire($old);
        }
        rename($dest, $old);
    }
    return $old;
}
Esempio n. 6
0
function supprimer_repertoire($dir)
{
    $current_dir = opendir($dir);
    while ($entryname = readdir($current_dir)) {
        if (is_dir("{$dir}/{$entryname}") and ($entryname != "." and $entryname != "..")) {
            supprimer_repertoire("{$dir}/{$entryname}");
        } elseif ($entryname != "." and $entryname != "..") {
            unlink("{$dir}/{$entryname}");
        }
    }
    //Fin tant que
    closedir($current_dir);
    rmdir(${dir});
}