Initial upload
This commit is contained in:
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal 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
144
MDC/Makefile
Executable 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
182
MDC/build
Executable 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
137
MDC/mdc.h
Executable 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
1466
MDC/mdc_client.c
Executable file
File diff suppressed because it is too large
Load Diff
148
MDC/mdc_common.c
Executable file
148
MDC/mdc_common.c
Executable 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
211
MDC/mdc_common.h
Executable 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
815
MDC/mdc_server.c
Executable 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
156
SDD/Makefile
Executable 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
174
SDD/build
Executable 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
159
SDD/sdd.h
Executable 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
522
SDD/sdd_aupl.c
Executable 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
71
SDD/sdd_aupl.h
Executable 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
2178
SDD/sdd_ftpx.c
Executable file
File diff suppressed because it is too large
Load Diff
126
SDD/sdd_ftpx.h
Executable file
126
SDD/sdd_ftpx.h
Executable 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
199
SDD/sdd_java.c
Executable 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
42
SDD/sdd_java.h
Executable 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
1671
SDD/sdd_odbc.c
Executable file
File diff suppressed because it is too large
Load Diff
80
SDD/sdd_odbc.h
Executable file
80
SDD/sdd_odbc.h
Executable 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
1282
SDD/sdd_scmd.c
Executable file
File diff suppressed because it is too large
Load Diff
87
SDD/sdd_scmd.h
Executable file
87
SDD/sdd_scmd.h
Executable 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
1204
SDD/sdd_sybc.c
Executable file
File diff suppressed because it is too large
Load Diff
85
SDD/sdd_sybc.h
Executable file
85
SDD/sdd_sybc.h
Executable 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
157
SDD/templates/sdd_xxxx.c
Executable 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
42
SDD/templates/sdd_xxxx.h
Executable 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
3
VDW/1bin/RunForLinuxClient
Executable 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
5
VDW/4bin/RunForSunOSClient
Executable 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
4
VDW/5bin/Run
Executable 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
4
VDW/5bin/RunForSolarisClient
Executable 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
154
VDW/Makefile
Executable 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
172
VDW/build
Executable 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
77
VDW/config.c
Executable 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
726
VDW/vdwd.c
Executable 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
117
VDW/vdwd.h
Executable 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 */
|
||||
150
ux/Makefile
Executable file
150
ux/Makefile
Executable 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
184
ux/build
Executable 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
48
ux/ux.h
Executable 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
174
ux/ux_cli.c
Executable 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
692
ux/ux_cmprs.c
Executable 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
49
ux/ux_cmprs.h
Executable 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
2399
ux/ux_comms.c
Executable file
File diff suppressed because it is too large
Load Diff
236
ux/ux_comms.h
Executable file
236
ux/ux_comms.h
Executable 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
114
ux/ux_comon.h
Executable 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
152
ux/ux_dtype.h
Executable 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
255
ux/ux_lgr.c
Executable 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
661
ux/ux_linkl.c
Executable 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
1097
ux/ux_mon.c
Executable file
File diff suppressed because it is too large
Load Diff
122
ux/ux_mon.h
Executable file
122
ux/ux_mon.h
Executable 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
766
ux/ux_str.c
Executable 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
223
ux/ux_thrd.c
Executable 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
0
ux_test/.pure
Executable file
152
ux_test/Makefile
Executable file
152
ux_test/Makefile
Executable 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
170
ux_test/build
Executable 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
548
ux_test/test_mon.c
Executable 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
98
ux_test/test_mon.h
Executable 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 */
|
||||
Reference in New Issue
Block a user