/* * mdremote.c * * Summary: Low level remote communication routines. * * Author: David Hardy */ #include "mdremote.h" MD_Errcode MD_remote_client_connect(MD_Remote *client, const char *serverhostname, MD_Int portnumber) { MD_Int sockfd; struct hostent *he; struct sockaddr_in serveraddr; /* server's address information */ /* get IP address from host name */ if ((he = gethostbyname(serverhostname)) == NULL) { MD_ERR(client->sim, client->name, MD_ERR_CONNECT, "unknown server to gethostbyname"); return MD_FAIL; } /* obtain socket */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { MD_ERR(client->sim, client->name, MD_ERR_CONNECT, strerror(errno)); return MD_FAIL; } serveraddr.sin_family = AF_INET; /* host byte order */ serveraddr.sin_port = htons(portnumber); /* short, network byte ordr */ serveraddr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(serveraddr.sin_zero), 0, 8); /* zero rest of the struct */ /* connect to server running on host_name */ if (connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) == -1) { MD_ERR(client->sim, client->name, MD_ERR_CONNECT, strerror(errno)); close(sockfd); return MD_FAIL; } client->sockfd = sockfd; return 0; } MD_Errcode MD_remote_client_disconnect(MD_Remote *client) { close(client->sockfd); return 0; } MD_Errcode MD_remote_send(MD_Remote *remote, const void *vbuf, MD_Int bufsz) { MD_Int nbytes; while (bufsz > 0) { nbytes = send(remote->sockfd, vbuf, bufsz, 0); if (nbytes == -1) { MD_ERR(remote->sim, remote->name, MD_ERR_CONNECT, strerror(errno)); return MD_FAIL; } ((const char *) vbuf) += nbytes; bufsz -= nbytes; } return 0; } MD_Int MD_remote_recv(MD_Remote *remote, void *vbuf, MD_Int bufsz, MD_Int sec) { MD_Int nbytes; struct timeval timeout; struct timeval *ptimeout = &timeout; fd_set readfds; /* set the timeout value to select */ /* for a negative timeout value, we make a blocking call */ if (sec < 0) { ptimeout = NULL; /* select will wait indefinitely */ } else { timeout.tv_sec = sec_timeout; timeout.tv_usec = 0; } /* use select to block for up to the timeout value */ FD_ZERO(&readfds); FD_SET(remote->sockfd, &readfds); if (select(remote->sockfd + 1, &readfds, NULL, NULL, ptimeout) == -1) { MD_ERR(remote->sim, remote->name, MD_ERR_CONNECT, strerror(errno)); return MD_FAIL; } if ( ! FD_ISSET(comm->sockfd, &readfds) ) { return 0; } /* there are bytes waiting for us */ nbytes = recv(comm->sockfd, vbuf, bufsz, 0); if (nbytes == -1) { MD_ERR(remote->sim, remote->name, MD_ERR_CONNECT, strerror(errno)); return MD_FAIL; } return nbytes; }