/* log4res.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ /* Applies a backedup .LOG file to DBF's */ /**************************************************************************** **:: Preprocessor Directives ****************************************************************************/ #include "d4all.h" #ifndef S4UTILS #error - Must compile with S4UTILS defined #endif #include "u4trans.h" /*#include */ #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 #define FILENAMELEN 12 #define UTIL4ADD 0 #define UTIL4ALL 1 #define UTIL4EXCLUSIVE 2 #define UTIL4INDEX 3 #define UTIL4LOG 4 #define UTIL4REMOVE 5 /**************************************************************************** **:: Global scope types and variables ****************************************************************************/ static UTIL4FLAG u4flags[] = { { "ADd", 0, 2, 2, 2, 0, 0, 0, 0, "[-add []]\r\n" }, { "ALl", 0, 2, 1, 1, 1, 0, 0, 0, "[-all {OFF | ON}]\r\n" }, { "Exclusive", 0, 1, 1, 1, 1, 0, 0, 0, "[-exclusive {OFF | ON}]\r\n" }, { "Index", 0, 1, 1, 1, 1, 0, 0, 0, "[-index {OFF | ON}]\r\n" }, { "Log", 0, 1, 1, 1, 1, 0, 0, 0, "{-log }\r\n" }, { "Remove", 0, 1, 2, 1, 1, 0, 0, 0, "[-remove ]\r\n" }, }; static int u4flagsNum = 6; static FIELD4INFO openFields[] = { { "CLIENTID", 'N', 11, 0 }, { "SERVERDTID", 'N', 11, 0 }, { "DATA4PTR", 'N', 11, 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 }, /* rolledback transaction ids */ { 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: typeTran4Open ** ***************************************************************************** ** ** Function: typeTran4Open() ** ****************************************************************************/ static short typeTran4Open(CODE4 *c4, UTIL4FLAG u4flags[], int u4flagsNum, DATA4 *openDbfs, TRAN4 *t4, int all) { DATA4 *tempDbf=0; short rc, found, logNumFields; unsigned i; char *data, *fullName, fileName[FILENAMELEN+1], addName[LEN4PATH+1], *destName=0, *cmpName; char *outMess[4], *logDbfDate; long logRecordWidth, logNumRecords, logDbfTime; /* struct _stat statbuf; */ data = (char *)tran4getData(t4, 0L); if (data == 0) return(-1); fullName = (char *)u4allocFree(c4, *(short *)data+1); if (fullName == 0) return(-1); strncpy(fullName, data+2, *(short *)data); fullName[*(short *)data] = 0; if (all == 0) { found = 0; for (i=0; ierrOpen = 0; if (destName != 0) { tempDbf = d4open(c4, destName); outMess[1] = destName; } else { tempDbf = d4open(c4, addName); outMess[1] = addName; } c4->errOpen = 1; if (!tempDbf) { if (c4->errorCode != r4noOpen) return(-1); outMess[0] = "\r\n\r\nAccess error! Destination database:\r\n"; outMess[2] = "\r\ncan not be found.\r\n\r\n"; util4out(c4, stdout, outMess, 3); return(-1); } if ((unsigned)logRecordWidth != d4recWidth(tempDbf) || logNumFields != d4numFields(tempDbf) || logNumRecords != d4recCount(tempDbf)) { d4close(tempDbf); outMess[0] = "\r\n\r\nDBF Consistency error! Destination database:\r\n"; outMess[2] = "\r\nstructure or record count does not match log file entry.\r\n\r\n"; util4out(c4, stdout, outMess, 3); return(-1); } /* if (tempDbf->dataFile->userCount == 1 && ((_fstat(tempDbf->dataFile->file.hand, &statbuf) == 0 && logDbfTime != statbuf.st_mtime) || strncmp(logDbfDate, &tempDbf->dataFile->yy, 3) != 0)) { outMess[0] = "\r\n\r\nDBF Consistency warning! Destination database:\r\n"; outMess[2] = "\r\nfile time or internal date does not match log file entry, continuing.\r\n\r\n"; outMess[3] = statusStringBlank; util4out(c4, stdout, outMess, 4); } */ rc = d4appendStart(openDbfs, 0); if (rc != 0) { d4close(tempDbf); return(rc); } d4blank(openDbfs); f4assignLong(d4field(openDbfs, "CLIENTID"), tran4clientId(t4)); f4assignLong(d4field(openDbfs, "SERVERDTID"), tran4serverDataId(t4)); f4assignLong(d4field(openDbfs, "DATA4PTR"), (long)tempDbf); rc = d4append(openDbfs); if (rc == r4unique) { outMess[0] = "\r\n\r\nLog file error! DBF identifier for:\r\n"; outMess[2] = "\r\nalready used.\r\n\r\n"; util4out(c4, stdout, outMess, 3); d4close(tempDbf); } return(rc); } /**************************************************************************** **:: Function: typeTran4Close ** ***************************************************************************** ** ** Function: typeTran4Close() ** ****************************************************************************/ static short typeTran4Close(CODE4 *c4, DATA4 *openDbfs, TRAN4 *t4) { short rc; char client[23]; util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; return(rc); } d4delete(openDbfs); return(rc); } /**************************************************************************** **:: Function: typeTran4Write ** ***************************************************************************** ** ** Function: typeTran4Write() ** ****************************************************************************/ static short typeTran4Write(CODE4 *c4, DATA4 *openDbfs, DATA4 *tranDbf, TRAN4 *t4) { DATA4 *tempDbf; FIELD4 *tempField; short rc, i, consistency=1; unsigned short offset; unsigned long offsetMemo; char client[23], *outMess[5]; char *data; char ltoaTemp[12]; char ltoaTemp2[12]; unsigned smallerSize; util4rightJ(ltoa(tran4id(t4), client, 10), 12); rc = d4seek(tranDbf, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; /* not rolledback */ else return(rc); } else return(0); /* rolledback */ util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; return(rc); } tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); data = (char *)tran4getData(t4, 0L); if (data == 0) return(-1); c4->errGo = 0; rc = d4go(tempDbf, *(long *)data); c4->errGo = 1; if (rc != 0) { if (rc == r4entry) { outMess[0] = "\r\n\r\nDBF consistency error!\r\nIn transaction #"; outMess[1] = ltoa(tran4id(t4), ltoaTemp, 10); outMess[2] = ", write to DBF record #"; outMess[3] = ltoa(*(long *)data, ltoaTemp2, 10); outMess[4] = " that does not exist.\r\n\r\n"; util4out(c4, stdout, outMess, 5); rc = -1; } return(rc); } offset = 5; offsetMemo = 4 + 2*d4recWidth(tempDbf); if (*(data+offset-1) == '*') { if (!d4deleted(tempDbf)) consistency = 0; } else if (d4deleted(tempDbf)) consistency = 0; for (i=1; i<=d4numFields(tempDbf) && consistency == 1; i++) { tempField = d4fieldJ(tempDbf, i); if (f4type(tempField) == 'M') { smallerSize = f4memoLen(tempField) < *(unsigned *)(data+offsetMemo) ? f4memoLen(tempField) : *(unsigned *)(data+offsetMemo); if (strncmp(f4memoPtr(tempField), data+offsetMemo+4, smallerSize) != 0) consistency = 0; offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { if (strncmp(f4ptr(tempField), data+offset, f4len(tempField)) != 0) consistency = 0; offset += f4len(tempField); } } if (consistency == 0) { outMess[0] = "\r\n\r\nDBF consistency error!\r\nIn transaction #"; outMess[1] = ltoa(tran4id(t4), ltoaTemp, 10); outMess[2] = ", DBF record #"; outMess[3] = ltoa(*(long *)data, ltoaTemp2, 10); outMess[4] = " does not match log file entry.\r\n\r\n"; util4out(c4, stdout, outMess, 5); return(-1); } offset = 5 + d4recWidth(tempDbf); offsetMemo = 4 + 2*d4recWidth(tempDbf); if (*(data+offset-1) == '*') d4delete(tempDbf); else d4recall(tempDbf); for (i=1; i<=d4numFields(tempDbf); i++) { tempField = d4fieldJ(tempDbf, i); if (f4type(tempField) == 'M') { offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); if (*(unsigned long *)(data+offsetMemo) != 0) f4memoAssignN(tempField, data+offsetMemo+4, *(unsigned *)(data+offsetMemo)); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { f4assignN(tempField, data+offset, f4len(tempField)); offset += f4len(tempField); } } return(rc); } /**************************************************************************** **:: Function: typeTran4Append ** ***************************************************************************** ** ** Function: typeTran4Append() ** ****************************************************************************/ static short typeTran4Append(CODE4 *c4, DATA4 *openDbfs, DATA4 *tranDbf, TRAN4 *t4) { DATA4 *tempDbf; FIELD4 *tempField; short rc, i; unsigned short offset; unsigned long offsetMemo; char client[23], *outMess[5]; char *data; char ltoaTemp[12]; char ltoaTemp2[12]; util4rightJ(ltoa(tran4id(t4), client, 10), 12); rc = d4seek(tranDbf, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; /* not rolledback */ else return(rc); } else return(0); /* rolledback */ util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; return(rc); } tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); data = (char *)tran4getData(t4, 0L); if (data == 0) return(-1); if (*(long *)data != d4recCount(tempDbf)+1) { outMess[0] = "\r\n\r\nDBF consistency error!\r\nIn transaction #"; outMess[1] = ltoa(tran4id(t4), ltoaTemp, 10); outMess[2] = ", DBF record #"; outMess[3] = ltoa(*(long *)data, ltoaTemp2, 10); outMess[4] = " would not be the appended record number.\r\n\r\n"; util4out(c4, stdout, outMess, 5); return(-1); } rc = d4appendStart(tempDbf,0); if (rc != 0) return(rc); offset = 5; offsetMemo = 4 + d4recWidth(tempDbf); if (*(data+offset-1) == '*') d4delete(tempDbf); for (i=1; i<=d4numFields(tempDbf); i++) { tempField = d4fieldJ(tempDbf, i); if (f4type(tempField) == 'M') { if (*(unsigned long *)(data+offsetMemo) != 0) f4memoAssignN(tempField, data+offsetMemo+4, *(unsigned *)(data+offsetMemo)); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { f4assignN(tempField, data+offset, f4len(tempField)); offset += f4len(tempField); } } rc = d4append(tempDbf); return(rc); } /**************************************************************************** **:: Function: typeTran4PackZap ** ***************************************************************************** ** ** Function: typeTran4PackZap() ** ****************************************************************************/ static short typeTran4PackZap(CODE4 *c4, DATA4 *openDbfs, TRAN4 *t4) { DATA4 *tempDbf; short rc; char client[23], *outMess[1]; char *data; util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) rc = 0; return(rc); } tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); if (tran4type(t4) == TRAN4ZAP) { data = (char *)tran4getData(t4, 0L); if (!data) return(-1); if (*(long *)data < 1 || *(long *)(data+4) > d4recCount(tempDbf)) { outMess[0] = "\r\n\r\nDBF consistency error! Record number range for zap is invalid.\r\n\r\n"; util4out(c4, stdout, outMess, 1); return(-1); } rc = d4zap(tempDbf, *(long *)data, *(long *)(data+4)); } else rc = d4pack(tempDbf); return(rc); } /**************************************************************************** **:: Function: doLogFile ** ***************************************************************************** ** ** Function: doLogFile() ** ****************************************************************************/ static int doLogFile(CODE4 *c4, UTIL4FLAG u4flags[], int u4flagsNum, int all, int exclusive, int index) { DATA4 *openDbfs, *tranDbf, *tempDbf; TRAN4 *t4; FIELD4 *data4Ptr; short rc, rc2, intPart, decPart; char *outMess[3], client[23]; long logFileLen; TRAN4ENTRY_LEN len; 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; openDbfs = d4createTemp(c4, openFields, openTags); if (openDbfs == 0) return(-1); tranDbf = d4createTemp(c4, tranFields, tranTags); if (tranDbf == 0) { d4close(openDbfs); return(-1); } #ifdef N4OTHER c4->autoOpen = 0; #else if (index == 0 || exclusive == 1) c4->autoOpen = 0; #endif d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); d4tagSelect(tranDbf, d4tag(tranDbf, "TRANID")); #ifndef S4WINDOWS outMess[0] = statusStringBlank; util4out(c4, stderr, outMess, 1); #endif for (rc = tran4top(t4); rc == 0; rc = tran4skip(t4, TRAN4FORWARDS)) { 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 TRAN4SHUTDOWN: case TRAN4BACKEDUP: case TRAN4INIT: case TRAN4INIT_UNDO: case TRAN4OPEN: case TRAN4OPEN_TEMP: case TRAN4CLOSE: case TRAN4WRITE: case TRAN4APPEND: case TRAN4PACK: case TRAN4ZAP: case TRAN4VOID: case TRAN4ROLLBACK: break; case TRAN4START: rc = d4appendStart(tranDbf, 0); if (rc != 0) break; d4blank(tranDbf); f4assignLong(d4field(tranDbf, "TRANID"), 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: util4rightJ(ltoa(tran4id(t4), client, 10), 12); rc = d4seek(tranDbf, client); if (rc != 0) { if (rc == r4after || rc == r4eof) { outMess[0] = "\r\n\r\nLog file error! Transaction completed 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) { for (rc = tran4top(t4); rc == 0; rc = tran4skip(t4, TRAN4FORWARDS)) { intPart = (short)((unsigned long)c4->c4trans.trans.pos*50/logFileLen+50); 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 TRAN4SHUTDOWN: case TRAN4BACKEDUP: case TRAN4INIT: case TRAN4INIT_UNDO: case TRAN4OPEN_TEMP: case TRAN4START: case TRAN4COMPLETE: case TRAN4ROLLBACK: case TRAN4VOID: break; case TRAN4OPEN: rc = typeTran4Open(c4, u4flags, u4flagsNum, openDbfs, t4, all); break; case TRAN4CLOSE: rc = typeTran4Close(c4, openDbfs, t4); break; case TRAN4WRITE: rc = typeTran4Write(c4, openDbfs, tranDbf, t4); break; case TRAN4APPEND: rc = typeTran4Append(c4, openDbfs, tranDbf, t4); break; case TRAN4PACK: case TRAN4ZAP: rc = typeTran4PackZap(c4, openDbfs, t4); 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) { if (rc == r4bof || rc == r4eof) rc = -1; 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) rc = 0; } if (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; d4tagSelect(openDbfs, 0); data4Ptr = d4field(openDbfs, "DATA4PTR"); for (rc = d4top(openDbfs); rc == 0; rc = d4skip(openDbfs, 1L)) { tempDbf = (DATA4 *)f4long(data4Ptr); if (!d4deleted(openDbfs)) { outMess[0] = "Log file warning! DBF file opened but not closed, continuing.\r\n\r\n"; util4out(c4, stdout, outMess, 1); } #ifndef N4OTHER if (rc2 == 0 && index == 1 && exclusive == 1 && tempDbf->dataFile->userCount == 1) { if (tempDbf->dataFile->hasMdxMemo) { if (i4open(tempDbf, 0) == 0) rc2 = -1; if (rc2 == 0) rc2 = d4reindex(tempDbf); } } #endif rc2 = rc2 || d4close(tempDbf); } if (rc == r4eof) rc = rc2; rc = rc || d4close(tranDbf); rc = rc || d4close(openDbfs); return(rc); } /**************************************************************************** **:: Function: main ** ***************************************************************************** ** ** Function: main() ** ****************************************************************************/ #ifdef S4DLL_BUILD int S4FUNCTION mainLog4Res(int argc, char *argv[], int hWnd ) #else int main(int argc, char *argv[]) #endif { CODE4 c4; int rc=0, all, exclusive, index; char *outMess[3]; #ifdef S4WINDOWS hWndStatus = hWnd ; messageType = MB_ICONSTOP ; #endif #ifndef S4DLL_BUILD #ifdef _WINDOWS _wabout("LOG4RES.EXE\r\n(c)Copyright Sequiter Software Inc., 1988-1996"); #endif #endif code4init(&c4); c4.lockAttempts = WAIT4EVER; c4.singleOpen = 0 ; /* evaluate command line parameters */ #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); if (rc == 0 && u4flags[UTIL4LOG].found == 0) { outMess[0] = "Command line error! Must specify -log switch.\r\n\r\n"; util4out(&c4, stdout, outMess, 1); rc = -1; } all = util4checkOnOffCommandLine(&c4, u4flags, UTIL4ALL, 0); if (all == -1) rc = -1; exclusive = util4checkOnOffCommandLine(&c4, u4flags, UTIL4EXCLUSIVE, 1); if (exclusive == -1) rc = -1; else c4.accessMode = exclusive * OPEN4DENY_RW; index = util4checkOnOffCommandLine(&c4, u4flags, UTIL4INDEX, 0); if (index == -1) rc = -1; if (rc != 0) { util4printCommandLine(&c4, u4flags, u4flagsNum, argv[0]); util4flagsFree(u4flags, u4flagsNum); code4initUndo(&c4); #ifdef S4WINDOWS sendCloseMessage( hWndStatus ) ; #endif return(rc); } /* initialize log file */ if (rc == 0) { rc = code4logOpen( &c4, u4flags[UTIL4LOG].ptr[0], "" ) ; /* rc = code4tranInit2(&c4, u4flags[UTIL4LOG].ptr[0], 0); */ 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; } c4.lockAttempts = 1; if (rc == 0) { rc = code4tranLockTransactions(&c4.c4trans, TRAN4LOCK_RESTORE); 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 using -log file "; outMess[1] = u4flags[UTIL4LOG].ptr[0]; outMess[2] = "!\r\n\r\n"; util4out(&c4, stdout, outMess, 3); } } c4.lockAttempts = WAIT4EVER; if (rc == 0) { rc = tran4top(&c4.c4trans.trans); if (rc == 0 && (tran4type(&c4.c4trans.trans) != TRAN4BACKEDUP || tran4serverDataId(&c4.c4trans.trans) > TRAN4VERSION_NUM)) { outMess[0] = "Log file error! File is either not 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 = doLogFile(&c4, u4flags, u4flagsNum, all, exclusive, index); if (rc == 0) { #ifdef S4WINDOWS messageType = MB_ICONEXCLAMATION ; sendStatusMessage( hWndStatus, 100 ) ; #endif outMess[0] = "Utility successfully finished!\r\n\r\n"; } else outMess[0] = "Error! Utility did not successfully finish!\r\n\r\n"; util4out(&c4, stdout, outMess, 1); code4transInitUndo(&c4.c4trans); util4flagsFree(u4flags, u4flagsNum); code4initUndo(&c4); #ifdef S4WINDOWS sendCloseMessage( hWndStatus ) ; #endif return(rc); }