Commit 65bc43d9 authored by Claes Sjofors's avatar Claes Sjofors

Pkg command to check for new distribution files

parent 2ad18f40
......@@ -81,6 +81,7 @@ createdbs <Create loadfile error> /error
edit <In edit mode> /error
notauthorized <User not authorized for requested operation> /error
nosuchvolume <No such volume> /error
distrerr <Distributor error> /error
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2017 SSAB EMEA AB.
!
! This file is part of Proview.
!
! 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 2 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 Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_c_distrdependnode.wb_load -- Defines the class DistrDependNode.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Group ProjectConfiguration
! @Summary Configures distribution dependency node.
! Configures distribution dependency node.
!
! @b See also
! @classlink NodeConfig pwrb_nodeconfig.html
! @classlink Distribute pwrb_distribute.html
!*/
Object DistrDependNode $ClassDef 700
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_RtAndDevBodies
EndBody
Object DevBody $ObjBodyDef 2
!/**
! Node name.
!*/
Object NodeName $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Project.
!*/
Object Project $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
EndObject
EndObject
EndSObject
\ No newline at end of file
......@@ -647,6 +647,7 @@ palette ProjectNavigatorPalette
class BusConfig
class ClassVolumeLoad
class CustomBuild
class DistrDependNode
class Distribute
class DetachedClassVolumeLoad
class FriendNodeConfig
......
......@@ -2597,7 +2597,8 @@ pwr_tStatus lfu_SaveDirectoryVolume(
/* Find the applications for this node */
class_vect[0] = pwr_cClass_Distribute;
class_vect[1] = pwr_cClass_ApplDistribute;
class_vect[2] = 0;
class_vect[2] = pwr_cClass_DistrDependNode;
class_vect[3] = 0;
objcount = 0;
objlist = 0;
......@@ -2741,6 +2742,46 @@ pwr_tStatus lfu_SaveDirectoryVolume(
free( source_ptr);
free( target_ptr);
break;
case pwr_cClass_DistrDependNode: {
char *depnodename_ptr;
char *project_ptr;
sts = ldh_ObjidToName( ldhses, applobjid, ldh_eName_Object,
appl_name, sizeof(appl_name), &size);
if ( EVEN(sts)) return sts;
/* Check Node attribute */
sts = ldh_GetObjectPar( ldhses, applobjid, "DevBody",
"NodeName", &depnodename_ptr, &size);
if (EVEN(sts)) return sts;
if ( !strcmp( depnodename_ptr, "")) {
char msg[200];
free( depnodename_ptr);
depnodename_ptr = null_nodename;
sprintf( msg, "Error in DistrDependNode object '%s', NodeName is missing",
appl_name);
MsgWindow::message( 'E', msg, msgw_ePop_Default);
syntax_error = 1;
}
/* Check Project attribute */
sts = ldh_GetObjectPar( ldhses, applobjid, "DevBody",
"Project", &project_ptr, &size);
if (EVEN(sts)) return sts;
if ( !strcmp( project_ptr, ""))
project_ptr = systemname;
fprintf( file, "depnode %s %s %s\n",
nodename_ptr,
depnodename_ptr,
project_ptr);
if ( depnodename_ptr != null_nodename)
free( depnodename_ptr);
if ( project_ptr != systemname)
free( project_ptr);
break;
}
default: ;
}
}
......
......@@ -60,7 +60,7 @@ static unsigned int pkg_random()
return (unsigned int)((double) rand() / ((double) RAND_MAX + 1) * 999999);
}
wb_pkg::wb_pkg( char *nodelist, bool distribute, bool config_only)
wb_pkg::wb_pkg( char *nodelist, bool distribute, bool config_only, bool check, int *new_files)
{
if ( nodelist) {
char node_str[32][20];
......@@ -87,6 +87,13 @@ wb_pkg::wb_pkg( char *nodelist, bool distribute, bool config_only)
for ( unsigned int i = 0; i < m_nodelist.size(); i++)
m_nodelist[i].checkNode();
if ( check && new_files) {
*new_files = 0;
for ( unsigned int i = 0; i < m_nodelist.size(); i++)
*new_files += m_nodelist[i].compareFiles();
return;
}
fetchFiles( distribute);
}
......@@ -176,6 +183,18 @@ void wb_pkg::readConfig()
continue;
}
}
else if ( strcmp( cdh_Low(line_item[0]), "depnode") == 0) {
if ( num != 4)
throw wb_error_str("File corrupt " pwr_cNameDistribute);
try {
pkg_node& n = getNode( line_item[1]);
pkg_depnode dn( line_item[2], line_item[3]);
n.depnodeAdd( dn);
} catch ( wb_error &e) {
continue;
}
}
else if ( strcmp( cdh_Low(line_item[0]), "load") == 0) {
pwr_tVolumeId *vollist;
pwr_tString40 *volnamelist;
......@@ -456,6 +475,161 @@ void pkg_node::checkVolume( char *filename)
free( (char *)volref);
}
int pkg_node::compareFiles()
{
char dev[80];
char dir[80];
char file[80];
char type[80];
int version;
char fname[200];
bool artime_minute = true;
int new_files = 0;
// Read package version
sprintf( fname, "$pwrp_load/pkg_v_%s.dat", m_name);
dcli_translate_filename( fname, fname);
ifstream ifv( fname);
if ( ifv) {
ifv >> version;
ifv.close();
}
else
// No previous package
return false;
// List the package and retrive the file date
pwr_tFileName pkg_name;
sprintf( pkg_name, pwr_cNamePkg, m_name, version);
pwr_tCmd cmd;
if ( artime_minute)
sprintf( cmd, "tar -tvf $pwrp_load/%s > %s", pkg_name, "$pwrp_tmp/fl.tmp");
else
sprintf( cmd, "tar --full-time -tvf $pwrp_load/%s > %s", pkg_name, "$pwrp_tmp/fl.tmp");
system( cmd);
dcli_translate_filename( fname, "$pwrp_tmp/fl.tmp");
ifstream is( fname);
char line[400];
char line_item[6][200];
int num;
char timstr[40];
pwr_tTime time;
pwr_tFileName source;
map<string, pwr_tTime> tarlist;
while ( is.getline( line, sizeof(line))) {
num = dcli_parse( line, " ", "", (char *)line_item,
sizeof(line_item)/sizeof(line_item[0]),
sizeof(line_item[0]), 0);
if ( num != 6)
continue;
if ( strncmp( line_item[5], "pkg_build/", 10) != 0)
continue;
// Add file to list
strncpy( timstr, line_item[3], sizeof(timstr));
strncat( timstr, " ", sizeof(timstr) - strlen(timstr));
strncat( timstr, line_item[4], sizeof(timstr) - strlen(timstr));
strncpy( source, &line_item[5][10], sizeof(source));
if ( artime_minute)
time_FormAsciiToA( timstr, MINUTE, 0, &time);
else
time_FormAsciiToA( timstr, SECOND, 0, &time);
string s(source);
tarlist[s] = time;
}
// Add volumes to pattern
for ( int i = 0; i < (int)m_volumelist.size(); i++) {
if ( !m_volumelist[i].m_isSystem) {
pkg_pattern vol( m_volumelist[i].m_filename, "$pwrp_load/", 'E');
push_back( vol);
}
}
for ( int i = 0; i < (int)m_pattern.size(); i++)
m_pattern[i].fetchFiles();
// Put all files in a single list
m_filelist.clear();
for ( int i = 0; i < (int)m_pattern.size(); i++) {
for ( int j = 0; j < (int)m_pattern[i].m_filelist.size(); j++) {
try {
pkg_file f = m_pattern[i].m_filelist[j];
dcli_parse_filename( f.m_source, dev, dir, file, type, &version);
strcpy( f.m_arname, file);
strcat( f.m_arname, type);
// Check that this name is unique
for (;;) {
bool new_name = false;
for ( int k = 0; k < (int)m_filelist.size(); k++) {
if ( strcmp( m_filelist[k].m_arname, f.m_arname) == 0) {
strcat( f.m_arname, "x");
new_name = true;
break;
}
}
if ( !new_name)
break;
}
m_filelist.push_back( f);
} catch ( wb_error &e) {
MsgWindow::message( 'W', e.what().c_str(), msgw_ePop_No);
m_warnings++;
}
}
}
for ( int k = 0; k < (int)m_filelist.size(); k++) {
string s(m_filelist[k].m_arname);
pwr_tTime tar_time, src_time;
pwr_tStatus sts;
tar_time = tarlist[s];
if ( tar_time.tv_sec == 0) {
printf("No such file: %s\n", m_filelist[k].m_arname);
new_files++;
continue;
}
sts = dcli_file_time( m_filelist[k].m_source, &src_time);
// printf( "tar: %lld src: %lld %s\n", tar_time.tv_sec, src_time.tv_sec, m_filelist[k].m_arname);
int diff = 0;
if ( artime_minute)
diff = 60;
if ( abs(tar_time.tv_sec - src_time.tv_sec) > diff) {
printf( "New file: %s\n", m_filelist[k].m_arname);
new_files++;
}
}
if ( m_errors) {
char msg[200];
sprintf( msg, "Distribute errors node %s: %d errors, %d warnings", m_name, m_errors, m_warnings);
MsgWindow::message( 'E', msg, msgw_ePop_Yes);
throw wb_error_str( msg);
}
else if ( m_warnings) {
char msg[200];
sprintf( msg, "Distribute warnings node %s: %d warnings", m_name, m_warnings);
MsgWindow::message( 'W', msg, msgw_ePop_Yes);
}
return new_files;
}
void pkg_node::fetchFiles( bool distribute)
{
char dev[80];
......@@ -482,6 +656,7 @@ void pkg_node::fetchFiles( bool distribute)
m_pattern[i].fetchFiles();
// Put all files in a single list
m_filelist.clear();
for ( int i = 0; i < (int)m_pattern.size(); i++) {
for ( int j = 0; j < (int)m_pattern[i].m_filelist.size(); j++) {
try {
......@@ -491,7 +666,7 @@ void pkg_node::fetchFiles( bool distribute)
strcpy( f.m_arname, file);
strcat( f.m_arname, type);
// Check that this name is unic
// Check that this name is unique
for (;;) {
bool new_name = false;
for ( int k = 0; k < (int)m_filelist.size(); k++) {
......@@ -560,13 +735,13 @@ void pkg_node::fetchFiles( bool distribute)
for ( int i = 0; i < (int)m_filelist.size(); i++)
of <<
"cp " << m_filelist[i].m_source << " " << m_blddir << "/" << m_filelist[i].m_arname << endl;
"cp --preserve=timestamps " << m_filelist[i].m_source << " " << m_blddir << "/" << m_filelist[i].m_arname << endl;
of <<
"cp $pwrp_tmp/pkg_unpack_" << m_name << ".sh " << m_tmpdir << "/pkg_unpack.sh" << endl <<
"cp $pwrp_tmp/pwr_pkg_" << m_name << ".dat " << m_tmpdir << "/pwr_pkg.dat" << endl <<
"cd " << m_tmpdir << endl <<
"tar -czf $pwrp_load/" << pkg_name << " pwr_pkg.dat pkg_unpack.sh pkg_build" << endl <<
"tar --atime-preserve -czf $pwrp_load/" << pkg_name << " pwr_pkg.dat pkg_unpack.sh pkg_build" << endl <<
"rm -r " << m_tmpdir << endl;
of.close();
......@@ -877,4 +1052,4 @@ pkg_file::pkg_file( char *source, char *target)
m_date.tv_nsec = 0;
strcpy( m_source, source);
strcpy( m_target, target);
}
\ No newline at end of file
}
......@@ -119,11 +119,26 @@ class pkg_volume {
}
};
class pkg_depnode {
friend class pkg_node;
private:
char m_nodename[40];
char m_project[40];
public:
pkg_depnode( char *nodename, char *project) {
strncpy( m_nodename, nodename, sizeof(m_nodename));
strncpy( m_project, project, sizeof(m_project));
}
};
class pkg_node {
private:
vector<pkg_pattern> m_pattern;
vector<pkg_file> m_filelist;
vector<pkg_volume> m_volumelist;
vector<pkg_depnode> m_depnodelist;
char m_name[80];
char m_bootnode[80];
pwr_mOpSys m_opsys;
......@@ -194,9 +209,13 @@ class pkg_node {
pattern.node( this);
m_pattern.push_back( pattern);
}
void depnodeAdd( pkg_depnode &depnode) {
m_depnodelist.push_back( depnode);
}
void checkVolume( char *filename);
void checkNode();
void fetchFiles( bool distribute);
int compareFiles();
void copyPackage( char *pkg_name);
void incrWarnings() { m_warnings++;}
void incrErrors() { m_errors++;}
......@@ -210,7 +229,8 @@ class wb_pkg {
void readConfig();
public:
wb_pkg( char *nodelist, bool distribute = true, bool config_only = false);
wb_pkg( char *nodelist, bool distribute = true, bool config_only = false, bool check = false,
int *new_files = 0);
pkg_node& getNode( char *name);
void fetchFiles( bool distribute) {
for ( int i = 0; i < (int)m_nodelist.size(); i++) m_nodelist[i].fetchFiles( distribute);
......@@ -219,4 +239,4 @@ class wb_pkg {
static void copyPackage( char *pkg_name);
};
#endif
\ No newline at end of file
#endif
......@@ -455,7 +455,7 @@ dcli_tCmdTable wnav_command_table[] = {
{
"DISTRIBUTE",
&wnav_distribute_func,
{ "/NODE", "/PACKAGE", "/FILE", ""}
{ "/NODE", "/PACKAGE", "/FILE", "/CHECK", ""}
},
{
"RELEASE",
......@@ -5145,6 +5145,33 @@ static int wnav_distribute_func( void *client_data,
else
node_ptr = NULL;
if ( ODD( dcli_get_qualifier( "/CHECK", 0, 0))) {
int new_files;
try {
wb_pkg *pkg = new wb_pkg( node_ptr, false, false, true, &new_files);
delete pkg;
}
catch ( wb_error &e) {
wnav->message(' ', (char *)e.what().c_str());
sts = e.sts();
if ( EVEN(sts)) {
if ( sts == 0)
return WNAV__DISTRERR;
return sts;
}
}
if ( new_files) {
char msg[80];
sprintf( msg, "Modified files found (%d)", new_files);
wnav->message('I', msg);
return 2;
}
else
wnav->message('I', "Package up to date");
return WNAV__SUCCESS;
}
package = ODD( dcli_get_qualifier( "/PACKAGE", 0, 0));
distribute = package ? false : true;
......@@ -5595,6 +5622,7 @@ static int wnav_check_func( void *client_data,
}
else
wnav->message( 'I', "Successful syntax check, no errors or warnings found");
return WNAV__SUCCESS;
}
else {
if ( EVEN( dcli_get_qualifier( "/NAME", namestr, sizeof(namestr)))) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment