1108 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1108 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* log4fix.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | |
| /* Fixes corrupt server .LOG files */
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Preprocessor Directives
 | |
| ****************************************************************************/
 | |
| 
 | |
| #include "d4all.h"
 | |
| 
 | |
| #ifndef S4UTILS
 | |
|    #error - Must compile with S4UTILS defined
 | |
| #endif
 | |
| 
 | |
| #include "u4trans.h"
 | |
| 
 | |
| #ifndef S4WINDOWS
 | |
| #ifndef S4UNIX
 | |
|    #ifdef __TURBOC__
 | |
|       #pragma hdrstop
 | |
|    #endif
 | |
|    extern unsigned _stklen = 10000;
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| #ifdef S4DLL_BUILD
 | |
|    extern FILE *stdout, *stderr ;
 | |
|    extern unsigned int messageType ;
 | |
|    HWND hWndStatus ;  /* status window handle */
 | |
| #endif
 | |
| 
 | |
| #ifndef S4UTIL_CONCURRENCY
 | |
|    #define UTIL4LOG    0
 | |
| #else
 | |
|    #define UTIL4CONFIG 0
 | |
| #endif
 | |
| #define UTIL4FORCE     1
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Global scope types and variables
 | |
| ****************************************************************************/
 | |
| 
 | |
| static UTIL4FLAG u4flags[] =
 | |
| {
 | |
| #ifndef S4UTIL_CONCURRENCY
 | |
|    { "Log",       0, 1, 1,  1, 1, 0, 0, 0, "{-log <server.log>}\r\n"      },
 | |
| #else
 | |
|    { "Config",    0, 1, 1, -1, 0, 0, 0, 0, "{-config [<config.dbf>]}\r\n" },
 | |
| #endif
 | |
|    { "Force",     0, 1, 1,  1, 1, 0, 0, 0, "[-force {OFF | ON}]\r\n"      },
 | |
| };
 | |
| 
 | |
| static int u4flagsNum = 2;
 | |
| 
 | |
| static FIELD4INFO openFields[] =
 | |
| {
 | |
|    { "CLIENTID",   'N', 11,       0 },
 | |
|    { "CLIENTDTID", 'N', 11,       0 },
 | |
|    { "SERVERDTID", 'N', 11,       0 },
 | |
|    { "PHYSNAME",   'C', LEN4PATH, 0 },
 | |
|    { "RECORDWID",  'N', 11,       0 },
 | |
|    { "NUMFIELDS",  'N',  6,       0 },
 | |
|    { 0,0,0,0 },
 | |
| };
 | |
| 
 | |
| static TAG4INFO openTags[] =
 | |
| {
 | |
|    { "CLID", "STR(CLIENTID,11,0)+STR(SERVERDTID,11,0)", ".NOT.DELETED()", r4unique, 0 },
 | |
|    { 0,0,0,0,0 },
 | |
| };
 | |
| 
 | |
| static FIELD4INFO tranFields[] =
 | |
| {
 | |
|    { "TRANID",   'N', 11, 0 },
 | |
|    { 0,0,0,0 },
 | |
| } ;
 | |
| 
 | |
| static TAG4INFO tranTags[] =
 | |
| {
 | |
|    { "TRANID", "STR(TRANID,11,0)", ".NOT.DELETED()", r4unique, 0 },
 | |
|    { 0,0,0,0,0 },
 | |
| } ;
 | |
| 
 | |
| #ifndef S4WINDOWS
 | |
|    char *statusStringBlank = "                         ";
 | |
|    char *statusStringMessg = "Processing log file: ";
 | |
|    char *statusStringBckSp = "\r";
 | |
|    char *statusStringFormt = "%3d.%02d%%%%";
 | |
|    #ifdef S4UNIX
 | |
|       char statusStringSpace[10] ;
 | |
|    #else
 | |
|       char *statusStringSpace = "100.00  ";
 | |
|    #endif
 | |
| #else
 | |
|    extern char *statusStringBlank ;
 | |
|    extern char *statusStringMessg ;
 | |
|    extern char *statusStringBckSp ;
 | |
|    extern char *statusStringFormt ;
 | |
|    extern char *statusStringSpace ;
 | |
| #endif
 | |
| 
 | |
| /*::************************************************************************/
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Function: findIncompleteTran
 | |
| **
 | |
| *****************************************************************************
 | |
| **
 | |
| **    Function: findIncompleteTran()
 | |
| **
 | |
| ****************************************************************************/
 | |
| short findIncompleteTran(CODE4 *c4, DATA4 *openDbf, DATA4 *tranDbf)
 | |
| {
 | |
|    short rc, intPart, decPart;
 | |
|    TRAN4 *t4=0;
 | |
|    FIELD4 *openClientId=0, *openClientDataId=0, *openServerDataId=0, *openPhysName=0, *tranTranId=0, *tranClientId=0;
 | |
|    FIELD4 *openRecordWidth=0, *openNumFields=0;
 | |
|    char client[23], *outMess[3];
 | |
|    char *data=0;
 | |
|    long logFileLen;
 | |
|    TRAN4ENTRY_LEN len;
 | |
|    #ifdef S4DATA_ALIGN
 | |
|       long templong;
 | |
|       short tempshort;
 | |
|    #endif
 | |
| 
 | |
|    rc = file4refresh(&c4->transFile.file);
 | |
|    if (rc != 0)
 | |
|       return(rc);
 | |
|    logFileLen = file4len(&c4->transFile.file);
 | |
|    if (logFileLen < 0)
 | |
|       return((short)logFileLen);
 | |
| 
 | |
|    t4 = &c4->c4trans.trans;
 | |
|    openClientId = d4field(openDbf, "CLIENTID");
 | |
|    openClientDataId = d4field(openDbf, "CLIENTDTID");
 | |
|    openServerDataId = d4field(openDbf, "SERVERDTID");
 | |
|    openPhysName = d4field(openDbf, "PHYSNAME");
 | |
|    openRecordWidth = d4field(openDbf, "RECORDWID");
 | |
|    openNumFields = d4field(openDbf, "NUMFIELDS");
 | |
|    d4tagSelect(openDbf, d4tag(openDbf, "CLID"));
 | |
| 
 | |
|    tranTranId = d4field(tranDbf, "TRANID");
 | |
|    d4tagSelect(tranDbf, d4tag(tranDbf, "TRANID"));
 | |
|    #ifndef S4WINDOWS
 | |
|       outMess[0] = statusStringBlank;
 | |
|       util4out(c4, stderr, outMess, 1);
 | |
|    #endif
 | |
| 
 | |
|    for (rc = tran4top(t4); ; rc = tran4skip(t4, TRAN4FORWARDS))
 | |
|    {
 | |
|       if (rc != 0)
 | |
|          break;
 | |
|       intPart = (short)((unsigned long)c4->c4trans.trans.pos*50/logFileLen);
 | |
|       decPart = (short)((unsigned long)c4->c4trans.trans.pos*5000/logFileLen%100);
 | |
|       #ifndef S4WINDOWS
 | |
|          sprintf(statusStringSpace, statusStringFormt, intPart, decPart);
 | |
|          outMess[0] = statusStringBckSp;
 | |
|          outMess[1] = statusStringMessg;
 | |
|          outMess[2] = statusStringSpace;
 | |
|          util4out(c4, stderr, outMess, 3);
 | |
|       #else
 | |
|          sendStatusMessage( hWndStatus, intPart ) ;
 | |
|       #endif
 | |
| 
 | |
|       switch (tran4type(t4))
 | |
|       {
 | |
|          case TRAN4BACKEDUP:
 | |
|          case TRAN4WRITE:
 | |
|          case TRAN4APPEND:
 | |
|          case TRAN4PACK:
 | |
|          case TRAN4ZAP:
 | |
|          case TRAN4VOID:
 | |
|             break;
 | |
| 
 | |
|          case TRAN4SHUTDOWN:
 | |
|             rc = d4pack(openDbf);
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             if (d4recCount(openDbf) > 0)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file corrupt! User(s) initialized at shutdown, continuing.\r\n\r\n";
 | |
|                #ifndef S4WINDOWS
 | |
|                   outMess[1] = statusStringBlank;
 | |
|                   util4out(c4, stdout, outMess, 2);
 | |
|                #else
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                #endif
 | |
|                rc = d4zap(openDbf, 1L, d4recCount(openDbf));
 | |
|                if (rc != 0)
 | |
|                   break;
 | |
|             }
 | |
|             rc = d4pack(tranDbf);
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             if (d4recCount(tranDbf) > 0)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file corrupt! Transaction(s) active at shutdown, continuing.\r\n\r\n";
 | |
|                #ifndef S4WINDOWS
 | |
|                   outMess[1] = statusStringBlank;
 | |
|                   util4out(c4, stdout, outMess, 2);
 | |
|                #else
 | |
|                   util4out(c4, stdout, outMess, 1) ;
 | |
|                #endif
 | |
| 
 | |
|                rc = d4zap(tranDbf, 1L, d4recCount(tranDbf));
 | |
|                if (rc != 0)
 | |
|                   break;
 | |
|             }
 | |
|             if (tran4serverDataId(&c4->c4trans.trans) > TRAN4VERSION_NUM)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file error! File is a newer version than this utility can handle!\r\n\r\n";
 | |
|                util4out(c4, stdout, outMess, 1);
 | |
|                rc = -1;
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|          case TRAN4INIT:
 | |
|             rc = d4appendStart(openDbf, 0);
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             d4blank(openDbf);
 | |
|             f4assignLong(openClientId, tran4clientId(t4));
 | |
|             rc = d4append(openDbf);
 | |
|             if (rc == r4unique)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file error! User already initialized.\r\n\r\n";
 | |
|                util4out(c4, stdout, outMess, 1);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|          case TRAN4INIT_UNDO:
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc == 0 && f4long(openClientDataId) != 0)
 | |
|                rc = r4after;
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! User uninitialized that is not initialized.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             d4delete(openDbf);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc == 0)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file error! User uninitialized with DBF's still open.\r\n\r\n";
 | |
|                util4out(c4, stdout, outMess, 1);
 | |
|                rc = -1;
 | |
|                break;
 | |
|             }
 | |
|             if (rc == r4after || rc == r4eof)
 | |
|                rc = 0;
 | |
|             break;
 | |
| 
 | |
|          case TRAN4OPEN:
 | |
|          case TRAN4OPEN_TEMP:
 | |
|             data = (char *)tran4getData(t4, 0L);
 | |
|             if (data == 0)
 | |
|             {
 | |
|                rc = -1;
 | |
|                break;
 | |
|             }
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! DBF opened by user that is not initialized.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             rc = d4appendStart(openDbf, 0);
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             f4assignLong(openClientDataId, tran4clientDataId(t4));
 | |
|             f4assignLong(openServerDataId, tran4serverDataId(t4));
 | |
|             f4assignN(openPhysName, data+2, *(short *)data);
 | |
|             #ifdef S4DATA_ALIGN
 | |
|                memcpy(&templong, (data+2+*(short *)data), sizeof(long) );
 | |
|                f4assignLong(openRecordWidth, templong);
 | |
|                memcpy(&tempshort, (data+6+*(short *)data), sizeof(short) );
 | |
|                f4assignInt(openNumFields, tempshort);
 | |
|             #else
 | |
|                f4assignLong(openRecordWidth, *(long *)(data+2+ *(short *)data));
 | |
|                f4assignInt(openNumFields, *(short *)(data+6+ *(short *)data));
 | |
|             #endif
 | |
|             rc = d4append(openDbf);
 | |
|             if (rc == r4unique)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file error! DBF identifier already used.\r\n\r\n";
 | |
|                util4out(c4, stdout, outMess, 1);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|          case TRAN4CLOSE:
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! DBF closed that is not open.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             d4delete(openDbf);
 | |
|             break;
 | |
| 
 | |
|          case TRAN4START:
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! Transaction started by user that is not initialized.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             rc = d4appendStart(tranDbf, 0);
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             d4blank(tranDbf);
 | |
|             f4assignLong(tranTranId, tran4id(t4));
 | |
|             rc = d4append(tranDbf);
 | |
|             if (rc == r4unique)
 | |
|             {
 | |
|                outMess[0] = "\r\n\r\nLog file error! Transaction ID already started.\r\n\r\n";
 | |
|                util4out(c4, stdout, outMess, 1);
 | |
|             }
 | |
|             break ;
 | |
| 
 | |
|          case TRAN4COMPLETE:
 | |
|          case TRAN4ROLLBACK:
 | |
|             util4rightJ(ltoa(tran4id(t4), client, 10), 12);
 | |
|             rc = d4seek(tranDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   if (tran4type(t4) == TRAN4COMPLETE)
 | |
|                      outMess[0] = "\r\n\r\nLog file error! Transaction completed that was not started.\r\n\r\n";
 | |
|                   else
 | |
|                      outMess[0] = "\r\n\r\nLog file error! Transaction rolledback that was not started.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             d4delete(tranDbf);
 | |
|             break;
 | |
| 
 | |
|          default:
 | |
|             outMess[0] = "\r\n\r\nLog file error! Unknown log entry type.\r\n\r\n";
 | |
|             util4out(c4, stdout, outMess, 1);
 | |
|             rc = -1;
 | |
|       }
 | |
|       if (rc != 0)
 | |
|          break;
 | |
|       if (t4->pos+sizeof(LOG4HEADER)+sizeof(TRAN4ENTRY_LEN) > logFileLen)
 | |
|       {
 | |
|          rc = r4eof;
 | |
|          break;
 | |
|       }
 | |
|       rc = file4readAll(&c4->transFile.file, t4->pos+sizeof(LOG4HEADER), &len, sizeof(TRAN4ENTRY_LEN));
 | |
|       if (rc == 0 && (long)(t4->pos+sizeof(LOG4HEADER)+len) > logFileLen)
 | |
|       {
 | |
|          rc = r4eof;
 | |
|          break;
 | |
|       }
 | |
|       if (rc != 0)
 | |
|          break;
 | |
|    }
 | |
|    if (rc == r4eof)
 | |
|       if (t4->pos+sizeof(LOG4HEADER) != logFileLen)
 | |
|          rc = file4lenSet(&c4->transFile.file, t4->pos+sizeof(LOG4HEADER));
 | |
|       else
 | |
|          rc = 0;
 | |
|    return rc;
 | |
| }
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Function: checkDbfHeader
 | |
| **
 | |
| *****************************************************************************
 | |
| **
 | |
| **    Function: checkDbfHeader()
 | |
| **
 | |
| ****************************************************************************/
 | |
| short checkDbfHeader(CODE4 *c4, char *fileName)
 | |
| {
 | |
|    short rc, rc2;
 | |
|    FILE4 file;
 | |
|    DATA4HEADER_FULL fullHeader;
 | |
|    S4LONG lengthRecords;
 | |
| 
 | |
|    c4trimN(fileName, strlen(fileName)+1);
 | |
|    rc = file4open(&file, c4, fileName, 1);
 | |
|    if (rc != 0)
 | |
|       if (rc != r4noOpen)
 | |
|          return(rc);
 | |
|       else
 | |
|          return(0);
 | |
| 
 | |
|    rc = file4readAll(&file, 0L, &fullHeader, sizeof(fullHeader));
 | |
|    if (rc < 0)
 | |
|    {
 | |
|       file4close(&file);
 | |
|       return(rc);
 | |
|    }
 | |
|    #ifdef S4BYTE_SWAP
 | |
|       fullHeader.numRecs = x4reverseLong( (void *)&fullHeader.numRecs ) ;
 | |
|       fullHeader.headerLen = x4reverseShort( (void *)&fullHeader.headerLen ) ;
 | |
|       fullHeader.recordLen = x4reverseShort( (void *)&fullHeader.recordLen ) ;
 | |
|    #endif
 | |
|    lengthRecords = (file4len(&file) - fullHeader.headerLen) / fullHeader.recordLen;
 | |
|    if (fullHeader.numRecs != lengthRecords)
 | |
|       rc = file4write(&file, 4L, &lengthRecords, sizeof(S4LONG));
 | |
|    rc2 = file4close(&file);
 | |
|    if (rc != 0)
 | |
|       rc2 = rc;
 | |
|    return(rc2);
 | |
| }
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Function: fixIncompleteTran
 | |
| **
 | |
| *****************************************************************************
 | |
| **
 | |
| **    Function: fixIncompleteTran()
 | |
| **
 | |
| ****************************************************************************/
 | |
| short fixIncompleteTran(CODE4 *c4, DATA4 *openDbf, DATA4 *tranDbf, short force)
 | |
| {
 | |
|    short rc, rc2, rc3, i, curNumFields, consistency, intPart, decPart;
 | |
|    unsigned smallerSize;
 | |
|    TRAN4 *t4=0;
 | |
|    DATA4 **userDbfs=0, *curDbf=0;
 | |
|    char *outMess[8], *data=0, client[23];
 | |
|    char ltoaTemp[12];
 | |
|    char ltoaTemp2[12];
 | |
|    unsigned long offsetMemo, offset;
 | |
|    long curRecWidth;
 | |
|    long logFileLen;
 | |
| 
 | |
|    rc = file4refresh(&c4->transFile.file);
 | |
|    if (rc != 0)
 | |
|       return(rc);
 | |
|    logFileLen = file4len(&c4->transFile.file);
 | |
|    if (logFileLen < 0)
 | |
|       return((short)logFileLen);
 | |
| 
 | |
|    t4 = &c4->c4trans.trans;
 | |
|    rc = d4pack(openDbf);
 | |
|    if (rc != 0)
 | |
|       return(rc);
 | |
|    if (d4recCount(openDbf) > 0)
 | |
|    {
 | |
|       userDbfs = (DATA4 **)u4allocFree(c4, d4recCount(openDbf)*4);
 | |
|       if (userDbfs == 0)
 | |
|          return(-1);
 | |
|    }
 | |
|    c4->errOpen = 0;
 | |
|    for (rc = d4top(openDbf); rc == 0; rc = d4skip(openDbf,1L))
 | |
|    {
 | |
|       if (f4long(d4field(openDbf, "SERVERDTID")) == 0)
 | |
|       {
 | |
|          userDbfs[d4recNo(openDbf)-1L] = 0;
 | |
|          continue;
 | |
|       }
 | |
|       rc = checkDbfHeader(c4, f4str(d4field(openDbf, "PHYSNAME")));
 | |
|       if (rc != 0)
 | |
|       {
 | |
|          outMess[0] = "\r\n\r\nError! Can not fix record count for ";
 | |
|          outMess[1] = f4str(d4field(openDbf, "PHYSNAME"));
 | |
|          outMess[2] = "\r\n\r\n";
 | |
|          util4out(c4, stdout, outMess, 3);
 | |
|          curDbf = 0;
 | |
|          c4->errorCode = 0;
 | |
|       }
 | |
|       else
 | |
|          curDbf = d4open(c4, f4str(d4field(openDbf, "PHYSNAME")));
 | |
|       if (curDbf && ((unsigned)f4long(d4field(openDbf, "RECORDWID")) != d4recWidth(curDbf) || f4int(d4field(openDbf, "NUMFIELDS")) != d4numFields(curDbf)))
 | |
|       {
 | |
|          rc = d4close(curDbf);
 | |
|          if (rc != 0)
 | |
|             c4->errorCode = 0;
 | |
|          else
 | |
|             c4->errorCode = r4noOpen;
 | |
|          curDbf = 0;
 | |
|       }
 | |
|       if (curDbf != 0)
 | |
|       {
 | |
|          rc = d4reindex(curDbf);
 | |
|          if (rc != 0)
 | |
|          {
 | |
|             d4close(curDbf);
 | |
|             curDbf = 0;
 | |
|             c4->errorCode = 0;
 | |
|          }
 | |
|       }
 | |
|       if (curDbf == 0)
 | |
|          if (c4->errorCode == r4noOpen)
 | |
|          {
 | |
|             outMess[0] = "\r\n\r\n";
 | |
|             outMess[1] = f4str(d4field(openDbf, "PHYSNAME"));
 | |
|             c4trimN(outMess[1], strlen(outMess[1])+1);
 | |
|             outMess[2] = "\r\neither not found or structure does not match log file entry, skipping.\r\n\r\n";
 | |
|             #ifndef S4WINDOWS
 | |
|                outMess[3] = statusStringBlank;
 | |
|                util4out(c4, stdout, outMess, 4);
 | |
|             #else
 | |
|                util4out(c4, stdout, outMess, 3);
 | |
|             #endif
 | |
|          }
 | |
|          else
 | |
|          {
 | |
|             for (rc = d4skip(openDbf, -1L); rc == 0; rc = d4skip(openDbf, -1L))
 | |
|                if (userDbfs[d4recNo(openDbf)-1L] != 0)
 | |
|                   d4close(userDbfs[d4recNo(openDbf)-1L]);
 | |
|             u4free(userDbfs);
 | |
|             return(-1);
 | |
|          }
 | |
|       userDbfs[d4recNo(openDbf)-1L] = curDbf;
 | |
|    }
 | |
|    c4->errOpen = 1;
 | |
| 
 | |
|    for (rc = tran4bottom(t4); ; rc = tran4skip(t4, TRAN4BACKWARDS))
 | |
|    {
 | |
|       if (rc != 0)
 | |
|          break;
 | |
|       consistency = 1;
 | |
|       intPart = (short)((unsigned long)(logFileLen-c4->c4trans.trans.pos)*50/logFileLen+50);
 | |
|       decPart = (short)((unsigned long)(logFileLen-c4->c4trans.trans.pos)*5000/logFileLen%100);
 | |
|       #ifndef S4WINDOWS
 | |
|          sprintf(statusStringSpace, statusStringFormt, intPart, decPart);
 | |
|          outMess[0] = statusStringBckSp;
 | |
|          outMess[1] = statusStringMessg;
 | |
|          outMess[2] = statusStringSpace;
 | |
|          util4out(c4, stderr, outMess, 3);
 | |
|       #else
 | |
|          sendStatusMessage( hWndStatus, intPart ) ;
 | |
|       #endif
 | |
| 
 | |
|       switch (tran4type(t4))
 | |
|       {
 | |
|          case TRAN4SHUTDOWN:
 | |
|          case TRAN4BACKEDUP:
 | |
|          case TRAN4INIT:
 | |
|          case TRAN4INIT_UNDO:
 | |
|          case TRAN4OPEN:
 | |
|          case TRAN4OPEN_TEMP:
 | |
|          case TRAN4CLOSE:
 | |
|          case TRAN4START:
 | |
|          case TRAN4COMPLETE:
 | |
|          case TRAN4ROLLBACK:
 | |
|          case TRAN4PACK:
 | |
|          case TRAN4ZAP:
 | |
|          case TRAN4VOID:
 | |
|             break;
 | |
| 
 | |
|          case TRAN4WRITE:
 | |
|             util4rightJ(ltoa(tran4id(t4), client, 10), 12);
 | |
|             rc = d4seek(tranDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                   rc = 0;
 | |
|                break;
 | |
|             }
 | |
| 
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! Write to DBF that is not open.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
| 
 | |
|             curDbf = userDbfs[d4recNo(openDbf)-1L];
 | |
|             if (curDbf == 0)
 | |
|                break;
 | |
|             data = (char *)tran4getData(t4, 0L);
 | |
|             if (data == 0)
 | |
|             {
 | |
|                rc = -1;
 | |
|                break;
 | |
|             }
 | |
|             c4->errGo = 0;
 | |
|             rc = d4go(curDbf, *(long *)data);
 | |
|             c4->errGo = 1;
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4entry)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\n";
 | |
|                   outMess[1] = f4str(d4field(openDbf, "PHYSNAME"));
 | |
|                   c4trimN(outMess[1], strlen(outMess[1])+1);
 | |
|                   outMess[2] = " consistency error!\r\nIn transaction #";
 | |
|                   outMess[3] = ltoa(tran4id(t4), ltoaTemp, 10);
 | |
|                   outMess[4] = ", write to DBF record #";
 | |
|                   outMess[5] = ltoa(*(long *)data, ltoaTemp2, 10);
 | |
|                   outMess[6] = " that does not exist, skipping.\r\n\r\n";
 | |
|                   outMess[7] = statusStringBlank;
 | |
|                   util4out(c4, stdout, outMess, 8);
 | |
|                   rc = 0;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
|             curRecWidth = f4long(d4field(openDbf, "RECORDWID"));
 | |
|             curNumFields = f4int(d4field(openDbf, "NUMFIELDS"));
 | |
| 
 | |
|             if (*(data+4+curRecWidth) == '*')
 | |
|             {
 | |
|                if (!d4deleted(curDbf))
 | |
|                   consistency = 0;
 | |
|             }
 | |
|             else
 | |
|                if (d4deleted(curDbf))
 | |
|                   consistency = 0;
 | |
|             offset = 5 + curRecWidth;
 | |
|             offsetMemo = 4 + 2*curRecWidth;
 | |
|             for (i=1; i <= d4numFields(curDbf) && consistency == 1; i++)
 | |
|             {
 | |
|                if (f4type(d4fieldJ(curDbf, i)) == 'M')
 | |
|                {
 | |
|                   offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                   smallerSize = f4memoLen(d4fieldJ(curDbf, i)) < *(unsigned *)(data+offsetMemo) ? f4memoLen(d4fieldJ(curDbf, i)) : *(unsigned *)(data+offsetMemo);
 | |
|                   if (strncmp(f4memoPtr(d4fieldJ(curDbf, i)), data+offsetMemo+4, smallerSize) != 0)
 | |
|                      consistency = 0;
 | |
|                   offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                   offset += 10;
 | |
|                }
 | |
|                else
 | |
|                {
 | |
|                   if (strncmp(f4ptr(d4fieldJ(curDbf, i)), data+offset, f4len(d4fieldJ(curDbf, i))) != 0)
 | |
|                      consistency = 0;
 | |
|                   offset += f4len(d4fieldJ(curDbf, i));
 | |
|                }
 | |
|             }
 | |
|             if (consistency == 0 && force == 0)
 | |
|                break;
 | |
| 
 | |
|             if (*(data+4) == '*')
 | |
|                d4delete(curDbf);
 | |
|             else
 | |
|                d4recall(curDbf);
 | |
|             offset = 5;
 | |
|             offsetMemo = 4 + 2*curRecWidth;
 | |
|             for (i=1; i <= d4numFields(curDbf); i++)
 | |
|             {
 | |
|                if (f4type(d4fieldJ(curDbf, i)) == 'M')
 | |
|                {
 | |
|                   if (*(unsigned long *)(data+offsetMemo) != 0)
 | |
|                   {
 | |
|                      f4memoAssignN(d4fieldJ(curDbf, i), data+offsetMemo+4, *(unsigned *)(data+offsetMemo));
 | |
|                      offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                   }
 | |
|                   else
 | |
|                   {
 | |
|                      offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                      if (*(unsigned long *)(data+offsetMemo) != 0)
 | |
|                         f4memoAssignN(d4fieldJ(curDbf, i), 0, 0);
 | |
|                   }
 | |
|                   offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                   offset += 10;
 | |
|                }
 | |
|                else
 | |
|                {
 | |
|                   f4assignN(d4fieldJ(curDbf, i), data+offset, f4len(d4fieldJ(curDbf, i)));
 | |
|                   offset += f4len(d4fieldJ(curDbf, i));
 | |
|                }
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|          case TRAN4APPEND:
 | |
|             util4rightJ(ltoa(tran4id(t4), client, 10), 12);
 | |
|             rc = d4seek(tranDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                   rc = 0;
 | |
|                break;
 | |
|             }
 | |
| 
 | |
|             util4rightJ(ltoa(tran4clientId(t4), client, 10), 12);
 | |
|             util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12);
 | |
|             rc = d4seek(openDbf, client);
 | |
|             if (rc != 0)
 | |
|             {
 | |
|                if (rc == r4after || rc == r4eof)
 | |
|                {
 | |
|                   outMess[0] = "\r\n\r\nLog file error! Append to DBF that is not open.\r\n\r\n";
 | |
|                   util4out(c4, stdout, outMess, 1);
 | |
|                   rc = -1;
 | |
|                }
 | |
|                break;
 | |
|             }
 | |
| 
 | |
|             curDbf = userDbfs[d4recNo(openDbf)-1L];
 | |
|             if (curDbf == 0)
 | |
|                break;
 | |
|             data = (char *)tran4getData(t4, 0L);
 | |
|             if (data == 0)
 | |
|             {
 | |
|                rc = -1;
 | |
|                break;
 | |
|             }
 | |
|             if (*(long *)data != d4recCount(curDbf))
 | |
|             {
 | |
|                outMess[0] ="\r\n\r\n";
 | |
|                outMess[1] = f4str(d4field(openDbf, "PHYSNAME"));
 | |
|                c4trimN(outMess[1], strlen(outMess[1])+1);
 | |
|                outMess[2] = " consistency error!\r\nIn transaction #";
 | |
|                outMess[3] = ltoa(tran4id(t4), ltoaTemp, 10);
 | |
|                outMess[4] = ", appended DBF record #";
 | |
|                outMess[5] = ltoa(*(long *)data, ltoaTemp2, 10);
 | |
|                outMess[6] = " is no longer the last record, skipping.\r\n\r\n";
 | |
|                outMess[7] = statusStringBlank;
 | |
|                util4out(c4, stdout, outMess, 8);
 | |
|                rc = 0;
 | |
|                break;
 | |
|             }
 | |
|             c4->errGo = 0;
 | |
|             rc = d4go(curDbf, *(long *)data);
 | |
|             c4->errGo = 1;
 | |
|             if (rc != 0)
 | |
|                break;
 | |
|             curRecWidth = f4long(d4field(openDbf, "RECORDWID"));
 | |
|             curNumFields = f4int(d4field(openDbf, "NUMFIELDS"));
 | |
| 
 | |
|             if (*(data+4) == '*')
 | |
|             {
 | |
|                if (!d4deleted(curDbf))
 | |
|                   consistency = 0;
 | |
|             }
 | |
|             else
 | |
|                if (d4deleted(curDbf))
 | |
|                   consistency = 0;
 | |
|             offset = 5;
 | |
|             offsetMemo = 4 + curRecWidth;
 | |
|             for (i=1; i <= d4numFields(curDbf) && consistency == 1; i++)
 | |
|             {
 | |
|                if (f4type(d4fieldJ(curDbf, i)) == 'M')
 | |
|                {
 | |
|                   smallerSize = f4memoLen(d4fieldJ(curDbf, i)) < *(unsigned *)(data+offsetMemo) ? f4memoLen(d4fieldJ(curDbf, i)) : *(unsigned *)(data+offsetMemo);
 | |
|                   if (strncmp(f4memoPtr(d4fieldJ(curDbf, i)), data+offsetMemo+4, smallerSize) != 0)
 | |
|                      consistency = 0;
 | |
|                   offsetMemo += 4 + *(unsigned long *)(data+offsetMemo);
 | |
|                   offset += 10;
 | |
|                }
 | |
|                else
 | |
|                {
 | |
|                   if (strncmp(f4ptr(d4fieldJ(curDbf, i)), data+offset, f4len(d4fieldJ(curDbf, i))) != 0)
 | |
|                      consistency = 0;
 | |
|                   offset += f4len(d4fieldJ(curDbf, i));
 | |
|                }
 | |
|             }
 | |
|             if (consistency == 0 && force == 0)
 | |
|                break;
 | |
| 
 | |
|             code4unlockAutoSet(c4, 0);
 | |
|             rc = d4unappend(curDbf);
 | |
|             code4unlockAutoSet(c4, 1);
 | |
|             break;
 | |
| 
 | |
|          default:
 | |
|             outMess[0] = "\r\n\r\nLog file error! Unknown log entry type.\r\n\r\n";
 | |
|             util4out(c4, stdout, outMess, 1);
 | |
|             rc = -1;
 | |
|       }
 | |
|       if (consistency == 0)
 | |
|       {
 | |
|          outMess[0] ="\r\n\r\n";
 | |
|          outMess[1] = f4str(d4field(openDbf, "PHYSNAME"));
 | |
|          c4trimN(outMess[1], strlen(outMess[1])+1);
 | |
|          outMess[2] = " consistency error!\r\nIn transaction #";
 | |
|          outMess[3] = ltoa(tran4id(t4), ltoaTemp, 10);
 | |
|          outMess[4] = ", DBF record #";
 | |
|          outMess[5] = ltoa(*(long *)data, ltoaTemp2, 10);
 | |
|          if (force == 0)
 | |
|             outMess[6] = " does not match log file entry, skipping.\r\n";
 | |
|          else
 | |
|             outMess[6] = " does not match log file entry, restore forced anyways.\r\n\r\n";
 | |
|          outMess[7] = statusStringBlank;
 | |
|          util4out(c4, stdout, outMess, 8);
 | |
|       }
 | |
|       if ( rc != 0 )
 | |
|          break ;
 | |
|    }
 | |
|    if (rc == r4bof)
 | |
|    {
 | |
|       rc = 0;
 | |
|       #ifndef S4WINDOWS
 | |
|          outMess[0] = statusStringBckSp;
 | |
|          outMess[1] = statusStringMessg;
 | |
|          sprintf(statusStringSpace, statusStringFormt, 100, 0);
 | |
|          outMess[2] = statusStringSpace;
 | |
|          util4out(c4, stderr, outMess, 3);
 | |
|       #endif
 | |
|    }
 | |
| 
 | |
|    #ifndef S4WINDOWS
 | |
|       outMess[0] = "\r\n";
 | |
|       util4out(c4, stderr, outMess, 1);
 | |
|       util4out(c4, stdout, outMess, 1);
 | |
|    #endif
 | |
|    rc2 = rc;
 | |
|    rc3 = 0;
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       for (rc=d4top(tranDbf); rc == 0; rc = d4skip(tranDbf, 1L))
 | |
|       {
 | |
|          rc = tran4set(t4, r4off, f4long(d4field(tranDbf, "TRANID")), 0, TRAN4ROLLBACK, 0, 0, 0);
 | |
|          if (rc < 0)
 | |
|          {
 | |
|             rc2 = rc;
 | |
|             continue;
 | |
|          }
 | |
|          rc = tran4lowAppend(t4, 0);
 | |
|          if (rc < 0)
 | |
|             rc2 = rc;
 | |
|       }
 | |
|       if (rc != r4eof)
 | |
|          rc2 = rc;
 | |
|    }
 | |
| 
 | |
|    for (rc=d4bottom(openDbf); rc == 0; rc = d4skip(openDbf, -1L))
 | |
|    {
 | |
|       if (rc2 == 0)
 | |
|       {
 | |
|          if (f4long(d4field(openDbf, "SERVERDTID")) == 0)
 | |
|          {
 | |
|             if (rc3 == 0)
 | |
|                rc = tran4set(t4, r4off, 0, f4long(d4field(openDbf, "CLIENTID")), TRAN4INIT_UNDO, 0, 0, 0);
 | |
|          }
 | |
|          else
 | |
|             rc = tran4set(t4, r4off, 0, f4long(d4field(openDbf, "CLIENTID")), TRAN4CLOSE, 0, f4long(d4field(openDbf, "CLIENTDTID")), f4long(d4field(openDbf, "SERVERDTID")));
 | |
|          if (rc < 0)
 | |
|          {
 | |
|             rc3 = rc;
 | |
|             continue;
 | |
|          }
 | |
|          rc = tran4lowAppend(t4, 0);
 | |
|          if (rc < 0)
 | |
|             rc3 = rc;
 | |
|       }
 | |
|       if (userDbfs[d4recNo(openDbf)-1L] != 0)
 | |
|          rc2 = rc2 || d4close(userDbfs[d4recNo(openDbf)-1L]);
 | |
|    }
 | |
|    if (rc == r4bof || rc == r4eof)
 | |
|       rc = 0;
 | |
| 
 | |
|    if (!rc && !rc2 && !rc3)
 | |
|    {
 | |
|       tran4set(t4, r4off, 0, 0, TRAN4SHUTDOWN, 0, 0, TRAN4VERSION_NUM);
 | |
|       tran4lowAppend(t4, 0);
 | |
|    }
 | |
|    return(rc || rc2 || rc3);
 | |
| }
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Function: getLogFileName
 | |
| **
 | |
| *****************************************************************************
 | |
| **
 | |
| **    Function: getLogFileName()
 | |
| **
 | |
| ****************************************************************************/
 | |
| int getLogFileName(CODE4 *c4, UTIL4FLAG *u4flag, char **logFileName)
 | |
| {
 | |
|    #ifdef S4UTIL_CONCURRENCY
 | |
|       int rc;
 | |
|       DATA4 *configDbf=0;
 | |
|       char *outMess[1];
 | |
| 
 | |
|       if (u4flags[UTIL4CONFIG].ptr != 0)
 | |
|          configDbf = d4open(c4, u4flags[UTIL4CONFIG].ptr[0]);
 | |
|       else
 | |
|          configDbf = d4open(c4, "S4SERVER");
 | |
|       if (configDbf == 0)
 | |
|          return(-1);
 | |
|       rc = d4top(configDbf);
 | |
|       if (rc == 0)
 | |
|       {
 | |
|          *logFileName = u4allocFree(c4, f4len(d4field(configDbf, "LOGNAME"))+1);
 | |
|          if (*logFileName == 0)
 | |
|             rc = -1;
 | |
|       }
 | |
|       if (rc == 0)
 | |
|       {
 | |
|          strcpy(*logFileName, f4str(d4field(configDbf, "LOGNAME")));
 | |
|          c4trimN(*logFileName, f4len(d4field(configDbf, "LOGNAME"))+1);
 | |
|          if (**logFileName == 0)
 | |
|          {
 | |
|             rc = -1;
 | |
|             outMess[0] = "Config Dbf error! Logging is disabled.\r\n\r\n";
 | |
|             util4out(c4, stdout, outMess, 1);
 | |
|          }
 | |
|       }
 | |
|       rc = rc || d4close(configDbf);
 | |
|       return(rc);
 | |
|    #else
 | |
|       *logFileName = u4flags[UTIL4LOG].ptr[0] ;
 | |
|       return 0 ;
 | |
|    #endif
 | |
| }
 | |
| 
 | |
| /****************************************************************************
 | |
| **::  Function: main
 | |
| **
 | |
| *****************************************************************************
 | |
| **
 | |
| **    Function: main()
 | |
| **
 | |
| ****************************************************************************/
 | |
| #ifdef S4DLL_BUILD
 | |
| int S4FUNCTION  mainLog4Fix(int argc, char *argv[], int hWnd )
 | |
| #else
 | |
| int main(int argc, char *argv[])
 | |
| #endif
 | |
| {
 | |
|    CODE4 c4;
 | |
|    DATA4 *openDbf=0, *tranDbf=0;
 | |
|    char *logFileName=0, *outMess[2];
 | |
|    int rc=0, goodAlready=0;
 | |
|    short force;
 | |
| 
 | |
|    #ifdef S4WINDOWS
 | |
|       hWndStatus = hWnd ;
 | |
|       messageType = MB_ICONSTOP ;
 | |
|    #endif
 | |
| 
 | |
|    #ifndef S4DLL_BUILD
 | |
|    #ifdef _WINDOWS
 | |
|       _wabout("LOG4FIX.EXE\r\n(c)Copyright Sequiter Software Inc., 1988-1996");
 | |
|    #endif
 | |
|    #endif
 | |
| 
 | |
|    code4init(&c4);
 | |
|    c4.lockAttempts = WAIT4EVER;
 | |
|    c4.accessMode = OPEN4DENY_RW;
 | |
|    #ifdef N4OTHER
 | |
|       c4.autoOpen = 0;
 | |
|    #endif
 | |
|    #ifndef S4WINDOWS
 | |
|       outMess[0] = "\r\n";
 | |
|       util4out(&c4, stderr, outMess, 1);
 | |
|    #endif
 | |
|    if (argc < 2)
 | |
|       rc = -1;
 | |
|    if (rc == 0)
 | |
|       rc = util4parseCommandLine(&c4, u4flags, u4flagsNum, argv, argc);
 | |
|    force = util4checkOnOffCommandLine(&c4, u4flags, UTIL4FORCE, 0);
 | |
|    if (force == -1)
 | |
|       rc = -1;
 | |
|    #ifdef S4UTIL_CONCURRENCY
 | |
|       if (rc == 0 && u4flags[UTIL4CONFIG].found == 0)
 | |
|       {
 | |
|          outMess[0] = "Command line error! Must specify -config switch.\r\n\r\n";
 | |
|    #else
 | |
|       if (rc == 0 && u4flags[UTIL4LOG].found == 0)
 | |
|       {
 | |
|          outMess[0] = "Command line error! Must specify -log switch.\r\n\r\n";
 | |
|    #endif
 | |
|          util4out(&c4, stdout, outMess, 1);
 | |
|          rc = -1;
 | |
|       }
 | |
| 
 | |
|    if (rc != 0)
 | |
|    {
 | |
|       util4printCommandLine(&c4, u4flags, u4flagsNum, argv[0]);
 | |
|       util4flagsFree(u4flags, u4flagsNum);
 | |
|       code4initUndo(&c4);
 | |
|       #ifdef S4WINDOWS
 | |
|          sendCloseMessage( hWndStatus ) ;
 | |
|       #endif
 | |
|       return(rc);
 | |
|    }
 | |
| 
 | |
|    rc = getLogFileName(&c4, u4flags, &logFileName);
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = code4logOpen( &c4, logFileName, "" ) ;
 | |
|       code4tranStatusSet(&c4, r4off);
 | |
|    }
 | |
|    if (rc == 0 && sizeof(LOG4HEADER)+sizeof(TRAN4ENTRY_LEN) > file4len(&c4.transFile.file))
 | |
|    {
 | |
|       rc = file4lenSet(&c4.transFile.file, 0L);
 | |
|       outMess[0] = "Log file error! Log file is empty.\r\n\r\n";
 | |
|       util4out(&c4, stdout, outMess, 1);
 | |
|       rc = -1;
 | |
|    }
 | |
| 
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       openDbf = d4createTemp(&c4, openFields, openTags);
 | |
|       tranDbf = d4createTemp(&c4, tranFields, tranTags);
 | |
|       if (openDbf == 0 || tranDbf == 0)
 | |
|          rc = -1;
 | |
|    }
 | |
|    c4.lockAttempts = 1;
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = code4tranLockTransactions(&c4.c4trans, TRAN4LOCK_FIX);
 | |
|       if (rc == r4locked)
 | |
|       {
 | |
|          outMess[0] = "Concurrency error! Another copy of this utility is running!\r\n\r\n";
 | |
|          util4out(&c4, stdout, outMess, 1);
 | |
|       }
 | |
|    }
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = code4tranLockTransactions(&c4.c4trans, TRAN4LOCK_BACKUP);
 | |
|       if (rc == r4locked)
 | |
|       {
 | |
|          outMess[0] = "Concurrency error! Backup utility is running!\r\n\r\n";
 | |
|          util4out(&c4, stdout, outMess, 1);
 | |
|       }
 | |
|    }
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = code4tranLockTransactions(&c4.c4trans, TRAN4LOCK_SERVER);
 | |
|       if (rc == r4locked)
 | |
|       {
 | |
|          outMess[0] = "Concurrency error! The server is running!\r\n\r\n";
 | |
|          util4out(&c4, stdout, outMess, 1);
 | |
|       }
 | |
|    }
 | |
|    c4.lockAttempts = WAIT4EVER;
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = tran4top(&c4.c4trans.trans);
 | |
|       if (rc == 0)
 | |
|          if (tran4type(&c4.c4trans.trans) != TRAN4SHUTDOWN || tran4serverDataId(&c4.c4trans.trans) > TRAN4VERSION_NUM)
 | |
|          {
 | |
|             outMess[0] = "Log file error! File is either a backup file or a newer version than this utility can handle!\r\n\r\n";
 | |
|             util4out(&c4, stdout, outMess, 1);
 | |
|             rc = -1;
 | |
|          }
 | |
|    }
 | |
| 
 | |
|    if (rc == 0)
 | |
|       rc = findIncompleteTran(&c4, openDbf, tranDbf);
 | |
|    if (rc == 0)
 | |
|    {
 | |
|       rc = tran4bottom(&c4.c4trans.trans);
 | |
|       if (rc == 0)
 | |
|          if (tran4type(&c4.c4trans.trans) == TRAN4SHUTDOWN)
 | |
|          {
 | |
|             #ifndef S4WINDOWS
 | |
|                outMess[0] = "\r\n";
 | |
|                util4out(&c4, stderr, outMess, 1);
 | |
|                util4out(&c4, stdout, outMess, 1);
 | |
|             #endif
 | |
|             outMess[0] = "Log file already in correct condition!\r\n\r\n";
 | |
|             util4out(&c4, stdout, outMess, 1);
 | |
|          }
 | |
|          else
 | |
|             rc = fixIncompleteTran(&c4, openDbf, tranDbf, force);
 | |
|    }
 | |
|    if (rc != 0)
 | |
|       outMess[0] = "Error! Utility did not successfully finish!\r\n";
 | |
|    else
 | |
|    {
 | |
|       #ifdef S4WINDOWS
 | |
|          messageType = MB_ICONEXCLAMATION ;
 | |
|          sendStatusMessage( hWndStatus, 100 ) ;
 | |
|       #endif
 | |
|       outMess[0] = "Utility successfully finished!\r\n";
 | |
|    }
 | |
|    util4out(&c4, stdout, outMess, 1);
 | |
| 
 | |
|    code4transInitUndo(&c4.c4trans);
 | |
|    if (tranDbf)
 | |
|       rc = rc || d4close(tranDbf);
 | |
|    if (openDbf)
 | |
|       rc = rc || d4close(openDbf);
 | |
|    #ifdef S4UTIL_CONCURRENCY
 | |
|       if (logFileName)
 | |
|          u4free(logFileName);
 | |
|    #endif
 | |
|    util4flagsFree(u4flags, u4flagsNum);
 | |
|    code4initUndo(&c4);
 | |
|    #ifdef S4WINDOWS
 | |
|       sendCloseMessage( hWndStatus ) ;
 | |
|    #endif
 | |
|    return(rc);
 | |
| }
 |