home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
mtp.lzh
/
mtpdc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-05
|
8KB
|
342 lines
/* mtpdc.c, Version 1.3, Created 3/7/91 */
/* Dr Alan M. McIvor, BP Sunbury Research Centre */
/* Programme to handle connections to mtp */
/*
It is assumed that this is forked by mtpd with open master socket s and
connected socket ns and the integer values of these sockets are passed
via the argument list.
*/
#include <stdio.h>
#include <types.h>
#include <socket.h>
#include <in.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <module.h>
#include "mtp.h"
#define MAX_UNLOAD_TRIES 32
#define VALID_MOD "mtpvalid"
extern mod_exec *modlink();
extern unsigned int _srqsiz;
main(argc, argv)
int argc;
char **argv;
{
int s; /* master socket */
int ns; /* socket connecting to master one */
int e; /* error code */
char buf;
int i;
void handle_error();
void put_module();
void get_module();
void shutdown_exit();
/* printf("mtpdc>> Starting\n");*/
/* get socket numbers from argument list */
if (argc != 3)
{
fprintf(stderr, "mtpdc: Wrong number of arguments %d\n", argc);
exit(1);
}
s = atoi(argv[1]);
ns = atoi(argv[2]);
/* close inherited master socket */
if (close(s) == -1)
{
fprintf(">>>>>mtpdc - Close failed\n");
exit(2);
}
/* write acknowledge to client */
buf = ACKNOWLEDGE;
if (write(ns, &buf, 1) == -1)
shutdown_exit(ns, _errmsg(errno, "Error on write 1\n"));
/* handle requests from client */
do
{
/* get 1 byte */
if (read(ns, &buf, 1) == -1)
shutdown_exit(ns, _errmsg(errno, "Error on read\n"));
/* printf("mtpdc>> Read character %c\n", buf);*/
switch (buf)
{
case ACKNOWLEDGE:
break;
case QUIT:
break;
case ERROR_CONTROL:
/* get four bytes for int */
if (read(ns, (char *)&i, 4) == -1)
shutdown_exit(ns, _errmsg(errno, "Error on read\n"));
i = ntohl(i); /* convert from network order to host order */
handle_error(i);
break;
case PUT_MODULE:
case UPUT_MODULE:
put_module(ns, buf);
break;
case GET_MODULE:
get_module(ns);
break;
default:
fprintf(stderr, "mtpdc>> Unknown code %c\n", buf);
break;
}
}
while (buf != QUIT);
if (shutdown(ns, 2) == -1)
{
close(ns);
exit(_errmsg(errno, "Could not shutdown\n"));
}
if (close(ns) == -1)
exit(_errmsg(errno, "Could not close\n"));
/* printf("mtpdc>> terminating\n");*/
exit(0);
}
void shutdown_exit(ns, en)
int ns;
int en;
{
shutdown(ns, 2);
close(ns);
exit(en);
}
void handle_error(e)
int e;
{
fprintf(stderr, "mtpdc>> Client reported error %d\n", e);
}
void put_module(ns, type)
int ns; /* socket */
char type;
{
int module_size;
char *module_name;
int name_size;
void send_control();
int i;
void send_error();
char *module_memory, *_srqmem();
/* read the name size and then the name */
if (read(ns, &name_size, 4) != 4)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
name_size = ntohl(name_size);
if ((module_name = (char *)malloc((name_size + 1))) == (char *)-1)
shutdown_exit(ns, _errmsg(errno, "Malloc error\n"));
if (read(ns, module_name, name_size) != name_size)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
module_name[name_size] = '\0';
/* read the module size */
if (read(ns, &module_size, 4) != 4)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
module_size = ntohl(module_size);
/*
printf("mtpdc>> Request to load module called %s of size 0x%x\n",
module_name, module_size);
*/
/* unload any module of the same name if PUT_MODULE command */
if (type == PUT_MODULE)
{
for (i = 0; i < MAX_UNLOAD_TRIES; i++)
if (munload(module_name, 0) == -1)
{
if (errno == E_MNF)
break;
else
{
_errmsg(errno, "Error on unload %d\n", errno);
send_error(ns, E_UNLOAD);
return;
}
}
if (i == MAX_UNLOAD_TRIES)
{
send_error(ns, E_UNLOAD);
return;
}
}
/* Get system memory to hold the module */
if ((module_memory = _srqmem(module_size)) == (char *)-1)
{
send_error(ns, E_MEMALLOC);
printf("Error allocing memory for module\n");
return;
}
/*
else
printf("Memory of size 0x%x allocated at address 0x%x\n",
_srqsiz, (int)module_memory);
*/
send_control(ns, ACKNOWLEDGE); /* acknowledge */
/* read the module data from the socket */
if (read_block(ns, module_memory, module_size) == -1)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
/*
printf("Finished reading module, validating ...\n");
*/
/* validate module */
if (!validate_module(module_memory, module_size))
{
send_error(ns, E_VALIDATE);
/* printf("Error validating module\n");*/
_srtmem(module_size, module_memory);
return;
}
send_control(ns, ACKNOWLEDGE);
free(module_name);
}
void send_control(ns, c)
int ns;
char c;
{
/* printf("about to send control %c ...\n", c);*/
if (write(ns, &c, 1) != 1)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
/* printf("\t\t\t... send control\n");*/
}
void send_error(ns, e)
int ns; /* socket */
int e;
{
void send_control();
/* printf("about to send ERROR_CONTROL ...\n");*/
send_control(ns, ERROR_CONTROL);
/* printf("\t\t... sent ERROR_CONTROL, sending code %d ...\n", e);*/
if (write(ns, &e, 4) != 4)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
/* printf("\t\t\t\t... sent\n");*/
}
int validate_module(module_memory, module_size)
char *module_memory;
int module_size;
{
/* returns 0 if error, non-zero otherwise */
int stat;
int request[5];
mod_exec *modptr;
char *modname;
/* call system-state programme mtpvalid to validate module, i.e., to
check it is okay and put in mdir */
request[0] = 0xFEEDFEED;
request[1] = 2;
request[2] = (int)module_memory;
request[3] = module_size;
request[4] = 0;
if (os9forkc(VALIDATION_HANDLER, 16, (char *)request, 0, 0, 0, 0, 0) == -1)
return(0);
wait(&stat);
/* printf("mtpvalid returned stat = %d\n", stat); */
if (stat != 0)
return(0);
/* link to the module so that its link count is 1 and hence it will
stay in memory */
modname = module_memory + ((struct modhcom *)module_memory)->_mname;
modptr = modlink(modname, 0);
/* printf("Module %s found at 0x%x\n", modname, (int)modptr);*/
if ((int)modptr == -1)
return(0);
return(1);
}
void get_module(ns)
int ns; /* socket */
{
char *module_name;
int name_size;
void send_control();
int i;
void send_error();
mod_exec *modptr;
/* read the name size and then the name */
if (read(ns, &name_size, 4) != 4)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
name_size = ntohl(name_size);
if ((module_name = (char *)malloc((name_size + 1))) == NULL)
shutdown_exit(ns, _errmsg(errno, "Malloc error\n"));
if (read(ns, module_name, name_size) != name_size)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
module_name[name_size] = '\0';
/* printf("Looking for module %s\n", module_name);*/
modptr = modlink(module_name, 0);
/* printf("Module %s found at 0x%x\n", module_name, (int)modptr);*/
if ((int)modptr == -1)
{
send_error(ns, E_NOMODULE);
return;
}
send_control(ns, ACKNOWLEDGE);
i = htonl(modptr->_mh._msize);
if (write(ns, &i, 4) != 4)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
/* printf("Size of module is %d\n", modptr->_mh._msize);*/
/* send the module data */
if (write_block(ns, (char *)modptr, modptr->_mh._msize) == -1)
shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
/* printf("Module sent\n");*/
/* unlink from the module */
munlink(modptr);
/*
if (munlink(modptr) == -1)
printf("Error unlinking module\n");
else
printf("Module unlinked.\n");
*/
free(module_name);
}