home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/drapeau/PortManager/RCS/PortManager.c,v 1.7 92/09/13 22:47:00 drapeau Exp $ */
- /* $Log: PortManager.c,v $
- * Revision 1.7 92/09/13 22:47:00 drapeau
- * Minor modification in main(). A diagnostic message used a non-portable
- * method of reporting the port number on which the PortManager is listening
- * for messages. A more portable method is now used.
- *
- * Revision 1.6 91/09/27 13:35:51 drapeau
- * Added Revision RCS id, so that the application can be aware of the current
- * revision number.
- *
- * Revision 1.5 91/09/18 13:09:35 drapeau
- * Minor cosmetic changes, and simple changes to better conform to ANSI-C specifications.
- * Also, added entries in the DispatchTable to reflect new protocol messages, and filled in the
- * GetPortFromName() slot, since the Port Manager now responds to the GetPortFromName() message.
- *
- * Revision 1.4 91/09/09 18:28:19 drapeau
- * Changed all diagnostic messages to go through the PrintDiagnostic() routine.
- * Also, added support for obtaining command-line options, through the
- * GetCommandLineOptions() routine.
- *
- * Revision 1.3 91/07/31 11:11:29 drapeau
- * The main() function was changed it two ways:
- * 1) PortManager now checks to see if it was able to reserve the port it needs
- * to listen for messages. If the port was not reservable, the
- * NewReceiver() call returns a NULL Receiver*, and the Port Manager reports
- * the error and exits cleanly, without crashing.
- * 2) The Port Manager makes a call to gethostname() to determine the actual
- * name of the computer on which it is listening for messages. This is done
- * for the PortMgrConnectWithPortMgr() and PortMgrDisconnectFromPortMgr()
- * functions, so they can determine the actual hostname of a calling
- * application when the calling application says it's calling from
- * "localhost".
- *
- * Revision 1.2 91/06/17 18:14:37 drapeau
- * Added copyright notice.
- *
- * Revision 1.1 90/11/30 13:45:42 drapeau
- * Initial revision
- * */
-
- static char portMgrRcsid[] ="$Header: /Source/Media/drapeau/PortManager/RCS/PortManager.c,v 1.7 92/09/13 22:47:00 drapeau Exp $";
-
- static char portMgrVersionID[] = "$Revision: 1.7 $";
-
- #include <Receiver.h>
- #include <Sender.h>
- #include "PortList.h"
- #include <stdio.h>
- #include <string.h>
-
- void PortMgrConnectWithPortMgr(Port* newApp);
- PortArray* PortMgrGetOpenApps(void* unusedArg);
- void PortMgrDisconnectFromPortMgr(Port* appToRemove);
- PortArray* PortMgrGetPortFromName(Port* appPort);
-
- char portMgrHostName[256];
- Receiver* portMgrReceiver;
- PortList* portMgrPortList;
- DispatchTable portMgrDispatchTable =
- {
- NULL, /* OpenDocument */
- NULL, /* GetCurrentDocName */
- NULL, /* GetSelection */
- NULL, /* SetSelection */
- NULL, /* PerformSelection */
- PortMgrConnectWithPortMgr, /* ConnectWithPortMgr */
- PortMgrGetOpenApps, /* GetOpenApps */
- PortMgrGetPortFromName, /* GetPortFromName */
- NULL, /* DispatchMessage */
- PortMgrDisconnectFromPortMgr, /* DisconnectFromPortMgr */
- NULL, /* Ping */
- NULL, /* HaltSelection */
- NULL, /* PauseSelection */
- NULL, /* ResumeSelection */
- NULL, /* HideApplication */
- NULL, /* ShowApplication */
- NULL, /* GetAppIcon */
- };
-
- extern char diagMessage[];
- extern void PrintDiagnostic(char*);
-
- /*******************************************************************
- * This function is responsible for listening for RPC requests and dispatching them. It also periodically
- * checks the list of apps that have registered with the Port Manager to see that they're still running.
- * If an application on the Port Manager's list is no longer running, this function removes that
- * application from the list.
- */
-
- void ListenForMessages()
- {
- fd_set rpcSockets; /* Variable holding list of RPC sockets to listen... */
- /* ...on. Used as an argument to select() to determine... */
- /* ...whether there are requests on any RPC socket ... */
- /* ...waiting to be processed. */
- int descriptorTableSize = 0;
- int numSockets = 0; /* Return value from select, tells how many files had... */
- /* ...input ready to be processed. */
- struct timeval waitTime; /* Used to tell select() how long to wait until it returns */
- struct timeval lastTestTime; /* Holds last time the Port Manager scanned its list of... */
- /* ...applications to see if any were invalid ("dead") */
- struct timeval now; /* Holds the current time */
- int updateInterval = 30; /* Determines how often to check for "dead" apps */
- int result; /* Holds result of "gettimeofday()" to check for errors */
- void ScanPortListForDeadApps(PortList**);
-
- descriptorTableSize = getdtablesize(); /* Get size of descriptor table for later use by select() */
- waitTime.tv_sec = 1; /* Set up a timeval to wait for 1.0 seconds */
- waitTime.tv_usec = 0;
- result = gettimeofday(&now,(struct timezone*)NULL); /* Get current time */
- if (result) /* Was there a problem getting the time of day? */
- { /* Yes, print an error and exit the program */
- sprintf(diagMessage, "Could not get the time of day. Exiting.\n");
- PrintDiagnostic(diagMessage);
- exit(result);
- }
- lastTestTime.tv_sec = now.tv_sec; /* Initialize the last time scanned to now */
- lastTestTime.tv_usec = now.tv_usec;
- for (;;) /* Loop forever */
- {
- rpcSockets = svc_fdset; /* Get the list of RPC sockets accepting requests */
- numSockets = select(descriptorTableSize, /* Check for input on RPC sockets */
- &rpcSockets, (int*)0,(int*)0, /* Only concerned with incoming stuff */
- &waitTime); /* Tell select how long to wait (not at all, in this case) */
- switch (numSockets) /* Based on how many sockets had input, determine what to do */
- {
- case -1: /* An error occurred */
- break; /* For now, don't do anything */
-
- case 0: /* There was no input to process */
- result = gettimeofday(&now,(struct timezone*)NULL); /* Get current time */
- if (result) /* Was there a problem getting the time of day? */
- { /* Yes, print an error and exit the program */
- sprintf(diagMessage, "Could not get the time of day. Exiting.\n");
- PrintDiagnostic(diagMessage);
- exit(result);
- }
- if ((now.tv_sec - lastTestTime.tv_sec) >= updateInterval) /* Did "updateInterval" seconds pass since last scan? */
- {
- ScanPortListForDeadApps(&portMgrPortList); /* Yes, check for "dead" apps and remove them from app list */
- PortListPrint(portMgrPortList); /* Print the current list of registered applications */
- lastTestTime.tv_sec = now.tv_sec; /* Reset the last time scanned to now */
- lastTestTime.tv_usec = now.tv_usec;
- }
- break;
-
- default: /* There was input to process */
- svc_getreqset(&rpcSockets); /* Handle the incoming RPC requests */
- break;
- } /* end switch */
- } /* end for (;;) */
- } /* end function ListenForMessages */
-
-
-
- main(int argc, char** argv)
- {
- Sender* sender;
- Port portMgrSender;
- void GetCommandLineOptions(int argc, char** argv);
-
- BuildDispatchTable(&portMgrDispatchTable); /* Override the default RPC callbacks with my own */
- (void) gethostname(portMgrHostName,sizeof(portMgrHostName)); /* Determine which host Port Manager is running on */
- portMgrPortList = NULL;
- portMgrSender.hostName = strdup(portMgrHostName);
- portMgrSender.portNumber = 0;
- sender = NewSender(&portMgrSender); /* Create a new Sender that doesn't try to connect with...*/
- /* ...the PortManager, because this is the PortManager.*/
- portMgrReceiver = NewReceiver(sender, "PortManager", /* Create new Receiver to listen for messages from other apps*/
- PortMgrPortNumber);
- if (portMgrReceiver == (Receiver*) NULL)
- {
- sprintf(diagMessage, "Port Manager could not reserve port %d to listen for messages. Exiting.\n",
- PortMgrPortNumber);
- PrintDiagnostic(diagMessage);
- exit(-1);
- }
- GetCommandLineOptions(argc, argv);
- sprintf(diagMessage, "Listening on host %s on port %d.\n",
- portMgrHostName,
- portMgrReceiver->receivePort.portNumber);
- PrintDiagnostic(diagMessage);
- ListenForMessages(); /* Begin listening for messages from other applications*/
- exit(0); /* This function should never be called.*/
- }
-