Changeset 8ad6681b in rtems


Ignore:
Timestamp:
Sep 25, 2007, 5:14:01 PM (12 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.9, master
Children:
a10128c
Parents:
96eadec4
Message:

2007-09-25 Joel Sherrill <joel.sherrill@…>

  • telnetd/README, telnetd/pty.c, telnetd/pty.h, telnetd/telnetd.c, telnetd/telnetd.h: telnetd rewrite.
  • telnetd/check_passwd.c, telnetd/des.c, telnetd/genpw.c: New files.
Location:
cpukit
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r96eadec4 r8ad6681b  
     12007-09-25      Joel Sherrill <joel.sherrill@oarcorp.com>
     2
     3        * telnetd/README, telnetd/pty.c, telnetd/pty.h, telnetd/telnetd.c,
     4        telnetd/telnetd.h: telnetd rewrite.
     5        * telnetd/check_passwd.c, telnetd/des.c, telnetd/genpw.c: New files.
     6
    172007-09-24      Joel Sherrill <joel.sherrill@oarcorp.com>
    28
  • cpukit/telnetd/README

    r96eadec4 r8ad6681b  
    22222.  If you have tcp/ip initialied you can start telnetd daemon.
    2323    You need register pseudo-terminals driver into device drivers table.
    24     16 ptyX termios device terminales are created into /dev/.
    25     Calling rtems_initialize_telnetd() starts the daemon.
    26     Enjoy it.
     24
     25Enjoy it.
    2726
    2827FUTURE:
  • cpukit/telnetd/pty.c

    r96eadec4 r8ad6681b  
    145145
    146146char *  telnet_get_pty(int socket) {
    147         int ndx;
    148         if (telnet_pty_inited) {
    149                 for (ndx=0;ndx<MAX_PTYS;ndx++) {
    150                         if (telnet_ptys[ndx].socket<0) {
    151                                 struct timeval t;
    152                                 /* set a long polling interval to save CPU time */
    153                                 t.tv_sec=2;
    154                                 t.tv_usec=00000;
    155                                 setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
    156                                 telnet_ptys[ndx].socket=socket;
    157                                 return telnet_ptys[ndx].devname;
    158                         };
    159                 };
    160         }
    161         close(socket);
    162         return NULL;
     147  int ndx;
     148  if (telnet_pty_inited) {
     149    for (ndx=0;ndx<MAX_PTYS;ndx++) {
     150      if (telnet_ptys[ndx].socket<0) {
     151        struct timeval t;
     152        /* set a long polling interval to save CPU time */
     153        t.tv_sec=2;
     154        t.tv_usec=00000;
     155        setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
     156        telnet_ptys[ndx].socket=socket;
     157        return telnet_ptys[ndx].devname;
     158      };
     159    };
     160  }
     161  close(socket);
     162  return NULL;
    163163}
    164164
     
    178178static
    179179int send_iac(int minor,unsigned char mode,unsigned char option) {
    180         unsigned char buf[3];
    181         buf[0]=IAC_ESC;
    182         buf[1]=mode;
    183         buf[2]=option;
    184         return write(telnet_ptys[minor].socket,buf,sizeof(buf));
     180  unsigned char buf[3];
     181  buf[0]=IAC_ESC;
     182  buf[1]=mode;
     183  buf[2]=option;
     184  return write(telnet_ptys[minor].socket,buf,sizeof(buf));
    185185}
    186186
     
    188188handleSB(pty_t *pty)
    189189{
    190         switch (pty->sb_buf[0]) {
    191                 case 31:        /* NAWS */
    192                         pty->width  = (pty->sb_buf[1]<<8) + pty->sb_buf[2];
    193                         pty->height = (pty->sb_buf[3]<<8) + pty->sb_buf[4];
     190  switch (pty->sb_buf[0]) {
     191    case 31:    /* NAWS */
     192      pty->width  = (pty->sb_buf[1]<<8) + pty->sb_buf[2];
     193      pty->height = (pty->sb_buf[3]<<8) + pty->sb_buf[4];
    194194#if DEBUG & DEBUG_WH
    195                         fprintf(stderr,
    196                                         "Setting width/height to %ix%i\n",
    197                                         pty->width,
    198                                         pty->height);
    199 #endif
    200                         break;
    201                 default:
    202                         break;
    203         }
    204         return 0;
     195      fprintf(stderr,
     196          "Setting width/height to %ix%i\n",
     197          pty->width,
     198          pty->height);
     199#endif
     200      break;
     201    default:
     202      break;
     203  }
     204  return 0;
    205205}
    206206
    207207static int read_pty(int minor) { /* Characters written to the client side*/
    208         unsigned char  value;
    209         unsigned int   omod;
    210         int                    count;
    211         int                    result;
    212         pty_t                  *pty=telnet_ptys+minor;
    213 
    214         count=read(pty->socket,&value,sizeof(value));
    215         if (count<0)
    216                 return -1;
    217 
    218         if (count<1) {
    219                         /* Unfortunately, there is no way of passing an EOF
    220                         * condition through the termios driver. Hence, we
    221                         * resort to an ugly hack. Setting cindex>ccount
    222                         * causes the termios driver to return a read count
    223                         * of '0' which is what we want here. We leave
    224                         * 'errno' untouched.
    225                         */
    226                         pty->ttyp->cindex=pty->ttyp->ccount+1;
    227                         return pty->ttyp->termios.c_cc[VEOF];
    228         };
    229 
    230         omod=pty->iac_mode;
    231         pty->iac_mode=0;
    232         switch(omod & 0xff) {
    233                         case IAC_ESC:
    234                                         switch(value) {
    235                                                         case IAC_ESC :
    236                                                                         /* in case this is an ESC ESC sequence in SB mode */
    237                                                                         pty->iac_mode = omod>>8;
    238                                                                         return IAC_ESC;
    239                                                         case IAC_DONT:
    240                                                         case IAC_DO  :
    241                                                         case IAC_WONT:
    242                                                         case IAC_WILL:
    243                                                                         pty->iac_mode=value;
    244                                                                         return -1;
    245                                                         case IAC_SB  :
     208  unsigned char        value;
     209  unsigned int omod;
     210  int                  count;
     211  int                  result;
     212  pty_t                        *pty=telnet_ptys+minor;
     213
     214  count=read(pty->socket,&value,sizeof(value));
     215  if (count<0)
     216    return -1;
     217
     218  if (count<1) {
     219      /* Unfortunately, there is no way of passing an EOF
     220      * condition through the termios driver. Hence, we
     221      * resort to an ugly hack. Setting cindex>ccount
     222      * causes the termios driver to return a read count
     223      * of '0' which is what we want here. We leave
     224      * 'errno' untouched.
     225      */
     226      pty->ttyp->cindex=pty->ttyp->ccount+1;
     227      return pty->ttyp->termios.c_cc[VEOF];
     228  };
     229
     230  omod=pty->iac_mode;
     231  pty->iac_mode=0;
     232  switch(omod & 0xff) {
     233      case IAC_ESC:
     234          switch(value) {
     235              case IAC_ESC :
     236                  /* in case this is an ESC ESC sequence in SB mode */
     237                  pty->iac_mode = omod>>8;
     238                  return IAC_ESC;
     239              case IAC_DONT:
     240              case IAC_DO  :
     241              case IAC_WONT:
     242              case IAC_WILL:
     243                  pty->iac_mode=value;
     244                  return -1;
     245              case IAC_SB  :
    246246#if DEBUG & DEBUG_DETAIL
    247                                                                         printk("SB\n");
    248 #endif
    249                                                                         pty->iac_mode=value;
    250                                                                         pty->sb_ind=0;
    251                                                                         return -100;
    252                                                         case IAC_GA  :
    253                                                                         return -1;
    254                                                         case IAC_EL  :
    255                                                                         return 0x03; /* Ctrl-C*/
    256                                                         case IAC_EC  :
    257                                                                         return '\b';
    258                                                         case IAC_AYT :
    259                                                                         write(pty->socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));
    260                                                                         return -1;
    261                                                         case IAC_AO  :
    262                                                                         return -1;
    263                                                         case IAC_IP  :
    264                                                                         write(pty->socket,IAC_IP_RSP,strlen(IAC_IP_RSP));
    265                                                                         return -1;
    266                                                         case IAC_BRK :
    267                                                                         write(pty->socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));
    268                                                                         return -1;
    269                                                         case IAC_DMARK:
    270                                                                         return -2;
    271                                                         case IAC_NOP :
    272                                                                         return -1;
    273                                                         case IAC_SE  :
     247                  printk("SB\n");
     248#endif
     249                  pty->iac_mode=value;
     250                  pty->sb_ind=0;
     251                  return -100;
     252              case IAC_GA  :
     253                  return -1;
     254              case IAC_EL  :
     255                  return 0x03; /* Ctrl-C*/
     256              case IAC_EC  :
     257                  return '\b';
     258              case IAC_AYT :
     259                  write(pty->socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));
     260                  return -1;
     261              case IAC_AO  :
     262                  return -1;
     263              case IAC_IP  :
     264                  write(pty->socket,IAC_IP_RSP,strlen(IAC_IP_RSP));
     265                  return -1;
     266              case IAC_BRK :
     267                  write(pty->socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));
     268                  return -1;
     269              case IAC_DMARK:
     270                  return -2;
     271              case IAC_NOP :
     272                  return -1;
     273              case IAC_SE  :
    274274#if DEBUG & DEBUG_DETAIL
    275                                                                         {
    276                                                                         int i;
    277                                                                         printk("SE");
    278                                                                         for (i=0; i<pty->sb_ind; i++)
    279                                                                                 printk(" %02x",pty->sb_buf[i]);
    280                                                                         printk("\n");
    281                                                                         }
    282 #endif
    283                                                                         handleSB(pty);
    284                                                         return -101;
    285                                                         case IAC_EOR :
    286                                                                         return -102;
    287                                                         default      :
    288                                                                         return -1;
    289                                         };
    290                                         break;
    291 
    292                         case IAC_SB:
    293                                         pty->iac_mode=omod;
    294                                         if (IAC_ESC==value) {
    295                                                 pty->iac_mode=(omod<<8)|value;
    296                                         } else {
    297                                                 if (pty->sb_ind < SB_MAX)
    298                                                         pty->sb_buf[pty->sb_ind++]=value;
    299                                         }
    300                                         return -1;
    301 
    302                         case IAC_WILL:
    303                                         if (value==34){
    304                                                         send_iac(minor,IAC_DONT,   34); /*LINEMODE*/
    305                                                         send_iac(minor,IAC_DO  ,    1); /*ECHO    */
    306                                         } else if (value==31) {
    307                                                         send_iac(minor,IAC_DO  ,   31); /*NAWS    */
     275                  {
     276                  int i;
     277                  printk("SE");
     278                  for (i=0; i<pty->sb_ind; i++)
     279                    printk(" %02x",pty->sb_buf[i]);
     280                  printk("\n");
     281                  }
     282#endif
     283                  handleSB(pty);
     284              return -101;
     285              case IAC_EOR :
     286                  return -102;
     287              default      :
     288                  return -1;
     289          };
     290          break;
     291
     292      case IAC_SB:
     293          pty->iac_mode=omod;
     294          if (IAC_ESC==value) {
     295            pty->iac_mode=(omod<<8)|value;
     296          } else {
     297            if (pty->sb_ind < SB_MAX)
     298              pty->sb_buf[pty->sb_ind++]=value;
     299          }
     300          return -1;
     301
     302      case IAC_WILL:
     303          if (value==34){
     304              send_iac(minor,IAC_DONT,   34);   /*LINEMODE*/
     305              send_iac(minor,IAC_DO  ,    1);   /*ECHO    */
     306          } else if (value==31) {
     307              send_iac(minor,IAC_DO  ,   31);   /*NAWS    */
    308308#if DEBUG & DEBUG_DETAIL
    309                                                         printk("replied DO NAWS\n");
    310 #endif
    311                                         } else {
    312                                                         send_iac(minor,IAC_DONT,value);
    313                                         }
    314                                         return -1;
    315                         case IAC_DONT:
    316                                         return -1;
    317                         case IAC_DO  :
    318                                         if (value==3) {
    319                                                         send_iac(minor,IAC_WILL,    3); /* GO AHEAD*/
    320                                         } else if (value==1) {                         
    321                                                         /* ECHO */
    322                                         } else {
    323                                                         send_iac(minor,IAC_WONT,value);
    324                                         };
    325                                         return -1;
    326                         case IAC_WONT:
    327                                         if (value==1) {send_iac(minor,IAC_WILL,    1);} else /* ECHO */
    328                                         {send_iac(minor,IAC_WONT,value);};
    329                                         return -1;
    330                         default:
    331                                         if (value==IAC_ESC) {
    332                                                         pty->iac_mode=value;
    333                                                         return -1;
    334                                         } else {
    335                                                         result=value; 
    336                                                         if ( 0
     309              printk("replied DO NAWS\n");
     310#endif
     311          } else {
     312              send_iac(minor,IAC_DONT,value);
     313          }
     314          return -1;
     315      case IAC_DONT:
     316          return -1;
     317      case IAC_DO  :
     318          if (value==3) {
     319              send_iac(minor,IAC_WILL,    3);   /* GO AHEAD*/
     320          } else       if (value==1) {                         
     321              /* ECHO */
     322          } else {
     323              send_iac(minor,IAC_WONT,value);
     324          };
     325          return -1;
     326      case IAC_WONT:
     327          if (value==1) {send_iac(minor,IAC_WILL,    1);} else /* ECHO */
     328          {send_iac(minor,IAC_WONT,value);};
     329          return -1;
     330      default:
     331          if (value==IAC_ESC) {
     332              pty->iac_mode=value;
     333              return -1;
     334          } else {
     335              result=value; 
     336              if ( 0
    337337#if 0                                                    /* pass CRLF through - they should use termios to handle it */
    338                                                                 ||     ((value=='\n') && (pty->last_cr))
    339 #endif
    340                                                                 /* but map telnet CRNUL to CR down here */
    341                                                                 || ((value==0) && pty->last_cr)
    342                                                                 ) result=-1;
    343                                                         pty->last_cr=(value=='\r');
    344                                                         return result;
    345                                         };
    346         };
    347         /* should never get here but keep compiler happy */
    348         return -1;
     338                ||     ((value=='\n') && (pty->last_cr))
     339#endif
     340                /* but map telnet CRNUL to CR down here */
     341                || ((value==0) && pty->last_cr)
     342                ) result=-1;
     343              pty->last_cr=(value=='\r');
     344              return result;
     345          };
     346  };
     347  /* should never get here but keep compiler happy */
     348  return -1;
    349349}
    350350
     
    361361static int
    362362ptySetAttributes(int minor,const struct termios *t) {
    363         if (minor<MAX_PTYS) {   
    364         telnet_ptys[minor].c_cflag=t->c_cflag;
    365         } else {
    366         return -1;
    367         };
    368         return 0;
     363  if (minor<MAX_PTYS) {
     364  telnet_ptys[minor].c_cflag=t->c_cflag;       
     365  } else {
     366  return -1;
     367  };
     368  return 0;
    369369}
    370370/*-----------------------------------------------------------*/
    371371static int
    372372ptyPollInitialize(int major,int minor,void * arg) {
    373         rtems_libio_open_close_args_t * args = (rtems_libio_open_close_args_t*)arg;
    374         struct termios t;
     373  rtems_libio_open_close_args_t * args = (rtems_libio_open_close_args_t*)arg;
     374  struct termios t;
    375375        if (minor<MAX_PTYS) {   
    376376         if (telnet_ptys[minor].socket<0) return -1;           
    377         telnet_ptys[minor].opened=TRUE;
    378         telnet_ptys[minor].ttyp= (struct rtems_termios_tty *) args->iop->data1;
    379         telnet_ptys[minor].iac_mode=0;
    380         telnet_ptys[minor].sb_ind=0;
    381         telnet_ptys[minor].width=0;
    382         telnet_ptys[minor].height=0;
    383         t.c_cflag=B9600|CS8;/* termios default */
    384         return ptySetAttributes(minor,&t);
    385         } else {
    386         return -1;
    387         };
     377  telnet_ptys[minor].opened=TRUE;
     378  telnet_ptys[minor].ttyp= (struct rtems_termios_tty *) args->iop->data1;
     379  telnet_ptys[minor].iac_mode=0;
     380  telnet_ptys[minor].sb_ind=0;
     381  telnet_ptys[minor].width=0;
     382  telnet_ptys[minor].height=0;
     383  t.c_cflag=B9600|CS8;/* termios default */
     384  return ptySetAttributes(minor,&t);
     385  } else {
     386  return -1;
     387  };
    388388}
    389389/*-----------------------------------------------------------*/
     
    391391ptyShutdown(int major,int minor,void * arg) {
    392392        if (minor<MAX_PTYS) {   
    393         telnet_ptys[minor].opened=FALSE;
     393  telnet_ptys[minor].opened=FALSE;
    394394         if (telnet_ptys[minor].socket>=0) close(telnet_ptys[minor].socket);
    395         telnet_ptys[minor].socket=-1;
    396         chown(telnet_ptys[minor].devname,2,0);
    397         } else {
    398         return -1;
    399         };
    400         return 0;
     395  telnet_ptys[minor].socket=-1;
     396  chown(telnet_ptys[minor].devname,2,0);
     397  } else {
     398  return -1;
     399  };
     400  return 0;
    401401}
    402402/*-----------------------------------------------------------*/
     
    405405static int
    406406ptyPollWrite(int minor, const char * buf,int len) {
    407         int count;
     407  int count;
    408408        if (minor<MAX_PTYS) {   
    409409         if (telnet_ptys[minor].socket<0) return -1;           
    410         count=write(telnet_ptys[minor].socket,buf,len);
    411         } else {
    412         count=-1;
    413         };
    414         return count;
     410  count=write(telnet_ptys[minor].socket,buf,len);
     411  } else {
     412  count=-1;
     413  };
     414  return count;
    415415}
    416416/*-----------------------------------------------------------*/
    417417static int
    418418ptyPollRead(int minor) {
    419         int result;
     419  int result;
    420420        if (minor<MAX_PTYS) {   
    421421         if (telnet_ptys[minor].socket<0) return -1;           
    422         result=read_pty(minor);
    423         return result;
    424         };
    425         return -1;
     422  result=read_pty(minor);
     423  return result;
     424  };
     425  return -1;
    426426}
    427427/*-----------------------------------------------------------*/
     
    447447rtems_status_code status ;
    448448
    449         /*
    450         * Set up ptys
    451         */
    452 
    453         for (ndx=0;ndx<MAX_PTYS;ndx++) {
    454                 telnet_ptys[ndx].devname=(char*)malloc(strlen("/dev/ptyXX")+1);
    455                 sprintf(telnet_ptys[ndx].devname,"/dev/pty%X",ndx);
    456                 telnet_ptys[ndx].ttyp=NULL;
    457                 telnet_ptys[ndx].c_cflag=CS8|B9600;
    458                 telnet_ptys[ndx].socket=-1;
    459                 telnet_ptys[ndx].opened=FALSE;
    460                 telnet_ptys[ndx].sb_ind=0;
    461                 telnet_ptys[ndx].width=0;
    462                 telnet_ptys[ndx].height=0;
    463 
    464         };
    465 
    466         /*
    467         * Register the devices
    468         */
    469         for (ndx=0;ndx<MAX_PTYS;ndx++) {
    470                 status = rtems_io_register_name(telnet_ptys[ndx].devname, major, ndx);
    471                 if (status != RTEMS_SUCCESSFUL)
    472                                 rtems_fatal_error_occurred(status);
    473                 chmod(telnet_ptys[ndx].devname,0660);
    474                 chown(telnet_ptys[ndx].devname,2,0); /* tty,root*/
    475         };
    476         printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",0,MAX_PTYS-1,MAX_PTYS);
    477 
    478         return RTEMS_SUCCESSFUL;
     449  /*
     450  * Set up ptys
     451  */
     452
     453  for (ndx=0;ndx<MAX_PTYS;ndx++) {
     454    telnet_ptys[ndx].devname=(char*)malloc(strlen("/dev/ptyXX")+1);
     455    sprintf(telnet_ptys[ndx].devname,"/dev/pty%X",ndx);
     456    telnet_ptys[ndx].ttyp=NULL;
     457    telnet_ptys[ndx].c_cflag=CS8|B9600;
     458    telnet_ptys[ndx].socket=-1;
     459    telnet_ptys[ndx].opened=FALSE;
     460    telnet_ptys[ndx].sb_ind=0;
     461    telnet_ptys[ndx].width=0;
     462    telnet_ptys[ndx].height=0;
     463
     464  };
     465
     466  /*
     467  * Register the devices
     468  */
     469  for (ndx=0;ndx<MAX_PTYS;ndx++) {
     470    status = rtems_io_register_name(telnet_ptys[ndx].devname, major, ndx);
     471    if (status != RTEMS_SUCCESSFUL)
     472        rtems_fatal_error_occurred(status);
     473    chmod(telnet_ptys[ndx].devname,0660);
     474    chown(telnet_ptys[ndx].devname,2,0); /* tty,root*/
     475  };
     476  printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",0,MAX_PTYS-1,MAX_PTYS);
     477
     478  return RTEMS_SUCCESSFUL;
    479479}
    480480
     
    484484rtems_status_code status;
    485485
    486                 if ( !telnet_pty_inited )
    487                         return 0;
    488 
    489                 for (ndx=0;ndx<MAX_PTYS;ndx++) {
    490                         if (telnet_ptys[ndx].opened) {
    491                                         fprintf(stderr,"There are still opened PTY devices, unable to proceed\n");
    492                                         return -1;
    493                         }
    494                 }
    495                 if (RTEMS_SUCCESSFUL != rtems_io_unregister_driver(pty_major)) {
    496                                 fprintf(stderr,"Unable to remove this driver\n");
    497                                 return -1;
    498                 }
    499                 for (ndx=0;ndx<MAX_PTYS;ndx++) {
    500                                 /* rtems_io_register_name() actually creates a node in the filesystem
    501                                 * (mknod())
    502                                 */
    503                                 status = (rtems_status_code)unlink(telnet_ptys[ndx].devname);
    504                                 if (status != RTEMS_SUCCESSFUL)
    505                                         perror("removing pty device node from file system");
    506                                 else
    507                                         free(telnet_ptys[ndx].devname);
    508                 };
    509                 fprintf(stderr,"PTY driver unloaded successfully\n");
    510                 telnet_pty_inited=FALSE;
    511                 return 0;
     486    if ( !telnet_pty_inited )
     487      return 0;
     488
     489    for (ndx=0;ndx<MAX_PTYS;ndx++) {
     490      if (telnet_ptys[ndx].opened) {
     491          fprintf(stderr,"There are still opened PTY devices, unable to proceed\n");
     492          return -1;
     493      }
     494    }
     495    if (RTEMS_SUCCESSFUL != rtems_io_unregister_driver(pty_major)) {
     496        fprintf(stderr,"Unable to remove this driver\n");
     497        return -1;
     498    }
     499    for (ndx=0;ndx<MAX_PTYS;ndx++) {
     500        /* rtems_io_register_name() actually creates a node in the filesystem
     501        * (mknod())
     502        */
     503        status = (rtems_status_code)unlink(telnet_ptys[ndx].devname);
     504        if (status != RTEMS_SUCCESSFUL)
     505          perror("removing pty device node from file system");
     506        else
     507          free(telnet_ptys[ndx].devname);
     508    };
     509    fprintf(stderr,"PTY driver unloaded successfully\n");
     510    telnet_pty_inited=FALSE;
     511    return 0;
    512512}
    513513
     
    585585pty_t                                    *p=&telnet_ptys[minor];
    586586
    587         switch (args->command) {
    588 
    589                 case TIOCGWINSZ:
    590 
    591                         wp->ws_row = p->height;
    592                         wp->ws_col = p->width;
    593                         args->ioctl_return=0;
     587  switch (args->command) {
     588
     589    case TIOCGWINSZ:
     590
     591      wp->ws_row = p->height;
     592      wp->ws_col = p->width;
     593      args->ioctl_return=0;
    594594#if DEBUG & DEBUG_WH
    595                         fprintf(stderr,
    596                                         "ioctl(TIOCGWINSZ), returning %ix%i\n",
    597                                         wp->ws_col,
    598                                         wp->ws_row);
    599 #endif
    600 
    601                         return RTEMS_SUCCESSFUL;
    602 
    603                 case TIOCSWINSZ:
     595      fprintf(stderr,
     596          "ioctl(TIOCGWINSZ), returning %ix%i\n",
     597          wp->ws_col,
     598          wp->ws_row);
     599#endif
     600
     601      return RTEMS_SUCCESSFUL;
     602
     603    case TIOCSWINSZ:
    604604#if DEBUG & DEBUG_WH
    605                         fprintf(stderr,
    606                                         "ioctl(TIOCGWINSZ), setting %ix%i\n",
    607                                         wp->ws_col,
    608                                         wp->ws_row);
    609 #endif
    610 
    611                         p->height = wp->ws_row;
    612                         p->width  = wp->ws_col;
    613                         args->ioctl_return=0;
    614 
    615                         return RTEMS_SUCCESSFUL;
    616 
    617                 default:
    618 
    619                 break;
     605      fprintf(stderr,
     606          "ioctl(TIOCGWINSZ), setting %ix%i\n",
     607          wp->ws_col,
     608          wp->ws_row);
     609#endif
     610
     611      p->height = wp->ws_row;
     612      p->width  = wp->ws_col;
     613      args->ioctl_return=0;
     614
     615      return RTEMS_SUCCESSFUL;
     616
     617    default:
     618
     619        break;
    620620  }
    621621
     
    624624
    625625static rtems_driver_address_table drvPty = {
    626                 my_pty_initialize,
    627                 my_pty_open,
    628                 my_pty_close,
    629                 my_pty_read,
    630                 my_pty_write,
    631                 my_pty_control
     626    my_pty_initialize,
     627    my_pty_open,
     628    my_pty_close,
     629    my_pty_read,
     630    my_pty_write,
     631    my_pty_control
    632632};
    633633
    634634/*-----------------------------------------------------------*/
    635635static const rtems_termios_callbacks pty_poll_callbacks = {
    636         ptyPollInitialize,      /* FirstOpen*/
    637         ptyShutdown,            /* LastClose*/
    638         ptyPollRead,            /* PollRead  */
    639         ptyPollWrite,           /* Write */
    640         ptySetAttributes,       /* setAttributes */
    641         NULL,                   /* stopRemoteTX */
    642         NULL,                   /* StartRemoteTX */
    643         0                       /* outputUsesInterrupts */
     636  ptyPollInitialize,    /* FirstOpen*/
     637  ptyShutdown,          /* LastClose*/
     638  ptyPollRead,          /* PollRead  */
     639  ptyPollWrite,         /* Write */
     640  ptySetAttributes,     /* setAttributes */
     641  NULL,                 /* stopRemoteTX */
     642  NULL,                 /* StartRemoteTX */
     643  0                     /* outputUsesInterrupts */
    644644};
    645645/*-----------------------------------------------------------*/
    646646static const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {
    647         return &pty_poll_callbacks;
     647  return &pty_poll_callbacks;
    648648}
    649649/*-----------------------------------------------------------*/
     
    651651static int pty_do_initialize()
    652652{
    653         if ( !telnet_pty_inited ) {
    654                 if (RTEMS_SUCCESSFUL==rtems_io_register_driver(0, &drvPty, &pty_major))
    655                         telnet_pty_inited=TRUE;
    656                 else
    657                         fprintf(stderr,"WARNING: registering the PTY driver FAILED\n");
    658         }
    659         return telnet_pty_inited;
     653  if ( !telnet_pty_inited ) {
     654    if (RTEMS_SUCCESSFUL==rtems_io_register_driver(0, &drvPty, &pty_major))
     655      telnet_pty_inited=TRUE;
     656    else
     657      fprintf(stderr,"WARNING: registering the PTY driver FAILED\n");
     658  }
     659  return telnet_pty_inited;
    660660}
    661661
     
    664664class TelnetPtyIni {
    665665public:
    666         TelnetPtyIni() { if (!nest++) {
    667                                                 pty_do_initialize();
    668                                 }
    669                         };
    670         ~TelnetPtyIni(){ if (!--nest) {
    671                                                 pty_do_finalize();
    672                                 }
    673                         };
     666  TelnetPtyIni() { if (!nest++) {
     667            pty_do_initialize();
     668        }
     669      };
     670  ~TelnetPtyIni(){ if (!--nest) {
     671            pty_do_finalize();
     672        }
     673      };
    674674private:
    675675static int nest;
     
    681681int telnet_pty_initialize()
    682682{
    683         return telnet_pty_inited;
     683  return telnet_pty_inited;
    684684}
    685685
    686686int telnet_pty_finalize()
    687687{
    688         return telnet_pty_inited;
     688  return telnet_pty_inited;
    689689}
    690690};
     
    692692int telnet_pty_initialize()
    693693{
    694         return pty_do_initialize();
     694  return pty_do_initialize();
    695695}
    696696
    697697int telnet_pty_finalize()
    698698{
    699         return pty_do_finalize();
    700 }
    701 #endif
     699  return pty_do_finalize();
     700}
     701#endif
  • cpukit/telnetd/pty.h

    r96eadec4 r8ad6681b  
    6262#define PTY_DRIVER_TABLE_ENTRY \
    6363       { pty_initialize , pty_open , pty_close , \
    64         pty_read , pty_write , pty_control }
     64  pty_read , pty_write , pty_control }
    6565
    6666#ifdef __cplusplus
  • cpukit/telnetd/telnetd.c

    r96eadec4 r8ad6681b  
    7979
    8080struct shell_args {
    81         char    *devname;
    82         void    *arg;
    83         char    peername[16];
    84         char    delete_myself;
     81  char  *devname;
     82  void  *arg;
     83  char  peername[16];
     84  char  delete_myself;
    8585};
    8686
    8787typedef union uni_sa {
    88         struct sockaddr_in      sin;
    89         struct sockaddr     sa;
     88  struct sockaddr_in    sin;
     89  struct sockaddr     sa;
    9090} uni_sa;
    9191
     
    114114uint32_t
    115115#endif
    116                         size_adr = sizeof(srv->sin);
     116      size_adr = sizeof(srv->sin);
    117117int                     acp_sock;
    118118
    119         acp_sock = accept(des_socket,&srv->sa,&size_adr);
    120 
    121         if (acp_sock<0) {
    122                 perror("telnetd:accept");
    123                 goto bailout;
    124         };
    125 
    126         if ( !(rval=telnet_get_pty(acp_sock)) ) {
    127                 syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
    128                 /* NOTE: failing 'do_get_pty()' closed the socket */
    129                 goto bailout;
    130         }
    131 
    132         if (sockpeername(acp_sock, peername, sz))
    133                 strncpy(peername, "<UNKNOWN>", sz);
     119  acp_sock = accept(des_socket,&srv->sa,&size_adr);
     120
     121  if (acp_sock<0) {
     122    perror("telnetd:accept");
     123    goto bailout;
     124  };
     125
     126  if ( !(rval=telnet_get_pty(acp_sock)) ) {
     127    syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
     128    /* NOTE: failing 'do_get_pty()' closed the socket */
     129    goto bailout;
     130  }
     131
     132  if (sockpeername(acp_sock, peername, sz))
     133    strncpy(peername, "<UNKNOWN>", sz);
    134134
    135135#ifdef PARANOIA
    136         syslog(LOG_DAEMON | LOG_INFO,
    137                         "telnetd: accepted connection from %s on %s",
    138                         peername,
    139                         rval);
     136  syslog(LOG_DAEMON | LOG_INFO,
     137      "telnetd: accepted connection from %s on %s",
     138      peername,
     139      rval);
    140140#endif
    141141
    142142bailout:
    143143
    144         return rval;
     144  return rval;
    145145}
    146146
     
    150150
    151151#ifdef PARANOIA
    152         syslog( LOG_DAEMON | LOG_INFO,
    153                         "telnetd: releasing connection from %s on %s",
    154                         peername,
    155                         devname );
    156 #endif
    157 
    158         while (--n>=0)
    159                 if (pstd[n]) fclose(pstd[n]);
     152  syslog( LOG_DAEMON | LOG_INFO,
     153      "telnetd: releasing connection from %s on %s",
     154      peername,
     155      devname );
     156#endif
     157
     158  while (--n>=0)
     159    if (pstd[n]) fclose(pstd[n]);
    160160
    161161}
     
    170170uint32_t
    171171#endif
    172                 len  = sizeof(peer.sin);
     172    len  = sizeof(peer.sin);
    173173
    174174int             rval = sock < 0;
    175175
    176         if ( !rval)
    177                 rval = getpeername(sock, &peer.sa, &len);
    178 
    179         if ( !rval )
    180                 rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
    181 
    182         return rval;
     176  if ( !rval)
     177    rval = getpeername(sock, &peer.sa, &len);
     178
     179  if ( !rval )
     180    rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
     181
     182  return rval;
    183183}
    184184
     
    206206struct shell_args       *arg;
    207207
    208         if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
    209                 perror("telnetd:socket");
    210                 telnetd_task_id=0;
    211                 rtems_task_delete(RTEMS_SELF);
    212         };
    213         setsockopt(des_socket,SOL_SOCKET,SO_KEEPALIVE,&i,sizeof(i));
    214 
    215         memset(&srv,0,sizeof(srv));
    216         srv.sin.sin_family=AF_INET;
    217         srv.sin.sin_port=htons(23);
    218         size_adr=sizeof(srv.sin);
    219         if ((bind(des_socket,&srv.sa,size_adr))<0) {
    220                 perror("telnetd:bind");
    221                 close(des_socket);
    222                 telnetd_task_id=0;
    223                 rtems_task_delete(RTEMS_SELF);
    224         };
    225         if ((listen(des_socket,5))<0) {
    226                 perror("telnetd:listen");
    227                 close(des_socket);
    228                 telnetd_task_id=0;
    229                 rtems_task_delete(RTEMS_SELF);
    230         };
    231 
    232         /* we don't redirect stdio as this probably
    233         * was started from the console anyways..
    234         */
    235         do {
    236           devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
    237 
    238           if ( !devname ) {
    239                 /* if something went wrong, sleep for some time */
    240                 sleep(10);
    241                 continue;
    242           }
    243           if ( telnetd_dont_spawn ) {
    244                 if ( 0 == check_passwd(peername) )
    245                         telnetd_shell(devname, telnetd_shell_arg);
    246           } else {
    247                 arg = malloc( sizeof(*arg) );
    248 
    249                 arg->devname = devname;
    250                 arg->arg = telnetd_shell_arg;
    251                 strncpy(arg->peername, peername, sizeof(arg->peername));
    252 
    253                 if ( !telnetd_spawn_task(&devname[5], telnetd_task_priority, telnetd_stack_size, spawned_shell, arg) ) {
    254 
    255                         FILE *dummy;
    256 
    257                         if ( telnetd_spawn_task != telnetd_dflt_spawn ) {
    258                                 fprintf(stderr,"Telnetd: Unable to spawn child task\n");
    259                         }
    260 
    261                         /* hmm - the pty driver slot can only be
    262                         * released by opening and subsequently
    263                         * closing the PTY - this also closes
    264                         * the underlying socket. So we mock up
    265                         * a stream...
    266                         */
    267 
    268                         if ( !(dummy=fopen(devname,"r+")) )
    269                                 perror("Unable to dummy open the pty, losing a slot :-(");
    270                         release_a_Connection(devname, peername, &dummy, 1);
    271                         free(arg);
    272                         sleep(2); /* don't accept connections too fast */
     208  if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
     209    perror("telnetd:socket");
     210    telnetd_task_id=0;
     211    rtems_task_delete(RTEMS_SELF);
     212  };
     213  setsockopt(des_socket,SOL_SOCKET,SO_KEEPALIVE,&i,sizeof(i));
     214
     215  memset(&srv,0,sizeof(srv));
     216  srv.sin.sin_family=AF_INET;
     217  srv.sin.sin_port=htons(23);
     218  size_adr=sizeof(srv.sin);
     219  if ((bind(des_socket,&srv.sa,size_adr))<0) {
     220    perror("telnetd:bind");
     221          close(des_socket);
     222    telnetd_task_id=0;
     223    rtems_task_delete(RTEMS_SELF);
     224  };
     225  if ((listen(des_socket,5))<0) {
     226    perror("telnetd:listen");
     227          close(des_socket);
     228    telnetd_task_id=0;
     229    rtems_task_delete(RTEMS_SELF);
     230  };
     231
     232  /* we don't redirect stdio as this probably
     233  * was started from the console anyways..
     234  */
     235  do {
     236    devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
     237
     238    if ( !devname ) {
     239    /* if something went wrong, sleep for some time */
     240    sleep(10);
     241    continue;
     242    }
     243    if ( telnetd_dont_spawn ) {
     244    if ( 0 == check_passwd(peername) )
     245      telnetd_shell(devname, telnetd_shell_arg);
     246    } else {
     247    arg = malloc( sizeof(*arg) );
     248
     249    arg->devname = devname;
     250    arg->arg = telnetd_shell_arg;
     251    strncpy(arg->peername, peername, sizeof(arg->peername));
     252
     253    if ( !telnetd_spawn_task(&devname[5], telnetd_task_priority, telnetd_stack_size, spawned_shell, arg) ) {
     254
     255      FILE *dummy;
     256
     257      if ( telnetd_spawn_task != telnetd_dflt_spawn ) {
     258        fprintf(stderr,"Telnetd: Unable to spawn child task\n");
     259      }
     260
     261      /* hmm - the pty driver slot can only be
     262      * released by opening and subsequently
     263      * closing the PTY - this also closes
     264      * the underlying socket. So we mock up
     265      * a stream...
     266      */
     267
     268      if ( !(dummy=fopen(devname,"r+")) )
     269        perror("Unable to dummy open the pty, losing a slot :-(");
     270      release_a_Connection(devname, peername, &dummy, 1);
     271      free(arg);
     272      sleep(2); /* don't accept connections too fast */
    273273                }
    274           }
    275         } while(1);
    276         /* TODO: how to free the connection semaphore? But then -
    277         *       stopping the daemon is probably only needed during
    278         *       development/debugging.
    279         *       Finalizer code should collect all the connection semaphore
    280         *       counts and eventually clean up...
    281         */
    282         close(des_socket);
    283         telnetd_task_id=0;
     274    }
     275  } while(1);
     276  /* TODO: how to free the connection semaphore? But then -
     277  *       stopping the daemon is probably only needed during
     278  *       development/debugging.
     279  *       Finalizer code should collect all the connection semaphore
     280  *       counts and eventually clean up...
     281  */
     282  close(des_socket);
     283  telnetd_task_id=0;
    284284}
    285285/***********************************************************/
    286286static int initialize_telnetd(void) {
    287        
    288         if (telnetd_task_id         ) return RTEMS_RESOURCE_IN_USE;
    289         if (telnetd_stack_size<=0   ) telnetd_stack_size   =32000;
    290 
    291         if ( !telnetd_spawn_task("TNTD", telnetd_task_priority, RTEMS_MINIMUM_STACK_SIZE, rtems_task_telnetd, 0) ) {
    292                 return -1;     
    293         }
    294         return 0;
     287 
     288  if (telnetd_task_id         ) return RTEMS_RESOURCE_IN_USE;
     289  if (telnetd_stack_size<=0   ) telnetd_stack_size   =32000;
     290
     291  if ( !telnetd_spawn_task("TNTD", telnetd_task_priority, RTEMS_MINIMUM_STACK_SIZE, rtems_task_telnetd, 0) ) {
     292    return -1; 
     293  }
     294  return 0;
    295295}
    296296
    297297/***********************************************************/
    298 int startTelnetd(void (*cmd)(char *, void *), void *arg, int dontSpawn, int stack, int priority)
    299 {
    300         rtems_status_code       sc;
    301 
    302         printf("This is rtems-telnetd (modified by Till Straumann)\n");
    303         printf("$Id$\n");
    304         printf("Release $Name$\n");
    305 
    306         if ( !telnetd_shell && !cmd ) {
    307                 fprintf(stderr,"startTelnetd(): setup error - NO SHELL; bailing out\n");
    308                 return 1;
    309         }
    310 
    311         if (telnetd_task_id) {
    312                 fprintf(stderr,"ERROR:telnetd already started\n");
    313                 return 1;
    314         };
    315 
    316         if ( !telnet_pty_initialize() ) {
    317                 fprintf(stderr,"PTY driver probably not properly registered\n");
    318                 return 1;
    319         }
    320 
    321         if (cmd)
    322                 telnetd_shell = cmd;
    323         telnetd_shell_arg     = arg;
    324         telnetd_stack_size    = stack;
    325         if ( !priority ) {
    326                 priority = rtems_bsdnet_config.network_task_priority;
    327         }
    328         if ( priority < 2 )
    329                 priority=100;
    330         telnetd_task_priority = priority;
    331         telnetd_dont_spawn    = dontSpawn;
    332 
    333         sc=initialize_telnetd();
     298int rtems_telnetd_initialize(
     299  void               (*cmd)(char *, void *),
     300  void                *arg,
     301  int                  dontSpawn,
     302  size_t               stack,
     303  rtems_task_priority  priority
     304)
     305{
     306  rtems_status_code     sc;
     307
     308#if 0
     309  printf("This is rtems-telnetd (modified by Till Straumann)\n");
     310  printf("$Id$\n");
     311  printf("Release $Name$\n");
     312#endif
     313
     314  if ( !telnetd_shell && !cmd ) {
     315    fprintf(stderr,"startTelnetd(): setup error - NO SHELL; bailing out\n");
     316    return 1;
     317  }
     318
     319  if (telnetd_task_id) {
     320    fprintf(stderr,"ERROR:telnetd already started\n");
     321    return 1;
     322  };
     323
     324  if ( !telnet_pty_initialize() ) {
     325    fprintf(stderr,"PTY driver probably not properly registered\n");
     326    return 1;
     327  }
     328
     329  if (cmd)
     330    telnetd_shell = cmd;
     331  telnetd_shell_arg     = arg;
     332  telnetd_stack_size    = stack;
     333  if ( !priority ) {
     334    priority = rtems_bsdnet_config.network_task_priority;
     335  }
     336  if ( priority < 2 )
     337    priority=100;
     338  telnetd_task_priority = priority;
     339  telnetd_dont_spawn    = dontSpawn;
     340
     341  sc=initialize_telnetd();
    334342        if (sc!=RTEMS_SUCCESSFUL) return sc;
    335         printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
     343  printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
    336344                        (unsigned)telnetd_stack_size,(int)telnetd_task_priority);
    337         return 0;
     345  return 0;
    338346}
    339347
     
    348356struct shell_args       *arg = targ;
    349357
    350         sc=rtems_libio_set_private_env();
    351 
    352         /* newlib hack/workaround. Before we change stdin/out/err we must make
     358  sc=rtems_libio_set_private_env();
     359
     360  /* newlib hack/workaround. Before we change stdin/out/err we must make
    353361         * sure the internal data are initialized (fileno(stdout) has this sideeffect).
    354         * This should probably be done from RTEMS' libc support layer...
    355         * (T.S., newlibc-1.13; 2005/10)
     362  * This should probably be done from RTEMS' libc support layer...
     363  * (T.S., newlibc-1.13; 2005/10)
    356364         */
    357365
    358         fileno(stdout);
    359 
    360         if (RTEMS_SUCCESSFUL != sc) {
    361                 rtems_error(sc,"rtems_libio_set_private_env");
    362                 goto cleanup;
    363         }
    364 
    365         /* redirect stdio */
    366         for (i=0; i<3; i++) {
    367                 if ( !(nstd[i]=fopen(arg->devname,"r+")) ) {
    368                         perror("unable to open stdio");
    369                         goto cleanup;
    370                 }
    371         }
    372 
    373         stdin  = nstd[0];
    374         stdout = nstd[1];
    375         stderr = nstd[2];
     366  fileno(stdout);
     367
     368  if (RTEMS_SUCCESSFUL != sc) {
     369    rtems_error(sc,"rtems_libio_set_private_env");
     370    goto cleanup;
     371  }
     372
     373  /* redirect stdio */
     374  for (i=0; i<3; i++) {
     375    if ( !(nstd[i]=fopen(arg->devname,"r+")) ) {
     376      perror("unable to open stdio");
     377      goto cleanup;
     378    }
     379  }
     380
     381  stdin  = nstd[0];
     382  stdout = nstd[1];
     383  stderr = nstd[2];
    376384
    377385
     
    383391#endif
    384392
    385         /* call their routine */
    386         if ( 0 == check_passwd(arg->peername) )
    387                 telnetd_shell(arg->devname, arg->arg);
    388 
    389         stdin  = ostd[0];
    390         stdout = ostd[1];
    391         stderr = ostd[2];
     393  /* call their routine */
     394  if ( 0 == check_passwd(arg->peername) )
     395    telnetd_shell(arg->devname, arg->arg);
     396
     397  stdin  = ostd[0];
     398  stdout = ostd[1];
     399  stderr = ostd[2];
    392400
    393401cleanup:
    394         release_a_Connection(arg->devname, arg->peername, nstd, i);
    395         free(arg);
     402  release_a_Connection(arg->devname, arg->peername, nstd, i);
     403  free(arg);
    396404}
    397405
    398406struct wrap_delete_args {
    399         void (*t)(void *);
    400         void           *a;
     407  void (*t)(void *);
     408  void           *a;
    401409};
    402410
     
    408416register void               *a   = pwa->a;
    409417
    410         /* free argument before calling function (which may never return if
    411         * they choose to delete themselves)
    412         */
    413         free(pwa);
    414         t(a);
    415         rtems_task_delete(RTEMS_SELF);
     418  /* free argument before calling function (which may never return if
     419  * they choose to delete themselves)
     420  */
     421  free(pwa);
     422  t(a);
     423  rtems_task_delete(RTEMS_SELF);
    416424}
    417425
     
    424432struct wrap_delete_args *pwa = malloc(sizeof(*pwa));
    425433
    426                 strncpy(nm, name, 4);
    427 
    428                 if ( !pwa ) {
    429                         perror("Telnetd: no memory\n");
    430                         return 0;
    431                 }
    432 
    433                 pwa->t = fn;
    434                 pwa->a = fnarg;
    435 
    436                 if ((sc=rtems_task_create(
    437                                 rtems_build_name(nm[0], nm[1], nm[2], nm[3]),
    438                                 (rtems_task_priority)priority,
    439                                 stackSize,
    440                                 RTEMS_DEFAULT_MODES,
    441                                 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,
    442                                 &task_id)) ||
    443                         (sc=rtems_task_start(
    444                                 task_id,
    445                                 wrap_delete,
    446                                 (rtems_task_argument)pwa))) {
    447                                         free(pwa);
    448                                         rtems_error(sc,"Telnetd: spawning task failed");
    449                                         return 0;
    450                 }
    451         return (void*)task_id;
     434    strncpy(nm, name, 4);
     435
     436    if ( !pwa ) {
     437      perror("Telnetd: no memory\n");
     438      return 0;
     439    }
     440
     441    pwa->t = fn;
     442    pwa->a = fnarg;
     443
     444    if ((sc=rtems_task_create(
     445        rtems_build_name(nm[0], nm[1], nm[2], nm[3]),
     446        (rtems_task_priority)priority,
     447        stackSize,
     448        RTEMS_DEFAULT_MODES,
     449        RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,
     450        &task_id)) ||
     451      (sc=rtems_task_start(
     452        task_id,
     453        wrap_delete,
     454        (rtems_task_argument)pwa))) {
     455          free(pwa);
     456          rtems_error(sc,"Telnetd: spawning task failed");
     457          return 0;
     458    }
     459  return (void*)task_id;
    452460}
    453461
  • cpukit/telnetd/telnetd.h

    r96eadec4 r8ad6681b  
    22 * (A first version for telnetd)
    33 *
    4  *  Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
     4 *  Original Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
    55 *  May 2001
     6 *
     7 *  Reworked by Till Straumann and .h overhauled by Joel Sherrill.
    68 *
    79 *  This program is distributed in the hope that it will be useful,
     
    911 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    1012 *
    11  *  rtems_initialize_telnetd() starts the daemon.
    12  *  main_telnetd() is the main_proc for the command telnetd in the shell
    13  *  register_telnetd() add a new command in the shell to start
    14  *  interactively the telnetd daemon.
    1513 *
    1614 *  $Id$
     
    2422#endif 
    2523
    26 extern int rtems_telnetd_initialize(void);
    27 extern int rtems_telnetd_main(int argc,char * argv[]);
    28 extern int rtems_telnetd_register(void);
    29 
    30 /* OBSOLETE */
    31 #define rtems_initialize_telnetd        rtems_telnetd_initialize
    32 #define main_telnetd                    rtems_telnetd_main
    33 #define register_telnetd                rtems_telnetd_register
     24/*
     25 *  Initialize the telnetd subsystem.
     26 *
     27 *  cmd        - function which is the "shell" telnetd invokes
     28 *  arg        - context pointer to cmd
     29 *  dontSpawn  - TRUE if telnetd takes over this task.
     30 *               FALSE to create another task for the shell.
     31 *  stack      - stack size of spawned task
     32 *  priority   - initial priority of spawned task
     33 */
     34int rtems_telnetd_initialize(
     35  void               (*cmd)(char *, void *),
     36  void                *arg,
     37  int                  dontSpawn,
     38  size_t               stack,
     39  rtems_task_priority  priority
     40);
    3441
    3542#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.