/* 
 * server - receive and process client messages.
 *
 * Programming Assignment #8.
 *
 * CSc 645  Spring 1995  Jim Warhol
 *
 * server is the companion program to client. Together the two programs
 * provide a client/server mechanism for managing shared memory storage.
 *
 * The client processes send Tread and Twrite requests to the server by
 * means of the SMlib shared memory library functions, which validate
 * the parameters and forward the request to the server. The server loops
 * forever waiting for client shared memory requests.
 *
 * The server can be compiled using either the datagram or the connection-
 * oriented stream message service remote procedure call library routines.
 *
 * Compile with: cc -o Apps/server server.c common.c SMlib.c RPCdg.c
 *    or
 *               cc -o Apps/server server.c common.c SMlib.c RPCst.c
 *
 * The server process is initiated by the startup program, which starts
 * up the server as well as all client processes.
 *
 * The user must note the local port number printed at server startup 
 * and enter this port number when prompted by the startup program, which
 * will provide the value on the command line when each client is started.
 *
 * Related components: startup.c, client.c, common.h/common.c, SMlib.c, 
 *                     and RPCdg.c/RPCst.c.
 *
 */

#include "common.h"

/* server function prototypes */

void perform_Tread(int sourceID, int *value1, int *value2); /* do Tread fn */
void perform_Twrite(int sourceID, int value1, int value2);  /* do Twrite fn */

/* server data definitions */

int shared_memory[MAXCLIENTS+1][2];	/* shared memory area; first dimension
					   is client index, accessed in range
					   [1..MAXCLIENTS]; second dimension
					   contains value1/value2, in [0]&[1] */

/* main program - server */

void main()
{
   print("  server: Initializing and executing server.\n");

   /* initialize shared memory to large negative number. Since the shared
      memory library routines validate Tread & Twrite parameters it should
      not be possible to read these incorrect values. Nonetheless they are
      initialized as a precaution */

   for (i = 1; i <= MAXCLIENTS; i++) 
      shared_memory[i][0] = shared_memory[i][1] = -999999;

   /* initiate and execute shared memory server */

   SM_server(perform_Tread, perform_Twrite); /* initialize and execute server */
   error("  server: Unexpected return from SM_server.");
}

/*
 * void perform_Tread(int sourceID, int *value1, int *value2);
 *
 * perform_Tread is called by the shared memory library server routines to
 * perform the actual Tread operation for the client specified by sourceID.
 * The values are returned to addresses value1 & value2. Because the shared
 * memory routines have already performed all necessary validation, no
 * error status is returned as no error is possible at this point.
 *
 */

void perform_Tread(int sourceID, int *value1, int *value2)
{
   printnnn("  server (perform_Tread): Doing Tread(client #%d); "
      "returning (%d,%d).\n", sourceID,
      shared_memory[sourceID][0], shared_memory[sourceID][1]);
   *value1 = shared_memory[sourceID][0];
   *value2 = shared_memory[sourceID][1];
   return; 
}

/*
 * void perform_Twrite(int sourceID, int value1, int value2);
 *
 * perform_Twrite is called by the shared memory library server routines to
 * perform the actual Twrite operation for the client specified by sourceID.
 * The values value1 and value2 are written to the indicated shared memory 
 * locations. Because the shared memory routines have already performed all 
 * necessary validation, no error status is returned as no error is possible 
 * at this point.
 *
 */

void perform_Twrite(int sourceID, int value1, int value2)
{
   printnnn("  server (perform_Twrite): Doing Twrite(%d,%d) => client "
      "ID #%d.\n", value1, value2, sourceID);
   shared_memory[sourceID][0] = value1;
   shared_memory[sourceID][1] = value2;
   return;
}
