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/NetworkProtocol/RCS/Sender.c,v 1.39 92/09/30 16:33:36 drapeau Exp $ */
- /* $Log: Sender.c,v $
- * Revision 1.39 92/09/30 16:33:36 drapeau
- * Modified an error message to provide better information about where errors
- * occur.
- *
- * Revision 1.38 92/09/24 14:07:04 drapeau
- * Modified code to support asynchronous messaging (actually, to be precise,
- * the code now supports one-way RPC's, but conceptually the programmer should
- * think of the messaging as non-blocking). In Sun RPC, if an RPC call has
- * a timeout value of zero, the sender will not block waiting for a return.
- * To support this model, a new method was added to the Sender object, called
- * "SenderAsynchronousMessaging()". It will enable or disable synchronous
- * messaging for the sender passed in as argument. It does this by modifying
- * the Sender's "timeOut" field. Also, each message in the Sender object
- * modifies a variable global to the NetworkProtocol library; this variable
- * is called "SenderTimeOut" and is used by each message in the Sender class.
- * When a message is sent, the responsible method first sets the SenderTimeOut
- * variable to the timeOut field of the current Sender.
- * Because of these changes, it is no longer necessary to create default
- * timeout values when a New Sender is created (via the NewSender() method).
- * Thus, the code to do so was removed.
- * A final note: the "sender->timeOut" field is new to this version of the code.
- *
- * Revision 1.37 92/05/29 12:40:41 drapeau
- * Changed the name of the "Selection" structure to "MAESelection",
- * to avoid name conflicts with other software packages and toolkits
- * that might also define a "Selection" structure.
- *
- * Revision 1.36 91/09/26 23:28:45 drapeau
- * Two major changes:
- * 1) Significant modification of SenderGetPortFromName();
- * 2) Addition of a new function, SenderLaunchApplication().
- *
- * SenderGetPortFromName() is extended so that if an application being
- * requested is not already running, this function will now attempt to launch
- * the application. The function will wait for a period of time, then try to
- * communicate with the application; if necessary, the function will retry a
- * number of times until successful or until the number of retries has been
- * exhausted.
- *
- * SenderGetPortFromName() also allows the calling application to explicitly
- * launch a new copy of the requested application, regardless of whether the
- * requested application is running or not. This was done in order to allow
- * multiple copies of the same application to launch.
- *
- * SenderGetPortFromName() has also been extensively commented, both before
- * the function (to explain the function's algorithm) and during the code
- * itself.
- *
- * A new function, SenderLaunchApplication() has been added. This function,
- * written to be called by SenderGetPortFromName(), will fork a new process
- * and try to exec the application whose name is passed in as argument.
- *
- * Revision 1.35 91/09/18 12:51:11 drapeau
- * Modified the SenderGetPortFromName() method, allowing it to receive a list of matching Ports, not
- * just a single matching Port. This was done because it is possible that an application will ask
- * for all applications currently open that match a given name (e.g., if an application needs to
- * communicate with several running copies of the same application).
- *
- * Revision 1.34 91/09/03 16:52:05 drapeau
- * Made minor cosmetic changes to code to better conform to ANSI-C definitions.
- * Also, modified NewSender() to check for the validity of the hostName
- * passed in as part of the senderPort paramater. If the hostName is not
- * valid, a NULL Sender* will be returned.
- *
- * Revision 1.33 91/06/19 14:09:13 drapeau
- * Added support for five new messages:
- * - PauseSelection
- * - ResumeSelection
- * - HideApplication
- * - ShowApplication
- * - GetAppIcon
- * Also, replaced the "PerformPartialSelection" message with
- * "HaltSelection" message.
- *
- *
- * Revision 1.32 91/06/17 18:17:23 drapeau
- * Added copyright notice.
- *
- * Revision 1.31 1991/02/28 07:25:45 drapeau
- * This version uses a new version numbering scheme and a new version of RCS.
- * Also, several other changes:
- * - Added comments at the end of functions to increase readability.
- * - Modified SenderGetSelection(); it now takes a Selection** and allocates
- * space for a Selection for the caller. This was done to provide a
- * more consistent programming interface to the Sender methods.
- * - Modified SenderGetOpenApps() in a similar fashion to SenderGetSelection().
- * The method now allocates space for the Port Array for the caller.
- *
- * Revision 1.3 1991/02/27 03:41:07 drapeau
- * Modified DestroySender() so that it frees space taken by the Sender passed
- * in as argument.
- *
- * Revision 1.2 1990/11/30 13:54:39 drapeau
- * Modified SenderGetSelection() to set duration field in selectionReturn as
- * well as the start and end fields. The previous version of this function
- * incorrectly omitted the duration field.
- *
- * Revision 1.1 90/10/24 18:26:55 drapeau
- * Initial revision
- * */
-
- static char SenderRcsid[] = "$Header: /Source/Media/drapeau/NetworkProtocol/RCS/Sender.c,v 1.39 92/09/30 16:33:36 drapeau Exp $";
-
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <string.h>
- #include <stdio.h>
- #include <Sender.h>
-
- Sender* NewSender(Port* senderPort)
- {
- char* tempHostName;
- struct hostent* hostEntry;
- struct sockaddr_in remoteAddress;
- Sender* newSender;
-
- tempHostName = senderPort->hostName; /* Initialize local variables */
- newSender = (Sender*)malloc(sizeof(Sender));
- newSender->clientSocket = RPC_ANYSOCK;
- newSender->portNumber = senderPort->portNumber;
- newSender->clientPtr = (CLIENT*)NULL;
- newSender->timeOut.tv_sec = 25;
- newSender->timeOut.tv_usec = 0;
- if (newSender->portNumber == 0) /* If the portNumber passed in is 0, then this...*/
- { /* ...Sender was not meant to be used, so...*/
- return(newSender); /* ...just return.*/
- }
- if (tempHostName == (char*)NULL) /* Was any name passed in?*/
- {
- tempHostName = (char*)strdup("localhost"); /* No, set default hostname to the local host*/
- }
- hostEntry = gethostbyname(tempHostName); /* Get host address from the hostname*/
- if (hostEntry == (struct hostent*) NULL) /* gethostbyname failed, print error and exit this function */
- {
- printf("MAEstro Protocol: Could not get host information for host named %s.\n",
- tempHostName);
- free(newSender); /* Free space taken by newSender, which is no longer valid */
- return((Sender*)NULL);
- }
- remoteAddress.sin_port = htons(newSender->portNumber); /* Set up remoteAddress's port number, address family,...*/
- remoteAddress.sin_family = hostEntry->h_addrtype; /* ...and Internet address.*/
- bcopy(hostEntry->h_addr,
- (char*)&remoteAddress.sin_addr,
- hostEntry->h_length);
- newSender->clientPtr = clnttcp_create(&remoteAddress, /* Try to create connection to remote application's...*/
- MAEstro, /* ...receiving port */
- FirstTestVersion,
- &newSender->clientSocket,
- 0,0);
- if (newSender->clientPtr == (CLIENT*)NULL) /* Was the client creation successful?*/
- { /* No, report the error message*/
- printf("MAEstro Protocol: Could not create a new Sender to communicate with\n");
- printf("\t\t Hostname:%s on Port Number:%d.\n",
- tempHostName,newSender->portNumber);
- free(newSender); /* Release space allocated for the invalid Sender */
- return((Sender*)NULL);
- }
- return(newSender);
- } /* end function NewSender*/
-
-
- void DestroySender(Sender* theSender)
- {
- if (theSender != (Sender*)NULL) /* Was the Sender passed in valid? */
- { /* Yes, clean up and destroy the Sender */
- clnt_destroy(theSender->clientPtr); /* Destroy means of communication with remote application */
- close(theSender->clientSocket); /* Close low-level socket on which the clientPtr was based*/
- free(theSender); /* Free space taken by the Sender */
- }
- } /* end function DestroySender */
-
-
- int SenderOpenDocument(Sender* sender, char* documentName)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = opendocument_1(&documentName,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderOpenDocument */
-
-
- int SenderGetCurrentDocName(Sender* sender, char** documentNameReturn)
- {
- char** returnVal = (char**)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = getcurrentdocname_1((void*)0, sender->clientPtr);
- if (returnVal == (char**)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- *documentNameReturn = *returnVal; /* Call succeeded; set up value to return to caller */
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderGetCurrentDocName */
-
-
- int SenderGetSelection(Sender* sender, MAESelection** selectionReturn)
- {
- MAESelection* returnVal = (MAESelection*)NULL;
- MAESelection* newSelection = (MAESelection*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = getselection_1((void*)0,sender->clientPtr);
- if (returnVal == (MAESelection*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- newSelection = (MAESelection*)malloc(sizeof(MAESelection)); /* Try to allocate space for a new MAESelection structure */
- if (newSelection == (MAESelection*)NULL) /* Did the allocation succeed? */
- { /* No, make the MAESelection pointer passed in point to... */
- *selectionReturn = (MAESelection*)NULL; /* ...NULL and return an error condition */
- return(-1);
- }
- *selectionReturn = newSelection; /* Yes, the allocation succeeded */
- newSelection->start = returnVal->start; /* Copy returned MAESelection into... */
- newSelection->end = returnVal->end; /* ...newly-allocated MAESelection */
- newSelection->duration = returnVal->duration;
- newSelection->offset = returnVal->offset;
- bcopy(returnVal->label, newSelection->label, LabelLength);
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderGetSelection */
-
-
- int SenderSetSelection(Sender* sender, MAESelection* selection)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = setselection_1(selection,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderSetSelection */
-
-
-
- int SenderPerformSelection(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = performselection_1((void*)0,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderPerformSelection */
-
-
-
- int SenderConnectWithPortMgr(Sender* sender, Port* receivingPort)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = connectwithportmgr_1(receivingPort,sender->clientPtr);
- if (returnVal == NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderConnectWithPortMgr */
-
-
-
- int SenderGetOpenApps(Sender* sender, PortArray** openAppsReturn)
- {
- PortArray* returnVal = (PortArray*)NULL;
- PortArray* newPortArray = (PortArray*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = getopenapps_1((void*)0,sender->clientPtr);
- if (returnVal == (PortArray*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- *openAppsReturn = (PortArray*)NULL; /* Point to a NULL Port Array, since the call failed */
- return(-1); /* Call failed; return a non-zero result */
- }
- newPortArray = (PortArray*)malloc(sizeof(PortArray)); /* Try to allocate space for a new PortArray */
- if (newPortArray == (PortArray*)NULL) /* Did the allocation fail? */
- { /* Yes, point "openAppsReturn" to a NULL PortArray and... */
- *openAppsReturn = (PortArray*)NULL; /* ...return an error condition */
- return(-1);
- }
- newPortArray->portArray = returnVal->portArray; /* Point new PortArray's Port list to that returned by RPC */
- newPortArray->numberOfPorts = returnVal->numberOfPorts; /* Set new PortArray's number of Ports in the above list */
- *openAppsReturn = newPortArray; /* Point to newly-allocated array */
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderGetOpenApps */
-
-
- /******************************************************************
- * SenderGetPortFromName
- *
- * This function is responsible for making sure that the
- * application specified by the "appNameAndHost" argument is
- * open and listening for messages.
- *
- * The function sends a message to the Port Manager to see if
- * the requested application is already alive. If not, this
- * function will attempt to launch the application.
- * In addition, this function allows the caller to explicitly
- * request that a new version be launched, even if one is
- * already running. To do so, the caller must set the
- * appNameAndHost->hostName field to the defined constant
- * "LaunchNewApp".
- *
- * The function returns a PortArray*, a list of Ports that
- * match the description passed in by appNameAndHost. If
- * no matches were found and if the the desired application
- * cannot be launched, the function returns a NULL PortArray*.
- *
- * The algorithm for this function is as follows:
- * First, the function sends the "GetPortFromName" message to
- * the PortManager, asking how many applications currently
- * open match the description specified by appNameAndHost.
- *
- * Next, the appNameAndHost->hostName field is checked to
- * determine if the caller wants to explicitly launch a new version
- * of the requested application. If so, the variable "numAppsOpen"
- * is set to the number of matching apps that are currently open;
- * otherwise, the variable is set to zero.
- * This variable is used later in the function.
- *
- * Next, the number of matching apps is checked. If the caller
- * does not explicitly need to launch a new copy of the app, then
- * all the function needs is one matching application. However,
- * if the caller explicitly wants an new copy of the app opened,
- * then the function must assure that there is one more copy of the
- * requested app than when the function was called. For example, if
- * the caller wanted an extra copy of "TextEdit" open and three
- * "TextEdit"'s were already open, then this function must assure
- * that four copies are alive before returning successfully.
- *
- * If the desired number of applications are already open, then
- * the function will return the list of matches. This will happen
- * only in the case that the caller is satisfied with any
- * version of the requested app; if the caller asked for a new copy,
- * this test will fail. Also, if there were no matching apps, this
- * test will fail.
- *
- * If the test fails, the function will try to launch a new copy of
- * the requested app, using the SenderLaunchApplication() function.
- * The function will sleep for a time, giving the new application
- * some time to start up.
- * After waiting, the function sends another GetPortFromName
- * message to the Port Manager, to see if the new application is
- * alive and listening for messages. If so, the function will
- * return successfully. If not, the function goes into a loop,
- * sleeping for about one second, then retrying the GetPortFromName
- * request.
- *
- * Eventually, either the loop will succeed, or the number of
- * retries will be exhausted. If the app is still not
- * running after the specified number of retries, the
- * function will return a failure code and a
- * NULL PortArray*.
- */
-
- int SenderGetPortFromName(Sender* sender,
- Port* appNameAndHost,
- PortArray** matchingPortsReturn)
- {
- PortArray* returnVal = (PortArray*)NULL;
- PortArray* newPortArray = (PortArray*)NULL;
- int result = 0;
- int numRetries = 20;
- int attemptNumber = 0; /* Counter variable used in re-trying GetPortFromName msg. */
- int numAppsOpen;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = getportfromname_1(appNameAndHost,sender->clientPtr); /* Find out how many matching apps are open */
- if (returnVal == (PortArray*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- perror("MAEstro Protocol: GetPortFromName message failed."); /* Failure; report the error, return an error code... */
- *matchingPortsReturn = (PortArray*)NULL; /* ...and a NULL PortArray. */
- return(-1);
- }
- if (appNameAndHost->hostName != (char*)NULL) /* Check if the caller wants to force a new copy... */
- { /* ...of the application to be launched */
- if (strcmp(appNameAndHost->hostName,LaunchNewApp) == 0)
- numAppsOpen = returnVal->numberOfPorts; /* Caller explicitly wanted a new version of the app... */
- else /* Caller does not need a new version of the app, only... */
- numAppsOpen = 0; /* ...one will do */
- }
- if (returnVal->numberOfPorts > numAppsOpen) /* Were any matches found? */
- { /* Yes, return right away; no need to try any longer */
- newPortArray = (PortArray*)malloc(sizeof(PortArray)); /* Try to allocate space for a new PortArray */
- if (newPortArray == (PortArray*)NULL) /* Did the allocation fail? */
- { /* Yes, point "openAppsReturn" to a NULL PortArray and... */
- *matchingPortsReturn = (PortArray*)NULL; /* ...return an error condition */
- return(-1);
- }
- newPortArray->portArray = returnVal->portArray; /* Point new PortArray's Port list to that returned by RPC */
- newPortArray->numberOfPorts = returnVal->numberOfPorts; /* Set new PortArray's number of Ports in the above list */
- *matchingPortsReturn = newPortArray; /* Point to newly-allocated array */
- return(0); /* Call succeeded; return success code (0) */
- } /* end if ((returnVal... */
- result = SenderLaunchApplication(appNameAndHost->appName); /* If this stmt. is reached, no matches were found */
- if (result == -1) /* Did attempted launch fail? (-1 is returned on failure) */
- { /* Yes, failure; report the error and return an error code */
- *matchingPortsReturn = (PortArray*)NULL; /* Return a NULL PortArray, since the call failed */
- return(-1);
- }
- usleep(WaitTimeInMicroSeconds); /* Give the child a chance to launch the application */
- for (attemptNumber = 1; /* Wait for newly-launched app to register itself with... */
- attemptNumber <= numRetries; /* ...the Port Manager; retry 20 times sleeping,... */
- attemptNumber++) /* ...for 1 second between tries */
- {
- returnVal = getportfromname_1(appNameAndHost, /* Ask the PortManager again if the application is... */
- sender->clientPtr); /* ...listening for messages */
- if ((returnVal != (PortArray*)NULL) && /* Did the call succeed, and... */
- (returnVal->numberOfPorts > numAppsOpen)) /* ...was a match found? */
- { /* Yes, return right away; no need to try any longer */
- newPortArray = (PortArray*)malloc(sizeof(PortArray)); /* Try to allocate space for a new PortArray */
- if (newPortArray == (PortArray*)NULL) /* Did the allocation fail? */
- { /* Yes, point "openAppsReturn" to a NULL PortArray and... */
- *matchingPortsReturn = (PortArray*)NULL; /* ...return an error condition */
- return(-1);
- }
- newPortArray->portArray = returnVal->portArray; /* Point new PortArray's Port list to that returned by RPC */
- newPortArray->numberOfPorts = returnVal->numberOfPorts; /* Set new PortArray's number of Ports in the above list */
- *matchingPortsReturn = newPortArray; /* Point to newly-allocated array */
- return(0); /* Call succeeded; return success code (0) */
- } /* end if ((returnVal... */
- usleep(OneSecond); /* Wait a short time between calls */
- } /* end (for attemptNumber... */
- if (returnVal == (PortArray*)NULL) /* If this code is reached, then failure occurred */
- { /* This failure means the call itself failed */
- perror("MAEstro Protocol: GetPortFromName message failed."); /* Report the error, return an error code... */
- }
- *matchingPortsReturn = (PortArray*)NULL; /* Return a NULL PortArray, since the call failed */
- return(-1);
- } /* end function SenderGetPortFromName */
-
-
-
- int SenderPortNumber(Sender* sender)
- {
- return(sender->portNumber);
- } /* end function SenderPortNumber */
-
-
-
- int SenderDisconnectFromPortMgr(Sender* sender, Port* appPort)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = disconnectfromportmgr_1(appPort,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderDisconnectFromPortMgr */
-
-
-
- int SenderPing(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = ping_1((void*)0, sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderPing */
-
-
-
- int SenderHaltSelection(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = haltselection_1((void*)0, sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderHaltSelection */
-
-
- int SenderPauseSelection(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = pauseselection_1((void*)0, sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderPauseSelection */
-
-
- int SenderResumeSelection(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = resumeselection_1((void*)0, sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderResumeSelection */
-
-
- int SenderHideApplication(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = hideapplication_1((void*)0,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderHideApplication */
-
-
- int SenderShowApplication(Sender* sender)
- {
- void* returnVal = (void*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = showapplication_1((void*)0,sender->clientPtr);
- if (returnVal == (void*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderShowApplication */
-
-
- int SenderGetAppIcon(Sender* sender, IconData** iconDataReturn)
- {
- IconData* returnVal = (IconData*)NULL;
- IconData* newIconData = (IconData*)NULL;
-
- SenderTimeOut = &(sender->timeOut); /* Use the timeout value for this Sender */
- returnVal = getappicon_1((void*)0,sender->clientPtr);
- if (returnVal == (IconData*)NULL) /* Did the call fail? NULL is returned on failure */
- {
- return(-1); /* Call failed; return a non-zero result */
- }
- newIconData = (IconData*) malloc (sizeof (IconData)); /* Try to allocate space for a new IconData structure */
- if (newIconData == (IconData*)NULL) /* Did the allocation succeed? */
- { /* No, make the IconData pointer passed in point to... */
- *iconDataReturn = (IconData*)NULL; /* ...NULL and return an error condition */
- return(-1);
- }
- *iconDataReturn = newIconData; /* Yes, the allocation succeeded */
- newIconData->iconData = (char*)NULL;
- newIconData->iconData = malloc(returnVal->dataLength); /* Try to allocate space for copy of application icon */
- if (newIconData->iconData == (char*)NULL) /* Did the allocation fail? */
- { /* Yes, failure: */
- free(newIconData); /* Free space taken by newIconData */
- return(-1); /* Return an error code */
- }
- bcopy(returnVal->iconData,newIconData->iconData, /* Copy icon data to the newly-allocated structure */
- returnVal->dataLength);
- newIconData->dataLength = returnVal->dataLength;
- return(0); /* Call succeeded; return success code (0) */
- } /* end function SenderGetAppIcon */
-
-
- /*******************************************************************
- * SenderLaunchApplication
- *
- * This function attempts to launch the application specified
- * by the string "appName" passed in as argument.
- * The function first tries to fork a new process. If the
- * fork is unsuccessful, and error will be printed and an
- * error code will be returned.
- * If the fork is successful, the function will then try to
- * exec the new process, using the "execlp()" function.
- * The execlp() function uses the calling environment's search
- * path to look for the application to be launched; therefore,
- * the full pathname of the application need not be known.
- * This function returns -1 if the launch failed; if the
- * launch is successful, the parent part of the fork will
- * return the process ID of the child process, and the child
- * part of the fork will not return at all (since a
- * successful exec() does not return; see the man page for
- * exec() for more details).
- *
- */
-
- int SenderLaunchApplication(char* appName)
- {
- int processID = 0;
- int result = 0;
- char errorString[256];
-
- processID = fork(); /* Try to fork and exec the new application */
- if (processID == -1)
- {
- perror("MAEstro Protocol: Could not create a new process in which to launch the application.");
- return(processID);
- }
- if (processID == 0) /* This is the child process part of the code */
- {
- if (appName != (char*)NULL) /* Try to launch the app, only if a valid app name was... */
- result = execlp(appName, appName, (char*)0); /* ..passed in as argument */
- if (result == -1) /* Did the execlp fail? */
- { /* Yes, report the error and return an error code */
- sprintf(errorString,
- "MAEstro Protocol: Could not find the application %s to launch.\n",
- appName);
- perror(errorString);
- return(result);
- }
- } /* End child part of the fork */
- else /* This is the parent part of the fork */
- return(processID);
- } /* end function LaunchApplication */
-
-
-
- int SenderSynchronousMessaging(Sender* sender, int onOff)
- {
- if (onOff == On)
- {
- sender->timeOut.tv_sec = 25;
- sender->timeOut.tv_usec = 0;
- }
- else
- {
- sender->timeOut.tv_sec = 0; /* In Sun RPC, if the timeout value for an RPC call is zero,... */
- sender->timeOut.tv_usec = 0; /* ...the sender will not block waiting for a return. In... */
- } /* ...effect, a zero-timeout value makes RPC's non-blocking. */
- return(0);
- } /* end function SenderSynchronousMessaging */
-