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 >
C/C++ Source or Header  |  1993-09-05  |  8KB  |  342 lines

  1. /* mtpdc.c, Version 1.3, Created 3/7/91 */
  2. /* Dr Alan M. McIvor, BP Sunbury Research Centre */
  3. /* Programme to handle connections to mtp */
  4.  
  5. /*
  6.    It is assumed that this is forked by mtpd with open master socket s and
  7.    connected socket ns and the integer values of these sockets are passed
  8.    via the argument list.
  9. */   
  10.  
  11. #include <stdio.h>
  12. #include <types.h>
  13. #include <socket.h>
  14. #include <in.h>
  15. #include <netdb.h>
  16. #include <strings.h>
  17. #include <errno.h>
  18. #include <module.h>
  19. #include "mtp.h"
  20.  
  21.  
  22. #define MAX_UNLOAD_TRIES 32
  23. #define VALID_MOD "mtpvalid"
  24.  
  25. extern mod_exec *modlink();
  26. extern unsigned int _srqsiz;
  27.  
  28. main(argc, argv)
  29.      int argc;
  30.      char **argv;
  31. {
  32.   int s;                       /* master socket */
  33.   int ns;                      /* socket connecting to master one */
  34.   int e;                       /* error code */
  35.   char buf;
  36.   int i;
  37.   void handle_error();
  38.  
  39.   void put_module();
  40.   void get_module();
  41.   void shutdown_exit();
  42.  
  43. /*  printf("mtpdc>> Starting\n");*/
  44.  
  45.   /* get socket numbers from argument list */
  46.   if (argc != 3)
  47.     {
  48.       fprintf(stderr, "mtpdc: Wrong number of arguments %d\n", argc);
  49.       exit(1);
  50.     }
  51.   s = atoi(argv[1]);
  52.   ns = atoi(argv[2]);
  53.  
  54.   /* close inherited master socket */
  55.   if (close(s) == -1)
  56.     {
  57.       fprintf(">>>>>mtpdc - Close failed\n");
  58.       exit(2);
  59.     }
  60.  
  61.   /* write acknowledge to client */
  62.   buf = ACKNOWLEDGE;
  63.   if (write(ns, &buf, 1) == -1)
  64.     shutdown_exit(ns, _errmsg(errno, "Error on write 1\n"));
  65.  
  66.   /* handle requests from client */
  67.   do
  68.     {
  69.       /* get 1 byte */
  70.       if (read(ns, &buf, 1) == -1)
  71.          shutdown_exit(ns, _errmsg(errno, "Error on read\n"));
  72. /*      printf("mtpdc>> Read character %c\n", buf);*/
  73.       switch (buf)
  74.        {
  75.          case ACKNOWLEDGE:
  76.            break;
  77.          case QUIT:
  78.            break;
  79.          case ERROR_CONTROL:
  80.            /* get four bytes for int */
  81.            if (read(ns, (char *)&i, 4) == -1)
  82.              shutdown_exit(ns, _errmsg(errno, "Error on read\n"));
  83.            i = ntohl(i);       /* convert from network order to host order */
  84.            handle_error(i);
  85.            break;
  86.          case PUT_MODULE:
  87.          case UPUT_MODULE:
  88.            put_module(ns, buf);
  89.            break;
  90.          case GET_MODULE:
  91.            get_module(ns);
  92.            break;
  93.          default:
  94.            fprintf(stderr, "mtpdc>> Unknown code %c\n", buf);
  95.            break;
  96.        }
  97.     }
  98.   while (buf != QUIT);
  99.   
  100.   if (shutdown(ns, 2) == -1)
  101.     {
  102.       close(ns);
  103.       exit(_errmsg(errno, "Could not shutdown\n"));
  104.     }
  105.  
  106.   if (close(ns) == -1)
  107.     exit(_errmsg(errno, "Could not close\n"));
  108.  
  109. /*  printf("mtpdc>> terminating\n");*/
  110.  
  111.   exit(0);
  112. }
  113.  
  114.  
  115. void shutdown_exit(ns, en)
  116.      int ns;
  117.      int en;
  118. {
  119.   shutdown(ns, 2);
  120.   close(ns);
  121.   exit(en);
  122. }
  123.  
  124.  
  125. void handle_error(e)
  126.      int e;
  127. {
  128.   fprintf(stderr, "mtpdc>> Client reported error %d\n", e);
  129. }  
  130.  
  131.  
  132. void put_module(ns, type)
  133.      int ns;                   /* socket */
  134.      char type;
  135. {
  136.   int module_size;
  137.   char *module_name;
  138.   int name_size;
  139.   void send_control();
  140.   int i;
  141.   void send_error();
  142.   char *module_memory, *_srqmem();
  143.  
  144.   /* read the name size and then the name */
  145.   if (read(ns, &name_size, 4) != 4)
  146.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  147.   name_size = ntohl(name_size);
  148.   if ((module_name = (char *)malloc((name_size + 1))) == (char *)-1)
  149.     shutdown_exit(ns, _errmsg(errno, "Malloc error\n"));
  150.   if (read(ns, module_name, name_size) != name_size)
  151.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  152.   module_name[name_size] = '\0';
  153.  
  154.   /* read the module size */
  155.   if (read(ns, &module_size, 4) != 4)
  156.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  157.   module_size = ntohl(module_size);
  158.  
  159. /*
  160.   printf("mtpdc>> Request to load module called %s of size 0x%x\n",
  161.         module_name, module_size);
  162. */
  163.  
  164.   /* unload any module of the same name if PUT_MODULE command */
  165.   if (type == PUT_MODULE)
  166.     {
  167.       for (i = 0; i < MAX_UNLOAD_TRIES; i++)
  168.        if (munload(module_name, 0) == -1) 
  169.          {
  170.            if (errno == E_MNF)
  171.              break;
  172.            else
  173.              {
  174.                _errmsg(errno, "Error on unload %d\n", errno);
  175.                send_error(ns, E_UNLOAD);
  176.                return;
  177.              }
  178.          }
  179.       if (i == MAX_UNLOAD_TRIES)
  180.        {
  181.          send_error(ns, E_UNLOAD);
  182.          return;
  183.        }
  184.     }
  185.  
  186.   /* Get system memory to hold the module */
  187.   if ((module_memory = _srqmem(module_size)) == (char *)-1)
  188.     {
  189.       send_error(ns, E_MEMALLOC);
  190.       printf("Error allocing memory for module\n");
  191.       return;
  192.     }
  193. /*
  194.   else
  195.     printf("Memory of size 0x%x allocated at address 0x%x\n",
  196.           _srqsiz, (int)module_memory);
  197. */
  198.  
  199.   send_control(ns, ACKNOWLEDGE); /* acknowledge */
  200.  
  201.   /* read the module data from the socket */
  202.   if (read_block(ns, module_memory, module_size) == -1)
  203.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  204.  
  205. /*
  206.   printf("Finished reading module, validating ...\n");
  207. */
  208.  
  209.   /* validate module */
  210.   if (!validate_module(module_memory, module_size))
  211.     {
  212.       send_error(ns, E_VALIDATE);
  213. /*      printf("Error validating module\n");*/
  214.       _srtmem(module_size, module_memory);
  215.       return;
  216.     }
  217.     
  218.   send_control(ns, ACKNOWLEDGE);
  219.   free(module_name);
  220. }
  221.  
  222.  
  223. void send_control(ns, c)
  224.      int ns;
  225.      char c;
  226. {
  227. /*  printf("about to send control %c ...\n", c);*/
  228.   if (write(ns, &c, 1) != 1)
  229.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  230. /*  printf("\t\t\t... send control\n");*/
  231. }
  232.  
  233.  
  234. void send_error(ns, e)
  235.      int ns;                   /* socket */
  236.      int e;
  237. {
  238.   void send_control();
  239.  
  240. /*  printf("about to send ERROR_CONTROL ...\n");*/
  241.   send_control(ns, ERROR_CONTROL);
  242. /*  printf("\t\t... sent ERROR_CONTROL, sending code %d ...\n", e);*/
  243.   if (write(ns, &e, 4) != 4)
  244.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  245. /*  printf("\t\t\t\t... sent\n");*/
  246. }
  247.  
  248.  
  249.  
  250. int validate_module(module_memory, module_size)
  251.      char *module_memory;
  252.      int module_size;
  253. {
  254.   /* returns 0 if error, non-zero otherwise */
  255.  
  256.   int stat;
  257.   int request[5];
  258.   mod_exec *modptr;
  259.   char *modname;
  260.  
  261.   /* call system-state programme mtpvalid to validate module, i.e., to
  262.      check it is okay and put in mdir */
  263.   request[0] = 0xFEEDFEED;
  264.   request[1] = 2;
  265.   request[2] = (int)module_memory;
  266.   request[3] = module_size;
  267.   request[4] = 0;
  268.   if (os9forkc(VALIDATION_HANDLER, 16, (char *)request, 0, 0, 0, 0, 0) == -1)
  269.     return(0);
  270.   wait(&stat);
  271.  
  272. /*  printf("mtpvalid returned stat = %d\n", stat); */
  273.  
  274.   if (stat != 0)
  275.     return(0);
  276.  
  277.   /* link to the module so that its link count is 1 and hence it will
  278.      stay in memory */
  279.   modname = module_memory + ((struct modhcom *)module_memory)->_mname;
  280.   modptr = modlink(modname, 0);
  281. /*  printf("Module %s found at 0x%x\n", modname, (int)modptr);*/
  282.   if ((int)modptr == -1)
  283.     return(0);
  284.  
  285.   return(1);
  286. }
  287.  
  288.  
  289. void get_module(ns)
  290.      int ns;                   /* socket */
  291. {
  292.   char *module_name;
  293.   int name_size;
  294.   void send_control();
  295.   int i;
  296.   void send_error();
  297.   mod_exec *modptr;
  298.  
  299.   /* read the name size and then the name */
  300.   if (read(ns, &name_size, 4) != 4)
  301.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  302.   name_size = ntohl(name_size);
  303.   if ((module_name = (char *)malloc((name_size + 1))) == NULL)
  304.     shutdown_exit(ns, _errmsg(errno, "Malloc error\n"));
  305.   if (read(ns, module_name, name_size) != name_size)
  306.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  307.   module_name[name_size] = '\0';
  308.  
  309. /*  printf("Looking for module %s\n", module_name);*/
  310.  
  311.   modptr = modlink(module_name, 0);
  312. /*  printf("Module %s found at 0x%x\n", module_name, (int)modptr);*/
  313.   if ((int)modptr == -1)
  314.     {
  315.       send_error(ns, E_NOMODULE);
  316.       return;
  317.     }
  318.  
  319.   send_control(ns, ACKNOWLEDGE);
  320.   
  321.   i = htonl(modptr->_mh._msize);
  322.   if (write(ns, &i, 4) != 4)
  323.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  324. /*  printf("Size of module is %d\n", modptr->_mh._msize);*/
  325.  
  326.   /* send the module data */
  327.   if (write_block(ns, (char *)modptr, modptr->_mh._msize) == -1)
  328.     shutdown_exit(ns, _errmsg(errno, "Error on socket I/O\n"));
  329.  
  330. /*  printf("Module sent\n");*/
  331.  
  332.   /* unlink from the module */
  333.   munlink(modptr);
  334. /*
  335.   if (munlink(modptr) == -1)
  336.     printf("Error unlinking module\n");
  337.   else
  338.     printf("Module unlinked.\n");
  339. */
  340.   free(module_name);
  341. }
  342.