Article

Herb Bujak's SQL program

/* 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 */
Related Topics: iSeries skills, VIEW ALL TOPICS

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to: