main() { char buf[ BUFFER_SIZE ] ; int cc ; int nbytes ; for ( ;; ) { nbytes = RANDOM() & ( BUFFER_SIZE - 1 ) ; if ( nbytes == 0 ) nbytes = 1 ; cc = read( 0, buf, nbytes ) ; if ( cc == 0 ) break ; if ( Swrite( 1, buf, cc ) != cc ) exit( 1 ) ; } exit( 0 ) ; }
static int banner_fail( const struct service *sp, const connection_s *cp ) { const char *func = "banner_fail"; const struct service_config *scp = SVC_CONF( sp ) ; if ( SC_BANNER_FAIL(scp) != NULL ) { char tmpbuf[TMPSIZE]; int retval; int bannerfd = open(SC_BANNER_FAIL(scp), O_RDONLY); if( bannerfd < 0 ) { msg( LOG_ERR, func, "service = %s, open of banner %s failed", SVC_ID( sp ), SC_BANNER_FAIL(scp)); return(-1); } while( (retval = read(bannerfd, tmpbuf, sizeof(tmpbuf))) ) { if (retval == -1) { if (errno == EINTR) continue; else { msg(LOG_ERR, func, "service %s, Error %m reading banner %s", SVC_ID( sp ), SC_BANNER(scp)); break; } } Swrite(cp->co_descriptor, tmpbuf, retval); } Sclose(bannerfd); Sflush ( cp->co_descriptor ); } return(0); }
static void tcpmux_handler( const struct server *serp ) { char svc_name[ BUFFER_SIZE ] ; int cc ; int descriptor = SERVER_FD( serp ) ; const struct service *svc = SERVER_SERVICE( serp ) ; unsigned u; struct service *sp = NULL; struct server server, *nserp; struct service_config *scp = NULL; close_all_svc_descriptors(); /* Read in the name of the service in the format "svc_name\r\n". * * XXX: should loop on partial reads (could probably use Sread() if * it wasn't thrown out of xinetd source code a few revisions back). */ do { cc = read( descriptor, svc_name, sizeof( svc_name ) ) ; } while (cc == -1 && errno == EINTR); if ( cc <= 0 ) { msg(LOG_ERR, "tcpmux_handler", "read failed"); exit(0); } if ( ( cc <= 2 ) || ( ( svc_name[cc - 1] != '\n' ) || ( svc_name[cc - 2] != '\r' ) ) ) { if ( debug.on ) msg(LOG_DEBUG, "tcpmux_handler", "Invalid service name format."); exit(0); } svc_name[cc - 2] = '\0'; /* Remove \r\n for compare */ if ( debug.on ) { msg(LOG_DEBUG, "tcpmux_handler", "Input (%d bytes) %s as service name.", cc, svc_name); } /* Search the services for the a match on name. */ for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) { sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; if ( strcasecmp( svc_name, SC_NAME( SVC_CONF( sp ) ) ) == 0 ) { /* Found the pointer. Validate its type. */ scp = SVC_CONF( sp ); /* if ( ! SVC_IS_MUXCLIENT( sp ) ) { if ( debug.on ) { msg(LOG_DEBUG, "tcpmux_handler", "Non-tcpmux service name: %s.", svc_name); } exit(0); } */ /* Send the accept string if we're a PLUS (+) client. */ if ( SVC_IS_MUXPLUSCLIENT( sp ) ) { if ( Swrite( descriptor, TCPMUX_ACK, sizeof( TCPMUX_ACK ) ) != sizeof( TCPMUX_ACK ) ) { msg(LOG_ERR, "tcpmux_handler", "Ack write failed for %s.", svc_name); exit(0); } } break; /* Time to get on with the service */ } continue; /* Keep looking */ } if ( u >= pset_count( SERVICES( ps ) ) ) { if ( debug.on ) { msg(LOG_DEBUG, "tcpmux_handler", "Service name %s not found.", svc_name); } exit(0); } if( SVC_WAITS( svc ) ) /* Service forks, so close it */ Sclose(descriptor); server.svr_sp = sp; server.svr_conn = SERVER_CONNECTION(serp); nserp = server_alloc(&server); if( SC_IS_INTERNAL( scp ) ) { SC_INTERNAL(scp, nserp); } else { exec_server(nserp); } }