Initial upload

This commit is contained in:
Philip Smart
2019-11-18 00:29:48 +00:00
commit af833c09ee
56 changed files with 20943 additions and 0 deletions

53
.gitignore vendored Normal file
View File

@@ -0,0 +1,53 @@
.metadata
.dm
.gradle
/Releases
/.nb-gradle/
*.bin
*.dmp
*.elf
*.lss
*.map
*.rpt
*.srec
*.swp
*.zpu
*.log
*.done
*.smsg
*.summary
*.jdi
*.pin
*.out.sdc
*.sof
*.sld
*.rbf
*.qws
*.sav
*.pof
*.qdf
*.srf
*.o
ux/SCCS/
ux/1lib/
ux/4lib/
ux/5lib/
ux_test/SCCS/
ux_test/1lib/
ux_test/4lib/
ux_test/5lib/
MDC/SCCS/
MDC/1lib/
MDC/4lib/
MDC/5lib/
SDD/SCCS/
SDD/1lib/
SDD/4lib/
SDD/5lib/
VDW/SCCS/
VDW/1lib/
VDW/4lib/
VDW/5lib/
VDW/odbclib/
VDW/test/
KIIL/

144
MDC/Makefile Executable file
View File

@@ -0,0 +1,144 @@
#******************************************************************************
#* Product: # # ###### ##### # ### ######
#* ## ## # # # # # # # #
#* # # # # # # # # # # #
#* # # # # # # # # ######
#* # # # # # # # # #
#* # # # # # # # # # #
#* # # ###### ##### ####### ####### ### ######
#*
#* File: Makefile
#* Description: Build description file for the virtual data warehouse
#* Meta Data Communications API library.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
TITLE = "Meta Data Communications API Library"
COPYRIGHT = "(C) P.D.Smart, %D%, Ver %I%"
PROJ =
PURIFY = #purify
PROJPATH = /dvlp/MDC_LIB
GNUINCLUDE = #-I/apps/gnu/$(ARCH)/include
UXINCLUDE = -I../ux
INCLUDEDIR = -I. $(UXINCLUDE) $(GNUINCLUDE)
1DEBUGFLAGS = -g #-DMDC_DEBUG #-E
4DEBUGFLAGS = -g #-DMDC_DEBUG #-E
5DEBUGFLAGS = -g #-DMDC_DEBUG #-E
1OPTIMIZEFLAGS = #-O2
4OPTIMIZEFLAGS = #-O2
5OPTIMIZEFLAGS = #-O2
1OPTIONFLAGS = -D${OS} #-ansi -Wall
4OPTIONFLAGS = -D${OS} #-ansi -Wall
5OPTIONFLAGS = -D${OS} -D_REENTRANT #-ansi -Wall
CFLAGS = $(${OSVER}DEBUGFLAGS) $(${OSVER}OPTIMIZEFLAGS) \
$(${OSVER}OPTIONFLAGS)
LDFLAGS = -static
SYBLIBS = -L/apps/sybase/lib -lsybdb
UXLIBS = -L../ux/${OSVER}lib -lux
LIBS = $(UXLIBS) -lm
SCCSFLAGS = -d$(PROJPATH)
SCCSGETFLAGS =
ifeq ($(ZPU_BUILD),)
BASE =
else
BASE = zpu-elf-
endif
CC = $(BASE)gcc
LD = $(BASE)gcc
AS = $(BASE)as
AR = $(BASE)ar
CP = $(BASE)objcopy
DUMP = $(BASE)objdump
RANLIB = $(BASE)ranlib
# Suffixes where interested in for this project.
#
.SUFFIXES:
.SUFFIXES: .o .c .h
# Our way of making an object file.
#
.c.o:
$(PURIFY) $(CC) $(INCLUDEDIR) $(CFLAGS) -c $<
# All, ie: all programs to be built
#
all:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Use 'build' command to make LIBMDC library."
libmdc: Begin \
libmdc.a \
End
# How to clean up the directory... make it look pretty!
#
clean: Begin \
DoClean \
End
# How to perform an installation of the resultant software.
#
install: Begin \
DoInstall \
End
#
# Pre-make start sequence.
#
Begin:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Operation commencing @ `date`"
@echo
#
# Post-make completion sequence.
#
End:
@echo
@echo "Completed @ `date`"
# Perform all cleanup operations to ensure future builds occur
# with completeness.
#
DoClean:
rm -f *.o *.bak *.a *.BAK *.sav core
# Perform installation of software as per spec.
#
DoInstall:
# Build the virtual data warehouse Meta Data Communications
# API library.
#
libmdc.a: mdc_common.o mdc_server.o mdc_client.o
$(AR) rcv libmdc.a mdc_common.o mdc_server.o mdc_client.o
mdc_client.o: mdc.h mdc_common.h
mdc_server.o: mdc.h mdc_common.h
mdc_common.o: mdc.h mdc_common.h

182
MDC/build Executable file
View File

@@ -0,0 +1,182 @@
#!/bin/csh
#******************************************************************************
#* Product: # # ###### ##### # ### ######
#* ## ## # # # # # # # #
#* # # # # # # # # # # #
#* # # # # # # # # ######
#* # # # # # # # # #
#* # # # # # # # # # #
#* # # ###### ##### ####### ####### ### ######
#*
#* File: build
#* Description: Build description file for the virtual data warehouse
#* Meta Data Communications API library.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
# Work out architecture we are compiling on..
#
setenv ARCH `uname -s`
setenv ARCH ${ARCH}`uname -r | cut -c1`
# Work out arguments and decide on actions from there.
#
if( $#argv > 0 ) then
switch("$argv[1]")
case "save":
make -f Makefile clean
sccs delta SCCS
exit 0
case "install":
echo "Installing libraries and header files."
echo -n "Please enter 'vdwd' "
su - vdwd <<EOF
cp /dvlp/MDC/1lib/libmdc.a ~/1lib/libmdc.a
cp /dvlp/MDC/4lib/libmdc.a ~/4lib/libmdc.a
cp /dvlp/MDC/5lib/libmdc.a ~/5lib/libmdc.a
cp /dvlp/MDC/mdc_common.h ~/include/.
cp /dvlp/MDC/mdc.h ~/include/mdc.h
EOF
exit 0
case "zpu":
setenv ARCH 'ZPU'
set makecmd="libmdc"
breaksw
default:
# If the command is not one this script recognises then pass on to
# the makefile.
#
set makecmd="$argv[1]"
endsw
else
set makecmd="libmdc"
endif
# Build according to parameter supplied.
#
switch ($ARCH)
case "SunOS4":
setenv OS "SUNOS"
setenv OSVER 4
echo "SunOS operating system build"
if( ! -r .sunos ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .sunos
chmod 777 .sunos
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libmdc.a ) then
\rm -f ${OSVER}lib/libmdc.a
ranlib ./libmdc.a
\mv -f libmdc.a ${OSVER}lib
endif
breaksw
case "SunOS5":
setenv OS "SOLARIS"
setenv OSVER 5
echo "Solaris operating system build"
if( ! -r .solaris ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .solaris
chmod 777 .solaris
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libmdc.a ) then
\rm -f ${OSVER}lib/libmdc.a
\mv -f libmdc.a ${OSVER}lib
endif
breaksw
case "Linux2":
case "Linux4":
setenv OS "LINUX"
setenv OSVER 1
echo "Linux operating system build"
echo ""
if( ! -r .linux ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .linux
chmod 777 .linux
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libmdc.a ) then
\rm -f ${OSVER}lib/libmdc.a
\mv -f libmdc.a ${OSVER}lib
endif
breaksw
case "ZPU":
setenv OS "ZPU"
setenv OSVER 1
echo "ZPU operating system build"
echo ""
if( ! -r .zpu ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .zpu
chmod 777 .zpu
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile ZPU_BUILD=1 $makecmd
set result = $status
endif
if( $result == 0 && -r libmdc.a ) then
\rm -f ${OSVER}lib/libmdc.a
\mv -f libmdc.a ${OSVER}lib
endif
breaksw
default:
echo "Unknown architecture, cannot build library..."
breaksw
endsw

137
MDC/mdc.h Executable file
View File

@@ -0,0 +1,137 @@
/******************************************************************************
* Product: # # ###### ##### # ### ######
* ## ## # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* # # ###### ##### ####### ####### ### ######
*
* File: mdc.h
* Description: Header file for declaration of structures, datatypes etc.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef MDC_H
#define MDC_H
/* Bring in declaration of all UX functions.
*/
#include <ux.h>
/* Definitions for maxims etc.
*/
#define MAX_DBNAMELEN 20 /* Database Name length */
#define MAX_ERRMSGLEN 1024 /* Length of an error msg */
#define MAX_FTPOPTIONLEN 20 /* Length of an option string for FTP */
#define MAX_PASSWORDLEN 20 /* Password length */
#define MAX_SERVERNAMELEN 20 /* Server Name length */
#define MAX_USERNAMELEN 20 /* User Name length */
/* Definitions for Function Returns
*/
#define MDC_OK 0 /* Return OK */
#define MDC_FAIL -1 /* Return FAIL */
#define MDC_NODAEMON -2 /* No daemon at destination */
#define MDC_SERVICENAK -3 /* Daemon cannot provide the req service */
/* or bad parameters provided */
#define MDC_BADCONTEXT -4 /* Attempting to perform action in the */
/* wrong context */
#define MDC_SNDREQNAK -5 /* NAK received for a Send Request */
/* Define MDC packet type definitions.
*/
#define MDC_ACK 'A' /* Positive comms reply */
#define MDC_ABORT 'B' /* Abort command packet */
#define MDC_CHANGE 'C' /* Change service command */
#define MDC_DATA 'D' /* Data packet */
#define MDC_EXIT 'E' /* Exit command packet */
#define MDC_INIT 'I' /* Service Initialisation request */
#define MDC_NAK 'N' /* Negative comms reply */
#define MDC_PREQ 'P' /* Process request command */
/* Service types
*/
#define SRV_FTPX 'F' /* FTP driver */
#define SRV_JAVA 'J' /* JAVA code execution */
#define SRV_ODBC 'O' /* ODBC access */
#define SRV_SCMD 'C' /* System command execution driver */
#define SRV_SYBASE 'S' /* Sybase database access */
#define SRV_AUPL 'A' /* Audio Player driver */
/* Define error return codes which are embedded into returned error messages
* for the user to decipher.
*/
#define MDC_EMSG_MEMORY "M0000"
/* Service details structures for Sybase & ODBC.
*/
typedef struct SybaseServInfo {
UCHAR szUser[MAX_USERNAMELEN]; /* User Name */
UCHAR szPassword[MAX_PASSWORDLEN]; /* Password */
UCHAR szServer[MAX_SERVERNAMELEN]; /* Server name */
UCHAR szDatabase[MAX_DBNAMELEN]; /* Database name */
} SERV_INFO;
/* Service detail structures for FTP.
*/
typedef struct FTPServInfo {
UCHAR szServer[MAX_SERVERNAMELEN]; /* Name of FTP server */
UCHAR szUser[MAX_USERNAMELEN]; /* User on FTP server */
UCHAR szPassword[MAX_PASSWORDLEN]; /* Pwd on FTP server */
} FTPX_INFO;
typedef struct ServiceDetails {
UCHAR cServiceType; /* Type of service identifier */
/* Union of the different types of service structures for the different
* types of drivers.
*/
union {
/* structure for each service type
*/
SERV_INFO sSybaseInfo;
SERV_INFO sODBCInfo;
FTPX_INFO sFTPInfo;
} uServiceInfo;
} SERVICEDETAILS;
/* Prototypes externally visible for MDC Client API.
*/
int MDC_Start(void);
int MDC_End(void);
int MDC_SetTimeout(UCHAR *, UINT, UCHAR *);
int MDC_CreateService(UCHAR *, UINT *, SERVICEDETAILS *);
int MDC_ChangeService(UINT, SERVICEDETAILS *);
int MDC_CloseService(UINT);
int MDC_SendRequest(UINT, UCHAR *, UINT, void (*) (UINT, UCHAR *, UINT));
int MDC_GetResult(UINT, UCHAR **);
int MDC_GetStatus(UINT, UINT *);
/* Prototypes externally visible for MDC Server API.
*/
int MDC_Server( UINT *, UCHAR *, int (*)(UCHAR *, int, UCHAR *), void (*)( UCHAR ) );
int MDC_ReturnData( UCHAR *, int );
int MDC_TimerCB( ULNG, UINT, UINT, void (*)(void) );
#endif /* MDC_H */

1466
MDC/mdc_client.c Executable file

File diff suppressed because it is too large Load Diff

148
MDC/mdc_common.c Executable file
View File

@@ -0,0 +1,148 @@
/******************************************************************************
* Product: # # ###### ##### # ### ######
* ## ## # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* # # ###### ##### ####### ####### ### ######
*
* File: mdc_common.c
* Description: Meta Data Communications common functions shared between
* the client and server API interfaces.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#if defined(SOLARIS)
#include <thread.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <ux.h>
/* Indicate that we are a C module for any header specifics.
*/
#define MDC_COMMON_C
/* Bring in local specific header files.
*/
#include "mdc.h"
#include "mdc_common.h"
/******************************************************************************
* Function: _MDC_Init
* Description: Function to perform MDC initialisation. The library performs
* checking to ensure that initialisation only occurs once
* prior to an _MDC_Terminate.
*
* Returns: MDC_FAIL- Couldnt initialise library.
* MDC_OK - Library initialised.
******************************************************************************/
int _MDC_Init( void )
{
/* Local variables.
*/
static int nInitialised = FALSE;
int nReturn;
UCHAR *szFunc = "_MDC_Init";
/* If this is the first invocation, setup the global state flag to
* a known value.
*/
if(nInitialised == FALSE)
{
nInitialised = TRUE;
MDC.nInitialised = FALSE;
MDC.nMDCCommsMode = FALSE;
MDC.spChanDetHead = NULL;
MDC.spChanDetTail = NULL;
}
/* Have we been initialised already..? If we have, just get out.
*/
if( MDC.nInitialised == FALSE )
{
/* Initialise all so-called globals.
*/
MDC.spIFifoHead = NULL;
MDC.spIFifoTail = NULL;
MDC.spOFifoHead = NULL;
MDC.spOFifoTail = NULL;
MDC.nClientChanId = 0;
MDC.nCloseDown = FALSE;
MDC.nInitialised = TRUE;
MDC.nNewSrvTimeout = DEF_NEW_SERVICE_TIMEOUT;
MDC.nSrvReqTimeout = DEF_SRV_REQ_TIMEOUT;
MDC.nSndReqTimeout = DEF_SEND_REQ_TIMEOUT;
#if defined(SOLARIS)
/* MDC.thMDCLock = DEFAULTMUTEX; */
#endif
/* Initialise UX comms
*/
if ((nReturn = SL_Init(MDC_SRV_KEEPALIVE, (UCHAR *) NULL)) != R_OK)
{
Lgr(LOG_DEBUG, szFunc, "SL_Init failed");
return(MDC_FAIL);
}
}
/* Return result to caller.
*/
return(MDC_OK);
}
/******************************************************************************
* Function: _MDC_Terminate
* Description: Function to shutdown the MDC library. After a successful
* shutdown, _MDC_Init may be called to re-initialise the
* library. If MDC_Terminate fails, program exit is advised.
*
* Returns: MDC_FAIL- Couldnt perform a clean shutdown.
* MDC_OK - Library successfully shutdown.
******************************************************************************/
int _MDC_Terminate( void )
{
/* Local variables.
*/
/* Free up all resources that weve used to return us to a virgin state.
*/
/* Give the UX library a slice of CPU so that it can tidy up.
*/
SL_Poll(MAX_TERMINATE_TIME);
/* Reset the initialisation flag so that user code can re-initialise us.
*/
MDC.nInitialised = FALSE;
/* Return result to caller.
*/
return(MDC_OK);
}

211
MDC/mdc_common.h Executable file
View File

@@ -0,0 +1,211 @@
/******************************************************************************
* Product: # # ###### ##### # ### ######
* ## ## # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* # # ###### ##### ####### ####### ### ######
*
* File: mdc_common.h
* Description: General purpose library routines for MDC.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef MDC_COMMON_H
#define MDC_COMMON_H
/* Define constants, definitions etc.
*/
#define DEF_POLLTIME 1000 /* Default comms poll wait time */
#define DEF_SERVICENAME "vdwd" /* Name of service in /etc/services */
#define MDC_SRV_KEEPALIVE 1000 /* TCP/IP keep alive for MDC Server */
#define MAX_TERMINATE_TIME 2000 /* Time for termination of MDC layer */
/* Timeout definitions.
*/
#define MDC_CL_KEEPALIVE 1000 /* TCP/IP keep alive for MDC client */
#define CS_SLEEP_TIME 1 /* Create service loop sleep time (mS)*/
#define SR_SLEEP_TIME 10 /* Srv req reply loop sleep time (mS) */
#define SNDREQ_SLEEP_TIME 10 /* Wait on send req sleep time (mS) */
#define DEF_NEW_SERVICE_TIMEOUT 30000 /* Number of mS before give up trying */
/* to make the connection */
#define DEF_SRV_REQ_TIMEOUT 10000 /* Number of mS to wait for Service */
/* Request reply */
#define DEF_SEND_REQ_TIMEOUT 5400000 /* Number of mS before timing out */
#define NEW_SERVICE_TIMEOUT "NEW_SERVICE"
#define SRV_REQ_TIMEOUT "SERVICE_REQUEST"
#define SEND_REQ_TIMEOUT "SEND_REQUEST"
/* Globals (yugghhh!) for the MDC library. They are contained within a
* structure so they are more manageable and readers can see immediately
* the variables scope.
*/
typedef struct {
/* Shared Globals
*/
UCHAR szErrMsg[MAX_ERRMSGLEN]; /* Storage for error messages */
/* Server Globals
*/
LINKLIST *spIFifoHead; /* Pointer to head of Incoming FIFO list */
LINKLIST *spIFifoTail; /* Pointer to tail of Incoming FIFO list */
LINKLIST *spOFifoHead; /* Pointer to head of Outgoing FIFO list */
LINKLIST *spOFifoTail; /* Pointer to tail of Outgoing FIfO list */
UINT nClientChanId; /* Server to client comms channel Id */
UINT nCloseDown; /* Shutdown flag */
UINT nInitialised; /* Flag to indicate if library initialised */
void (*fCntrlCB)( UCHAR ); /* User Control callback */
/* Client Globals
*/
UINT nMDCCommsMode; /* Indicates whether the Client software */
/* is in MDC Comms Mode, i.e. between an */
/* MDC_start and MDC_End */
LINKLIST *spChanDetHead; /* Pointer to head of Channel Details list */
LINKLIST *spChanDetTail; /* Pointer to tail of Channel Details list */
UINT nNewSrvTimeout; /* New service timeout */
UINT nSrvReqTimeout; /* Service Request timeout */
UINT nSndReqTimeout; /* Send Request timeout */
UINT nLinkUp; /* Indicates if the link is up and running */
UINT nPendCon; /* Indicates whether a connection is */
/* pending */
UINT nPendConChanId; /* Indicates chanid for the pending */
/* connection, control call back sets */
/* this to zero when connection received */
UINT nPendSRChanId; /* Indicates chanid for a pending */
/* service request reply */
/* 0: no pending service request reply */
char cReplyType; /* Reply to service request ACK or NAK */
#if defined(MDC_CLIENT_C) && defined(SOLARIS)
mutex_t thMDCLock; /* Single thread lock for MT environment */
#endif
} MDC_GLOBALS;
/* Declare any common module prototypes which can only be seen by the MDC
* API library.
*/
#if defined(MDC_COMMON_C) || defined(MDC_CLIENT_C) || defined(MDC_SERVER_C)
int _MDC_Init( void );
int _MDC_Terminate( void );
#endif
/* Declare any required data types or variables which are specific to the
* common module.
*/
#ifdef MDC_COMMON_C
MDC_GLOBALS MDC;
#endif
/* Declare any required data types or variables which are specific to the
* client API module.
*/
#ifdef MDC_CLIENT_C
extern MDC_GLOBALS MDC;
typedef enum ChState
{
MAKING_CONN, /* Making connection to daemon */
IN_SERVICE_REQUEST, /* Waiting for reply to service request */
IDLE, /* Waiting for a send request, Change */
/* service or Close service */
IN_CHANGE_SERVICE, /* In process of changing service */
IN_SEND_REQUEST, /* Processing a request */
SEND_REQUEST_COMPLETE, /* Processing for send request is complete. */
/* Will go to IDLE after user has done a */
/* GetStatus for the Channel */
} CHSTATE;
typedef struct ChanStatus
{
UINT nChanId; /* Channel ID for connection */
CHSTATE State; /* State for channel */
void (*UserDataCB) (UINT, UCHAR *, UINT);
/* Call back function for send request */
/* The following are only valid if the state is
SEND_REQUEST_COMPLETE
*/
UINT bSendReqResult; /* Result of send request */
UCHAR pszErrStr[MAX_ERRMSGLEN];
/* If NAK returned then contains */
/* the NAK Error String */
} CHANSTATUS;
int _MDC_SendPacket(UINT, char, UCHAR *, UINT);
int _MDC_PrintErrMsg(UCHAR *, UINT);
int _MDC_GetSrvRqtReply(UINT, char *);
int _MDC_CreateChStatus(UINT);
int _MDC_DelChStatus(UINT);
int _MDC_SetChState(UINT, CHSTATE);
int _MDC_GetChState(UINT, CHSTATE *);
int _MDC_SetSRResult(UINT, UINT);
int _MDC_GetSRResult(UINT, UINT *);
int _MDC_GetNAKErrStr(UINT, UCHAR **);
int _MDC_SetUserCB(UINT, void (*) (UINT, UCHAR *, UINT));
int _MDC_GetUserCB(UINT, void (**) (UINT, UCHAR *, UINT));
int _MDC_WaitOnSndReq( UINT );
#endif
/* Declare any required data types or variables which are specific to the
* server API module.
*/
#ifdef MDC_SERVER_C
/* Structure to hold incoming and outgoing data packets within a FIFO
* linklist mechanism.
*/
typedef struct {
UCHAR *pszData; /* Pointer to a data block */
UINT nDataLen; /* Length of data contained in block */
} FIFO;
/* External global variable.
*/
extern MDC_GLOBALS MDC;
/* Prototypes for functions internal to MDC Server module.
*/
int _MDC_SendACK( void );
int _MDC_SendNAK( UCHAR * );
void _MDC_ServerCntlCB( int, ... );
void _MDC_ServerDataCB( UINT, UCHAR *, UINT );
#endif
/* A set of macros for implementing a simple thread locking strategy
* for the MDC library under solaris. The strategy is that only one
* thread may have access to the MDC libraries at any one time. Eventually
* the library will become completely thread-safe.
*/
#if defined(SOLARIS)
#define SINGLE_THREAD_LOCK mutex_lock(&MDC.thMDCLock);
#define THREAD_UNLOCK_RETURN(p) { \
mutex_unlock(&MDC.thMDCLock); \
return(p); \
}
#else
#define SINGLE_THREAD_LOCK
#define THREAD_UNLOCK_RETURN(p) return(p)
#endif
#endif /* MDC_COMMON_H */

815
MDC/mdc_server.c Executable file
View File

@@ -0,0 +1,815 @@
/******************************************************************************
* Product: # # ###### ##### # ### ######
* ## ## # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* # # ###### ##### ####### ####### ### ######
*
* File: mdc_server.c
* Description: Meta Data Communications API providing all functionality
* for server processes within the Virtual Data Warehouse
* project design.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#undef R_OK
/* Indicate that we are a C module for any header specifics.
*/
#define MDC_SERVER_C
/* Bring in local specific header files.
*/
#include "mdc.h"
#include "mdc_common.h"
/******************************************************************************
* Function: _MDC_SendACK
* Description: Function to send an acknowledge to the client in response to
* a data block received correctly or a request processed
* successfully.
*
* Returns: MDC_FAIL- Couldnt transmit an ACK message to the client.
* MDC_OK - ACK sent successfully.
******************************************************************************/
int _MDC_SendACK( void )
{
/* Local variables.
*/
int nReturn = MDC_OK;
UCHAR szAckBuf[2];
UCHAR *szFunc = "_MDC_SendACK";
/* Make sure that we have a valid channel connection in case of rogue
* program code.
*/
if( MDC.nClientChanId != 0 )
{
/* Build up the message to transmit.
*/
sprintf(szAckBuf, "%c", MDC_ACK);
/* Try and transmit it.
*/
if(SL_BlockSendData(MDC.nClientChanId, szAckBuf, 1) == R_FAIL)
{
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_ALERT, szFunc, "Couldnt transmit an ACK packet");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
} else
{
/* Log a message as this condition shouldnt not occur!
*/
Lgr(LOG_DEBUG, szFunc,
"Trying to transmit an ACK to an unknown client!");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
/* All finished, exit with result code.
*/
return(nReturn);
}
/******************************************************************************
* Function: _MDC_SendNAK
* Description: Function to send a negative acknowledge to the client in
* response to a data block which arrived incorrectly or a
* request which couldnt be processed successfully.
*
* Returns: MDC_FAIL- Couldnt transmit a NAK message to the client.
* MDC_OK - NAK sent successfully.
******************************************************************************/
int _MDC_SendNAK( UCHAR *szErrMsg ) /* I: Error msg to send with NAK */
{
/* Local variables.
*/
UINT nErrLen;
int nReturn = MDC_OK;
UINT nXmitLen;
UCHAR *psnzCmpBuf;
UCHAR *psnzTmpBuf;
UCHAR *szFunc = "_MDC_SendNAK";
/* Make sure that we have a valid channel connection in case of rogue
* program code.
*/
if( MDC.nClientChanId != 0 )
{
/* Calculate length of error message buffer for use in later
* memory manipulations.
*/
nErrLen = strlen(szErrMsg);
/* Allocate enough memory to hold a message id and the data prior
* to transmission.
*/
if((psnzTmpBuf=(UCHAR *)malloc(nErrLen+2)) == NULL)
{
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_DEBUG, szFunc, "Couldnt allocate (%d) bytes memory",
nErrLen+2);
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
} else
{
/* Log the message if we are in debug mode.
*/
Lgr(LOG_DEBUG, szFunc, "%s", szErrMsg);
/* Build up the message to transmit.
*/
*psnzTmpBuf = (UCHAR)MDC_NAK;
memcpy(psnzTmpBuf+1, szErrMsg, nErrLen);
/* Compress it to save on transmission overheads.
*/
nXmitLen=nErrLen+1;
if((psnzCmpBuf=Compress(psnzTmpBuf, &nXmitLen)) != NULL)
{
/* Free up memory we used to store the original message.
*/
if(psnzCmpBuf != psnzTmpBuf)
{
free(psnzTmpBuf);
/* Make our temporary pointer point to the new compressed
* memory block.
*/
psnzTmpBuf = psnzCmpBuf;
}
}
/* Try and transmit it.
*/
if(SL_BlockSendData(MDC.nClientChanId,psnzTmpBuf,nXmitLen) ==R_FAIL)
{
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_ALERT, szFunc, "Couldnt transmit NAK message");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
/* Free up used memory, no longer needed.
*/
free(psnzTmpBuf);
}
} else
{
/* Log a message as this condition shouldnt not occur!
*/
Lgr(LOG_DEBUG, szFunc,
"Trying to transmit a NAK to an unknown client!");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
/* All finished, exit with success.
*/
return(nReturn);
}
/******************************************************************************
* Function: _MDC_ServerCntlCB
* Description: A function to handle any communications control callbacks
* that are generated as a result of MDC_Server being executed.
*
* Returns: No Returns.
******************************************************************************/
void _MDC_ServerCntlCB( int nType, /* I: Type of callback */
... ) /* I: Arg list according to type */
{
/* Local variables.
*/
UINT nChanId;
UINT nPortNo;
ULNG lIPaddr;
va_list pArgs;
UCHAR *szFunc = "_MDC_ServerCntlCB";
/* Start var-arg list by making pArgs point to first arg in list.
*/
va_start(pArgs, nType);
/* What type of callback is it...?
*/
switch(nType)
{
/* A new connection has arrived.
*/
case SLC_NEWSERVICE:
/* Extract var args which indicate who the client is.
*/
nChanId = va_arg(pArgs, UINT);
nPortNo = va_arg(pArgs, UINT);
lIPaddr = va_arg(pArgs, ULNG);
/* Log a message to indicate who the client is.
*/
Lgr(LOG_DEBUG, szFunc,
"New service: PPID=%d, PID=%d, Chan=%d, Port=%d, IPaddr=%s",
getppid(), getpid(), nChanId, nPortNo, SL_HostIPtoString(lIPaddr));
/* Store the Channel Id of the client so that it can be used
* for async communications.
*/
MDC.nClientChanId = nChanId;
break;
/* Given connection has become temporarily unavailable.
*/
case SLC_LINKDOWN:
/* Extract var args which indicate who the client is.
*/
nChanId = va_arg(pArgs, UINT);
nPortNo = va_arg(pArgs, UINT);
lIPaddr = va_arg(pArgs, ULNG);
/* Log a message to indicate that the link has gone down.
*/
Lgr(LOG_DEBUG, szFunc,
"Link temporarily down, Chan=%d, Port=%d, IPaddr=%s",
nChanId, nPortNo, SL_HostIPtoString(lIPaddr));
break;
/* Given connection has died.
*/
case SLC_LINKFAIL:
/* Extract var args which indicate who the client is.
*/
nChanId = va_arg(pArgs, UINT);
nPortNo = va_arg(pArgs, UINT);
lIPaddr = va_arg(pArgs, ULNG);
/* Post a signal to indicate that we are about to shut down.
*/
if(MDC.nCloseDown == FALSE)
{
/* Call out of band processing mechanism.
*/
MDC.fCntrlCB(MDC_EXIT);
/* Setup exit flag so that we can terminate, as failure of
* our main connection port means we should exit.
*/
MDC.nCloseDown = TRUE;
}
/* Log a message to indicate that the link has gone down.
*/
Lgr(LOG_DEBUG, szFunc,
"Link closed or failed, Chan=%d, Port=%d, IPaddr=%s",
nChanId, nPortNo, SL_HostIPtoString(lIPaddr));
break;
default:
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_DEBUG, szFunc, "Unrecognised message type (%d)", nType);
break;
}
/* Terminate var-arg list.
*/
va_end(pArgs);
/* Return to caller.
*/
return;
}
/******************************************************************************
* Function: _MDC_ServerDataCB
* Description: A function to handle any data callbacks that are generated as
* a result of data arriving during an MDC_Server execution.
*
* Returns: No Returns.
******************************************************************************/
void _MDC_ServerDataCB( UINT nChanId, /* I: Channel data rcv on*/
UCHAR *szData, /* I: Rcvd data */
UINT nDataLen ) /* I: Rcvd data length */
{
/* Local variables.
*/
UINT nDLen = nDataLen;
FIFO *psFifo;
UCHAR *szFunc = "_MDC_ServerDataCB";
/* Special case processing for out of bands message. Normally messages
* are queued in a FIFO awaiting processing, but certain messages must be
* acted upon as soon as they arrive.
*/
if(nDataLen == 1)
{
/* Process according to type of message.
*/
switch(szData[0])
{
/* Special message which only has meaning when the daemon is
* returning data to the caller. Its actions are to basically
* force the driver to stop sending data and cancel all further
* data that may be awaiting transmission.
*/
case MDC_ABORT:
/* Initiate abort mechanism.
*/
MDC.fCntrlCB(MDC_ABORT);
return;
case MDC_EXIT:
/* Initiate closedown mechanism.
*/
MDC.fCntrlCB(MDC_EXIT);
MDC.nCloseDown = TRUE;
return;
default:
break;
}
}
/* Allocate memory to store a FIFO carrier. This FIFO carrier is then
* populated with the FIFO data below.
*/
if( (psFifo=(FIFO *)malloc(sizeof(FIFO))) == NULL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Memory exhausted, couldnt create FIFO carrier");
/* Send a NAK to client to indicate that we've run out of memory.
*/
if( _MDC_SendNAK("Memory exhausted on server, packet rejected (1)")
== MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc,
"Couldnt send a NAK message, Houston we have problems!!");
}
/* Get out, nothing more can be done.
*/
return;
}
/* Data block arrives in a compressed format, so uncompress prior to
* placing it into the incoming FIFO list.
*/
if( (psFifo->pszData=Decompress(szData, &nDLen)) == NULL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Couldnt decompress buffer, Chan (%d), Len (%d)",
nChanId, nDLen);
/* Send a NAK to client to indicate that the buffer sent cant be
* processed.
*/
if( _MDC_SendNAK("Couldnt decompress buffer, memory problems!")
== MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc,
"Couldnt send a NAK message, Houston we have problems!!");
}
/* Free up used resources and get out as nothing more can be done.
*/
free(psFifo);
return;
}
/* Complete the FIFO carrier information set.
*/
psFifo->nDataLen = nDLen;
/* Log message as to what has been received, may help track bugs.
*/
Lgr(LOG_DEBUG, szFunc,
"Message received: Data=%s, Len=%d", psFifo->pszData, psFifo->nDataLen);
/* Add buffer to the end of the incoming FIFO list.
*/
if( AddItem(&MDC.spIFifoHead, &MDC.spIFifoTail, SORT_NONE, NULL, NULL, NULL,
psFifo) == R_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc,
"Memory exhausted, couldnt add packet onto the FIFO link list");
/* Send a NAK to client to indicate that we've run out of memory.
*/
if(_MDC_SendNAK("Memory exhausted on server, packet rejected (2)")
== MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc,
"Couldnt send a NAK message, Houston we have problems!!");
}
/* Free up used resources and get out as nothing more can be done.
*/
free(psFifo->pszData);
free(psFifo);
return;
}
/* Return to caller.
*/
return;
}
/******************************************************************************
* Function: MDC_Server
* Description: Entry point into the Meta Data Communications for a server
* process. This function initialises all communications etc
* and then runs the given user callback to perform any required
* actions.
*
* Returns: MDC_FAIL- Function terminated due to a critical error, see
* Errno for exact reason code.
* MDC_OK - Function completed successfully without error.
******************************************************************************/
int MDC_Server( UINT *nPortNo, /* I: TCP/IP port number */
UCHAR *szService, /* I: Name of TCP/IP Service */
int (*fLinkDataCB) /* I: User function callback*/
(UCHAR *, int, UCHAR *),
void (*fControlCB)(UCHAR) /* I: User control callback */
)
{
/* Local variables.
*/
FIFO *psFifo;
LINKLIST *psNext;
UINT nServicePort;
static int nInitialised = FALSE;
int nReturn;
UCHAR *szFunc = "MDC_Server";
/* Check to see that we are not being called twice... some people may
* be idiotic.
*/
if( nInitialised == TRUE )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Attempt to initialise function more than once");
/* Exit as nothing more can be done.
*/
return(MDC_FAIL);
}
/* Initialise the library, exiting if we fail.
*/
if( (nReturn=_MDC_Init()) == MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Failed to initialise MDC Library");
/* Exit as nothing more can be done.
*/
return(nReturn);
}
/* Do we need to work out the TCP port number by looking in /etc/services?
*/
if( nPortNo == NULL )
{
/* Work out the port number by a lookup on the given service name.
*/
if( szService == NULL ||
SL_GetService(szService, &nServicePort) == R_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc,
"Service (%s) does not exist in /etc/services", szService);
/* Exit as nothing more can be achieved.
*/
return(MDC_FAIL);
}
} else
{
/* Store the port number provided into a common variable for the
* add server command.
*/
nServicePort = *nPortNo;
}
/* Add a service port so that we can accept incoming TCP connections.
*/
if( SL_AddServer(nServicePort, TRUE, _MDC_ServerDataCB, _MDC_ServerCntlCB)
== R_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc, "Couldnt add service on port %d", nServicePort);
/* Exit, nothing more that can be done.
*/
return(MDC_FAIL);
}
/* Save the control callback within MDC structure so out of band
* control messages can call the function directly.
*/
MDC.fCntrlCB = fControlCB;
/* Where initialised, so set the flag to prevent further re-entry.
*/
nInitialised = TRUE;
ML_Init(8080, MON_SERVICE_HTML, "MDC Server/2.2.aaa", NULL, NULL, NULL);
/* Now enter a tight loop, performing CPU scheduling in a non-preemptive
* fashion and handling events as and when they occur.
*/
do {
/* Call the UX scheduler to ensure comms events occur.
*/
SL_Poll(DEF_POLLTIME);
/* Any packets on the incoming FIFO? If there are, then grab the
* first one.
*/
if( (psFifo=StartItem(MDC.spIFifoHead, &psNext)) != NULL )
{
/* Delete the entry off the FIFO before working with it to
* guarantee that we never call the user twice with the same
* data.
*/
if(DelItem(&MDC.spIFifoHead, &MDC.spIFifoTail, psFifo, NULL, NULL,
NULL) == R_FAIL)
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc,
"Couldnt delete first FIFO entry, will retry later..");
} else
{
/* OK, weve got the data and we know its no longer on the FIFO,
* so lets call the users callback with this data.
*/
MDC.szErrMsg[0] = '\0';
if(fLinkDataCB(psFifo->pszData, psFifo->nDataLen, MDC.szErrMsg)
== MDC_FAIL)
{
/* The callback failed, need to send a NAK to the client
* plus the provided error message.
*/
if( _MDC_SendNAK(MDC.szErrMsg) == MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_ALERT, szFunc,
"Couldnt send a NAK message, we have problems!!");
}
} else
{
/* The callback succeeded, so send out an ACK to the client
* to let him continue on his merry way.
*/
if( _MDC_SendACK() == MDC_FAIL )
{
/* Log a message to indicate problem.
*/
Lgr(LOG_ALERT, szFunc,
"Couldnt send an ACK to the client...");
}
}
}
}
} while( MDC.nCloseDown == FALSE );
/* Where exitting cleanly, so toggle flag so that a new entry can
* succeed.
*/
nInitialised = FALSE;
/* Return result to caller.
*/
return(MDC_OK);
}
/******************************************************************************
* Function: MDC_ReturnData
* Description: Function called by user code to return any required data
* to a connected client. This function can only be called
* in response to a callback 'from the MDC layer to the user
* code' which has provided data.
*
* Returns: MDC_FAIL- An error occurred in transmitting the given data
* block to the client process, see Errno for exact
* reason code.
* MDC_OK - Data packet was transmitted successfully.
******************************************************************************/
int MDC_ReturnData( UCHAR *snzDataBuf, /* I: Data to return */
int nDataLen /* I: Length of data */
)
{
/* Local variables.
*/
int nReturn = MDC_OK;
UINT nXmitLen;
UCHAR *psnzCmpBuf;
UCHAR *psnzTmpBuf;
UCHAR *szFunc = "MDC_ReturnData";
/* Make sure that we have a valid channel connection in case of rogue
* program code.
*/
if( MDC.nClientChanId != 0 )
{
/* Allocate enough memory to hold a message id and the data prior
* to transmission.
*/
if((psnzTmpBuf=(UCHAR *)malloc(nDataLen+1)) == NULL)
{
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_DEBUG, szFunc, "Couldnt allocate (%d) bytes memory",
nDataLen+1);
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
} else
{
/* Build up the message to transmit.
*/
*psnzTmpBuf = (UCHAR)MDC_DATA;
memcpy(psnzTmpBuf+1, snzDataBuf, nDataLen);
/* Compress it to save on transmission overheads.
*/
nXmitLen=nDataLen+1;
if((psnzCmpBuf=Compress(psnzTmpBuf, &nXmitLen)) != NULL)
{
/* Free up memory we used to store the original message.
*/
if(psnzCmpBuf != psnzTmpBuf)
{
free(psnzTmpBuf);
/* Make our temporary pointer point to the new compressed
* memory block.
*/
psnzTmpBuf = psnzCmpBuf;
}
}
/* Try and transmit the new buffer.
*/
if(SL_BlockSendData(MDC.nClientChanId,psnzTmpBuf,nXmitLen) ==R_FAIL)
{
/* Log a message as this condition shouldnt occur.
*/
Lgr(LOG_ALERT, szFunc, "Couldnt transmit data packet");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
/* Free up used memory, no longer needed.
*/
free(psnzTmpBuf);
}
} else
{
/* Log a message as this condition shouldnt not occur!
*/
Lgr(LOG_DEBUG, szFunc,
"Trying to transmit a data packet to an unknown client!");
/* Set exit code to indicate failure.
*/
nReturn = MDC_FAIL;
}
/* Return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: MDC_TimerCB
* Description: Function to allow user code to register a callback event
* which is activated upon a timer expiring. The user provides
* the frequency and a function to callback and the MDC
* schedules it.
*
* Returns: No Return Values.
******************************************************************************/
int MDC_TimerCB( ULNG lTimePeriod, /* I: CB Time in Millseconds */
UINT nEnable, /* I: Enable(TRUE)/Dis(FALSE) CB*/
UINT nAstable, /* I: Astable(TRUE) or Mono CB */
void (*fTimerCB)(void)/* I: Function to call back */
)
{
/* Local variables.
*/
int nReturn;
int nTimerMode;
UCHAR *szFunc = "MDC_TimerCB";
/* Initialise the library, if needed.
*/
if( (nReturn=_MDC_Init()) == MDC_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Failed to initialise MDC Library");
/* Exit as nothing more can be done.
*/
return(nReturn);
}
/* Work out the UX timer mode with given parameters.
*/
if( nEnable == TRUE )
{
if( nAstable == TRUE )
{
nTimerMode = TCB_ASTABLE;
} else
{
nTimerMode = TCB_FLIPFLOP;
}
} else
{
nTimerMode = TCB_OFF;
}
/* Call UX to add the timed event.
*/
if( SL_AddTimerCB( lTimePeriod, nTimerMode, 0, fTimerCB ) == R_FAIL )
{
/* Log a message if needed.
*/
Lgr(LOG_DEBUG, szFunc, "Failed to add timer CB, Time=%ld, Mode=%d",
lTimePeriod, nTimerMode );
/* Exit as nothing more can be done.
*/
return(MDC_FAIL);
}
/* Return result to caller.
*/
return(MDC_OK);
}

156
SDD/Makefile Executable file
View File

@@ -0,0 +1,156 @@
#******************************************************************************
#* Product: ##### ###### ###### # ### ######
#* # # # # # # # # # #
#* # # # # # # # # #
#* ##### # # # # # # ######
#* # # # # # # # # #
#* # # # # # # # # # #
#* ##### ###### ###### ####### ####### ### ######
#*
#* File: Makefile
#* Description: Build description file for the virtual data warehouse
#* daemon Server Data-source Drivers.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
TITLE = "Server Data-source Driver Library"
COPYRIGHT = "(C) P.D.Smart, %D%, Ver %I%"
PROJ =
PURIFY = #purify
PROJPATH = ../SDD
GNUINCLUDE = -I/apps/gnu/$(ARCH)/include
MDCINCLUDE = -I../MDC
UXINCLUDE = -I../ux
ODBCINCLUDE = -I../odbc/include
SYBINCLUDE = -I/apps/sybase/include
INCLUDEDIR = -I. $(UXINCLUDE) $(MDCINCLUDE) $(GNUINCLUDE) $(ODBCINCLUDE)\
$(SYBINCLUDE)
1DEBUGFLAGS = -g #-DMDC_DEBUG #-E
4DEBUGFLAGS = -g #-DMDC_DEBUG #-E
5DEBUGFLAGS = -g #-DMDC_DEBUG #-E
1OPTIMIZEFLAGS = #-O2
4OPTIMIZEFLAGS = #-O2
5OPTIMIZEFLAGS = #-O2
1OPTIONFLAGS = -D${OS} #-ansi -Wall
4OPTIONFLAGS = -D${OS} #-ansi -Wall
5OPTIONFLAGS = -D${OS} -D_REENTRANT #-ansi -Wall
CFLAGS = $(${OSVER}DEBUGFLAGS) $(${OSVER}OPTIMIZEFLAGS) \
$(${OSVER}OPTIONFLAGS)
LDFLAGS = -static
ODBCLIBS = -I../odbc/dlls -lodbc
LIBS = -lm
SCCSFLAGS = -d$(PROJPATH)
SCCSGETFLAGS =
ifeq ($(ZPU_BUILD),)
BASE =
else
BASE = zpu-elf-
endif
CC = $(BASE)gcc
LD = $(BASE)gcc
AS = $(BASE)as
AR = $(BASE)ar
CP = $(BASE)objcopy
DUMP = $(BASE)objdump
RANLIB = $(BASE)ranlib
# Suffixes where interested in for this project.
#
.SUFFIXES:
.SUFFIXES: .o .c .h
# Our way of making an object file.
#
.c.o:
$(PURIFY) $(CC) $(INCLUDEDIR) $(CFLAGS) -c $<
# All, ie: all programs to be built
#
all:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Use 'build' command to make LIBSDD library."
libsdd: Begin \
libsdd.a \
End
# How to clean up the directory... make it look pretty!
#
clean: Begin \
DoClean \
End
# How to perform an installation of the resultant software.
#
install: Begin \
DoInstall \
End
#
# Pre-make start sequence.
#
Begin:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Operation commencing @ `date`"
@echo
#
# Post-make completion sequence.
#
End:
@echo
@echo "Completed @ `date`"
# Perform all cleanup operations to ensure future builds occur
# with completeness.
#
DoClean:
rm -f *.o *.bak *.a *.BAK *.sav core
# Perform installation of software as per spec.
#
DoInstall:
# Build the virtual data warehouse project Server
# Data-source Driver library.
#
libsdd.a: sdd_java.o sdd_scmd.o sdd_ftpx.o sdd_sybc.o
$(AR) rcv libsdd.a sdd_java.o sdd_scmd.o sdd_ftpx.o \
sdd_sybc.o
#libsdd.a: sdd_java.o sdd_scmd.o sdd_ftpx.o sdd_aupl.o
# $(AR) rcv libsdd.a sdd_java.o sdd_scmd.o sdd_ftpx.o sdd_aupl.o
sdd_java.o: sdd.h sdd_java.h
sdd_odbc.o: sdd.h sdd_odbc.h
sdd_scmd.o: sdd.h sdd_scmd.h
sdd_ftpx.o: sdd.h sdd_ftpx.h
sdd_sybc.o: sdd.h sdd_sybc.h
sdd_aupl.o: sdd.h sdd_aupl.h

174
SDD/build Executable file
View File

@@ -0,0 +1,174 @@
#!/bin/csh
#******************************************************************************
#* Product: ##### ###### ###### # ### ######
#* # # # # # # # # # #
#* # # # # # # # # #
#* ##### # # # # # # ######
#* # # # # # # # # #
#* # # # # # # # # # #
#* ##### ###### ###### ####### ####### ### ######
#*
#* File: build
#* Description: Build file for making different versions of the Server
#* Data-source Driver library.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
# Work out architecture we are compiling on..
#
setenv ARCH `uname -s`
setenv ARCH ${ARCH}`uname -r | cut -c1`
# Work out arguments and decide on actions from there.
#
if( $#argv > 0 ) then
switch("$argv[1]")
case "save":
make -f Makefile clean
sccs delta SCCS
exit 0
case "zpu":
setenv ARCH 'ZPU'
set makecmd="libsdd"
breaksw
case "install":
echo "Nothing to install, drivers specific to VDWD."
exit 0
default:
# If the command is not one this script recognises then pass on to
# the makefile.
#
set makecmd="$argv[1]"
endsw
else
set makecmd="libsdd"
endif
# Build according to parameter supplied.
#
switch ($ARCH)
case "SunOS4":
setenv OS "SUNOS"
setenv OSVER 4
echo "SunOS operating system build"
if( ! -r .sunos ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .sunos
chmod 777 .sunos
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libsdd.a ) then
\rm -f ${OSVER}lib/libsdd.a
ranlib ./libsdd.a
\mv -f libsdd.a ${OSVER}lib
endif
breaksw
case "SunOS5":
setenv OS "SOLARIS"
setenv OSVER 5
echo "Solaris operating system build"
if( ! -r .solaris ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .solaris
chmod 777 .solaris
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libsdd.a ) then
\rm -f ${OSVER}lib/libsdd.a
\mv -f libsdd.a ${OSVER}lib
endif
breaksw
case "Linux2":
case "Linux4":
setenv OS "LINUX"
setenv OSVER 1
echo "Linux operating system build"
echo ""
if( ! -r .linux ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .linux
chmod 777 .linux
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libsdd.a ) then
\rm -f ${OSVER}lib/libsdd.a
\mv -f libsdd.a ${OSVER}lib
endif
breaksw
case "ZPU":
setenv OS "ZPU"
setenv OSVER 1
echo "ZPU operating system build"
echo ""
if( ! -r .zpu ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .zpu
chmod 777 .zpu
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile ZPU_BUILD=1 $makecmd
set result = $status
endif
if( $result == 0 && -r libsdd.a ) then
\rm -f ${OSVER}lib/libsdd.a
\mv -f libsdd.a ${OSVER}lib
endif
breaksw
default:
echo "Unknown architecture, cannot build library..."
breaksw
endsw

159
SDD/sdd.h Executable file
View File

@@ -0,0 +1,159 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd.h
* Description: Server Data-source Driver library driver global header file
* for all library drivers.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_H
#define SDD_H
/* Bring in the MDC Library global definitions header file as we need to
* know about SERVICEDETAILS.
*/
#include <mdc.h>
/* Define any default values common to all drivers.
*/
#define DEF_COLSEP "|"
#define DEF_PADCHR " "
/* Define return types.
*/
#define SDD_OK 0 /* Success reture code */
#define SDD_FAIL -1 /* Fail return code */
/* Define driver sub-commands.
*/
#define SDD_ABORT 'A' /* Abort command */
#define SDD_EXIT 'E' /* Exit command */
/* System command module commands.
*/
#define SDD_CMD_DEL 'D' /* Perform a delete on D host */
#define SDD_CMD_EXEC 'X' /* Execute a cmd on the local system */
#define SDD_CMD_EXEC_TIMED 'T' /* Execute a cmd on local system @ Time */
#define SDD_CMD_MOVE 'M' /* Perform a rename/move on D host */
#define SDD_CMD_READ 'R' /* Perform a read operation D -> Client */
#define SDD_CMD_WRITE 'W' /* Perform a write operation D <- Client */
/* FTP sub-commands.
*/
#define SDD_FTPX_RCV 'R' /* FTP Receive a File command */
#define SDD_FTPX_XMIT 'X' /* FTP Transmit a File command */
#define SDD_FTPX_REN 'M' /* FTP Rename a File command */
/* Database (Sybase, ODBC) sub-commands).
*/
#define SDD_LIST_DB 'F' /* List all database names on data source */
#define SDD_LIST_COLS 'G' /* List all column names on data source */
#define SDD_LIST_TABLES 'H' /* List all tables names on data source */
#define SDD_RUNSQL 'R' /* Execute an SQL statement */
/* Audio sub-commands.
*/
#define SDD_PLAY_Z 'Z' /* Play a compressed audio file */
/* Define driver data return sub-commands.
*/
#define SDD_DATABLOCK 'D' /* Data is one block out of many blocks */
#define SDD_ENDBLOCK 'E' /* Data is last block in series */
/* Define error return codes which are embedded into returned error messages
* for the user to decipher.
*/
#define SDD_EMSG_MEMORY "D0001"
#define SDD_EMSG_SQLLOAD "D0002"
#define SDD_EMSG_SQLSYNTAX "D0003"
#define SDD_EMSG_SQLRUNERR "D0004"
#define SDD_EMSG_FETCHHEAD "D0005"
#define SDD_EMSG_FETCHROW "D0006"
#define SDD_EMSG_SENDROW "D0007"
#define SDD_EMSG_ABORTRCVD "D0008"
#define SDD_EMSG_SRCINIT "D0009"
#define SDD_EMSG_BADLOGIN "D0010"
#define SDD_EMSG_BADDBASE "D0011"
#define SDD_EMSG_BADREQ "D0012"
#define SDD_EMSG_BADCMD "D0013"
#define SDD_EMSG_BADPATH "D0014"
#define SDD_EMSG_BADARGS "D0015"
#define SDD_EMSG_BADTIME "D0016"
#define SDD_EMSG_BADEXEC "D0017"
#define SDD_EMSG_BADEXIT "D0018"
#define SDD_EMSG_BADFREE "D0019"
#define SDD_EMSG_NOTYI "D0020"
#define SDD_EMSG_BADBLOCKSZ "D0021"
#define SDD_EMSG_FILEERROR "D0022"
#define SDD_EMSG_BADFILE "D0023"
/* JAVA Driver.
*/
int java_InitService( SERVICEDETAILS *, UCHAR * );
int java_CloseService( UCHAR * );
int java_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void java_ProcessOOB( UCHAR );
/* ODBC Driver.
*/
int odbc_InitService( SERVICEDETAILS *, UCHAR * );
int odbc_CloseService( UCHAR * );
int odbc_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void odbc_ProcessOOB( UCHAR );
/* System Command Driver.
*/
int scmd_InitService( SERVICEDETAILS *, UCHAR * );
int scmd_CloseService( UCHAR * );
int scmd_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void scmd_ProcessOOB( UCHAR );
/* FTP Driver.
*/
int ftpx_InitService( SERVICEDETAILS *, UCHAR * );
int ftpx_CloseService( UCHAR * );
int ftpx_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void ftpx_ProcessOOB( UCHAR );
/* SYBASE Driver.
*/
int sybc_InitService( SERVICEDETAILS *, UCHAR * );
int sybc_CloseService( UCHAR * );
int sybc_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void sybc_ProcessOOB( UCHAR );
/* Audio Player Driver.
*/
int aupl_InitService( SERVICEDETAILS *, UCHAR * );
int aupl_CloseService( UCHAR * );
int aupl_ProcessRequest( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void aupl_ProcessOOB( UCHAR );
#endif /* SDD_H */

522
SDD/sdd_aupl.c Executable file
View File

@@ -0,0 +1,522 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_aupl.c
* Description: Server Data-source Driver library driver to handle playback
* of 16bit Stereo Audio WAV file to the DSP circuitry of
* an underlying sound card.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1997-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define SDD_AUPL_C
/* Bring in local specific header files.
*/
#include "sdd.h"
#include "sdd_aupl.h"
/******************************************************************************
* Function: _AUPL_GetStrArg
* Description: Function to scan an input buffer and extract a string based
* argument.
*
* Returns: SDD_FAIL- Couldnt obtain argument.
* SDD_OK - Argument obtained.
******************************************************************************/
int _AUPL_GetStrArg( UCHAR *snzDataBuf, /* I: Input buffer */
int nDataLen, /* I: Len of data */
UCHAR *szArg, /* I: Arg to look for */
UCHAR **pszPath ) /* O: Pointer to argument */
{
/* Local variables.
*/
int nCmpLen;
int nPos;
int nReturn = SDD_FAIL;
UCHAR *szFunc = "_AUPL_GetStrArg";
/* Go through the input buffer looking for 'szArg' within the
* input buffer. If it exists, then note the position just after it
* as this contains the string argument.
*/
for(nPos=0, nCmpLen=strlen(szArg); nPos < nDataLen; nPos++)
{
/* If a match occurs, then setup the pointer to correct location.
*/
if(strncmp(&snzDataBuf[nPos], szArg, nCmpLen) == 0)
{
/* Make sure that the match is not a sub-match as some of the
* variables we are scanning for are similar.
*/
if( (nPos == 0) ||
(nPos > 0 && snzDataBuf[nPos-1] == '\0') ||
(nPos > 0 && isspace(snzDataBuf[nPos-1])) )
{
nPos += nCmpLen;
break;
}
}
}
/* If the pointer did not reach the end of the buffer then we have
* located a valid name.
*/
if(nPos < nDataLen)
{
/* Setup the callers pointer to point to the correct location
* in the buffer.
*/
*pszPath = &snzDataBuf[nPos];
nReturn=SDD_OK;
}
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: _AUPL_ValidatePath
* Description: Function to validate the existence of a path.
*
* Returns: SDD_FAIL- Couldnt validate PATH.
* SDD_OK - PATH validated.
******************************************************************************/
int _AUPL_ValidatePath( UCHAR *pszPath ) /* I: Path to validate */
{
/* Local variables.
*/
int nReturn = SDD_FAIL;
UCHAR *szFunc = "_AUPL_ValidatePath";
struct stat sStat;
/* Test the path to ensure its valid.
*/
if( (stat(pszPath, &sStat) == -1) ||
((sStat.st_mode & S_IFDIR) == 0) )
{
nReturn=SDD_FAIL;
} else
{
nReturn=SDD_OK;
}
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: _AUPL_ValidateFile
* Description: Function to validate the existence of a file or to validate
* that a file can be created.
*
* Returns: SDD_FAIL- Couldnt obtain Filename or validate it.
* SDD_OK - Filename obtained and validated.
******************************************************************************/
int _AUPL_ValidateFile( UCHAR *pszPath, /* I: Path to file */
UCHAR *pszFile, /* I: File to validate */
UINT nWriteFlag ) /* I: Read = 0, Write = 1 */
{
/* Local variables.
*/
int nReturn = SDD_FAIL;
UCHAR szTmpBuf[MAX_TMPBUFLEN];
UCHAR *szFunc = "_AUPL_ValidateFile";
struct stat sStat;
FILE *fpTest;
/* Concatenate the file and path together, ready to perform a test.
*/
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
sprintf(szTmpBuf, "%s//%s", pszPath, pszFile);
#endif
#if defined(_WIN32)
sprintf(szTmpBuf, "%s%c%s", pszPath, 0x5c, pszFile);
#endif
/* Is the file to be created?
*/
if(nWriteFlag == TRUE)
{
/* Test the file by trying to create it, see if the underlying OS
* can perform this operation.
*/
if((fpTest=fopen(szTmpBuf, "w")) != NULL)
{
/* Close and remove the file we created, not needed yet.
*/
fclose(fpTest);
unlink(szTmpBuf);
nReturn = SDD_OK;
} else
{
nReturn = SDD_FAIL;
}
} else
{
/* Test the file to ensure that it exists and is readable.
*/
if( (stat(szTmpBuf, &sStat) == -1) ||
((sStat.st_mode & S_IFREG) == 0) )
{
nReturn=SDD_FAIL;
} else
{
nReturn=SDD_OK;
}
}
/* Return result code to caller.
*/
return(nReturn);
}
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
/******************************************************************************
* Function: _AUPL_PlayZ
* Description: Function to play a compressed audio file. Method of attach
* is to launch a child which is the actual decompressor, this
* feeds data back via the stdout of the child to our stdin. The
* data is then buffered in a round robin fashion and fed to the
* audio DSP hardware.
*
* Returns: SDD_FAIL- Command failed during execution.
* SDD_OK - Command executed successfully.
******************************************************************************/
int _AUPL_PlayZ( UCHAR *pszAudioPath, /* I: Path to Audio File */
UCHAR *pszAudioFile, /* I: Audio Filename */
int (*fSendDataCB)(UCHAR *, UINT),
/* I: Func for returning data */
UCHAR *szErrMsg ) /* O: Error message generated */
{
/* Local variables.
*/
int nChar;
int nEnd = FALSE;
int nNdx;
int nResult;
/* int nRetBufSize; */
int nReturn = SDD_OK;
UCHAR *pszTmpBuf;
/* UCHAR *pszRetBuf; */
UCHAR *szFunc = "_AUPL_Exec";
FILE *fpStdIn;
FILE *fpStdOut;
/* Allocate memory for return buffer.
if((pszRetBuf=(UCHAR *)malloc(nRetBufSize)) == NULL)
{
return(SDD_FAIL);
}
*/
/* Concatenate the decompressors file name plus the path and filename of
* the audio file to enable the decompression of the audio file to go
* ahead.
*/
nNdx=strlen(AUPL.szDecompExec)+strlen(pszAudioPath)+strlen(pszAudioFile)+10;
if((pszTmpBuf=(UCHAR *)malloc(nNdx)) == NULL)
{
return(SDD_FAIL);
}
sprintf(pszTmpBuf, "%s %s//%s", AUPL.szDecompExec, pszAudioPath,
pszAudioFile);
/* Execute the program as a child with its stdout connected to a read
* stream such that we can capture its output.
*/
if((fpStdIn=popen(pszTmpBuf, "r")) == NULL)
{
/* Build up an error message to indicate that the decompression
* command failed.
*/
sprintf(szErrMsg, "%s: Failed to de-compress file (%s//%s).",
SDD_EMSG_BADEXEC, pszAudioPath, pszAudioFile);
/* Set exit code to indicate failure.
*/
nReturn = SDD_FAIL;
} else
if((fpStdOut=popen(AUPL.szAudioPlayer, "w")) == NULL)
{
/* Build up an error message to indicate that the Audio Player
* command failed.
*/
sprintf(szErrMsg, "%s: Failed to start Audio Player.",
SDD_EMSG_BADEXEC);
/* Set exit code to indicate failure.
*/
nReturn = SDD_FAIL;
}
while((nChar=fgetc(fpStdIn)) != EOF)
{
fputc(nChar, fpStdOut);
}
/* Close the Decompressor and get its exit code.
*/
nResult=pclose(fpStdIn);
/* Close the Audio Player and get its exit code.
*/
nResult=pclose(fpStdOut);
/* Free up allocated memory block.
*/
free(pszTmpBuf);
/* Return result code to caller.
*/
return(nReturn);
}
#endif
/******************************************************************************
* Function: aupl_InitService
* Description: Entry point which initialises the driver into a defined state.
* It is mandatory that this function is called before any other
* in order for the driver to function correctly. The caller
* provides it with two types of data, 1) A structure containing
* data for it to use in initialising itself, 2) a pointer to a
* buffer which the driver uses to place an error message should
* it not be able to complete initialisation.
*
* Returns: SDD_FAIL- An error occurred in initialising the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver initialised successfully.
******************************************************************************/
int aupl_InitService( SERVICEDETAILS *sServiceDet, /* I: Init data */
UCHAR *szErrStr ) /* O: Error message */
{
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *szFunc = "aupl_InitService";
/* Setup any required constants, variables etc.
*/
strcpy(AUPL.szAudioPlayer, AUPL_AUDIO_PLAYER);
strcpy(AUPL.szDecompExec, AUPL_DECOMPRESSOR);
/* Log if debugging switched on.
*/
Lgr(LOG_MESSAGE, szFunc, "AUPL Driver: Initialised:");
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: aupl_CloseService
* Description: Entry point which performs a drive closedown. The closedown
* procedure ensure that the driver returns to a virgin state
* (ie.like at power up) so that InitService can be called again.
*
* Returns: SDD_FAIL- An error occurred in closing the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver successfully closed.
******************************************************************************/
int aupl_CloseService( UCHAR *szErrMsg ) /* O: Error message if failed */
{
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *szFunc = "aupl_CloseService";
/* Log if debugging switched on.
*/
Lgr(LOG_MESSAGE, szFunc, "AUPL Driver: Closed.");
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: aupl_ProcessRequest
* Description: Entry point into driver to initiate the driver into
* processing a request. A data block is passed as a parameter
* to the driver which represents a request with relevant
* parameters. The data within the structure is only relevant
* to the original client and this driver code.
*
* Returns: SDD_FAIL- An error occurred within the driver whilst trying to
* process the request, see error text.
* SDD_OK - Request processed successfully.
******************************************************************************/
int aupl_ProcessRequest( UCHAR *snzDataBuf, /* I: Input data */
int nDataLen, /* I: Len of data */
int (*fSendDataCB)(UCHAR *, UINT),
/* I: CB to send reply*/
UCHAR *szErrMsg ) /* O: Error text */
{
/* Static variables.
*/
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *pszAudioFile;
UCHAR *pszAudioPath;
UCHAR *szFunc = "aupl_ProcessRequest";
/* If the request block doesnt contain any data, something went wrong
* somewhere?
*/
if(nDataLen <= 1)
{
sprintf(szErrMsg,
"%s: Illegal request, has size of %dBytes",
SDD_EMSG_BADREQ, nDataLen);
return(SDD_FAIL);
}
/* If we have a PLAY_Z command, then extract relevant information from
* buffer.
*/
if(snzDataBuf[0] == SDD_PLAY_Z)
{
/* Locate the path argument and validate it.
*/
if(_AUPL_GetStrArg(&snzDataBuf[1], nDataLen-1, AUPL_AUDIOPATH,
&pszAudioPath) == SDD_FAIL||
_AUPL_ValidatePath(pszAudioPath) == SDD_FAIL)
{
sprintf(szErrMsg, "%s: Invalid PATH to Audio File provided",
SDD_EMSG_BADPATH);
return(SDD_FAIL);
}
/* Locate the Audio File Name argument and validate it.
*/
if(_AUPL_GetStrArg(&snzDataBuf[1], nDataLen-1, AUPL_AUDIOFILE,
&pszAudioFile) == SDD_FAIL ||
_AUPL_ValidateFile(pszAudioPath, pszAudioFile, FALSE) == SDD_FAIL)
{
sprintf(szErrMsg, "%s: Invalid Audio Filename provided",
SDD_EMSG_BADFILE);
return(SDD_FAIL);
}
}
/* First byte of the request data block indicates actions required, so
* decipher it.
*/
switch(snzDataBuf[0])
{
case SDD_PLAY_Z:
/* Log if debugging switched on.
*/
Lgr(LOG_DEBUG, szFunc,
"AUPL Driver: Req to execute Play Compressed File");
Lgr(LOG_DEBUG, szFunc,
"File Details: Path=%s, File=%s", pszAudioPath, pszAudioFile);
/* Execute the function. The final exit status dictates wether the
* command was a success or failure.
*/
if(_AUPL_PlayZ(pszAudioPath, pszAudioFile, fSendDataCB,
szErrMsg) == SDD_FAIL)
{
return(SDD_FAIL);
}
break;
default:
sprintf(szErrMsg,
"%s: Illegal request in request buffer (%x)",
SDD_EMSG_BADREQ, snzDataBuf[0]);
return(SDD_FAIL);
}
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: aupl_ProcessOOB
* Description: Entry point into driver to process an out of band command
* that may or may not be relevant to current state of
* operation. The task of this function is to decipher the
* command and act on it immediately, ie. a cancel command
* would abort any ProcessRequest that is in process and
* clean up.
*
* Returns: No returns.
******************************************************************************/
void aupl_ProcessOOB( UCHAR nCommand ) /* I: OOB Command */
{
/* Local variables.
*/
/* Decipher command and perform actions accordingly.
*/
switch(nCommand)
{
/* Request to abort current ProcessRequest command and return daemon
* to a waiting-for-request state.
*/
case SDD_ABORT:
break;
/* Request to close down and exit.
*/
case SDD_EXIT:
break;
default:
break;
}
/* Return to caller.
*/
return;
}

71
SDD/sdd_aupl.h Executable file
View File

@@ -0,0 +1,71 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_aupl.h
* Description: Server Data-source Driver library driver header file for
* the audio player driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_AUPL_H
#define SDD_AUPL_H
/* Definitions for constants, configurable options etc.
*/
#define AUPL_AUDIOPATH "PATH="
#define AUPL_AUDIOFILE "FILE="
#define AUPL_DECOMPRESSOR "/home/vdwd/bin/zcat"
#define AUPL_AUDIO_PLAYER "/home/vdwd/bin/play"
/* Definitions for maxims and defaults etc.
*/
#define MAX_AUDIOPLAYER_LEN sizeof(AUPL_AUDIO_PLAYER)
#define MAX_DECOMPRESSOR_LEN sizeof(AUPL_DECOMPRESSOR)
/* Structure for variables needed within this module.
*/
typedef struct {
UCHAR szAudioPlayer[MAX_AUDIOPLAYER_LEN+1];
UCHAR szDecompExec[MAX_DECOMPRESSOR_LEN+1];
} AUPL_DRIVER;
/* Allocate global variables by instantiating the above structure.
*/
static AUPL_DRIVER AUPL;
/* Prototypes of internal functions, not seen by any outside module.
*/
int _AUPL_GetStrArg( UCHAR *, int, UCHAR *, UCHAR ** );
int _AUPL_ValidatePath( UCHAR * );
int _AUPL_ValidateFile( UCHAR *, UCHAR *, UINT );
#if defined(SOLARIS) || defined(SUNOS)
int _AUPL_PlayZ(UCHAR *, UCHAR *, int(*)(UCHAR *, UINT), UCHAR * );
#endif
#endif /* SDD_AUPL_H */

2178
SDD/sdd_ftpx.c Executable file

File diff suppressed because it is too large Load Diff

126
SDD/sdd_ftpx.h Executable file
View File

@@ -0,0 +1,126 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_ftpx.h
* Description: Server Data-source Driver library driver header file for
* the system command execution driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_FTPX_H
#define SDD_FTPX_H
/* Define FTP response codes require by this module.
*/
#define FTP_RESPONSE_NONE 0
#define FTP_RESPONSE_DATASTART 150
#define FTP_RESPONSE_CWDOK 200
#define FTP_RESPONSE_CONNECTED 220
#define FTP_RESPONSE_GOODBYE 221
#define FTP_RESPONSE_DATAEND 226
#define FTP_RESPONSE_PASSIVE 227
#define FTP_RESPONSE_PWDOK 230
#define FTP_RESPONSE_CMDOK 250
#define FTP_RESPONSE_USEROK 331
#define FTP_RESPONSE_RENFROK 350
#define FTP_RESPONSE_BADSEQ 503
#define FTP_RESPONSE_PWDFAIL 530
#define FTP_RESPONSE_CMDFAIL 550
#define FTP_REQUIRE_NOTHING 0
#define FTP_REQUIRE_RESPONSE 1
/* Definitions for maxims etc.
*/
#define MAX_RETURN_BUF 2048+1
#define MAX_FTP_FILENAME 256
#define MAX_FTP_BUF_SIZE 65536
#define MAX_TMP_BUF_SIZE 1024
/* Definitions for constants, configurable options etc.
*/
#define FTP_DATA "DATA="
#define FTP_END "END="
#define FTP_SRCFILE "SRCFILE="
#define FTP_DSTFILE "DSTFILE="
#define FTP_MODE "MODE="
#define FTP_SRCPATH "SRCPATH="
#define FTP_DSTPATH "DSTPATH="
#define FTP_ASCII_MODE 0
#define FTP_BINARY_MODE 1
#define FTP_ASCII "ASCII"
#define FTP_BINARY "BINARY"
#define FTP_CONNECT_TIME 10000
#define DEF_FTP_SERVICE_NAME "ftp"
#define DEF_FTP_BUF_SIZE 65536
#define DEF_FTP_BUF_INCSIZE 65536
#define DEF_FTP_XMIT_SIZE 1024
#define DEF_SRV_START_PORT 10000
#define DEF_SRV_END_PORT 15000
/* Structure for variables internal to this driver module.
*/
typedef struct {
UINT nPIChanId; /* Comms identifier for PI channel */
UINT nPIDataBufLen; /* Max len of snzPIDataBuf */
UINT nPIDataBufPos; /* Position locator in snzPIDataBuf */
UINT nPIResponseCode; /* Response code on the PI channel */
UCHAR *snzPIDataBuf; /* Buffer for incoming confirmations */
UINT nDTPChanId; /* Comms identifier for DTP channel */
UINT nDTPConnected; /* DTP channel connected, TRUE=connected */
ULNG lDTPIPaddr; /* IP address of the DTP server */
UINT nDTPPortNo; /* Port of the DTP server */
FILE *fDataFile; /* Data I/O stream for FTP file */
} FTPX_DRIVER;
/* Allocate any global variables needed within this module.
*/
static FTPX_DRIVER FTPX;
/* Prototypes of internal functions, not seen by any outside module.
*/
int _FTPX_GetStrArg( UCHAR *, int, UCHAR *, UCHAR ** );
int _FTPX_GetMode( UCHAR *, int );
int _FTPX_GetWriteData( UCHAR *, int, FILE *, int *, UCHAR * );
int _FTPX_PutReadData( FILE *, int (*)(UCHAR *, UINT), UCHAR * );
void _FTPX_PIDataCB( UINT, UCHAR *, UINT );
void _FTPX_PICtrlCB( int, ... );
void _FTPX_DTPDataCB( UINT, UCHAR *, UINT );
void _FTPX_DTPCtrlCB( int, ... );
int _FTPX_PISendCmd( UCHAR *, UINT *, UCHAR * );
int _FTPX_PIGetDTPResponse( void );
int _FTPX_PISendDTPCmd( UCHAR *, UINT *, UCHAR * );
int _FTPX_SetMode( UINT, UCHAR * );
int _FTPX_SetCwd( UCHAR *, UCHAR * );
int _FTPX_FTPInit( UCHAR *, UCHAR *, UCHAR *, UCHAR * );
int _FTPX_FTPClose( UCHAR * );
int _FTPX_FTPRenFile( UCHAR *, UCHAR *, UCHAR *, UCHAR * );
int _FTPX_FTPRcvFile( UCHAR *, UCHAR *, UCHAR *, UINT, UCHAR * );
int _FTPX_FTPXmitFile( UCHAR *, UCHAR *, UCHAR *, UINT, UCHAR * );
#endif /* SDD_FTPX_H */

199
SDD/sdd_java.c Executable file
View File

@@ -0,0 +1,199 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_java.c
* Description: Server Data-source Driver library driver to handle java
* connectivity.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
/* Indicate that we are a C module for any header specifics.
*/
#define SDD_JAVA_C
/* Bring in local specific header files.
*/
#include "sdd.h"
#include "sdd_java.h"
/******************************************************************************
* Function: java_InitService
* Description: Entry point which initialises the driver into a defined state.
* It is mandatory that this function is called before any other
* in order for the driver to function correctly. The caller
* provides it with two types of data, 1) A structure containing
* data for it to use in initialising itself, 2) a pointer to a
* buffer which the driver uses to place an error message should
* it not be able to complete initialisation.
*
* Returns: SDD_FAIL- An error occurred in initialising the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver initialised successfully.
******************************************************************************/
int java_InitService( SERVICEDETAILS *sServiceDet, /* I: Init data */
UCHAR *szErrStr ) /* O: Error message */
{
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *szFunc = "java_InitService";
/* Log if debugging switched on.
*/
Lgr(LOG_MESSAGE, szFunc, "Java Driver: Initialised:");
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: java_CloseService
* Description: Entry point which performs a drive closedown. The closedown
* procedure ensure that the driver returns to a virgin state
* (ie.like at power up) so that InitService can be called again.
*
* Returns: SDD_FAIL- An error occurred in closing the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver successfully closed.
******************************************************************************/
int java_CloseService( UCHAR *szErrMsg ) /* O: Error message if failed */
{
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *szFunc = "java_CloseService";
/* Log if debugging switched on.
*/
Lgr(LOG_MESSAGE, szFunc, "Java Driver: Closed.");
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: java_ProcessRequest
* Description: Entry point into driver to initiate the driver into
* processing a request. A data block is passed as a parameter
* to the driver which represents a request with relevant
* parameters. The data within the structure is only relevant
* to the original client and this driver code.
*
* Returns: SDD_FAIL- An error occurred within the driver whilst trying to
* process the request, see error text.
* SDD_OK - Request processed successfully.
******************************************************************************/
int java_ProcessRequest( UCHAR *snzDataBuf, /* I: Input data */
int nDataLen, /* I: Len of data */
int (*fSendDataCB)(UCHAR *, UINT),
/* I: CB to send reply*/
UCHAR *szErrMsg ) /* O: Error text */
{
/* Local variables.
*/
int nReturn = SDD_OK;
UCHAR *szFunc = "java_ProcessRequest";
/* If the request block doesnt contain any data, something went wrong
* somewhere??
*/
if(nDataLen <= 1)
{
sprintf(szErrMsg,
"%s: Illegal request, has size of %dBytes",
SDD_EMSG_BADREQ, nDataLen);
return(SDD_FAIL);
}
/* First byte of the request data block indicates actions required, so
* decipher it.
*/
switch(snzDataBuf[0])
{
default:
sprintf(szErrMsg,
"%s: Illegal command in request buffer (%x)",
SDD_EMSG_BADCMD, snzDataBuf[0]);
return(SDD_FAIL);
}
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: java_ProcessOOB
* Description: Entry point into driver to process an out of band command
* that may or may not be relevant to current state of
* operation. The task of this function is to decipher the
* command and act on it immediately, ie. a cancel command
* would abort any ProcessRequest that is in process and
* clean up.
*
* Returns: No returns.
******************************************************************************/
void java_ProcessOOB( UCHAR nCommand ) /* I: OOB Command */
{
/* Local variables.
*/
/* Decipher command and perform actions accordingly.
*/
switch(nCommand)
{
/* Request to abort current ProcessRequest command and return daemon
* to a waiting-for-request state.
*/
case SDD_ABORT:
break;
/* Request to close down and exit.
*/
case SDD_EXIT:
break;
default:
break;
}
/* Return to caller.
*/
return;
}

42
SDD/sdd_java.h Executable file
View File

@@ -0,0 +1,42 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_java.h
* Description: Server Data-source Driver library driver header file for
* java driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_JAVA_H
#define SDD_JAVA_H
/* Definitions for maxims etc.
*/
#endif /* SDD_JAVA_H */

1671
SDD/sdd_odbc.c Executable file

File diff suppressed because it is too large Load Diff

80
SDD/sdd_odbc.h Executable file
View File

@@ -0,0 +1,80 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_odbc.h
* Description: Server Data-source Driver library driver header file for
* odbc driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_ODBC_H
#define SDD_ODBC_H
/* Definitions for maxims etc.
*/
#define MAX_DSN_DESCR_LEN 255
#define MAX_TABLE_DESCR_LEN 255
/* Definitions for constants, configurable options etc.
*/
#define ODBC_COLFILTER "COLUMN="
#define ODBC_DBNAME "DBNAME="
#define ODBC_TABLENAME "TABLENAME="
/* Structure for variables internal to this driver module.
*/
typedef struct {
UINT nAbortPending; /* An abort is pending */
UCHAR szUserName[MAX_USERNAMELEN]; /* Name of user that this */
/* module will use when */
/* connecting to data source. */
UCHAR szPassword[MAX_PASSWORDLEN]; /* Password that this module */
/* will use when connecting */
/* to data source. */
UCHAR szServer[MAX_SERVERNAMELEN]; /* Name of Data Source server */
UCHAR szDatabase[MAX_DBNAMELEN]; /* Name of Data Source data */
/* base. */
HENV hEnv; /* Environment buffer for ODBC*/
HDBC hDbc; /* ODBC connection handle */
} ODBC_DRIVER;
/* Allocate any global variables needed within this module.
*/
static ODBC_DRIVER ODBC;
/* Prototypes of internal functions, not seen by any outside module.
*/
void _ODBC_LogODBCError( HSTMT );
int _ODBC_GetArg( UCHAR *, UCHAR *, int, UCHAR ** );
int _ODBC_RunSql( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
int _ODBC_ListDB( int (*)(UCHAR *, UINT), UCHAR * );
int _ODBC_ListTables( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
int _ODBC_ListCols( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
#endif /* SDD_ODBC_H */

1282
SDD/sdd_scmd.c Executable file

File diff suppressed because it is too large Load Diff

87
SDD/sdd_scmd.h Executable file
View File

@@ -0,0 +1,87 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_scmd.h
* Description: Server Data-source Driver library driver header file for
* the system command execution driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_SCMD_H
#define SDD_SCMD_H
/* Definitions for constants, configurable options etc.
*/
#define SCMD_ASCII "ASCII"
#define SCMD_ARGS "ARGS="
#define SCMD_BINARY "BINARY"
#define SCMD_CMD "COMMAND="
#define SCMD_DATA "DATA="
#define SCMD_END "END="
#define SCMD_MODE "MODE="
#define SCMD_BUFSIZE "BUFSIZE="
#define SCMD_TIME "TIME="
#define SCMD_SRCPATH "SRCPATH="
#define SCMD_DSTPATH "DSTPATH="
#define SCMD_SRCFILE "SRCFILE="
#define SCMD_DSTFILE "DSTFILE="
#define SCMD_ASCIIMODE 0
#define SCMD_BINMODE 1
/* Definitions for maxims and defaults etc.
*/
#define DEF_RETURN_BUF_SIZE 2048
#define DEF_RETURN_MODE SCMD_BINMODE
#define MAX_MODE_SIZE 6
#define MAX_FILENAME_LEN 128
#define MIN_RETURN_BUF_SIZE 1
#define MAX_RETURN_BUF_SIZE 65536
/* Structure for variables needed within this module.
*/
typedef struct {
UINT nRetBufSize; /* Return buffer transmit size */
UINT nRetMode; /* Return Transmit mode 1=B, 0=A */
} SCMD_DRIVER;
/* Allocate global variables by instantiating the above structure.
*/
static SCMD_DRIVER SCMD;
/* Prototypes of internal functions, not seen by any outside module.
*/
int _SCMD_GetStrArg( UCHAR *, int, UCHAR *, UCHAR ** );
int _SCMD_ValidatePath( UCHAR * );
int _SCMD_ValidateFile( UCHAR *, UCHAR *, UINT );
int _SCMD_ValidateTime( UCHAR *, ULNG * );
#if defined(SOLARIS) || defined(SUNOS)
int _SCMD_Exec(int, UCHAR *, UCHAR *, UCHAR *, ULNG, int(*)(UCHAR *, UINT), UCHAR * );
#endif
#endif /* SDD_SCMD_H */

1204
SDD/sdd_sybc.c Executable file

File diff suppressed because it is too large Load Diff

85
SDD/sdd_sybc.h Executable file
View File

@@ -0,0 +1,85 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_sybc.h
* Description: Server Data-source Driver library driver header file for
* sybc driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_SYBC_H
#define SDD_SYBC_H
/* Definitions for maxims, defaults etc.
*/
#define DEF_APPNAME "sdd_sybc"
#define DEF_LINELEN 1024
#define MAX_SYBC_COLNAME 256
#define MAX_SYBC_DBNAME 256
#define MAX_SYBC_TABLENAME 256
#define MAX_SYBC_TYPENAME 256
/* Definitions for constants, configurable options etc.
*/
#define SYBC_COLFILTER "COLUMN="
#define SYBC_DBNAME "DBNAME="
#define SYBC_TABLENAME "TABLENAME="
/* Structure for variables internal to this driver module.
*/
typedef struct {
UINT nAbortPending; /* An abort is pending */
UCHAR szUserName[MAX_USERNAMELEN]; /* Name of user that this */
/* module will use when */
/* connecting to data source. */
UCHAR szPassword[MAX_PASSWORDLEN]; /* Password that this module */
/* will use when connecting */
/* to data source. */
UCHAR szServer[MAX_SERVERNAMELEN]; /* Name of Data Source server */
UCHAR szDatabase[MAX_DBNAMELEN]; /* Name of Data Source data */
/* base. */
DBPROCESS *dbProc; /* Process handle into sybase */
LOGINREC *sLoginRec; /* Login record for making */
/* and maintaining connection */
/* with sybase */
} SYB_DRIVER;
/* Allocate any global variables needed within this module.
*/
static SYB_DRIVER SYB;
/* Prototypes of internal functions, not seen by any outside module.
*/
int _SYBC_GetArg( UCHAR *, UCHAR *, int, UCHAR ** );
int _SYBC_RunSql( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
int _SYBC_ListDB( int (*)(UCHAR *, UINT), UCHAR * );
int _SYBC_ListTables( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
int _SYBC_ListCols( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
#endif /* SDD_SYBC_H */

157
SDD/templates/sdd_xxxx.c Executable file
View File

@@ -0,0 +1,157 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_xxxx.c
* Description: Server Data-source Driver library driver to handle xxxx
* connectivity.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
/* Indicate that we are a C module for any header specifics.
*/
#define SDD_xxxx_C
/* Bring in local specific header files.
*/
#include "sdd.h"
#include "sdd_xxxx.h"
/******************************************************************************
* Function: xxxx_InitService
* Description: Entry point which initialises the driver into a defined state.
* It is mandatory that this function is called before any other
* in order for the driver to function correctly. The caller
* provides it with two types of data, 1) A structure containing
* data for it to use in initialising itself, 2) a pointer to a
* buffer which the driver uses to place an error message should
* it not be able to complete initialisation.
*
* Returns: SDD_FAIL- An error occurred in initialising the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver initialised successfully.
******************************************************************************/
int xxxx_InitService( SERVICEDETAILS *sServiceDet, /* I: Init data */
UCHAR *szErrStr ) /* O: Error message */
{
/* Local variables.
*/
int nReturn = SDD_OK;
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: xxxx_CloseService
* Description: Entry point which performs a drive closedown. The closedown
* procedure ensure that the driver returns to a virgin state
* (ie.like at power up) so that InitService can be called again.
*
* Returns: SDD_FAIL- An error occurred in closing the driver and an
* error message is stored in szErrStr.
* SDD_OK - Driver successfully closed.
******************************************************************************/
int xxxx_CloseService( UCHAR *szErrMsg ) /* O: Error message if failed */
{
/* Local variables.
*/
int nReturn = SDD_OK;
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: xxxx_ProcessRequest
* Description: Entry point into driver to initiate the driver into
* processing a request. A data block is passed as a parameter
* to the driver which represents a request with relevant
* parameters. The data within the structure is only relevant
* to the original client and this driver code.
*
* Returns: SDD_FAIL- An error occurred within the driver whilst trying to
* process the request, see error text.
* SDD_OK - Request processed successfully.
******************************************************************************/
int xxxx_ProcessRequest( UCHAR *snzDataBuf, /* I: Input data */
int nDataLen, /* I: Len of data */
int (*fSendDataCB)(), /* I: CB to send reply*/
UCHAR *szErrMsg ) /* O: Error text */
{
/* Local variables.
*/
int nReturn = SDD_OK;
/* Return result code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: xxxx_ProcessOOB
* Description: Entry point into driver to process an out of band command
* that may or may not be relevant to current state of
* operation. The task of this function is to decipher the
* command and act on it immediately, ie. a cancel command
* would abort any ProcessRequest that is in process and
* clean up.
*
* Returns: No returns.
******************************************************************************/
void xxxx_ProcessOOB( UINT nCommand ) /* I: OOB Command */
{
/* Local variables.
*/
/* Decipher command and perform actions accordingly.
*/
switch(nCommand)
{
/* Request to abort current ProcessRequest command and return daemon
* to a waiting-for-request state.
*/
case SDD_ABORT:
break;
default:
break;
}
/* Return to caller.
*/
return;
}

42
SDD/templates/sdd_xxxx.h Executable file
View File

@@ -0,0 +1,42 @@
/******************************************************************************
* Product: ##### ###### ###### # ### ######
* # # # # # # # # # #
* # # # # # # # # #
* ##### # # # # # # ######
* # # # # # # # # #
* # # # # # # # # # #
* ##### ###### ###### ####### ####### ### ######
*
* File: sdd_xxxx.h
* Description: Server Data-source Driver library driver header file for
* xxxx driver.
* Version: %I%
* Dated: %D%
* Copyright: P.D.Smart, 1996-2019
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef SDD_xxxx_H
#define SDD_xxxx_H
/* Definitions for maxims etc.
*/
#endif /* SDD_xxxx_H */

3
VDW/1bin/RunForLinuxClient Executable file
View File

@@ -0,0 +1,3 @@
#! /bin/csh
/dvlp/VDW/1bin/vdwd -m 2 -l /dvlp/VDW/log/`hostname`.log &

5
VDW/4bin/RunForSunOSClient Executable file
View File

@@ -0,0 +1,5 @@
#! /bin/csh
setenv LD_LIBRARY_PATH /dvlp/third/ilog/views/lib/sparc_4_4.0:/dvlp/third/contrib/SunOS:/usr/motif/lib:/usr/openwin/lib:/dvlp/odbc/dlls:/dvlp2/sybase/syb1002_SunOS4/lib:/usr/ucblib
setenv SYBASE /home/sybase
/dvlp/VDW/4bin/vdwd -m 0 > /dvlp/VDW/log/`hostname`.log &

4
VDW/5bin/Run Executable file
View File

@@ -0,0 +1,4 @@
#! /bin/csh
setenv LD_LIBRARY_PATH /usr/motif/lib:/usr/openwin/lib:/home/psmart/dvlp/odbc/dlls:/apps/sybase/lib:/usr/ucblib
/home/psmart/dvlp/VDW/5bin/vdwd -m 3 > /tmp/`hostname`.log &

4
VDW/5bin/RunForSolarisClient Executable file
View File

@@ -0,0 +1,4 @@
#! /bin/csh
setenv LD_LIBRARY_PATH /dvlp/third/ilog/views/lib/sparc_4_4.0:/dvlp/third/contrib/SunOS:/usr/motif/lib:/usr/openwin/lib:/dvlp/odbc/dlls:/dvlp2/sybase/syb1002_SunOS5/lib:/usr/ucblib
/dvlp/VDW/5bin/vdwd -m 0 > /dvlp/VDW/log/`hostname`.log &

154
VDW/Makefile Executable file
View File

@@ -0,0 +1,154 @@
#******************************************************************************
#* Product: # # ###### # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # ###### ## ##
#*
#* File: Makefile
#* Description: Build description file for the Virtual Data Warehouse
#* Daemon.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
TITLE = "Virtual Data Warehouse Daemon"
COPYRIGHT = "(C) P.D.Smart, %D%, Vers %I%"
PROJ =
PURIFY = #purify -best-effort -follow-child-processes=yes
PROJPATH = ../VDW
GNUINCLUDE = #-I/apps/gnu/$(ARCH)/include
MDCINCLUDE = -I../MDC
SDDINCLUDE = -I../SDD
UXINCLUDE = -I../ux
INCLUDEDIR = -I. $(UXINCLUDE) $(MDCINCLUDE) $(SDDINCLUDE) $(GNUINCLUDE)
1DEBUGFLAGS = -g #-DMDC_DEBUG #-E
4DEBUGFLAGS = -g #-DMDC_DEBUG #-E
5DEBUGFLAGS = -g #-DMDC_DEBUG #-E
1OPTIMIZEFLAGS = #-O2
4OPTIMIZEFLAGS = #-O2
5OPTIMIZEFLAGS = #-O2
1OPTIONFLAGS = -D${OS} #-ansi -Wall
4OPTIONFLAGS = -D${OS} #-ansi -Wall
5OPTIONFLAGS = -D${OS} -D_REENTRANT #-ansi -Wall
CFLAGS = $(${OSVER}DEBUGFLAGS) $(${OSVER}OPTIMIZEFLAGS) \
$(${OSVER}OPTIONFLAGS)
LDFLAGS = #-static
MDCLIBS = -L../MDC/${OSVER}lib -lmdc
ODBCLIBS = -L../odbc/dlls -lodbc
SDDLIBS = -L../SDD/${OSVER}lib -lsdd
1SYBLIBS =
4SYBLIBS = -L/apps/sybase/lib -lsybdb
5SYBLIBS = -L/apps/sybase/lib -lsybdb
UXLIBS = -L../ux/${OSVER}lib -lux
1LIBS = -lm
4LIBS = -lm
5LIBS = -L/usr/ucblib -lsocket -lnsl -lucb #-liberty -lucb
LIBS = $(MDCLIBS) $(SDDLIBS) $(UXLIBS) $(${OSVER}SYBLIBS) $(${OSVER}LIBS)
SCCSFLAGS = -d$(PROJPATH)
SCCSGETFLAGS =
ifeq ($(ZPU_BUILD),)
BASE =
else
BASE = zpu-elf-
endif
CC = $(BASE)gcc
LD = $(BASE)gcc
AS = $(BASE)as
AR = $(BASE)ar
CP = $(BASE)objcopy
DUMP = $(BASE)objdump
RANLIB = $(BASE)ranlib
# Suffixes where interested in for this project.
#
.SUFFIXES:
.SUFFIXES: .o .c .h
# Our way of making an object file.
#
.c.o:
$(PURIFY) $(CC) $(INCLUDEDIR) $(CFLAGS) -c $<
# All, ie: all programs to be built
#
all:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Use 'build' command to make Virtual DataWarehouse Daemon."
VDWD: Begin \
vdwd \
End
# How to clean up the directory... make it look pretty!
#
clean: Begin \
DoClean \
End
# How to perform an installation of the resultant software.
#
install: Begin \
DoInstall \
End
#
# Pre-make start sequence.
#
Begin:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Operation commencing @ `date`"
@echo
#
# Post-make completion sequence.
#
End:
@echo
@echo "Completed @ `date`"
# Perform all cleanup operations to ensure future builds occur
# with completeness.
#
DoClean:
rm -f *.o *.bak *.a *.BAK *.sav core
# Perform installation of software as per spec.
#
DoInstall:
# Build the Virtual Data Warehouse Daemon Process.
#
vdwd: vdwd.o config.o
$(PURIFY) $(CC) $(LDFLAGS) -o vdwd \
vdwd.o \
config.o \
$(LIBS)
vdwd.o: vdwd.c vdwd.h
config.o: config.c vdwd.h

172
VDW/build Executable file
View File

@@ -0,0 +1,172 @@
#!/bin/csh
#******************************************************************************
#* Product: # # ###### # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # # # # # # #
#* # ###### ## ##
#*
#* File: VDWd
#* Description: Build description file for the Virtual Data Warehouse
#* daemon.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
# Work out architecture we are compiling on..
#
setenv ARCH `uname -s`
setenv ARCH ${ARCH}`uname -r | cut -c1`
# Work out arguments and decide on actions from there.
#
if( $#argv > 0 ) then
switch("$argv[1]")
case "save":
make -f Makefile clean
sccs delta SCCS
exit 0
case "install":
echo "Installing executables."
echo -n "Please enter 'vdwd' "
su - vdwd <<EOF
cp /dvlp/VDW/1bin/vdwd ~/bin/vdwd.1
cp /dvlp/VDW/4bin/vdwd ~/bin/vdwd.4
cp /dvlp/VDW/5bin/vdwd ~/bin/vdwd.5
EOF
exit 0
case "zpu":
setenv ARCH 'ZPU'
set makecmd="VDWD"
breaksw
default:
# If the command is not one this script recognises then pass on to
# the makefile.
#
set makecmd="$argv[1]"
endsw
else
set makecmd="VDWD"
endif
# Build according to parameter supplied.
#
switch ($ARCH)
case "SunOS4":
setenv OS "SUNOS"
setenv OSVER 4
echo "SunOS operating system build"
if( ! -r .sunos ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
touch .sunos
chmod 777 .sunos
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r vdwd ) then
\mv -f vdwd ${OSVER}bin
endif
breaksw
case "SunOS5":
setenv OS "SOLARIS"
setenv OSVER 5
echo "Solaris operating system build"
if( ! -r .solaris ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
touch .solaris
chmod 777 .solaris
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r vdwd ) then
\mv -f vdwd ${OSVER}bin
endif
breaksw
case "Linux2":
case "Linux4":
setenv OS "LINUX"
setenv OSVER 1
echo "Linux operating system build"
echo ""
if( ! -r .linux ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
touch .linux
chmod 777 .linux
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r vdwd ) then
\mv -f vdwd ${OSVER}bin
endif
breaksw
case "ZPU":
setenv OS "ZPU"
setenv OSVER 1
echo "ZPU operating system build"
echo ""
if( ! -r .zpu ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .zpu
chmod 777 .zpu
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile ZPU_BUILD=1 $makecmd
set result = $status
endif
if( $result == 0 && -r vdwd ) then
\mv -f vdwd ${OSVER}bin
endif
breaksw
default:
echo "Unknown architecture, cannot build library..."
breaksw
endsw

77
VDW/config.c Executable file
View File

@@ -0,0 +1,77 @@
/******************************************************************************
* Product: # # ###### # #
* # # # # # # # #####
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # ###### ## ## #####
*
* File: config.c
* Description: Configuration file for the Virtual Data Warehouse server Daemon
* process. This configuration file indicates which drivers the
* final built daemon knows about and provides entry points for
* the main vdwd code to call the drivers.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <mdc.h>
#include <sdd.h>
/* Indicate that we are a C module for any header specifics.
*/
#define VDWD_CONFIG_C
/* Bring in local specific header files.
*/
#include "vdwd.h"
/* Driver entry point configuration table.
* If you have a driver that you wish to embed within the daemon then enter
* it into this table. Ordering is not relevant as you must provide a driver
* type code which is known to both the client code and your driver.
*/
VDWD_DRIVERS Driver[]={
/* #if defined(SOLARIS) || defined(_WIN32)
# { SRV_ODBC, odbc_InitService, odbc_CloseService,
# odbc_ProcessRequest, odbc_ProcessOOB },
#endif */
#if defined(SOLARIS) || defined(SUNOS) || defined(_WIN32)
{ SRV_SYBASE, sybc_InitService, sybc_CloseService,
sybc_ProcessRequest, sybc_ProcessOOB },
#endif
{ SRV_JAVA, java_InitService, java_CloseService,
java_ProcessRequest, java_ProcessOOB },
{ SRV_SCMD, scmd_InitService, scmd_CloseService,
scmd_ProcessRequest, scmd_ProcessOOB },
{ SRV_FTPX, ftpx_InitService, ftpx_CloseService,
ftpx_ProcessRequest, ftpx_ProcessOOB },
/* # { SRV_AUPL, aupl_InitService, aupl_CloseService,
# aupl_ProcessRequest, aupl_ProcessOOB }, */
{ 0, NULL, NULL,
NULL, NULL }
};

726
VDW/vdwd.c Executable file
View File

@@ -0,0 +1,726 @@
/******************************************************************************
* Product: # # ###### # #
* # # # # # # # #####
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # ###### ## ## #####
*
* File: vdwd.c
* Description: The Virtual Data Warehouse server Daemon process. A daemon
* built upon the API libraries of MDC and the Server Data-source
* Driver libraries to provide a generic mechanism for
* retrieving data from any data source local to the daemon.
* The daemon is designed to interact with VDW client
* applications and serve their data needs.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <mdc.h>
#include <sdd.h>
/* Specials for Solaris.
*/
#if defined(SOLARIS) || defined(LINUX)
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define VDWD_C
/* Bring in local specific header files.
*/
#include "vdwd.h"
/******************************************************************************
* Function: GetConfig
* Description: Get configuration information from the OS or command line
* flags.
*
* Returns: VDWD_OK - Configuration obtained.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int GetConfig( int argc, /* I: CLI argument count */
UCHAR **argv, /* I: CLI argument contents */
char **envp, /* I: Environment variables */
UCHAR *szErrMsg ) /* O: Any generated error message */
{
/* Local variables.
*/
int nReturn = VDWD_OK;
FILE *fp;
UCHAR *szFunc = "GetConfig";
/* See if the user wishes to use a logfile?
*/
if( GetCLIParam(argc, argv, FLG_LOGFILE, T_STR, VDWD.szLogFile,
MAX_LOGFILELEN, FALSE) == R_OK )
{
/* Check to see if the filename is valid.
*/
if((fp=fopen(VDWD.szLogFile, "a")) == NULL)
{
sprintf(szErrMsg, "Cannot write to logfile (%s)", VDWD.szLogFile);
return(VDWD_FAIL);
}
/* Close the file as test complete.
*/
fclose(fp);
} else
{
/* Set logfile to a default, dependant on OS.
*/
strcpy(VDWD.szLogFile, DEF_LOGFILE);
}
/* Get log mode from command line.
*/
if(GetCLIParam(argc, argv, FLG_LOGMODE, T_INT, (UCHAR *)&VDWD.nLogMode,
0, 0) == R_OK)
{
/* Check the validity of the mode.
*/
if((VDWD.nLogMode < LOG_OFF || VDWD.nLogMode > LOG_FATAL) &&
VDWD.nLogMode != LOG_CONFIG)
{
sprintf(szErrMsg, "Illegal Logger mode (%d)", VDWD.nLogMode);
return(VDWD_FAIL);
}
} else
{
/* Setup default log mode.
*/
VDWD.nLogMode = LOG_MESSAGE;
}
/* Finished, get out!
*/
return( nReturn );
}
/******************************************************************************
* Function: VDWDInit
* Description: Initialisation of variables, functionality, communications
* and turning the process into a daemon.
*
* Returns: VDWD_OK - Initialised successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int VDWDInit( UCHAR *szErrMsg ) /* O: Generated error message */
{
/* Local variables.
*/
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
pid_t pid;
#endif
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
/* To start daemonisation, we must fork a child to detach from the
* parent process.
*/
if( (pid=fork()) < 0 )
{
/* Couldnt fork a child, so build up an error message and then exit
* with failure code.
*/
sprintf(szErrMsg, "Couldnt fork a child process for daemonisation");
return(VDWD_FAIL);
} else
if( pid != 0 )
{
/* As the parent, we exit here, cela-vie.
*/
exit(0);
}
/* OK, we are a child and are maturing to be a parent, so lets shed
* our childish skin....
*
* Firstly, become session leader..
*/
setsid();
/* Then ensure we are not hogging an NFS directory.
*/
chdir("/");
/* Setup the UMASK for known file creation state.
*/
umask(0);
#endif
/* Setup logger mode.
*/
Lgr(LOG_CONFIG, LGM_FLATFILE, VDWD.nLogMode, VDWD.szLogFile);
/* All done, lets get out.
*/
return(VDWD_OK);
}
/******************************************************************************
* Function: VDWDClose
* Description: Function to perform closure of all used resources within the
* module.
*
* Returns: VDWD_OK - Closed successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int VDWDClose( UCHAR *szErrMsg ) /* O: Generated error message */
{
/* Local variables.
*/
/* If the service hasnt been previously initialised, then there is no
* reason to close it down!!!
*/
if(VDWD.nServiceInitialised == TRUE)
{
/* Close the currently active service
*/
if(VDWDCloseService(VDWD.nActiveService, szErrMsg) == VDWD_FAIL)
return(VDWD_FAIL);
/* Tidy up variables.
*/
VDWD.nServiceInitialised = FALSE;
VDWD.nActiveService = 0;
}
/* Exit with success.
*/
return(VDWD_OK);
}
/******************************************************************************
* Function: VDWDSentToClient
* Description: Function to send data from this daemon back to the relevant
* client.
*
* Returns: SDD_OK - Data sent successfully.
* SDD_FAIL - Failure in sending data.
******************************************************************************/
int VDWDSendToClient( UCHAR *snzData, /* I: Data to send */
UINT nDataLen ) /* I: Length of data */
{
/* Local variables.
*/
int nReturn = SDD_OK;
/* Call the MDC library to transmit the data. If it fails, then just
* let the driver know by the return value.
*/
if(MDC_ReturnData(snzData, nDataLen) == MDC_FAIL)
{
nReturn = SDD_FAIL;
}
/* Return code to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: VDWDInitService
* Description: Function to call a given drivers initialisation function.
*
* Returns: VDWD_OK - Service was initialised successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int VDWDInitService( int nServiceType, /* I: Type of service*/
SERVICEDETAILS *sServiceDet, /* I: Service Data */
UCHAR *szErrMsg ) /* O: Error message */
{
/* Local variables.
*/
UINT nNdx;
int nReturn = VDWD_OK;
UCHAR *szFunc = "VDWDInitService";
/* Go through list of drivers and locate one that is of the correct type.
*/
for(nNdx=0; Driver[nNdx].nType != 0 && Driver[nNdx].nType != nServiceType;
nNdx++);
/* If we located the correct driver then we can perform initialisation.
*/
if(Driver[nNdx].nType == nServiceType)
{
/* If there is a registered Initialisation function for this driver
* then invoke it, else just return as though everything completed
* successfully.
*/
if(Driver[nNdx].InitService != NULL)
{
/* Perform the initialisation and set return code accordingly.
*/
if(Driver[nNdx].InitService(sServiceDet, szErrMsg) == SDD_FAIL)
{
nReturn = VDWD_FAIL;
}
} else
{
/* Log the fact that there is no driver.
*/
Lgr(LOG_DEBUG, szFunc,
"No registered InitService for Driver type (%d)", nServiceType);
}
} else
{
/* Build up an error message and exit.
*/
sprintf(szErrMsg,
"%s: Illegal service type (%d)",
VDWD_EMSG_BADSERVICE, nServiceType);
nReturn = VDWD_FAIL;
}
/* Finished, return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: VDWDCloseService
* Description: Function to call a given drivers closedown function.
*
* Returns: VDWD_OK - Service was closed successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int VDWDCloseService( int nServiceType, /* I: Type of service*/
UCHAR *szErrMsg ) /* O: Error message */
{
/* Local variables.
*/
UINT nNdx;
int nReturn = VDWD_OK;
UCHAR *szFunc = "VDWDCloseService";
/* Go through list of drivers and locate one that is of the correct type.
*/
for(nNdx=0; Driver[nNdx].nType != 0 && Driver[nNdx].nType != nServiceType;
nNdx++);
/* If we located the correct driver then we can perform a closedown.
*/
if(Driver[nNdx].nType == nServiceType)
{
/* If there is a registered Closedown function for this driver
* then invoke it, else just return as though everything completed
* successfully.
*/
if(Driver[nNdx].CloseService != NULL)
{
/* Perform the closedown and set return code accordingly.
*/
if(Driver[nNdx].CloseService(szErrMsg) == SDD_FAIL)
{
nReturn = VDWD_FAIL;
}
} else
{
/* Log the fact that there is no driver.
*/
Lgr(LOG_DEBUG, szFunc,
"No registered CloseService for Driver type (%d)",nServiceType);
}
} else
{
/* Build up an error message and exit.
*/
sprintf(szErrMsg,
"%s: Illegal service type (%d)",
VDWD_EMSG_BADSERVICE, nServiceType);
nReturn = VDWD_FAIL;
}
/* Finished, return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: VDWDProcessRequest
* Description: Function to call a given drivers function to process a
* service request.
*
* Returns: VDWD_OK - Request was processed successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int VDWDProcessRequest( int nServiceType, /* I: Type of service */
UCHAR *snzData, /* I: Data Buffer */
UINT nDataLen, /* I: Len of Data */
UCHAR *szErrMsg ) /* O: Error message */
{
/* Local variables.
*/
UINT nNdx;
int nReturn = VDWD_OK;
UCHAR *szFunc = "VDWDProcessRequest";
/* Go through list of drivers and locate one that is of the correct type.
*/
for(nNdx=0; Driver[nNdx].nType != 0 && Driver[nNdx].nType != nServiceType;
nNdx++);
/* If we located the correct driver then we can perform the request.
*/
if(Driver[nNdx].nType == nServiceType)
{
/* If there is a registered Process Request function for this driver
* then invoke it, else just return as though everything completed
* successfully.
*/
if(Driver[nNdx].ProcessRequest != NULL)
{
/* Call the driver function to process the request.
*/
if(Driver[nNdx].ProcessRequest(snzData, nDataLen, VDWDSendToClient,
szErrMsg) == SDD_FAIL)
{
nReturn=VDWD_FAIL;
}
} else
{
/* Log the fact that there is no driver.
*/
Lgr(LOG_DEBUG, szFunc,
"No registered ProcessRequest for Driver type (%d)",
nServiceType);
}
} else
{
/* Build up an error message and exit.
*/
sprintf(szErrMsg,
"%s: Illegal service type (%d)",
VDWD_EMSG_BADSERVICE, nServiceType);
nReturn = VDWD_FAIL;
}
/* Finished, return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: VDWDDataCallback
* Description: Function which is registered as a callback and is called
* every time data arrives from a new client.
*
* Returns: MDC_OK - Closed successfully.
* MDC_FAIL - Failure, see error message.
******************************************************************************/
int VDWDDataCallback( UCHAR *snzData, /* I: Buffer containing data */
int nDataLen, /* I: Length of data in buffer */
UCHAR *szErrMsg ) /* O: Error messages generated */
{
/* Local variables.
*/
SERVICEDETAILS *sServiceDet;
UCHAR *szFunc = "VDWDDataCallback";
/* Data has arrived from a connected client. We know for sure that we
* will only ever deal with one client, so its safe to make a lot of
* assumptions about the data path. In this function, we only need to
* decipher the data packet that we've been passed and dispatch it to
* the correct handler.
*/
/* First, check the length... it must be at least 1 byte!!
*/
if(nDataLen <= 0)
{
Lgr(LOG_DEBUG, szFunc, "Being called with %dByte packets", nDataLen);
return(MDC_FAIL);
}
/* Work out the type of packet that we've been passed by analysing the
* first byte.
*/
switch(snzData[0])
{
case MDC_ACK:
sprintf(szErrMsg,
"%s: Server being sent an ACK, illegal!!",
VDWD_EMSG_BADACK);
return(MDC_FAIL);
case MDC_NAK:
sprintf(szErrMsg,
"%s: Server being sent a NAK, illegal!!",
VDWD_EMSG_BADNAK);
return(MDC_FAIL);
case MDC_PREQ:
/* Has the service been initialised yet? If it hasnt, then we
* cant possibly pass a data block to the unknown.
*/
if(VDWD.nServiceInitialised == TRUE)
{
/* Try and process the given request.
*/
if(VDWDProcessRequest(VDWD.nActiveService, &snzData[1],
nDataLen-1, szErrMsg) == VDWD_FAIL)
{
return(MDC_FAIL);
}
} else
{
/* Just return an error message/code to indicate the problem.
*/
sprintf(szErrMsg,
"%s: No service initialised, data packet illegal!!!",
VDWD_EMSG_BADDATA);
return(MDC_FAIL);
}
break;
case MDC_CHANGE:
case MDC_INIT:
/* Is this the first initialisation call...? If it isnt then close
* the original service prior to initialising the new service.
*/
if(VDWD.nServiceInitialised == TRUE)
{
/* Close the service, exit if we cant, using provided error
* message.
*/
if(VDWDCloseService(VDWD.nActiveService, szErrMsg) == VDWD_FAIL)
return(MDC_FAIL);
/* Toggle the flag in case of failure.
*/
VDWD.nServiceInitialised = FALSE;
}
/* Extract the type of service by casting the provided data to
* a service block and then using the structure types.
*/
snzData++;
sServiceDet = (SERVICEDETAILS *)snzData;
VDWD.nActiveService=(UINT)sServiceDet->cServiceType;
/* Initialise the requested sevice.
*/
if(VDWDInitService(VDWD.nActiveService, sServiceDet, szErrMsg)
== VDWD_FAIL)
{
return(MDC_FAIL);
}
/* Set flag to indicate that service has been initialised.
*/
VDWD.nServiceInitialised = TRUE;
break;
default:
sprintf(szErrMsg,
"%s: Unknown Service Type (%x)",
VDWD_EMSG_BADSERVICE, snzData[0]);
return(MDC_FAIL);
}
/* Return any result codes to MDC library.
*/
return(MDC_OK);
}
/******************************************************************************
* Function: VDWDOOBCallback
* Description: Function to take action on out of band commands from the
* MDC layer. Out of band messages are generally commands which
* need to be actioned upon immediately, so they are passed up
* into the Drivers out of band processing function.
*
* Returns: No returns.
******************************************************************************/
void VDWDOOBCallback( UCHAR cCmd ) /* I: Command to action upon */
{
/* Local variables.
*/
UINT nNdx;
UCHAR *szFunc = "VDWDOOBCallback";
/* Has a service been initialised yet? If one hasnt, then there is no
* point in going further as OOB processing is only relevant to an
* intialised module.
*/
if(VDWD.nServiceInitialised == FALSE)
{
/* Log an error message and exit.
*/
Lgr(LOG_DEBUG, szFunc,
"Services not initialised, cannot process OOB (%x)",cCmd);
return;
}
/* Go through list of drivers and locate one that is of the correct type.
*/
for(nNdx=0; Driver[nNdx].nType != 0 &&
Driver[nNdx].nType != VDWD.nActiveService;
nNdx++);
/* If we located the correct driver then we can perform the request.
*/
if(Driver[nNdx].nType == VDWD.nActiveService)
{
/* Process out of band message according to type.
*/
switch(cCmd)
{
case MDC_ABORT:
/* Log message for debug purposes.
*/
Lgr(LOG_DEBUG, szFunc,
"ABORT Out Of Band message received, processing");
if(Driver[nNdx].ProcessOOB != NULL)
{
Driver[nNdx].ProcessOOB(SDD_ABORT);
} else
{
Lgr(LOG_DEBUG, szFunc,
"No registered ABORT OOB handler in driver");
}
break;
case MDC_EXIT:
/* Log message for debug purposes.
*/
Lgr(LOG_DEBUG, szFunc,
"EXIT Out Of Band message received, exitting");
if(Driver[nNdx].ProcessOOB != NULL)
{
Driver[nNdx].ProcessOOB(SDD_EXIT);
} else
{
Lgr(LOG_DEBUG, szFunc,
"No registered EXIT OOB handler in driver");
}
break;
default:
/* Build up an error message and exit.
*/
Lgr(LOG_DEBUG, szFunc, "Illegal command (%x)", cCmd);
break;
}
} else
{
/* Build up an error message and exit.
*/
Lgr(LOG_DEBUG, szFunc, "Called with no active service, cCmd=(%x)",cCmd);
}
/* Return to caller.
*/
return;
}
/******************************************************************************
* Function: main
* Description: Entry point into the Virtual Data Warehouse Daemon. Basic
* purpose is to invoke intialisation, enter the main program
* loop and finally tidy up and close down.
*
* Returns: 0 - Program completed successfully without errors.
* -1 - Program terminated with errors, see logged message.
******************************************************************************/
int main( int argc, /* I: Count of available arguments */
char **argv, /* I: Array of arguments */
char **envp ) /* I: Array of environment parameters */
{
/* Local variables.
*/
UCHAR szErrMsg[MAX_ERRMSG_LEN];
UCHAR *szFunc = "main";
/* Bring in any configuration parameters passed on the command line etc.
*/
if( GetConfig(argc, (UCHAR **)argv, envp, szErrMsg) == VDWD_FAIL )
{
printf( "%s\n"
"Usage: %s <parameters>\n"
"<parameters>: -l<LogFile Name>\n"
" -m<Logging Mode>\n",
szErrMsg, argv[0]);
}
/* Initialise variables, communications and become a daemon.
*/
if( VDWDInit(szErrMsg) == VDWD_FAIL )
{
/* Log an error message to indicate reason for failure.
*/
Lgr(LOG_DIRECT, szFunc, "%s: %s", argv[0], szErrMsg);
exit(-1);
}
/* Start the daemon running by passing control into the MDC library and
* letting it generate callbacks as events occur.
*/
if( MDC_Server(NULL, DEF_SERVICENAME, VDWDDataCallback,
VDWDOOBCallback ) == MDC_FAIL )
{
/* Problems within the MDC library, indicate error and get out.
*/
Lgr(LOG_DIRECT, szFunc, "%s: MDC_Server error, aborting..", argv[0]);
exit(-1);
}
/* Perform close down of used facilities ready for exit.
*/
if( VDWDClose(szErrMsg) == VDWD_FAIL )
{
/* Log an error message to indicate reason for failure.
*/
Lgr(LOG_DIRECT, szFunc, "%s: %s", argv[0], szErrMsg);
exit(-1);
}
/* Log off message.
*/
Lgr(LOG_DEBUG, szFunc, "Child daemon closing.");
/* All done, go bye bye's.
*/
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX)
exit;
#endif
#if defined(_WIN32)
return(0);
#endif
}

117
VDW/vdwd.h Executable file
View File

@@ -0,0 +1,117 @@
/******************************************************************************
* Product: # # ###### # #
* # # # # # # # #####
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # # # # # # # # #
* # ###### ## ## #####
*
* File: vdwd.h
* Description: Header file for declaration of structures, datatypes etc for
* the Virtual Data Warehouse Daemon.
* Version: %I%
* Dated: %D%
* Copyright: P.D.Smart, 1996-2019
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef VDWD_H
#define VDWD_H
/* Return type definitions.
*/
#define VDWD_OK 0
#define VDWD_FAIL 1
#define VDWD_EXIT 2
/* Definitions for maxims etc.
*/
#define MAX_ERRMSG_LEN 256
#define MAX_LOGFILELEN 256
/* Definitions for defaults.
*/
#define DEF_SERVICENAME "vdwd"
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(ZPU)
#define DEF_LOGFILE "/tmp/vdwd.log"
#endif
#if defined(_WIN32)
#define DEF_LOGFILE "\\VDWD.LOG"
#endif
/* Define command line flags.
*/
#define FLG_LOGFILE "-l"
#define FLG_LOGMODE "-m"
/* Define error return codes which are embedded into returned error messages
* for the user to decipher.
*/
#define VDWD_EMSG_BADSERVICE "V0001"
#define VDWD_EMSG_BADACK "V0002"
#define VDWD_EMSG_BADNAK "V0003"
#define VDWD_EMSG_BADDATA "V0004"
/* Structure to provide the interface between the VDW Daemon and its
* linked in driver modules. Provides entry points into the driver for the
* daemon.
*/
typedef struct {
int nType;
int (*InitService)( SERVICEDETAILS *, UCHAR * );
int (*CloseService)( UCHAR * );
int (*ProcessRequest)( UCHAR *, int, int (*)(UCHAR *, UINT), UCHAR * );
void (*ProcessOOB)( UCHAR );
} VDWD_DRIVERS;
/* Globals (yuggghhh!) for the VDW Daemon. They are contained within a
* structure so they are more manageable and readers can see immediately
* the variables scope.
*/
typedef struct {
int nActiveService;
UINT nLogMode;
UINT nServiceInitialised;
UCHAR szLogFile[MAX_LOGFILELEN];
} VDWD_GLOBALS;
/* Declare any globals required by the daemon, or any specifics to the
* C module.
*/
#if defined(VDWD_C)
static VDWD_GLOBALS VDWD={0, LOG_DEBUG, FALSE, ""};
extern VDWD_DRIVERS Driver[];
#endif
/* Prototypes for functions within VDWd
*/
int GetConfig( int, UCHAR **, char **, UCHAR * );
int VDWDInit( UCHAR * );
int VDWDClose( UCHAR * );
int VDWDInitService( int, SERVICEDETAILS *, UCHAR * );
int VDWDCloseService( int, UCHAR * );
int VDWDProcessRequest( int, UCHAR *, UINT, UCHAR * );
int VDWDSendToClient( UCHAR *, UINT );
int VDWDDataCallback( UCHAR *, int, UCHAR * );
void VDWDOOBCallback( UCHAR );
int main( int, char **, char ** );
#endif /* VDWD_H */

0
ux/.pure Executable file
View File

150
ux/Makefile Executable file
View File

@@ -0,0 +1,150 @@
#******************************************************************************
#* Product: # # # # # ### ######
#* # # # # # # # #
#* # # # # # # # #
#* # # # # # ######
#* # # # # # # # #
#* # # # # # # # #
#* ##### # # ####### ####### ### ######
#*
#* File: Makefile
#* Description: Build description file for UX lib.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1994-2019
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
TITLE = "UniX Library"
COPYRIGHT = "(C) P.D. Smart %D%, Version %I%"
PROJ =
PURIFY = #purify
PROJPATH = /users/bopropsm/ux
INCLUDEDIR = -I.
IM_INCLUDE = -I/usr/5include
1DEBUGFLAGS = -g # -DUX_DEBUG #-E
4DEBUGFLAGS = -g # -DUX_DEBUG #-E
5DEBUGFLAGS = -g # -DUX_DEBUG #-E
1OPTIMIZEFLAGS = #-O2
4OPTIMIZEFLAGS = #-O2
5OPTIMIZEFLAGS = #-O2
1OPTIONFLAGS = -D${OS} #-DUX_MONITOR #-ansi -Wall
4OPTIONFLAGS = -D${OS} #-DUX_MONITOR #-ansi -Wall
5OPTIONFLAGS = -D${OS} -D_REENTRANT
CFLAGS = $(${OSVER}DEBUGFLAGS) $(${OSVER}OPTIMIZEFLAGS) \
$(${OSVER}OPTIONFLAGS)
LDFLAGS = -static
SCCSFLAGS = -d$(PROJPATH)
SCCSGETFLAGS =
ifeq ($(ZPU_BUILD),)
BASE =
else
BASE = zpu-elf-
endif
CC = $(BASE)gcc
LD = $(BASE)gcc
AS = $(BASE)as
AR = $(BASE)ar
CP = $(BASE)objcopy
DUMP = $(BASE)objdump
RANLIB = $(BASE)ranlib
# Suffixes where interested in for this project.
#
.SUFFIXES:
.SUFFIXES: .o .c .h
# Our way of making an object file.
#
.c.o:
$(PURIFY) $(CC) $(INCLUDEDIR) $(CFLAGS) -c $<
# All, ie: all programs to be built
#
all:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Use 'build' command to make LIBUX library."
libux: Begin \
libux.a \
End
# How to clean up the directory... make it look pretty!
#
clean: Begin \
DoClean \
End
# How to perform an installation of the resultant software.
#
install: Begin \
DoInstall \
End
#
# Pre-make start sequence.
#
Begin:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Operation commencing @ `date`"
@echo
#
# Post-make completion sequence.
#
End:
@echo
@echo "Completed @ `date`"
# Perform all cleanup operations to ensure future builds occur with
# completeness.
#
DoClean:
rm -f *.o *.bak *.a *.BAK *.sav core
# Perform installation of software as per spec.
#
DoInstall:
# Build the UniX Library.
#
libux.a: ux_cli.o ux_cmprs.o ux_comms.o ux_lgr.o ux_linkl.o \
ux_mon.o ux_str.o ux_thrd.o
$(AR) rcv libux.a \
ux_cli.o ux_cmprs.o ux_comms.o ux_lgr.o \
ux_linkl.o ux_mon.o ux_str.o ux_thrd.o
ux_cli.o: ux_cli.c ux_comon.h ux_dtype.h ux_comms.h
ux_cmprs.o: ux_cmprs.c
ux_comms.o: ux_comms.c ux_comms.h ux_dtype.h ux_comon.h
ux_lgr.o: ux_lgr.c ux_comon.h ux_dtype.h ux_comms.h
ux_linkl.o: ux_linkl.c ux_comon.h ux_dtype.h ux_comms.h
ux_mon.o: ux_mon.c ux_mon.h ux_comon.h ux_dtype.h ux_comms.h
ux_str.o: ux_str.c ux_comon.h ux_dtype.h ux_comms.h
ux_thrd.o: ux_thrd.c ux_comon.h ux_dtype.h ux_comms.h

184
ux/build Executable file
View File

@@ -0,0 +1,184 @@
#!/bin/csh
#******************************************************************************
#* Product: # # # # # ### ######
#* # # # # # # # #
#* # # # # # # # #
#* # # # # # ######
#* # # # # # # # #
#* # # # # # # # #
#* ##### # # ####### ####### ### ######
#*
#* File: build
#* Description: Build description file for making different versions of the
#* UX library.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1994-2019
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
# Work out architecture we are compiling on..
#
setenv ARCH `uname -s`
setenv ARCH ${ARCH}`uname -r | cut -c1`
# Work out arguments and decide on actions from there.
#
if( $#argv > 0 ) then
switch("$argv[1]")
case "save":
make -f Makefile clean
sccs delta SCCS
exit 0
case "install":
echo "Installing libraries and header files."
echo -n "Please enter 'vdwd' "
su - vdwd <<EOF
cp /dvlp/ux/1lib/libux.a ~/1lib/.
cp /dvlp/ux/4lib/libux.a ~/4lib/.
cp /dvlp/ux/5lib/libux.a ~/5lib/.
cp /dvlp/ux/ux.h ~/include/.
cp /dvlp/ux/ux_dtype.h ~/include/.
cp /dvlp/ux/ux_comms.h ~/include/.
cp /dvlp/ux/ux_comon.h ~/include/.
EOF
exit 0
case "zpu":
setenv ARCH 'ZPU'
set makecmd="libux"
breaksw
default:
# If the command is not one this script recognises then pass on to
# the makefile.
#
set makecmd="$argv[1]"
endsw
else
set makecmd="libux"
endif
# Build according to parameter supplied.
#
switch ($ARCH)
case "SunOS4":
setenv OS "SUNOS"
setenv OSVER 4
echo "SunOS operating system build"
if( ! -r .sunos ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .sunos
chmod 777 .sunos
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libux.a ) then
\rm -f ${OSVER}lib/libux.a
ranlib ./libux.a
\mv -f libux.a ${OSVER}lib
endif
breaksw
case "SunOS5":
setenv OS "SOLARIS"
setenv OSVER 5
echo "Solaris operating system build"
if( ! -r .solaris ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .solaris
chmod 777 .solaris
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libux.a ) then
\rm -f ${OSVER}lib/libux.a
\mv -f libux.a ${OSVER}lib
endif
breaksw
case "Linux2":
case "Linux4":
setenv OS "LINUX"
setenv OSVER 1
echo "Linux operating system build"
echo ""
if( ! -r .linux ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .linux
chmod 777 .linux
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r libux.a ) then
\rm -f ${OSVER}lib/libux.a
\mv -f libux.a ${OSVER}lib
endif
breaksw
case "ZPU":
setenv OS "ZPU"
setenv OSVER 1
echo "ZPU operating system build"
echo ""
if( ! -r .zpu ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .zpu
chmod 777 .zpu
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile ZPU_BUILD=1 $makecmd
set result = $status
endif
if( $result == 0 && -r libux.a ) then
\rm -f ${OSVER}lib/libux.a
\mv -f libux.a ${OSVER}lib
endif
breaksw
default:
echo "Unknown architecture, cannot build library..."
breaksw
endsw

48
ux/ux.h Executable file
View File

@@ -0,0 +1,48 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux.h
* Description: Header file for declaration of structures, datatypes etc.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_H
#define UX_H
#include "ux_dtype.h"
#include "ux_comon.h"
#include "ux_comms.h"
#include "ux_cmprs.h"
#include "ux_mon.h"
/* Version Control.
*/
#define PROGRAM_VERSION "%I%"
#endif /* UX_H */

174
ux/ux_cli.c Executable file
View File

@@ -0,0 +1,174 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_cli.c
* Description: Unix or Windows Command Line Processing functions.
*
* Version: %I%
* Dated: %D%
* Author: P.D. Smart
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_CLI_C
/* Bring in specific header files.
*/
#include "ux.h"
/******************************************************************************
* Function: GetCLIParam
* Description: Get a Command Line Interface Parameter from the command line
* of the shell which started this program... Confusing!
* Returns: R_OK - Parameter obtained.
* R_FAIL - Parameter does not exist.
******************************************************************************/
int GetCLIParam( int nArgc, /* I: Argc or equiv */
UCHAR **Argv, /* IO: Argv or equiv */
UCHAR *szParm, /* I: Param flag to look for */
UINT nParmType, /* I: Type of param (ie int) */
UCHAR *pVar, /* O: Pointer to variable for parm */
UINT nVarLen, /* I: Length pointed to by pVar */
UINT nZapParam ) /* I: Delete argument after proc */
{
/* Local variables.
*/
int nNdx;
int nReturn = R_FAIL;
UCHAR *pArg = NULL;
/* Scan through the command line, seeing if the required flag exists.
*/
for(nNdx=1; nNdx < nArgc; nNdx++)
{
if(strcasecmp(Argv[nNdx], szParm) == 0)
{
/* Has the user provided a parameter?
*/
if( strlen(Argv[nNdx]) < strlen(szParm) )
{
pArg = Argv[nNdx]+strlen(Argv[nNdx]);
} else
if( nNdx+1 <= nArgc )
{
pArg = Argv[nNdx+1];
} else pArg = NULL;
break;
}
}
/* Found the required flag?
*/
if( nNdx != nArgc && pArg != NULL )
{
/* Convert the parameter into the required destination format.
*/
switch( nParmType )
{
case T_INT:
if(sscanf(pArg, "%d", (UINT *)pVar) == 1)
nReturn = R_OK;
break;
case T_STR:
if(sscanf(pArg, "%s", (UCHAR *)pVar) == 1)
nReturn = R_OK;
break;
case T_CHAR:
if(sscanf(pArg, "%c", (UCHAR *)pVar) == 1)
nReturn = R_OK;
break;
case T_LONG:
if(sscanf(pArg, "%ld", (ULNG *)pVar) == 1)
nReturn = R_OK;
break;
default:
break;
}
/* If the caller has requested that the command line argument
* be deleted for security purposes, delete!
*/
if(nZapParam == TRUE)
{
memset(pArg, '*', strlen(pArg));
}
} else
/* If a valid flag appeared, but it did not have an argument, then
* assume its a state flag, so set the var parameter to NULL but return
* success.
*/
if( nNdx != nArgc && pArg == NULL )
{
pVar = NULL;
nReturn = R_OK;
}
/* Finished, get out!!
*/
return( nReturn );
}

692
ux/ux_cmprs.c Executable file
View File

@@ -0,0 +1,692 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_cmprs.c
* Description: Routines to compress/decompress data. The basic code stems
* from a LINUX public domain lzw compression/decompression
* algorithm, basically tidied up a little as it looked awful and
* enhanced to allow embedding within programs. Eventually, a more
* hi-tech algorithm will be implemented, but for now, this
* lzw appears to have very high compression ratio's
* on text.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_CMPRS_C
/* Bring in specific header files.
*/
#include "ux.h"
#define LZSIZE 4096 /* Should stay < 32768 */
#define CLEAR 256 /* Clear Code */
#define REPEAT 257
#define START 258
static code Prefix, Prefix0, Index;
static int code_len, new_entry; /* For repeated strings */
static int bits, off, size;
static code *scode;
static byte *sbyte;
static unsigned int pcode, pbyte, length;
static int nInit = 0;
static int nNdx;
static unsigned short nEndian = 0xff00;
static unsigned char *pEndian = (unsigned char *)&nEndian;
static unsigned char *pC, cTmp;
code *PTable, *NTable;
byte *CTable;
/******************************************************************************
* Function: Compress
* Description: A generic function to compress a buffer of text.
* Returns: NULL - Memory problems.
* Memory buffer containing compressed copy of input.
******************************************************************************/
UCHAR *Compress( UCHAR *spInBuf, /* I: Buffer to be compressed. */
UINT *nLen ) /* IO: Length of dec/compressed buffer. */
{
/* Local variables.
*/
int nSize;
UINT nInLen = *nLen;
UINT nOutLen = nInLen+10;
UCHAR *spReturn = spInBuf;
UCHAR *spOut;
char *szFunc = "Compress";
/* If the input buffer is smaller than a given threshold then dont
* waste CPU trying to compress it.
*/
if(nInLen < MIN_COMPRESSLEN)
{
return(spInBuf);
}
/* Allocate a buffer to hold the compressed data.
*/
if((spOut=(UCHAR *)malloc(sizeof(USHRT) * nOutLen)) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes", nOutLen);
Errno = E_NOMEM;
return(NULL);
}
/* Compress the buffer.
*/
nSize=WLZW(spInBuf, (unsigned short *)&spOut[6], nInLen, nOutLen-4);
/* Could we compress it?
*/
if(nSize > 0 && (UINT)nSize < nInLen)
{
/* OK, add in the compressed id-byte and the original buffer size.
*/
spOut[0] = spOut[1] =0xff;
PutCharFromLong( &spOut[2], (ULNG)nInLen );
spReturn = spOut;
if(nLen != NULL) *nLen = nSize + 6;
/* Debugging code.
*/
#if defined(UX_DEBUG)
printf("Compressed from (%d) to (%d) bytes\n", nInLen, nSize);
#endif
} else
{
Lgr(LOG_DEBUG, szFunc, "Couldnt compress data (%d)", nSize);
if(nLen != NULL) *nLen = nInLen;
free(spOut);
}
/* Return buffer or NULL to caller.
*/
return(spReturn);
}
/******************************************************************************
* Function: Decompress
* Description: A generic function to de-compress a buffer to text.
* Returns: NULL - Memory problems.
* Memory buffer containing decompressed copy of input.
******************************************************************************/
UCHAR *Decompress( UCHAR *spInBuf, /* I: Buffer to be decompressed. */
UINT *nCmpLen ) /* IO: Length of comp/dec buffer */
{
/* Local variables.
*/
UINT nSize;
UINT nOutLen;
UINT nShift;
UCHAR *spTmp;
UCHAR *spReturn = spInBuf;
char *szFunc = "Decompress";
/* Is the input buffer in compressed format..? The first byte should
* contain the value 0xff if its compressed.
*/
if(spInBuf[0] == 0xff && spInBuf[1] == 0xff)
{
/* Extract the expanded size from the buffer.
*/
nOutLen = GetLongFromChar(&spInBuf[2]);
/* Allocate a buffer to hold the de-compressed data.
*/
if((spTmp=(UCHAR *)malloc(nOutLen+2)) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes", nOutLen);
Errno = E_NOMEM;
return(NULL);
}
/* Ensure that the data beings on a LONG boundary as the compression/
* Decompression works with integers/shorts.
*/
nShift=(int)((long)(&spInBuf[6]) % sizeof(long));
/* Shift the memory block onto a long boundary.
*/
memcpy(&spInBuf[6-nShift], &spInBuf[6], (*nCmpLen)-(6-nShift));
/* Decompress data.
*/
if((nSize=RLZW((unsigned short *)&spInBuf[6-nShift], spTmp,
(*nCmpLen)-6, nOutLen)) <= 0)
{
Lgr(LOG_WARNING,szFunc, "Couldnt Decompress data (%s)",nSize);
free(spTmp);
return(NULL);
}
/* Terminate string as this may just be a character string.
*/
spTmp[nOutLen] = '\0';
/* Setup pointer to new buffer containing decompressed data.
*/
spReturn = spTmp;
/* Update the callers length parameter to indicate buffers new
* length.
*/
*nCmpLen = nOutLen;
} else
{
/* The buffer is not compressed, terminate it in case its a character
* string. No need to update the callers lenght parameter as it
* has not changed.
*/
spInBuf[*nCmpLen] = '\0';
/* Debugging code.
*/
#if defined(UX_DEBUG)
printf("Buffer not compressed (%c, %x)\n", spInBuf[0], spInBuf[1]);
#endif
}
/* Return buffer or NULL to caller.
*/
return(spReturn);
}
/*
* LZW_init - Initialise compression routines.
*/
void LZW_init()
{
PTable = (code *) malloc(LZSIZE*sizeof(code));
NTable = (code *) malloc(LZSIZE*sizeof(code));
CTable = (byte *) malloc(LZSIZE*sizeof(byte));
}
/* Write Next Code */
static int WCode(code wcode)
{
/* Local variables.
*/
int todo;
pcode+=bits;
/* Quickly check output buffer size for insufficient compression.
*/
if((pcode>>3) > length)
return 0;
if((todo = bits+off-16)>=0)
{
*scode++ |= wcode>>todo;
*scode = wcode<<(16-todo);
off = todo;
} else
{
*scode |= wcode<<(-todo);
off += bits;
}
/* Finished, get out.
*/
return(1);
}
/* Read Next Code */
static short RCode(void)
{
/* Local variables.
*/
code rcode; /* 15 bits maximum, with LZSIZE=32768; never negative */
short todo;
if((todo = bits+off-16)>=0)
{
rcode = (*scode++)<<todo;
rcode |= (*scode)>>(16-todo);
off = todo;
} else
{
rcode = (*scode)>>(-todo);
off += bits;
}
rcode&=size-1;
return((short)rcode);
}
/* Initialization (R/W) */
static void InitTable(void)
{
bits = 8;
size = 256;
pbyte = pcode = off = 0;
memset(PTable, -1, LZSIZE*sizeof(code));
Index = START;
}
/* Initialization for decompression */
static void RInitTable(void)
{
/* Local variables.
*/
int i;
byte *p;
InitTable();
for(i = 0, p = CTable; i < CLEAR; i++)
*p++ = i;
}
/* Lookup Table */
static short LookUp(byte Car)
{
/* Local variables.
*/
code pi;
pi = PTable[Prefix];
while(((short)pi) != -1)
{
if(CTable[pi] == Car) return pi;
pi = NTable[pi];
}
/* No hit.
*/
return(-1);
}
/* byte is added to table and becomes prefix */
static int WAddPrefix(void)
{
/* Local variables.
*/
code pi;
pi = PTable[Prefix];
PTable[Prefix] = Index; /* Next entry */
NTable[Index] = pi;
CTable[Index++] = Prefix = Prefix0 = *sbyte;
/* Table full.
*/
if(Index == LZSIZE)
{
if(!WCode(CLEAR)) return 0;
Index = START;
memset(PTable, -1, LZSIZE*sizeof(code));
bits = 8;
size = 256;
} else
if(Index > size)
{
bits++;
size <<= 1;
}
/* Finished, get out.
*/
return(1);
}
static int Expand(code val)
{
/* Local variables.
*/
code p,q,r;
if(val > Index)
return -2;
q = -1;
PTable[Index] = Prefix;
do {
p = val;
/* Get previous
*/
while((p = PTable[(r = p)]) != q);
*sbyte++ = CTable[r];
/* Done; skip useless stuff
*/
if(++pbyte >= length)
return 0;
if(((short)q) == -1 && new_entry)
{
if(Index == LZSIZE) return -3;
CTable[Index++] = CTable[r];
new_entry = 0;
}
q = r;
} while(q != val);
Prefix = val;
/* Finished, get out.
*/
return(1);
}
int check_repeat(int len)
{
/* Local variables.
*/
int n = 0;
char *s;
char *s0;
/* Current string.
*/
s = sbyte;
/* Reference string.
*/
s0 = s - code_len;
while(code_len <= len && (n+1) < size)
{
if(memcmp(s0, s, code_len))
break;
/* Number of bytes left.
*/
len -= code_len;
/* Number of repeats.
*/
n++;
s += code_len;
}
/* Finished, get out!
*/
return(n);
}
/******************************************************************************
* Function: WLZW
* Description: Write or compress data in LZW format.
* Returns: 0 = Worthless CPU waste (No compression)
* -1 = General error
* -2 = Logical error
* -3 = Expand error
* >0 = OK/total length
******************************************************************************/
int WLZW( byte *si, /* I: Data for compression */
code *so, /* O: Compressed data */
int len, /* I: Length of data for compression */
int maxlen ) /* I: Maximum length of compressed data */
{
/* Local variables.
*/
code val;
int Repeat;
if(nInit == 0)
{
LZW_init();
nInit = 1;
}
scode = so;
*scode = 0;
sbyte = si;
length = maxlen;
InitTable();
Prefix = Prefix0 = *sbyte;
code_len = 0;
while(++pbyte<len)
{
/* Length of current string.
*/
code_len++;
/* at least 2 bytes.
*/
if(*(++sbyte) == Prefix0 && code_len > 1)
{
/* Check for string repeat. If positive, we are going to write
* 3 codes. Therefore, we need to filter small repeats.
*/
Repeat = check_repeat(len-pbyte);
/* Could do better.
*/
if(Repeat > 1)
{
/* At least 3 times (1+>2).
*/
WCode(REPEAT);
WCode(Repeat);
if(!WCode(Prefix))
return(0);
/* Total length of repeat.
*/
pbyte += code_len*Repeat;
if(pbyte >= len)
break;
/* Position of next byte.
*/
sbyte += code_len*Repeat;
}
}
/* Break in sequence.
*/
if(((short)(val=LookUp(*sbyte)))==-1)
{
/* Write to buffer.
*/
if(!WCode(Prefix))
return(0);
/* Car is new prefix.
*/
if(!WAddPrefix())
return(0);
code_len = 0;
} else
Prefix = val;
}
if(!WCode(Prefix))
return(0);
len = pcode/sizeof(code)/8;
if(pcode&(sizeof(code)*8-1))
len++;
len *= sizeof(code);
/* Portability issue, will change the code to be insensitive to
* little/big endian eventually.
*/
if(*pEndian == 0x00)
{
pC = (unsigned char *)so;
for(nNdx=0; nNdx < len; nNdx += 2, pC += 2)
{
cTmp = *pC;
*pC = *(pC+1);
*(pC+1) = cTmp;
}
}
return(len);
}
/* CLEAR Code Read */
static int RClear(void)
{
bits = 8;
size = 256;
Prefix = RCode();
*sbyte++ = Prefix;
if(++pbyte >= length)
return(0);
new_entry = 1;
Index = START;
bits++;
size = 512;
/* Finished, get out!
*/
return(1);
}
/******************************************************************************
* Function: RLZW
* Description: Read or de-compress data from LZW format.
* Returns: 0 = Worthless CPU waste (No compression)
* -1 = General error
* -2 = Logical error
* -3 = Expand error
* >0 = OK/total length
******************************************************************************/
int RLZW( code *si, /* I: Data to be decompressed */
byte *so, /* O: Decompressed data */
int silen, /* I: Compressed length */
int len ) /* I: Expected length of decompressed data. */
{
/* Local variables.
*/
code val;
int n;
/* Portability issue, will change the code to be insensitive to
* little/big endian eventually.
*/
if(*pEndian == 0x00)
{
pC = (unsigned char *)si;
for(nNdx=0; nNdx < silen; nNdx += 2, pC += 2)
{
cTmp = *pC;
*pC = *(pC+1);
*(pC+1) = cTmp;
}
}
if(nInit == 0)
{
LZW_init();
nInit = 1;
}
sbyte = so;
scode = si;
length = len;
RInitTable();
RClear();
for(;;)
{
val = RCode();
if(val == CLEAR)
{
if(!RClear())
break;
continue;
}
if(val == REPEAT)
{
/* # of repeats.
*/
len = RCode();
val = RCode(); /* code to expand */
do {
n = Expand(val);
} while(--len && n > 0);
} else
{
n = Expand(val);
if(Index >= size)
{
bits++;
size <<= 1;
}
/* Add new entry at next code.
*/
new_entry = 1;
}
if(n < 0)
return(n);
if(n == 0)
break;
}
/* Finished, get out!
*/
return(1);
}

49
ux/ux_cmprs.h Executable file
View File

@@ -0,0 +1,49 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_cmprs.h
* Description: General purpose compression routines.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_CMPRS_H
#define UX_CMPRS_H
/* Typedefs used within the module.
*/
typedef unsigned short code;
typedef unsigned char byte;
/* Define prototypes for functions globally available.
*/
int WLZW( byte *, code *, int, int );
int RLZW( code *, byte *, int, int );
#endif /* UX_CMPRS_H */

2399
ux/ux_comms.c Executable file

File diff suppressed because it is too large Load Diff

236
ux/ux_comms.h Executable file
View File

@@ -0,0 +1,236 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_comms.h
* Description: Generic communications routines.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_COMMS_H
#define UX_COMMS_H
#define SL_SINGLE_THREAD_ONLY
#define SL_THREAD_ONLY
/* Windows comms result values are different to unix, so define them
* here.
*/
#if defined(_WIN32)
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINVAL WSAEINVAL
#define EINPROGRESS WSAEINPROGRESS
#define EALREADY WSAEALREADY
#define ENOTSOCK WSAENOTSOCK
#define EDESTADDRREQ WSAEDESTADDRREQ
#define EMSGSIZE WSAEMSGSIZE
#define EPROTOTYPE WSAEPROTOTYPE
#define ENOPROTOOPT WSAENOPROTOOPT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#define EOPNOTSUPP WSAEOPNOTSUPP
#define EPFNOSUPPORT WSAEPFNOSUPPORT
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define EADDRINUSE WSAEADDRINUSE
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define ENETDOWN WSAENETDOWN
#define ENETUNREACH WSAENETUNREACH
#define ENETRESET WSAENETRESET
#define ECONNABORTED WSAECONNABORTED
#define ECONNRESET WSAECONNRESET
#define ENOBUFS WSAENOBUFS
#define EISCONN WSAEISCONN
#define ENOTCONN WSAENOTCONN
#define ESHUTDOWN WSAESHUTDOWN
#define ETOOMANYREFS WSAETOOMANYREFS
#define ETIMEDOUT WSAETIMEDOUT
#define ECONNREFUSED WSAECONNREFUSED
#define ELOOP WSAELOOP
#define EHOSTDOWN WSAEHOSTDOWN
#define EHOSTUNREACH WSAEHOSTUNREACH
#define EPROCLIM WSAEPROCLIM
#define EUSERS WSAEUSERS
#define EDQUOT WSAEDQUOT
#define ESTALE WSAESTALE
#define EREMOTE WSAEREMOTE
/* Getdtablesize is not implemented in windows, so we set a fixed value
* for the RLIMIT_NOFILE equivalent.
*/
#define MAX_WIN_RLIMIT 256
#endif
/* Defaults
*/
#define DEF_CHANID 1000 /* Starting internal comms chan Id */
#define DEF_BUFINCSIZE 65536 /* Default comms buffer increment */
#define DEF_INITRECVBUF 524288 /* Default size of comms receive buffer */
#define DEF_MAXBLOCKPERIOD 10000 /* Default max select sleep period in mS */
#define DEF_CONWAITPER 50 /* Default wait period for reconnect */
#define DEF_CONFAILPER 30000 /* Default wait period for a fail */
/* Communications framing characters.
*/
#define A_STX 0x02 /* Start of Text */
#define A_ETX 0x03 /* End of Text */
#define A_SYN 0x22 /* Synchronise */
/* Timer callback option flags.
*/
#define TCB_OFF 0 /* Disable callback */
#define TCB_FLIPFLOP 1 /* Callback toggles, not uniform in time */
#define TCB_ASTABLE 2 /* Callback toggles, uniform in time */
#define TCB_ONESHOT 3 /* Callback occurs only once */
/* Timer callback status flags.
*/
#define TCB_UP 128 /* Callback is active */
#define TCB_DOWN 129 /* Callback is in-active */
/* Socket/Line status flags.
*/
#define SSL_UP 128 /* Socket/Line is up */
#define SSL_DOWN 129 /* Socket/Line is down */
#define SSL_LISTENING 130 /* Socket is listening for connections */
#define SSL_FAIL 131 /* Socket/Line failure */
/* Connection type flags.
*/
#define STP_SERVER 'S' /* Connection is a server */
#define STP_CLIENT 'C' /* Connection is a client */
/* Communication callback control types. These are typically used when a
* socket, acting as a server port, receives a connection, or a client
* eventually connects to a server.
*/
#define SLC_NEWSERVICE 1 /* New service connection event */
#define SLC_CONNECT 2 /* New client connect event */
#define SLC_LINKDOWN 3 /* A Client link has gone down */
#define SLC_LINKFAIL 4 /* A link has failed and been removed */
/* Operating system specifics.
*/
#define SocketClose close
/* Structure to hold 16 bit CRC lookup values. For speed, the CRC algorithm
* has been constructed using lookup tables.
*/
typedef struct {
UCHAR cHiCRC; /* Hi Byte of CRC */
UCHAR cLoCRC; /* Lo Byte of CRC */
} SL_CRCTAB;
/* A structure to define and hold a timed callback event. A timed callback
* event is the invocation of a function after a certain period of time. The
* invocation can be single, multiple etc.
*/
typedef struct {
void (*nCallback)(); /* Function to call when timer expired */
UINT nOptions; /* Options controlling callback */
UINT nStatus; /* Status. Active or Inactive */
ULNG lTimeExpire; /* Time when callback is triggered */
ULNG lTimePeriod; /* Period inbetween triggers */
ULNG lCBData; /* Callback specific data */
} SL_CALLIST;
/* A structure to define and maintain a connection, either server of client
* with its opposite on another process.
*/
typedef struct {
UINT nChanId; /* Internal channel Id associated with link */
UINT nClose; /* Flag for sync socket closure */
UINT nForkForAccept; /* Fork a child prior to every accept on srv port */
UINT nOurPortNo; /* Port number where using */
UINT nRawMode; /* No prepackaging and post packaging of data */
UINT nRecvLen; /* Current number of bytes in receive buffer */
UINT nRecvBufLen; /* Current size of receive buffer */
UINT nServerPortNo; /* Port number of server service */
UINT nStatus; /* Status of link */
UINT nXmitLen; /* Total length of data in xmit buffer */
UINT nXmitPos; /* Pos in buffer for xmission */
int nSd; /* Socket descriptor */
ULNG lDownTimer; /* Amount of time a downed connection remains idle*/
ULNG lServerIPaddr; /* IP address of server */
UCHAR cCorS; /* (C) or (S)erver */
UCHAR *spRecvBuf; /* Flat, dynamic expand/shrink receive buffer */
UCHAR *spXmitBuf; /* Singular xmit buffer, to contain 1 packet */
UCHAR szServerName[MAX_SERVERNAME+1];/* Name of server */
void (*nDataCallback)(); /* Function to call with data */
void (*nCntrlCallback)(int, ...); /* Function to call with out-of-band info */
} SL_NETCONS;
/* Global variables for the Comms module.
*/
typedef struct {
LINKLIST *spHead; /* Head of LinkedList containing connections */
LINKLIST *spTail; /* Tail ... */
LINKLIST *spCBHead; /* Head of LinkedList containing timer callbacks */
LINKLIST *spCBTail; /* Tail ... */
UINT nCloseDown; /* Shutdown in progress flag */
UINT nSockKeepAlive; /* Time to keep socket alive */
} SL_GLOBALS;
/* Prototypes for functions internal to SocketLib module.
*/
UINT _SL_CalcCRC( UCHAR *, UINT );
UINT _SL_CheckCRC( UCHAR *, UINT );
int _SL_FdBlocking( int, int );
UINT _SL_GetPortNo( SL_NETCONS * );
int _SL_AcceptClient( UINT, SL_NETCONS *, SL_NETCONS ** );
int _SL_Close( SL_NETCONS *, UINT );
int _SL_ConnectToServer( SL_NETCONS * );
int _SL_ReceiveFromSocket( SL_NETCONS * );
int _SL_ProcessRecvBuf( SL_NETCONS * );
int _SL_ProcessWaitingPorts( ULNG );
ULNG _SL_ProcessCallbacks( void );
/* Prototypes to externally visible and usable functions.
*/
UCHAR *SL_HostIPtoString( ULNG );
int SL_GetIPaddr( UCHAR *, ULNG * );
int SL_GetService( UCHAR *, UINT * );
int SL_Init( UINT, UCHAR * );
int SL_Exit( UCHAR * );
void SL_PostTerminate( void );
UINT SL_GetChanId( ULNG );
int SL_RawMode( UINT, UINT );
int SL_AddServer( UINT, UINT, void (*)(), void (*)(int, ...) );
int SL_AddClient( UINT, ULNG, UCHAR *, void (*)(), void (*)(int, ...) );
int SL_AddTimerCB( ULNG, UINT, ULNG, void (*)() );
int SL_DelServer( UINT );
int SL_DelClient( UINT );
int SL_Close( UINT );
int SL_SendData( UINT, UCHAR *, UINT );
int SL_BlockSendData( UINT, UCHAR *, UINT );
int SL_Poll( ULNG );
int SL_Kernel( void );
#endif /* UX_COMMS_H */

114
ux/ux_comon.h Executable file
View File

@@ -0,0 +1,114 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_comon.h
* Description: General purpose library routines.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_COMMON_H
#define UX_COMMON_H
/* Definitions for Linked List sorting.
*/
#define SORT_NONE 0 /* No linklist sorting */
#define SORT_INT_UP 1 /* Linklist sorted incrementally on int */
#define SORT_INT_DOWN 2 /* Linklist sorted decrementally on int */
#define SORT_LONG_UP 3 /* Linklist sorted incrementally on long */
#define SORT_LONG_DOWN 4 /* Linklist sorted decrementally on long */
#define SORT_CHAR_UP 5 /* Linklist sorted on alpha string */
#define SORT_CHAR_DOWN 6 /* Linklist sorted in reverseo on alpha string*/
/* Logger definitions. Define's mode and level logger operates at.
*/
#define LOG_OFF 0 /* LEVEL: Logging off */
#define LOG_CONFIG 1 /* LEVEL: Logger being configured */
#define LOG_DEBUG 2 /* LEVEL: All debug messages and above */
#define LOG_WARNING 3 /* LEVEL: All warning messages and above */
#define LOG_MESSAGE 4 /* LEVEL: All information messages and above */
#define LOG_ALERT 5 /* LEVEL: All alert messages and above */
#define LOG_FATAL 6 /* LEVEL: All fatal messages */
#define LOG_DIRECT 7 /* LEVEL: Always log to stdout if logging on */
#define LGM_OFF 0 /* MODE: Logger switched off */
#define LGM_STDOUT 1 /* MODE: Logger logging to stdout */
#define LGM_FLATFILE 2 /* MODE: Logger logging to flat file */
#define LGM_DB 3 /* MODE: Logger logging to database */
#define LGM_ALL 4 /* MODE: Logger logging to all destinations */
/* Parser token flags. Identifies the type of token encountered in a parsing
* input stream.
*/
#define TOK_EOB 0 /* End of Buffer */
#define TOK_ALPHA 1 /* Token is an alphabetic word */
#define TOK_ALPHANUM 2 /* Token is an alphanumeric word */
#define TOK_STRING 3 /* Token is a complete string */
#define TOK_NUMERIC 4 /* Token is a numeric */
#define TOK_COMMENT 5 /* Token is a comment */
#define TOK_CHAR 6 /* Token is a character */
/* Define prototypes for functions globally available.
*/
int AddItem(LINKLIST **, LINKLIST **, int, UINT *, ULNG *, UCHAR *, void *);
int DelItem( LINKLIST **, LINKLIST **, void *, UINT *, ULNG *, UCHAR * );
void *FindItem( LINKLIST *, UINT *, ULNG *, UCHAR * );
void *StartItem( LINKLIST *, LINKLIST ** );
void *NextItem( LINKLIST ** );
int MergeLists( LINKLIST **, LINKLIST **, LINKLIST *, LINKLIST *, int );
int DelList( LINKLIST **, LINKLIST ** );
int SizeList( LINKLIST *, UINT * );
int PutCharFromLong( UCHAR *, ULNG );
int PutCharFromInt( UCHAR *, UINT );
ULNG GetLongFromChar( UCHAR * );
UINT GetIntFromChar( UCHAR * );
UINT StrPut( UCHAR *, UCHAR *, UINT );
void FFwdOverWhiteSpace( UCHAR *, UINT * );
UINT ParseForToken( UCHAR *, UINT *, UCHAR * );
int ParseForString( UCHAR *, UINT *, UCHAR * );
int ParseForInteger( UCHAR *, UINT *, UINT *, UINT *, int * );
int ParseForLong( UCHAR *, UINT *, long *, long *, long * );
UCHAR *Compress( UCHAR *, UINT * );
UCHAR *Decompress( UCHAR *, UINT * );
void Lgr( int, ... );
int GetCLIParam( int, UCHAR **, UCHAR *, UINT, UCHAR *, UINT, UINT );
char *StrRTrim( char * );
int StrCaseCmp( const char *, const char * );
int StrnCaseCmp(const char *, const char *, size_t );
int SplitFQFN( char *, char **, char ** );
/* For windows, we must logically associate the case insensitive comparator
* functions with those in this library rather than those in the operating
* system as at the current moment (6/96) Windows does not provide them.
*/
#if defined(_WIN32)
#define strcasecmp StrCaseCmp
#define strncasecmp StrnCaseCmp
#endif
#endif /* UX_COMMON_H */

152
ux/ux_dtype.h Executable file
View File

@@ -0,0 +1,152 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_dtype.h
* Description: Header file for declaration of structures, datatypes etc.
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_DATATYPE_H
#define UX_DATATYPE_H
/* Datatype declarations. Basically need to use unsigned variables in most
* instances, so rather than typing out the full word, we define some
* short names.
*/
typedef unsigned int UINT;
typedef unsigned long ULNG;
typedef unsigned char UCHAR;
typedef unsigned short USHRT;
/* Standard declarations. Sometimes they may not be defined.
*/
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Define Maxim's, minimums etc.
*/
#define MAX_DATETIME 27 /* Max len of a date/time buffer */
#define MAX_DBNAME 32 /* Max len of database name */
#define MAX_DBROWSIZE 255 /* Max size of a database row */
#define MAX_DESTMAPENTRIES 255 /* Max number of dest map lookup entries */
#define MAX_ERRMSG 2048 /* Max size of an error message */
#define MAX_FILEDESCR 256 /* Max number of Socket/File descriptors */
#define MAX_FILENAME 80 /* Max size of a filename */
#define MAX_HOSTNAME 11 /* Max size of a machine host name */
#define MAX_INGRESSTMTBUF 131072 /* Max size for Ingres Statement Buffer */
#define MAX_IPADDR 16 /* Max size of an ascii IP address */
#define MAX_MACHINENAME 40 /* Max size of a machines name */
#define MAX_PACKETS 256 /* Max number of packets in the inqueue */
#define MAX_PATHLEN 128 /* Max len of a pathname */
#define MAX_PROGNAME 80 /* Max size of a program name */
#define MAX_QDATA 1530 /* Max size of Q data */
#define MAX_RECVBUFSIZE 1048576 /* Max size a rcv buf can grow to */
#define MAX_RECVLEN 2048 /* Max size of a single receive */
#define MAX_SENDBUFFER 2048 /* Max size of a transmit buffer */
#define MAX_SERVERNAME 32 /* Max size of a server name */
#define MAX_SERVICENAME 50 /* Max size of a service name */
#define MAX_SOCKETBACKLOG 5 /* Max number of incoming socket backlog */
#define MAX_SYB_INQUPD 15 /* Max simultaneous number of InQ updates */
#define MAX_SYB_OUTQUPD 15 /* Max simultaneous number of OutQ Upd */
#define MAX_TABLENAME 32 /* Max size of a table name */
#define MAX_TMPBUFLEN 2048 /* Max size of a temporary buffer */
#define MAX_USERNAME 32 /* Max size of a user name */
#define MAX_USERPWD 32 /* Max size of a user password */
#define MAX_VARARGBUF 8192 /* Max size of a vararg sprintf buffer */
#define MAX_XLATEBUF 10240 /* Max size of an sql xlate buffer */
#define MIN_COMPRESSLEN 256 /* Min size of data prior to compression */
/* Definitions for function return parameters.
*/
#undef R_OK /* Linux declares R_OK for Read permissions, so undefine as name clash and not needed. */
#define R_OK 0
#define R_FAIL 1
#define R_EXIT 2
/* Definitions for describing a target variable to a called function. Used
* primarily in switches.
*/
#define T_INT 3000 /* Type is for integer */
#define T_STR 3001 /* Type is for string */
#define T_CHAR 3002 /* Type is for character */
#define T_LONG 3003 /* Type is for long */
/* Error return codes from functions within the Replication System. Generally
* returned by a function in the global external 'errno'.
*/
#define E_BADHEAD 1 /* Bad Head pointer in Link List */
#define E_BADTAIL 2 /* Bad Tail pointer in Link List */
#define E_BADPARM 3 /* Bad parameters passed to a function */
#define E_NOKEY 4 /* No Link List search key */
#define E_MEMFREE 5 /* Couldnt free allocated memory */
#define E_NOMEM 6 /* Couldnt allocate memory */
#define E_EXISTS 7 /* A Link List entry already exists */
#define E_NOBIND 8 /* Couldnt perform a socket bind */
#define E_NOLISTEN 9 /* Couldnt perform a socket listen */
#define E_NOSOCKET 10 /* Couldnt allocate a socket */
#define E_BADACCEPT 11 /* Couldnt perform an accept on a socket */
#define E_INVCHANID 12 /* Invalid channel Id passed to comms lib */
#define E_NOSERVICE 13 /* No service provider for a client */
#define E_BADCONNECT 14 /* Couldnt issue a successful connect */
#define E_NOCONNECT 15 /* Couldnt perform a socket connect */
#define E_BUSY 16 /* Comms channel is busy, retry later */
#define E_BADSOCKET 17 /* Given socket is bad or not connected */
#define E_BADSELECT 18 /* Bad parameters causing select to fail */
#define E_NODBSERVER 19 /* No database server available */
#define E_NODATA 20 /* No data available */
#define E_DBNOTINIT 21 /* Database not initialised */
/* Own internal link list handling. Simple progressive link list, with the
* header containing the key elements. In this case, one of each type is
* given, thereby allowing searches without knowing the structure of
* the underlying code.
*/
typedef struct linklist {
UINT nKey;
ULNG lKey;
UCHAR *szKey;
void *spData;
struct linklist *spNext;
} LINKLIST;
/* Need a reference to the external errorno which the UX library procedures make
* use of.
extern int errno;
*/
#if defined(UX_COMMS_C)
int Errno;
#else
extern int Errno;
#endif
#endif /* UX_DATATYPE_H */

255
ux/ux_lgr.c Executable file
View File

@@ -0,0 +1,255 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_lgr.c
* Description: General purpose standalone (programmable) logging
* utilities.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_LOGGER_C
/* Bring in specific header files.
*/
#include "ux.h"
/******************************************************************************
* Function: Lgr
* Description: A function to log a message to a flatfile, database or both.
* Returns: Non.
******************************************************************************/
void Lgr( int nLevel, /* I: Level of error message/or command */
... ) /* I: Varargs */
{
/* Static's.
*/
#ifdef SL_MONITOR
static UCHAR nAlert = FALSE;
#endif
static UINT nLogMode = LGM_STDOUT;
static int nErrLevel = LOG_MESSAGE;
static UCHAR *szLogFile = NULL;
/* Local variables.
*/
va_list pArgs;
struct tm sTime;
time_t nTime;
UCHAR szBuf[MAX_VARARGBUF];
UCHAR *szFormat;
UCHAR *szFuncName;
#ifdef SL_MONITOR
UCHAR szMonBuf[MAX_ERRMSG];
#endif
UCHAR szTime[50];
FILE *fp;
/* Start variable argument passing.
*/
va_start(pArgs, nLevel);
/* Is this a configuration call? If so, set up for future calls.
*/
if(nLevel == LOG_CONFIG)
{
/* Extract varargs off stack. Caller should have called with the
* format: (nLevel, nLogMode, nErrLevel, szProgName)
*/
nLogMode = va_arg(pArgs, UINT);
nErrLevel = va_arg(pArgs, UINT);
szLogFile = va_arg(pArgs, UCHAR *);
/* Tidy up for exit and return to caller.
*/
va_end(pArgs);
return;
}
/* If the logger is switched off, just exit.
*/
if((nErrLevel == LOG_OFF || nLogMode == LGM_OFF) && nLevel != LOG_DIRECT)
{
/* Tidy up for exit and return to caller.
*/
va_end(pArgs);
return;
}
/* Is the level of this error worth logging.. ie. When configured, the
* caller sets a level of which future calls have to equal or better.
*/
#if defined(UX_DEBUG)
if(TRUE)
#else
if(nLevel >= nErrLevel)
#endif
{
/* Extract varargs off stack. Caller should have called with the
* format: (nLevel, szFuncName, szFormat, ...)
*/
szFuncName = va_arg(pArgs, UCHAR *);
szFormat = va_arg(pArgs, UCHAR *);
/* Build up full message for logging.
*/
vsprintf(szBuf, szFormat, pArgs);
/* Get current time to stamp message with. This is only used for non-
* database log messages.
*/
time(&nTime);
#if defined(SOLARIS)
localtime_r(&nTime, &sTime);
#else
memcpy(&sTime, localtime(&nTime), sizeof(struct tm));
#endif
sprintf(szTime, "%02d/%02d/%02d %02d:%02d:%02d", sTime.tm_mday,
sTime.tm_mon+1, sTime.tm_year, sTime.tm_hour, sTime.tm_min,
sTime.tm_sec);
/* Log according to programmed mode.
* LGM_OFF - No logging.
* LGM_STDOUT - Log to stdout.
* LGM_FLATFILE- Log to a flatfile.
* LGM_DB - Log to Database.
* LGM_ALL - Log to all output destinations.
*/
if(nLogMode == LGM_STDOUT || nLevel == LOG_DIRECT)
{
/* Print to stdout as requested.
*/
printf("[%d %s %s] %s\n", nLevel, szTime, szFuncName,szBuf);
fflush(stdout);
}
if((nLogMode == LGM_ALL || nLogMode == LGM_FLATFILE) &&
nLevel != LOG_DIRECT)
{
/* Only log to flatfile if a program name exists.
*/
if(szLogFile != NULL)
{
/* Build up the name of file to open.
*/
if((fp=fopen(szLogFile, "a")) != NULL)
{
/* Place string in buffer.
*/
fprintf(fp, "[%d %s %s] %s\n", nLevel, szTime,
szFuncName, szBuf);
/* Close file when finished, in case a crash occurs,
* sys-op wants to see last message.
*/
fclose(fp);
}
}
}
if((nLogMode == LGM_ALL || nLogMode == LGM_DB) && nLevel != LOG_DIRECT)
{
/* Call the database to log the message.
*/
}
}
/* If monitor processing is enabled, then dispatch all log messages to
* monitor processes.
*/
#ifdef SL_MONITOR
/* If we've had a previous alert and we've got an new message,
* then send cancel alert.
*/
if(nAlert == TRUE && nLevel >= LOG_MESSAGE)
{
sprintf(szMonBuf, "%c", MON_MSG_CANALERT);
SL_MonitorBroadcast(szMonBuf, strlen(szMonBuf));
nAlert = FALSE;
}
/* Look at error level, Alerts and Fatal messages require dispatch
* of an ALERT message to all monitor sites.
*/
if(nLevel >= LOG_ALERT)
{
sprintf(szMonBuf, "%c", MON_MSG_ALERT);
SL_MonitorBroadcast(szMonBuf, strlen(szMonBuf));
nAlert = TRUE;
}
/* Build up error message and transmit seperately.
*/
sprintf(szMonBuf, "%c%s %s", MON_MSG_ERRMSG, szTime, szBuf);
SL_MonitorBroadcast(szMonBuf, strlen(szMonBuf));
#endif
/* Stop vararg processing... ie tidy up stack.
*/
va_end(pArgs);
/* Finished, get out!!
*/
return;
}

661
ux/ux_linkl.c Executable file
View File

@@ -0,0 +1,661 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_linkl.c
* Description: A library of linked list functions for creating, deleting,
* searching (etc..) linked lists.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_LINKEDLIST_C
/* Bring in specific header files.
*/
#include "ux.h"
/******************************************************************************
* Function: AddItem
* Description: A simplistic mechanism to compose a linked list. The link
* is only singly linked, and items are only added to the tail
* of the list.
* Returns: R_OK - Item added successfully.
* R_FAIL - Failure in addition, see Errno.
* <Errno> E_NOMEM - Memory exhaustion.
* E_BADHEAD - Head pointer is bad.
* E_BADTAIL - Tail pointer is bad.
* E_NOKEY - No search key provided.
******************************************************************************/
int AddItem( LINKLIST **spHead, /* IO: Pointer to head of list */
LINKLIST **spTail, /* IO: Pointer to tail of list */
int nMode, /* I: Mode of addition to link */
UINT *nKey, /* I: Integer based search key */
ULNG *lKey, /* I: Long based search key */
UCHAR *szKey, /* I: String based search key */
void *spData ) /* I: Address of carried data */
{
/* Local variables.
*/
char *szFunc = "AddItem";
LINKLIST *pTmpLRec;
LINKLIST *pTailRec;
LINKLIST *spCur;
LINKLIST *spPrev;
/* Quick check, no point adding to list if there is no data.
*/
if(spData == NULL)
{
Errno = E_NODATA;
return(R_FAIL);
}
/* Allocate enough memory for a linklist control block. This will be
* tagged on to the end of the list... eventually!
*/
if( (pTmpLRec=(LINKLIST *)malloc(sizeof(LINKLIST))) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes",
sizeof(LINKLIST));
Errno = E_NOMEM;
return(R_FAIL);
}
memset((UCHAR *)pTmpLRec, '\0', sizeof(LINKLIST));
/* If a text based search key provided, need to allocate space in which
* to store it. If allocation succeeds, dup key.
*/
if(szKey != NULL)
{
if( (pTmpLRec->szKey=(UCHAR *)malloc(strlen(szKey)+1)) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes",
strlen(szKey)+1);
free(pTmpLRec);
Errno = E_NOMEM;
return(R_FAIL);
} else
{
strcpy(pTmpLRec->szKey, szKey);
}
}
/* Populate linklist.
*/
pTmpLRec->nKey = (nKey == NULL ? 0 : *nKey);
pTmpLRec->lKey = (lKey == NULL ? 0L : *lKey);
pTmpLRec->spData = spData;
/* Right, we have a record, so where do we add it.
*/
if(*spHead == NULL)
{
/* Both pointers look at new element.
*/
*spHead = pTmpLRec;
*spTail = pTmpLRec;
pTmpLRec->spNext = NULL;
} else
{
/* If were sorting the list as we go along, then we need to scan it and
* find the required location.
*/
if(nMode != SORT_NONE)
{
for(spPrev=NULL, spCur= *spHead; spCur != NULL;
spPrev=spCur, spCur=spCur->spNext)
{
if(nMode == SORT_INT_UP && pTmpLRec->nKey < spCur->nKey)
break;
else
if(nMode == SORT_INT_DOWN && pTmpLRec->nKey > spCur->nKey)
break;
else
if(nMode == SORT_LONG_UP && pTmpLRec->lKey < spCur->lKey)
break;
else
if(nMode == SORT_LONG_DOWN && pTmpLRec->lKey > spCur->lKey)
break;
}
/* Error condition, should not occur?
*/
if(spPrev == NULL && spCur == NULL)
{
if(pTmpLRec->szKey != NULL)
free(pTmpLRec->szKey);
free(pTmpLRec);
return(R_FAIL);
} else
/* Insert at very beginning of list?
*/
if(spPrev == NULL && spCur != NULL)
{
pTmpLRec->spNext = *spHead;
*spHead = pTmpLRec;
} else
/* Insert in the middle of the list?
*/
if(spPrev != NULL && spCur != NULL)
{
pTmpLRec->spNext = spPrev->spNext;
spPrev->spNext = pTmpLRec;
} else
/* Insert at the end of the list!
*/
{
/* Add to tail of list by making tail point to new item, then
* new item becomes the tail.
*/
pTailRec = *spTail;
pTailRec->spNext = pTmpLRec;
*spTail = pTmpLRec;
pTmpLRec->spNext = NULL;
}
} else
{
/* Add to tail of list by making tail point to new item, then
* new item becomes the tail.
*/
pTailRec = *spTail;
pTailRec->spNext = pTmpLRec;
*spTail = pTmpLRec;
pTmpLRec->spNext = NULL;
}
}
/* Return success or fail...?
*/
return(R_OK);
}
/******************************************************************************
* Function: DelItem
* Description: Delete an element from a given linked list. The underlying
* carried data is not freed, it is assumed that the caller
* will free that, as it was the caller that allocated it.
* Returns: R_OK - Item deleted successfully.
* R_FAIL - Failure in deletion, see Errno.
* <Errno> E_BADHEAD - Head pointer is bad.
* E_BADTAIL - Tail pointer is bad.
* E_MEMFREE - Couldnt free memory to sys pool.
* E_NOKEY - No search key provided.
******************************************************************************/
int DelItem( LINKLIST **spHead, /* IO: Pointer to head of list */
LINKLIST **spTail, /* IO: Pointer to tail of list */
void *spKey, /* I: Addr of item, direct update */
UINT *nKey, /* I: Integer based search key */
ULNG *lKey, /* I: Long based search key */
UCHAR *szKey ) /* I: String based search key */
{
/* Local variables.
*/
int nResult = R_FAIL;
LINKLIST *spCur;
LINKLIST *spPrev;
/* Check input values. Is head valid?
*/
if(*spHead == NULL)
{
Errno = E_BADHEAD;
return(nResult);
}
/* Is tail valid?
*/
if(*spTail == NULL)
{
Errno = E_BADTAIL;
return(nResult);
}
/* Have search keys been provided.
*/
if(spKey == NULL && nKey == NULL && lKey == NULL && szKey == NULL)
{
Errno = E_NOKEY;
return(nResult);
}
/* Locate item by scanning the list. This may get updated in years to
* come to be a hash/btree lookup/delete.... dream on!!
*/
for(spPrev=NULL, spCur= *spHead; spCur != NULL;
spPrev=spCur, spCur=spCur->spNext)
{
/* See if we have a match!
*/
if( (spKey != NULL && spCur->spData != spKey) ||
(nKey != NULL && *nKey != spCur->nKey) ||
(lKey != NULL && *lKey != spCur->lKey) ||
(szKey != NULL && spCur->szKey != NULL &&
strcmp(szKey, spCur->szKey) != 0))
continue;
/* OK, found the one.
*/
break;
}
/* If records not null, then we have located the required record, remove
* it.
*/
if(spCur != NULL)
{
/* Item at beginning of list?
*/
if(spPrev == NULL)
{
/* Point head at next in list. If next is NULL, then list empty,
* so update Tail.
*/
if((*spHead = spCur->spNext) == NULL)
*spTail = NULL;
} else
{
if((spPrev->spNext = spCur->spNext) == NULL)
*spTail = spPrev;
}
/* Free memory used by removed element.
*/
if(spCur->szKey != NULL)
free(spCur->szKey);
free(spCur);
nResult = R_OK;
}
/* Return success or fail...?
*/
return(nResult);
}
/******************************************************************************
* Function: FindItem
* Description: Find an element in a given linked list.
* Returns: NOTNULL - Item found, address returned.
* NULL - Item not found, see Errno.
* <Errno> E_BADHEAD - Head pointer is bad.
* E_BADTAIL - Tail pointer is bad.
* E_NOKEY - No search key provided.
******************************************************************************/
void *FindItem( LINKLIST *spHead, /* I: Pointer to head of list */
UINT *nKey, /* I: Integer based search key */
ULNG *lKey, /* I: Long based search key */
UCHAR *szKey ) /* I: String based search key */
{
/* Local variables.
*/
UCHAR *spResult = NULL;
LINKLIST *spCur;
/* Quite simple at the momoko, just loop through the list and see if an
* entry exists. Eventually, (he hopes) this could be enhanced to inc
* btree/hash lookup.
*/
for(spCur=spHead; spCur != NULL; spCur=spCur->spNext)
{
if(nKey != NULL && spCur->nKey == *nKey)
break;
if(lKey != NULL && spCur->lKey == *lKey)
break;
if(szKey != NULL && strcmp(szKey, spCur->szKey) == 0)
break;
}
/* Found a record?
*/
if( spCur != NULL )
spResult = spCur->spData;
/* Return success or fail...?
*/
return(spResult);
}
/******************************************************************************
* Function: StartItem
* Description: Setup pointers for a complete list scan. Return the top most
* list 'data item' to caller.
* Returns: NOTNULL - Item found, address returned.
* NULL - Item not found, see Errno.
* <Errno> E_BADHEAD - Head pointer is bad.
******************************************************************************/
void *StartItem( LINKLIST *spHead, /* I: Pointer to head of list */
LINKLIST **spNext ) /* O: Pointer to next item in list */
{
/* Local variables.
*/
void *spResult = NULL;
/* Does the list exist yet?
*/
if( spHead == NULL )
{
Errno = E_BADHEAD;
} else
{
/* Setup pointer to next in link and return pointer to data to caller.
*/
*spNext = (LINKLIST *)spHead->spNext;
spResult = (UCHAR *)spHead->spData;
}
/* Return success or fail...?
*/
return(spResult);
}
/******************************************************************************
* Function: NextItem
* Description: Move to next item in a given list. Return the current 'data
* item' to caller.
* Returns: NOTNULL - Item found, address returned.
* NULL - Item not found, see Errno.
* <Errno> E_BADPARM - Bad parameter passed to function.
******************************************************************************/
void *NextItem( LINKLIST **spNext ) /* O: Pointer to next item in list */
{
/* Local variables.
*/
void *spResult = NULL;
LINKLIST *spLink = *spNext;
/* Check parameter, maybe at end of list already.
*/
if( *spNext == NULL )
{
Errno = E_BADPARM;
} else
{
/* Extract pointer to data and move down link.
*/
spResult = (UCHAR *)spLink->spData;
*spNext = (LINKLIST *)spLink->spNext;
}
/* Return success or fail...?
*/
return(spResult);
}
/******************************************************************************
* Function: MergeLists
* Description: Merge two list together. The Source list is merged into the
* target list. Lists are re-sorted if required.
* Returns: R_OK - Item added successfully.
* R_FAIL - Failure in addition, see Errno.
* <Errno> E_NOMEM - Memory exhaustion.
* E_BADHEAD - Head pointer is bad.
* E_BADTAIL - Tail pointer is bad.
* E_NOKEY - No search key provided.
******************************************************************************/
int MergeLists( LINKLIST **spDstHead, /* IO: Pointer to head of dest list */
LINKLIST **spDstTail, /* IO: Pointer to tail of dest list */
LINKLIST *spSrcHead, /* I: Pointer to head of src list */
LINKLIST *spSrcTail, /* I: Pointer to tail of src list */
int nMode ) /* I: Mode of list merging */
{
/* Local variables.
*/
LINKLIST *spNext;
LINKLIST *spSrc;
LINKLIST *pTailRec;
LINKLIST *spCur;
LINKLIST *spPrev;
/* Go through each record in the source list and add onto the destination
* list.
*/
if((spSrc = spSrcHead) != NULL)
spNext = spSrcHead->spNext;
else
spNext = NULL;
/* Loop through the entire source list and merge into the destination list.
*/
while(spSrc != NULL)
{
/* Right, we have a record, so where do we add it.
*/
if(*spDstHead == NULL)
{
/* Both pointers look at new element.
*/
*spDstHead = spSrc;
*spDstTail = spSrc;
spSrc->spNext = NULL;
} else
{
/* If were sorting the list as we go along, then we need to scan it
* and find the required location.
*/
if(nMode != SORT_NONE)
{
for(spPrev=NULL, spCur= *spDstHead; spCur != NULL;
spPrev=spCur, spCur=spCur->spNext)
{
if(nMode == SORT_INT_UP && spSrc->nKey < spCur->nKey)
break;
else
if(nMode == SORT_INT_DOWN && spSrc->nKey > spCur->nKey)
break;
else
if(nMode == SORT_LONG_UP && spSrc->lKey < spCur->lKey)
break;
else
if(nMode == SORT_LONG_DOWN && spSrc->lKey > spCur->lKey)
break;
}
/* Insert at very beginning of list?
*/
if(spPrev == NULL && spCur != NULL)
{
spSrc->spNext = *spDstHead;
*spDstHead = spSrc;
} else
/* Insert in the middle of the list?
*/
if(spPrev != NULL && spCur != NULL)
{
spSrc->spNext = spPrev->spNext;
spPrev->spNext = spSrc;
} else
/* Insert at the end of the list!
*/
{
/* Add to tail of list by making tail point to new item,
* then new item becomes the tail.
*/
pTailRec = *spDstTail;
pTailRec->spNext = spSrc;
*spDstTail = spSrc;
spSrc->spNext = NULL;
}
} else
{
/* Add to tail of list by making tail point to new item, then
* new item becomes the tail.
*/
pTailRec = *spDstTail;
pTailRec->spNext = spSrc;
*spDstTail = spSrc;
spSrc->spNext = NULL;
}
}
/* Move to next element.
*/
if((spSrc = spNext) != NULL)
spNext = spSrc->spNext;
}
/* Return success or fail...?
*/
return(R_OK);
}
/******************************************************************************
* Function: DelList
* Description: Delete an entire list and free memory used by the list and the
* underlying carried data.
* Returns: R_OK - List deleted successfully.
* R_FAIL - Failed to delete list, see Errno.
* <Errno> E_BADHEAD - Head pointer is bad.
* E_BADTAIL - Tail pointer is bad.
******************************************************************************/
int DelList( LINKLIST **spHead, /* IO: Pointer to head of list */
LINKLIST **spTail ) /* IO: Pointer to tail of list */
{
/* Local variables.
*/
LINKLIST *spTmp;
LINKLIST *spNext;
/* Check input values. Is head valid?
*/
if(*spHead == NULL)
{
Errno = E_BADHEAD;
return(R_FAIL);
}
/* Is tail valid?
*/
if(*spTail == NULL)
{
Errno = E_BADTAIL;
return(R_FAIL);
}
/* Quite simple, breeze through list, deleting everything.
*/
for(spTmp= *spHead; spTmp != NULL; spTmp=spNext)
{
/* Free any memory allocated for text search buffer.
*/
if(spTmp->szKey != NULL)
free(spTmp->szKey);
/* Free any memory allocated for data record.
*/
if(spTmp->spData != NULL)
free(spTmp->spData);
/* Get next element then release element memory.
*/
spNext=spTmp->spNext;
free(spTmp);
}
/* Tidy up callers pointers.
*/
*spHead = *spTail = NULL;
/* Got here, perhaps everything worked...!
*/
return(R_OK);
}
/******************************************************************************
* Function: SizeList
* Description: Find the total number of elements in a given list by scanning
* it.
* Returns: R_OK - List size calculated.
* R_FAIL - Failed to calculate list size, see Errno.
* <Errno> E_BADHEAD - Head pointer is bad.
******************************************************************************/
int SizeList( LINKLIST *spHead, /* I: Pointer to head of list */
UINT *nCnt ) /* O: Count of elements in list */
{
/* Local variables.
*/
LINKLIST *spTmp;
/* Check input values. Is head valid?
*/
if(spHead == NULL)
{
Errno = E_BADHEAD;
return(R_FAIL);
}
/* Quite simple, breeze through list, counting.
*/
for(*nCnt=0,spTmp=spHead; spTmp != NULL; *nCnt += 1, spTmp=spTmp->spNext);
/* Got here, perhaps everything worked...!
*/
return(R_OK);
}

1097
ux/ux_mon.c Executable file

File diff suppressed because it is too large Load Diff

122
ux/ux_mon.h Executable file
View File

@@ -0,0 +1,122 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_mon.h
* Description: Application internal monitor processing system. Allows
* possibility of real-time access to a running application.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef UX_MONITOR_H
#define UX_MONITOR_H
/* Interactive monitor service types.
*/
#define MON_SERVICE_HTML 0x00 /* All comms are based on HTML */
#define MON_SERVICE_NL 0x01 /* All comms are based on Natural Language. */
#define MON_SERVICE_EXT 0xff /* External service handled by an application interpreter override */
/* Interactive monitor commands.
*/
#define MON_MSG_NEW 0x1F /* New IM process connecting */
#define MON_MSG_TERMINATE 0x1E /* Terminating IM process */
#define MON_MSG_REDISPLAY 0x1D /* Redisplay prompt */
#define MON_MSG_TEST 0x1C /* Test connectivity */
#define MON_MSG_ERRMSG 0x1B /* Inbound error message */
#define MON_MSG_ALERT 0x1A /* Red-Alert condition */
#define MON_MSG_CANALERT 0x19 /* Cancel Red-Alert condition */
/* Basic Interactive monitoring command set.
*/
#define MC_TERMINATE "TERMINATE"
#define MC_HTMLGET "GET"
#define MC_HTMLHEAD "HEAD"
#define MC_HTMLPOST "POST"
#define MC_HTMLPUT "PUT"
#define MC_HTMLDELETE "DELETE"
#define MC_HTMLCONNECT "CONNECT"
#define MC_HTMLOPTIONS "OPTIONS"
#define MC_HTMLTRACE "TRACE"
/* A structure containing data relevant to each unique connection made
* by a client with the monitor system.
*/
typedef struct {
UINT nChanId; /* Channel ID descr for Socket Lib */
UINT nClientPortNo; /* TCP port client connected on */
ULNG lClientIPaddr; /* IP address of connecting client */
} ML_CONLIST;
/* A structure defining the list of commands that the interactive monitor
* port recognises and the associated callbacks for each command.
*/
typedef struct {
UCHAR *szCommand; /* Command in ascii text format */
int (*nCallback)(); /* Function to call when text recognised */
} ML_COMMANDLIST;
/* A structure defining an individual service offered by this application.
*/
typedef struct {
UINT nMonPort; /* TCP port service provided on */
UINT nServiceType; /* Type of service provided */
int (*nConnectCB)(); /* CB on Client Connection */
int (*nDisconCB)(); /* CB on Client Disconnection */
int (*nInterpretOvr)(); /* Override for Interpretation function */
UCHAR *szServerName; /* Name of server for HTTP responses */
LINKLIST *spConHead; /* Head of Connection List */
LINKLIST *spConTail; /* Tail of Connection List */
LINKLIST *spMCHead; /* Head of LList containing I/Mon commands */
LINKLIST *spMCTail; /* Tail of LList containing I/Mon commands */
} ML_MONLIST;
/* Global variables for the Comms module.
*/
typedef struct {
LINKLIST *spMonHead; /* Head of LList containing I/Mon commands */
LINKLIST *spMonTail; /* Tail of LList containing I/Mon commands */
} ML_GLOBALS;
/* Prototypes for functions internal to MonitorLib module.
*/
int _ML_MonTerminate( UINT, UCHAR *, UINT );
void _ML_MonitorCB( UINT, UCHAR *, UINT );
void _ML_MonitorCntrl( int, ... );
/* Prototypes to externally visible and usable functions.
*/
int ML_Init( UINT, UINT, UCHAR *, int (*)(), int (*)(), int (*)());
int ML_Exit( UCHAR * );
int ML_Send( UINT, UCHAR *, UINT );
int ML_AddMonCommand( UINT, UCHAR *, int (*)() );
int ML_DelMonCommand( UINT, UCHAR * );
int ML_Broadcast( UCHAR *, UINT );
#endif /* UX_MONITOR_H */

766
ux/ux_str.c Executable file
View File

@@ -0,0 +1,766 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_str.c
* Description: General purpose string processing funtions. Additions to
* those which exist within the C libraries.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_STRINGPROCESSING_C
/* Bring in specific header files.
*/
#include "ux.h"
/******************************************************************************
* Function: PutCharFromLong
* Description: Place a long type variable into a character buffer in a known
* byte order. IE. A long is 32 bit, and is placed into the
* char buffer as MSB (3), 2, 1, LSB (0). Where MSB fits into the
* first byte of the buffer.
* Returns: R_OK - Cannot fail ... will I be eating my words...?
******************************************************************************/
int PutCharFromLong( UCHAR *pDestBuf, /* O: Destination buffer */
ULNG lVar ) /* I: Variable of type long */
{
/* Local variables.
*/
int nReturn = R_OK;
ULNG lVal = lVar;
/* Cant assume any byte ordering, so use arithmetic to break it down
* into fundamental components. Assume a long is 32bit.
*/
pDestBuf[0] = (UCHAR)(lVal/16777216L);
lVal -= (ULNG)pDestBuf[0] * 16777216L;
pDestBuf[1] = (UCHAR)(lVal/65536L);
lVal -= (ULNG)pDestBuf[1] * 65536L;
pDestBuf[2] = (UCHAR)(lVal/256L);
lVal -= (ULNG)pDestBuf[2] * 256L;
pDestBuf[3] = (UCHAR)lVal;
/* Finished, get out!!
*/
return( nReturn );
}
/******************************************************************************
* Function: PutCharFromInt
* Description: Place an int type variable into a character buffer in a known
* byte order. IE. An int is 16 bit, and is placed into the
* char buffer as MSB (1), LSB (0). Where MSB fits into the
* first byte of the buffer.
* Returns: R_OK - Cannot fail ... see comment above.
******************************************************************************/
int PutCharFromInt( UCHAR *pDestBuf, /* O: Destination buffer */
UINT lVar ) /* I: Variable of type int */
{
/* Local variables.
*/
int nReturn = R_OK;
ULNG lVal = (ULNG)lVar;
/* Cant assume any byte ordering, so use arithmetic to break it down
* into fundamental components. Assume 16 bit Int.
*/
if(lVal > 65536L)
{
/* > 16 bit, so remove upper component.
*/
lVal -= (lVal/16777216L)*65536L;
}
pDestBuf[0] = (UCHAR)(lVal/256L);
lVal -= (ULNG)pDestBuf[0] * 256L;
pDestBuf[1] = (UCHAR)lVal;
/* Finished, get out!!
*/
return( nReturn );
}
/******************************************************************************
* Function: GetLongFromChar
* Description: Get a long type variable from a character buffer. The byte
* ordering in the buffer is assumed to be 32bit, MSB(3), 2, 1,
* LSB (0), where the MSB fits into the first byte of the
* buffer.
* Returns: R_OK - Cannot fail ... will I be eating my words...?
******************************************************************************/
ULNG GetLongFromChar( UCHAR *pDestBuf ) /* I: Source buffer to convert */
{
/* Local variables.
*/
ULNG lVal = 0;
/* Cant assume any byte ordering, so use arithmetic to break it down
* into fundamental components. Assume a long is 32bit.
*/
lVal = (UCHAR)pDestBuf[0] * 16777216L;
lVal += (UCHAR)pDestBuf[1] * 65536L;
lVal += (UCHAR)pDestBuf[2] * 256L;
lVal += (UCHAR)pDestBuf[3];
/* Finished, get out!!
*/
return( lVal );
}
/******************************************************************************
* Function: GetIntFromChar
* Description: Get a long type variable from a character buffer. The byte
* ordering in the buffer is assumed to be 16bit, MSB(1), LSB(0)
* where the MSB fits into the first byte of the buffer.
* Returns: R_OK - Cannot fail ... will I be eating my words...?
******************************************************************************/
UINT GetIntFromChar( UCHAR *pDestBuf ) /* I: Source buffer to convert */
{
/* Local variables.
*/
UINT lVal = 0;
/* Cant assume any byte ordering, so use arithmetic to break it down
* into fundamental components. Assume a long is 32bit.
*/
lVal += (UCHAR)pDestBuf[0] * 256;
lVal += (UCHAR)pDestBuf[1];
/* Finished, get out!!
*/
return( lVal );
}
/******************************************************************************
* Function: StrPut
* Description: Put a string INTO another string. Same as strcpy BUT it doesnt
* terminate the destination string.
* Returns: R_OK - Cannot fail ... will I be eating my words...?
******************************************************************************/
UINT StrPut( UCHAR *spDestBuf, /* I: Destination buffer to copy into */
UCHAR *spSrcBuf, /* I: Source buffer to copy from */
UINT nBytes ) /* I: Number of bytes to copy */
{
/* Local variables.
*/
UINT nNdx;
/* Simple copy.
*/
for(nNdx=0; nNdx < nBytes && spSrcBuf[nNdx] != '\0'; nNdx++)
{
spDestBuf[nNdx] = spSrcBuf[nNdx];
}
/* Finished, get out!!
*/
return( R_OK );
}
/******************************************************************************
* Function: FFwdOverWhiteSpace
* Description: Forward a pointer past whitespace in the input buffer.
* Returns: Non.
******************************************************************************/
void FFwdOverWhiteSpace( UCHAR *szInBuf, /* I: Input data buffer */
UINT *nPos ) /* IO: Start/End position in buf */
{
/* Local variables.
*/
/* Move the pointer past whitespace to the fisrt non-whitespace character
* or the end of file.
*/
while(szInBuf[*nPos] != '\0' && isspace(szInBuf[*nPos]))
{ (*nPos)++; }
return;
}
/******************************************************************************
* Function: ParseForToken
* Description: Parse the input buffer for the next token. A token can be a
* Alpha/Alphanum word, a numeric, a single character or a
* string.
* Returns: Type of Token located.
******************************************************************************/
UINT ParseForToken( UCHAR *szInBuf, /* I: Input buffer */
UINT *nPos, /* IO: Current pos in buffer */
UCHAR *szTokBuf ) /* O: Token output buffer */
{
/* Local variables.
*/
UINT nExit;
UINT nQuoteType;
UINT nToken;
UINT nTokNdx;
/* Initially, forward to the first non-whitespace.
*/
while(szInBuf[*nPos] != '\0' && isspace(szInBuf[*nPos]))
{
(*nPos)++;
}
/* End of buffer..?
*/
if(szInBuf[*nPos] == '\0')
{
/* Instruct caller that we are at the end.
*/
nToken = TOK_EOB;
} else
/* Do we have an alpha/alphanum in the buffer?
*/
if(isalpha(szInBuf[*nPos]))
{
/* Instruct caller, initially, that we located an ALPHA word.
*/
nToken = TOK_ALPHA;
/* Go through the buffer, copying out the word.
*/
for(nTokNdx=0; isalnum(szInBuf[*nPos]) || szInBuf[*nPos] == '-' ||
szInBuf[*nPos] == '_' || szInBuf[*nPos] == '/';
nTokNdx++, (*nPos)++)
{
/* Data copy.
*/
szTokBuf[nTokNdx] = szInBuf[*nPos];
}
/* Terminate Token Buffer.
*/
szTokBuf[nTokNdx] = '\0';
} else
/* Do we have a numeric in the buffer?
*/
if(isdigit(szInBuf[*nPos]) ||
(szInBuf[*nPos] == '-' && isdigit(szInBuf[(*nPos)+1])) ||
(szInBuf[*nPos] == '+' && isdigit(szInBuf[(*nPos)+1])))
{
/* Instruct caller that we located a numeric.
*/
nToken = TOK_NUMERIC;
/* Straight data copy.
*/
for(nTokNdx=0;
isdigit(szInBuf[*nPos]) || szInBuf[*nPos] == '.' ||
szInBuf[*nPos] == '-' || szInBuf[*nPos] == '+';
nTokNdx++, (*nPos)++)
{
szTokBuf[nTokNdx] = szInBuf[*nPos];
}
/* Terminate Token Buffer.
*/
szTokBuf[nTokNdx] = '\0';
} else
/* Do we have a string in the buffer?
*/
if(szInBuf[*nPos] == 0x27 || szInBuf[*nPos] == 0x22)
{
/* Instruct caller that we located a string.
*/
nToken = TOK_STRING;
/* What type of quote are we looking for?
*/
if(szInBuf[(*nPos)] == 0x27)
nQuoteType = 0;
else
nQuoteType = 1;
/* Go through the input buffer until we locate the matching quote
* or we hit the end of buffer.
*/
for(nTokNdx=0, nExit=FALSE; nExit == FALSE; nTokNdx++, (*nPos)++)
{
/* Copy over to the token buffer, all chars, including the final
* quote/eob.
*/
szTokBuf[nTokNdx] = szInBuf[*nPos];
/* If were looking for single quotes and we locate one which is
* not escaped, then we've reached the end of the string.
*/
if(szInBuf[*nPos] == 0x27 && nQuoteType == 0)
{
/* If where at the beginning of a string and we dont meet
* the criterion for a null string, the loop.
*/
if(nTokNdx == 0 &&
szInBuf[(*nPos)+1] != 0x27)
{
continue;
} else
/* A null string?
*/
if(nTokNdx == 0 &&
szInBuf[(*nPos)+1] == 0x27 &&
szInBuf[(*nPos)+2] != 0x27)
{
/* Copy final byte into token buffer.
*/
szTokBuf[++nTokNdx] = szInBuf[++(*nPos)];
nExit = TRUE;
} else
/* A lone quote?
*/
if(szInBuf[(*nPos)-1] != 0x5c &&
szInBuf[(*nPos)+1] != 0x27 &&
szInBuf[(*nPos)-1] != 0x27)
{
nExit = TRUE;
}
} else
/* If were looking for double quotes and we locate on which is
* not escaped, then we've reached the end of the string.
*/
if(szInBuf[*nPos] == 0x22 && nQuoteType == 1)
{
/* If where at the beginning of a string and we dont meet
* the criterion for a null string, then loop.
*/
if(nTokNdx == 0 &&
szInBuf[(*nPos)+1] != 0x22)
{
continue;
} else
/* A null string?
*/
if(szInBuf[(*nPos)+1] == 0x22 &&
szInBuf[(*nPos)+2] != 0x22 &&
nTokNdx == 0)
{
/* Copy final byte into token buffer.
*/
szTokBuf[++nTokNdx] = szInBuf[++(*nPos)];
nExit = TRUE;
} else
/* A lone quote?
*/
if(szInBuf[(*nPos)-1] != 0x5c &&
szInBuf[(*nPos)+1] != 0x22 &&
szInBuf[(*nPos)-1] != 0x22)
{
nExit = TRUE;
}
} else
/* Found the end of buffer... some idiot hasnt terminated the
* string correctly.
*/
if(szInBuf[*nPos] == '\0')
nExit = TRUE;
}
/* Terminate Token Buffer.
*/
szTokBuf[nTokNdx] = '\0';
} else
/* Is this a comment...?
*/
if(szInBuf[*nPos] == '/' && szInBuf[(*nPos)+1] == '*')
{
/* Instruct caller that we located a comment.
*/
nToken = TOK_COMMENT;
/* Loop through copying upto the end of the comment.
*/
for(nTokNdx=0, nExit=FALSE; nExit == FALSE; nTokNdx++, (*nPos)++)
{
/* Copy data into token buffer.
*/
szTokBuf[nTokNdx] = szInBuf[*nPos];
if(nTokNdx < 2) continue;
/* End of comment?
*/
if(szInBuf[*nPos] == '*' && szInBuf[(*nPos)+1] == '/')
{
nExit = TRUE;
}
/* Found the end of buffer... some idiot hasnt terminated the
* comment correctly.
*/
if(szInBuf[*nPos] == '\0')
nExit = TRUE;
}
/* Terminate Token Buffer.
*/
szTokBuf[nTokNdx] = '\0';
} else
{
/* Instruct caller that we located a character.
*/
nToken = TOK_CHAR;
/* Straight data copy and termination.
*/
szTokBuf[0] = szInBuf[(*nPos)++];
szTokBuf[1] = '\0';
}
/* Return type to caller.
*/
return(nToken);
}
/******************************************************************************
* Function: ParseForString
* Description: Get next valid string from input buffer.
* Returns: Non.
******************************************************************************/
int ParseForString( UCHAR *szInBuf, /* I: Input buffer */
UINT *nPos, /* I: Position in input buffer */
UCHAR *szOutBuf ) /* O: Target buffer for string */
{
/* Local variables.
*/
UINT nReturn = R_OK;
UINT nTokType;
/* Zero callers buffer.
*/
szOutBuf[0] = '\0';
/* Get next parameter.
*/
nTokType = ParseForToken(szInBuf, nPos, szOutBuf);
/* If its not a valid string, modify return code.
*/
if(nTokType == TOK_COMMENT || nTokType == TOK_CHAR ||
nTokType == TOK_EOB || strlen(szOutBuf) == 0)
{
nReturn = R_FAIL;
}
/* Return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: ParseForInteger
* Description: Get next valid integer from input buffer.
* Returns: Non.
******************************************************************************/
int ParseForInteger( UCHAR *szInBuf, /* I: Input buffer */
UINT *nPos, /* I: Position in input buffer */
UINT *nMin, /* I: Minimum allowable value */
UINT *nMax, /* I: Maximum allowable value */
int *pOutInt ) /* O: Target buffer for integer */
{
/* Local variables.
*/
UINT nInt;
UINT nReturn = R_OK;
UINT nTokType;
UCHAR szTmpBuf[MAX_TMPBUFLEN];
/* Get next parameter.
*/
nTokType = ParseForToken(szInBuf, nPos, szTmpBuf);
/* Convert into an integer.
*/
if(nTokType != TOK_NUMERIC || sscanf(szTmpBuf, "%d", &nInt) != 1 ||
(nMin != NULL && nInt < *nMin) || (nMax != NULL && nInt > *nMax))
{
nReturn = R_FAIL;
} else
{
*pOutInt = nInt;
}
/* Return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: ParseForLong
* Description: Get next valid Long from input buffer.
* Returns: Non.
******************************************************************************/
int ParseForLong( UCHAR *szInBuf, /* I: Input buffer */
UINT *nPos, /* I: Position in input buffer */
long *lMin, /* I: Minimum allowable value */
long *lMax, /* I: Maximum allowable value */
long *pOutLong ) /* O: Target buffer for Long */
{
/* Local variables.
*/
UINT nReturn = R_OK;
UINT nTokType;
long lLng;
UCHAR szTmpBuf[MAX_TMPBUFLEN];
/* Get next parameter.
*/
nTokType = ParseForToken(szInBuf, nPos, szTmpBuf);
/* Convert into an integer.
*/
if(nTokType != TOK_NUMERIC || sscanf(szTmpBuf, "%ld", &lLng) != 1 ||
(lMin != NULL && lLng < *lMin) || (lMax != NULL && lLng > *lMax))
{
nReturn = R_FAIL;
} else
{
*pOutLong = lLng;
}
/* Return result to caller.
*/
return(nReturn);
}
/******************************************************************************
* Function: StrRTrim
* Description: A function to trim off all trailing spaces for a given string.
* The function works by starting at the end of a null terminated
* string and looking for the first non-space character. It then
* places a null terminator at the new location.
* Returns: Pointer to new string.
******************************************************************************/
char *StrRTrim( char *szSrc ) /* IO: Base string to trim */
{
/* Local variables.
*/
char *pLocation = &szSrc[strlen(szSrc)-1];
/* Scan backwards until we find a non space or we meet the beginning
* of the string.
*/
while( pLocation != szSrc && isspace(*pLocation) )
{
pLocation--;
}
/* If we are not at the beginning of the string, then place a null
* terminator at t+1;
*/
if(pLocation != szSrc)
{
pLocation++;
*pLocation = '\0';
}
/* All done, exit.
*/
return(szSrc);
}
/******************************************************************************
* Function: StrCaseCmp
* Description: A function to perform string compares regardless of
* character case. Provided mainly for operating systems that
* dont possess such functionality.
* Returns: 0 - Strings compare.
* > 0
* < 0
******************************************************************************/
int StrCaseCmp( const char *szSrc, /* I: Base string to compare against */
const char *szCmp ) /* I: Comparator string */
{
/* Local variables.
*/
register signed char cResult;
/* Loop, progressing through the strings until we have a difference or
* we get to the end of the string and hence have a comparison match.
*/
while(1)
{
cResult = toupper(*szSrc) - toupper(*szCmp);
szCmp++;
szSrc++;
if(cResult != 0 || *szCmp == '\0' || *szSrc == '\0')
break;
}
/* Return result to caller.
*/
return(cResult);
}
/******************************************************************************
* Function: StrnCaseCmp
* Description: A function to perform string compares regardless of
* character case for a specified number of characters within
* both strings. Provided mainly for operating systems that
* dont possess such functionality.
* Returns: 0 - Strings compare.
* > 0
* < 0
******************************************************************************/
int StrnCaseCmp( const char *szSrc, /* I: Base string to compare against */
const char *szCmp, /* I: Comparator string */
size_t nCount ) /* I: Number of bytes to compare */
{
/* Local variables.
*/
register signed char cResult;
/* Loop, progressing through the strings until we have a difference or
* the given number of characters match in both strings.
*/
while(nCount)
{
cResult = toupper(*szSrc) - toupper(*szCmp);
szCmp++;
szSrc++;
if(cResult != 0 || *szCmp == '\0' || *szSrc == '\0')
break;
nCount--;
}
/* Return result to caller.
*/
return(cResult);
}
/******************************************************************************
* Function: SplitFQFN
* Description: A function to split a fully qualified filename into a
* directory and filename components.
* Returns: R_OK - Filename split.
* R_FAIL - Couldnt split due to errors, ie. memory.
******************************************************************************/
int SplitFQFN( char *szFQFN, /* I: Fully Qualified File Name */
char **szDir, /* O: Directory component */
char **szFN ) /* O: Filename component */
{
/* Local variables.
*/
UINT nNdx;
char *spTmpDir;
char *spTmpFN;
char *szFunc = "SplitFQFN";
/* Allocate a buffer to hold the directory component.
*/
if((spTmpDir=(UCHAR *)malloc(strlen(szFQFN)+1)) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes", strlen(szFQFN)+1);
Errno = E_NOMEM;
return(R_FAIL);
}
/* Allocate a buffer to hold the filename component.
*/
if((spTmpFN=(UCHAR *)malloc(strlen(szFQFN)+1)) == NULL)
{
Lgr(LOG_DEBUG, szFunc, "Couldnt malloc (%d) bytes", strlen(szFQFN)+1);
Errno = E_NOMEM;
return(R_FAIL);
}
/* Starting at the end of the string, work backwards until we find
* a directory element character or start of string.
*/
for(nNdx=strlen(szFQFN); nNdx >= 0 && szFQFN[nNdx] != '/'; nNdx--);
/* If nNdx == 0 && szFQFN[nNdx] not equal to the directory character
* then we have a filename with no directory. Just copy.
*/
if(nNdx == 0 && szFQFN[nNdx] != '/')
{
strcpy(spTmpDir, "");
strcpy(spTmpFN, szFQFN);
} else
if(nNdx == 0 && szFQFN[nNdx] == '/')
{
strcpy(spTmpDir, "/");
strcpy(spTmpFN, &szFQFN[1]);
} else
{
szFQFN[nNdx] = '\0';
strcpy(spTmpDir, szFQFN);
strcpy(spTmpFN, &szFQFN[nNdx+1]);
szFQFN[nNdx] = '/';
}
/* Setup callers pointers to point to new memory.
*/
*szDir = spTmpDir;
*szFN = spTmpFN;
/* Return result to caller.
*/
return(R_OK);
}

223
ux/ux_thrd.c Executable file
View File

@@ -0,0 +1,223 @@
/******************************************************************************
* Product: # # # # # ### ######
* # # # # # # # #
* # # # # # # # #
* # # # # # ######
* # # # # # # # #
* # # # # # # # #
* ##### # # ####### ####### ### ######
*
* File: ux_thrd.c
* Description: UX Thread Management routines. A module with the specific aim
* of invoking, charting and termination of threads required by
* programs built with this library.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1994-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(SUNOS) || defined(SOLARIS) || defined(LINUX)
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#endif
#if defined(SOLARIS)
#include <sys/file.h>
#endif
#if defined(LINUX)
#include <term.h>
#endif
#if defined(_WIN32)
#include <winsock.h>
#include <time.h>
#endif
#if defined(SUNOS) || defined(SOLARIS)
#include <netinet/in.h>
#include <sys/wait.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define UX_THREADS_C
/* Bring in specific header files.
*/
#include "ux.h"
/******************************************************************************
* Internal Library functions.
******************************************************************************/
/* Internal structures: A global Mutex lock set, split up into sections,
* which the threads examine and wait on according to
* their state.
*
* No lock in all _SL functions, can only be entered by the SL library
* thread. During initialisation, store id of SL thread, compare upon entry
* to the library and exit with error if id incorrect.
*
* Single lock for all SL functions. Upon entry, thread checks lock,
* if its free, it sets it and proceeds. If its locked, it waits till it
* becomes free.
*
*
*/
/* Internal Function: Create Thread and Add to Linked List. Linked List to
* contain Mutex Locks for local locks and global lock set.
*
* Delete Thread.
*/
/******************************************************************************
* Function: _TM_<INTERNAL FUNCTION NAME>
* Description: <Description of Function>
*
* Returns: <RETURN PARAMETERS>.
******************************************************************************/
/******************************************************************************
* User API functions.
******************************************************************************/
/* API Function: Create New Thread. Calls Internal function with Mutex
* protection.
*
* API Function: Delete or Terminate existing thread. Calls Internal function.
*
*
*/
/******************************************************************************
* Function: TM_<API FUNCTION NAME>
* Description: <Description of Function>
*
* Returns: <RETURN PARAMETERS>.
******************************************************************************/
/******************************************************************************
* Function: TM_Init
* Description: Function to initialise the Thread Management Library.
*
* Returns: R_OK - Succeeded.
* R_FAIL - Failed to init, see errno and szErrMsg.
******************************************************************************/
int TM_Init( UCHAR *szErrMsg ) /* O: Error message if function fails */
{
/* Local variables.
*/
char *szFunc = "TM_Init";
/* Initialise control&tracking linked list.
*/
/* Got this far, exit with success.
*/
return(R_OK);
}
/******************************************************************************
* Function: TM_Exit
* Description: Function to terminate all threads and clear the
* control&tracking records. Must be the main parent thread
* ie. Thread0 that calls this function otherwise an error
* is returned.
*
* Returns: R_OK - Succeeded.
* R_FAIL - Failed to exit, see errno and szErrMsg.
******************************************************************************/
int TM_Exit( UCHAR *szErrMsg ) /* O: Error message if function fails */
{
/* Local variables.
*/
char *szFunc = "TM_Init";
/* Free up all resources used by the control&tracking linked list.
*/
/* Got this far, exit with success.
*/
return(R_OK);
}
/******************************************************************************
* Function: TM_CreateThread
* Description: Function to create a new thread. Uses current thread as
* base, allocates a new control&tracking record which gets
* stored in the Thread Management linked list and releases
* the thread onto the supplied start function.
*
* Author: P.D. Smart
* Returns: R_OK - Succeeded.
* R_FAIL - Failed to create thread, see errno and szErrMsg.
******************************************************************************/
int TM_CreateThread( /* I: Start Function */
UCHAR *szErrMsg ) /* O: Error msg if func fails */
{
/* Local variables.
*/
char *szFunc = "TM_CreateThread";
/* Got this far, exit with success.
*/
return(R_OK);
}
/******************************************************************************
* Function: TM_KillThread
* Description: Function to kill a requested thread. Once killed, the
* control&tracking lists are updated.
*
* Returns: R_OK - Succeeded.
* R_FAIL - Failed to kill thread, see errno and szErrMsg.
******************************************************************************/
int TM_Create( /* I: Thread Id */
UCHAR *szErrMsg ) /* O: Error msg if func fails */
{
/* Local variables.
*/
char *szFunc = "TM_KillThread";
/* Got this far, exit with success.
*/
return(R_OK);
}

0
ux_test/.pure Executable file
View File

152
ux_test/Makefile Executable file
View File

@@ -0,0 +1,152 @@
#******************************************************************************
#* Product:
#* ####### ####### ##### ####### ##### # # ### ####### #######
#* # # # # # # # # # # # #
#* # # # # # # # # # #
#* # ##### ##### # ##### # # # # #####
#* # # # # # # # # # #
#* # # # # # # # # # # # #
#* # ####### ##### # ##### ##### ##### ### # #######
#*
#* File: Makefile
#* Description: Build description file for the test suite of programs.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
TITLE = "Program Test Suite"
COPYRIGHT = "(C) P.D.Smart, %D%, Vers %I%"
PROJ =
PURIFY = #purify
PROJPATH = ../ux_test
GNUINCLUDE = #-I/apps/gnu/$(ARCH)/include
MDCINCLUDE = -I../MDC
SDDINCLUDE = -I../SDD
UXINCLUDE = -I../ux
INCLUDEDIR = -I. $(UXINCLUDE) $(MDCINCLUDE) $(SDDINCLUDE) $(GNUINCLUDE)
1DEBUGFLAGS = -g #-DMDC_DEBUG #-E
4DEBUGFLAGS = -g #-DMDC_DEBUG #-E
5DEBUGFLAGS = -g #-DMDC_DEBUG #-E
1OPTIMIZEFLAGS = #-O2
4OPTIMIZEFLAGS = #-O2
5OPTIMIZEFLAGS = #-O2
1OPTIONFLAGS = -D${OS} #-ansi -Wall
4OPTIONFLAGS = -D${OS} #-ansi -Wall
5OPTIONFLAGS = -D${OS} -D_REENTRANT #-ansi -Wall
CFLAGS = $(${OSVER}DEBUGFLAGS) $(${OSVER}OPTIMIZEFLAGS) \
$(${OSVER}OPTIONFLAGS)
LDFLAGS = #-static
MDCLIBS = -L../MDC/${OSVER}lib -lmdc
ODBCLIBS = -L../odbc/dlls -lodbc
SDDLIBS = -L../SDD/${OSVER}lib -lsdd
UXLIBS = -L../ux/${OSVER}lib -lux
1SYBLIBS =
4SYBLIBS = -L/apps/sybase/lib -lsybdb
5SYBLIBS = -L/apps/sybase/lib -lsybdb
1LIBS = -lm
4LIBS = -lm
5LIBS = -L/usr/ucblib -lsocket -lnsl -lucb #-liberty -lucb
LIBS = $(UXLIBS) $(${OSVER}LIBS)
SCCSFLAGS = -d$(PROJPATH)
SCCSGETFLAGS =
ifeq ($(ZPU_BUILD),)
BASE =
else
BASE = zpu-elf-
endif
CC = $(BASE)gcc
LD = $(BASE)gcc
AS = $(BASE)as
AR = $(BASE)ar
CP = $(BASE)objcopy
DUMP = $(BASE)objdump
RANLIB = $(BASE)ranlib
# Suffixes where interested in for this project.
#
.SUFFIXES:
.SUFFIXES: .o .c .h
# Our way of making an object file.
#
.c.o:
$(PURIFY) $(CC) $(INCLUDEDIR) $(CFLAGS) -c $<
# All, ie: all programs to be built
#
all:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Use 'build' command to make Test Suite."
TestSuite: Begin \
test_mon \
End
# How to clean up the directory... make it look pretty!
#
clean: Begin \
DoClean \
End
# How to perform an installation of the resultant software.
#
install: Begin \
DoInstall \
End
#
# Pre-make start sequence.
#
Begin:
@echo $(TITLE)
@echo $(COPYRIGHT)
@echo
@echo "Operation commencing @ `date`"
@echo
#
# Post-make completion sequence.
#
End:
@echo
@echo "Completed @ `date`"
# Perform all cleanup operations to ensure future builds occur
# with completeness.
#
DoClean:
rm -f *.o *.bak *.a *.BAK *.sav core
# Perform installation of software as per spec.
#
DoInstall:
# Build the Monitor Facility test program.
#
test_mon: test_mon.o
$(PURIFY) $(CC) $(LDFLAGS) -o test_mon \
test_mon.o \
$(LIBS)
@echo "Monitor Facility Test Program 'test_mon' built."
test_mon.o: test_mon.c test_mon.h

170
ux_test/build Executable file
View File

@@ -0,0 +1,170 @@
#!/bin/csh
#******************************************************************************
#* Product:
#* ####### ####### ##### ####### ##### # # ### ####### #######
#* # # # # # # # # # # # #
#* # # # # # # # # # #
#* # ##### ##### # ##### # # # # #####
#* # # # # # # # # # #
#* # # # # # # # # # # # #
#* # ####### ##### # ##### ##### ##### ### # #######
#*
#* File: build
#* Description: Build description file for all test programs relevant to the
#* ux libraries.
#* Version: %I%
#* Dated: %D%
#* Copyright: P.D. Smart, 1996-2019.
#*
#* History: 1.0 - Initial Release.
#*
#******************************************************************************
#* This source file is free software: you can redistribute it and#or modify
#* it under the terms of the GNU General Public License as published
#* by the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This source file is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#******************************************************************************
# Work out architecture we are compiling on..
#
setenv ARCH `uname -s`
setenv ARCH ${ARCH}`uname -r | cut -c1`
# Work out arguments and decide on actions from there.
#
if( $#argv > 0 ) then
switch("$argv[1]")
case "save":
make -f Makefile clean
sccs delta SCCS
exit 0
case "install":
echo "Nothing to install.."
exit 0
case "zpu":
setenv ARCH 'ZPU'
set makecmd="TestSuite"
breaksw
default:
# If the command is not one this script recognises then pass on to
# the makefile.
#
set makecmd="$argv[1]"
endsw
else
set makecmd="TestSuite"
endif
# Build according to parameter supplied.
#
switch ($ARCH)
case "SunOS4":
setenv OS "SUNOS"
setenv OSVER 4
echo "SunOS operating system build"
if( ! -r .sunos ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .sunos
chmod 777 .sunos
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r test_mon ) then
\mv -f test_mon ${OSVER}bin
endif
breaksw
case "SunOS5":
setenv OS "SOLARIS"
setenv OSVER 5
echo "Solaris operating system build"
if( ! -r .solaris ) then
\rm -f .solaris
\rm -f .sunos
\rm -f .linux
\rm -f .zpu
touch .solaris
chmod 777 .solaris
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r test_mon ) then
\mv -f test_mon ${OSVER}bin
endif
breaksw
case "Linux2":
case "Linux4":
setenv OS "LINUX"
setenv OSVER 1
echo "Linux operating system build"
echo ""
if( ! -r .linux ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .linux
chmod 777 .linux
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile $makecmd
set result = $status
endif
if( $result == 0 && -r test_mon ) then
\mv -f test_mon ${OSVER}bin
endif
breaksw
case "ZPU":
setenv OS "ZPU"
setenv OSVER 1
echo "ZPU operating system build"
echo ""
if( ! -r .zpu ) then
\rm -f .sunos
\rm -f .solaris
\rm -f .linux
\rm -f .zpu
touch .zpu
chmod 777 .zpu
make -f Makefile clean $makecmd
set result = $status
else
make -f Makefile ZPU_BUILD=1 $makecmd
set result = $status
endif
if( $result == 0 && -r test_mon ) then
\mv -f test_mon ${OSVER}bin
endif
breaksw
default:
echo "Unknown architecture, cannot build library..."
breaksw
endsw

548
ux_test/test_mon.c Executable file
View File

@@ -0,0 +1,548 @@
/******************************************************************************
* Product: ####### ####### ##### ####### # # ####### # #
* # # # # # ## ## # # ## #
* # # # # # # # # # # # # #
* # ##### ##### # # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # # # ##
* # ####### ##### # ####### # # ####### # #
*
* File: test_mon.c
* Description: A Test Harness program specifically for testing out ux
* monitor functionality. Ie the ability to add an interactive
* monitor to any application.
*
* Version: %I%
* Dated: %D%
* Copyright: P.D. Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Bring in system header files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
/* Bring in UX header files.
*/
#include <ux.h>
/* Specials for Solaris.
*/
#if defined(SOLARIS) || defined(LINUX) || defined(ZPU)
#include <sys/types.h>
#endif
/* Indicate that we are a C module for any header specifics.
*/
#define TEST_MON_C
/* Bring in local specific header files.
*/
#include "test_mon.h"
/******************************************************************************
* Function: _HTML_GetHandler
* Description: Call back to override default HTML GET handler. This function
* works out what the client browser requires and tries to
* satisfy it.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _HTML_GetHandler( UINT nChanId, /* I: Channel Id of new con */
UCHAR *szData, /* I: Data received by WWW */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
int nCnt=0;
int nChar;
UINT nPos = 0;
UINT nTokType;
UCHAR *spEndStr;
UCHAR *spMsgBuf = NULL;
UCHAR szFileName[MAX_FILENAMELEN+1];
char *szFunc = "_HTML_GetHandler";
FILE *fp;
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc,
"GET Handler called: Data=%s, nChanId=%d, MonPort=%d\n",
szData, nChanId, nMonPort);
/* Setup HTML content type.
*/
ML_Send(nChanId, "Content-type: text/html\n\n", 0);
/* Scan the buffer for the recognised browser end of stream:
* HTTP/version. If it doesnt exist, send an error message to client
* and exit.
*/
if( (spMsgBuf=(UCHAR *)malloc((strlen(szData)*3)+1)) == NULL )
{
/* Get out with a failure, memory exhausted.
*/
ML_Send(nChanId, "<HTML><TITLE>Out of Memory</TITLE>"
"Out of Memory, Re-Try Later</HTML>/n/n", 0);
if(spMsgBuf != NULL) free(spMsgBuf);
return(R_FAIL);
}
if((spEndStr=strstr(szData, "HTTP")) != NULL)
{
/* Command we are required to understand lies between the beginning
* of the buffer and where HTTP starts, extract it.
*/
FFwdOverWhiteSpace(szData, &nPos);
strncpy(spMsgBuf, &szData[nPos], ((spEndStr - szData)-nPos));
spMsgBuf[(spEndStr - szData)-nPos] = '\0';
} else
{
/* Dispatch an error message to the client as their is not much
* we can do.
*/
ML_Send(nChanId, "<HTML><TITLE>Illegal HTML</TITLE>"
"The HTML that your browser issued is illegal, or it is from"
" a newer version not supported by this product</HTML>\n\n", 0);
return(R_FAIL);
}
/* Trim off the fat and open file.
*/
strcpy(szFileName, StrRTrim(spMsgBuf));
if((fp=fopen(szFileName, "r")) == NULL)
{
sprintf(spMsgBuf, "<HTML><TITLE>Cannot access %s</TITLE>"
"<H1>File Not Available</H1>\n"
"The file requested (%s) cannot be accessed.</HTML>\n\n",
szFileName, szFileName);
ML_Send(nChanId, spMsgBuf, 0);
return(R_FAIL);
} else
{
/* Crude but effective, read 1 byte at a time and fire it off,
* wrapped in a HTML structure.
*/
ML_Send(nChanId, "<HTML>\n<BODY><PRE>\n", 0);
spMsgBuf[1]='\0';
while((nChar=fgetc(fp)) != EOF)
{
nCnt++;
spMsgBuf[0]=nChar;
ML_Send(nChanId, spMsgBuf, 1);
}
ML_Send(nChanId, "</PRE></BODY></HTML>", 0);
fclose(fp);
}
/* All done, get out!
*/
return(R_OK);
}
/******************************************************************************
* Function: _HTML_ConnectCB
* Description: Call back for when an incoming WWW browser makes a connection
* with us.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _HTML_ConnectCB( UINT nChanId, /* I: Channel Id of new con */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
char *szFunc = "_HTML_ConnectCB";
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc, "New Connection: ChanID=%d, MonPort=%d\n",
nChanId, nMonPort);
/* All done, get out!
*/
return;
}
/******************************************************************************
* Function: _HTML_DisconnectCB
* Description: Call back for when an existing WWW browser connection ceases
* to exist.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _HTML_DisconnectCB( UINT nChanId, /* I: Channel Id of new con */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
char *szFunc = "_HTML_DisconnectCB";
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc, "Connection Closed: ChanID=%d, MonPort=%d\n",
nChanId, nMonPort);
/* All done, get out!
*/
return;
}
/******************************************************************************
* Function: _NL_HelpHandler
* Description: Call back to implement a HELP feature in the natural
* language command interface. This command basically lists
* global or specific help according to the arguments of the
* command and fires it back to the client.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _NL_HelpHandler( UINT nChanId, /* I: Channel Id of new con */
UCHAR *szData, /* I: Data received by WWW */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
char *szFunc = "_NL_HelpHandler";
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc,
"Help Handler called: Data=%s, nChanId=%d, MonPort=%d\n",
szData, nChanId, nMonPort);
/* All done, get out!
*/
return(R_OK);
}
/******************************************************************************
* Function: _NL_ConnectCB
* Description: Call back for when an incoming WWW browser makes a connection
* with us.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _NL_ConnectCB( UINT nChanId, /* I: Channel Id of new con */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
char *szFunc = "_NL_ConnectCB";
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc, "New Connection: ChanID=%d, MonPort=%d\n",
nChanId, nMonPort);
/* All done, get out!
*/
return;
}
/******************************************************************************
* Function: _NL_DisconnectCB
* Description: Call back for when an existing WWW browser connection ceases
* to exist.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int _NL_DisconnectCB( UINT nChanId, /* I: Channel Id of new con */
UINT nMonPort ) /* I: Monitor Port Number */
{
/* Local variables.
*/
char *szFunc = "_NL_DisconnectCB";
/* Log a debug message to indicate details of this connection.
*/
Lgr(LOG_DEBUG, szFunc, "Connection Closed: ChanID=%d, MonPort=%d\n",
nChanId, nMonPort);
/* All done, get out!
*/
return;
}
/******************************************************************************
* Function: GetConfig
* Description: Get configuration information from the OS or command line
* flags.
*
* Returns: R_OK - Configuration obtained.
* R_FAIL - Failure, see error message.
******************************************************************************/
int GetConfig( int argc, /* I: CLI argument count */
UCHAR **argv, /* I: CLI argument contents */
char **envp, /* I: Environment variables */
UCHAR *szErrMsg ) /* O: Any generated error message */
{
/* Local variables.
*/
int nReturn = R_OK;
FILE *fp;
UCHAR *szFunc = "GetConfig";
/* See if the user wishes to use a logfile?
*/
if( GetCLIParam(argc, argv, FLG_LOGFILE, T_STR, TMON.szLogFile,
MAX_LOGFILELEN, FALSE) == R_OK )
{
/* Check to see if the filename is valid.
*/
if((fp=fopen(TMON.szLogFile, "a")) == NULL)
{
sprintf(szErrMsg, "Cannot write to logfile (%s)", TMON.szLogFile);
return(R_FAIL);
}
/* Close the file as test complete.
*/
fclose(fp);
} else
{
/* Set logfile to a default, dependant on OS.
*/
strcpy(TMON.szLogFile, DEF_LOGFILE);
}
/* Get log mode from command line.
*/
if(GetCLIParam(argc, argv, FLG_LOGMODE, T_INT, (UCHAR *)&TMON.nLogMode,
0, 0) == R_OK)
{
/* Check the validity of the mode.
*/
if((TMON.nLogMode < LOG_OFF || TMON.nLogMode > LOG_FATAL) &&
TMON.nLogMode != LOG_CONFIG)
{
sprintf(szErrMsg, "Illegal Logger mode (%d)", TMON.nLogMode);
return(R_FAIL);
}
} else
{
/* Setup default log mode.
*/
TMON.nLogMode = LOG_DEBUG;
}
/* Get the port to be used for HTML monitoring.
*/
if(GetCLIParam(argc, argv, FLG_HTMLPORT, T_INT, (UCHAR *)&TMON.nHtmlPort,
0, 0) == R_OK)
{
/* Check the validity of the port.
*/
if((TMON.nHtmlPort < 2000 || TMON.nHtmlPort > 10000))
{
sprintf(szErrMsg, "Illegal HTML TCP Port (%d)", TMON.nHtmlPort);
return(R_FAIL);
}
} else
{
/* Setup default port.
*/
TMON.nHtmlPort = DEF_HTML_PORT;
}
/* Get the port to be used for HTML monitoring.
*/
if(GetCLIParam(argc, argv, FLG_NLPORT, T_INT, (UCHAR *)&TMON.nNLPort,
0, 0) == R_OK)
{
/* Check the validity of the port.
*/
if((TMON.nNLPort < 2000 || TMON.nNLPort > 10000))
{
sprintf(szErrMsg, "Illegal Natural Language TCP Port (%d)",
TMON.nNLPort);
return(R_FAIL);
}
} else
{
/* Setup default port.
*/
TMON.nNLPort = DEF_NL_PORT;
}
/* Finished, get out!
*/
return( nReturn );
}
/******************************************************************************
* Function: TMONInit
* Description: Initialisation of variables, functionality, communications etc.
*
* Returns: VDWD_OK - Initialised successfully.
* VDWD_FAIL - Failure, see error message.
******************************************************************************/
int TMONInit( UCHAR *szErrMsg ) /* O: Generated error message */
{
/* Local variables.
*/
char *szFunc = "TMONInit";
/* Setup logger mode.
*/
Lgr(LOG_CONFIG, LGM_FLATFILE, TMON.nLogMode, TMON.szLogFile);
/* Initialise Socket Library.
*/
if(SL_Init(TMON_SRV_KEEPALIVE, (UCHAR *)NULL) != R_OK)
{
sprintf(szErrMsg, "SL_Init failed");
Lgr(LOG_DEBUG, szFunc, szErrMsg);
return(R_FAIL);
}
/* Initialise Monitor Library for HTML servicing.
*/
if(ML_Init(TMON.nHtmlPort, MON_SERVICE_HTML, "Test Monitor Program (HTML)",
_HTML_ConnectCB, _HTML_DisconnectCB, NULL) == R_FAIL)
{
sprintf(szErrMsg, "ML_Init failed for HTML service");
Lgr(LOG_DEBUG, szFunc, szErrMsg);
return(R_FAIL);
}
/* Initialise Monitor Library for Natural Language servicing.
*/
if(ML_Init(TMON.nNLPort, MON_SERVICE_NL, "Test Monitor Program (NL)",
_NL_ConnectCB, _NL_DisconnectCB, NULL) == R_FAIL)
{
sprintf(szErrMsg, "ML_Init failed for NL service");
Lgr(LOG_DEBUG, szFunc, szErrMsg);
return(R_FAIL);
}
/* Add test commands for HTML.
*/
ML_AddMonCommand(TMON.nHtmlPort, MC_HTMLGET, _HTML_GetHandler);
/* Add test commands for Natural Language.
*/
ML_AddMonCommand(TMON.nNLPort, MC_NLHELP, _NL_HelpHandler);
/* All done, lets get out.
*/
return(R_OK);
}
/******************************************************************************
* Function: TMONClose
* Description: Function to perform closure of all used resources within the
* program.
*
* Returns: R_OK - Closed successfully.
* R_FAIL - Failure, see error message.
******************************************************************************/
int TMONClose( UCHAR *szErrMsg ) /* O: Generated error message */
{
/* Local variables.
*/
char *szFunc = "TMONClose";
/* Call monitor library to close and tidy up.
*/
if(ML_Exit(NULL) == R_FAIL)
{
Lgr(LOG_DEBUG, szFunc, "Failed to close Monitor Library");
}
/* Exit with success.
*/
return(R_OK);
}
/******************************************************************************
* Function: main
* Description: Entry point into the Monitor facility Test program. Basic
* purpose is to invoke intialisation, enter the main program
* loop and finally tidy up and close down.
*
* Returns: 0 - Program completed successfully without errors.
* -1 - Program terminated with errors, see logged message.
******************************************************************************/
int main( int argc, /* I: Count of available arguments */
char **argv, /* I: Array of arguments */
char **envp ) /* I: Array of environment parameters */
{
/* Local variables.
*/
UCHAR szErrMsg[MAX_ERRMSG_LEN];
UCHAR *szFunc = "main";
/* Bring in any configuration parameters passed on the command line etc.
*/
if( GetConfig(argc, (UCHAR **)argv, envp, szErrMsg) == R_FAIL )
{
printf( "%s\n"
"Usage: %s <parameters>\n"
"<parameters>: -l<LogFile Name>\n"
" -m<Logging Mode>\n"
" -html_port<TCP Port No>\n"
" -nl_port<TCP Port No>\n",
szErrMsg, argv[0]);
}
/* Initialise variables, communications etc.
*/
if( TMONInit(szErrMsg) == R_FAIL )
{
/* Log an error message to indicate reason for failure.
*/
Lgr(LOG_DIRECT, szFunc, "%s: %s", argv[0], szErrMsg);
exit(-1);
}
/* Do nothing basically, where testing monitor functionality, so just loop.
*/
while(TRUE)
{
SL_Poll(DEF_POLLTIME);
}
/* Perform close down of used facilities ready for exit.
*/
if( TMONClose(szErrMsg) == R_FAIL )
{
/* Log an error message to indicate reason for failure.
*/
Lgr(LOG_DIRECT, szFunc, "%s: %s", argv[0], szErrMsg);
exit(-1);
}
/* All done, go bye bye's.
*/
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(ZPU)
exit;
#endif
#if defined(_WIN32)
return(0);
#endif
}

98
ux_test/test_mon.h Executable file
View File

@@ -0,0 +1,98 @@
/******************************************************************************
* Product: ####### ####### ##### ####### # # ####### # #
* # # # # # ## ## # # ## #
* # # # # # # # # # # # # #
* # ##### ##### # # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # # # ##
* # ####### ##### # ####### # # ####### # #
*
* File: test_mon.h
* Description: Header file for declaration of structures, datatypes etc for
* the ux library monitor testing program.
* Version: %I%
* Dated: %D%
* Copyright: P.D.Smart, 1996-2019.
*
* History: 1.0 - Initial Release.
*
******************************************************************************
* This source file is free software: you can redistribute it and#or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This source file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Ensure file is only included once - avoid compile loops.
*/
#ifndef TEST_MON_H
#define TEST_MON_H
/* Definitions for maxims etc.
*/
#define MAX_ERRMSG_LEN 256
#define MAX_LOGFILELEN 256
/* Definitions for defaults.
*/
#define DEF_HTML_PORT 9000
#define DEF_NL_PORT 9001
#define DEF_POLLTIME 1000
#if defined(SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(ZPU)
#define DEF_LOGFILE "/tmp/test_mon.log"
#endif
#if defined(_WIN32)
#define DEF_LOGFILE "\\TEST_MON.LOG"
#endif
/* Define constants etc.
*/
#define TMON_SRV_KEEPALIVE 1000 /* TCP/IP keep alive */
/* Define command line flags.
*/
#define FLG_LOGFILE "-l"
#define FLG_LOGMODE "-m"
#define FLG_HTMLPORT "-html_port"
#define FLG_NLPORT "-nl_port"
/* Monitor commands for Natural Language interface.
*/
#define MC_NLHELP "HELP"
/* Maxims.
*/
#define MAX_FILENAMELEN 80
/* Globals (yuggghhh!).
*/
typedef struct {
int nHtmlPort;
int nNLPort;
UINT nLogMode;
UCHAR szLogFile[MAX_LOGFILELEN];
} TMON_GLOBALS;
/* Declare any globals required by the daemon, or any specifics to the
* C module.
*/
#if defined(TEST_MON_C)
static TMON_GLOBALS TMON={9000, 9001, LOG_DEBUG, ""};
#endif
/* Prototypes for functions.
*/
int GetConfig( int, UCHAR **, char **, UCHAR * );
int TMONInit( UCHAR * );
int TMONClose( UCHAR * );
int main( int, char **, char ** );
#endif /* TEST_MON_H */