ldapsaisie/src/includes/addons/LSaddons.ftp.php
2023-10-13 19:28:12 +02:00

247 lines
7.4 KiB
PHP

<?php
/*******************************************************************************
* Copyright (C) 2007 Easter-eggs
* https://ldapsaisie.org
*
* Author: See AUTHORS file in top-level directory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/
// Error messages
// Support
LSerror :: defineError('FTP_SUPPORT_01',
___("FTP support: PHP ftp extension is missing.")
);
// Other errors
LSerror :: defineError('FTP_00',
___("FTP error: %{msg}")
);
LSerror :: defineError('FTP_01',
___("FTP: Unable to connect to FTP Server (Step : %{step}).")
);
LSerror :: defineError('FTP_02',
___("FTP: Unable to make directory %{dir} on the remote server.")
);
LSerror :: defineError('FTP_03',
___("FTP: Unable to list directory %{dir} content on the remote server.")
);
LSerror :: defineError('FTP_04',
___("FTP: Unable to delete directory %{dir} on the remote server.")
);
LSerror :: defineError('FTP_05',
___("FTP: Unable to delete file %{file} on the remote server.")
);
LSerror :: defineError('FTP_06',
___("FTP: Unable to modify rights on the directory %{dir} on the remote server.")
);
LSerror :: defineError('FTP_07',
___("FTP: Unable to rename folder from %{old} to %{new} on the remote server.")
);
/**
* Check support of FTP addon
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @return boolean true if FTP addon is fully supported, false in other case
*/
function LSaddon_ftp_support() {
$retval = true;
// PHP ftp extension dependency
if (!function_exists('ftp_connect')) {
LSerror :: addErrorCode('FTP_SUPPORT_01');
$retval = false;
}
return $retval;
}
/**
* Log last FTP error
* @return void
*/
function _logLastFtpError() {
$error = error_get_last();
if ($error) LSerror :: addErrorCode('FTP_00', $error['message']);
}
/**
* Connect to FTP server
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @param string $host FTP server FQDN or IP address
* @param string $port The TCP port of the FTP server
* @param string $user The username
* @param string $pwd The password
*
* @return FTP\Connection|resource|false FTP\Connection (or resource with PHP <= 8.1.0) in case of
* success, false otherwise
*/
function connectToFTP($host, $port, $user, $pwd) {
$cnx = @ftp_connect($host, $port);
if ($cnx === false) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_01', "1");
return false;
}
if (@ftp_login($cnx, $user, $pwd))
return $cnx;
_logLastFtpError();
LSerror :: addErrorCode('FTP_01', "2");
return false;
}
/**
* Create one or more directories throught FTP
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @param string $host FTP server FQDN or IP address
* @param string $port The TCP port of the FTP server
* @param string $user The username
* @param string $pwd The password
* @param array|string $dirs The directory/ies to add
* @param int $chmod The directory/ies mode as an octal number (do not forget leading zero,
* example: 0755 or 02755, default : default umask on the SSH server)
*
* @return boolean
*/
function createDirsByFTP($host, $port, $user, $pwd, $dirs, $chmod=NULL) {
$cnx = connectToFTP($host, $port, $user, $pwd);
if (!$cnx) return false;
foreach(ensureIsArray($dirs) as $dir) {
if (@ftp_mkdir($cnx, $dir) === false) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_02', $dir);
return false;
}
if ($chmod && !@ftp_chmod($cnx, $chmod, $dir)) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_06', $dir);
}
}
return true;
}
/**
* Internal function call recursively to remove a directory and its content
* @param FTP\Connection|resource $cnx The FTP\Connection object (or resource with PHP < 8.1.0)
* @param string $dir The directory path to remove
* @return boolean
*/
function _removeDirByFTP(&$cnx, $dir) {
if ($dir[strlen($dir)-1] == '/')
$dir = substr($dir, 0, strlen($dir)-1);
$items = @ftp_nlist($cnx, $dir);
LSlog :: get_logger('LSaddon_ftp') -> trace(
"_removeDirByFTP($dir): directory content: ".varDump($items));
if (!is_array($items)) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_03', $dir);
return false;
}
foreach($items as $item) {
if (@ftp_chdir($cnx, $item)) {
LSlog :: get_logger('LSaddon_ftp') -> trace(
"_removeDirByFTP($dir): item '$item' is a directory, delete it recursively");
if (!_removeDirByFTP($cnx, $item))
return false;
}
else {
LSlog :: get_logger('LSaddon_ftp') -> trace(
"_removeDirByFTP($dir): item '$item' is a file, delete it");
if (!@ftp_delete($cnx, $item)) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_05', $item);
return false;
}
else {
LSlog :: get_logger('LSaddon_ftp') -> trace(
"_removeDirByFTP($dir): file '$item' removed");
}
}
}
if (@!ftp_rmdir($cnx, $dir)) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_04', $dir);
return false;
}
else {
LSlog :: get_logger('LSaddon_ftp') -> trace(
"_removeDirByFTP($dir): directory '$dir' removed");
}
return true;
}
/**
* Delete one or more directories throught FTP
*
* Caution : recursive deletion ! The content of the directory will be listed and deleted before the
* directory. If your FTP server is configured to mask some files or directories (for instance,
* starting by '.'), they will not be listed and deleted and this may cause the deletion to fail.
* With VsFTPd, you have to add force_dot_files=1 in configuration.
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @param string $host FTP server FQDN or IP address
* @param string $port The TCP port of the FTP server
* @param string $user The username
* @param string $pwd The password
* @param array|string $dirs The directory/ies to remove
*
* @return boolean
*/
function removeDirsByFTP($host, $port, $user, $pwd, $dirs) {
$cnx = connectToFTP($host, $port, $user, $pwd);
if (!$cnx) return false;
foreach(ensureIsArray($dirs) as $dir)
if (!_removeDirByFTP($cnx, $dir))
return false;
return true;
}
/**
* Rename a directory throught FTP
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @param string $host FTP server FQDN or IP address
* @param string $port The TCP port of the FTP server
* @param string $user The username
* @param string $pwd The password
* @param string $old The actual directory path to rename
* @param string $new The new directory path
*
* @return boolean
*/
function renameDirByFTP($host, $port, $user, $pwd, $old, $new) {
$cnx = connectToFTP($host, $port, $user, $pwd);
if (!$cnx) return false;
if (!@ftp_rename($cnx, $old, $new)) {
_logLastFtpError();
LSerror :: addErrorCode('FTP_07', array('old' => $old, 'new' => $new));
return false;
}
return true;
}