/* log4dbf.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ /* Convert .LOG file to .DBF format */ /**************************************************************************** **:: Preprocessor Directives *****************************************************************************/ #include "d4all.h" #include #ifdef S4WINTEL #include #else #ifdef S4UNIX #include #endif #endif #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 #define TIME4LEN 21 #define FILENAMELEN 12 static char ascTime[TIME4LEN+1]; #define UTIL4ADD 0 #define UTIL4ALL 1 #define UTIL4INCLUDE 2 #define UTIL4LOG 3 #define UTIL4MISC 4 #define UTIL4MULTIPLE 5 #define UTIL4NETID 6 #define UTIL4ORIGINAL 7 #define UTIL4OUTDIR 8 #define UTIL4OVERWRITE 9 #define UTIL4REMOVE 10 #define UTIL4TIME 11 #define UTIL4USERID 12 #ifdef S4UTIL_CONCURRENCY #define UTIL4CONFIG 13 #endif /**************************************************************************** **:: Global scope types and variables *****************************************************************************/ static UTIL4FLAG u4flags[] = { { "ADd", 0, 2, 2, 3, 0, 0, 0, 0, "[-add [] []]\r\n" }, { "ALl", 0, 2, 1, 1, 1, 0, 0, 0, "[-all {OFF | ON}]\r\n" }, { "Include", 0, 1, 2, 6, 0, 0, 0, 0, "[-include [ALL] [INITIAL] [MEMO] [OPEN] [ROLLBACK] [TEMP] [UPDATE]]\r\n" }, { "Log", 0, 1, 1, 1, 1, 0, 0, 0, "{-log }\r\n" }, { "MIsclen", 0, 2, 1, 1, 1, 0, 0, 0, "[-misclen <#>]\r\n" }, { "MUltiple", 0, 2, 1, 1, 1, 0, 0, 0, "[-multiple {OFF | ON}]\r\n" }, { "Netidlen", 0, 1, 1, 1, 1, 0, 0, 0, "[-netidlen <#>]\r\n" }, { "ORiginal", 0, 2, 1, 1, 1, 0, 0, 0, "[-original {OFF | ON}]\r\n" }, { "OUtdir", 0, 2, 1, 1, 1, 0, 0, 0, "[-outdir ]\r\n" }, { "OVerwrite", 0, 2, 1, 1, 1, 0, 0, 0, "[-overwrite {OFF | ON}]\r\n" }, { "Remove", 0, 1, 2, 1, 1, 0, 0, 0, "[-remove ]\r\n" }, { "Time", 0, 1, 1, 1, 1, 0, 0, 0, "[-time {OFF | ON}]\r\n" }, { "Useridlen", 0, 1, 1, 1, 1, 0, 0, 0, "[-useridlen <#>]\r\n" }, #ifdef S4UTIL_CONCURRENCY { "Config", 0, 1, 1, -1, 0, 0, 0, 0, "{-config []}\r\n" }, #endif }; #ifdef S4UTIL_CONCURRENCY static int u4flagsNum = 14; #else static int u4flagsNum = 13; #endif #define INCLUDE_UPDATE 1<<0 #define INCLUDE_INITIAL 1<<1 #define INCLUDE_ROLLBACK 1<<2 #define INCLUDE_TEMP 1<<3 #define INCLUDE_OPEN 1<<4 #define INCLUDE_MEMO 1<<5 #define INCLUDE_ALL (1<<6)-1 typedef struct SETTINGSTRUCT_st { #ifdef S4UTIL_CONCURRENCY char *config; #endif char *log; char *outDir; char **addDbf; /* actually "remove" Dbf's if all == 1 */ char numAdd; char all; char include; char multiple; char original; char overwrite; char time; short netid; short userid; short misc; } SETTINGSTRUCT; static FIELD4INFO openFields[] = { { "NETNAME", 'C', 80, 0 }, { "USERNAME", 'C', 80, 0 }, { "CLIENTID", 'N', 11, 0 }, { "SERVERDTID", 'N', 11, 0 }, { "RECORDWID", 'N', 5, 0 }, { "TRANID", 'N', 11, 0 }, { "DATA4PTR", 'N', 11, 0 }, { "FILENAME", 'C', LEN4PATH, 0 }, { "TEMP", 'L', 1, 0 }, { 0,0,0,0 }, }; static TAG4INFO openTags[] = { { "CLID", "STR(CLIENTID,11,0)+STR(SERVERDTID,11,0)", ".NOT.DELETED()", r4unique, 0 }, { "TRANID", "STR(TRANID,11,0)", ".NOT.DELETED()", 0, 0 }, { 0,0,0,0,0 }, }; #define L4TYPE_F 0 #define L4ID_F 1 #define L4TIME_F 2 #define L4NETID_F 3 #define L4USERID_F 4 #define L4ROLLED_F 5 #define L4MISC_F 6 #define L4RECNO_F 7 #define L4DELETED_F 8 #define L4RECORD_F 9 #define L4_F 10 static FIELD4INFO outFieldsTemp[] = { { "L4TYPE", 'C', 10, 0 }, { "L4ID", 'N', 11, 0 }, { "L4TIME", 'C', 21, 0 }, { "L4NETID", 'C', 0, 0 }, { "L4USERID", 'C', 0, 0 }, { "L4ROLLED", 'L', 1, 0 }, { "L4MISC", 'C', 0, 0 }, { "L4RECNO", 'N', 9, 0 }, { "L4DELETED", 'L', 1, 0 }, { "L4RECORD", 'C', 0, 0 }, { 0, 0, 0, 0 }, }; static FIELD4INFO tranFields[] = { { "TRANID", 'N', 11, 0 }, /* rolledback transaction ids */ { 0,0,0,0 }, }; static TAG4INFO tranTags[] = { { "TRANID_T", "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: checkFlags ** ***************************************************************************** ** ** Function: checkFlags() ** ****************************************************************************/ int checkFlags(CODE4 *c4, UTIL4FLAG u4[], int numFlags, SETTINGSTRUCT *settings) { char *outMess[5]; unsigned i; settings->all = util4checkOnOffCommandLine(c4, u4flags, UTIL4ALL, 0); if (settings->all == -1) return(-1); settings->multiple = util4checkOnOffCommandLine(c4, u4flags, UTIL4MULTIPLE, 0); if (settings->multiple == -1) return(-1); settings->original = util4checkOnOffCommandLine(c4, u4flags, UTIL4ORIGINAL, 1); if (settings->original == -1) return(-1); settings->overwrite = util4checkOnOffCommandLine(c4, u4flags, UTIL4OVERWRITE, 0); if (settings->overwrite == -1) return(-1); settings->time = util4checkOnOffCommandLine(c4, u4flags, UTIL4TIME, 1); if (settings->time == -1) return(-1); settings->netid = (int)util4checkRangeCommandLine(c4, u4flags, UTIL4NETID, 20, 0, 80); if (settings->netid == -1) return(-1); settings->userid = (int)util4checkRangeCommandLine(c4, u4flags, UTIL4USERID, 20, 0, 80); if (settings->userid == -1) return(-1); settings->misc = (int)util4checkRangeCommandLine(c4, u4flags, UTIL4MISC, 0, 0, 30000); if (settings->misc == -1) return(-1); #ifdef S4UTIL_CONCURRENCY if (u4flags[UTIL4CONFIG].ptr != 0) settings->config = u4flags[UTIL4CONFIG].ptr[0]; else if (u4flags[UTIL4CONFIG].found) settings->config = ""; #endif #ifndef S4UTIL_CONCURRENCY if ( u4flags[UTIL4LOG].found == 0 ) { outMess[0] = "Command line error! Must specify -log switch.\r\n\r\n"; util4out(c4, stdout, outMess, 1); return(-1); } #endif if (u4flags[UTIL4LOG].ptr != 0) settings->log = u4flags[UTIL4LOG].ptr[0]; if (u4flags[UTIL4OUTDIR].ptr != 0) settings->outDir = u4flags[UTIL4OUTDIR].ptr[0]; else settings->outDir = "LOG4DBF"; if (settings->all == 0) { settings->addDbf = u4flags[UTIL4ADD].ptr; settings->numAdd = u4flags[UTIL4ADD].numPtr/4; } else { settings->addDbf = u4flags[UTIL4REMOVE].ptr; settings->numAdd = u4flags[UTIL4REMOVE].numPtr/4; } settings->include = 0; for (i=0; iinclude = INCLUDE_ALL; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "UPDATE", 6) == 0) { settings->include |= INCLUDE_UPDATE; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "INITIAL", 7) == 0) { settings->include |= INCLUDE_INITIAL; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "ROLLBACK", 8) == 0) { settings->include |= INCLUDE_ROLLBACK; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "TEMP", 4) == 0) { settings->include |= INCLUDE_TEMP; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "OPEN", 4) == 0) { settings->include |= INCLUDE_OPEN; continue; } if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "MEMO", 4) == 0) { settings->include |= INCLUDE_MEMO; continue; } outMess[0] = "Command line error! -"; outMess[1] = u4flags[UTIL4INCLUDE].name; outMess[2] = " flag has unknown value: "; outMess[3] = u4flags[UTIL4INCLUDE].ptr[i]+1; outMess[4] = "\r\n"; util4out(c4, stdout, outMess, 5); return(-1); } if (i == 0) settings->include = INCLUDE_UPDATE; /* default */ return(0); } /**************************************************************************** **:: Function: getLogFileName ** ***************************************************************************** ** ** Function: getLogFileName() ** ****************************************************************************/ static int getLogFileName(CODE4 *c4, SETTINGSTRUCT *settings, char **logFileName) { #ifdef S4UTIL_CONCURRENCY int rc=-1; DATA4 *configDbf; char *outMess[1]; #endif if (settings->log != 0) { *logFileName = (char *)u4allocFree(c4, strlen(settings->log)+1); if (*logFileName == 0) return(-1); strcpy(*logFileName, settings->log); return(0); } #ifndef S4UTIL_CONCURRENCY else return(-1) ; #endif #ifdef S4UTIL_CONCURRENCY if (settings->config != 0) { if (*settings->config == 0) configDbf = d4open(c4, "S4SERVER"); else configDbf = d4open(c4, settings->config); 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"; util4out(c4, stdout, outMess, 1); } } d4close(configDbf); } return(rc); #endif } /**************************************************************************** **:: Function: typeTran4Shutdown ** ***************************************************************************** ** ** Function: typeTran4Shutdown() ** ****************************************************************************/ short typeTran4Shutdown(CODE4 *c4, DATA4 *openDbfs, TRAN4 *t4) { short rc; char *outMess[1]; rc = d4top(openDbfs); if (rc != r4eof && rc != 0) return(rc); if (rc == 0) { outMess[0] = "\r\n\r\nLog file error! Server shutdown while user(s) initialized.\r\n\r\n"; util4out(c4, stdout, outMess, 1); return(-1); } if (tran4serverDataId(t4) > 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); return(-1); } return(0); } /**************************************************************************** *:: Function: typeTran4Init ** ***************************************************************************** ** ** Function: typeTran4Init() ** ****************************************************************************/ short typeTran4Init(CODE4 *c4, DATA4 *openDbfs, TRAN4 *t4) { short rc; char *data, *outMess[1]; rc = d4appendStart(openDbfs, 0); if (rc != 0) return(rc); d4blank(openDbfs); data = (char *)tran4getData(t4, 0L); if (data == 0) return(-1); f4assignN(d4field(openDbfs, "NETNAME"), data+2, *(short *)data); f4assignN(d4field(openDbfs, "USERNAME"), data+4+ *(short *)data, *(short *)(data+2+ *(short *)data)); f4assignLong(d4field(openDbfs, "CLIENTID"), tran4clientId(t4)); rc = d4append(openDbfs); if (rc == r4unique) { outMess[0] = "\r\n\r\nLog file error! User already initialized.\r\n\r\n"; util4out(c4, stdout, outMess, 1); } return(rc); } /**************************************************************************** *:: Function: typeTran4InitUndo ** ***************************************************************************** ** ** Function: typeTran4InitUndo() ** ****************************************************************************/ short typeTran4InitUndo(CODE4 *c4, DATA4 *openDbfs, TRAN4 *t4) { short rc; char client[12], *outMess[1]; util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, client); if (rc != 0) { outMess[0] = "\r\n\r\nLog file error! User not initialized.\r\n\r\n"; util4out(c4, stdout, outMess, 1); return(rc); } d4delete(openDbfs); rc = d4seek(openDbfs, client); if (rc != r4after && rc != r4eof) { 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); return(-1); } return(rc); } return(0); } /**************************************************************************** **:: Function: openOriginal ** ***************************************************************************** ** ** Function: openOriginal() ** ****************************************************************************/ short openOriginal(CODE4 *c4, DATA4** origDbf, char *fileName, long logRecordWidth, short logNumFields) { short rc=0; c4->errOpen = 0; *origDbf = d4open(c4, fileName); c4->errOpen = 1; if (!*origDbf) if (c4->errorCode != r4noOpen) return(-1); else c4->errorCode = 0; else if ((unsigned)logRecordWidth != d4recWidth(*origDbf) || logNumFields != d4numFields(*origDbf)) { rc = d4close(*origDbf); *origDbf = 0; } return(rc); } /**************************************************************************** **:: Function: noPath ** ***************************************************************************** ** ** Function: noPath() ** ****************************************************************************/ char *noPath(char *fullName) { short i=-1; if (!fullName) return(fullName); while (fullName[++i] != 0); while (--i >= 0 && fullName[i] != '\\' && fullName[i] != ':'); return(fullName+i+1); } /**************************************************************************** **:: Function: getNextFileName ** ***************************************************************************** ** ** Function: getNextFileName() ** ****************************************************************************/ short getNextFileName(char *fileName) { short i=-1, j, k, l; while (fileName[++i] != 0); j = i; while (--i >= 0 && fileName[i] != '.'); if (i == -1) i = j; if (i > 3 && isdigit(fileName[i-3]) && isdigit(fileName[i-2]) && isdigit(fileName[i-1])) { for (k=1; k<4; k++) { fileName[i-k]++; if (fileName[i-k] == ':') fileName[i-k] = '0'; else break; } if (k == 4) return(-1); } else { if (i >= FILENAMELEN-7) { k = FILENAMELEN - 7; for (l=j-1; l>=i; l--) fileName[l+FILENAMELEN-i-4] = fileName[l]; fileName[j+FILENAMELEN-i-4] = 0; } else { k = i; for (l=j-1; l>=i; l--) fileName[l+3] = fileName[l]; fileName[j+3] = 0; } fileName[k] = fileName[k+1] = fileName[k+2] = '0'; } return(0); } /**************************************************************************** **:: Function: checkField ** ***************************************************************************** ** ** Function: checkField() ** ****************************************************************************/ short checkField(FIELD4 *f4, FIELD4INFO *info, unsigned len) { if (strcmp(info->name, f4name(f4)) != 0) return(-1); if (len != 0) { if (len != f4len(f4)) return(-1); } else if (info->len != f4len(f4)) return(-1); if (info->type != f4type(f4)) return(-1); if ((int)info->dec != f4decimals(f4)) return(-1); return(0); } /**************************************************************************** **:: Function: checkStructure ** ***************************************************************************** ** ** Function: checkStructure() ** ****************************************************************************/ short checkStructure(SETTINGSTRUCT *settings, DATA4 *origDbf, DATA4 *tempDbf, long logRecordWidth, long *tempNumFields) { short rc=0, count=2, numFields, j; long tempLength=0; if (tempDbf) { numFields = d4numFields(tempDbf); if (numFields < 4) rc = -1; } tempLength = outFieldsTemp[L4TYPE_F].len; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, 1), outFieldsTemp+L4TYPE_F, 0) != 0) rc = -1; tempLength += outFieldsTemp[L4ID_F].len; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, 2), outFieldsTemp+L4ID_F, 0) != 0) rc = -1; if (settings->time) { tempLength += outFieldsTemp[L4TIME_F].len; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4TIME_F, 0) != 0) rc = -1; } if (settings->netid > 0) { tempLength += settings->netid; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4NETID_F, settings->netid) != 0) rc = -1; } if (settings->userid > 0) { tempLength += settings->userid; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4USERID_F, settings->userid) != 0) rc = -1; } if (settings->include & INCLUDE_ROLLBACK) { tempLength += outFieldsTemp[L4ROLLED_F].len; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4ROLLED_F, 0) != 0) rc = -1; } if (settings->misc > 0) { tempLength += settings->misc; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4MISC_F, settings->misc) != 0) rc = -1; } tempLength += outFieldsTemp[L4RECNO_F].len; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4RECNO_F, 0) != 0) rc = -1; tempLength += outFieldsTemp[L4DELETED_F].len; count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4DELETED_F, 0) != 0) rc = -1; if (origDbf) for (j=1; j<=d4numFields(origDbf); j++) { if (!(settings->include & INCLUDE_MEMO) && f4type(d4fieldJ(origDbf, j)) == r4memo) continue; if (count == 2046 || tempLength + f4len(d4fieldJ(origDbf, j)) > 65535) break; tempLength += f4len(d4fieldJ(origDbf, j)); count++; if (!tempDbf || rc != 0 || numFields-- <= 0 || strcmp(f4name(d4fieldJ(origDbf, j)), f4name(d4fieldJ(tempDbf, count))) != 0 || f4len(d4fieldJ(origDbf, j)) != f4len(d4fieldJ(tempDbf, count)) || f4type(d4fieldJ(origDbf, j)) != f4type(d4fieldJ(tempDbf, count)) || f4decimals(d4fieldJ(origDbf, j)) != f4decimals(d4fieldJ(tempDbf, count))) rc = -1; } else { count++; if (!tempDbf || rc != 0 || numFields != 1 || checkField(d4fieldJ(tempDbf, count), outFieldsTemp+L4RECORD_F, (unsigned)(logRecordWidth > 32767 ? 32767 : logRecordWidth)) != 0) rc = -1; } *tempNumFields = count; return(rc); } /**************************************************************************** **:: Function: timeformat ** ***************************************************************************** ** ** Function: timeformat() ** ****************************************************************************/ char *timeformat(TRAN4 *t4) { struct tm *time; time = localtime(&t4->header.time); #ifndef S4DLL_BUILD if (strftime(ascTime, TIME4LEN+1, "%a %m/%d/%y %H:%M:%S", time) == 0) #else if( sprintf( ascTime, "%.3s %2d/%2d/%2d %.8s", asctime(time), time->tm_mon, time->tm_mday, time->tm_year, asctime(time)+11 ) == EOF ) #endif return(0); return(ascTime); } /**************************************************************************** **:: Function: typeTran4Open ** ***************************************************************************** ** ** Function: typeTran4Open() ** ****************************************************************************/ static short typeTran4Open(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, TRAN4 *t4) { DATA4 *origDbf=0, *tempDbf=0; FIELD4INFO *changeFields, *origFields; short rc, found, i, j, logNumFields; char *data, *fullName, fileName[FILENAMELEN+1], addName[LEN4PATH+1], *originalName=0, *changeName=0, *cmpName; char *outName, *outNameMemo, *curDir, *outMess[6]; long tempNumFields, logRecordWidth; char clientId[12]; static didProcess = 0; #ifndef S4UNIX unsigned origDrive=0, curDrive, dummy; #endif if (tran4type(t4) == TRAN4OPEN_TEMP && !(settings->include & INCLUDE_TEMP)) return(0); 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 (!settings->all) { found = 0; for (i=0; inumAdd; i++) { u4namePiece(fileName, FILENAMELEN+1, settings->addDbf[i]+1, 0, 1); if (strlen(fileName) != strlen(settings->addDbf[i]+1)) { u4nameCurrent(addName, LEN4PATH+1, settings->addDbf[i]+1); #ifdef S4UNIX u4nameExt(addName, LEN4PATH+1, ".dbf", 0); #else u4nameExt(addName, LEN4PATH+1, ".DBF", 0); #endif cmpName = fullName; } else { u4namePiece(addName, LEN4PATH+1, fullName, 0, 1); #ifdef S4UNIX u4nameExt(fileName, LEN4PATH+1, ".dbf", 0); #else u4nameExt(fileName, LEN4PATH+1, ".DBF", 0); #endif cmpName = fileName; } if (i != settings->numAdd-1 && *settings->addDbf[i] == *settings->addDbf[i+1]) originalName = settings->addDbf[++i]+1; if (i != settings->numAdd-1 && *settings->addDbf[i] == *settings->addDbf[i+1]) changeName = settings->addDbf[++i]+1; if (strcmp(addName, cmpName) == 0) { found = 1; break; } originalName = changeName = 0; } } else { found = 1; for (i=0; inumAdd; i++) { u4namePiece(fileName, FILENAMELEN+1, settings->addDbf[i], 0, 1); if (strlen(fileName) != strlen(settings->addDbf[i])) { u4nameCurrent(addName, LEN4PATH+1, settings->addDbf[i]); #ifdef S4UNIX u4nameExt(addName, LEN4PATH+1, ".dbf", 0); #else u4nameExt(addName, LEN4PATH+1, ".DBF", 0); #endif cmpName = fullName; } else { u4namePiece(addName, LEN4PATH+1, fullName, 0, 1); #ifdef S4UNIX u4nameExt(fileName, LEN4PATH+1, ".dbf", 0); #else u4nameExt(fileName, LEN4PATH+1, ".DBF", 0); #endif cmpName = fileName; } if (strcmp(addName, cmpName) == 0) { found = 0; break; } } } strcpy(addName, fullName); u4free(fullName); if (found == 0) return(0); #ifdef S4DATA_ALIGN memcpy(&logRecordWidth, (data+2+*(short *)data), sizeof(long) ); memcpy(&logNumFields, (data+6+*(short *)data), sizeof(short) ); #else logRecordWidth = *(long *)(data+2+ *(short *)data); logNumFields = *(short *)(data+6+ *(short *)data); #endif if (originalName) rc = openOriginal(c4, &origDbf, originalName, logRecordWidth, logNumFields); else rc = openOriginal(c4, &origDbf, addName, logRecordWidth, logNumFields); if (rc != 0) return(rc); if (!origDbf && settings->original) { outMess[0] = "\r\n\r\nData file structure not available! Skipping data file:\r\n"; outMess[1] = addName; #ifndef S4WINDOWS outMess[2] = "\r\n\r\n"; outMess[3] = statusStringBlank; util4out(c4, stdout, outMess, 4); #else util4out(c4, stdout, outMess, 2); #endif return(0); } outName = (char *)u4allocFree(c4, LEN4PATH+1); if (!outName) { if (origDbf) d4close(origDbf); return(-1); } if (changeName) strcpy(outName, changeName); else if (originalName) u4namePiece(outName, LEN4PATH+1, originalName, 0, 1); else u4namePiece(outName, LEN4PATH+1, addName, 0, 1); #ifndef S4UNIX #ifndef S4OS2 if (strlen(settings->outDir) > 1 && *(settings->outDir+1) == ':') { _dos_getdrive(&origDrive); _dos_setdrive(*settings->outDir-'a'<0 ? *settings->outDir-'A'+1 : *settings->outDir-'a'+1, &dummy); _dos_getdrive(&curDrive); if ((char)curDrive != (*settings->outDir-'a'<0 ? *settings->outDir-'A'+1 : *settings->outDir-'a'+1)) rc = -1; } #endif #endif if (rc == 0) { curDir = (char *)u4allocFree(c4, LEN4PATH+1); if (!curDir) rc = -1; else if( getcwd(curDir, LEN4PATH+1) == NULL) rc = -1 ; } if (rc == 0) { rc = chdir(settings->outDir); if (rc != 0) { #ifdef S4UNIX rc = mkdir(settings->outDir, 0755); #else rc = mkdir(settings->outDir); #endif if (rc != 0) { outMess[0] = "\r\n\r\nAccess error! Can not create output directory:\r\n"; outMess[1] = settings->outDir; outMess[2] = "\r\n\r\n"; util4out(c4, stdout, outMess, 3); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); return(-1); } rc = chdir(settings->outDir); } } if (rc != 0) { if (curDir) u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); return(-1); } c4->errOpen = 0; tempDbf = d4open(c4, outName); c4->errOpen = 1; if (!tempDbf && c4->errorCode == r4noOpen) { if( access(outName, 00) == 0 ) /* if file exists, this is an error */ { #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif chdir(curDir); u4free(curDir); if (origDbf) d4close(origDbf); if (settings->overwrite) outMess[0] = "\r\n\r\nAccess error! Can not over-write existing version of output file:\r\n"; else outMess[0] = "\r\n\r\nAccess error! Can not open existing version of output file:\r\n"; #ifndef S4UNIX outMess[1] = strupr(settings->outDir); outMess[2] = "\\" ; outMess[3] = strupr(outName) ; #else outMess[1] = settings->outDir; outMess[2] = "/" ; outMess[3] = outName ; #endif outMess[4] = "\r\nThe file may be in use by another application."; if( didProcess ) { didProcess = 0; outMess[5] = "\r\n\r\nNOTE:\nSome analysis output files were successfully created before the" "\r\nerror occurred. Check the date/time stamps on the files located in" "\r\nthe specified output directory." "\r\n\r\n"; } else outMess[5] = "\r\n\r\n"; util4out(c4, stdout, outMess, 6); u4free(outName); return(-1); } else { checkStructure(settings, origDbf, origDbf, logRecordWidth, &tempNumFields); } } for (; tempDbf; ) { if (tempDbf->dataFile->userCount == 1 && settings->overwrite == 1) { rc = d4close(tempDbf); tempDbf = 0; if (rc == 0) { #ifdef S4UNIX u4nameExt(outName, LEN4PATH+1, "dbf", 0); #else u4nameExt(outName, LEN4PATH+1, "DBF", 0); #endif rc = remove(outName); if (rc == 0) { outNameMemo = (char *)u4allocFree(c4, strlen(outName)+4); if (outNameMemo == 0) rc = -1; else { strcpy(outNameMemo, outName); #ifdef S4MFOX #ifdef S4UNIX u4nameExt(outNameMemo, strlen(outName)+4, "fpt", 1); #else u4nameExt(outNameMemo, strlen(outName)+4, "FPT", 1); #endif #else #ifdef S4UNIX u4nameExt(outNameMemo, strlen(outName)+4, "dbt", 1); #else u4nameExt(outNameMemo, strlen(outName)+4, "DBT", 1); #endif #endif if (access(outNameMemo, 0) == 0) rc = remove(outNameMemo); u4free(outNameMemo); checkStructure(settings, origDbf, origDbf, logRecordWidth, &tempNumFields); } } } break; } rc = checkStructure(settings, origDbf, tempDbf, logRecordWidth, &tempNumFields); if (rc == 0) break; for(;;) { if (rc != 0 && !settings->multiple) { rc = d4close(tempDbf); rc = rc || chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); _dos_getdrive(&curDrive); if (curDrive != origDrive) rc = -1; #endif #endif u4free(outName); if (origDbf) rc = rc || d4close(origDbf); if (rc != 0) return(rc); outMess[0] = "\r\n\r\nOutput file does not match log entry description! Skipping file:\r\n"; outMess[1] = addName; #ifndef S4WINDOWS outMess[2] = "\r\n\r\n"; outMess[3] = statusStringBlank; util4out(c4, stdout, outMess, 4); #else util4out(c4, stdout, outMess, 2); #endif return(0); } rc = d4close(tempDbf); tempDbf = 0; if (rc != 0) break; rc = getNextFileName(noPath(outName)); if (rc != 0) { outMess[0] = "\r\n\r\nFile name error! Can not create unique name for output file for:\r\n"; outMess[1] = addName; outMess[2] = "\r\n\r\n"; util4out(c4, stdout, outMess, 3); break; } c4->errOpen = 0; tempDbf = d4open(c4, outName); c4->errOpen = 1; if (tempDbf) rc = checkStructure(settings, origDbf, tempDbf, logRecordWidth, &tempNumFields); if (rc == 0) break; } break; } if (rc != 0 || (!tempDbf && c4->errorCode != r4noOpen && c4->errorCode != 0)) { chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); return(-1); } c4->errorCode = 0; if (!tempDbf) { changeFields = (FIELD4INFO *)u4allocFree(c4, (tempNumFields+1)*sizeof(FIELD4INFO)); if (!changeFields) { chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); return(-1); } i = 0; memcpy(changeFields, outFieldsTemp, 2*sizeof(FIELD4INFO)); /* L4TYPE & L4ID */ i += 2; if (settings->time) { memcpy(changeFields+i, outFieldsTemp+L4TIME_F, sizeof(FIELD4INFO)); i++; } if (settings->netid > 0) { memcpy(changeFields+i, outFieldsTemp+L4NETID_F, sizeof(FIELD4INFO)); changeFields[i].len = settings->netid; i++; } if (settings->userid > 0) { memcpy(changeFields+i, outFieldsTemp+L4USERID_F, sizeof(FIELD4INFO)); changeFields[i].len = settings->userid; i++; } if (settings->include & INCLUDE_ROLLBACK) { memcpy(changeFields+i, outFieldsTemp+L4ROLLED_F, sizeof(FIELD4INFO)); i++; } if (settings->misc > 0) { memcpy(changeFields+i, outFieldsTemp+L4MISC_F, sizeof(FIELD4INFO)); changeFields[i].len = settings->misc; i++; } memcpy(changeFields+i, outFieldsTemp+L4RECNO_F, 2*sizeof(FIELD4INFO)); /* L4RECNO & L4DELETED */ i += 2; if (!origDbf) { memcpy(changeFields+i, outFieldsTemp+L4RECORD_F, sizeof(FIELD4INFO)); if (logRecordWidth > 32767) changeFields[i].len = 32767; else changeFields[i].len = (unsigned)logRecordWidth; i++; } else { origFields = d4fieldInfo(origDbf); if (!origFields) { u4free(changeFields); chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); d4close(origDbf); return(-1); } for (j=0; jinclude & INCLUDE_MEMO) && origFields[j].type == r4memo) continue; memcpy(changeFields+i, origFields+j, sizeof(FIELD4INFO)); i++; } u4free(origFields); } memcpy(changeFields+i, outFieldsTemp+L4_F, sizeof(FIELD4INFO)); c4->errCreate = 0; if( origDbf ) if( origDbf->dataFile->version == 0x30 ) c4->compatibility = 30 ; tempDbf = d4create(c4, outName, changeFields, 0); while (tempDbf == 0 && c4->errorCode == r4noCreate) { rc = getNextFileName(noPath(outName)); if (rc != 0) { u4free(changeFields); chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); outMess[0] = "\r\n\r\nFile name error! Can not create unique name for output file for:\r\n"; outMess[1] = addName; if( didProcess ) { didProcess = 0; outMess[2] = "\r\n\r\nNOTE:\nSome analysis output files were successfully created before the" "\r\nerror occurred. Check the date/time stamps on the files located in" "\r\nthe specified output directory." "\r\n\r\n"; } else outMess[2] = "\r\n\r\n"; util4out(c4, stdout, outMess, 3); return(rc); } tempDbf = d4create(c4, outName, changeFields, 0); } c4->errCreate = 1; u4free(changeFields); if (tempDbf == 0) { outMess[0] = "\r\n\r\nFile creation error! Can not create change file:\r\n"; outMess[1] = outName; if( didProcess ) { didProcess = 0; outMess[2] = "\r\n\r\nNOTE:\nSome analysis output files were successfully created before the" "\r\nerror occurred. Check the date/time stamps on the files located in" "\r\nthe specified output directory." "\r\n\r\n"; } else outMess[2] = "\r\n\r\n"; util4out(c4, stdout, outMess, 3); chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) _dos_setdrive(origDrive, &dummy); #endif #endif u4free(outName); if (origDbf) d4close(origDbf); return(-1); } } rc = chdir(curDir); u4free(curDir); #ifndef S4UNIX #ifndef S4OS2 if (origDrive) { _dos_setdrive(origDrive, &dummy); _dos_getdrive(&curDrive); if (curDrive != origDrive) rc = -1; } #endif #endif u4free(outName); if (origDbf) rc = rc || d4close(origDbf); if (rc != 0) return(rc); util4rightJ(ltoa(tran4clientId(t4), clientId, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, clientId); if (rc != 0) { outMess[0] = "\r\n\r\nLog file error! User not initialized.\r\n\r\n"; util4out(c4, stdout, outMess, 1); d4close(tempDbf); return(rc); } rc = d4appendStart(openDbfs, 0); if (rc != 0) return(rc); f4assignLong(d4field(openDbfs, "SERVERDTID"), tran4serverDataId(t4)); f4assignLong(d4field(openDbfs, "RECORDWID"), logRecordWidth); f4assignLong(d4field(openDbfs, "DATA4PTR"), (long)tempDbf); f4assign(d4field(openDbfs, "FILENAME"), addName); if (tran4type(t4) == TRAN4OPEN_TEMP) f4assignChar(d4field(openDbfs, "TEMP"), 'Y'); rc = d4append(openDbfs); if (rc == r4unique) { outMess[0] = "\r\n\r\nLog file error! DBF identifier already used.\r\n\r\n"; util4out(c4, stdout, outMess, 1); } if (rc != 0) return(rc); if (settings->include & INCLUDE_OPEN) { rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); if (tran4type(t4) == TRAN4OPEN) f4assign(d4field(tempDbf, "L4TYPE"), "OPEN"); else f4assign(d4field(tempDbf, "L4TYPE"), "OPEN_TEMP"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (settings->misc > 0) f4assign(d4field(tempDbf, "L4MISC"), addName); rc = d4append(tempDbf); } if ( !rc && !didProcess ) didProcess = 1; return(rc); } /**************************************************************************** **:: Function: typeTran4Close ** ***************************************************************************** ** ** Function: typeTran4Close() ** ****************************************************************************/ static short typeTran4Close(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, TRAN4 *t4) { DATA4 *tempDbf; short rc; char client[23]; util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) return(0); return(rc); } d4delete(openDbfs); if (settings->include & INCLUDE_OPEN) { tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); if (f4true(d4field(openDbfs, "TEMP"))) f4assign(d4field(tempDbf, "L4TYPE"), "CLOSE_TEMP"); else f4assign(d4field(tempDbf, "L4TYPE"), "CLOSE"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (settings->misc > 0) f4assignField(d4field(tempDbf, "L4MISC"), d4field(openDbfs, "FILENAME")); rc = d4append(tempDbf); } return(rc); } /**************************************************************************** **:: Function: typeTran4Start ** ***************************************************************************** ** ** Function: typeTran4Start() ** ****************************************************************************/ short typeTran4Start(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, DATA4* tranDbf, TRAN4 *t4) { DATA4 *tempDbf; short rc, rolledBack; char clientId[12], *outMess[1]; util4rightJ(ltoa(tran4clientId(t4), clientId, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, clientId); if (rc != 0) { outMess[0] = "\r\n\r\nLog file error! User not initialized.\r\n\r\n"; util4out(c4, stdout, outMess, 1); return(rc); } rc = d4skip(openDbfs, 1L); if (rc != 0 && rc != r4eof) return(rc); while (f4long(d4field(openDbfs, "SERVERDTID")) != 0 && rc == 0) { f4assignLong(d4field(openDbfs, "TRANID"), tran4id(t4)); if (settings->include & INCLUDE_ROLLBACK) { tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); f4assign(d4field(tempDbf, "L4TYPE"), "START"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); rolledBack = 1; util4rightJ(ltoa(tran4id(t4), clientId, 10), 12); rc = d4seek(tranDbf, clientId); if (rc != 0) if (rc == r4after || rc == r4eof) rolledBack = 0; else return(rc); if (rolledBack) f4assignChar(d4field(tempDbf, "L4ROLLED"), 'Y'); rc = d4append(tempDbf); if (rc != 0) return(rc); } rc = d4skip(openDbfs, 1L); } if (rc == r4eof) rc = 0; return(rc); } /**************************************************************************** **:: Function: typeTran4CompleteRollback ** ***************************************************************************** ** ** Function: typeTran4CompleteRollback() ** ****************************************************************************/ short typeTran4CompleteRollback(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, TRAN4 *t4) { DATA4 *tempDbf; short rc; char tranId[12]; util4rightJ(ltoa(tran4id(t4), tranId, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "TRANID")); rc = d4seek(openDbfs, tranId); if (rc != 0 && rc != r4eof && rc != r4after) return(rc); while (rc == 0) { f4assignLong(d4field(openDbfs, "TRANID"), 0); if (settings->include & INCLUDE_ROLLBACK) { tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); if (tran4type(t4) == TRAN4COMPLETE) f4assign(d4field(tempDbf, "L4TYPE"), "COMPLETE"); else f4assign(d4field(tempDbf, "L4TYPE"), "ROLLBACK"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); rc = d4append(tempDbf); if (rc != 0) return(rc); } rc = d4seek(openDbfs, tranId); } if (rc == r4eof || rc == r4after) rc = 0; return(rc); } /**************************************************************************** **:: Function: typeTran4Write ** ***************************************************************************** ** ** Function: typeTran4Write() ** ****************************************************************************/ static short typeTran4Write(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, DATA4* tranDbf, TRAN4 *t4) { DATA4 *tempDbf; short rc, i, rolledBack=1; unsigned long offset; char client[23]; char *data; unsigned long offsetMemo; util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) return(0); return(rc); } util4rightJ(ltoa(tran4id(t4), client, 10), 12); rc = d4seek(tranDbf, client); if (rc != 0) if (rc == r4after || rc == r4eof) rolledBack = 0; else return(rc); if (!(settings->include & INCLUDE_ROLLBACK) && rolledBack) return(0); tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); data = (char *)tran4getData(t4, 0L); if (!data) return(-1); if (settings->include & INCLUDE_INITIAL) { rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); f4assign(d4field(tempDbf, "L4TYPE"), "WRITE_OLD"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (rolledBack) f4assignChar(d4field(tempDbf, "L4ROLLED"), 'Y'); f4assignLong(d4field(tempDbf, "L4RECNO"), *(long *)data); if (*(data+4) == '*') f4assignChar(d4field(tempDbf, "L4DELETED"), 'Y'); offset = 5; offsetMemo = 4+f4long(d4field(openDbfs, "RECORDWID"))*2; if (!d4field(tempDbf, "L4RECORD")) for (i=d4fieldNumber(tempDbf, "L4DELETED")+1; i<=d4numFields(tempDbf); i++) if (f4type(d4fieldJ(tempDbf, i)) == 'M') { if (*(unsigned long *)(data+offsetMemo) != 0) f4memoAssignN(d4fieldJ(tempDbf, i), data+offsetMemo+4, *(unsigned *)(data+offsetMemo)); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { f4assignN(d4fieldJ(tempDbf, i), data+offset, f4len(d4fieldJ(tempDbf, i))); offset += f4len(d4fieldJ(tempDbf, i)); } else f4assignN(d4field(tempDbf, "L4RECORD"), data+offset, (unsigned)f4long(d4field(openDbfs, "RECORDWID"))-1); rc = d4append(tempDbf); if (rc != 0) return(rc); } if (!(settings->include & INCLUDE_UPDATE)) return(0); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); f4assign(d4field(tempDbf, "L4TYPE"), "WRITE_NEW"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (rolledBack) f4assignChar(d4field(tempDbf, "L4ROLLED"), 'Y'); f4assignLong(d4field(tempDbf, "L4RECNO"), *(long *)data); offset = 4+f4long(d4field(openDbfs, "RECORDWID")); offsetMemo = 4+f4long(d4field(openDbfs, "RECORDWID"))*2; if (*(data+offset++) == '*') f4assignChar(d4field(tempDbf, "L4DELETED"), 'Y'); if (!d4field(tempDbf, "L4RECORD")) for (i=d4fieldNumber(tempDbf, "L4DELETED")+1; i<=d4numFields(tempDbf); i++) if (f4type(d4fieldJ(tempDbf, i)) == 'M') { offsetMemo += 4 + (unsigned long) *(data+offsetMemo); if (*(unsigned long *)(data+offsetMemo) != 0) f4memoAssignN(d4fieldJ(tempDbf, i), data+offsetMemo+4, *(unsigned *)(data+offsetMemo)); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { f4assignN(d4fieldJ(tempDbf, i), data+offset, f4len(d4fieldJ(tempDbf, i))); offset += f4len(d4fieldJ(tempDbf, i)); } else f4assignN(d4field(tempDbf, "L4RECORD"), data+offset, (unsigned)f4long(d4field(openDbfs, "RECORDWID"))-1); rc = d4append(tempDbf); return(rc); } /**************************************************************************** **:: Function: typeTran4Append ** ***************************************************************************** ** ** Function: typeTran4Append() ** ****************************************************************************/ static short typeTran4Append(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, DATA4* tranDbf, TRAN4 *t4) { DATA4 *tempDbf; short rc, i, rolledBack=1; unsigned short offset; char client[23]; char *data; unsigned long offsetMemo; if (!(settings->include & INCLUDE_UPDATE)) return(0); util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) return(0); return(rc); } util4rightJ(ltoa(tran4id(t4), client, 10), 12); rc = d4seek(tranDbf, client); if (rc != 0) if (rc == r4after || rc == r4eof) rolledBack = 0; else return(rc); if (!(settings->include & INCLUDE_ROLLBACK) && rolledBack) return(0); tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); data = (char *)tran4getData(t4, 0L); if (!data) return(-1); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); f4assign(d4field(tempDbf, "L4TYPE"), "APPEND"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (rolledBack) f4assignChar(d4field(tempDbf, "L4ROLLED"), 'Y'); f4assignLong(d4field(tempDbf, "L4RECNO"), *(long *)data); if (*(data+4) == '*') f4assignChar(d4field(tempDbf, "L4DELETED"), 'Y'); offset = 5; offsetMemo = 4+f4long(d4field(openDbfs, "RECORDWID")); if (!d4field(tempDbf, "L4RECORD")) for (i=d4fieldNumber(tempDbf, "L4DELETED")+1; i<=d4numFields(tempDbf); i++) if (f4type(d4fieldJ(tempDbf, i)) == 'M') { if (*(unsigned long *)(data+offsetMemo) != 0) f4memoAssignN(d4fieldJ(tempDbf, i), data+offsetMemo+4, *(unsigned *)(data+offsetMemo)); offsetMemo += 4 + *(unsigned long *)(data+offsetMemo); offset += 10; } else { f4assignN(d4fieldJ(tempDbf, i), data+offset, f4len(d4fieldJ(tempDbf, i))); offset += f4len(d4fieldJ(tempDbf, i)); } else f4assignN(d4field(tempDbf, "L4RECORD"), data+offset, (unsigned)f4long(d4field(openDbfs, "RECORDWID"))-1); rc = d4append(tempDbf); return(rc); } /**************************************************************************** **:: Function: typeTran4PackZap ** ***************************************************************************** ** ** Function: typeTran4PackZap() ** ****************************************************************************/ static short typeTran4PackZap(CODE4 *c4, SETTINGSTRUCT *settings, DATA4 *openDbfs, TRAN4 *t4) { DATA4 *tempDbf; short rc; char client[23]; char *data, buff[49]; if (!(settings->include & INCLUDE_UPDATE)) return(0); util4rightJ(ltoa(tran4clientId(t4), client, 10), 12); util4rightJ(ltoa(tran4serverDataId(t4), client+11, 10), 12); d4tagSelect(openDbfs, d4tag(openDbfs, "CLID")); rc = d4seek(openDbfs, client); if (rc != 0) { if (rc == r4after || rc == r4eof) return(0); return(rc); } tempDbf = (DATA4 *)f4long(d4field(openDbfs, "DATA4PTR")); data = (char *)tran4getData(t4, 0L); if (!data) return(-1); rc = d4appendStart(tempDbf, 0); if (rc != 0) return(rc); d4blank(tempDbf); if (tran4type(t4) == TRAN4ZAP) f4assign(d4field(tempDbf, "L4TYPE"), "ZAP"); else f4assign(d4field(tempDbf, "L4TYPE"), "PACK"); f4assignLong(d4field(tempDbf, "L4ID"), tran4id(t4)); if (settings->time) f4assign(d4field(tempDbf, "L4TIME"), timeformat(t4)); if (settings->netid > 0) f4assignField(d4field(tempDbf, "L4NETID"), d4field(openDbfs, "NETNAME")); if (settings->userid > 0) f4assignField(d4field(tempDbf, "L4USERID"), d4field(openDbfs, "USERNAME")); if (tran4type(t4) == TRAN4ZAP && settings->misc > 0) { sprintf(buff, "Begin Recno: %lu, End Recno: %lu", *(unsigned long *)data, *(unsigned long *)(data+4)); f4assign(d4field(tempDbf, "L4MISC"), buff); } rc = d4append(tempDbf); return(rc); } /**************************************************************************** **:: Function: doLogFile ** ***************************************************************************** ** ** Function: doLogFile() ** ****************************************************************************/ static int doLogFile(CODE4 *c4, SETTINGSTRUCT *settings) { DATA4 *openDbfs, *tranDbf, *tempDbf; TRAN4 *t4; FIELD4 *data4Ptr; short rc, rc2, intPart, decPart; char *outMess[3]; char 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); openDbfs = d4createTemp(c4, openFields, openTags); if (openDbfs == 0) return(-1); tranDbf = d4createTemp(c4, tranFields, tranTags); if (tranDbf == 0) { d4close(openDbfs); return(-1); } t4 = &c4->c4trans.trans; c4->autoOpen = 0; d4tagSelect(tranDbf, d4tag(tranDbf, "TRANID_T")); #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: rc = typeTran4Shutdown(c4, openDbfs, t4); break; case TRAN4INIT: rc = typeTran4Init(c4, openDbfs, t4); break; case TRAN4INIT_UNDO: rc = typeTran4InitUndo(c4, openDbfs, t4); break; case TRAN4OPEN: case TRAN4OPEN_TEMP: rc = typeTran4Open(c4, settings, openDbfs, t4); break; case TRAN4CLOSE: rc = typeTran4Close(c4, settings, openDbfs, t4); break; case TRAN4START: rc = typeTran4Start(c4, settings, openDbfs, tranDbf, t4); break; case TRAN4COMPLETE: case TRAN4ROLLBACK: rc = typeTran4CompleteRollback(c4, settings, openDbfs, t4); break; case TRAN4WRITE: rc = typeTran4Write(c4, settings, openDbfs, tranDbf, t4); break; case TRAN4APPEND: rc = typeTran4Append(c4, settings, openDbfs, tranDbf, t4); break; case TRAN4PACK: case TRAN4ZAP: rc = typeTran4PackZap(c4, settings, openDbfs, t4); break; case TRAN4BACKEDUP: case TRAN4VOID: 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; 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 (tempDbf) 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 mainLog4Dbf(int argc, char *argv[], int hWnd ) #else int main(int argc, char *argv[]) #endif { CODE4 c4; TRAN4 *t4; SETTINGSTRUCT settings; int rc=0; char *logFileName=0, *outMess[1]; #ifdef S4WINDOWS hWndStatus = hWnd ; messageType = MB_ICONSTOP ; #endif #ifndef S4DLL_BUILD #ifdef _WINDOWS _wabout("LOG4DBF.EXE\r\n(c)Copyright Sequiter Software Inc., 1988-1996"); #endif #endif #ifdef S4UNIX strcpy(statusStringSpace, "100.00 "); #endif code4init(&c4); c4.autoOpen = 1; c4.errFieldName = 0; c4.lockAttempts = WAIT4EVER; c4.safety = 1; c4.singleOpen = 0 ; memset(&settings, 0, sizeof(SETTINGSTRUCT)); #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) rc = checkFlags(&c4, u4flags, u4flagsNum, &settings); if (rc != 0) { util4printCommandLine(&c4, u4flags, u4flagsNum, argv[0]); code4initUndo(&c4); #ifdef S4WINDOWS sendCloseMessage( hWndStatus ) ; #endif return(rc); } rc = getLogFileName(&c4, &settings, &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) { t4 = &c4.c4trans.trans; rc = tran4top(t4); if (rc == 0 && ((tran4type(t4) != TRAN4SHUTDOWN && tran4type(t4) != TRAN4BACKEDUP) || tran4serverDataId(t4) > TRAN4VERSION_NUM)) { outMess[0] = "Log file error! File is either not valid 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, &settings); if (rc == 0) { #ifdef S4WINDOWS messageType = MB_ICONEXCLAMATION ; sendStatusMessage( hWndStatus, 100 ) ; #endif outMess[0] = "Utility successfully finished!\r\n"; } else outMess[0] = "Error! Utility did not successfully finish!\r\n"; util4out(&c4, stdout, outMess, 1); code4transInitUndo(&c4.c4trans); if (logFileName) u4free(logFileName); util4flagsFree(u4flags, u4flagsNum); code4initUndo(&c4); #ifdef S4WINDOWS sendCloseMessage( hWndStatus ) ; #endif return(rc); }