* * This file is part of NOCC. NOCC is free software under the terms of the * GNU General Public License. You should have received a copy of the license * along with NOCC. If not, see . * * @package NOCC * @license http://www.gnu.org/licenses/ GNU General Public License * @version SVN: $Id: update.php 2610 2016-08-30 08:48:56Z oheil $ */ require_once './common.php'; $currentdir=getcwd(); try { $pop = new nocc_imap(); $pop->close(); } catch (Exception $ex) { require_once './utils/proxy.php'; Header('Location: ' . $conf->base_url . 'index.php?'.NOCC_Session::getUrlGetSession()); return; } require './html/header.php'; require './html/menu_inbox.php'; $state_ok=true; $start_time=time(); echo '
'; echo '

This section is available only in english.

'; if( $state_ok && ( !isset($_SESSION['auto_update']) || !$_SESSION['auto_update'] ) ) { echo '

Missing proper rights, contact your system administrator.

'; $state_ok=false; } if( $state_ok && ini_get("allow_url_fopen")!=1 ) { echo '

php.ini "allow_url_fopen" is not set, contact your system administrator.

'; unset($_SESSION['auto_update_new']); $state_ok=false; } if( $state_ok && ( !isset($_SESSION['auto_update_new']) || $_SESSION['auto_update_new']===2 ) ) { echo '

New NOCC version is undetermined, please try again.

'; unset($_SESSION['auto_update_new']); $state_ok=false; } if( $state_ok && ( !isset($_SESSION['auto_update_new']) || $_SESSION['auto_update_new']===1 ) ) { echo '

No new NOCC version.

'; $state_ok=false; } $nocc_update_running=false; if( $state_ok && is_file("NOCC_UPDATE_RUNNING") ) { $nocc_update_running=true; echo '

Another update process is running!

'; echo '

Please wait some minutes to make sure that a running process can finish.

'; echo '

Then, if possible, delete the file NOCC_UPDATE_RUNNING in your NOCC root directory if it still exists or contact your system administrator.

'; echo '

Go back into NOCC and check if an update is still needed.

'; $state_ok=false; } $new_version="undefined"; if( $state_ok ) { $new_version=$_SESSION['auto_update_new']; $new_version=str_ireplace("-dev","",$new_version); $new_v=explode('.',$new_version); $old_v=explode('.',str_ireplace("-dev","",$conf->nocc_version)); $old_dev_version=false; if( preg_match("/-dev/",$conf->nocc_version) ) { $old_dev_version=true; } if( ($old_dev_version && $old_v[0]==$new_v[0] && $old_v[1]==$new_v[1] && $old_v[2]<=$new_v[2]) || ($old_v[0]==$new_v[0] && $old_v[1]==$new_v[1] && $old_v[2]<$new_v[2]) || ($old_v[0]==$new_v[0] && $old_v[1]<$new_v[1]) || ($old_v[0]<$new_v[0]) || 0 ) { echo '

Udate from '.$conf->nocc_version.' to '.$new_version.' possible.

'; } else { echo '

No update possible. Current version: '.$conf->nocc_version.', new version: '.$new_version.'

'; unset($_SESSION['auto_update_new']); $state_ok=false; } } if( $state_ok ) { echo '

Your version is: '.$conf->nocc_version.', Updating to version: '.$new_version.'

'; echo '

Checking environment

'; $nocc_root=dirname(__FILE__); chdir($nocc_root); if( is_writable(".") ) { echo '

NOCC root directory is writable.

'; } else { echo '

NOCC root directory is not writable.

'; $state_ok=false; } $target_extract_dir="nocc-".$new_version; if( ! file_exists($target_extract_dir) ) { echo '

Directory '.$target_extract_dir.' does not exist. Good.

'; } else { echo '

Directory '.$target_extract_dir.' should not exist.

'; $state_ok=false; } if( strncasecmp(PHP_OS,"win",3)==0 ) { if( defined("ZIPARCHIVE::CREATE") ) { echo '

ZipArchive extension exists.

'; } else { echo '

ZipArchive extension missing.

'; $state_ok=false; } } if( defined("Phar::TAR") && Phar::TAR==2 && defined("Phar::ZIP") && Phar::ZIP==3 ) { echo '

Phar extension exists.

'; } else { echo '

Phar extension missing.

'; $state_ok=false; } try { $file_list=array( 'action.php', 'ckeditor.php', 'ckeditor5.php', //'ckeditor_php4.php', //'ckeditor_php5.php', 'addcgipath.sh', 'common.php', 'contacts_manager.php', 'contacts.php', 'delete.php', 'download.php', 'down_mail.php', 'favicon.ico', 'get_img.php', 'help.php', 'index.php', 'logout.php', 'robots.txt', 'rss.php', 'send.php', 'update.php' ); $file_list=array_merge($file_list,recursive_directory("htmlpurifier","/^.*(?getMessage()); require './html/error.php'; $state_ok=false; } foreach($file_list as $file) { if( file_exists($file) && ! is_writable($file) ) { if( is_file($file) ) { echo '

File '.$file.' is not writable!

'; } else if( is_dir($file) ) { echo '

Folder '.$file.' is not writable!

'; } else { echo '

File '.$file.' can not be checked for being writable!

'; } $state_ok=false; } } $number_of_files=count($file_list); if( $state_ok ) { echo '

All '.$number_of_files.' files are writable.

'; } $max_execution_time=ini_get("max_execution_time"); $end_time=time(); $diff_time=$end_time-$start_time; if( $diff_time >= 1 ) { echo '

Environment check took '.$diff_time.' seconds.

'; } else { $diff_time=1; echo '

Environment check took less than 1 second.

'; } $min_execution_time=30*$diff_time+60; if( $max_execution_time>$min_execution_time ) { echo '

Your php max_execution_time of '.$max_execution_time.' seconds seems to be sufficient.

'; } else { echo '

Your php max_execution_time of '.$max_execution_time.' could be to small. Please consider setting the php max_execution_time to at least '.($min_execution_time+20).' seconds.'; echo '

'; $state_ok=false; } } if( ! isset($_GET['doUpdate']) || $_GET['doUpdate']!=1 ) { if( $state_ok ) { //creating zip files with Phar has performance issues under windows if( strncasecmp(PHP_OS,"win",3)==0 ) { $archive_name="nocc-".$conf->nocc_version."_backup_".date("YmdHis").".zip"; } else { $archive_name="nocc-".$conf->nocc_version."_backup_".date("YmdHis").".tar.gz"; } //unpacking zip file with Phar does not work on windows if( strncasecmp(PHP_OS,"win",3)==0 ) { $download_link='http://downloads.sourceforge.net/project/nocc/NOCC/'.$new_version.'/nocc-'.$new_version.'.zip'; } else { $download_link='http://downloads.sourceforge.net/project/nocc/NOCC/'.$new_version.'/nocc-'.$new_version.'.tar.gz'; } echo '

Click here to automatically backup and update your existing NOCC installation. ONLY CLICK ONCE AND WAIT!

'; echo '

Change Log:

'; $news=file_get_contents('http://nocc.sourceforge.net/docs/NEWS?v='.$conf->nocc_version); echo ''; echo '

What will happen:

'; echo '

Backup:

'; echo ''; echo '

Update:

'; echo ''; } else { echo '

Automatic update not possible.

'; } } else { error_log('NOCC: user <'.$_SESSION['nocc_user'].'@'.$_SESSION['nocc_domain'].'> initiated system update'); if( $state_ok ) { if( $nocc_update_running ) { $state_ok=false; } else { $step=0; file_put_contents("NOCC_UPDATE_RUNNING",$step); } } if( $state_ok ) { echo '

Creating backup

'; try { //creating zip files with Phar has performance issues under windows if( strncasecmp(PHP_OS,"win",3)==0 ) { $archive_name="nocc-".$conf->nocc_version."_backup_".date("YmdHis").".zip"; echo '

Creating backup file: '.$archive_name.'

'; //$archive=new PharData($archive_name,FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO,"",Phar::ZIP); $archive=new ZipArchive(); $archive->open($archive_name,ZIPARCHIVE::CREATE); foreach($file_list as $file) { if( is_dir($file) ) { //$number_of_files--; $archive->addEmptyDir($file); } else { $archive->addFile($file); } } //unset($archive); $archive->close(); $archive=new PharData($archive_name); $number_of_files_check=$archive->count(); unset($archive); if( $number_of_files==$number_of_files_check ) { echo '

Created archive of '.$number_of_files_check.' files successfully: '.$archive_name.'

'; } else { echo '

Number of files in '.$archive_name.' is '.$number_of_files_check.', should be '.$number_of_files.'.

'; unlink($archive_name); $state_ok=false; } } else { $archive_name="nocc-".$conf->nocc_version."_backup_".date("YmdHis").".tar"; echo '

Creating backup file: '.$archive_name.'

'; $archive=new PharData($archive_name,FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO,"",Phar::TAR); foreach($file_list as $file) { //can not add directory name to archive under windows if( strncasecmp(PHP_OS,"win",3)==0 && is_dir($file) ) { $number_of_files--; } else { $archive->addFile($file); } } echo '

Compressing archive: '.$archive_name.'.gz

'; //the following fails in php 8.2 with Allowed memory size exhausted //$archive->compress(Phar::GZ); //doing it manually: $gzfile=gzcompressfile($archive_name); unset($archive); echo '

Removing file: '.$archive_name.'

'; Phar::unlinkArchive($archive_name); $archive_name=gzdecompressfile($gzfile); $archive=new PharData($archive_name); $number_of_files_check=$archive->count(); unset($archive); unlink($archive_name); if( $number_of_files==$number_of_files_check ) { echo '

Created archive of '.$number_of_files_check.' files successfully: '.$archive_name.'.gz

'; } else { echo '

Number of files in '.$archive_name.'.gz is '.$number_of_files_check.', should be '.$number_of_files.'.

'; unlink($archive_name.'.gz'); $state_ok=false; } } } catch (Exception $ex) { $ev = new NoccException($ex->getMessage()); require './html/error.php'; $state_ok=false; } } if( $state_ok ) { echo '

Download new version

'; //creating zip files with Phar has performance issues under windows //unpacking zip file with Phar does not work on windows if( strncasecmp(PHP_OS,"win",3)==0 ) { $archive_name='nocc-'.$new_version.'.zip'; $download_link='http://downloads.sourceforge.net/project/nocc/NOCC/'.$new_version.'/nocc-'.$new_version.'.zip'; } else { $archive_name='nocc-'.$new_version.'.tar.gz'; $download_link='http://downloads.sourceforge.net/project/nocc/NOCC/'.$new_version.'/nocc-'.$new_version.'.tar.gz'; } if( ! is_file($archive_name) ) { $fpc=file_put_contents($archive_name,fopen($download_link,'r')); if( $fpc!=false ) { echo '

Downloaded new version archive successful.

'; } else { echo '

Downloaded new version archive failed. You can savely try again.

'; $state_ok=false; } } else { echo '

New version archive already exists, proceeding to checksum.

'; } } if( $state_ok ) { echo '

Checking checksum

'; $ckecksums=file_get_contents('https://nocc.sourceforge.net/checksums.txt'); $checksum=""; $checksumType=""; $matches=array(); if( preg_match("/".$archive_name."\tsha256\t(\S+)\R/",$ckecksums,$matches) ) { $checksum=$matches[1]; $checksumType="sha256"; } else if( preg_match("/".$archive_name."\tmd5\t(\S+)\R/",$ckecksums,$matches) ) { $checksum=$matches[1]; $checksumType="md5"; } else if( preg_match("/".$archive_name."\t(\S+)\R/",$ckecksums,$matches) ) { $checksum=$matches[1]; $checksumType="md5"; } else { echo '

Could not find checksum. See also http://nocc.sourceforge.net/download/

'; $state_ok=false; } if( $checksumType == "md5" ) { $md5sum_check=md5_file($archive_name); if( $checksum == $md5sum_check) { echo '

MD5 checksums match: '.$checksum.'. See also http://nocc.sourceforge.net/download/

'; } else { echo '

Failed md5 checksum match: '.$md5sum_check.' should be '.$checksum.'.

'; echo '

See also http://nocc.sourceforge.net/download/

'; $state_ok=false; } } if( $checksumType == "sha256" ) { $sha256sum_check=hash_file("sha256",$archive_name); if( $checksum == $sha256sum_check ) { echo '

sha256 checksums match: '.$checksum.'. See also http://nocc.sourceforge.net/download/

'; } else { echo '

Failed sha256 checksum match: '.$sha256sum_check.' should be '.$checksum.'.

'; echo '

See also http://nocc.sourceforge.net/download/

'; $state_ok=false; } } } if( $state_ok ) { echo '

Unpacking new version

'; if( strncasecmp(PHP_OS,"win",3)==0 ) { $archive=new ZipArchive(); $archive->open($archive_name); $archive->extractTo('.'); $archive->close(); } else { //the following fails in php 8.2 with Allowed memory size exhausted //$archive=new PharData($archive_name); //doing it manually: $tar_archive_name=gzdecompressfile($archive_name); $archive=new PharData($tar_archive_name); $archive->extractTo('.'); unset($archive); unlink($tar_archive_name); } chdir($target_extract_dir); $file_list=recursive_directory(".","/^.*(?Failed creating file: '.$file.'.nocc-'.$new_version.'. Try manually.

'; } echo '

Important:
'; echo '  Integrate content of new file '.$file.".nocc-".$new_version.' into '.$file.'

'; } else { echo '

New file '.$target_extract_dir.DIRECTORY_SEPARATOR.$file.' and '.$file.' match, nothing to do.

'; } unlink($target_extract_dir.DIRECTORY_SEPARATOR.$file); } else { if( ! is_dir(dirname($file)) ) { mkdir(dirname($file),0777,true); } if( ! copy($target_extract_dir.DIRECTORY_SEPARATOR.$file,$file) ) { echo '

Failed to copy file: '.$file.'. Try manually.

'; } unlink($target_extract_dir.DIRECTORY_SEPARATOR.$file); } } else { if( is_file($target_extract_dir.DIRECTORY_SEPARATOR.$file) ) { if( ! is_dir(dirname($file)) ) { mkdir(dirname($file),0777,true); } if( ! copy($target_extract_dir.DIRECTORY_SEPARATOR.$file,$file) ) { echo '

Failed to copy file: '.$file.'. Try manually.

'; } unlink($target_extract_dir.DIRECTORY_SEPARATOR.$file); } else if( is_dir($target_extract_dir.DIRECTORY_SEPARATOR.$file) ) { rmdir($target_extract_dir.DIRECTORY_SEPARATOR.$file); } } } rmdir($target_extract_dir); } if( $state_ok ) { echo '

Removing deprecated files

'; $file_list=array( 'ckeditor_php4.php', 'ckeditor_php5.php', ); foreach($file_list as $file) { if( file_exists($file) ) { if( ! unlink($file) ) { echo '

Failed to remove deprecated file: '.$file.'. Try manually.

'; } else { echo '

File '.$file.' removed.

'; } } } } $end_time=time(); $diff_time=$end_time-$start_time; if( ! $state_ok ) { echo '

Update failed.

'; } else { echo '

Update took '.$diff_time.' seconds to finish successfully.

'; unset($_SESSION['auto_update_new']); } if( ! $nocc_update_running && is_file("NOCC_UPDATE_RUNNING") ) { unlink("NOCC_UPDATE_RUNNING"); } } echo '

'; chdir($currentdir); require './html/menu_inbox.php'; require './html/footer.php'; // https://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php/56140427#56140427 function gzcompressfile(string $inFilename, int $level = 9): string { // Is the file gzipped already? $extension = pathinfo($inFilename, PATHINFO_EXTENSION); if ($extension == "gz") { return $inFilename; } // Open input file $inFile = fopen($inFilename, "rb"); if ($inFile === false) { throw new \Exception("Unable to open input file: $inFilename"); } // Open output file $gzFilename = $inFilename.".gz"; $mode = "wb".$level; $gzFile = gzopen($gzFilename, $mode); if ($gzFile === false) { fclose($inFile); throw new \Exception("Unable to open output file: $gzFilename"); } // Stream copy $length = 512 * 1024; // 512 kB while (!feof($inFile)) { gzwrite($gzFile, fread($inFile, $length)); } // Close files fclose($inFile); gzclose($gzFile); // Return the new filename return $gzFilename; } // https://stackoverflow.com/questions/3293121/how-can-i-unzip-a-gz-file-with-php function gzdecompressfile(string $file_name): string { // Raising this value may increase performance $buffer_size = 4096; // read 4kb at a time $out_file_name = str_replace('.gz', '', $file_name); // Open our files (in binary mode) $file = gzopen($file_name, 'rb'); $out_file = fopen($out_file_name, 'wb'); // Keep repeating until the end of the input file while(!gzeof($file)) { // Read buffer-size bytes // Both fwrite and gzread and binary-safe fwrite($out_file, gzread($file, $buffer_size)); } // Files are done, close files fclose($out_file); gzclose($file); return $out_file_name; }