1
1
/*
2
- * Copyright (c) 2016,2020 IBM Corporation and other Contributors.
2
+ * Copyright (c) 2016,2023 IBM Corporation and other Contributors.
3
3
*
4
4
* All rights reserved. This program and the accompanying materials
5
5
* are made available under the terms of the Eclipse Public License v1.0
@@ -163,6 +163,7 @@ static int offsetCorrection = 0;
163
163
static BOOL warn115_240 = FALSE;
164
164
165
165
static time_t startTime = 0 ;
166
+ static time_t endTime = 0 ;
166
167
static char * formatRate ;
167
168
168
169
static int amsType = SMFTYPE_MQ_AMS ;
@@ -207,6 +208,7 @@ int main( int argc, char *argv[] )
207
208
int i ,j ; /* loop counters */
208
209
char dataBuf [MAX_SMF_DATA ]; /* Contains the SMF data */
209
210
int bytesRead ; /* Number of bytes from fread() */
211
+ int tmpBytes ;
210
212
int offset ; /* total number of bytes in a record*/
211
213
unsigned int d [3 ]; /* used in date conversion */
212
214
unsigned int ddd ,year ; /* day number and year number */
@@ -399,8 +401,7 @@ int main( int argc, char *argv[] )
399
401
400
402
fstat (fileno (fp ),& statbuf );
401
403
totalFileSize = statbuf .st_size ;
402
- if (debugLevel >=3 )
403
- fprintf (infoStream ,"Total File Size = %lld\n" ,totalFileSize );
404
+ debugf (3 ,"Total File Size = %lld\n" ,totalFileSize );
404
405
405
406
convInit (); /* Decide whether this is a big or little endian machine*/
406
407
@@ -466,15 +467,22 @@ int main( int argc, char *argv[] )
466
467
/* same as the SMF record length). It comes from the first two */
467
468
/* bytes of the Record Descriptor Word (RDW). */
468
469
/********************************************************************/
469
-
470
470
bytesRead = fread (& pSMFMQRecord -> Header .SMFLEN ,1 ,2 ,fp );
471
471
if (bytesRead < 2 )
472
- continue ;
472
+ {
473
+ debugf (1 ,"At end of input data - fread (phase 1a) returned %d bytes\n" ,tmpBytes );
474
+ break ;
475
+ }
473
476
474
477
/********************************************************************/
475
478
/* The second half-word is the segment indicator. */
476
479
/********************************************************************/
477
- fread (& pSMFMQRecord -> Header .SMFSEG ,1 ,2 ,fp );
480
+ tmpBytes = fread (& pSMFMQRecord -> Header .SMFSEG ,1 ,2 ,fp );
481
+ if (tmpBytes < 2 )
482
+ {
483
+ debugf (1 ,"At end of input data - fread (phase 1b) returned %d bytes\n" ,tmpBytes );
484
+ break ;
485
+ }
478
486
479
487
/********************************************************************/
480
488
/* And then read the actual data, starting at the RECFLG field in */
@@ -483,8 +491,7 @@ int main( int argc, char *argv[] )
483
491
/* amount. */
484
492
/********************************************************************/
485
493
nextLength = conv16 (pSMFMQRecord -> Header .SMFLEN ) - 4 ;
486
- if (debugLevel >=3 )
487
- fprintf (infoStream ," NextLen = %d bytes \n" ,nextLength );
494
+ debugf (3 ," NextLen = %d bytes \n" ,(nextLength ));
488
495
489
496
bytesRead = fread (& pSMFMQRecord -> Header .SMFRECFLG , 1 , nextLength , fp );
490
497
if (bytesRead != nextLength )
@@ -504,18 +511,28 @@ int main( int argc, char *argv[] )
504
511
/* segmentation, no SMF record is meant to be >32768 bytes, so we */
505
512
/* need to check that. Once again, ignore the RDW when working */
506
513
/* out how much real data there is. */
514
+ /* We've also seen input files which were truncated such that */
515
+ /* the continuation records were not captured. So check that we are */
516
+ /* actually able to read the data and that we're not at the EOF. */
507
517
/********************************************************************/
508
518
if (pSMFMQRecord -> Header .SMFSEG [0 ] != 0 )
509
519
{
510
520
do
511
521
{
522
+ tmpBytes = fread (& nextLength ,1 ,2 ,fp );
523
+ if (tmpBytes < 2 ) {
524
+ debugf (1 ,"At end of input data - fread (phase 2a) returned %d bytes\n" ,tmpBytes );
525
+ goto mod_exit ;
526
+ }
512
527
513
- fread (& nextLength ,1 ,2 ,fp );
514
528
nextLength = conv16 (nextLength );
515
- fread (& pSMFMQRecord -> Header .SMFSEG ,1 ,2 ,fp );
529
+ tmpBytes = fread (& pSMFMQRecord -> Header .SMFSEG ,1 ,2 ,fp );
530
+ if (tmpBytes < 2 ) {
531
+ debugf (1 ,"At end of input data - fread (phase 2b) returned %d bytes\n" ,tmpBytes );
532
+ goto mod_exit ;
533
+ }
516
534
517
- if (debugLevel >=3 )
518
- fprintf (infoStream ," NextLen = %d bytes \n" ,nextLength );
535
+ debugf (3 ," NextLen = %d bytes \n" ,nextLength );
519
536
520
537
if (offset + nextLength > sizeof (dataBuf ))
521
538
{
@@ -524,6 +541,10 @@ int main( int argc, char *argv[] )
524
541
}
525
542
526
543
bytesRead = fread (& dataBuf [offset ], 1 , nextLength - 4 , fp );
544
+ if (bytesRead < (nextLength - 4 )) {
545
+ debugf (1 ,"At end of input data - fread (phase 2c) returned %d bytes\n" ,tmpBytes );
546
+ goto mod_exit ;
547
+ }
527
548
offset += bytesRead ;
528
549
} while (pSMFMQRecord -> Header .SMFSEG [0 ] != 0x02 );/* end of record indicator*/
529
550
@@ -685,7 +706,7 @@ int main( int argc, char *argv[] )
685
706
convDate (pqwhs -> qwhsstck ,dt );
686
707
strcpy (commonF .stckFormatDate ,dt [0 ]);
687
708
strcpy (commonF .stckFormatDate ,dt [1 ]);
688
- if (recordType == SMFTYPE_MQ_STAT )
709
+ if (recordType == SMFTYPE_MQ_STAT )
689
710
{
690
711
if (conv16 (pqwhs -> qwhslen ) >= 52 )
691
712
{
@@ -745,8 +766,8 @@ int main( int argc, char *argv[] )
745
766
}
746
767
}
747
768
748
- if (debugLevel >= 3 && pqwhs != NULL )
749
- fprintf ( infoStream ,"Section count %d for %4.4s, qwhslen=%d\n" ,sectionCount ,commonF .qMgr ,conv16 (pqwhs -> qwhslen ));
769
+ if (pqwhs != NULL )
770
+ debugf ( 3 ,"Section count %d for %4.4s, qwhslen=%d\n" ,sectionCount ,commonF .qMgr ,conv16 (pqwhs -> qwhslen ));
750
771
751
772
/*********************************************************************/
752
773
/* Once we know how many sections there are, copy the triplet values */
@@ -792,7 +813,7 @@ int main( int argc, char *argv[] )
792
813
case SMFTYPE_MQ_STAT :
793
814
switch (recordSubType )
794
815
{
795
- case SMFSUBTYPE_MQ_STAT_BASIC :
816
+ case SMFSUBTYPE_MQ_STAT_BASIC :
796
817
/*****************************************************************/
797
818
/* Some of the triplets seem to refer to internal/undocumented */
798
819
/* structures. Only the QSST and QJST are known elements. */
@@ -935,15 +956,15 @@ int main( int argc, char *argv[] )
935
956
936
957
case SMFSUBTYPE_MQ_STAT_RESERVED_1 :
937
958
/* These are internal undocumented structures. There's not much we can do */
938
- /* except ignore them. We will see them show up in the overall subtype */
959
+ /* except ignore them. We will see them show up in the overall subtype */
939
960
/* stats of records processed, but no other debug. */
940
- if (!warn115_240 )
961
+ if (!warn115_240 )
941
962
{
942
963
sprintf (tmpHead ,"Internal SMF %d subtype %d records found" ,SMFTYPE_MQ_STAT ,recordSubType );
943
964
fprintf (infoStream ,"%s\n" ,tmpHead );
944
965
warn115_240 = TRUE;
945
966
}
946
- break ;
967
+ break ;
947
968
948
969
default :
949
970
knownSubType = FALSE;
@@ -1163,22 +1184,20 @@ int main( int argc, char *argv[] )
1163
1184
/* Cleanup and exit. If we get here normally, then the checkpoint */
1164
1185
/* file is not needed any more, so it is deleted. */
1165
1186
/***********************************************************************/
1166
- if (debugLevel >= 1 ) {
1167
- fprintf (infoStream ,"Removing checkpoint file\n" );
1168
- }
1187
+ debugf (1 ,"Removing checkpoint file %s\n" ,checkPointFileName );
1169
1188
remove (checkPointFileName );
1170
1189
pos = ftello (fp );
1171
1190
1191
+ mod_exit :
1172
1192
if (outputFormat == OF_SQL && ddlTemplateClose != NULL ) {
1173
1193
closeFinalDDL ();
1174
1194
}
1175
1195
1176
- mod_exit :
1177
-
1178
1196
fflush (NULL ); /* Ensure all streams flushed if possible */
1179
1197
1180
1198
for (i = 0 ;i < MAXCP ;i ++ ) {
1181
1199
if (checkPoint [i ].fp ) {
1200
+ debugf (1 ," Closing %s\n" ,checkPoint [i ].name );
1182
1201
fclose (checkPoint [i ].fp );
1183
1202
}
1184
1203
}
@@ -1188,8 +1207,8 @@ int main( int argc, char *argv[] )
1188
1207
}
1189
1208
1190
1209
formatRate = getFormatRate (pos );
1191
- fprintf ( infoStream , "Processed %u records total %s\n" , totalRecords , formatRate );
1192
-
1210
+ endTime = time ( NULL );
1211
+ fprintf ( infoStream , "Processed %u records total %s in %d seconds \n" , totalRecords , formatRate ,( int )( endTime - startTime ));
1193
1212
1194
1213
/**********************************************************************/
1195
1214
/* If the program has been restarted via checkpoint, these counts are */
@@ -1375,9 +1394,7 @@ myoff_t readCheckPoint(FILE *fp) {
1375
1394
sscanf (line ,"%d %lld" ,& startingRecords ,& inputOffset );
1376
1395
fprintf (infoStream ,"Reading from recovery checkpoint.\n" );
1377
1396
1378
- if (debugLevel >=1 ) {
1379
- fprintf (infoStream ,"InputOffset: %lld Processed records: %d\n" ,inputOffset , startingRecords );
1380
- }
1397
+ debugf (1 ,"InputOffset: %lld Processed records: %d\n" ,inputOffset , startingRecords );
1381
1398
1382
1399
/************************************************************************/
1383
1400
/* Subsequent lines have two fields naming the output structure and how */
@@ -1392,9 +1409,7 @@ myoff_t readCheckPoint(FILE *fp) {
1392
1409
sscanf (line ,"%s %lld" ,field ,& offset );
1393
1410
checkPoint [i ].name = strdup (field );
1394
1411
checkPoint [i ].offset = offset ;
1395
- if (debugLevel >=2 ) {
1396
- fprintf (infoStream ,"Loaded status[%d] for %s as offset %lld\n" ,i ,field ,offset );
1397
- }
1412
+ debugf (2 ,"Loaded status[%d] for %s as offset %lld\n" ,i ,field ,offset );
1398
1413
i ++ ;
1399
1414
}
1400
1415
} while (c );
@@ -1552,7 +1567,7 @@ int laterThan(int v)
1552
1567
strncpy (mqVer ,commonF .mqVer ,4 );
1553
1568
currentVersion = atoi (mqVer );
1554
1569
}
1555
- if (currentVersion > v )
1570
+ if (currentVersion > v )
1556
1571
return 1 ;
1557
1572
return rc ;
1558
1573
}
0 commit comments