Need help with a structure related problem
Bob Calbridge
bobc at attctc.Dallas.TX.US
Sun Dec 10 12:24:08 AEST 1989
I've been asked to help someone with the following piece of code. Please
excuse the 'goto's, they are not mine. The sample code from which this
was derived had them in there and my co-worker didn't feel like removing
them or rewriting the code.
The header for the program and a segment of the code follow. After that is
an explanation of the problem. The program is at this point a test to
get used to the nature of the functions that were supplied to us. In the
long run the program is to be used to interface to a mainframe program
running NATURAL to access records in ADABAS. The program is used by first
logging on to the mainframe and executing NATURAL. From this point on we
should be able to shell to DOS, execute the download progam and do whatever
we need with the data. The following program begins by sending a command to
NATURAL to run a download program. This mainframe program at this point
simply downloads a simple string which the C program intercepts and uses.
Some lines have been deleted to reduce the size of this posting.
/**********************************************************************
* File : sagapi.h
* Description: API .. defines
**********************************************************************/
/* How to call API: */
/* nc(API, (APICB far *)&apicb) */
#define API 0x1b00 /* Application Program Interface */
#define APIPTR unsigned char far
/* API CONTROL BLOCK STRUCTURE *******/
typedef struct
{ /* API control block ----------------*/
int cmd; /* command */
int rc; /* response code */
APIPTR *input; /* -> input command string */
/* -> compare string */
/* file transfer info: */
int type; /* file transfer type */
int fnr; /* file number */
int filler; /* reserved */
int len; /* record length */
APIPTR *record; /* record/buffer */
APIPTR *format; /* format */
/* IF parameters */
int start; /* starting offset of screen */
int cols; /* columns to compare */
int op; /* operator */
/* Terminal Emulation Screen */
APIPTR *screen; /* screen (row 1 - 25) */
} APICB;
/* REQUEST CODES *********************/
#define API_CMD 100 /* COMMAND STRING */
#define API_IF 200 /* IF COMMAND */
/* FILE TRANSFER REQUEST CODES *******/
#define API_ABORT 0x1b01 /* ABORT */
#define API_GET_RCD 0x1b02 /* GET_RECORD */
#define API_GET_BUF 0x1b03 /* GET_BUFFER */
#define API_EOF 0x1b04 /* EOF (UPLOAD'S ONLY) */
#define API_PUT_RCD 0x1b05 /* PUT_RECORD */
#define API_PUT_BUF 0x1b06 /* PUT_BUFFER */
/* RESPONSE CODES ********************/
#define API_SUCCESS 0 /* SUCCESS */
#define API_NOT_ACTIVE -1 /* NATCON NOT ACTIVE */
#define API_UNKNOWN_REQ -100 /* UNKOWN REQUEST */
#define API_NO_COMM -200 /* COMM CAN'T BE INITIALIZED */
#define API_FILEXFER -300 /* FILE TRANSFER DETECTED */
#define API_SCREEN -400 /* SCREEN DETECTED */
#define API_TIMEOUT -500 /* TIMEOUT DETECTED */
#define API_ESCAPE -600 /* ESCAPE KEY DETECTED */
#define API_NOT_IN_FT -700 /* FILE TRANSFER NOT IN PROGRESS */
#define API_FT_IN_PROGRESS -800 /* FILE TRANSFER IN PROGRESS */
#define API_BFT_IN_PROGRESS -900 /* FILE TRANSFER IN PROGRESS */
#define API_END_OF_FILE -1000 /* FILE TRANSFER END OF FILE DETECTED*/
#define API_BIN_CONV_ERROR -1100 /* BINARY CONVERSION ERROR */
#define API_IF_ERROR1 -2100 /* string length zero (0) */
#define API_IF_ERROR2 -2200 /* cols < 1 or > 2000 */
#define API_IF_ERROR3 -2300 /* cols < string length */
#define API_IF_ERROR4 -2400 /* start < 0 or > 1999 */
#define API_IF_ERROR5 -2500 /* screen exceeded by string length */
#define API_IF_ERROR6 -2600 /* screen exceeded by cols */
#define API_IF_ERROR7 -2700 /* invalid operator */
/* API_IF RESPONSE CODES *************/
#define API_FALSE 0 /* IF STATEMENT IS FALSE */
#define API_TRUE 1 /* IF STATEMENT IS TRUE */
/* API_IF OPERATOR *******************/
#define API_EQ 0 /* eq */
#define API_NE 1 /* ne */
#define API_GT 2 /* gt */
#define API_LT 3 /* lt */
#define API_GE 4 /* ge */
#define API_LE 5 /* le */
/* api.type **************************/
#define API_DOWNLOAD 1 /* DOWNLOAD DATA */
#define API_UPLOAD 2 /* UPLOAD DATA */
#define API_REPORT 3 /* DOWNLOAD REPORT */
>>>>>> main program begins here <<<<<<<<
#include "sagapi.h"
APICB api;
char buf[79];
main(argc, argv)
int argc;
char *argv[];
{
int i;
/* Send Natural connection command to set up pcfile 2 */
/* for an API file transfer (download data ascii). */
api.cmd = API_CMD;
api.input = "set pcfile 2 down data api=asc";
rc = nc(API, (APICB far *) &api);
if (rc != API_SUCCESS)
goto error1d;
/* Send a natural connection command to run a natural */
/* program called NATDOWN. */
/* NOTE: Natural programs to be used with API should */
/* not contain any display or screen write */
/* statements. */
api.input = "type 'run natdown' cr";
rc = nc(API, (APICB far *) &api);
if (rc != API_FILEXFER) /* File transfer? */
goto error2;
/* Set up download loop to process each record. */
loop1:
api.cmd = API_GET_RCD;
>>>>>>>>> <<<<
**** the following gets the necessary data into the api structure ****
(1)
rc = nc(API, (APICB far *) &api);
if (rc == API_END_OF_FILE) /* end of file? */
goto eoj;
if (rc != API_SUCCESS) /* Unexpected response */
goto error3a;
strcpy(buf,argv[1]);
switch(buf[0])
{
(2) case '1':
for(i=0;i<api.len;i++)
putchar(*api.record++);
/* printf("\n\n"); */
break;
(3) case '2':
strncpy(buf,&api.record,api.len);
printf("** buf size = %d\n",api.len);
printf("** buf len = %d\n",strlen(buf));
printf("** buffer = %s\n",buf);
break;
(4) default:
printf("** rec size = %d\n",api.len);
printf("** rec len = %d\n",strlen(api.record));
printf("** record = %s\n",api.record);
break;
}
Point (1) is the call to the routine that receives the downloaded data and
places the necessary information in the structure 'api'. api.len should have
the length of the downloaded data and api.pointer should point to the ASCII
string containing the data.
Point (2) is a short loop that I suggested to see if the data is where the
pointer points to. This does indeed print out the information that the
NATURAL program is supposed to download.
Point (3) is supposed to copy the data pointed to by api.record into the
buffer then print out the statistics and the data.
Point (4) does the same as (3) but with the data taken directly from the
information in the api structure.
The problem is that parts (3) and (4) don't work. We've tried both strncpy()
and strcpy(). There is no garbage printed but there is also no data.
Can anyone offer any advice? I suspect that the problem lies in how we're
trying to use pointers in the structure but similar things have worked for me
before.
More information about the Comp.lang.c
mailing list