home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / portmngr / prtmgrrc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  13.1 KB  |  266 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/drapeau/PortManager/RCS/PortMgrReceiver.c,v 1.61 92/06/15 15:01:27 drapeau Exp $ */
  25. /* $Log:    PortMgrReceiver.c,v $
  26.  * Revision 1.61  92/06/15  15:01:27  drapeau
  27.  * Minor change: cast two calls to "svc_getcaller()" to avoid compiler
  28.  * warnings.  The function was not correctly defined in the RPC
  29.  * header files (actually, it is currently defined as a macro).
  30.  * 
  31.  * Revision 1.6  91/09/27  17:05:43  drapeau
  32.  * Minor change to PortMgrConnectWithPortMgr(); changed diagnostic
  33.  * message so that it is clear exactly which application has
  34.  * just registered.
  35.  * 
  36.  * Revision 1.5  91/09/18  13:11:21  drapeau
  37.  * Added a function, PortMgrGetPortFromName(), to respond to the GetPortFromName message in the
  38.  * MAEstro protocol.  This function is not yet fully implemented, but at this time will check for
  39.  * matches with the "appName" field of the Port* passed in as argument.  The behavior of this new
  40.  * function is documented in comments at the beginning of the function.
  41.  * 
  42.  * Also, made minor cosmetic changes to the code.
  43.  * 
  44.  * Revision 1.4  91/09/09  18:29:07  drapeau
  45.  * Changed all diagnostic messages to go through the PrintDiagnostic() routine.
  46.  * This allowed the removal of the test for the "Testing" preprocessor
  47.  * definition.
  48.  * 
  49.  * Revision 1.3  91/07/31  11:06:11  drapeau
  50.  * Modified ConnectWithPortMgr() and DisconnectFromPortMgr() as follows:
  51.  * When an application running on the same machine as the PortManager registers
  52.  * itself as running on machine "localhost", the PortManager's call to
  53.  * gethostbyaddr() would return "localhost" as the official name of the caller's
  54.  * hostname.  This is incorrect, since it causes the PortManager to register
  55.  * the application as registering from "localhost" instead of, say, "sioux" (the
  56.  * real host name, in other words).
  57.  * The PortManager now asks what hostname it's running on when it first starts.
  58.  * Whenever an application connects or disconnects with the Port Manager, the
  59.  * Port Manager now checks to see if the calling application was on "localhost"
  60.  * (i.e., the same host as the Port Manager).  If so, the Port Manager now
  61.  * substitutes the real host name for the name "localhost".  Now applications
  62.  * can register with the Port Manager on host "localhost" but the Port Manager
  63.  * will always use the real hostname instead of the name "localhost".
  64.  * 
  65.  * Also, minor cosmetic code changes were made to conform to coding standards.
  66.  * 
  67.  * Revision 1.2  91/06/17  18:14:42  drapeau
  68.  * Added copyright notice.
  69.  * 
  70.  * Revision 1.1  90/11/30  13:46:03  drapeau
  71.  * Initial revision
  72.  *  */
  73.  
  74. static char portMgrRecvrRcsid[] ="$Header: /Source/Media/drapeau/PortManager/RCS/PortMgrReceiver.c,v 1.61 92/06/15 15:01:27 drapeau Exp $";
  75.  
  76. #include <Receiver.h>
  77. #include "PortList.h"
  78. #include <stdio.h>
  79. #include <string.h>
  80. #include <sys/types.h>
  81. #include <sys/socket.h>
  82. #include <netinet/in.h>
  83. #include <arpa/inet.h>
  84. #include <netdb.h>
  85.  
  86.  
  87. extern char        portMgrHostName[256];
  88. extern PortList*    portMgrPortList;
  89. extern Receiver*    portMgrReceiver;
  90. extern char        diagMessage[];
  91. extern void        PrintDiagnostic(char*);
  92.  
  93. void PortMgrConnectWithPortMgr(Port* newApp,                /* Warning: This function takes the implicit 2nd argument... */
  94.                    struct svc_req* theRequest)        /* ...passed in by the RPC layer, even though it is not... */
  95. {                                    /* ...declared in the .h file. */
  96.   Port*            tempPtr;
  97.   struct sockaddr_in*    callerAddr;
  98.   struct hostent*    callingHost;
  99.   char*            realHostName;
  100.  
  101.   callerAddr = (struct sockaddr_in*)svc_getcaller(theRequest->rq_xprt);    /* Find out where the calling app is calling from */
  102.   callingHost = gethostbyaddr(&(callerAddr->sin_addr),            /* Get the host name of the calling app, from its... */
  103.                   sizeof(callerAddr->sin_addr),        /* ...Internet address */
  104.                   AF_INET);
  105.   if ( strcmp(callingHost->h_name,"localhost") == 0)            /* Was the official hostname returned as "localhost"? */
  106.   {                                    /* Yes, use the real hostname for this machine instead... */
  107.     realHostName = (char*) portMgrHostName;                /* ...of "localhost" */
  108.   }
  109.   else                                    /* No, use the hostname given by the caller */
  110.     realHostName = callingHost->h_name;
  111.   sprintf(diagMessage,
  112.       "In Connect, %s is calling from %s.\n",
  113.       newApp->appName,
  114.       realHostName);
  115.   PrintDiagnostic(diagMessage);
  116.   tempPtr = (Port*)malloc(sizeof(Port));
  117.   tempPtr->appName = strdup(newApp->appName);
  118.   tempPtr->hostName = strdup(realHostName);
  119.   tempPtr->portNumber = newApp->portNumber;
  120.   PortListAddPortToList(&portMgrPortList, tempPtr);
  121.   return;
  122. }                                    /* end function PortMgrConnectWithPortMgr */
  123.  
  124.  
  125. void PortMgrDisconnectFromPortMgr(Port* appToRemove,            /* Warning: This function takes the implicit 2nd argument... */
  126.                   struct svc_req* theRequest)        /* ...passed in by the RPC layer, even though it is not... */
  127. {                                    /* ...declared in the .h file. */
  128.   struct sockaddr_in*    callerAddr;
  129.   struct hostent*    callingHost;
  130.   Port            tempPort;
  131.   char*            realHostName;
  132.   
  133.   callerAddr = (struct sockaddr_in*)svc_getcaller(theRequest->rq_xprt);    /* Find out where the calling app is calling from */
  134.   callingHost = gethostbyaddr(&(callerAddr->sin_addr),            /* Get the host name of the calling app, from its... */
  135.                   sizeof(callerAddr->sin_addr),        /* ...Internet address */
  136.                   AF_INET);
  137.   if ( strcmp(callingHost->h_name,"localhost") == 0)            /* Was the official hostname returned as "localhost"? */
  138.   {                                    /* Yes, use the real hostname for this machine instead... */
  139.     realHostName = (char*) portMgrHostName;                /* ...of "localhost" */
  140.   }
  141.   else                                    /* No, use the hostname given by the caller */
  142.     realHostName = callingHost->h_name;
  143.   sprintf(diagMessage, "In Disconnect, App is calling from the computer named %s.\n",
  144.       realHostName);
  145.   PrintDiagnostic(diagMessage);
  146.   if (strcmp(appToRemove->hostName,realHostName) != 0)            /* Did the requesting application correctly fill in its... */
  147.     {                                    /* ...hostname?  If not, do the following: */
  148.     tempPort.appName = appToRemove->appName;                /* Copy the requesting app's Port structure to a... */
  149.     tempPort.portNumber = appToRemove->portNumber;            /* ...temporary Port so as not to disturb the original */
  150.     tempPort.hostName = realHostName;                    /* Use the calling app's real hostname, not the one given */
  151.     PortListRemovePortFromList(&portMgrPortList,&tempPort);        /* Remove the Port from the PortList using valid Port info */
  152.     }
  153.   else                                    /* The requesting app correctly identified itself;... */
  154.     PortListRemovePortFromList(&portMgrPortList,appToRemove);        /* ...remove the Port from the PortList using the app's info */
  155.   PortListPrint(portMgrPortList);
  156.   return;
  157. }                                    /* end function PortMgrDisconnectFromPortMgr */
  158.  
  159.  
  160. PortArray* PortMgrGetOpenApps(void* unusedArg)                /* This function returns a list of Port's, one for each... */
  161. {                                    /* ... application currently connected to the Port Manager. */
  162.   static PortArray    appList = {(Port*)NULL,0};
  163.   PortList*        tempList;
  164.   int            openAppCount;
  165.   Port*            tempPort;
  166.   
  167.   openAppCount = 0;                            /* Init number of open apps to zero. */
  168.   for (tempList = portMgrPortList; tempList;                /* Traverse the list of open Applications kept track of... */
  169.        tempList = tempList->next)                    /* ...by the Port Manager */
  170.     {
  171.       openAppCount++;                            /* One more app in the list, increment counter variable */
  172.     }
  173.   if (appList.portArray)
  174.     DestroyPortArray(&appList);                        /* Free space previously allocated for a PortArray */
  175.   appList.portArray =(Port*)malloc((openAppCount+1) *            /* Allocate space for 1 Port per open application, plus... */
  176.                    sizeof(Port));            /* ...1 more for a NULL Port to end the list. */
  177.   openAppCount = 0;                            /* Reset the counter variable for the next stmt */
  178.   for (tempList = portMgrPortList; tempList;
  179.        tempList = tempList->next)
  180.     {
  181.       tempPort = &(appList.portArray[openAppCount]);
  182.       tempPort->appName = (char*)strdup(tempList->port->appName);
  183.       tempPort->hostName = (char*)strdup(tempList->port->hostName);
  184.       tempPort->portNumber = tempList->port->portNumber;
  185.       openAppCount++;                            /* Increment the array variable counter */
  186.     }
  187.   bzero((char*)&appList.portArray[openAppCount],sizeof(Port));
  188.   appList.numberOfPorts = openAppCount;
  189.   return(&appList);                            /* Return the list of Port's */
  190. }                                    /* end function PortMgrGetOpenApps */
  191.  
  192.  
  193.  
  194. /******************************************************************
  195.  *    PortMgrGetPortFromName
  196.  *
  197.  *    This function scans through the Port Manager's internal
  198.  *    list of Ports (representing the currently open
  199.  *    applications), attempting to find all matches that
  200.  *    satisfy the criteria passed in as argument.
  201.  *    The function takes one argument, a Port*, specifying the
  202.  *    application to be searched for.  The Port* passed in
  203.  *    can be filled in two different ways:
  204.  *
  205.  *    1) Only the "appName" field is filled in
  206.  *    2) Both the "appName" and "hostName" field are filled in
  207.  *    
  208.  *    In the first case, it is assumed that the calling
  209.  *    application is asking for any applications with the name
  210.  *    stored in "appName"; in other words, the host on which
  211.  *    the applications are running does not matter.  Based on
  212.  *    this assumption, the function will do a simple string
  213.  *    comparison to find all matching Ports, then return the
  214.  *    resulting list of Ports (as the PortArray* return value).
  215.  *
  216.  *    In the second case, it is assumed that not only the name
  217.  *    of the application is important, but also the location on
  218.  *    the network of the desired application.
  219.  *    This case is not currently implemented, although the
  220.  *    function should do two string comparisons (looking at
  221.  *    both appName and hostName fields) before returning a
  222.  *    successful match.
  223.  */
  224.  
  225. PortArray*    PortMgrGetPortFromName(Port* appPort)
  226. {
  227.   static PortArray    appList = {(Port*)NULL,0};
  228.   PortList*        tempList;
  229.   Port*            tempPort;
  230.   int            matchingAppsCount;
  231.   int            counter;
  232.   
  233.   if (appList.portArray)
  234.     DestroyPortArray(&appList);                        /* Free space allocated for a PortArray from previous call */
  235.   if (appPort == (Port*)NULL)                        /* Was the Port* passed in invalid? */
  236.     return(&appList);                            /* Yes, return an empty PortArray* */
  237.   matchingAppsCount = 0;                        /* Init number of matching apps to zero. */
  238.   for (tempList = portMgrPortList; tempList;                /* Traverse the list of open Applications kept track of... */
  239.        tempList = tempList->next)                    /* ...by the Port Manager */
  240.     {
  241.       if (strcmp(tempList->port->appName, appPort->appName) == 0)   /* Was a match found on this element of the portMgrPortList? */
  242.     matchingAppsCount++;                        /* Yes, a match was found, increment counter variable */
  243.     }
  244.   if (matchingAppsCount == 0)                        /* Were there any matches found? */
  245.     return(&appList);                            /* No, return the empty PortArray and exit this function */
  246.   appList.portArray =(Port*)malloc((matchingAppsCount+1) *        /* Allocate space for 1 Port per open application, plus... */
  247.                    sizeof(Port));            /* ...1 more for a NULL Port to end the list. */
  248.   counter = 0;                                /* Initialize counter variable for the next stmt */
  249.   for (tempList = portMgrPortList; tempList;                /* 2nd pass through the list: pick off matching apps... */
  250.        tempList = tempList->next)                    /* ...and copy them to the PortArray to be returned */
  251.   {
  252.     if (strcmp(tempList->port->appName, appPort->appName) == 0)        /* Was a match found on this element of the portMgrPortList? */
  253.     {                                    /* Yes, copy this Port's information into the PortArray: */
  254.       tempPort = &(appList.portArray[counter]);                /* Point to the appropriate element of the PortArray */
  255.       tempPort->appName = (char*)strdup(tempList->port->appName);   /* Copy the Port information into the current element */
  256.       tempPort->hostName = (char*)strdup(tempList->port->hostName);
  257.       tempPort->portNumber = tempList->port->portNumber;
  258.       counter++;                            /* Move on to next element in PortArray "appList.portArray" */
  259.     }
  260.   }
  261.   bzero((char*)&appList.portArray[counter],sizeof(Port));        /* Zero out the last element of the PortArray to be returned */
  262.   appList.numberOfPorts = matchingAppsCount;                /* Update number of apps that matched */
  263.   return(&appList);
  264. }                                    /* end function PortMgrGetPortFromName */
  265.  
  266.