* Copyright (C) 2008-2009 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * 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, see . */ /** * \file htdocs/ftp/index.php * \ingroup ftp * \brief Main page for FTP section area * \author Laurent Destailleur */ require('../main.inc.php'); require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php'; // Load traductions files $langs->load("ftp"); $langs->load("companies"); $langs->load("other"); // Security check if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'ftp',''); // Get parameters $action = isset($_GET["action"])?$_GET["action"]:$_POST['action']; $section=isset($_GET["section"])?$_GET["section"]:$_POST['section']; if (! $section) $section='/'; $numero_ftp = GETPOST("numero_ftp"); if (! $numero_ftp) $numero_ftp=1; $file=isset($_GET["file"])?$_GET["file"]:$_POST['file']; $upload_dir = $conf->ftp->dir_temp; $download_dir = $conf->ftp->dir_temp; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page",'int'); if ($page == -1) { $page = 0; } $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="label"; $s_ftp_name='FTP_NAME_'.$numero_ftp; $s_ftp_server='FTP_SERVER_'.$numero_ftp; $s_ftp_port='FTP_PORT_'.$numero_ftp; $s_ftp_user='FTP_USER_'.$numero_ftp; $s_ftp_password='FTP_PASSWORD_'.$numero_ftp; $s_ftp_passive='FTP_PASSIVE_'.$numero_ftp; $ftp_name=$conf->global->$s_ftp_name; $ftp_server=$conf->global->$s_ftp_server; $ftp_port=$conf->global->$s_ftp_port; if (empty($ftp_port)) $ftp_port=21; $ftp_user=$conf->global->$s_ftp_user; $ftp_password=$conf->global->$s_ftp_password; $ftp_passive=$conf->global->$s_ftp_passive; $conn_id=null; // FTP connection ID /******************************************************************* * ACTIONS * * Put here all code to do according to value of "action" parameter ********************************************************************/ // Envoie fichier if ( $_POST["sendit"] && ! empty($conf->global->MAIN_UPLOAD_DOC)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $result=$ecmdir->fetch($_REQUEST["section"]); if (! $result > 0) { dol_print_error($db,$ecmdir->error); exit; } $relativepath=$ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; if (dol_mkdir($upload_dir) >= 0) { $resupload = dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_dir . "/" . dol_unescapefile($_FILES['userfile']['name']),0); if (is_numeric($resupload) && $resupload > 0) { $result=$ecmdir->changeNbOfFiles('+'); } else { $langs->load("errors"); if ($resupload < 0) // Unknown error { setEventMessage($langs->trans("ErrorFileNotUploaded"), 'errors'); } else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload)) // Files infected by a virus { setEventMessage($langs->trans("ErrorFileIsInfectedWithAVirus"), 'errors'); } else // Known error { setEventMessage($langs->trans($resupload), 'errors'); } } } else { // Echec transfert (fichier depassant la limite ?) $langs->load("errors"); setEventMessage($langs->trans("ErrorFailToCreateDir",$upload_dir), 'errors'); } } // Action ajout d'un rep if ($_POST["action"] == 'add' && $user->rights->ftp->setup) { $ecmdir->ref = $_POST["ref"]; $ecmdir->label = $_POST["label"]; $ecmdir->description = $_POST["desc"]; $id = $ecmdir->create($user); if ($id > 0) { header("Location: ".$_SERVER["PHP_SELF"]); exit; } else { //TODO: Translate setEventMessage('Error '.$langs->trans($ecmdir->error)); $_GET["action"] = "create"; } } // Remove file if ($_REQUEST['action'] == 'confirm_deletefile' && $_REQUEST['confirm'] == 'yes') { // set up a connection or die if (! $conn_id) { $newsectioniso=utf8_decode($section); $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $newsectioniso, $ftp_passive); $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; } if ($conn_id && $ok && ! $mesg) { $langs->load("other"); // Remote file $filename=$file; $remotefile=$section.(preg_match('@[\\\/]$@',$section)?'':'/').$file; $newremotefileiso=utf8_decode($remotefile); //print "x".$newremotefileiso; dol_syslog("ftp/index.php ftp_delete ".$newremotefileiso); $result=@ftp_delete($conn_id, $newremotefileiso); if ($result) { setEventMessage($langs->trans("FileWasRemoved",$file)); } else { dol_syslog("ftp/index.php ftp_delete", LOG_ERR); setEventMessage($langs->trans("FTPFailedToRemoveFile",$file), 'errors'); } //ftp_close($conn_id); Close later $action=''; } else { dol_print_error('',$mesg); } } // Delete several lines at once if ($_POST["const"] && $_POST["delete"] && $_POST["delete"] == $langs->trans("Delete")) { // set up a connection or die if (! $conn_id) { $newsectioniso=utf8_decode($section); $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $newsectioniso, $ftp_passive); $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; } if ($conn_id && $ok && ! $mesg) { foreach($_POST["const"] as $const) { if ($const["check"]) // Is checkbox checked { $langs->load("other"); // Remote file $file=$const["file"]; $section=$const["section"]; $remotefile=$section.(preg_match('@[\\\/]$@',$section)?'':'/').$file; $newremotefileiso=utf8_decode($remotefile); //print "x".$newremotefileiso; dol_syslog("ftp/index.php ftp_delete ".$newremotefileiso); $result=@ftp_delete($conn_id, $newremotefileiso); if ($result) { setEventMessage($langs->trans("FileWasRemoved",$file)); } else { dol_syslog("ftp/index.php ftp_delete", LOG_ERR); setEventMessage($langs->trans("FTPFailedToRemoveFile",$file), 'errors'); } //ftp_close($conn_id); Close later $action=''; } } } else { dol_print_error('',$mesg); } } // Remove directory if ($_REQUEST['action'] == 'confirm_deletesection' && $_REQUEST['confirm'] == 'yes') { // set up a connection or die if (! $conn_id) { $newsectioniso=utf8_decode($section); $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $newsectioniso, $ftp_passive); $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; } if ($conn_id && $ok && ! $mesg) { // Remote file $filename=$file; $remotefile=$section.(preg_match('@[\\\/]$@',$section)?'':'/').$file; $newremotefileiso=utf8_decode($remotefile); $result=@ftp_rmdir($conn_id, $newremotefileiso); if ($result) { setEventMessage($langs->trans("DirWasRemoved",$file)); } else { setEventMessage($langs->trans("FTPFailedToRemoveDir",$file), 'errors'); } //ftp_close($conn_id); Close later $action=''; } else { dol_print_error('',$mesg); } } // Download directory if ($_REQUEST['action'] == 'download') { // set up a connection or die if (! $conn_id) { $newsectioniso=utf8_decode($section); $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $newsectioniso, $ftp_passive); $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; } if ($conn_id && $ok && ! $mesg) { // Local file $localfile=tempnam($download_dir,'dol_'); // Remote file $filename=$file; $remotefile=$section.(preg_match('@[\\\/]$@',$section)?'':'/').$file; $newremotefileiso=utf8_decode($remotefile); $result=ftp_get($conn_id,$localfile,$newremotefileiso,FTP_BINARY); if ($result) { if (! empty($conf->global->MAIN_UMASK)) @chmod($localfile, octdec($conf->global->MAIN_UMASK)); // Define mime type $type = 'application/octet-stream'; if (! empty($_GET["type"])) $type=$_GET["type"]; else $type=dol_mimetype($original_file); // Define attachment (attachment=true to force choice popup 'open'/'save as') $attachment = true; if ($encoding) header('Content-Encoding: '.$encoding); if ($type) header('Content-Type: '.$type); if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); else header('Content-Disposition: inline; filename="'.$filename.'"'); // Ajout directives pour resoudre bug IE header('Cache-Control: Public, must-revalidate'); header('Pragma: public'); readfile($localfile); ftp_close($conn_id); exit; } else { setEventMessages($langs->transnoentitiesnoconv('FailedToGetFile',$remotefile), null, 'errors'); } } else { dol_print_error('',$mesg); } //ftp_close($conn_id); Close later } /******************************************************************* * PAGE * * Put here all code to do according to value of "action" parameter ********************************************************************/ llxHeader(); // Add logic to shoow/hide buttons if ($conf->use_javascript_ajax) { ?> trans("FTPArea")); print $langs->trans("FTPAreaDesc")."
"; if (! function_exists('ftp_connect')) { print $langs->trans("FTPFeatureNotSupportedByYourPHP"); } else { if (! empty($ftp_server)) { // Confirm remove file if ($_GET['action'] == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode($_REQUEST["section"]).'&file='.urlencode($_GET["file"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1); } // Confirmation de la suppression d'une ligne categorie if ($_GET['action'] == 'delete_section') { print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode($_REQUEST["section"]).'&file='.urlencode($_GET["file"]), $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection','','',1); } print $langs->trans("Server").': '.$ftp_server.'
'; print $langs->trans("Port").': '.$ftp_port.' '.($ftp_passive?"(Passive)":"(Active)").'
'; print $langs->trans("User").': '.$ftp_user.'
'; print $langs->trans("Directory").': '; $sectionarray=preg_split('|[\/]|',$section); // For / $newsection='/'; print ''; print '/'; print ' '; // For other directories $i=0; foreach($sectionarray as $val) { if (empty($val)) continue; // Discard first and last entry that should be empty as section start/end with / if ($i > 0) { print ' / '; $newsection.='/'; } $newsection.=$val; print ''; print $val; print ''; $i++; } print '
'; print "
\n"; print '
'; print ''; print ''; // Construit liste des repertoires print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; // set up a connection or die if (! $conn_id) { $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive); $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; } if ($ok) { //$type = ftp_systype($conn_id); $newsectioniso=utf8_decode($section); $buff = ftp_rawlist($conn_id, $newsectioniso); $contents = ftp_nlist($conn_id, $newsectioniso); // Sometimes rawlist fails but never nlist //var_dump($contents); //var_dump($buff); $nboflines=count($contents); $var=true; $rawlisthasfailed=false; $i=0; while ($i < $nboflines && $i < 1000) { $vals=preg_split('@ +@',utf8_encode($buff[$i]),9); //$vals=preg_split('@ +@','drwxr-xr-x 2 root root 4096 Aug 30 2008 backup_apollon1',9); //var_dump($vals); $file=$vals[8]; if (empty($file)) { $rawlisthasfailed=true; $file=utf8_encode($contents[$i]); } if ($file == '.' || ($file == '..' && $section == '/')) { $i++; continue; } // Is it a directory ? $is_directory=0; if ($file == '..') $is_directory=1; else if (! $rawlisthasfailed) { if (preg_match('/^d/',$vals[0])) $is_directory=1; if (preg_match('/^l/',$vals[0])) $is_link=1; } else { // Remote file $filename=$file; //print "section=".$section.' file='.$file.'X'; //print preg_match('@[\/]$@','aaa/').'Y'; //print preg_match('@[\\\/]$@',"aaa\\").'Y'; $remotefile=$section.(preg_match('@[\\\/]$@',$section)?'':'/').preg_replace('@^[\\\/]@','',$file); //print 'A'.$remotefile.'A'; $newremotefileiso=utf8_decode($remotefile); //print 'Z'.$newremotefileiso.'Z'; $is_directory=ftp_isdir($conn_id, $newremotefileiso); } $var=!$var; print ''; // Name print ''; // Size print ''; // Date print ''; // User print ''; // Group print ''; // Permissions print ''; // Action print ''; print ''."\n"; $i++; $nbofentries++; } } print "
'.$langs->trans("Content").''.$langs->trans("Size").''.$langs->trans("Date").''.$langs->trans("Owner").''.$langs->trans("Group").''.$langs->trans("Permissions").''; print ''.img_picto($langs->trans("Refresh"),'refresh').' '; print '
'; $newsection=$section.(preg_match('@[\\\/]$@',$section)?'':'/').$file; $newsection=preg_replace('@[\\\/][^\\\/]+[\\\/]\.\.$@','/',$newsection); // Change aaa/xxx/.. to new aaa if ($is_directory) print ''; print $file; if ($is_directory) print ''; print ''; if (! $is_directory && ! $is_link) print $vals[4]; else print ' '; print ''; print $vals[5].' '.$vals[6].' '.$vals[7]; print ''; print $vals[2]; print ''; print $vals[3]; print ''; print $vals[0]; print ''; if ($is_directory) { if ($file != '..') print ''.img_delete().''; else print ' '; } else if ($is_link) { $newfile=$file; $newfile=preg_replace('/ ->.*/','',$newfile); print ''.img_delete().''; } else { print ''.img_picto('','file').''; print '   '; print ''; print '   '; print ''.img_delete().''; print ''; print ''; } print '
"; // Actions /* if ($user->rights->ftp->write && ! empty($section)) { $formfile->form_attach_new_file(DOL_URL_ROOT.'/ftp/index.php','',0,$section,1); } else print ' '; */ print '
'; print '
'; print ''; print '
'; print "
"; } else { print $langs->trans("SetupOfFTPClientModuleNotComplete"); } } print '
'; // Close FTP connection if ($conn_id) ftp_close($conn_id); // End of page $db->close(); llxFooter(); /** * Connect to FTP server * * @param string $ftp_server Server name * @param string $ftp_port Server port * @param string $ftp_user FTP user * @param string $ftp_password FTP password * @param string $section Directory * @param integer $ftp_passive Use a passive mode * @return int <0 if OK, >0 if KO */ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive=0) { global $langs, $conf; $ok=1; if (! is_numeric($ftp_port)) { $mesg=$langs->trans("FailedToConnectToFTPServer",$ftp_server,$ftp_port); $ok=0; } if ($ok) { $connecttimeout=(empty($conf->global->FTP_CONNECT_TIMEOUT)?40:$conf->global->FTP_CONNECT_TIMEOUT); if (! empty($conf->global->FTP_CONNECT_WITH_SSL)) $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); else $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); if ($conn_id) { if ($ftp_user) { if (ftp_login($conn_id, $ftp_user, $ftp_password)) { // Turn on passive mode transfers (must be after a successful login if ($ftp_passive) ftp_pasv($conn_id, true); // Change the dir $newsectioniso=utf8_decode($section); ftp_chdir($conn_id, $newsectioniso); } else { $mesg=$langs->trans("FailedToConnectToFTPServerWithCredentials"); $ok=0; } } } else { $mesg=$langs->trans("FailedToConnectToFTPServer",$ftp_server,$ftp_port); $ok=0; } } $arrayresult=array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg); return $arrayresult; } /** * Tell if an entry is a FTP directory * * @param resource $connect_id Connection handler * @param string $dir Directory * @return int 1=directory, 0=not a directory */ function ftp_isdir($connect_id,$dir) { if (@ftp_chdir($connect_id,$dir)) { ftp_cdup($connect_id); return 1; } else { return 0; } }