campo-sirio/cb/log/log4dbf.c
alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

2174 lines
66 KiB
C
Executable File

/* log4dbf.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
/* Convert .LOG file to .DBF format */
/****************************************************************************
**:: Preprocessor Directives
*****************************************************************************/
#include "d4all.h"
#include <ctype.h>
#ifdef S4WINTEL
#include <direct.h>
#else
#ifdef S4UNIX
#include <sys/stat.h>
#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 <data.dbf> [<original.dbf>] [<output.chg>]]\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 <server.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 <output directory>]\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 <data.dbf>]\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 [<config.dbf>]}\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; i<u4flags[UTIL4INCLUDE].numPtr/4; i++)
{
c4upper ( u4flags[UTIL4INCLUDE].ptr[i]+1 ) ;
if (memcmp(u4flags[UTIL4INCLUDE].ptr[i]+1, "ALL", 3) == 0)
{
settings->include = 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; i<settings->numAdd; 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; i<settings->numAdd; 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; j<d4numFields(origDbf) && i < tempNumFields; j++)
{
if (!(settings->include & 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);
}