/*
* Listing 3 - demo_client.c
*/
#include <stdio.h>
#include <rpc/rpc.h>
#include <malloc.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/time.h>
#include "ips.h"
/* Prototypes */
char *get_file();
void image_release();
void upcase();
void help_text();
/* Globals */
static unsigned long image_id=-1;
static struct timeval Timeout = { 10000, 0 };
void
main(argc, argv)
int argc;
char **argv;
{
int done = 0;
CLIENT *cl;
char cmd[256];
Packet *request, *reply;
int id;
char command[256];
request = (Packet *) malloc(sizeof(Packet));
if(argc < 2) {
printf("Usage: %s server\n", argv[0]);
exit(0);
}
if(!(cl = clnt_create(argv[1], IPSPROG, IPSVERS,
"tcp"))) {
clnt_pcreateerror(argv[1]);
exit(1);
}
clnt_control(cl, CLSET_TIMEOUT, (char *)&Timeout);
request->op = IPS_INIT;
reply = ips_1(request, cl);
if(reply)
printf("\n%s\n\n",
reply->Packet_u.hello_string);
while(!done) {
printf("(? for help)>>");
fflush(stdout);
gets(cmd);
if(strcmp(cmd, "help") == 0 ||
strcmp(cmd, "?") == 0)
help_text();
else if(strcmp(cmd, "send") == 0)
decode(cl);
else if(strcmp(cmd, "get") == 0)
encode(cl);
else if(strcmp(cmd, "process") == 0)
process(cl);
else if(strcmp(cmd, "operators") == 0)
get_operators(cl);
else if(strcmp(cmd, "loaders") == 0)
get_loaders(cl);
else if(strcmp(cmd, "savers") == 0)
get_savers(cl);
else if(strcmp(cmd, "quit") == 0) {
image_release(cl);
done = 1;
}
printf("\n");
}
}
int
encode(cl)
CLIENT *cl;
{
char buf[256];
char filename[256];
char format[40];
Packet *reply, *request;
request = (Packet *) malloc(sizeof(Packet));
printf("\nIPS Send Image:\n\n");
printf("Enter image filename (abort to quit): ");
fflush(stdout);
gets(filename);
if(strcmp(filename, "abort") == 0)
return 1;
printf("Enter format (abort to quit): ");
fflush(stdout);
gets(format);
if(strcmp(format, "abort") == 0)
return 1;
upcase(format);
request->op = IPS_REQUEST_IMAGE;
request->Packet_u.send_ops.id = image_id;
request->Packet_u.send_ops.format = format;
request->Packet_u.send_ops.argc = 0;
request->Packet_u.send_ops._argv.name = "test";
request->Packet_u.send_ops._argv.next = NULL;
reply = ips_1(request, cl);
if(!reply) {
puts("Reply error or timeout.");
exit(1);
}
if(reply->op == IPS_SEND_IMAGE) {
FILE *fp;
fp = fopen(filename, "w");
fwrite(reply->Packet_u.img.data.data_val, 1,
reply->Packet_u.img.data.data_len, fp);
fclose(fp);
printf("\"%s\" Received.\n", filename);
} else if(reply->op == IPS_IMAGE_NOT_AVAIL)
printf("IPS_IMAGE_NOT_AVAIL recevied.\n");
else if(reply->op == IPS_UNSUPPORTED_FORMAT)
printf("IPS_UNSUPPORTED_FORMAT received\n");
else {
printf("Error in encoding.\n");
return 1;
}
free(request);
if(reply) xdr_free(xdr_Packet, reply);
return 0;
}
int
decode(cl)
CLIENT *cl;
{
FILE *fp;
long size;
char buf[256];
char buf2[256];
char *filename;
unsigned char *raw_img;
Packet *reply, *request;
request = (Packet *) malloc(sizeof(Packet));
if((filename = get_file()) == NULL) {
printf("Error or aborted.\n");
return 1;
}
printf("Please enter image format: ");
fflush(stdout);
scanf("%s", buf2);
upcase(buf2);
image_release(cl);
sprintf(buf, "%s", filename);
fp = fopen(buf, "r");
fseek(fp, 0, 2);
size = ftell(fp);
fseek(fp, 0, 0);
raw_img = (unsigned char *) malloc(size);
fread(raw_img, 1, size, fp);
fclose(fp);
request->op = IPS_DECODE;
request->Packet_u.raw_img.filename = filename;
request->Packet_u.raw_img.format = strdup(buf2);
request->Packet_u.raw_img.data.data_len = size;
request->Packet_u.raw_img.data.data_val =
(char *) raw_img;
reply = ips_1(request, cl);
if(!reply) {
puts("Timeout.");
exit(1);
}
if(reply->op == IPS_OK_ID) {
image_id = reply->Packet_u.id;
} else {
printf("Error in decoding.\n\n");
return 1;
}
free(raw_img);
free(request);
xdr_free(xdr_Packet, reply);
return 0;
}
int
process(cl)
CLIENT *cl;
{
int i,
retval;
list *nlp, *cp;
char buf[256];
Packet *reply = NULL,
*request;
int nitems;
char *items[10];
if(image_id == -1) {
printf("No image sent to server.\n");
return;
}
/*
For this article, nitems will be 0, but
this allows you to send arguments to the
operator program. For example, if you
were executing a SCALE program, you would
have to send the new width and height.
*/
nitems = 0;
request = (Packet *) malloc(sizeof(Packet));
printf("Please enter processing command: ");
fflush(stdout);
scanf("%s", buf);
upcase(buf);
request->op = IPS_PROCESS;
request->Packet_u.proc.id = image_id;
request->Packet_u.proc.command = strdup(buf);
request->Packet_u.proc.argc = nitems;
if(nitems == 0) {
request->Packet_u.proc.argv.name = "\0";
request->Packet_u.proc.argv.next = 0;
} else {
nlp = &request->Packet_u.proc.argv;
for(i=0;i<nitems;i++) {
nlp->name = strdup(items[i]);
cp = nlp;
nlp->next = (list *) malloc(sizeof(list));
nlp = nlp->next;
}
cp->next = nlp = NULL;
}
reply = ips_1(request, cl);
free(request);
if(!reply) {
puts("Encode timeout.");
return -1;
}
if(reply->op == IPS_PROCESS_OK)
retval = 0;
else {
puts("There was an error processing.\n");
retval = -1;
}
xdr_free(xdr_Packet, reply);
return retval;
}
int
get_loaders(cl)
CLIENT *cl;
{
list *nlp;
Packet *reply, *request;
request = (Packet *) malloc(sizeof(Packet));
request->op = IPS_REQUEST_LOADERS;
reply = ips_1(request, cl);
switch(reply->op) {
case IPS_SEN_LOADERS:
printf("\nIPS Load Formats:\n\n");
for(nlp = &reply->Packet_u.operators;
nlp != NULL;
nlp = nlp->next)
printf(" %s\n", nlp->name);
printf("\n");
break;
case ERROR:
printf("get_loaders failed.\n");
return 1;
}
free(request);
xdr_free(xdr_Packet, reply);
return 0;
}
int
get_savers(cl)
CLIENT *cl;
{
list *nlp;
Packet *reply, *request;
request = (Packet *) malloc(sizeof(Packet));
request->op = IPS_REQUEST_SAVERS;
reply = ips_1(request, cl);
switch(reply->op) {
case IPS_SEND_SAVERS:
printf("\nIPS Save Formats:\n\n");
for(nlp = &reply->Packet_u.operators;
nlp != NULL;
nlp = nlp->next)
printf(" %s\n", nlp->name);
printf("\n");
break;
case ERROR:
printft"get_savers failed.\n");
return 1;
}
free(request);
xdr_free(xdr_Packet, reply);
return 0;
}
int
get_operators(cl)
CLIENT *cl;
{
list *nlp;
Packet *reply, *request;
request = (Packet *) malloc(sizeof(Packet));
request->op = IPS_REQUEST_OPS;
reply = ips_1(request, cl];
switch(reply->op) {
case IPS_SEND_OPS:
printf("\nIPS Processing Tools:\n\n");
for(nlp = &reply->Packet_u.operators;
nlp != NULL;
nlp = nlp->next)
printf(" %s\n", nlp->name);
printf("\n");
break;
case ERROR:
printf("get_operators failed.\n");
return 1;
}
free(request);
xdr_free(xdr_Packet, reply);
return 0;
}
char *
get_file()
{
int status;
char filename[1024], command[1024];
printf("\nIPS Receive Image:\n\n");
printf("Type 'abort' to cancel. Filename: ");
fflush(stdout);
gets(filename);
if(strcmp(filename, "abort") == 0)
return NULL;
if(access(filename, R_OK) == 0)
return strdup(filename);
return NULL;
}
void
image_release(cl)
CLIENT *cl;
{
Packet *request, *reply;
request = (Packet *) malloc(sizeof(Packet));
if(image_id != -1) {
request->op = IPS_IMAGE_RELEASE;
request->Packet_u.id = image_id;
reply = ips_1(request, cl);
if(reply->op == IPS_RELEASE_OK)
printf("Release of %d ok.\n", image_id);
}
free(request);
}
void
upcase(text)
char *text;
{
char *p = text;
while(*p != NULL) {
*p = toupper(*p);
p++;
}
}
void
help_text()
{
printf("\n");
printf(" Cmd Description\n");
printf("------- -----------------------\n");
printf(" send send an image to the IPS\n");
printf(" get receive an image from IPS\n");
printf(" in a certain format\n");
printf(" process process an image\n");
printf(" loaders list all available loaders\n");
printf(" savers list all available savers\n");
printf(" operators list all avail. operators\n");
printf(" quit exit this client\n");
printf("\n");
}
/* End of File */