blob: 0bd259bf5435b157fee209181885f3c8fd3b710c [file] [log] [blame]
#include <stdio.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
int program = 2000333;
int version = 10;
char *server = NULL;
char *file_name = NULL;
char host_name[100];
long host_address;
struct data {
long address;
long request_id;
long data_length;
char *data;
};
int xdr_receive_data(XDR *, struct data **);
int xdr_send_data(XDR *, struct data *);
void do_compare(int, char *, struct data *, char *);
void usage_error(char *program_name);
int
main(int argc, char *argv[])
{
struct hostent *hp;
struct data buffer, *return_buffer;
int i, n, rc;
FILE *fp;
struct stat stat_buffer;
char *p;
CLIENT *clnt;
struct sockaddr_in server_sin;
int sock;
struct timeval timeout;
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-s")) {
if (++i >= argc) {
fprintf(stderr, "-s requires a host name\n");
usage_error(argv[0]);
}
server = argv[i];
continue;
}
if (!strcmp(argv[i], "-f")) {
if (++i >= argc) {
fprintf(stderr, "-h requires a file name\n");
usage_error(argv[0]);
}
file_name = argv[i];
continue;
}
if (!strcmp(argv[i], "-p")) {
if (++i >= argc) {
fprintf(stderr, "-p requires an argument\n");
usage_error(argv[0]);
}
n = sscanf(argv[i], "%d", &program);
if (n != 1) {
fprintf(stderr, "-p requires an numeric argument\n");
usage_error(argv[0]);
}
continue;
}
if (!strcmp(argv[i], "-v")) {
if (++i >= argc) {
fprintf(stderr, "-v requires an argument\n");
usage_error(argv[0]);
}
n = sscanf(argv[i], "%d", &version);
if (n != 1) {
fprintf(stderr, "-v requires an numeric argument\n");
usage_error(argv[0]);
}
continue;
}
}
if (!server) {
fprintf(stderr, "server not given\n");
usage_error(argv[0]);
}
hp = gethostbyname(server);
if (hp == (struct hostent *) NULL) {
fprintf(stderr, "server %s unknown\n", server);
usage_error(argv[0]);
}
memset(&server_sin, 0x00, sizeof(server_sin));
server_sin.sin_family = AF_INET;
memcpy((char *) &server_sin.sin_addr, hp->h_addr, sizeof(hp->h_addr));
if (!file_name) {
fprintf(stderr, "file name not given\n");
usage_error(argv[0]);
}
gethostname(host_name, 100);
if (hp=gethostbyname(host_name))
host_address = (long) *((int *) hp->h_addr_list[0]);
buffer.address = host_address;
buffer.request_id = getpid();
fp = fopen(file_name, "r");
if (!fp) {
fprintf(stderr, "Can not open %s\n", file_name);
usage_error(argv[0]);
}
if (stat(file_name, &stat_buffer))
fprintf(stderr, "stat() failed for %s, errno %d\n", file_name, errno);
buffer.data_length = stat_buffer.st_size;
if (buffer.data_length > 2187) {
fprintf(stderr, "file too large (2187 max)\n");
usage_error(argv[0]);
}
buffer.data = (char *) malloc(buffer.data_length);
for (i=0, p=buffer.data; i < buffer.data_length; i++, p++)
*p = getc(fp);
fclose(fp);
rc = callrpc(server, program, version, 1, xdr_send_data, &buffer,
xdr_receive_data, &return_buffer);
do_compare(rc, "callrpc", &buffer, return_buffer->data);
server_sin.sin_port = 0;
sock = RPC_ANYSOCK;
timeout.tv_usec = 0;
timeout.tv_sec = 10;
clnt = clntudp_create(&server_sin, program, version, timeout, &sock);
if (clnt == (CLIENT *) NULL) {
fprintf(stderr, "clntudp_create failed\n");
exit(1);
}
timeout.tv_usec = 0;
timeout.tv_sec = 30;
rc = (int) clnt_call(clnt, 1, xdr_send_data, &buffer,
xdr_receive_data, &return_buffer, timeout);
clnt_destroy(clnt);
do_compare(rc, "udp transport", &buffer, return_buffer->data);
server_sin.sin_port = 0;
sock = RPC_ANYSOCK;
clnt = clnttcp_create(&server_sin, program, version, &sock, 0, 0);
if (clnt == (CLIENT *) NULL) {
fprintf(stderr, "clntudp_create failed\n");
exit(1);
}
timeout.tv_usec = 0;
timeout.tv_sec = 30;
rc = (int) clnt_call(clnt, 1, xdr_send_data, &buffer,
xdr_receive_data, &return_buffer, timeout);
clnt_destroy(clnt);
do_compare(rc, "tcp transport", &buffer, return_buffer->data);
exit(0);
}
void
do_compare(int rpc_rc, char *msg, struct data *buffer, char *ret_data)
{
int rc;
if (rpc_rc) {
printf("RPC call with %s returned %d: ", msg, rpc_rc);
clnt_perrno(rpc_rc);
printf("\n");
exit(1);
}
rc = memcmp(buffer->data, ret_data, buffer->data_length);
if (rc) {
printf("Data compare for %s returned %d\n", msg, rc);
exit(1);
}
}
int
xdr_receive_data(XDR *xdrs, struct data **buffer)
{
struct data *bp;
int i, rc;
char *p;
bp = *buffer = (struct data *) malloc(sizeof(struct data));
rc = xdr_long(xdrs, &(bp->address));
rc = rc && xdr_long(xdrs, &bp->request_id);
rc = rc && xdr_long(xdrs, &bp->data_length);
p = (*buffer)->data = (char *) malloc(bp->data_length);
for (i=0; rc && i < bp->data_length; p++, i++)
rc = xdr_char(xdrs, p);
return(rc);
}
int
xdr_send_data(XDR *xdrs, struct data *buffer)
{
int i, rc;
char *p;
rc = xdr_long(xdrs, &buffer->address);
rc = rc && xdr_long(xdrs, &buffer->request_id);
rc = rc && xdr_long(xdrs, &buffer->data_length);
for (i=0, p=buffer->data; rc && i < buffer->data_length; i++, p++)
rc = xdr_char(xdrs, p);
return(rc);
}
void
usage_error(char *program_name)
{
fprintf(stderr, "Usage: %s -s server -f file [-p program-number] [-v version]\n",
program_name);
exit(2);
}