/*** IBMCOPYR ********************************************************/
/* */
/* Component Name: XTISC.C (alias EZAEC0YM) */
/* */
/* 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: EZAEC0YM */
/* */
/* */
/*** IBMCOPYR ********************************************************/
static char ibmcopyr[]=
"XTISC - Licensed Materials - Property of IBM. "
"This module is \"Restricted Materials of IBM\" "
"5647-A01 (C) Copyright IBM Corp. 1994. "
"See IBM Copyright Instructions.";
/*********************************************************************/
/* XTIS Sample : Server */
/* */
/* Function: */
/* */
/* 1. Establishes an XTI endpoint (Asynchronous mode) */
/* 2. Listens for a connection request from an XTI client */
/* 3. Accepts the connection request */
/* 4. Receives a block of data from the client */
/* 5. Echos the data back to the client */
/* 6. Waits for the disconnect request from the XTI client */
/* 7. Server stops */
/* */
/* Command line: */
/* */
/* XTIS H */
/* */
/*********************************************************************/
#include "xti.h"
#include "xti1006.h"
#include "stdio.h"
/*
* bind request structure for t_bind()
*/
struct t_bind req,ret;
/*
* for server to listen for calls with
*/
struct t_call call;
/*
* descriptor to t_listen() on
*/
int fd;
/*
* descriptor to t_accept() on
*/
int resfd;
int tot_received;
/*
* 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 tot_sent;
int pnum = 102;
char *port = "102";
char *hostnm;
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. No arguments should be passed to the server
*/
if (argc > 2) {
fprintf(stderr,"Usage : XTIS <port>\n");
exit(1);
}
if(argc == 2)
{
pnum = (unsigned short) atoi(argv[1]);
port = 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");
exit(t_errno);
}
/*
* establish endpoint to t_accept() on
*/
if ((resfd = t_open(tprov[0],O_NONBLOCK,NULL)) < 0)
{
t_error("Error on t_open");
cleanup(fd);
exit(t_errno);
}
/*
* compose req structure for t_bind() calls
*/
/*
* length of tsap
*/
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, \
stsel, \
fd, \
resfd);
/*
* length of tsap
*/
ret.addr.maxlen = sizeof(tsapret);
ret.addr.buf = (char *)malloc(sizeof(tsapret));
/*
* listening endpoint needs qlen > 0,
* ability to queue 10 requests
*/
req.qlen = 10;
ret.qlen = rqlen;
/*
* now that we're done composing the req,
* do the bind of fd to addr in req
*/
if (t_bind(fd,&req,&ret) != 0)
{
t_error("Error on t_bind");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* accepting endpoint with same addr needs qlen == 0
*/
req.qlen = 0;
/*
* now that we're done composing the req,
* do the bind of resfd to addr in req
*/
if (t_bind(resfd,&req,&ret) != 0)
{
t_error("Error on t_bind");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* initialize call receipt structure for t_listen()
*/
call.opt.maxlen = 0;
call.addr.len = 0;
call.opt.len = 0;
call.udata.len = 0;
call.opt.buf = NULL;
call.addr.maxlen = sizeof(tsapret); /* listen for return*/
call.addr.buf = (char *)malloc(sizeof(tsapret));
call.udata.maxlen = 0;
call.udata.buf = NULL;
/*
* wait for connect req & get seq num in the call variable
*/
looking = 1;
while (looking)
if (t_listen(fd,&call) == 0)
looking = 0;
else
if (t_errno != TNODATA)
{
t_error("Error on t_accept");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* accept the connection on the accepting endpoint
*/
if (t_accept(fd,resfd,&call) != 0)
{
t_error("Error on t_accept");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* receive data from the client
*/
looking = 1;
while (looking)
if (t_rcv(resfd,buf,sizeof(buf),&rflags) > 0)
looking = 0;
else
if (t_errno != TNODATA)
{
t_error("Error on t_rcv");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* sent data back to the client
*/
strcpy(buf,"DATA FROM SERVER");
looking = 1;
while (looking)
if (t_snd(resfd,buf,sizeof(buf),sflags) > 0)
looking = 0;
/*
* wait for disconnect from the client
*/
looking = 1;
while (looking)
if (t_look(resfd) == T_DISCONNECT)
looking = 0;
/*
* receive the disconnect request
*/
looking = 1;
while (looking)
if (t_rcvdis(resfd,NULL) == 0)
looking = 0;
/*
* unbind the endpoints
*/
if (t_unbind(resfd) != 0)
{
t_error("Error on t_unbind for resfd");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
if (t_unbind(fd) != 0)
{
t_error("Error on t_unbind for fd");
cleanup(fd);
cleanup(resfd);
exit(t_errno);
}
/*
* if fd is an endpoint, try to close it
*/
cleanup(fd);
/*
* if resfd is an endpoint, try to close it
*/
cleanup(resfd);
printf("Server 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
server code for XTI