/* * PROGRAM: sockets.c * * DESCRIPTION: This code provides the sockets functions which are called * to converse with the CICS server transaction * */ /* HEADER FILES */ #include #include #include /* Socket details */ #include #include /* To enable network error trapping */ #include /* CONSTANTS */ #define io_buf_size 2001 /* data buffer for socket comms, size */ #define recv_flags 0 /* flags parameter on recv() */ #define send_flags 0 /* flags parameter on send() */ #define socket_protocol 0 /* protocol parameter on socket() */ #define call_failed -1 /* most TCP calls return -1 if failed */ struct hostent *gethostbyname(char *name); int clients_sock_desc; /* Client's socket */ struct hostent *hostnm_info; /* Server hostname information */ struct sockaddr_in server_inetaddr; /* Server internet address */ unsigned short clients_port; /* Port number client will bind to */ char transid[5]; char tsqueue[9]; char tsact[2]; char tsqdata[51]; char padding[50] = " "; int socket(int domain, int type, int protocol); int connect(int s, struct sockaddr *name, int namelen); int close(int s); void report_nerrno(int error_number); char *do_read(); void shut_down(); void exit(int status); int atoi(char *string); /* * do_socket_call() * * Function called from main() to send data to server, and await reply */ char *do_socket_call(char *addr, char *port, char *tran, char *action, char *queue, char *qdata) { char input[10]; int recv_len; clients_port = (unsigned short) atoi(port); server_inetaddr.sin_family = AF_INET; server_inetaddr.sin_port = htons(clients_port); server_inetaddr.sin_addr.s_addr = (inet_addr(addr)); strcpy(transid,tran); transid[4] = '\0'; strcpy(tsact,action); tsact[1] = '\0'; strcpy(tsqueue,queue); tsqueue[8] = '\0'; strcpy(tsqdata,qdata); tsqdata[50] = '\0'; return (char *)do_read(); } /* * startup() * * Initialise the connection with the CICS server, and send the initial * data from the client. * The limit is 30 bytes on the first send. If the user requested a WRITE * operation, then there is more data, so we must perform further socket * calls to transfer the info. */ void startup(char *start_buf) { char io_buf[io_buf_size]; int num_bytes; int io_len; unsigned char *x; int y; /* Proper error conditions need to be handled here */ if ((clients_sock_desc = socket(AF_INET,SOCK_STREAM,socket_protocol)) == call_failed) { printf("Problem with socket()\n"); report_nerrno(errno); exit(3); } if (connect(clients_sock_desc, (struct sockaddr *) &server_inetaddr, sizeof(server_inetaddr)) == call_failed) { printf("Problem with connect()\n"); printf("errno = %d\n",errno); report_nerrno(errno); exit(4); } /* printf("\n-------> Connection opened.\n\n"); */ strcpy(io_buf,start_buf); io_len = strlen(io_buf); if (send(clients_sock_desc,io_buf,io_len,send_flags) == call_failed) { printf("Problem with send()\n"); report_nerrno(errno); exit(5); } return; } /* end of startup() */ /* * do_read() * * Get the HTML information back from the CICS server transaction */ char *do_read() { /* function to read msg msg_num for user to_user */ char from_user[9]; char to_user[9]; char subject[21]; char message[433]; char rcv_buf[io_buf_size+1]; char io_buf[io_buf_size+1]; int num_bytes; int io_len; char *next_field; strcpy(io_buf,transid); strcat(io_buf,","); strncat(tsact,padding,(1-strlen(tsact))); strcat(io_buf,tsact); strncat(tsqueue,padding,(8-strlen(tsqueue))); strcat(io_buf,tsqueue); startup(io_buf); if (!strcmp(tsact,"W")) { /* send MORE bytes to the server - the data to write to the queue */ /* first, receive a response from the server (help keep things in */ /* sync, and also flushes the buffers correctly :-) */ num_bytes = recv(clients_sock_desc,rcv_buf,io_buf_size,recv_flags); if (num_bytes == call_failed) { printf("Problem with recv()\n"); report_nerrno(errno); exit(6); } strncat(tsqdata,padding,(50-strlen(tsqdata))); strcpy(io_buf,tsqdata); io_len = strlen(io_buf); if (send(clients_sock_desc,io_buf,io_len,send_flags) == call_failed) { printf("Problem with send()\n"); report_nerrno(errno); exit(5); } num_bytes = recv(clients_sock_desc,rcv_buf,io_buf_size,recv_flags); if (num_bytes == call_failed) { printf("Problem with recv()\n"); report_nerrno(errno); exit(6); } } num_bytes = recv(clients_sock_desc,rcv_buf,io_buf_size,recv_flags); if (num_bytes == call_failed) { printf("Problem with recv()\n"); report_nerrno(errno); exit(6); } shut_down(); return(rcv_buf); } /* * shut_down() * * closes the connection with the CICS server */ void shut_down() { if ((close(clients_sock_desc)) == call_failed) { printf("Problem with close()\n"); report_nerrno(errno); exit(8); } return; } /* Reports network errors */ void report_nerrno(int error_number) { switch (error_number) { case ENOTSOCK : printf("ENOTSOCK - invalid socket descriptor\n"); break; case EOPNOTSUPP : printf("EOPNOTSUPP - socket descriptor does not support listen()\n"); break; case EADDRINUSE : printf("EADDRINUSE - address already in use\n"); break; case EADDRNOTAVAIL : printf("EADDRNOTAVAIL - address specified invalid on this host\n"); break; case EAFNOSUPPORT : printf("EAFNOSUPPORT - address family is not supported\n"); break; case EINVAL : printf("EINVAL - socket already bound/unexpected namelen length\n"); break; case ENOBUFS : printf("ENOBUFS - no buffer space available\n"); break; case EPROTONOSUPPORT : printf("EPROTONOSUPPORT - protocol unsupported by this\n"); printf(" domain/socket type\n"); break; case EPROTOTYPE : printf("EPROTOTYPE - wrong type of protocol for this socket\n"); break; case EWOULDBLOCK : printf("EWOULDBLOCK - the socket is in nonblocking mode\n"); printf(" & no data is available to read\n"); break; case EALREADY : printf("EALREADY - the socket is nonblocking & a previous\n"); printf(" connection attempt is incomplete\n"); break; case ENOTCONN : printf("ENOTCONN - the socket is not connected\n"); break; case ECONNREFUSED : printf("ECONNREFUSED - the connection request was rejected by\n"); printf(" the destination host\n"); break; case EINPROGRESS : printf("EINPROGRESS - the socket is marked non-blocking & the\n"); printf(" connection cannot be made immediately\n"); printf(" - this is not an error condition\n"); break; case EISCONN : printf("EISCONN - the socket is already connected\n"); break; case ENETUNREACH : printf("ENETUNREACH - network cannot be reached from this host\n"); break; case ETIMEDOUT : printf("ETIMEDOUT - the connection establishment timed out\n"); printf(" before a connection was made\n"); } }