void SendFailed(struct display *d, const char *reason) { Debug("display start failed, sending <failed>\n"); send_failed((struct sockaddr *)(d->from.data), d->from.length, d->name, d->sessionID, reason, d->xdmcpFd); }
int CSocket::send(const void* data,uint len,int flags) { int ret=::send(m_s,(const char*)data,len,flags); if(ret==-1)throw send_failed(L"send failed"); return ret; }
static void manage(struct sockaddr *from, int fromlen, int length, int fd) { CARD32 sessionID; CARD16 displayNumber; ARRAY8 displayClass; int expectlen; struct protoDisplay *pdpy; struct display *d; char *name = NULL; char *class2 = NULL; XdmcpNetaddr from_save; ARRAY8 clientAddress, clientPort; CARD16 connectionType; Debug("<manage> %d\n", length); displayClass.data = 0; displayClass.length = 0; if(XdmcpReadCARD32(&buffer, &sessionID) && XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY8(&buffer, &displayClass)) { expectlen = 4 + /* session ID */ 2 + /* displayNumber */ 2 + displayClass.length; /* displayClass */ if(expectlen != length) { Debug("<manage> length error got %d expect %d\n", length, expectlen); goto abort; } pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber); Debug("<manage> session ID %ld, pdpy %p\n", (long)sessionID, pdpy); if(!pdpy || pdpy->sessionID != sessionID) { /* * We may have already started a session for this display * but it hasn't seen the response in the form of an * XOpenDisplay() yet. So check if it is in the list of active * displays, and if so check that the session id's match. * If all this is true, then we have a duplicate request that * can be ignored. */ if(!pdpy && (d = FindDisplayByAddress((XdmcpNetaddr)from, fromlen, displayNumber)) && d->sessionID == sessionID) { Debug("manage: got duplicate pkt, ignoring\n"); goto abort; } Debug("session ID %ld refused\n", (long)sessionID); if(pdpy) Debug("existing session ID %ld\n", (long)pdpy->sessionID); send_refuse(from, fromlen, sessionID, fd); } else { name = NetworkAddressToName(pdpy->connectionType, &pdpy->connectionAddress, from, pdpy->displayNumber); if(!name) { Debug("could not compute display name\n"); send_failed(from, fromlen, "(no name)", sessionID, "out of memory", fd); goto abort; } Debug("computed display name: %s\n", name); if((d = FindDisplayByName(name))) { Debug("terminating active session for %s\n", d->name); StopDisplay(d); } if(displayClass.length) { if(!StrNDup(&class2, (char *)displayClass.data, displayClass.length)) { send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } } if(!(from_save = (XdmcpNetaddr)Malloc(fromlen))) { send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } memmove(from_save, from, fromlen); if(!(d = NewDisplay(name))) { free((char *)from_save); send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } d->class2 = class2; class2 = 0; d->displayType = dForeign | dTransient | dFromXDMCP; d->sessionID = pdpy->sessionID; d->from.data = (unsigned char *)from_save; d->from.length = fromlen; d->displayNumber = pdpy->displayNumber; ClientAddress(from, &clientAddress, &clientPort, &connectionType); d->useChooser = 0; d->xdmcpFd = fd; if(IsIndirectClient(&clientAddress, connectionType)) { Debug("IsIndirectClient\n"); ForgetIndirectClient(&clientAddress, connectionType); if(UseChooser(&clientAddress, connectionType)) { d->useChooser = 1; Debug("use chooser for %s\n", d->name); } } d->clientAddr = clientAddress; d->connectionType = connectionType; d->remoteHost = NetworkAddressToHostname(pdpy->connectionType, &pdpy->connectionAddress); XdmcpDisposeARRAY8(&clientPort); if(pdpy->fileAuthorization) { d->authorizations = (Xauth **)Malloc(sizeof(Xauth *)); if(!d->authorizations) { free((char *)from_save); free((char *)d); send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } d->authorizations[0] = pdpy->fileAuthorization; d->authNum = 1; pdpy->fileAuthorization = 0; } DisposeProtoDisplay(pdpy); Debug("starting display %s,%s\n", d->name, d->class2); if(LoadDisplayResources(d) < 0) { LogError( "Unable to read configuration for display %s; " "stopping it.\n", d->name); StopDisplay(d); } else StartDisplay(d); CloseGetter(); } } abort: XdmcpDisposeARRAY8(&displayClass); if(name) free((char *)name); if(class2) free((char *)class2); }