[comp.lang.c] Need help with a structure related problem

bobc@attctc.Dallas.TX.US (Bob Calbridge) (12/10/89)

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.