diff --git a/CHANGES.md b/CHANGES.md index df77157..c8c10b3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,16 @@ History (newest at top) ======================= + +Sep 2023 (v5.4.4) +* Try to recognise some input file corruption and cleanly exit + Jun 2023 (v5.4.3) * Update for MQ V9.3.3 - * Many more QQST fields + * Many more QQST fields * New "-f jsoncompact" option for single-line JSON records * Add Task_Index field to channel structures, to easier tie up with MP1B output -* Correct a couple of column names in WQ structure +* Correct a couple of column names in WQ structure Feb 2023 (v5.4.2) * Update for MQ V9.3.2 diff --git a/src/M b/src/M index 17870df..d0b91d2 100755 --- a/src/M +++ b/src/M @@ -33,6 +33,11 @@ fi export PLATFLAGS=$flags CC=$cc VERS=$VERS make -e -f Makefile.unix $* +rc=$? +if [ $rc -ne 0 ] +then + exit $rc +fi rm -f $targdir/convH $targdir/mqsmfcsv cp convH mqsmfcsv $targdir diff --git a/src/Makefile.unix b/src/Makefile.unix index 5d80941..6940e32 100644 --- a/src/Makefile.unix +++ b/src/Makefile.unix @@ -3,6 +3,7 @@ CC=cc CFLAGS= -I. -O2 PLATFLAGS= SRC = \ + mqsmf.c \ smfDDL.c \ smfPrint.c \ smfDate.c \ @@ -39,8 +40,7 @@ SRC = \ t123/printDataV2.c \ t123/printServerV1.c \ t123/printServerV2.c \ - t180/printAMS.c \ - mqsmf.c + t180/printAMS.c HDR = mqsmfstrucU.h \ t123/smf123.h \ @@ -62,7 +62,7 @@ shipTest: mqsmfcsv mqsmfcsv: $(SRC) $(HDR) Makefile.unix dummy $(CC) $(PLATFLAGS) -o $@ $(SRC) $(CFLAGS) -DCSQDSMF_VERSION=$(VERS) -mqsmfstrucU.h: convH dummy # csqdsmfc-$(VERS).h +mqsmfstrucU.h: convH dummy # csqdsmfc-$(VERS).h (test -s csqdsmfc-$(VERS).h && convH $(VERS) < csqdsmfc-$(VERS).h > $@) || exit 0 convH: convH64.c dummy diff --git a/src/mqsmf.c b/src/mqsmf.c index bd8b6f5..7f4a862 100755 --- a/src/mqsmf.c +++ b/src/mqsmf.c @@ -161,6 +161,7 @@ static myoff_t pos; static int offsetCorrection = 0; static BOOL warn115_240=FALSE; +static BOOL corruptData = FALSE; static time_t startTime = 0; static time_t endTime = 0; @@ -243,6 +244,7 @@ int main( int argc, char *argv[] ) int sectionCount; int recordSubTypeVersion; + int triplet1Offset; infoStream=stdout; @@ -697,7 +699,18 @@ int main( int argc, char *argv[] ) /*******************************************************************/ offsetBlockStart = &pSMFMQRecord->s[0]; offsetBlockType = BT_TRIPLET; - p = &dataBuf[conv32(pSMFMQRecord->s[0].offset)]; + triplet1Offset = conv32(pSMFMQRecord->s[0].offset); + p = &dataBuf[triplet1Offset]; + + /* + debugf(2,"Current file offset: 0x%08X\n",currentOffset); + printDEBUG("INPUT BUF",dataBuf,offset); + debugf(2,"\n p=%p bytesread=%d offset=%d\n",p,bytesRead+4,offset); + debugf(2," trip[0] tripOffset=%d [0x%08X] len=%d count=%d\n", triplet1Offset,triplet1Offset, + conv16(pSMFMQRecord->s[0].l), + conv16(pSMFMQRecord->s[0].n)); + */ + if (conv16(pSMFMQRecord->s[0].l) == 4) /* There is no QWHS */ { sectionCount = 2; /* 1 extra triplet beyond the QWHS location */ @@ -708,7 +721,24 @@ int main( int argc, char *argv[] ) else { char *dt[2]; + int qwshlen; + pqwhs = (qwhs *)p; + qwshlen = conv16(pqwhs->qwhslen); + if (debugLevel >= 2) { + printDEBUG("QWHS",p,(qwshlen!=0)?qwshlen:0x30); + } + if (qwshlen <= 0) + { + FILE *dfp = printDEBUGStream(); + fprintf(stderr,"Error: Data at file offset 0x%08X appears corrupt. Exiting the formatter.\n",currentOffset); + if (dfp) { + fprintf(dfp, "Error: Data at file offset 0x%08X appears corrupt. Exiting the formatter.\n",currentOffset); + } + corruptData = TRUE; + continue; + } + sectionCount = pqwhs->qwhsnsda[0]; convDate(pqwhs->qwhsstck,dt); strcpy(commonF.stckFormatDate,dt[0]); @@ -736,7 +766,7 @@ int main( int argc, char *argv[] ) } break; - case SMFTYPE_ZCEE: + case SMFTYPE_ZCEE: recordSubTypeVersion = conv32(pSMFMQRecord->Header.u.v); switch (recordSubTypeVersion) @@ -773,8 +803,9 @@ int main( int argc, char *argv[] ) } } - if (pqwhs != NULL) - debugf(3,"Section count %d for %4.4s, qwhslen=%d\n",sectionCount,commonF.qMgr,conv16(pqwhs->qwhslen)); + if (pqwhs != NULL) { + debugf(3,"Section count %d for %4.4s, qwhslen=%d\n",sectionCount,commonF.qMgr,conv16(pqwhs->qwhslen)); + } /*********************************************************************/ /* Once we know how many sections there are, copy the triplet values */ @@ -786,8 +817,9 @@ int main( int argc, char *argv[] ) /*********************************************************************/ recLength = getOffsets(sectionCount,offsetBlockStart, offsetBlockType, recordType,subTypesValid, currentOffset); currentOffset += recLength; - if (debugLevel >= 2) + if (debugLevel >= 2) { printDEBUG("FULL RECORD",dataBuf + offsetCorrection,recLength); + } /*********************************************************************/ @@ -1185,7 +1217,7 @@ int main( int argc, char *argv[] ) exit(0); } } - } while (0 != bytesRead && totalRecords < maxRecords); + } while (0 != bytesRead && totalRecords < maxRecords && !corruptData); /***********************************************************************/ /* Cleanup and exit. If we get here normally, then the checkpoint */ @@ -1740,26 +1772,20 @@ int getOffsets(int sectionCount,void *offsetBlockStart, int offsetBlockType, int { if (recordType == amsType) { - fprintf(infoStream, "Highest doublet = %d RecLength = %d New Offset = %lld\n", + debugf(3, "Highest doublet = %d RecLength = %d New Offset = %lld\n", h, recLength, currentOffset); - if (debugLevel >=4) + for (i=0;i=4) + for (i=0;i= _level) fprintf(infoStream,_fmt,__VA_ARGS__);} + {if (debugLevel >= _level) { \ + FILE *dfp = printDEBUGStream(); \ + if (dfp) { \ + fprintf(dfp,_fmt,__VA_ARGS__); \ + } \ + fprintf(infoStream,_fmt,__VA_ARGS__);} \ + } #endif /* * Convert some MQI values into the corresponding string diff --git a/src/printDEBUG.c b/src/printDEBUG.c index 224c0ce..6dfb4a2 100644 --- a/src/printDEBUG.c +++ b/src/printDEBUG.c @@ -72,3 +72,8 @@ void printDEBUG(char *title, void *buf,int length) } return; } + +FILE *printDEBUGStream() +{ + return fp; +}