IceWriteData32 ( IceConn iceConn, unsigned long nbytes, int *data ) { int numLongs = nbytes / 4; int index = 0; while (index < numLongs) { int spaceLeft, count, i; int longsLeft = numLongs - index; spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; if (spaceLeft < 4) { IceFlush (iceConn); spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; } count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4; for (i = 0; i < count; i++) STORE_CARD32 (iceConn->outbufptr, data[index++]); } }
Status SmcRequestSaveYourselfPhase2(SmcConn smcConn, SmcSaveYourselfPhase2Proc saveYourselfPhase2Proc, SmPointer clientData) { IceConn iceConn = smcConn->iceConn; _SmcPhase2Wait *wait; if (smcConn->phase2_wait) wait = smcConn->phase2_wait; else { if ((wait = (_SmcPhase2Wait *) malloc ( sizeof (_SmcPhase2Wait))) == NULL) { return (0); } } wait->phase2_proc = saveYourselfPhase2Proc; wait->client_data = clientData; smcConn->phase2_wait = wait; IceSimpleMessage (iceConn, _SmcOpcode, SM_SaveYourselfPhase2Request); IceFlush (iceConn); return (1); }
Status SmcGetProperties(SmcConn smcConn, SmcPropReplyProc propReplyProc, SmPointer clientData) { IceConn iceConn = smcConn->iceConn; _SmcPropReplyWait *wait, *ptr; if ((wait = (_SmcPropReplyWait *) malloc ( sizeof (_SmcPropReplyWait))) == NULL) { return (0); } wait->prop_reply_proc = propReplyProc; wait->client_data = clientData; wait->next = NULL; ptr = smcConn->prop_reply_waits; while (ptr && ptr->next) ptr = ptr->next; if (ptr == NULL) smcConn->prop_reply_waits = wait; else ptr->next = wait; IceSimpleMessage (iceConn, _SmcOpcode, SM_GetProperties); IceFlush (iceConn); return (1); }
Status IcePing ( IceConn iceConn, IcePingReplyProc pingReplyProc, IcePointer clientData ) { _IcePingWait *newping = malloc (sizeof (_IcePingWait)); _IcePingWait *ptr = iceConn->ping_waits; if (newping == NULL) return (0); newping->ping_reply_proc = pingReplyProc; newping->client_data = clientData; newping->next = NULL; while (ptr && ptr->next) ptr = ptr->next; if (ptr == NULL) iceConn->ping_waits = newping; else ptr->next = newping; IceSimpleMessage (iceConn, 0, ICE_Ping); IceFlush (iceConn); return (1); }
void SmcDeleteProperties(SmcConn smcConn, int numProps, char **propNames) { IceConn iceConn = smcConn->iceConn; smDeletePropertiesMsg *pMsg; char *pData; int extra, i; extra = 8; for (i = 0; i < numProps; i++) extra += ARRAY8_BYTES (strlen (propNames[i])); IceGetHeaderExtra (iceConn, _SmcOpcode, SM_DeleteProperties, SIZEOF (smDeletePropertiesMsg), WORD64COUNT (extra), smDeletePropertiesMsg, pMsg, pData); STORE_CARD32 (pData, numProps); pData += 4; for (i = 0; i < numProps; i++) STORE_ARRAY8 (pData, strlen (propNames[i]), propNames[i]); IceFlush (iceConn); }
IceWriteData16 ( IceConn iceConn, unsigned long nbytes, short *data ) { int numShorts = nbytes / 2; int index = 0; while (index < numShorts) { int spaceLeft, count, i; int shortsLeft = numShorts - index; spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; if (spaceLeft < 2) { IceFlush (iceConn); spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; } count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2; for (i = 0; i < count; i++) STORE_CARD16 (iceConn->outbufptr, data[index++]); } }
bool KRequestShutdownHelper::requestShutdown( ShutdownConfirm confirm ) { #if HAVE_X11 if( conn == NULL ) return false; SmcRequestSaveYourself( conn, SmSaveBoth, True, SmInteractStyleAny, confirm == ShutdownConfirmNo, True ); // flush the request IceFlush(SmcGetIceConnection(conn)); #endif return true; }
void SmcSaveYourselfDone(SmcConn smcConn, Bool success) { IceConn iceConn = smcConn->iceConn; smSaveYourselfDoneMsg *pMsg; IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfDone, SIZEOF (smSaveYourselfDoneMsg), smSaveYourselfDoneMsg, pMsg); pMsg->success = success; IceFlush (iceConn); }
void SmcInteractDone(SmcConn smcConn, Bool cancelShutdown) { IceConn iceConn = smcConn->iceConn; smInteractDoneMsg *pMsg; IceGetHeader (iceConn, _SmcOpcode, SM_InteractDone, SIZEOF (smInteractDoneMsg), smInteractDoneMsg, pMsg); pMsg->cancelShutdown = cancelShutdown; IceFlush (iceConn); }
void SmcRequestSaveYourself(SmcConn smcConn, int saveType, Bool shutdown, int interactStyle, Bool fast, Bool global) { IceConn iceConn = smcConn->iceConn; smSaveYourselfRequestMsg *pMsg; IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfRequest, SIZEOF (smSaveYourselfRequestMsg), smSaveYourselfRequestMsg, pMsg); pMsg->saveType = saveType; pMsg->shutdown = shutdown; pMsg->interactStyle = interactStyle; pMsg->fast = fast; pMsg->global = global; IceFlush (iceConn); }
void SmcSetProperties(SmcConn smcConn, int numProps, SmProp **props) { IceConn iceConn = smcConn->iceConn; smSetPropertiesMsg *pMsg; char *pBuf; char *pStart; int bytes; IceGetHeader (iceConn, _SmcOpcode, SM_SetProperties, SIZEOF (smSetPropertiesMsg), smSetPropertiesMsg, pMsg); LISTOF_PROP_BYTES (numProps, props, bytes); pMsg->length += WORD64COUNT (bytes); pBuf = pStart = IceAllocScratch (iceConn, bytes); memset(pStart, 0, bytes); STORE_LISTOF_PROPERTY (pBuf, numProps, props); IceWriteData (iceConn, bytes, pStart); IceFlush (iceConn); }
Status SmcInteractRequest(SmcConn smcConn, int dialogType, SmcInteractProc interactProc, SmPointer clientData) { IceConn iceConn = smcConn->iceConn; smInteractRequestMsg *pMsg; _SmcInteractWait *wait, *ptr; if ((wait = (_SmcInteractWait *) malloc ( sizeof (_SmcInteractWait))) == NULL) { return (0); } wait->interact_proc = interactProc; wait->client_data = clientData; wait->next = NULL; ptr = smcConn->interact_waits; while (ptr && ptr->next) ptr = ptr->next; if (ptr == NULL) smcConn->interact_waits = wait; else ptr->next = wait; IceGetHeader (iceConn, _SmcOpcode, SM_InteractRequest, SIZEOF (smInteractRequestMsg), smInteractRequestMsg, pMsg); pMsg->dialogType = dialogType; IceFlush (iceConn); return (1); }
SmcConn SmcOpenConnection(char *networkIdsList, SmPointer context, int xsmpMajorRev, int xsmpMinorRev, unsigned long mask, SmcCallbacks *callbacks, char *previousId, char **clientIdRet, int errorLength, char *errorStringRet) { SmcConn smcConn; IceConn iceConn; char *ids; IceProtocolSetupStatus setupstat; int majorVersion; int minorVersion; char *vendor = NULL; char *release = NULL; smRegisterClientMsg *pMsg; char *pData; int extra, len; IceReplyWaitInfo replyWait; _SmcRegisterClientReply reply; Bool gotReply, ioErrorOccured; const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"}; IcePoAuthProc auth_procs[] = {_IcePoMagicCookie1Proc}; int auth_count = 1; IcePoVersionRec versions[] = { {SmProtoMajor, SmProtoMinor, _SmcProcessMessage} }; int version_count = 1; *clientIdRet = NULL; if (errorStringRet && errorLength > 0) *errorStringRet = '\0'; if (!_SmcOpcode) { /* * For now, there is only one version of XSMP, so we don't * have to check {xsmpMajorRev, xsmpMinorRev}. In the future, * we will check against versions and generate the list * of versions the application actually supports. */ if ((_SmcOpcode = IceRegisterForProtocolSetup ("XSMP", SmVendorString, SmReleaseString, version_count, versions, auth_count, auth_names, auth_procs, NULL)) < 0) { if (errorStringRet && errorLength > 0) { strncpy (errorStringRet, "Could not register XSMP protocol with ICE", errorLength); errorStringRet[errorLength - 1] = '\0'; } return (NULL); } } if (networkIdsList == NULL || *networkIdsList == '\0') { if ((ids = (char *) getenv ("SESSION_MANAGER")) == NULL) { if (errorStringRet && errorLength > 0) { strncpy (errorStringRet, "SESSION_MANAGER environment variable not defined", errorLength); errorStringRet[errorLength - 1] = '\0'; } return (NULL); } } else { ids = networkIdsList; } if ((iceConn = IceOpenConnection ( ids, context, 0, _SmcOpcode, errorLength, errorStringRet)) == NULL) { return (NULL); } if ((smcConn = (SmcConn) malloc (sizeof (struct _SmcConn))) == NULL) { if (errorStringRet && errorLength > 0) { strncpy (errorStringRet, "Can't malloc", errorLength); errorStringRet[errorLength - 1] = '\0'; } IceCloseConnection (iceConn); return (NULL); } setupstat = IceProtocolSetup (iceConn, _SmcOpcode, (IcePointer) smcConn, False /* mustAuthenticate */, &majorVersion, &minorVersion, &vendor, &release, errorLength, errorStringRet); if (setupstat == IceProtocolSetupFailure || setupstat == IceProtocolSetupIOError) { IceCloseConnection (iceConn); free ((char *) smcConn); return (NULL); } else if (setupstat == IceProtocolAlreadyActive) { /* * This case should never happen, because when we called * IceOpenConnection, we required that the ICE connection * may not already have XSMP active on it. */ free ((char *) smcConn); if (errorStringRet && errorLength > 0) { strncpy (errorStringRet, "Internal error in IceOpenConnection", errorLength); errorStringRet[errorLength - 1] = '\0'; } return (NULL); } smcConn->iceConn = iceConn; smcConn->proto_major_version = majorVersion; smcConn->proto_minor_version = minorVersion; smcConn->vendor = vendor; smcConn->release = release; smcConn->client_id = NULL; bzero ((char *) &smcConn->callbacks, sizeof (SmcCallbacks)); set_callbacks (smcConn, mask, callbacks); smcConn->interact_waits = NULL; smcConn->phase2_wait = NULL; smcConn->prop_reply_waits = NULL; smcConn->save_yourself_in_progress = False; smcConn->shutdown_in_progress = False; /* * Now register the client */ if (!previousId) previousId = ""; len = strlen (previousId); extra = ARRAY8_BYTES (len); IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), smRegisterClientMsg, pMsg, pData); STORE_ARRAY8 (pData, len, previousId); IceFlush (iceConn); replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); replyWait.major_opcode_of_request = _SmcOpcode; replyWait.minor_opcode_of_request = SM_RegisterClient; replyWait.reply = (IcePointer) &reply; gotReply = False; ioErrorOccured = False; while (!gotReply && !ioErrorOccured) { ioErrorOccured = (IceProcessMessages ( iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); if (ioErrorOccured) { if (errorStringRet && errorLength > 0) { strncpy (errorStringRet, "IO error occured opening connection", errorLength); errorStringRet[errorLength - 1] = '\0'; } free (smcConn->vendor); free (smcConn->release); free ((char *) smcConn); return (NULL); } else if (gotReply) { if (reply.status == 1) { /* * The client successfully registered. */ *clientIdRet = reply.client_id; smcConn->client_id = (char *) malloc ( strlen (*clientIdRet) + 1); strcpy (smcConn->client_id, *clientIdRet); } else { /* * Could not register the client because the previous ID * was bad. So now we register the client with the * previous ID set to NULL. */ extra = ARRAY8_BYTES (0); IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), smRegisterClientMsg, pMsg, pData); STORE_ARRAY8 (pData, 0, ""); IceFlush (iceConn); replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); gotReply = False; } } } return (smcConn); }
void FWPprocessMessages( IceConn iceConn, IcePointer * client_data, int opcode, unsigned long length, Bool swap) { switch (opcode) { /* * this is really the only opcode we care about -- the one * which indicates an XFindProxy request for a connection * to a specified server */ case PM_GetProxyAddr: { pmGetProxyAddrMsg *pMsg; char *pData, *pStart; char *serviceName = NULL, *serverAddress = NULL; char *hostAddress = NULL, *startOptions = NULL; char *authName = NULL, *authData = NULL; int authLen; struct clientDataStruct * program_data; char * listen_port_string; int pm_send_msg_len; pmGetProxyAddrReplyMsg * pReply; char * pReplyData; struct hostent * hostptr; struct sockaddr_in server_sockaddr_in; struct sockaddr_in dummy_sockaddr_in; char * server_name_base; char * config_failure = "unrecognized server or permission denied"; char * tmp_str; int rule_number = -1; char * colon; char * tmpAddress = NULL; /* * this is where we need and get access to that client data we * went through such contortions to set up earlier! */ program_data = (struct clientDataStruct *) client_data; /* * initial check on expected message size */ CHECK_AT_LEAST_SIZE (iceConn, global_data.major_opcode, opcode, length, SIZEOF (pmGetProxyAddrMsg), IceFatalToProtocol); IceReadCompleteMessage (iceConn, SIZEOF (pmGetProxyAddrMsg), pmGetProxyAddrMsg, pMsg, pStart); if (!IceValidIO (iceConn)) { IceDisposeCompleteMessage (iceConn, pStart); return; } authLen = swap ? lswaps (pMsg->authLen) : pMsg->authLen; pData = pStart; SKIP_STRING (pData, swap); /* proxy-service */ SKIP_STRING (pData, swap); /* server-address */ SKIP_STRING (pData, swap); /* host-address */ SKIP_STRING (pData, swap); /* start-options */ if (authLen > 0) { SKIP_STRING (pData, swap); /* auth-name */ pData += (authLen + PAD64 (authLen)); /* auth-data */ } /* * now a detailed check on message size */ CHECK_COMPLETE_SIZE (iceConn, global_data.major_opcode, opcode, length, pData - pStart + SIZEOF (pmGetProxyAddrMsg), pStart, IceFatalToProtocol); pData = pStart; /* * extract message data, based on known characteristics * of this message type */ EXTRACT_STRING (pData, swap, serviceName); EXTRACT_STRING (pData, swap, serverAddress); EXTRACT_STRING (pData, swap, hostAddress); EXTRACT_STRING (pData, swap, startOptions); if (authLen > 0) { EXTRACT_STRING (pData, swap, authName); authData = (char *) malloc (authLen); memcpy (authData, pData, authLen); } #ifdef DEBUG (void) fprintf (stderr, "Got GetProxyAddr, serviceName = %s, serverAddr = %s\n", serviceName, serverAddress); (void) fprintf (stderr, "\thostAddr = %s, options = %s, authLen = %d\n", hostAddress, startOptions, authLen); if (authLen > 0) (void) fprintf (stderr, "\tauthName = %s\n", authName); #endif /* * need to copy the host port string because strtok() changes it */ if ((tmp_str = strdup (serverAddress)) == NULL) { (void) fprintf(stderr, "malloc - serverAddress copy\n"); goto sendFailure; } /* * before proceeding we want to verify that we are allowed to * accept connections from the host who called xfindproxy(); * the thing is, we don't get that host name from Proxy Manager * even if the "-host <hostname>" command-line option was present * in xfindproxy (and even if it was we shouldn't rely on it -- * much better to have ProxyMngr query the xfindproxy connect * socket for its origin); the upshot of all this that we do * a configuration check *only* on the destination (which we * assume in this case to be the serverAddress passed in by * xfindproxy(); so get the destination IP address! */ server_name_base = strtok(tmp_str, ":"); if ((hostptr = gethostbyname(server_name_base)) == NULL) { (void) fprintf(stderr, "gethostbyname (%s) failed\n", server_name_base); goto sendFailure; } memset(&server_sockaddr_in, 0, sizeof(server_sockaddr_in)); memset(&dummy_sockaddr_in, 0, sizeof(dummy_sockaddr_in)); memcpy((char *) &server_sockaddr_in.sin_addr, hostptr->h_addr, hostptr->h_length); /* * need to initialize dummy to something, but doesn't matter * what (should eventually be the true host address); * NOTE: source configuration will always match (see XFWP man * page) unless sysadmin explicitly chooses to deny */ memcpy((char *) &dummy_sockaddr_in.sin_addr, hostptr->h_addr, hostptr->h_length); if ((doConfigCheck(&dummy_sockaddr_in, &server_sockaddr_in, global_data.config_info, FINDPROXY, &rule_number)) == FAILURE) { (void) fprintf(stderr, "xfindproxy failed config check\n"); sendFailure: /* * report failure back to the ProxyMgr * */ pm_send_msg_len = STRING_BYTES(config_failure) + STRING_BYTES(NULL); IceGetHeaderExtra(iceConn, program_data->major_opcode, PM_GetProxyAddrReply, SIZEOF(pmGetProxyAddrReplyMsg), WORD64COUNT (pm_send_msg_len), pmGetProxyAddrReplyMsg, pReply, pReplyData); pReply->status = PM_Failure; STORE_STRING(pReplyData, NULL); STORE_STRING(pReplyData, config_failure); IceFlush(iceConn); free(tmp_str); return; } /* * okay, you got what you need from the PM to proceed, * so extract the fd of the selected connection and use * it to set up the remote client listen port and add * the name of the X server to your list of server connections */ /* * Before checking to see if you already have a PM connection * request for this server, make serverAddress a * FQDN so that synonomous names like oregon:0 and oregon.com:0 * will be recognized as the same Xserver. If this server * already exists, don't allocate another listen port for it - * use the already allocated one */ colon = strchr (serverAddress, ':'); if (colon) { struct hostent *hostent; *colon = '\0'; hostent = gethostbyname (serverAddress); *colon = ':'; if (hostent && hostent->h_name) { tmpAddress = (char *) malloc (strlen (hostent->h_name) + strlen (colon) + 1); (void) sprintf (tmpAddress, "%s%s", hostent->h_name, colon); serverAddress = tmpAddress; } } if ((doCheckServerList(serverAddress, &listen_port_string, program_data->config_info->num_servers)) == FAILURE) { /* * this server name isn't in your list; so set up a new * remote client listen port for it; extract the fd from * the connection and pass it in as index to array lookup */ if ((doSetupRemClientListen(&listen_port_string, program_data, serverAddress)) == FAILURE) { goto sendFailure; } } if (tmpAddress) free (tmpAddress); /* * the PM-sent server address *was* in your list, so send back * the rem client listen port you had already associated with * that server (it will presumably be forwarded to the remote * client through some other channel) * use IceGetHeaderExtra() and the */ pm_send_msg_len = STRING_BYTES(listen_port_string) + STRING_BYTES(NULL); IceGetHeaderExtra(iceConn, program_data->major_opcode, PM_GetProxyAddrReply, SIZEOF(pmGetProxyAddrReplyMsg), WORD64COUNT (pm_send_msg_len), pmGetProxyAddrReplyMsg, pReply, pReplyData); pReply->status = PM_Success; STORE_STRING(pReplyData, listen_port_string); STORE_STRING(pReplyData, NULL); IceFlush(iceConn); /* * before leaving this routine, change the select() timeout * here to be equal to the configured client listen timeout * (otherwise you'll never *get* to your listen timeout * if it's shorter than the startup select() default */ program_data->config_info->select_timeout.tv_sec = program_data->config_info->client_listen_timeout; break; } case ICE_Error: { iceErrorMsg *pMsg; char *pStart; CHECK_AT_LEAST_SIZE (iceConn, global_data.major_opcode, ICE_Error, length, sizeof(iceErrorMsg), IceFatalToProtocol); IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg), iceErrorMsg, pMsg, pStart); if (!IceValidIO (iceConn)) { IceDisposeCompleteMessage (iceConn, pStart); return; } if (swap) { pMsg->errorClass = lswaps (pMsg->errorClass); pMsg->offendingSequenceNum = lswapl (pMsg->offendingSequenceNum); } (void) fprintf(stderr, "Proxy Manager reported ICE Error:\n"); (void) fprintf(stderr, "\tclass = 0x%x, offending minor opcode = %d\n", pMsg->errorClass, pMsg->offendingMinorOpcode); (void) fprintf(stderr, "\tseverity = %d, sequence = %ld\n", pMsg->severity, (long)pMsg->offendingSequenceNum); IceDisposeCompleteMessage (iceConn, pStart); break; } default: break; } /* end switch */ }
int main(int argc, char *argv[]) { static XtAppContext appContext; IceConn iceConn; IceProtocolSetupStatus setupstat; char *vendor = NULL; char *release = NULL; pmGetProxyAddrMsg *pMsg; char *pData; int i; size_t len; IceReplyWaitInfo replyWait; GetProxyAddrReply reply; int majorVersion, minorVersion; Bool gotReply, ioErrorOccured; char errorString[255]; char *serviceName = NULL, *serverAddress = NULL; char *hostAddress = NULL, *startOptions = NULL; char *managerAddress = NULL; Bool haveAuth = 0; char authName[40]; char authData[128]; char *authDataBinary = NULL; int authLen = 0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'a': /* -auth */ haveAuth = 1; continue; case 'm': /* -manager */ if (++i >= argc) goto usage; managerAddress = (char *) XtNewString (argv[i]); continue; case 's': /* -server */ if (++i >= argc) goto usage; serverAddress = (char *) XtNewString (argv[i]); continue; case 'n': /* -name */ if (++i >= argc) goto usage; serviceName = XtNewString (argv[i]); continue; case 'h': /* -host */ if (++i >= argc) goto usage; hostAddress = XtNewString (argv[i]); continue; case 'o': /* -options */ if (++i >= argc) goto usage; startOptions = XtNewString (argv[i]); continue; case 'v': puts(PACKAGE_STRING); exit(0); } } usage: if (i >= argc) fprintf (stderr, "%s: %s requires an argument\n", argv[0], argv[i-1]); else fprintf (stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[i]); usage(); } if (serviceName == NULL) { fprintf (stderr, "%s: -name serviceName must be specified\n", argv[0]); usage(); } if (serverAddress == NULL) { fprintf (stderr, "%s: -server serverAddr must be specified\n", argv[0]); usage(); } if (managerAddress == NULL) { managerAddress = getenv("PROXY_MANAGER"); if (managerAddress == NULL) { fprintf (stderr, "Error: -manager option must be specified when PROXY_MANAGER is not in the environment\n"); exit (1); } } /* * Register support for PROXY_MANAGEMENT. */ if ((PMopcode = IceRegisterForProtocolSetup ( PM_PROTOCOL_NAME, "XC", "1.0", PMversionCount, PMversions, 0, /* authcount */ NULL, /* authnames */ NULL, /* authprocs */ NULL /* IceIOErrorProc */ )) < 0) { fprintf (stderr, "Could not register PROXY_MANAGEMENT protocol with ICE"); exit (1); } appContext = XtCreateApplicationContext (); InitWatchProcs (appContext); if ((iceConn = IceOpenConnection ( managerAddress, NULL, 0, 0, 256, errorString)) == NULL) { fprintf (stderr, "Could not open ICE connection to proxy manager: %s", errorString); exit (1); } setupstat = IceProtocolSetup (iceConn, PMopcode, NULL, False /* mustAuthenticate */, &majorVersion, &minorVersion, &vendor, &release, 256, errorString); if (setupstat != IceProtocolSetupSuccess) { IceCloseConnection (iceConn); fprintf (stderr, "Could not initialize proxy management protocol: %s\n", errorString); exit (1); } /* * If auth data is supplied, read it from stdin. */ if (haveAuth) { fgets (authName, sizeof (authName), stdin); fgets (authData, sizeof (authData), stdin); for (i = 0; i < strlen (authName); i++) if (authName[i] == '\n') { authName[i] = '\0'; break; } for (i = 0; i < strlen (authData); i++) if (authData[i] == '\n') { authData[i] = '\0'; break; } /* * Convert the hex auth data to binary. */ authLen = cvthexkey (authData, &authDataBinary); if (authLen == -1) { fprintf (stderr, "Could not convert hex auth data to binary\n"); exit (1); } } /* * Now send the GetProxyAddr request. */ len = STRING_BYTES (serviceName) + STRING_BYTES (serverAddress) + STRING_BYTES (hostAddress) + STRING_BYTES (startOptions) + (authLen > 0 ? (STRING_BYTES (authName) + authLen) : 0); IceGetHeaderExtra (iceConn, PMopcode, PM_GetProxyAddr, SIZEOF (pmGetProxyAddrMsg), WORD64COUNT (len), pmGetProxyAddrMsg, pMsg, pData); pMsg->authLen = (CARD16) authLen; STORE_STRING (pData, serviceName); STORE_STRING (pData, serverAddress); STORE_STRING (pData, hostAddress); STORE_STRING (pData, startOptions); if (authLen > 0) { STORE_STRING (pData, authName); memcpy (pData, authDataBinary, authLen); } IceFlush (iceConn); replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); replyWait.major_opcode_of_request = PMopcode; replyWait.minor_opcode_of_request = PM_GetProxyAddr; replyWait.reply = (IcePointer) &reply; gotReply = False; ioErrorOccured = False; while (!gotReply && !ioErrorOccured) { ioErrorOccured = (IceProcessMessages ( iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); if (ioErrorOccured) { fprintf (stderr, "IO error occured\n"); exit (1); } else if (gotReply) { if (reply.status == PM_Success) { fprintf (stdout, "%s\n", reply.addr); exit (0); } else { fprintf (stderr, "Error from proxy manager: %s\n", reply.error); exit (1); } } } /*NOTREACHED*/ exit(0); }
IceProtocolSetupStatus IceProtocolSetup ( IceConn iceConn, int myOpcode, IcePointer clientData, Bool mustAuthenticate, int *majorVersionRet, int *minorVersionRet, char **vendorRet, char **releaseRet, int errorLength, char *errorStringRet ) { iceProtocolSetupMsg *pMsg; char *pData; _IceProtocol *myProtocol; int extra; Bool gotReply, ioErrorOccured; int accepted, i; int hisOpcode; unsigned long setup_sequence; IceReplyWaitInfo replyWait; _IceReply reply; IcePoVersionRec *versionRec = NULL; int authCount; int *authIndices; if (errorStringRet && errorLength > 0) *errorStringRet = '\0'; *majorVersionRet = 0; *minorVersionRet = 0; *vendorRet = NULL; *releaseRet = NULL; if (myOpcode < 1 || myOpcode > _IceLastMajorOpcode) { strncpy (errorStringRet, "myOpcode out of range", errorLength); return (IceProtocolSetupFailure); } myProtocol = &_IceProtocols[myOpcode - 1]; if (myProtocol->orig_client == NULL) { strncpy (errorStringRet, "IceRegisterForProtocolSetup was not called", errorLength); return (IceProtocolSetupFailure); } /* * Make sure this protocol hasn't been activated already. */ if (iceConn->process_msg_info) { for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++) { if (iceConn->process_msg_info[ i - iceConn->his_min_opcode].in_use && iceConn->process_msg_info[ i - iceConn->his_min_opcode ].my_opcode == myOpcode) break; } if (i <= iceConn->his_max_opcode) { return (IceProtocolAlreadyActive); } } /* * Generate the message. */ if (myProtocol->orig_client->auth_count > 0) { authIndices = malloc ( myProtocol->orig_client->auth_count * sizeof (int)); _IceGetPoValidAuthIndices (myProtocol->protocol_name, iceConn->connection_string, myProtocol->orig_client->auth_count, (const char **) myProtocol->orig_client->auth_names, &authCount, authIndices); } else { authCount = 0; authIndices = NULL; } extra = STRING_BYTES (myProtocol->protocol_name) + STRING_BYTES (myProtocol->orig_client->vendor) + STRING_BYTES (myProtocol->orig_client->release); for (i = 0; i < authCount; i++) { extra += STRING_BYTES (myProtocol->orig_client->auth_names[ authIndices[i]]); } extra += (myProtocol->orig_client->version_count * 4); IceGetHeaderExtra (iceConn, 0, ICE_ProtocolSetup, SIZEOF (iceProtocolSetupMsg), WORD64COUNT (extra), iceProtocolSetupMsg, pMsg, pData); setup_sequence = iceConn->send_sequence; pMsg->protocolOpcode = myOpcode; pMsg->versionCount = myProtocol->orig_client->version_count; pMsg->authCount = authCount; pMsg->mustAuthenticate = mustAuthenticate; STORE_STRING (pData, myProtocol->protocol_name); STORE_STRING (pData, myProtocol->orig_client->vendor); STORE_STRING (pData, myProtocol->orig_client->release); for (i = 0; i < authCount; i++) { STORE_STRING (pData, myProtocol->orig_client->auth_names[ authIndices[i]]); } for (i = 0; i < myProtocol->orig_client->version_count; i++) { STORE_CARD16 (pData, myProtocol->orig_client->version_recs[i].major_version); STORE_CARD16 (pData, myProtocol->orig_client->version_recs[i].minor_version); } IceFlush (iceConn); /* * Process messages until we get a Protocol Reply. */ replyWait.sequence_of_request = setup_sequence; replyWait.major_opcode_of_request = 0; replyWait.minor_opcode_of_request = ICE_ProtocolSetup; replyWait.reply = (IcePointer) &reply; iceConn->protosetup_to_you = malloc (sizeof (_IceProtoSetupToYouInfo)); iceConn->protosetup_to_you->my_opcode = myOpcode; iceConn->protosetup_to_you->my_auth_count = authCount; iceConn->protosetup_to_you->auth_active = 0; iceConn->protosetup_to_you->my_auth_indices = authIndices; gotReply = False; ioErrorOccured = False; accepted = 0; while (!gotReply && !ioErrorOccured) { ioErrorOccured = (IceProcessMessages ( iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); if (ioErrorOccured) { strncpy (errorStringRet, "IO error occured doing Protocol Setup on connection", errorLength); return (IceProtocolSetupIOError); } else if (gotReply) { if (reply.type == ICE_PROTOCOL_REPLY) { if (reply.protocol_reply.version_index >= myProtocol->orig_client->version_count) { strncpy (errorStringRet, "Got a bad version index in the Protocol Reply", errorLength); free (reply.protocol_reply.vendor); free (reply.protocol_reply.release); } else { versionRec = &(myProtocol->orig_client->version_recs[ reply.protocol_reply.version_index]); accepted = 1; } } else /* reply.type == ICE_PROTOCOL_ERROR */ { /* Protocol Setup failed */ strncpy (errorStringRet, reply.protocol_error.error_message, errorLength); free (reply.protocol_error.error_message); } if (iceConn->protosetup_to_you->my_auth_indices) free (iceConn->protosetup_to_you->my_auth_indices); free (iceConn->protosetup_to_you); iceConn->protosetup_to_you = NULL; } } if (accepted) { _IceProcessMsgInfo *process_msg_info; *majorVersionRet = versionRec->major_version; *minorVersionRet = versionRec->minor_version; *vendorRet = reply.protocol_reply.vendor; *releaseRet = reply.protocol_reply.release; /* * Increase the reference count for the number of active protocols. */ iceConn->proto_ref_count++; /* * We may be using a different major opcode for this protocol * than the other client. Whenever we get a message, we must * map to our own major opcode. */ hisOpcode = reply.protocol_reply.major_opcode; _IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode); process_msg_info = &iceConn->process_msg_info[hisOpcode - iceConn->his_min_opcode]; process_msg_info->client_data = clientData; process_msg_info->accept_flag = 0; process_msg_info->process_msg_proc.orig_client = versionRec->process_msg_proc; return (IceProtocolSetupSuccess); } else { return (IceProtocolSetupFailure); } }
Bool dcop_call( const char * appId, const char * remApp, const char * remObjId, const char * remFun, const char * data, int dataLength, char ** replyType, char ** replyData, int * replyDataLength ) { IceReplyWaitInfo waitInfo; IceProcessMessagesStatus status; struct dcop_reply_struct replyStruct; char * pos = 0L; char * outputData = 0L; int outputDataLength = 0; int temp = 0; Bool success = False; Bool readyRet = False; struct DCOPMsg * pMsg; fprintf(stderr, "dcop_call() ...\n"); if (0 == dcop_ice_conn) { fprintf(stderr, "Try running dcop_register(), moron\n"); return False; } temp += strlen(appId); temp += strlen(remApp); temp += strlen(remObjId); temp += strlen(remFun); temp += dataLength; temp += 1024; /* Extra space for marshalling overhead */ outputData = (char *)malloc(temp); temp = 0; pos = outputData; pos = dcop_write_string(pos, appId); pos = dcop_write_string(pos, remApp); pos = dcop_write_string(pos, remObjId); pos = dcop_write_string(pos, remFun); pos = dcop_write_int(pos, dataLength); outputDataLength = pos - outputData; IceGetHeader( dcop_ice_conn, dcop_major_opcode, DCOPCall, sizeof(struct DCOPMsg), struct DCOPMsg, pMsg ); pMsg->length += outputDataLength + dataLength; IceSendData(dcop_ice_conn, outputDataLength, outputData); IceSendData(dcop_ice_conn, dataLength, (char *)data); IceFlush(dcop_ice_conn); free(outputData); outputData = NULL; if (IceConnectionStatus(dcop_ice_conn) != IceConnectAccepted) { fprintf(stderr, "dcop_call(): Connection not accepted\n"); return False; } waitInfo.sequence_of_request = IceLastSentSequenceNumber(dcop_ice_conn); waitInfo.major_opcode_of_request = dcop_major_opcode; waitInfo.minor_opcode_of_request = DCOPCall; replyStruct.status = DCOP_REPLY_PENDING; replyStruct.replyId = dcop_reply_id++; replyStruct.replyType = replyType; replyStruct.replyData = replyData; replyStruct.replyDataLength = replyDataLength; waitInfo.reply = (IcePointer)(&replyStruct); readyRet = False; do { fprintf(stderr, "dcop_call(): Doing IceProcessMessages\n"); status = IceProcessMessages(dcop_ice_conn, &waitInfo, &readyRet); if (status == IceProcessMessagesIOError) { fprintf(stderr, "dcop_call(): IceProcessMessagesIOError\n"); IceCloseConnection(dcop_ice_conn); return False; } fprintf(stderr, "dcop_call(): readyRet == %s\n", readyRet ? "True" : "False"); } while (!readyRet); fprintf(stderr, "dcop_call(): Finished\n"); return (replyStruct.status == DCOP_REPLY_OK) ? True : False; }
Bool dcop_send_signal( const char * receiving_app, const char * object, const char * function, char * data, int dataLength ) { char * pos = 0L; char * header = 0L; unsigned int headerLength = 0; struct DCOPMsg * pMsgPtr = 0; static const char* sAnonymous = "anonymous"; if (0 == dcop_ice_conn) { fprintf(stderr, "Try running dcop_attach(), moron\n"); return False; } /* * First let ICE initialize the ICE Message Header and give us a pointer to * it (ICE manages that buffer internally) */ IceGetHeader( dcop_ice_conn, dcop_major_opcode, DCOPSend, sizeof(struct DCOPMsg), struct DCOPMsg, pMsgPtr ); /* * Marshall the arguments for the DCOP message header (callerApp, destApp, * destObj, destFunc. The last argument is actually part of the data part of * the call, but we add it to the header. It's the size of the marshalled * argument data. In Qt it would look like TQDataStream str( ... ) str << * callerApp << destApp << destObj << destFun << * argumentQByteArrayDataStuff; (where as str is the complete data stream * sent do the dcopserver, excluding the ICE header) As the TQByteArray is * marshalled as [size][data] and as we (below) send the data in two chunks, * first the dcop msg header and the the data, we just put the [size] field * as last field into the dcop msg header ;-) */ headerLength = strlen(sAnonymous) + 1 + strlen(receiving_app) + 1 + strlen(object) + 1 + strlen(function) + 1 + 4*5; /* 4 string lengths + 1 int */ header = (char *)malloc(headerLength); pos = header; pos = dcop_write_string(pos, sAnonymous); pos = dcop_write_string(pos, receiving_app); pos = dcop_write_string(pos, object); pos = dcop_write_string(pos, function); pos = dcop_write_int(pos, dataLength); headerLength = pos - header; pMsgPtr->key = dcop_key; /* * The length field tells the dcopserver how much bytes the dcop message * takes up. We add that size to the already by IceGetHeader initialized * length value, as it seems that under some circumstances (depending on the * DCOPMsg structure size) the length field is aligned/padded. */ pMsgPtr->length += headerLength + dataLength; /* First let's send the dcop message header. * IceSendData automatically takes care of first sending the Ice Message * Header (outbufptr > outbuf -> flush the connection buffer) */ IceSendData(dcop_ice_conn, headerLength, header); /* Now the function argument data */ IceSendData(dcop_ice_conn, dataLength, data); /* Send it all ;-) */ IceFlush(dcop_ice_conn); free(header); if (IceConnectionStatus(dcop_ice_conn) != IceConnectAccepted) return False; return True; }
SmcCloseStatus SmcCloseConnection(SmcConn smcConn, int count, char **reasonMsgs) { IceConn iceConn = smcConn->iceConn; smCloseConnectionMsg *pMsg; char *pData; int extra, i; IceCloseStatus closeStatus; SmcCloseStatus statusRet; extra = 8; for (i = 0; i < count; i++) extra += ARRAY8_BYTES (strlen (reasonMsgs[i])); IceGetHeaderExtra (iceConn, _SmcOpcode, SM_CloseConnection, SIZEOF (smCloseConnectionMsg), WORD64COUNT (extra), smCloseConnectionMsg, pMsg, pData); STORE_CARD32 (pData, count); pData += 4; for (i = 0; i < count; i++) STORE_ARRAY8 (pData, strlen (reasonMsgs[i]), reasonMsgs[i]); IceFlush (iceConn); IceProtocolShutdown (iceConn, _SmcOpcode); IceSetShutdownNegotiation (iceConn, False); closeStatus = IceCloseConnection (iceConn); if (smcConn->vendor) free (smcConn->vendor); if (smcConn->release) free (smcConn->release); if (smcConn->client_id) free (smcConn->client_id); if (smcConn->prop_reply_waits) { _SmcPropReplyWait *ptr = smcConn->prop_reply_waits; _SmcPropReplyWait *next; while (ptr) { next = ptr->next; free ((char *) ptr); ptr = next; } } free ((char *) smcConn); if (closeStatus == IceClosedNow) statusRet = SmcClosedNow; else if (closeStatus == IceClosedASAP) statusRet = SmcClosedASAP; else statusRet = SmcConnectionInUse; return (statusRet); }
IceCloseStatus IceCloseConnection ( IceConn iceConn ) { int refCountReachedZero; IceCloseStatus status; /* * If this connection object was never valid, we can close * it right now. This happens if IceAcceptConnection was * called, but after calling IceProcessMessages several times * the connection was rejected (because of authentication or * some other reason). */ if (iceConn->listen_obj && iceConn->connection_status != IceConnectAccepted) { _IceConnectionClosed (iceConn); /* invoke watch procs */ _IceFreeConnection (iceConn); return (IceClosedNow); } /*--------------------------------------------------------------- ACTIONS: A = Invoke Watch Procedures B = Set free-asap bit C = Free connection D = Initialize shutdown negotiation N = do nothing ACTION TABLE: IO free- dispatch protocol shutdown error asap bit level refcount negotiation ACTION occured set reached 0 reached 0 0 0 0 0 0 N 0 0 0 0 1 N 0 0 0 1 0 AB 0 0 0 1 1 N 0 0 1 0 0 N 0 0 1 0 1 N 0 0 1 1 0 AC 0 0 1 1 1 D 0 1 0 0 0 N 0 1 0 0 1 N 0 1 0 1 0 N 0 1 0 1 1 N 0 1 1 0 0 C 0 1 1 0 1 D 0 1 1 1 0 C 0 1 1 1 1 D 1 0 0 0 0 AB 1 0 0 0 1 AB 1 0 0 1 0 AB 1 0 0 1 1 AB 1 0 1 0 0 AC 1 0 1 0 1 AC 1 0 1 1 0 AC 1 0 1 1 1 AC 1 1 0 0 0 N 1 1 0 0 1 N 1 1 0 1 0 N 1 1 0 1 1 N 1 1 1 0 0 C 1 1 1 0 1 C 1 1 1 1 0 C 1 1 1 1 1 C ---------------------------------------------------------------*/ if (iceConn->open_ref_count > 0) iceConn->open_ref_count--; refCountReachedZero = iceConn->open_ref_count == 0 && iceConn->proto_ref_count == 0; status = IceConnectionInUse; if (!iceConn->free_asap && (!iceConn->io_ok || (iceConn->io_ok && refCountReachedZero && iceConn->skip_want_to_close))) { /* * Invoke the watch procedures now. */ _IceConnectionClosed (iceConn); status = IceClosedNow; /* may be overwritten by IceClosedASAP */ } if (!iceConn->free_asap && iceConn->dispatch_level != 0 && (!iceConn->io_ok || (iceConn->io_ok && refCountReachedZero && iceConn->skip_want_to_close))) { /* * Set flag so we free the connection as soon as possible. */ iceConn->free_asap = True; status = IceClosedASAP; } if (iceConn->io_ok && iceConn->dispatch_level == 0 && !iceConn->skip_want_to_close && refCountReachedZero) { /* * Initiate shutdown negotiation. */ IceSimpleMessage (iceConn, 0, ICE_WantToClose); IceFlush (iceConn); iceConn->want_to_close = 1; status = IceStartedShutdownNegotiation; } else if (iceConn->dispatch_level == 0 && (!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close && (iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero))))) { /* * Free the connection. */ _IceFreeConnection (iceConn); status = IceClosedNow; } return (status); }