Index: cpukit/telnetd/telnetd.c
===================================================================
--- cpukit/telnetd/telnetd.c	(revision 1c567c56c0597d99a16da826f4020b69254b893c)
+++ cpukit/telnetd/telnetd.c	(revision bf4c7ff6ab8df166c42007501eb690ec738ef0f5)
@@ -73,4 +73,5 @@
 struct telnetd_context {
   rtems_telnetd_config_table config;
+  int                        server_socket;
   uint16_t                   active_clients;
 };
@@ -81,19 +82,12 @@
 } uni_sa;
 
-static int sockpeername(int sock, char *buf, int bufsz);
-
 /***********************************************************/
 static telnetd_context telnetd_instance;
 
-static telnetd_session *grab_a_Connection(
-  telnetd_context *ctx,
-  int des_socket,
-  uni_sa *srv,
-  char *peername,
-  int sz
-)
+static telnetd_session *grab_a_Connection(telnetd_context *ctx)
 {
   telnetd_session *session;
-  socklen_t size_adr = sizeof(srv->sin);
+  uni_sa peer;
+  socklen_t address_len;
   int acp_sock;
 
@@ -108,5 +102,6 @@
   }
 
-  acp_sock = accept(des_socket,&srv->sa,&size_adr);
+  address_len = sizeof(peer.sin);
+  acp_sock = accept(ctx->server_socket, &peer.sa, &address_len);
   if (acp_sock<0) {
     perror("telnetd:accept");
@@ -122,11 +117,19 @@
   }
 
-  if (sockpeername(acp_sock, peername, sz))
-    strncpy(peername, "<UNKNOWN>", sz);
+  if (
+    inet_ntop(
+      AF_INET,
+      &peer.sin.sin_addr,
+      session->peername,
+      sizeof(session->peername)
+    ) == NULL
+  ) {
+    strlcpy(session->peername, "<UNKNOWN>", sizeof(session->peername));
+  }
 
 #ifdef PARANOIA
   syslog(LOG_DAEMON | LOG_INFO,
       "telnetd: accepted connection from %s on %s",
-      peername,
+      session->peername,
       session->pty.name);
 #endif
@@ -138,13 +141,18 @@
 
 
-static void release_a_Connection(telnetd_context *ctx, const char *devname,
-  const char *peername, FILE **pstd, int n)
-{
-
+static void release_a_Connection(
+  telnetd_context *ctx,
+  telnetd_session *session,
+  FILE **pstd,
+  int n
+)
+{
 #ifdef PARANOIA
-  syslog( LOG_DAEMON | LOG_INFO,
-      "telnetd: releasing connection from %s on %s",
-      peername,
-      devname );
+  syslog(
+    LOG_DAEMON | LOG_INFO,
+    "telnetd: releasing connection from %s on %s",
+    session->peername,
+    session->pty.name
+  );
 #endif
 
@@ -154,20 +162,5 @@
     if (pstd[n]) fclose(pstd[n]);
 
-  unlink(devname);
-}
-
-static int sockpeername(int sock, char *buf, int bufsz)
-{
-  uni_sa peer;
-  int    rval = sock < 0;
-  socklen_t len  = sizeof(peer.sin);
-
-  if ( !rval )
-    rval = getpeername(sock, &peer.sa, &len);
-
-  if ( !rval )
-    rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
-
-  return rval;
+  unlink(session->pty.name);
 }
 
@@ -206,33 +199,7 @@
 telnetd_server_task(rtems_task_argument arg)
 {
-  int                des_socket;
-  uni_sa             srv;
-  char               peername[16];
-  int                i=1;
-  int                size_adr;
   telnetd_session   *session = NULL;
   rtems_id           task_id;
   telnetd_context   *ctx = (telnetd_context *) arg;
-
-  if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
-    perror("telnetd:socket");
-    rtems_task_exit();
-  };
-  (void)setsockopt(des_socket,SOL_SOCKET,SO_KEEPALIVE,&i,sizeof(i));
-
-  memset(&srv,0,sizeof(srv));
-  srv.sin.sin_family=AF_INET;
-  srv.sin.sin_port=htons(23);
-  size_adr=sizeof(srv.sin);
-  if ((bind(des_socket,&srv.sa,size_adr))<0) {
-    perror("telnetd:bind");
-    close(des_socket);
-    rtems_task_exit();
-  };
-  if ((listen(des_socket,5))<0) {
-    perror("telnetd:listen");
-          close(des_socket);
-    rtems_task_exit();
-  };
 
   /* we don't redirect stdio as this probably
@@ -240,6 +207,5 @@
    */
   do {
-    session = grab_a_Connection(ctx, des_socket, &srv, peername,
-      sizeof(peername));
+    session = grab_a_Connection(ctx);
 
     if (session == NULL) {
@@ -248,6 +214,4 @@
       continue;
     }
-
-    strncpy(session->peername, peername, sizeof(session->peername));
 
     task_id = telnetd_spawn_task(
@@ -270,17 +234,55 @@
       if ( !(dummy=fopen(session->pty.name,"r+")) )
         perror("Unable to dummy open the pty, losing a slot :-(");
-      release_a_Connection(ctx, session->pty.name, peername, &dummy, 1);
+      release_a_Connection(ctx, session, &dummy, 1);
       free(session);
       sleep(2); /* don't accept connections too fast */
     }
   } while(1);
-
-  /* TODO: how to free the connection semaphore? But then -
-   *       stopping the daemon is probably only needed during
-   *       development/debugging.
-   *       Finalizer code should collect all the connection semaphore
-   *       counts and eventually clean up...
-   */
-  close(des_socket);
+}
+
+static void telnetd_destroy_context(telnetd_context *ctx)
+{
+  if (ctx->server_socket >= 0) {
+    close(ctx->server_socket);
+  }
+}
+
+static rtems_status_code telnetd_create_server_socket(telnetd_context *ctx)
+{
+  uni_sa srv;
+  socklen_t address_len;
+  int enable;
+
+  ctx->server_socket = socket(PF_INET, SOCK_STREAM, 0);
+  if (ctx->server_socket < 0) {
+    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot create server socket");
+    return RTEMS_UNSATISFIED;
+  }
+
+  enable = 1;
+  (void)setsockopt(
+    ctx->server_socket,
+    SOL_SOCKET,
+    SO_KEEPALIVE,
+    &enable,
+    sizeof(enable)
+  );
+
+  memset(&srv, 0, sizeof(srv));
+  srv.sin.sin_family = AF_INET;
+  srv.sin.sin_port = htons(23);
+  address_len = sizeof(srv.sin);
+
+  if (bind(ctx->server_socket, &srv.sa, address_len) != 0) {
+    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot bind server socket");
+    return RTEMS_RESOURCE_IN_USE;
+  };
+
+  if (listen(ctx->server_socket, ctx->config.client_maximum) != 0) {
+    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot listen on server socket");
+    return RTEMS_UNSATISFIED;
+  };
+
+  return RTEMS_SUCCESSFUL;
 }
 
@@ -289,4 +291,5 @@
   telnetd_context *ctx = &telnetd_instance;
   rtems_id task_id;
+  rtems_status_code sc;
 
   if (config->command == NULL) {
@@ -319,4 +322,10 @@
   if (ctx->config.client_maximum == 0) {
     ctx->config.client_maximum = 5;
+  }
+
+  sc = telnetd_create_server_socket(ctx);
+  if (sc != RTEMS_SUCCESSFUL) {
+    telnetd_destroy_context(ctx);
+    return sc;
   }
 
@@ -331,4 +340,5 @@
     ctx->config.command = NULL;
     syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot create server task");
+    telnetd_destroy_context(ctx);
     return RTEMS_UNSATISFIED;
   }
@@ -405,5 +415,5 @@
 
 cleanup:
-  release_a_Connection(ctx, session->pty.name, session->peername, nstd, i);
+  release_a_Connection(ctx, session, nstd, i);
   free(session);
 }
