2015-12-11 04:08:32 +00:00
#!/usr/bin/env php
2015-02-21 08:44:03 +00:00
< ? php
2017-02-10 16:05:45 +00:00
/* Copyright ( C ) 2015 - 2017 Laurent Destailleur < eldy @ users . sourceforge . net >
2024-09-22 23:59:14 +00:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2015-02-24 11:44:12 +00:00
*
* 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
2019-06-23 13:27:11 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2015-02-24 11:44:12 +00:00
*/
/**
2025-01-05 13:46:26 +00:00
* \file dev / build / generate_filelist_xml . php
2015-02-24 11:44:12 +00:00
* \ingroup dev
* \brief This script create a xml checksum file
*/
2023-12-04 09:16:54 +00:00
if ( ! defined ( 'NOREQUIREDB' )) {
2021-02-28 23:48:36 +00:00
define ( 'NOREQUIREDB' , '1' ); // Do not create database handler $db
}
2025-11-19 15:18:09 +00:00
define ( 'NOREQUIREVIRTUALURL' , 1 );
2018-06-05 16:21:56 +00:00
2015-02-24 11:44:12 +00:00
$sapi_type = php_sapi_name ();
$script_file = basename ( __FILE__ );
2023-12-04 09:16:54 +00:00
$path = dirname ( __FILE__ ) . '/' ;
2015-02-24 11:44:12 +00:00
// Test if batch mode
if ( substr ( $sapi_type , 0 , 3 ) == 'cgi' ) {
2021-02-28 23:48:36 +00:00
echo " Error: You are using PHP for CGI. To execute " . $script_file . " from command line, you must use PHP for CLI mode. \n " ;
2024-07-06 15:53:24 +00:00
exit ( 1 );
2015-02-24 11:44:12 +00:00
}
2025-11-19 15:16:53 +00:00
define ( 'DOL_DOCUMENT_ROOT' , dirname ( dirname ( $path )) . '/htdocs' );
2026-01-16 13:50:36 +00:00
//$algo = 'md5'; // Old algorithm
2025-12-22 03:52:12 +00:00
$algo = 'sha256' ;
2025-04-10 11:06:13 +00:00
require_once $path . " ../../htdocs/master.inc.php " ;
2018-07-26 09:57:25 +00:00
require_once DOL_DOCUMENT_ROOT . " /core/lib/files.lib.php " ;
2026-05-26 15:10:30 +00:00
require_once DOL_DOCUMENT_ROOT . " /blockedlog/versionmod.inc.php " ;
2026-06-19 21:40:38 +00:00
/** @var array $arrayofunalterablefiles */
2026-05-26 15:10:30 +00:00
2016-09-30 13:41:08 +00:00
/*
* Main
*/
2023-12-04 09:16:54 +00:00
$includecustom = 0 ;
$includeconstants = array ();
$buildzip = 0 ;
2025-11-17 15:39:27 +00:00
$release = '' ;
$checklock = '' ;
2017-02-10 16:05:45 +00:00
2025-10-11 11:01:49 +00:00
print '***** ' . $script_file . ' *****' . " \n " ;
2019-01-27 12:23:32 +00:00
if ( empty ( $argv [ 1 ])) {
2025-10-11 11:01:49 +00:00
print " Usage: " . $script_file . " release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1] \n " ;
2026-04-08 17:52:45 +00:00
print " Usage: " . $script_file . " checklock=auto[-mybuild]|x.y.z[-mybuild] name_of_locked_scope \n " ;
2025-11-17 15:39:27 +00:00
print " \n " ;
2025-10-28 12:07:19 +00:00
print " Example: " . $script_file . " release=6.0.0 includecustom=1 includeconstant=ES:CONST_XX_IS_ON includeconstant=all:MAILING_NO_USING_PHPMAIL:1 \n " ;
2026-04-08 17:52:45 +00:00
print " Example: " . $script_file . " checklock=auto unalterable_files \n " ;
2025-10-11 11:01:49 +00:00
print " \n " ;
2026-04-08 17:52:45 +00:00
print " Generate the XML filelist-x.y.z[-mybuild].xml with the signature of files. " ;
print " The XML always includes the 3 sections: \n " ;
2025-09-27 16:28:35 +00:00
print " - dolibarr_htdocs_dir \n " ;
print " - dolibarr_scripts_dir \n " ;
print " - dolibarr_unalterable_files (only files inside the scope of the unalterable module) \n " ;
2026-04-08 17:52:45 +00:00
print " and if a specific setup/parameter need to be included into the signature: \n " ;
2025-10-28 12:07:19 +00:00
print " - dolibarr_constants \n " ;
2025-09-27 16:28:35 +00:00
print " \n " ;
2026-04-08 17:52:45 +00:00
print " If used with the parameter 'checklock' 'unalterable_files', it will validate that the signature generated is the same than the one for scope 'unalterable_files' found into dev/lockedfiles.txt \n " ;
2025-11-17 15:39:27 +00:00
print " \n " ;
2024-07-06 15:44:20 +00:00
exit ( 1 );
2016-09-30 13:41:08 +00:00
}
2021-03-01 23:48:02 +00:00
2016-09-30 13:41:08 +00:00
2026-04-08 17:52:45 +00:00
// We can defined here a list of scopes that need a dedicated signature
$arrayoflockedscopes = array (
'unalterable_files' => DOLCERT_VERSION // The scope for the French Loi Finance and certification
);
2023-12-04 09:16:54 +00:00
$i = 0 ;
2023-03-24 18:33:51 +00:00
$result = array ();
2019-01-27 12:23:32 +00:00
while ( $i < $argc ) {
2022-08-31 20:14:20 +00:00
if ( ! empty ( $argv [ $i ])) {
2022-11-25 22:53:16 +00:00
parse_str ( $argv [ $i ], $result ); // set all params $release, $includecustom, $includeconstant, $buildzip ...
2021-02-28 23:48:36 +00:00
}
2022-11-25 22:53:16 +00:00
if ( ! empty ( $result [ " release " ])) {
$release = $result [ " release " ];
}
2025-11-17 15:39:27 +00:00
if ( ! empty ( $result [ " checklock " ])) {
$checklock = $result [ " checklock " ];
}
2022-11-25 22:53:16 +00:00
if ( ! empty ( $result [ " includecustom " ])) {
$includecustom = $result [ " includecustom " ];
}
2025-11-17 15:39:27 +00:00
if ( preg_match ( '/unalterable_files/' , strval ( $argv [ $i ]))) {
$checksource = 'unalterable_files' ;
}
2022-11-25 22:53:16 +00:00
if ( preg_match ( '/includeconstant=/' , strval ( $argv [ $i ]))) {
2023-12-04 09:16:54 +00:00
$tmp = explode ( ':' , $result [ 'includeconstant' ], 3 ); // $includeconstant has been set with previous parse_str()
2021-02-28 23:48:36 +00:00
if ( count ( $tmp ) != 3 ) {
2022-11-25 22:53:16 +00:00
print " Error: Bad parameter includeconstant= " . $result [ 'includeconstant' ] . " \n " ;
2025-09-12 00:29:23 +00:00
exit ( 1 );
2021-02-28 23:48:36 +00:00
}
$includeconstants [ $tmp [ 0 ]][ $tmp [ 1 ]] = $tmp [ 2 ];
}
2025-10-11 11:01:49 +00:00
if ( ! empty ( $result [ " buildzip " ])) {
2026-07-15 22:20:39 +00:00
$buildzip = $result [ " buildzip " ];
2025-10-11 11:01:49 +00:00
}
2021-02-28 23:48:36 +00:00
$i ++ ;
2017-02-10 16:05:45 +00:00
}
2016-09-30 13:41:08 +00:00
2025-11-17 15:39:27 +00:00
if ( empty ( $release ) && empty ( $checklock )) {
print " Error: Missing release or checklock parameter \n " ;
2025-06-23 12:04:36 +00:00
print " Usage: " . $script_file . " release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] \n " ;
2025-11-17 15:39:27 +00:00
print " Usage: " . $script_file . " checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files \n " ;
2026-04-08 17:52:45 +00:00
print " \n " ;
2024-07-06 15:44:20 +00:00
exit ( 2 );
2018-05-05 21:12:31 +00:00
}
2018-05-05 20:54:22 +00:00
$savrelease = $release ;
2026-04-04 01:41:27 +00:00
// If $release is auto, we take current version
2023-12-04 09:16:54 +00:00
$tmpver = explode ( '-' , $release , 2 );
2025-06-23 12:04:36 +00:00
if ( $tmpver [ 0 ] == 'auto' ) {
2023-12-04 09:16:54 +00:00
$release = DOL_VERSION ;
2026-07-15 22:20:39 +00:00
if ( ! empty ( $tmpver [ 1 ])) {
2023-12-04 09:16:54 +00:00
$release .= '-' . $tmpver [ 1 ];
2021-02-28 23:48:36 +00:00
}
2018-03-22 12:22:33 +00:00
}
2026-02-20 19:09:13 +00:00
$releaseblockedlog = DOLCERT_VERSION ;
2026-04-04 01:41:27 +00:00
// If $checklock is auto, we take current version to read checklock file
2025-11-17 15:39:27 +00:00
$tmpver = explode ( '-' , $checklock , 2 );
if ( $tmpver [ 0 ] == 'auto' ) {
2026-04-08 17:52:45 +00:00
$checklock = DOL_VERSION ;
foreach ( $arrayoflockedscopes as $lockedscope => $versionlocked ) {
if ( $checksource == $lockedscope ) {
$checklock = $versionlocked ;
break ;
}
2026-04-04 01:41:27 +00:00
}
2025-11-17 15:39:27 +00:00
if ( ! empty ( $tmpver [ 1 ]) && $tmpver [ 0 ] == 'auto' ) {
$checklock .= '-' . $tmpver [ 1 ];
}
2025-11-17 15:50:53 +00:00
}
2025-11-17 15:39:27 +00:00
2025-11-17 15:50:53 +00:00
$checklockmajorversion = '' ;
if ( $checklock ) {
2025-11-17 15:39:27 +00:00
$checklockmajorversion = preg_replace ( '/-.*$/' , '' , $checklock );
$checklockmajorversion = preg_replace ( '/\..*/' , '' , $checklockmajorversion );
$checklockmajorversion .= '.0.0' ;
}
2018-03-22 12:22:33 +00:00
2025-11-17 15:39:27 +00:00
if ( $release ) {
if ( empty ( $includecustom )) {
$tmpverbis = explode ( '-' , $release , 2 );
if ( empty ( $tmpverbis [ 1 ])) {
if ( DOL_VERSION != $tmpverbis [ 0 ] && $savrelease != 'auto' ) {
2025-11-17 15:50:53 +00:00
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php (' . DOL_VERSION . ') must be exactly the same value than "release" parameter (' . $tmpverbis [ 0 ] . ')' . " \n " ;
2025-11-17 15:39:27 +00:00
print " Usage: " . $script_file . " release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] \n " ;
print " \n " ;
exit ( 3 );
}
} else {
$tmpverter = explode ( '-' , DOL_VERSION , 2 );
if ( $tmpverter [ 0 ] != $tmpverbis [ 0 ]) {
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php (' . DOL_VERSION . ') must have value without prefix (' . $tmpverter [ 0 ] . ') that is exact same value than "release" parameter (' . $tmpverbis [ 0 ] . ')' . " \n " ;
print " Usage: " . $script_file . " release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] \n " ;
print " \n " ;
exit ( 4 );
}
2021-02-28 23:48:36 +00:00
}
} else {
2025-11-17 15:39:27 +00:00
if ( ! preg_match ( '/' . preg_quote ( DOL_VERSION , '/' ) . '-/' , $release )) {
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php (' . DOL_VERSION . ') must be used with a suffix into "release" parameter (ex: ' . DOL_VERSION . '-mydistrib).' . " \n " ;
print " Usage: " . $script_file . " release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] \n " ;
print " \n " ;
exit ( 5 );
2021-02-28 23:48:36 +00:00
}
}
2016-09-30 13:41:08 +00:00
}
2025-11-17 15:39:27 +00:00
if ( $checklock && empty ( $checksource )) {
print 'Error: When action "checklock" is set, second parameter must be the scope family to check, for example "unalterable_files"' . " \n " ;
print " Usage: " . $script_file . " checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files \n " ;
print " \n " ;
exit ( 6 );
}
if ( $release ) {
print " Working on files into : " . DOL_DOCUMENT_ROOT . " \n " ;
print " Version of target release : " . $release . " \n " ;
2026-02-20 19:09:13 +00:00
print " Version of blockedlog module : " . $releaseblockedlog . " \n " ;
2026-01-16 13:50:36 +00:00
print " Algo : " . $algo . " \n " ;
2025-11-17 15:39:27 +00:00
print " Include custom dir in signature : " . ( empty ( $includecustom ) ? 'no' : 'yes' ) . " \n " ;
print " Include constants in signature : " . ( empty ( $includeconstants ) ? 'none' : '' );
foreach ( $includeconstants as $countrycode => $tmp ) {
foreach ( $tmp as $constname => $constvalue ) {
print $constname . '=' . $constvalue . " " ;
}
2021-02-28 23:48:36 +00:00
}
2025-11-17 15:39:27 +00:00
print " \n " ;
2026-01-16 13:50:36 +00:00
print " \n " ;
2025-11-17 15:39:27 +00:00
}
if ( $checklock ) {
print " Working on files into : " . DOL_DOCUMENT_ROOT . " \n " ;
2026-06-09 00:14:03 +00:00
print " Version of running Dolibarr : " . DOL_VERSION . " \n " ;
2026-04-04 01:41:27 +00:00
print " Version to check in lockedfiles.txt : " . $checklockmajorversion . " \n " ; // For example 2.0.0
2026-04-08 17:52:45 +00:00
print " Scope name to check : " . $checksource . " \n " ; // For example unalterable_files
2017-02-10 16:05:45 +00:00
}
2017-02-06 12:37:23 +00:00
2025-11-17 15:39:27 +00:00
if ( $release ) {
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
$outputdir = dirname ( dirname ( dirname ( __FILE__ ))) . '/htdocs/install' ;
print 'Delete current files ' . $outputdir . '/filelist*.xml*' . " \n " ;
dol_delete_file ( $outputdir . '/filelist*.xml*' , 0 , 1 , 1 );
}
2016-09-30 13:41:08 +00:00
2017-02-10 16:05:45 +00:00
2025-11-19 15:25:16 +00:00
$needtoclose = 0 ;
2025-11-17 15:39:27 +00:00
// Build the XML file
if ( $release ) {
$checksumconcat = array ();
2020-11-26 16:00:49 +00:00
2025-11-17 15:39:27 +00:00
$outputfile = $outputdir . '/filelist-' . $release . '.xml' ;
$fp = fopen ( $outputfile , 'w' );
if ( empty ( $fp )) {
print 'Failed to open file ' . $outputfile . " \n " ;
exit ( 7 );
}
2025-07-20 16:21:15 +00:00
2025-11-17 15:39:27 +00:00
$gitcommit = 'seetag' ;
$branchname = preg_replace ( '/^(\d+\.\d+)\..*$/' , '\1' , $release ); // Keep only x.y into x.y.z
$fileforgit = dirname ( dirname ( dirname ( __FILE__ ))) . '/.git/refs/heads/' . $branchname ;
print " Try to get last commit ID from file " . $fileforgit . " \n " ;
$fileforgitcontent = '' ;
if ( file_exists ( $fileforgit )) {
$fileforgitcontent = file_get_contents ( $fileforgit );
}
if ( empty ( $fileforgitcontent )) {
2026-05-26 14:51:18 +00:00
print " Can't get the last commit ID (are you on the branch for the release branch name " . $branchname . " ?). We will use an empty value for gitcommit. \n " ;
2025-11-17 15:39:27 +00:00
}
$gitcommit = trim ( $fileforgitcontent );
2025-07-20 16:21:15 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<?xml version="1.0" encoding="UTF-8" ?>' . " \n " );
2025-12-22 03:52:12 +00:00
fputs ( $fp , '<checksum_list version="' . $release . '" date="' . dol_print_date ( dol_now (), 'dayhourrfc' ) . '" generator="' . $script_file . '" algo="' . $algo . '" gitcommit="' . $gitcommit . '">' . " \n " );
2025-11-17 15:39:27 +00:00
foreach ( $includeconstants as $countrycode => $tmp ) {
fputs ( $fp , '<dolibarr_constants country="' . $countrycode . '">' . " \n " );
foreach ( $tmp as $constname => $constvalue ) {
$valueforchecksum = ( empty ( $constvalue ) ? '0' : $constvalue );
$checksumconcat [] = $valueforchecksum ;
fputs ( $fp , ' <constant name="' . $constname . '">' . $valueforchecksum . '</constant>' . " \n " );
}
fputs ( $fp , '</dolibarr_constants>' . " \n \n " );
2021-02-28 23:48:36 +00:00
}
2015-09-13 18:25:33 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<dolibarr_htdocs_dir includecustom="' . $includecustom . '">' . " \n " );
2016-12-26 18:51:24 +00:00
2025-11-17 15:39:27 +00:00
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$' ;
2026-06-01 20:55:42 +00:00
$regextoexclude = '(' . ( $includecustom ? '' : 'custom|' ) . 'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install\/doctemplates|install\/mysql\/migration|install\/filelist.*|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$' ; // Exclude dirs
2026-06-01 18:10:17 +00:00
2026-06-19 21:40:38 +00:00
//$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'type_fullname');
2025-11-17 15:39:27 +00:00
$files = dol_dir_list ( DOL_DOCUMENT_ROOT , 'files' , 1 , $regextoinclude , $regextoexclude , 'fullname' );
2021-02-20 10:09:23 +00:00
2025-11-17 15:39:27 +00:00
$dir = '' ;
foreach ( $files as $filetmp ) {
$file = $filetmp [ 'fullname' ];
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
$newdir = str_replace ( DOL_DOCUMENT_ROOT , '' , dirname ( $file ));
if ( $newdir != $dir ) {
if ( $needtoclose ) {
fputs ( $fp , ' </dir>' . " \n " );
$needtoclose = 0 ;
}
fputs ( $fp , ' <dir name="' . $newdir . '">' . " \n " );
$dir = $newdir ;
$needtoclose = 1 ;
}
if ( filetype ( $file ) == " file " ) {
2025-12-22 03:52:12 +00:00
$hashoffile = hash_file ( $algo , $file );
$checksumconcat [] = $hashoffile ;
fputs ( $fp , ' <' . $algo . 'file name="' . basename ( $file ) . '" size="' . filesize ( $file ) . '">' . $hashoffile . '</' . $algo . 'file>' . " \n " );
2021-02-28 23:48:36 +00:00
}
}
2025-11-17 15:39:27 +00:00
if ( $needtoclose ) {
fputs ( $fp , ' </dir>' . " \n " );
$needtoclose = 0 ;
2021-02-28 23:48:36 +00:00
}
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</dolibarr_htdocs_dir>' . " \n " );
2015-09-13 18:25:33 +00:00
2025-11-17 15:39:27 +00:00
asort ( $checksumconcat ); // Sort list of checksum
2025-12-22 03:52:12 +00:00
$hashhtdocsdir = hash ( $algo , join ( ',' , $checksumconcat ));
2024-09-22 23:59:14 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<dolibarr_htdocs_dir_checksum>' . " \n " );
2025-12-22 03:52:12 +00:00
fputs ( $fp , $hashhtdocsdir . " \n " );
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</dolibarr_htdocs_dir_checksum>' . " \n \n " );
2016-12-26 18:51:24 +00:00
2025-11-17 15:39:27 +00:00
// Add the checksum for the part in scripts
2025-06-23 12:04:36 +00:00
2025-11-17 15:39:27 +00:00
$checksumconcat = array ();
2015-09-13 18:25:33 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<dolibarr_scripts_dir version="' . $release . '">' . " \n " );
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$' ;
$regextoexclude = '(custom|documents|conf|install)$' ; // Exclude dirs
$files = dol_dir_list ( dirname ( __FILE__ ) . '/../../scripts/' , 'files' , 1 , $regextoinclude , $regextoexclude , 'fullname' );
$dir = '' ;
2026-06-19 21:40:38 +00:00
2025-11-17 15:39:27 +00:00
foreach ( $files as $filetmp ) {
$file = $filetmp [ 'fullname' ];
$newdir = str_replace ( DOL_DOCUMENT_ROOT , '' , dirname ( $file ));
2026-06-19 21:40:38 +00:00
$newdir = str_replace ( dirname ( __FILE__ ) . '/../../scripts' , '' , $newdir );
2025-11-17 15:39:27 +00:00
if ( $newdir != $dir ) {
if ( $needtoclose ) {
fputs ( $fp , ' </dir>' . " \n " );
$needtoclose = 0 ;
}
fputs ( $fp , ' <dir name="' . $newdir . '">' . " \n " );
$dir = $newdir ;
$needtoclose = 1 ;
}
if ( filetype ( $file ) == " file " ) {
2025-12-22 03:52:12 +00:00
$hashoffile = hash_file ( $algo , $file );
$checksumconcat [] = $hashoffile ;
fputs ( $fp , ' <' . $algo . 'file name="' . basename ( $file ) . '" size="' . filesize ( $file ) . '">' . $hashoffile . '</' . $algo . 'file>' . " \n " );
2021-02-28 23:48:36 +00:00
}
}
2025-11-17 15:39:27 +00:00
if ( $needtoclose ) {
fputs ( $fp , ' </dir>' . " \n " );
$needtoclose = 0 ;
2021-02-28 23:48:36 +00:00
}
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</dolibarr_scripts_dir>' . " \n " );
asort ( $checksumconcat ); // Sort list of checksum
2025-12-22 03:52:12 +00:00
$hashscriptsdir = hash ( $algo , join ( ',' , $checksumconcat ));
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<dolibarr_scripts_dir_checksum>' . " \n " );
2025-12-22 03:52:12 +00:00
fputs ( $fp , $hashscriptsdir . " \n " );
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</dolibarr_scripts_dir_checksum>' . " \n \n " );
2015-09-13 18:25:33 +00:00
}
2025-06-23 12:04:36 +00:00
2025-06-23 12:31:11 +00:00
// Add the checksum for the files into the scope of the unalterable system (record, read, export)
2025-06-23 12:04:36 +00:00
$checksumconcat = array ();
2026-02-21 10:56:15 +00:00
if ( $release && $releaseblockedlog ) {
2026-02-20 19:09:13 +00:00
fputs ( $fp , '<dolibarr_unalterable_files version="' . $releaseblockedlog . '">' . " \n " );
2025-11-17 15:39:27 +00:00
}
2025-06-23 12:04:36 +00:00
2025-10-22 12:14:58 +00:00
// Array of dir/files to include in the section
foreach ( $arrayofunalterablefiles as $entry ) {
if ( $entry [ 'file' ] == 'all' ) {
2026-07-29 16:46:50 +00:00
$regextoinclude = $entry [ 'regextoinclude' ] ? ? null ;
$regextoexclude = $entry [ 'regextoexclude' ] ? ? null ;
2025-10-22 12:14:58 +00:00
$files = dol_dir_list ( $entry [ 'dir' ], 'files' , 1 , $regextoinclude , $regextoexclude , 'fullname' );
$dir = '' ;
2026-06-19 21:40:38 +00:00
2025-10-22 12:14:58 +00:00
foreach ( $files as $filetmp ) {
$file = $filetmp [ 'fullname' ];
$newdir = str_replace ( DOL_DOCUMENT_ROOT , '' , dirname ( $file ));
2026-06-19 21:40:38 +00:00
$newdir = str_replace ( dirname ( __FILE__ ) . '/../../htdocs' , '' , $newdir );
$newdir = str_replace ( dirname ( dirname ( dirname ( __FILE__ ))) . '/htdocs' , '' , $newdir );
2025-10-22 12:14:58 +00:00
if ( $newdir != $dir ) {
if ( $needtoclose ) {
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , ' </dir>' . " \n " );
}
2025-10-22 12:14:58 +00:00
$needtoclose = 0 ;
}
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , ' <dir name="' . $newdir . '">' . " \n " );
}
2025-10-22 12:14:58 +00:00
$dir = $newdir ;
$needtoclose = 1 ;
}
if ( filetype ( $file ) == " file " ) {
2025-12-22 03:52:12 +00:00
$hashoffile = hash_file ( $algo , $file );
$checksumconcat [] = $hashoffile ;
2025-11-17 15:39:27 +00:00
if ( $release ) {
2025-12-22 03:52:12 +00:00
fputs ( $fp , ' <' . $algo . 'file name="' . basename ( $file ) . '" size="' . filesize ( $file ) . '">' . $hashoffile . '</' . $algo . 'file>' . " \n " );
2025-11-17 15:39:27 +00:00
}
2025-10-22 12:14:58 +00:00
}
}
2025-06-23 12:04:36 +00:00
if ( $needtoclose ) {
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , ' </dir>' . " \n " );
}
2025-07-20 16:21:15 +00:00
$needtoclose = 0 ;
2025-06-23 12:04:36 +00:00
}
2025-10-22 12:14:58 +00:00
} else {
$file = $entry [ 'dir' ] . '/' . $entry [ 'file' ];
2025-11-19 15:25:16 +00:00
$dir = '' ;
2025-10-22 12:14:58 +00:00
$newdir = str_replace ( DOL_DOCUMENT_ROOT , '' , dirname ( $file ));
2026-06-19 21:40:38 +00:00
$newdir = str_replace ( dirname ( __FILE__ ) . '/../../htdocs' , '' , $newdir );
$newdir = str_replace ( dirname ( dirname ( dirname ( __FILE__ ))) . '/htdocs' , '' , $newdir );
2025-10-22 12:14:58 +00:00
if ( ! file_exists ( $file )) {
print " Error file " . $file . " does not exists. " ;
exit ( 1 );
}
if ( $newdir != $dir ) {
2026-08-13 17:21:32 +00:00
if ( $needtoclose ) {
if ( $release ) {
fputs ( $fp , ' </dir>' . " \n " );
}
2026-07-15 22:20:39 +00:00
$needtoclose = 0 ;
2026-08-13 17:21:32 +00:00
}
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , ' <dir name="' . $newdir . '">' . " \n " );
}
2025-10-22 12:14:58 +00:00
$dir = $newdir ;
$needtoclose = 1 ;
}
if ( filetype ( $file ) == " file " ) {
2025-12-22 03:52:12 +00:00
$hashoffile = hash_file ( $algo , $file );
$checksumconcat [] = $hashoffile ;
2025-11-17 15:39:27 +00:00
if ( $release ) {
2025-12-22 03:52:12 +00:00
fputs ( $fp , ' <' . $algo . 'file name="' . basename ( $file ) . '" size="' . filesize ( $file ) . '">' . $hashoffile . '</' . $algo . 'file>' . " \n " );
2025-11-17 15:39:27 +00:00
}
2025-10-22 12:14:58 +00:00
}
2025-06-23 12:37:38 +00:00
if ( $needtoclose ) {
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , ' </dir>' . " \n " );
}
2025-07-20 16:21:15 +00:00
$needtoclose = 0 ;
2025-06-23 12:37:38 +00:00
}
}
2025-08-06 10:21:32 +00:00
}
2025-06-23 12:04:36 +00:00
asort ( $checksumconcat ); // Sort list of checksum
2026-02-20 19:09:13 +00:00
2025-12-22 03:52:12 +00:00
$hashunalterable_files = hash ( $algo , join ( ',' , $checksumconcat ));
2025-06-23 12:04:36 +00:00
2025-11-17 15:39:27 +00:00
if ( $release ) {
fputs ( $fp , '</dolibarr_unalterable_files>' . " \n " );
2025-06-23 12:04:36 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '<dolibarr_unalterable_files_checksum>' . " \n " );
2025-12-22 03:52:12 +00:00
fputs ( $fp , $hashunalterable_files . " \n " );
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</dolibarr_unalterable_files_checksum>' . " \n \n " );
2025-06-23 12:04:36 +00:00
2025-11-17 15:39:27 +00:00
// End of file
2025-06-23 12:04:36 +00:00
2025-11-17 15:39:27 +00:00
fputs ( $fp , '</checksum_list>' . " \n " );
fclose ( $fp );
}
2015-02-24 11:44:12 +00:00
2025-10-11 11:01:49 +00:00
print " \n " ;
2025-11-17 15:39:27 +00:00
if ( $release ) {
if ( empty ( $buildzip )) {
print " File " . $outputfile . " generated. \n " ;
2025-12-22 03:52:12 +00:00
print " Signature for htdocs files: " . $hashhtdocsdir . " \n " ;
print " Signature for scripts files: " . $hashscriptsdir . " \n " ;
2026-04-08 17:52:45 +00:00
// For the scope unalterable_files:
print " Signature for the " . count ( $checksumconcat ) . " files in scope unalterable_files " ;
print DOLCERT_VERSION ;
print " : " . $hashunalterable_files . " \n " ;
2025-11-17 15:39:27 +00:00
} else {
if ( $buildzip == '1' || $buildzip == 'zip' ) {
$result = dol_compress_file ( $outputfile , $outputfile . '.zip' , 'zip' );
if ( $result > 0 ) {
dol_delete_file ( $outputfile );
print " File " . $outputfile . " .zip generated. \n " ;
}
} elseif ( $buildzip == '2' || $buildzip == 'gz' ) {
$result = dol_compress_file ( $outputfile , $outputfile . '.gz' , 'gz' );
if ( $result > 0 ) {
dol_delete_file ( $outputfile );
print " File " . $outputfile . " .gz generated. \n " ;
}
2021-09-13 00:47:27 +00:00
}
2025-11-17 15:39:27 +00:00
}
}
if ( $checklock ) {
2026-04-08 17:52:45 +00:00
print " Signature of locked files for the scope ' " . $checksource . " ' : " . $algo . " " . $hashunalterable_files . " \n " ;
2025-11-17 15:39:27 +00:00
2025-11-19 15:16:53 +00:00
$lockedfile = DOL_DOCUMENT_ROOT . '/../dev/lockedfiles.txt' ;
2025-11-17 15:39:27 +00:00
$checksuminlockedfile = '' ;
2025-11-19 15:16:53 +00:00
if ( ! file_exists ( $lockedfile )) {
print " Can't find the file " . $lockedfile . " . No checksum to check \n " ;
} else {
// Now we check the content of lockedfiles.txt
$arraylocked = file ( $lockedfile );
foreach ( $arraylocked as $line ) {
2025-12-22 03:52:12 +00:00
$tmparray = preg_split ( " / \ s+/ " , $line , 4 );
if ( $tmparray [ 0 ] == $checklockmajorversion && $tmparray [ 2 ] == $algo ) {
2026-04-08 18:02:03 +00:00
$checksuminlockedfile = trim ( $tmparray [ 3 ]);
2025-11-19 15:16:53 +00:00
}
2025-11-17 15:39:27 +00:00
}
2025-11-19 15:16:53 +00:00
if ( empty ( $checksuminlockedfile )) {
2026-04-08 18:02:03 +00:00
print " The major version " . $checklockmajorversion . " is not locked on the scope ' " . $checksource . " ' (file found but no lock entry found into dev/lockedfiles.txt). \n " ;
} else {
2026-04-08 17:52:45 +00:00
print " The major version " . $checklockmajorversion . " is locked on scope ' " . $checksource . " ' with the checksum : " . $algo . " " . $checksuminlockedfile . " \n " ;
2026-04-08 18:02:03 +00:00
print " \n " ;
if ( hash_equals ( $checksuminlockedfile , $hashunalterable_files )) {
print " OK - The checksum of current files is the same than the locked one. \n " ;
} else {
print " ERROR - The checksum of current files differs from the locked one, so we return an error. \n " ;
2025-11-19 15:16:53 +00:00
print " \n " ;
exit ( 10 );
}
2021-09-13 00:47:27 +00:00
}
2021-08-19 00:54:58 +00:00
}
2021-08-19 00:48:45 +00:00
}
2015-02-24 11:44:12 +00:00
2025-10-11 11:01:49 +00:00
print " \n " ;
2025-11-17 15:39:27 +00:00
2015-02-24 11:44:12 +00:00
exit ( 0 );