📄 xdmcp.c
字号:
voidXdmcpRegisterAuthorizations (){ XdmcpDisposeARRAYofARRAY8 (&AuthorizationNames); RegisterAuthorizations ();}voidXdmcpRegisterAuthorization (name, namelen) char *name; int namelen;{ ARRAY8 authName; int i; authName.data = (CARD8 *) xalloc (namelen * sizeof (CARD8)); if (!authName.data) return; if (!XdmcpReallocARRAYofARRAY8 (&AuthorizationNames, AuthorizationNames.length +1)) { xfree (authName.data); return; } for (i = 0; i < namelen; i++) authName.data[i] = (CARD8) name[i]; authName.length = namelen; AuthorizationNames.data[AuthorizationNames.length-1] = authName;}/* * Register the DisplayClass string */ARRAY8 DisplayClass;voidXdmcpRegisterDisplayClass (name, length) char *name; int length;{ int i; XdmcpDisposeARRAY8 (&DisplayClass); if (!XdmcpAllocARRAY8 (&DisplayClass, length)) return; for (i = 0; i < length; i++) DisplayClass.data[i] = (CARD8) name[i];}/* * Register the Manufacturer display ID */ARRAY8 ManufacturerDisplayID;voidXdmcpRegisterManufacturerDisplayID (name, length) char *name; int length;{ int i; XdmcpDisposeARRAY8 (&ManufacturerDisplayID); if (!XdmcpAllocARRAY8 (&ManufacturerDisplayID, length)) return; for (i = 0; i < length; i++) ManufacturerDisplayID.data[i] = (CARD8) name[i];}/* * initialize XDMCP; create the socket, compute the display * number, set up the state machine */void XdmcpInit(){ state = XDM_INIT_STATE;#ifdef HASXDMAUTH if (xdmAuthCookie) XdmAuthenticationInit (xdmAuthCookie, strlen (xdmAuthCookie));#endif if (state != XDM_OFF) { XdmcpRegisterAuthorizations(); XdmcpRegisterDisplayClass (defaultDisplayClass, strlen (defaultDisplayClass)); AccessUsingXdmcp(); RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler, (pointer) 0); timeOutRtx = 0; DisplayNumber = (CARD16) atoi(display); get_xdmcp_sock(); send_packet(); }}voidXdmcpReset (){ state = XDM_INIT_STATE; if (state != XDM_OFF) { RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler, (pointer) 0); timeOutRtx = 0; send_packet(); }}/* * Called whenever a new connection is created; notices the * first connection and saves it to terminate the session * when it is closed */voidXdmcpOpenDisplay(sock) int sock;{ if (state != XDM_AWAIT_MANAGE_RESPONSE) return; state = XDM_RUN_SESSION; sessionSocket = sock;}void XdmcpCloseDisplay(sock) int sock;{ if ((state != XDM_RUN_SESSION && state != XDM_AWAIT_ALIVE_RESPONSE) || sessionSocket != sock) return; state = XDM_INIT_STATE; if (OneSession) dispatchException |= DE_TERMINATE; else dispatchException |= DE_RESET; isItTimeToYield = TRUE;}/* * called before going to sleep, this routine * may modify the timeout value about to be sent * to select; in this way XDMCP can do appropriate things * dynamically while starting up *//*ARGSUSED*/static voidXdmcpBlockHandler(data, wt, pReadmask) pointer data; /* unused */ struct timeval **wt; pointer pReadmask;{ fd_set *LastSelectMask = (fd_set*)pReadmask; CARD32 millisToGo, wtMillis; static struct timeval waittime; if (state == XDM_OFF) return; FD_SET(xdmcpSocket, LastSelectMask); if (timeOutTime == 0) return; millisToGo = GetTimeInMillis(); if (millisToGo < timeOutTime) millisToGo = timeOutTime - millisToGo; else millisToGo = 0; if (*wt == NULL) { waittime.tv_sec = (millisToGo) / 1000; waittime.tv_usec = 1000 * (millisToGo % 1000); *wt = &waittime; } else { wtMillis = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000; if (millisToGo < wtMillis) { (*wt)->tv_sec = (millisToGo) / 1000; (*wt)->tv_usec = 1000 * (millisToGo % 1000); } }}/* * called after select returns; this routine will * recognise when XDMCP packets await and * process them appropriately *//*ARGSUSED*/static voidXdmcpWakeupHandler(data, i, pReadmask) pointer data; /* unused */ int i; pointer pReadmask;{ fd_set* LastSelectMask = (fd_set*)pReadmask; fd_set devicesReadable; if (state == XDM_OFF) return; if (i > 0) { if (FD_ISSET(xdmcpSocket, LastSelectMask)) { receive_packet(); FD_CLR(xdmcpSocket, LastSelectMask); } XFD_ANDSET(&devicesReadable, LastSelectMask, &EnabledDevices); if (XFD_ANYSET(&devicesReadable)) { if (state == XDM_AWAIT_USER_INPUT) restart(); else if (state == XDM_RUN_SESSION) keepaliveDormancy = defaultKeepaliveDormancy; } if (XFD_ANYSET(&AllClients) && state == XDM_RUN_SESSION) timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000; } else if (timeOutTime && GetTimeInMillis() >= timeOutTime) { if (state == XDM_RUN_SESSION) { state = XDM_KEEPALIVE; send_packet(); } else timeout(); }}/* * This routine should be called from the routine that drives the * user's host menu when the user selects a host */XdmcpSelectHost(host_sockaddr, host_len, AuthenticationName) struct sockaddr_in *host_sockaddr; int host_len; ARRAY8Ptr AuthenticationName;{ state = XDM_START_CONNECTION; memmove(&req_sockaddr, host_sockaddr, host_len); req_socklen = host_len; XdmcpSetAuthentication (AuthenticationName); send_packet();}/* * !!! this routine should be replaced by a routine that adds * the host to the user's host menu. the current version just * selects the first host to respond with willing message. *//*ARGSUSED*/XdmcpAddHost(from, fromlen, AuthenticationName, hostname, status) struct sockaddr_in *from; ARRAY8Ptr AuthenticationName, hostname, status;{ XdmcpSelectHost(from, fromlen, AuthenticationName);}/* * A message is queued on the socket; read it and * do the appropriate thing */ARRAY8 UnwillingMessage = { (CARD8) 14, (CARD8 *) "Host unwilling" };static voidreceive_packet(){ struct sockaddr_in from; int fromlen = sizeof(struct sockaddr_in); XdmcpHeader header; /* read message off socket */ if (!XdmcpFill (xdmcpSocket, &buffer, (struct sockaddr *) &from, &fromlen)) return; /* reset retransmission backoff */ timeOutRtx = 0; if (!XdmcpReadHeader (&buffer, &header)) return; if (header.version != XDM_PROTOCOL_VERSION) return; switch (header.opcode) { case WILLING: recv_willing_msg(&from, fromlen, header.length); break; case UNWILLING: XdmcpFatal("Manager unwilling", &UnwillingMessage); break; case ACCEPT: recv_accept_msg(header.length); break; case DECLINE: recv_decline_msg(header.length); break; case REFUSE: recv_refuse_msg(header.length); break; case FAILED: recv_failed_msg(header.length); break; case ALIVE: recv_alive_msg(header.length); break; }}/* * send the appropriate message given the current state */staticsend_packet(){ int rtx; switch (state) { case XDM_QUERY: case XDM_BROADCAST: case XDM_INDIRECT: send_query_msg(); break; case XDM_START_CONNECTION: send_request_msg(); break; case XDM_MANAGE: send_manage_msg(); break; case XDM_KEEPALIVE: send_keepalive_msg(); break; } rtx = (XDM_MIN_RTX << timeOutRtx); if (rtx > XDM_MAX_RTX) rtx = XDM_MAX_RTX; timeOutTime = GetTimeInMillis() + rtx * 1000;}/* * The session is declared dead for some reason; too many * timeouts, or Keepalive failure. */XdmcpDeadSession (reason) char *reason;{ ErrorF ("XDM: %s, declaring session dead\n", reason); state = XDM_INIT_STATE; isItTimeToYield = TRUE; dispatchException |= DE_RESET; timeOutTime = 0; timeOutRtx = 0; send_packet();}/* * Timeout waiting for an XDMCP response. */static voidtimeout(){ timeOutRtx++; if (state == XDM_AWAIT_ALIVE_RESPONSE && timeOutRtx >= XDM_KA_RTX_LIMIT ) { XdmcpDeadSession ("too many keepalive retransmissions"); return; } else if (timeOutRtx >= XDM_RTX_LIMIT) { ErrorF("XDM: too many retransmissions\n"); state = XDM_AWAIT_USER_INPUT; timeOutTime = 0; timeOutRtx = 0; return; } switch (state) { case XDM_COLLECT_QUERY: state = XDM_QUERY; break; case XDM_COLLECT_BROADCAST_QUERY: state = XDM_BROADCAST; break; case XDM_COLLECT_INDIRECT_QUERY: state = XDM_INDIRECT; break; case XDM_AWAIT_REQUEST_RESPONSE: state = XDM_START_CONNECTION; break; case XDM_AWAIT_MANAGE_RESPONSE: state = XDM_MANAGE; break; case XDM_AWAIT_ALIVE_RESPONSE: state = XDM_KEEPALIVE; break; } send_packet();}staticrestart(){ state = XDM_INIT_STATE; timeOutRtx = 0; send_packet();}XdmcpCheckAuthentication (Name, Data, packet_type) ARRAY8Ptr Name, Data; int packet_type;{ return (XdmcpARRAY8Equal (Name, AuthenticationName) && (AuthenticationName->length == 0 || (*AuthenticationFuncs->Validator) (AuthenticationData, Data, packet_type)));}XdmcpAddAuthorization (name, data) ARRAY8Ptr name, data;{ Bool (*AddAuth)(), AddAuthorization(); if (AuthenticationFuncs && AuthenticationFuncs->AddAuth) AddAuth = AuthenticationFuncs->AddAuth; else AddAuth = AddAuthorization; return (*AddAuth) ((unsigned short)name->length, (char *)name->data, (unsigned short)data->length, (char *)data->data);}/* * from here to the end of this file are routines private * to the state machine. */static voidget_xdmcp_sock(){#ifdef STREAMSCONN struct netconfig *nconf; if ((xdmcpSocket = t_open("/dev/udp", O_RDWR, 0)) < 0) { XdmcpWarning("t_open() of /dev/udp failed"); return; } if( t_bind(xdmcpSocket,NULL,NULL) < 0 ) { XdmcpWarning("UDP socket creation failed"); t_error("t_bind(xdmcpSocket) failed" ); t_close(xdmcpSocket); return; } /* * This part of the code looks contrived. It will actually fit in nicely * when the CLTS part of Xtrans is implemented. */ if( (nconf=getnetconfigent("udp")) == NULL ) { XdmcpWarning("UDP socket creation failed: getnetconfigent()"); t_unbind(xdmcpSocket); t_close(xdmcpSocket); return; } if( netdir_options(nconf, ND_SET_BROADCAST, xdmcpSocket, NULL) ) { XdmcpWarning("UDP set broadcast option failed: netdir_options()"); freenetconfigent(nconf); t_unbind(xdmcpSocket); t_close(xdmcpSocket); return; } freenetconfigent(nconf);#else#ifndef _MINIX int soopts = 1; if ((xdmcpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -