/* Command: ZRUNSQL */
ZRUNSQL: CMD PROMPT('Execute SQL statement')
SQLSTMT: PARM KWD(SQLSTMT) TYPE(*CHAR) LEN(3000) MIN(1) +
EXPR(*YES) VARY(*YES *INT4) PROMPT('SQL +
statement')
LOG: PARM KWD(LOG) TYPE(*CHAR) LEN(4) RSTD(*YES) +
DFT(*NO) VALUES(*YES *NO) EXPR(*YES) +
PROMPT('Log results?')
PRTDEV: PARM KWD(PRTDEV) TYPE(*NAME) LEN(10) DFT(*JOB) +
SPCVAL((*JOB) (*SYSVAL)) PROMPT('Printer +
device')
USRDTA: PARM KWD(USRDTA) TYPE(*CHAR) LEN(10) DFT('ZSQL +
log') SPCVAL((*NONE ' ') (*JOB) (*USER) +
(*DATE)) PROMPT('Spool file user data')
ALLROWWRN: PARM KWD(ALLROWWRN) TYPE(*CHAR) LEN(4) RSTD(*YES) +
DFT(*YES) VALUES(*YES *NO) EXPR(*YES) +
PROMPT('Warn if all rows?')
BORDCOL: PARM KWD(BORDCOL) TYPE(*CHAR) LEN(6) RSTD(*YES) +
DFT(*BLUE) VALUES(*BLUE *GREEN *WHITE +
*PINK *RED) SPCVAL((*BLUE X'3B') (*RED +
X'29') (*GREEN X'21') (*WHITE X'23') +
(*PINK X'39')) EXPR(*YES) PROMPT('Window +
border color')
TEXTCOL: PARM KWD(TEXTCOL) TYPE(*CHAR) LEN(6) RSTD(*YES) +
DFT(*WHITE) VALUES(*BLUE *GREEN *WHITE +
*PINK *RED) SPCVAL((*BLUE X'3A') (*RED +
X'28') (*GREEN X'20') (*WHITE X'22') +
(*PINK X'38')) EXPR(*YES) PROMPT('Window +
text color')
MODE: PARM KWD(MODE) TYPE(*CHAR) LEN(6) RSTD(*YES) +
DFT(*EXEC) VALUES(*CHECK *EXEC) +
EXPR(*YES) PROMPT('Run mode (*EXEC / +
*CHECK)')
/* CLP: ZRUNSQL */
ZRUNSQL: PGM PARM(&SQLSTMT &LOG &PRTDEV &USRDTA +
&ALLROWWRN &BORDERCOL &TEXTCOL &MODE)
DCL VAR(&SQLSTMT) TYPE(*CHAR) LEN(3004)
DCL VAR(&LOG) TYPE(*CHAR) LEN( 4)
DCL VAR(&PRTDEV) TYPE(*CHAR) LEN( 10)
DCL VAR(&USRDTA) TYPE(*CHAR) LEN( 10)
DCL VAR(&ALLROWWRN) TYPE(*CHAR) LEN( 4)
DCL VAR(&BORDERCOL) TYPE(*CHAR) LEN( 6)
DCL VAR(&TEXTCOL) TYPE(*CHAR) LEN( 6)
DCL VAR(&MODE) TYPE(*CHAR) LEN( 6)
DCL VAR(&NULL) TYPE(*CHAR) LEN(1) VALUE(X'00')
DCL VAR(&STMTLEN) TYPE(*DEC ) LEN(5 0)
DCL VAR(&ERRORSW) TYPE(*LGL)
DCL VAR(&MSGID) TYPE(*CHAR) LEN( 7)
DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80)
DCL VAR(&PGM) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
/* Global MONMSG for unexpected errors. */
MONMSG MSGID(CPF0000 SQL0000) EXEC(GOTO CMDLBL(ERROR))
CHGVAR VAR(&STMTLEN) VALUE(%BINARY(&SQLSTMT 1 4))
CHGVAR VAR(&SQLSTMT) VALUE(%SST(&SQLSTMT 5 3000) +
*TCAT &NULL)
IF COND(&PRTDEV *EQ *SYSVAL) THEN(RTVSYSVAL +
SYSVAL(QPRTDEV) RTNVAR(&PRTDEV))
IF COND(&USRDTA *EQ *USER) THEN(RTVJOBA +
USER(&USRDTA))
IF COND(&USRDTA *EQ *JOB) THEN(RTVJOBA +
JOB(&USRDTA))
IF COND(&USRDTA *EQ *DATE) THEN(RTVJOBA +
DATE(&USRDTA))
OVRPRTF FILE(QSYSPRT) DEV(&PRTDEV) USRDTA(&USRDTA)
CALL PGM(RUNSQL.EXE) PARM(&SQLSTMT &LOG +
&ALLROWWRN &BORDERCOL &TEXTCOL &MODE)
RCVMSG MSGTYPE(*COMP) MSGDTA(&MSGDTA) MSGID(&MSGID) +
MSGF(&MSGF) MSGFLIB(&MSGFLIB)
IF COND(&MSGID *EQ ' ') THEN(RETURN)
SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
MSGDTA(&MSGDTA) MSGTYPE(*COMP)
RETURN
/* Standard error processing */
ERROR: IF COND(&ERRORSW) +
THEN(SNDPGMMSG MSGID(CPF9999) +
MSGF(QCPFMSG) +
MSGTYPE(*ESCAPE))
CHGVAR &ERRORSW '1'
ERROR1: RCVMSG MSGTYPE(*DIAG) +
MSGDTA(&MSGDTA) +
MSGID(&MSGID)
IF COND(&MSGID *EQ ' ') +
THEN(GOTO CMDLBL(ESCAPE))
SNDPGMMSG MSGID(&MSGID) +
MSGF(QSQLMSG) +
MSGDTA(&MSGDTA) +
MSGTYPE(*DIAG)
GOTO CMDLBL(ERROR1)
ESCAPE: RCVMSG MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) +
MSGF(&MSGF) MSGFLIB(&MSGFLIB)
SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)
ENDPGM: RETURN
ENDPGM
/* ============================================================================
**
** Filename : RUNSQL.EXE
**
** Description: Execute an SQL statement
**
** Parameters : 1) SQLSTMT - SQL statement
** 2) LOG - Print audit trail
** 3) ALLROWWRN - Warn if all rows to be updated/deleted
** 4) BORDCOL - Window border color (display attribute byte)
** 5) TEXTCOL - Window text color
** 6) MODE - Run mode (*EXEC / *CHECK)
** ============================================================================
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stddef.h>
#include <qsnapi.h>
/*
** ===========================================================================
** Defines go here
** ===========================================================================
*/
#define TOP_ROW 9
#define LEFT_COL 15
#define ROWS 6
#define COLS 49
#define TRUE 1
#define FALSE 0
#define JOB_FMT_BASIC_INFO "JOBI0100"
#define JOB_TYPE_INTERACTIVE 'I'
#define JOB_CURRENT_JOB "* "
#define SQLERRML sqlca.sqlerrml
#define SQLERRMC sqlca.sqlerrmc
#define SQLNUMREC sqlca.sqlerrd[3]
#define SQL_OK 0
#define SQLCODE sqlca.sqlcode
#define SQLWARN4 sqlca.sqlwarn[4]
#define SQLSTATE sqlca.sqlstate
#define SQLERRD sqlca.sqlerrd
#define SQLERRML sqlca.sqlerrml
#define TEXT1 "You are about to UPDATE or DELETE all rows"
#define TEXT2 "in the requested table. "
#define TEXT3 "Press F12 to CANCEL or ENTER to continue. "
#define COMP_MSG "*COMP "
#define ESC_MSG "*ESCAPE "
#define SQL_MSGF "QSQLMSG QSYS "
#define WDW_BORDER_BLANK " "
#define WDW_BORDER_DFT "...::..."
/*
** ===========================================================================
** Type definitions go here
** ===========================================================================
*/
typedef char T_JOB_QualName[26];
typedef char T_JOB_Format[8];
typedef char T_JOB_IntID[16];
typedef struct
{
T_JOB_QualName JobName;
T_JOB_IntID IntID;
} T_JOB_JobID;
typedef _Packed struct
{
long BytesRet;
long BytesAvail;
char JobName[10];
char UserName[10];
char JobNumber[6];
char InternalJobID[16];
char Status[10];
char Type;
char SubType;
char Reserved[2];
long RunPrty;
long TimeSlice;
long DefaultWait;
char Purge[10];
} T_JOB_Basic_Info;
typedef int T_Error;
typedef enum
{
ERR_UNDEFINED = -9999,
ERR_NOT_OK = -1,
ERR_OK = 0
} T_ErrorCode;
typedef struct T_WINDOW
{
Qsn_Win_Desc_T WdwDesc;
Qsn_Env_Desc_T LLEnv;
Qsn_Env_T LLEnvHandle;
} T_WINDOW;
/*
** ===========================================================================
** Function prototypes go here
** ===========================================================================
*/
T_Error PrintLongLine( FILE *pLog, char *pData, int DataSize, int BufferLen );
T_Error PrintMsg( FILE *pLog, char *pMsgID, char *pMsgData, long MsgDataLen );
T_Error WarnAllRows( void );
#pragma linkage( QUSRJOBI, OS )
extern void QUSRJOBI(
char *pRetData,
long RetDataLen,
T_JOB_Format FmtName,
T_JOB_QualName JobName,
T_JOB_IntID InternalID
);
T_Error RtvCurrJobInfo(
T_JOB_Basic_Info *pstBasicInfo
);
T_Error InitWdw(
T_WINDOW *pWdwDesc
);
T_Error SetWdwArea(
T_WINDOW *pWdwDesc,
int TopRow,
int LeftColumn,
int NbrRows,
int NbrColumns
);
T_Error SetWdwBorder(
T_WINDOW *pWdwDesc,
char Color,
char *pBorderChar
);
#pragma linkage( QMHSNDPM, OS )
extern void QMHSNDPM(
char *pMsgID,
char *pMsgFile,
char *pMsgData,
long MsgDataLen,
char *pMsgType,
char *pMsgQ,
long StackCnt,
char *pMsgKey,
char *pError
);
#pragma linkage( QMHRTVM, OS )
extern void QMHRTVM (
char *pMsgInfo,
long MsgInfoLen,
char *pFmtName,
char *pMsgID,
char *pMsgFile,
char *pMsgData,
long MsgDataLen,
char *pSubVar,
char *pRetFCC,
char *pError
);
T_Error SendMsg(
char *pMsgID,
char *pMsgFile,
char *pMsgData,
long MsgLen,
char *pMsgType
);
void DrawWindow( const Qsn_Win_T *win,
const Qsn_Cmd_Buf_T *cbuf );
/*
** ===========================================================================
** Global variables go here
** ===========================================================================
*/
T_WINDOW stWindow;
int BufferLen = -1; /* Print buffer length work field */
int PrintLog = FALSE, /* Print log report? */
ExecMode = FALSE, /* Execute SQL or just check */
SyntaxOK = FALSE, /* SQL syntax is OK */
SendEsc = FALSE; /* Send escape message at EOJ? */
FILE *pLog = NULL; /* Pointer to print file */
void *pSepLine = NULL; /* Report separator line */
Qsn_Win_Ext_Inf_T ext = { NULL, NULL, NULL, NULL, NULL, NULL };
Q_Bin4 win_desc_length = sizeof(Qsn_Win_Desc_T );
char text_color = QSN_SA_WHT;
int text_row = 2, text_col = 3;
long StackCount = 0;
struct sqlca
{ unsigned char sqlcaid[8];
long sqlcabc;
long sqlcode;
short sqlerrml;
unsigned char sqlerrmc[70];
unsigned char sqlerrp[8];
long sqlerrd[6];
unsigned char sqlwarn[11];
unsigned char sqlstate[5];
} ;
struct sqlca sqlca;
/*
** ===========================================================================
** Mainline processing
** ===========================================================================
*/
int main( int argc,
char *argv[] )
{
/* Declare local variables */
time_t start, finish;
T_Error ReturnError = ERR_OK;
T_JOB_Basic_Info stJobBasicInfo;
char pMsgID[8];
double elapsed = -1;
int seconds = -1,
minutes = -1,
hours = -1;
/* SQL stuff */
exec sql include SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
char pacSQLStmt[10000];
EXEC SQL END DECLARE SECTION;
/* Begin processing
Get job information so we can determine if running interactively */
ReturnError = RtvCurrJobInfo( &stJobBasicInfo );
/* Second parm is *YES or *NO indicating whether or not a log is to be
printed. Trap it here. */
if ( argc > 2 &&
memcmp( argv[2], "*YES", 4 ) == 0 )
{
PrintLog = TRUE;
}
/* Sixth parm is *EXEC or *CHECK indicating whether or not the SQL stmt
is to be executed or just syntax checked. Trap it here. */
if ( argc > 6 &&
memcmp( argv[6], "*EXEC ", 6 ) == 0 )
{
ExecMode = TRUE;
}
/* Copy incoming SQL statement to host variable */
strcpy( pacSQLStmt, argv[1] );
/* Open printer log if required and print headings. */
if ( PrintLog == TRUE )
{
pLog = fopen( "qsysprt", "w" );
BufferLen = 80; /* pLog->__buflen;*/
pSepLine = malloc( BufferLen );
memset( pSepLine, '-', BufferLen - 1 );
fprintf( pLog, "%sn", pSepLine );
time(&start);
fprintf( pLog, "SQL Log - Job: %.10s User: %.10s Number: %.6snn"
"Run date/time: %s",
stJobBasicInfo.JobName, stJobBasicInfo.UserName,
stJobBasicInfo.JobNumber, ctime(&start) );
fprintf( pLog, "%sn", pSepLine );
fprintf( pLog, "SQL statement : " );
PrintLongLine( pLog, pacSQLStmt, strlen( pacSQLStmt ), BufferLen );
fprintf( pLog, "nRun mode : %6.6sn", argv[6] );
}
/*
** Prepare the SQL statement. This will check the syntax and also determine
** if an UPDATE or DELETE with no WHERE clause is present. If syntax errors
** are found an error message is logged and sent to the user. If no WHERE
** clause is found and this is an interactive job and the user has NOT
** deactivated the warning processing a window will be displayed to give the
** user a chance to abandon processing.
*/
EXEC SQL PREPARE s1 FROM :pacSQLStmt;
if ( SQLCODE >= SQL_OK )
{
SyntaxOK = TRUE;
if ( SQLWARN4 == 'W' && /* no WHERE clause? */
stJobBasicInfo.Type == JOB_TYPE_INTERACTIVE && /* interactive? */
argc > 3 &&
ExecMode == TRUE &&
memcmp( argv[3], "*YES", 4 ) == 0 /* ALLROWWARN(*YES) */
)
{
ReturnError = InitWdw( &stWindow );
ReturnError = SetWdwBorder( &stWindow, QSN_SA_BLU_RI, NULL );
if ( argc > 4 )
ReturnError = SetWdwBorder( &stWindow, *argv[4], WDW_BORDER_BLANK );
if ( argc > 5 )
text_color = *argv[5];
WarnAllRows();
}
/*
** If we reach this point, then the SQL stmt is OK and the user has not
** chosen to abandon processing by hitting F12 in "WarnAllRows". If this
** is not just a syntax check then execute the SQL statment.
*/
if ( ExecMode == TRUE )
{
/* Print start time */
if ( PrintLog == TRUE )
{
time(&start);
fprintf( pLog, "nStart time : %s", ctime(&start) );
}
EXEC SQL EXECUTE IMMEDIATE :pacSQLStmt;
/* Print stop time, elapsed time and results of SQL execution */
if ( PrintLog == TRUE )
{
time(&finish);
fprintf( pLog, "End time : %s", ctime(&finish) );
elapsed = difftime( finish, start );
seconds = elapsed;
minutes = elapsed / 60;
hours = elapsed / (60 * 60);
fprintf( pLog, "Elapsed time : ---------- %02d:%02d:%02dn",
hours, minutes, seconds % 60 );
fprintf( pLog, "nSQL code : %dn", SQLCODE );
}
}
}
else
{
if ( PrintLog == TRUE )
{
fprintf( pLog,
"n (SQL statement contains errors)nn" );
}
}
/*
** If SQLCODE is less than zero then the SQL statement failed. Create a
** message number by concatenating "SQL" with the absolute value of the
** returned SQLCODE. Print the generated error message and set the flag to
** send an escape message later.
*/
if ( SQLCODE < SQL_OK )
{
sprintf( pMsgID, "SQL%4.4d", abs(SQLCODE) );
if ( PrintLog == TRUE )
{
if ( SyntaxOK == TRUE && ExecMode == TRUE )
{
fprintf( pLog,
"n (SQL statement was NOT processed)nn" );
}
fprintf( pLog, "nSQL code : %dn", abs(SQLCODE) );
fprintf( pLog, "nSQL state : %5.5sn", SQLSTATE );
fprintf( pLog, "nSQL MsgID : %sn", pMsgID );
PrintMsg( pLog, pMsgID, SQLERRMC, SQLERRML );
}
SendEsc = TRUE;
} /* SQLCODE < SQL_OK */
/* If SQLCODE is greater than or equal to zero then the SQL statement was
OK. Log the success if required and send a completion message. */
else
{
if ( PrintLog == TRUE )
{
if ( ExecMode == TRUE )
{
fprintf( pLog,
"n (SQL statement WAS successfully processed)nn" );
fprintf( pLog, "Rows processed : %dn", SQLERRD[2] );
}
else
{
fprintf( pLog,
"n (SQL statement contains no errors)nn" );
}
}
/* If SQLCODE is greater than zero then format a message ID the same as if
an error occurred. */
if ( SQLCODE != SQL_OK )
sprintf( pMsgID, "SQL%4.4d", abs(SQLCODE) );
/* If SQLCODE is zero then we have to get the number portion of the message
ID from SQLERRD[5]. SQL overlays this long int with 4 bytes of character
data. */
else
sprintf( pMsgID, "SQL%.4s", (char *)(&SQLERRD[5]) );
/* Send a completion message */
SendMsg( pMsgID, SQL_MSGF, SQLERRMC, SQLERRML, COMP_MSG );
if ( PrintLog == TRUE )
PrintMsg( pLog, pMsgID, SQLERRMC, SQLERRML );
}
if ( PrintLog == TRUE )
{
fprintf( pLog, "n*** End of SQL log report ***n%s", pSepLine );
fclose( pLog );
}
/* Send an escape message. This is done here because escape messages halt
processing. */
if ( SendEsc == TRUE )
SendMsg( pMsgID, SQL_MSGF, SQLERRMC, SQLERRML, ESC_MSG );
} /* EXCSQL.C */
/* ============================================================================
**
** Function : WarnAllRows
**
** Description: Displays a "window" that warns user that he/she is about to
** update / delete all rows in a table (SQL statement has no
** WHERE clause). User has the option to press ENTER to continue
** with the UPDATE / DELETE or press F12 to cancel. If the user
** chooses to cancel, processing is ended by sending SQL6107 as
** an *ESCAPE message.
*/
T_Error WarnAllRows( void )
{
T_Error ErrorReturned = ERR_OK;
unsigned char aid = -1;
ErrorReturned = SetWdwArea( &stWindow, TOP_ROW, LEFT_COL, ROWS, COLS );
ext.draw_fp = DrawWindow;
/* Create the window */
QsnCrtWin( &stWindow.WdwDesc, win_desc_length, &ext, sizeof(ext),
'1', NULL, 0, NULL, NULL );
/* Get attention key */
for ( ; aid != QSN_ENTER; )
{
if (( (aid=QsnGetAID(NULL, 0, NULL)) == QSN_F12))
{
if ( PrintLog == TRUE )
{
fprintf( pLog,
"n (SQL statement was NOT processed)nn" );
PrintMsg( pLog, "SQL6107", SQLERRMC, SQLERRML );
fprintf( pLog, "n*** End of SQL log report ***n%s", pSepLine );
fclose( pLog );
}
SendMsg( "SQL6107", SQL_MSGF, "", 0L, ESC_MSG );
exit(1);
}
else if ( aid == QSN_ENTER )
{
break;
}
}
} /* WarnAllRows */
/* ============================================================================
**
** Function : PrintLongLine
**
** Description: Prints the specifed data out to the SQL log report and handles
** line wrapping when the data exceeds the report width. Attempts
** to split sentences at blank space to produce a ragged right
** side.
*/
T_Error PrintLongLine( FILE *pLog, /* Pointer to print file */
char *pData, /* Data to be printed */
int DataSize, /* length of data */
int BufferLen ) /* Report width */
{
int Lines = -1, Rem = -1, PrintSize = BufferLen - 19, CurrLine,
FirstLine = TRUE;
char *pBuff = pData, *pEnd = NULL, *pEOL, *pNextChar;
if ( DataSize > 0 )
{
pEnd = pData + ( DataSize - 1 );
Lines = DataSize / PrintSize;
Rem = DataSize % PrintSize;
for ( CurrLine = 0;
CurrLine < Lines;
++CurrLine, pBuff = pEOL + 1, PrintSize = BufferLen - 19 )
{
if ( FirstLine != TRUE )
fprintf( pLog, " " );
if ( *pBuff == ' ' )
{
++pBuff;
--Rem;
}
pEOL = pBuff + ( PrintSize - 1 );
pNextChar = pBuff + PrintSize;
while( *pEOL != ' ' && *pNextChar != ' ' && pEOL > pBuff )
{
--pEOL;
--pNextChar;
++Rem;
}
PrintSize = ( pEOL - pBuff) + 1;
if ( PrintSize == 1 && pEnd != pBuff )
{
PrintSize = BufferLen - 19;
pEOL = pBuff + ( PrintSize - 1 );
Rem += BufferLen - 19;
}
fprintf( pLog, "%.*sn", PrintSize, pBuff );
FirstLine = FALSE;
if ( Rem >= ( BufferLen - 19) )
{
++Lines;
Rem = Rem - ( BufferLen - 19 );
}
}
if ( Rem > 0 )
{
if ( FirstLine != TRUE )
fprintf( pLog, " " );
if ( *pBuff == ' ' )
{
++pBuff;
--Rem;
}
fprintf( pLog, "%.*sn", Rem, pBuff );
}
}
}
/* ============================================================================
**
** Function : PrintMsg
**
** Description: Retrieves the descriptions for specified message ID and prints
** them out to the SQL log.
*/
T_Error PrintMsg( FILE *pLog,
char *pMsgID,
char *pMsgData,
long MsgDataLen )
{
char pMsgKey[4], pError[512], pMsgInfo[2096];
*(long *)pError = 496;
QMHRTVM( pMsgInfo, 2096L, "RTVM0100", pMsgID, SQL_MSGF, pMsgData,
MsgDataLen, "*YES ", "*NO ", pError );
fprintf( pLog, "Message : " );
PrintLongLine( pLog, pMsgInfo + 24, *(long *)(pMsgInfo + 8), BufferLen );
if ( *(long *)(pMsgInfo + 20) > 0 )
{
fprintf( pLog, "Help message : " );
PrintLongLine( pLog, pMsgInfo + 24 + *(long *)(pMsgInfo + 8),
*(long *)(pMsgInfo + 16), BufferLen );
}
} /* PrintMsg */
/* ============================================================================
**
** Function: RtvCurrJobInfo
**
** Description: Retrieves current job information
*/
T_Error RtvCurrJobInfo(
T_JOB_Basic_Info *pstBasicInfo
)
{
T_JOB_JobID stJobID;
T_Error LocalError = ERR_OK;
memcpy( stJobID.JobName, JOB_CURRENT_JOB, sizeof( stJobID.JobName) );
memset( stJobID.IntID, ' ', sizeof( stJobID.IntID ) );
QUSRJOBI( (void *)pstBasicInfo,
sizeof( T_JOB_Basic_Info ),
JOB_FMT_BASIC_INFO,
stJobID.JobName,
stJobID.IntID );
} /* RtvCurrJobInfo */
/* ============================================================================
**
** Function: InitWdw
**
** Description: Initialize a window description structure
*/
T_Error InitWdw( T_WINDOW *pWindow )
{
/* Initialize the window description */
QsnInzWinD( &pWindow->WdwDesc,
sizeof( Qsn_Win_Desc_T ),
NULL );
pWindow->WdwDesc.GUI_support = '0';
pWindow->WdwDesc.msg_line = '0';
memcpy ( &pWindow->WdwDesc.upper_left_border_char,
WDW_BORDER_DFT,
strlen( WDW_BORDER_DFT ) );
} /* InitWdw */
/* ============================================================================
**
** Function: SetWdwArea
**
** Description: Defines the area occupied by a window
*/
T_Error SetWdwArea(
T_WINDOW *pWindow,
int TopRow,
int LeftColumn,
int NbrRows,
int NbrColumns
)
{
if ( TopRow > 0 ) pWindow->WdwDesc.top_row = TopRow;
if ( LeftColumn > 0) pWindow->WdwDesc.left_col = LeftColumn;
if ( NbrRows > 0 ) pWindow->WdwDesc.num_rows = NbrRows;
if ( NbrColumns > 0 ) pWindow-> WdwDesc.num_cols = NbrColumns;
} /* SetWdwArea */
/* ============================================================================
**
** Function: SetWdwBorder
**
** Description: Sets window border display attributes
*/
T_Error SetWdwBorder(
T_WINDOW *pWindow,
char Color,
char *pBorderChar
)
{
if ( Color > 0 )
{
pWindow->WdwDesc.dsp_atr_color.non_cur_border = Color;
pWindow->WdwDesc.dsp_atr_color.cur_border = Color;
}
if ( pBorderChar != NULL )
{
memcpy ( &pWindow->WdwDesc.upper_left_border_char,
pBorderChar,
strlen( pBorderChar ) );
}
} /* SetWdwBorder */
/* ============================================================================
**
** Function : DrawWindow
**
** Description: Draws a window warning user that he/she is about to update or
** delete all rows in the table.
*/
void DrawWindow( const Qsn_Win_T *win,
const Qsn_Cmd_Buf_T *cbuf )
{
QsnWrtDta( TEXT1, strlen( TEXT1 ), 0, text_row, text_col,
QSN_SA_UL, QSN_SA_NORM, text_color, QSN_SA_NORM,
*cbuf, *win, NULL );
++text_row;
QsnWrtDta( TEXT2, strlen( TEXT2 ), 0, text_row, text_col,
QSN_SA_UL, QSN_SA_NORM, text_color, QSN_SA_NORM,
*cbuf, *win, NULL );
++text_row;
QsnWrtDta( TEXT3, strlen( TEXT3 ), 0, text_row, text_col,
QSN_SA_UL, QSN_SA_NORM, text_color, QSN_SA_NORM,
*cbuf, *win, NULL );
} /* DrawWindow */
/* ============================================================================
**
** Function : SendMsg
**
** Description: Send a message
*/
T_Error SendMsg(
char *pMsgID,
char *pMsgFile,
char *pMsgData,
long MsgLen,
char *pMsgType
)
{
char pMsgKey[5], pError[496];
*(long *)pError = 496;
QMHSNDPM( pMsgID, pMsgFile, pMsgData, MsgLen + 1, pMsgType,
"*PGMBDY ", 1, pMsgKey, pError );
} /* SendMsg */