/*** IBMCOPYR ********************************************************/
/* */
/* Component Name: XTICC.C (alias EZAEC0YL) */
/* */
/* Copyright: Licensed Materials - Property of IBM */
/* */
/* "Restricted Materials of IBM" */
/* */
/* 5647-A01 */
/* */
/* (C) Copyright IBM Corp. 1977, 1998 */
/* */
/* US Government Users Restricted Rights - */
/* Use, duplication or disclosure restricted by */
/* GSA ADP Schedule Contract with IBM Corp. */
/* */
/* Status: CSV2R6 */
/* */
/* */
/* SMP/E Distribution Name: EZAEC0YL */
/* */
/* */
/*** IBMCOPYR ********************************************************/
static char ibmcopyr[] =
"XTICC - Licensed Materials - Property of IBM. "
"This module is \"Restricted Materials of IBM\" "
"5647-A01 (C) Copyright IBM Corp. 1994. "
"See IBM Copyright Instructions.";
/*********************************************************************/
/* XTIC Sample : Client */
/* */
/* Function: */
/* */
/* 1. Establishes an XTI endpoint (Asynchronous mode) */
/* 2. Sends a connection request to an XTI server */
/* 3. Receives the request */
/* 4. Sends a block of data to the server */
/* 5. Receives a block of data from the server */
/* 6. Disconnects from the server */
/* 7. Client stops */
/* */
/* Command line: */
/* */
/* XTIC hostname */
/* */
/* hostname - name of the host that the server is running. */
/* */
/*********************************************************************/
#include "xti.h"
#include "xti1006.h"
#include "stdio.h"
/*
* bind request structure for t_bind()
*/
struct t_bind req,ret;
/*
* for client to make calls to server
*/
struct t_call scall,rcall;
/*
* store fd returned on open()
*/
int fd;
int tot_received;
char *hostname;
/*
* data buffer
*/
char buf[25];
int looking;
/*
* flags returned from t_rcv()
*/
int rflags,sflags;
/*
* transport provider for t_open()
*/
char tprov[1][8] =
{ "RFC1006" } ;
/*
* args that are optional
*/
int args;
int pnum = 102;
char *port = "102";
char *ctsel = "client";
char *stsel = "server";
unsigned int rqlen = 0;
struct xti1006tsap tsap, tsapret;
void cleanup(int);
void form_addr_1006(struct xti1006tsap *,int, char *, char*, int, int);
/*
* MAIN line program starts here !!!
*/
main(argc,argv)
int argc;
char *argv[];
{
/*
* Check arguments. The host name is required. Host name is the
* last parameter passed. Port can be changed by passing it as the
* first parameter.
*/
if ((argc > 3) | (argc < 2)) {
fprintf(stderr,"Usage XTIC <port> <host>\n");
exit(1);
}
if(argc==2)
hostname = argv[1];
else
{
hostname = argv[2];
port = argv[1];
pnum = (unsigned short) atoi(argv[1]);
}
/*
* assume normal data
*/
sflags = 0;
/*
* establish endpoint to t_listen() on
*/
if ((fd = t_open(tprov[0],O_NONBLOCK,NULL)) < 0)
{
t_error("Error on t_open for FD");
exit(t_errno);
}
/*
* compose req structure for t_bind() calls
*/
/*
* length of tsap
*/
req.qlen = 0;
req.addr.len = sizeof(tsap);
/*
* allocate the buffer to contain the
* port and tsel to bind server to
*/
req.addr.buf = (char *)malloc(sizeof(tsap));
/*
* fill address buffer with the address information
*/
form_addr_1006((struct xti1006tsap *)req.addr.buf,pnum,NULL, \
ctsel,fd,-1);
/*
* now that we're done composing the req,
* do the bind of fd to addr in req
*/
if (t_bind(fd,&req,NULL) != 0)
{
t_error("ERROR ON BIND FOR FD");
exit(t_errno);
}
/*
* compose call structure for t_connect() call
*/
scall.addr.len = sizeof(tsap);
scall.addr.buf = (char *)malloc(sizeof(tsap));
/*
* fill address buffer with the address information
*/
form_addr_1006((struct xti1006tsap *)scall.addr.buf,-1,hostname, \
stsel,fd,-1);
scall.opt.maxlen = 0;
scall.opt.len = 0;
scall.opt.buf = NULL;
scall.udata.len = 0;
scall.udata.buf = NULL;
rcall.addr.maxlen = sizeof(tsapret);
rcall.addr.buf = (char *)malloc(sizeof(tsapret));
rcall.opt.maxlen = 0;
rcall.udata.maxlen = 0;
rcall.udata.buf = NULL;
/*
* issue connect request
*/
looking = t_connect(fd,&scall,&rcall);
if (looking < 0 & t_errno != TNODATA)
{
t_error("ERROR ON CONNECT");
cleanup(fd);
exit(t_errno);
}
looking = 1;
while (looking)
{
looking = t_look(fd);
if (looking == T_CONNECT & looking > 0)
looking = 0;
else
if (looking != 0)
{
t_error("ERROR ON LOOK");
cleanup(fd);
exit(t_errno);
}
else
looking = 1;
}
/*
* establish connection
*/
looking = 1;
while (looking)
if (t_rcvconnect(fd,&rcall) == 0)
looking = 0;
else
if (t_errno != TNODATA)
{
t_error("ERROR ON RCVCONNECT");
cleanup(fd);
exit(t_errno);
}
/*
* place message in buffer
*/
memset(buf,'B',25);
/*
* send message to server
*/
looking = 1;
while (looking)
if ((looking = t_snd(fd,buf,sizeof(buf),sflags)) < 0)
{
t_error("ERROR SENDING MESSAGE TO SERVER");
cleanup(fd);
exit(t_errno);
}
else
if (looking == 0)
looking = 1;
else
looking = 0;
/*
* receive data back from the server
*/
looking = 1;
while (looking)
{
if ((looking = t_rcv(fd,buf,sizeof(buf),&rflags)) > 0)
looking = 0;
else
{
if (looking < 0 & t_errno != TNODATA)
{
t_error("ERROR RECEIVING DATA FROM SERVER");
cleanup(fd);
exit(t_errno);
}
else
looking = 1;
}
}
/*
* disconnect from server
*/
looking = 1;
while (looking)
if (t_snddis(fd,NULL) == 0)
looking = 0;
else
{
t_error("ERROR DISCONNECTING FROM SERVER");
cleanup(fd);
exit(t_errno);
}
/*
* if fd is an endpoint, try to close it
*/
if (t_unbind(fd) != 0)
{
t_error("ERROR ON BIND FOR FD");
exit(t_errno);
}
cleanup(fd);
printf("Client ended successfully\n");
exit(0);
}
/*********************************************************************/
void form_addr_1006(addrbuf1006,portnum,hostnmstr,tselstr1006,fd1,fd2)
/*
* formats the provided address information
* into the buffer for RFC1006
*/
/*
* address buffer to be filled in
*/
struct xti1006tsap *addrbuf1006;
int portnum;
/*
* hostnmstr represented as a string
*/
char *hostnmstr;
/*
* tsel represented as a string
*/
char *tselstr1006;
/*
* one possible endpoint to close if
* an error occurs in forming address
*/
int fd1;
/*
* other possible endpoint to close
*/
int fd2;
{
/*
* check validity of hostname
* there's no way program can
* continue without valid addr
*/
if (strlen(hostnmstr) > 64)
{
fprintf(stderr,"hostname %s too long\n",hostnmstr);
/*
* don't want TADDRBUSY when you try to reuse the address
*/
cleanup(fd1);
cleanup(fd2);
exit(TBADADDR);
}
addrbuf1006->xti1006_hostnm_len = strlen(hostnmstr);
strcpy(addrbuf1006->xti1006_hostnm,hostnmstr);
/*
* check validity of hostname
* there's no way program can
* continue without valid addr
*/
if (strlen(tselstr1006) > 64)
{
fprintf(stderr,"tsel %s too long\n",tselstr1006);
/*
* don't want TADDRBUSY when you try to reuse the address
*/
cleanup(fd1);
cleanup(fd2);
exit(TBADADDR);
}
addrbuf1006->xti1006_tsel_len = strlen(tselstr1006);
strcpy(addrbuf1006->xti1006_tsel,tselstr1006);
if (tselstr1006 == "Nulltsap")
{
addrbuf1006->xti1006_tsel_len = 0;
strcpy(addrbuf1006->xti1006_tsel,NULL);
}
else
{
addrbuf1006->xti1006_tsel_len = strlen(tselstr1006);
strcpy(addrbuf1006->xti1006_tsel,tselstr1006);
} /* endif */
if (portnum != -1)
addrbuf1006->xti1006_tset = portnum;
}
/*********************************************************************/
void cleanup(fd)
int fd;
{
if (fd >= 0)
if (t_close(fd) != 0)
{
fprintf(stderr,"unable to t_close() endpoint while");
fprintf(stderr," cleaning up from error\n");
}
}
Figure 1. Sample client code for XTI