static void error_conn_max(XtransConnInfo trans_conn) { int fd = _FontTransGetConnectionNumber (trans_conn); fsConnSetup conn; char pad[3]; char byteOrder = 0; int whichbyte = 1; struct timeval waittime; fd_set mask; waittime.tv_usec = BOTIMEOUT / MILLI_PER_SECOND; waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) * (1000000 / MILLI_PER_SECOND); FD_ZERO(&mask); FD_SET(fd, &mask); (void) Select(fd + 1, &mask, NULL, NULL, &waittime); /* try to read the byteorder of the connection */ (void) _FontTransRead(trans_conn, &byteOrder, 1); if ((byteOrder == 'l') || (byteOrder == 'B')) { int num_alts; AlternateServerPtr altservers, as; int i, altlen = 0; num_alts = ListAlternateServers(&altservers); conn.status = AuthDenied; conn.major_version = FS_PROTOCOL; conn.minor_version = FS_PROTOCOL_MINOR; conn.num_alternates = num_alts; for (i = 0, as = altservers; i < num_alts; i++, as++) { altlen += (2 + as->namelen + 3) >> 2; } conn.alternate_len = altlen; /* blow off the auth info */ conn.auth_index = 0; conn.auth_len = 0; if (((*(char *) &whichbyte) && (byteOrder == 'B')) || (!(*(char *) &whichbyte) && (byteOrder == 'l'))) { conn.status = lswaps(conn.status); conn.major_version = lswaps(conn.major_version); conn.minor_version = lswaps(conn.minor_version); conn.alternate_len = lswaps(conn.alternate_len); } (void) _FontTransWrite(trans_conn, (char *) &conn, SIZEOF(fsConnSetup)); /* dump alternates */ for (i = 0, as = altservers; i < num_alts; i++, as++) { (void) _FontTransWrite(trans_conn, (char *) as, 2); /* XXX */ (void) _FontTransWrite(trans_conn, (char *) as->name, as->namelen); altlen = 2 + as->namelen; /* pad it */ if (altlen & 3) (void) _FontTransWrite(trans_conn, (char *) pad, ((4 - (altlen & 3)) & 3)); } }
/* * creates the sockets for listening to clients * * only called when server first started */ void CreateSockets(int old_listen_count, OldListenRec *old_listen) { int i; FD_ZERO(&AllSockets); FD_ZERO(&AllClients); FD_ZERO(&LastSelectMask); FD_ZERO(&ClientsWithInput); FD_ZERO(&WellKnownConnections); for (i = 0; i < MAXSOCKS; i++) ConnectionTranslation[i] = 0; #ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */ #undef _SC_OPEN_MAX #endif #ifdef _SC_OPEN_MAX lastfdesc = sysconf(_SC_OPEN_MAX) - 1; #else #if defined(hpux) || defined(__UNIXOS2__) lastfdesc = _NFILE - 1; #else lastfdesc = getdtablesize() - 1; #endif /* hpux */ #endif if (lastfdesc > MAXSOCKS) { lastfdesc = MAXSOCKS; } if (old_listen_count > 0) { /* * The font server cloned itself. Re-use previously opened * transports for listening. */ ListenTransConns = (XtransConnInfo *) malloc ( old_listen_count * sizeof (XtransConnInfo)); ListenTransFds = (int *) malloc (old_listen_count * sizeof (int)); ListenTransCount = 0; for (i = 0; i < old_listen_count; i++) { char portnum[10]; if (old_listen[i].portnum != ListenPort) continue; /* this should never happen */ else sprintf (portnum, "%d", old_listen[i].portnum); if ((ListenTransConns[ListenTransCount] = _FontTransReopenCOTSServer (old_listen[i].trans_id, old_listen[i].fd, portnum)) != NULL) { ListenTransFds[ListenTransCount] = old_listen[i].fd; FD_SET (old_listen[i].fd, &WellKnownConnections); NoticeF("reusing existing file descriptor %d\n", old_listen[i].fd); ListenTransCount++; } } } else { char port[20]; int partial; sprintf (port, "%d", ListenPort); if ((_FontTransMakeAllCOTSServerListeners (port, &partial, &ListenTransCount, &ListenTransConns) >= 0) && (ListenTransCount >= 1)) { ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int)); for (i = 0; i < ListenTransCount; i++) { int fd = _FontTransGetConnectionNumber (ListenTransConns[i]); ListenTransFds[i] = fd; FD_SET (fd, &WellKnownConnections); } } } if (! XFD_ANYSET(&WellKnownConnections)) FatalError("cannot establish any listening sockets\n"); /* set up all the signal handlers */ signal(SIGPIPE, SIG_IGN); signal(SIGHUP, AutoResetServer); signal(SIGINT, GiveUp); signal(SIGTERM, GiveUp); signal(SIGUSR1, ServerReconfig); signal(SIGUSR2, ServerCacheFlush); signal(SIGCHLD, CleanupChild); XFD_COPYSET (&WellKnownConnections, &AllSockets); }
/* * accepts new connections */ void MakeNewConnections(void) { fd_mask readyconnections; int curconn; int newconn; long connect_time; int i; ClientPtr client; OsCommPtr oc; fd_set tmask; XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections); readyconnections = tmask.fds_bits[0]; if (!readyconnections) return; connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i = MINCLIENT; i < currentMaxClients; i++) { if ((client = clients[i]) != NullClient) { oc = (OsCommPtr) client->osPrivate; if ((oc && (oc->conn_time != 0) && (connect_time - oc->conn_time) >= TimeOutValue) || ((client->noClientException != FSSuccess) && (client->clientGone != CLIENT_GONE))) CloseDownClient(client); } } while (readyconnections) { XtransConnInfo trans_conn, new_trans_conn; int status; curconn = ffs(readyconnections) - 1; readyconnections &= ~(1 << curconn); if ((trans_conn = lookup_trans_conn (curconn)) == NULL) continue; if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL) continue; newconn = _FontTransGetConnectionNumber (new_trans_conn); _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); oc = (OsCommPtr) fsalloc(sizeof(OsCommRec)); if (!oc) { fsfree(oc); error_conn_max(new_trans_conn); _FontTransClose(new_trans_conn); continue; } FD_SET(newconn, &AllClients); FD_SET(newconn, &AllSockets); oc->fd = newconn; oc->trans_conn = new_trans_conn; oc->input = (ConnectionInputPtr) NULL; oc->output = (ConnectionOutputPtr) NULL; oc->conn_time = connect_time; if ((newconn < lastfdesc) && (client = NextAvailableClient((pointer) oc))) { ConnectionTranslation[newconn] = client->index; } else { error_conn_max(new_trans_conn); close_fd(oc); } } }
/* * creates the sockets for listening to clients * * only called when server first started */ void CreateSockets(int old_listen_count, OldListenRec *old_listen) { int i; struct sigaction act; FD_ZERO(&AllSockets); FD_ZERO(&AllClients); FD_ZERO(&LastSelectMask); FD_ZERO(&ClientsWithInput); FD_ZERO(&WellKnownConnections); for (i = 0; i < MAXSOCKS; i++) ConnectionTranslation[i] = 0; lastfdesc = sysconf(_SC_OPEN_MAX) - 1; if ((lastfdesc < 0) || (lastfdesc > MAXSOCKS)) { lastfdesc = MAXSOCKS; } if (old_listen_count > 0) { /* * The font server cloned itself. Re-use previously opened * transports for listening. */ ListenTransConns = (XtransConnInfo *) malloc ( old_listen_count * sizeof (XtransConnInfo)); ListenTransFds = (int *) malloc (old_listen_count * sizeof (int)); ListenTransCount = 0; for (i = 0; i < old_listen_count; i++) { char portnum[10]; if (old_listen[i].portnum != ListenPort) continue; /* this should never happen */ else sprintf (portnum, "%d", old_listen[i].portnum); if ((ListenTransConns[ListenTransCount] = _FontTransReopenCOTSServer (old_listen[i].trans_id, old_listen[i].fd, portnum)) != NULL) { ListenTransFds[ListenTransCount] = old_listen[i].fd; FD_SET (old_listen[i].fd, &WellKnownConnections); NoticeF("reusing existing file descriptor %d\n", old_listen[i].fd); ListenTransCount++; } } } else { char port[20]; int partial; sprintf (port, "%d", ListenPort); if ((_FontTransMakeAllCOTSServerListeners (port, &partial, &ListenTransCount, &ListenTransConns) >= 0) && (ListenTransCount >= 1)) { ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int)); for (i = 0; i < ListenTransCount; i++) { int fd = _FontTransGetConnectionNumber (ListenTransConns[i]); ListenTransFds[i] = fd; FD_SET (fd, &WellKnownConnections); } } } if (! XFD_ANYSET(&WellKnownConnections)) FatalError("cannot establish any listening sockets\n"); /* set up all the signal handlers */ sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; #define HANDLE_SIGNAL(s, h) act.sa_handler = h; sigaction(s, &act, NULL) HANDLE_SIGNAL(SIGPIPE, SIG_IGN); HANDLE_SIGNAL(SIGHUP, AutoResetServer); HANDLE_SIGNAL(SIGINT, GiveUp); HANDLE_SIGNAL(SIGTERM, GiveUp); HANDLE_SIGNAL(SIGUSR1, ServerReconfig); HANDLE_SIGNAL(SIGUSR2, ServerCacheFlush); HANDLE_SIGNAL(SIGCHLD, CleanupChild); XFD_COPYSET (&WellKnownConnections, &AllSockets); }