Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/telnet.c

    r1765 r2725  
    99 * Last modified: Fri Jun  9 14:34:24 2000 too
    1010 *
    11  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     11 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1212 *
    1313 * HISTORY
     
    2222 */
    2323
    24 #include <termios.h>
    2524#include <arpa/telnet.h>
    2625#include <netinet/in.h>
     
    4443    UF_SGA = 0x02,
    4544
    46     TS_0 = 1,
     45    TS_NORMAL = 0,
     46    TS_COPY = 1,
    4747    TS_IAC = 2,
    4848    TS_OPT = 3,
    4949    TS_SUB1 = 4,
    5050    TS_SUB2 = 5,
     51    TS_CR = 6,
    5152};
    5253
    5354typedef unsigned char byte;
    5455
     56enum { netfd = 3 };
     57
    5558struct globals {
    56     int netfd; /* console fd:s are 0 and 1 (and 2) */
    57     short   iaclen; /* could even use byte */
     59    int iaclen; /* could even use byte, but it's a loss on x86 */
    5860    byte    telstate; /* telnet negotiation state from network input */
    5961    byte    telwish;  /* DO, DONT, WILL, WONT */
    6062    byte    charmode;
    6163    byte    telflags;
    62     byte    gotsig;
    6364    byte    do_termios;
    6465#if ENABLE_FEATURE_TELNET_TTYPE
     
    6970#endif
    7071#if ENABLE_FEATURE_AUTOWIDTH
    71     int win_width, win_height;
     72    unsigned win_width, win_height;
    7273#endif
    7374    /* same buffer used both for network and console read/write */
     
    7778    struct termios termios_def;
    7879    struct termios termios_raw;
    79 };
     80} FIX_ALIASING;
    8081#define G (*(struct globals*)&bb_common_bufsiz1)
    81 void BUG_telnet_globals_too_big(void);
    8282#define INIT_G() do { \
    83     if (sizeof(G) > COMMON_BUFSIZE) \
    84         BUG_telnet_globals_too_big(); \
    85     /* memset(&G, 0, sizeof G); - already is */ \
     83    struct G_sizecheck { \
     84        char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \
     85    }; \
    8686} while (0)
    8787
    88 /* Function prototypes */
     88
    8989static void rawmode(void);
    9090static void cookmode(void);
     
    9292static void will_charmode(void);
    9393static void telopt(byte c);
    94 static int subneg(byte c);
    95 
    96 static void iacflush(void)
    97 {
    98     write(G.netfd, G.iacbuf, G.iaclen);
     94static void subneg(byte c);
     95
     96static void iac_flush(void)
     97{
     98    write(netfd, G.iacbuf, G.iaclen);
    9999    G.iaclen = 0;
    100100}
     
    102102#define write_str(fd, str) write(fd, str, sizeof(str) - 1)
    103103
     104static void doexit(int ev) NORETURN;
    104105static void doexit(int ev)
    105106{
     
    108109}
    109110
    110 static void conescape(void)
     111static void con_escape(void)
    111112{
    112113    char b;
    113114
    114     if (G.gotsig)   /* came from line mode... go raw */
     115    if (bb_got_signal) /* came from line mode... go raw */
    115116        rawmode();
    116117
     
    121122            " e exit telnet\r\n");
    122123
    123     if (read(0, &b, 1) <= 0)
    124         doexit(1);
     124    if (read(STDIN_FILENO, &b, 1) <= 0)
     125        doexit(EXIT_FAILURE);
    125126
    126127    switch (b) {
    127128    case 'l':
    128         if (!G.gotsig) {
     129        if (!bb_got_signal) {
    129130            do_linemode();
    130             goto rrturn;
     131            goto ret;
    131132        }
    132133        break;
    133134    case 'c':
    134         if (G.gotsig) {
     135        if (bb_got_signal) {
    135136            will_charmode();
    136             goto rrturn;
     137            goto ret;
    137138        }
    138139        break;
     
    143144        break;
    144145    case 'e':
    145         doexit(0);
     146        doexit(EXIT_SUCCESS);
    146147    }
    147148
    148149    write_str(1, "continuing...\r\n");
    149150
    150     if (G.gotsig)
     151    if (bb_got_signal)
    151152        cookmode();
    152 
    153  rrturn:
    154     G.gotsig = 0;
    155 
    156 }
    157 
    158 static void handlenetoutput(int len)
    159 {
    160     /*  here we could do smart tricks how to handle 0xFF:s in output
    161      *  stream  like writing twice every sequence of FF:s (thus doing
    162      *  many write()s. But I think interactive telnet application does
    163      *  not need to be 100% 8-bit clean, so changing every 0xff:s to
    164      *  0x7f:s
     153 ret:
     154    bb_got_signal = 0;
     155}
     156
     157static void handle_net_output(int len)
     158{
     159    /* here we could do smart tricks how to handle 0xFF:s in output
     160     * stream like writing twice every sequence of FF:s (thus doing
     161     * many write()s. But I think interactive telnet application does
     162     * not need to be 100% 8-bit clean, so changing every 0xff:s to
     163     * 0x7f:s
    165164     *
    166      *  2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com)
    167      *  I don't agree.
    168      *  first - I cannot use programs like sz/rz
    169      *  second - the 0x0D is sent as one character and if the next
    170      *       char is 0x0A then it's eaten by a server side.
    171      *  third - whay doy you have to make 'many write()s'?
    172      *      I don't understand.
    173      *  So I implemented it. It's realy useful for me. I hope that
    174      *  others people will find it interesting to.
     165     * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com)
     166     * I don't agree.
     167     * first - I cannot use programs like sz/rz
     168     * second - the 0x0D is sent as one character and if the next
     169     *  char is 0x0A then it's eaten by a server side.
     170     * third - why do you have to make 'many write()s'?
     171     *  I don't understand.
     172     * So I implemented it. It's really useful for me. I hope that
     173     * other people will find it interesting too.
    175174     */
    176 
    177     int i, j;
    178     byte * p = (byte*)G.buf;
    179     byte outbuf[4*DATABUFSIZE];
    180 
    181     for (i = len, j = 0; i > 0; i--, p++)
    182     {
    183         if (*p == 0x1d)
    184         {
    185             conescape();
     175    byte outbuf[2 * DATABUFSIZE];
     176    byte *p = (byte*)G.buf;
     177    int j = 0;
     178
     179    for (; len > 0; len--, p++) {
     180        byte c = *p;
     181        if (c == 0x1d) {
     182            con_escape();
    186183            return;
    187184        }
    188         outbuf[j++] = *p;
    189         if (*p == 0xff)
    190             outbuf[j++] = 0xff;
    191         else if (*p == 0x0d)
    192             outbuf[j++] = 0x00;
     185        outbuf[j++] = c;
     186        if (c == IAC)
     187            outbuf[j++] = c; /* IAC -> IAC IAC */
     188        else if (c == '\r')
     189            outbuf[j++] = '\0'; /* CR -> CR NUL */
    193190    }
    194191    if (j > 0)
    195         write(G.netfd, outbuf, j);
    196 }
    197 
    198 static void handlenetinput(int len)
     192        full_write(netfd, outbuf, j);
     193}
     194
     195static void handle_net_input(int len)
    199196{
    200197    int i;
    201198    int cstart = 0;
    202199
    203     for (i = 0; i < len; i++)
    204     {
     200    for (i = 0; i < len; i++) {
    205201        byte c = G.buf[i];
    206202
    207         if (G.telstate == 0) /* most of the time state == 0 */
    208         {
    209             if (c == IAC)
    210             {
     203        if (G.telstate == TS_NORMAL) { /* most typical state */
     204            if (c == IAC) {
    211205                cstart = i;
    212206                G.telstate = TS_IAC;
    213207            }
    214         }
    215         else
    216             switch (G.telstate)
    217              {
    218              case TS_0:
    219                  if (c == IAC)
    220                      G.telstate = TS_IAC;
    221                  else
    222                      G.buf[cstart++] = c;
    223                  break;
    224 
    225              case TS_IAC:
    226                  if (c == IAC) /* IAC IAC -> 0xFF */
    227                  {
    228                      G.buf[cstart++] = c;
    229                      G.telstate = TS_0;
    230                      break;
    231                  }
    232                  /* else */
    233                  switch (c)
    234                  {
    235                  case SB:
    236                      G.telstate = TS_SUB1;
    237                      break;
    238                  case DO:
    239                  case DONT:
    240                  case WILL:
    241                  case WONT:
    242                      G.telwish =  c;
    243                      G.telstate = TS_OPT;
    244                      break;
    245                  default:
    246                      G.telstate = TS_0; /* DATA MARK must be added later */
    247                  }
    248                  break;
    249              case TS_OPT: /* WILL, WONT, DO, DONT */
    250                  telopt(c);
    251                  G.telstate = TS_0;
    252                  break;
    253              case TS_SUB1: /* Subnegotiation */
    254              case TS_SUB2: /* Subnegotiation */
    255                  if (subneg(c))
    256                      G.telstate = TS_0;
    257                  break;
    258              }
    259     }
    260     if (G.telstate)
    261     {
    262         if (G.iaclen)           iacflush();
    263         if (G.telstate == TS_0) G.telstate = 0;
    264 
     208            else if (c == '\r') {
     209                cstart = i + 1;
     210                G.telstate = TS_CR;
     211            }
     212            /* No IACs were seen so far, no need to copy
     213             * bytes within G.buf: */
     214            continue;
     215        }
     216
     217        switch (G.telstate) {
     218        case TS_CR:
     219            /* Prev char was CR. If cur one is NUL, ignore it.
     220             * See RFC 1123 section 3.3.1 for discussion of telnet EOL handling.
     221             */
     222            G.telstate = TS_COPY;
     223            if (c == '\0')
     224                break;
     225            /* else: fall through - need to handle CR IAC ... properly */
     226
     227        case TS_COPY: /* Prev char was ordinary */
     228            /* Similar to NORMAL, but in TS_COPY we need to copy bytes */
     229            if (c == IAC)
     230                G.telstate = TS_IAC;
     231            else
     232                G.buf[cstart++] = c;
     233            if (c == '\r')
     234                G.telstate = TS_CR;
     235            break;
     236
     237        case TS_IAC: /* Prev char was IAC */
     238            if (c == IAC) { /* IAC IAC -> one IAC */
     239                G.buf[cstart++] = c;
     240                G.telstate = TS_COPY;
     241                break;
     242            }
     243            /* else */
     244            switch (c) {
     245            case SB:
     246                G.telstate = TS_SUB1;
     247                break;
     248            case DO:
     249            case DONT:
     250            case WILL:
     251            case WONT:
     252                G.telwish = c;
     253                G.telstate = TS_OPT;
     254                break;
     255            /* DATA MARK must be added later */
     256            default:
     257                G.telstate = TS_COPY;
     258            }
     259            break;
     260
     261        case TS_OPT: /* Prev chars were IAC WILL/WONT/DO/DONT */
     262            telopt(c);
     263            G.telstate = TS_COPY;
     264            break;
     265
     266        case TS_SUB1: /* Subnegotiation */
     267        case TS_SUB2: /* Subnegotiation */
     268            subneg(c); /* can change G.telstate */
     269            break;
     270        }
     271    }
     272
     273    if (G.telstate != TS_NORMAL) {
     274        /* We had some IACs, or CR */
     275        if (G.iaclen)
     276            iac_flush();
     277        if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */
     278            G.telstate = TS_NORMAL;
    265279        len = cstart;
    266280    }
    267281
    268282    if (len)
    269         write(1, G.buf, len);
    270 }
    271 
    272 static void putiac(int c)
     283        full_write(STDOUT_FILENO, G.buf, len);
     284}
     285
     286static void put_iac(int c)
    273287{
    274288    G.iacbuf[G.iaclen++] = c;
    275289}
    276290
    277 static void putiac2(byte wwdd, byte c)
     291static void put_iac2(byte wwdd, byte c)
    278292{
    279293    if (G.iaclen + 3 > IACBUFSIZE)
    280         iacflush();
    281 
    282     putiac(IAC);
    283     putiac(wwdd);
    284     putiac(c);
     294        iac_flush();
     295
     296    put_iac(IAC);
     297    put_iac(wwdd);
     298    put_iac(c);
    285299}
    286300
    287301#if ENABLE_FEATURE_TELNET_TTYPE
    288 static void putiac_subopt(byte c, char *str)
    289 {
    290     int len = strlen(str) + 6;   // ( 2 + 1 + 1 + strlen + 2 )
     302static void put_iac_subopt(byte c, char *str)
     303{
     304    int len = strlen(str) + 6;   // ( 2 + 1 + 1 + strlen + 2 )
    291305
    292306    if (G.iaclen + len > IACBUFSIZE)
    293         iacflush();
    294 
    295     putiac(IAC);
    296     putiac(SB);
    297     putiac(c);
    298     putiac(0);
     307        iac_flush();
     308
     309    put_iac(IAC);
     310    put_iac(SB);
     311    put_iac(c);
     312    put_iac(0);
    299313
    300314    while (*str)
    301         putiac(*str++);
    302 
    303     putiac(IAC);
    304     putiac(SE);
     315        put_iac(*str++);
     316
     317    put_iac(IAC);
     318    put_iac(SE);
    305319}
    306320#endif
    307321
    308322#if ENABLE_FEATURE_TELNET_AUTOLOGIN
    309 static void putiac_subopt_autologin(void)
     323static void put_iac_subopt_autologin(void)
    310324{
    311325    int len = strlen(G.autologin) + 6;  // (2 + 1 + 1 + strlen + 2)
    312     const char *user = "USER";
     326    const char *p = "USER";
    313327
    314328    if (G.iaclen + len > IACBUFSIZE)
    315         iacflush();
    316 
    317     putiac(IAC);
    318     putiac(SB);
    319     putiac(TELOPT_NEW_ENVIRON);
    320     putiac(TELQUAL_IS);
    321     putiac(NEW_ENV_VAR);
    322 
    323     while (*user)
    324         putiac(*user++);
    325 
    326     putiac(NEW_ENV_VALUE);
    327 
    328     while (*G.autologin)
    329         putiac(*G.autologin++);
    330 
    331     putiac(IAC);
    332     putiac(SE);
     329        iac_flush();
     330
     331    put_iac(IAC);
     332    put_iac(SB);
     333    put_iac(TELOPT_NEW_ENVIRON);
     334    put_iac(TELQUAL_IS);
     335    put_iac(NEW_ENV_VAR);
     336
     337    while (*p)
     338        put_iac(*p++);
     339
     340    put_iac(NEW_ENV_VALUE);
     341
     342    p = G.autologin;
     343    while (*p)
     344        put_iac(*p++);
     345
     346    put_iac(IAC);
     347    put_iac(SE);
    333348}
    334349#endif
    335350
    336351#if ENABLE_FEATURE_AUTOWIDTH
    337 static void putiac_naws(byte c, int x, int y)
     352static void put_iac_naws(byte c, int x, int y)
    338353{
    339354    if (G.iaclen + 9 > IACBUFSIZE)
    340         iacflush();
    341 
    342     putiac(IAC);
    343     putiac(SB);
    344     putiac(c);
    345 
    346     putiac((x >> 8) & 0xff);
    347     putiac(x & 0xff);
    348     putiac((y >> 8) & 0xff);
    349     putiac(y & 0xff);
    350 
    351     putiac(IAC);
    352     putiac(SE);
     355        iac_flush();
     356
     357    put_iac(IAC);
     358    put_iac(SB);
     359    put_iac(c);
     360
     361    put_iac((x >> 8) & 0xff);
     362    put_iac(x & 0xff);
     363    put_iac((y >> 8) & 0xff);
     364    put_iac(y & 0xff);
     365
     366    put_iac(IAC);
     367    put_iac(SE);
    353368}
    354369#endif
     
    379394    setConMode();
    380395
    381     putiac2(DO, TELOPT_ECHO);
    382     putiac2(DO, TELOPT_SGA);
    383     iacflush();
     396    put_iac2(DO, TELOPT_ECHO);
     397    put_iac2(DO, TELOPT_SGA);
     398    iac_flush();
    384399}
    385400
     
    390405    setConMode();
    391406
    392     putiac2(DONT, TELOPT_ECHO);
    393     putiac2(DONT, TELOPT_SGA);
    394     iacflush();
     407    put_iac2(DONT, TELOPT_ECHO);
     408    put_iac2(DONT, TELOPT_SGA);
     409    iac_flush();
    395410}
    396411
     
    398413{
    399414    if (G.telwish == WILL)
    400         putiac2(DONT, c);
     415        put_iac2(DONT, c);
    401416    else if (G.telwish == DO)
    402         putiac2(WONT, c);
     417        put_iac2(WONT, c);
    403418}
    404419
     
    407422    /* if server requests ECHO, don't agree */
    408423    if (G.telwish == DO) {
    409         putiac2(WONT, TELOPT_ECHO);
     424        put_iac2(WONT, TELOPT_ECHO);
    410425        return;
    411426    }
     
    423438
    424439    if (G.telflags & UF_ECHO)
    425         putiac2(DO, TELOPT_ECHO);
     440        put_iac2(DO, TELOPT_ECHO);
    426441    else
    427         putiac2(DONT, TELOPT_ECHO);
     442        put_iac2(DONT, TELOPT_ECHO);
    428443
    429444    setConMode();
    430     write_str(1, "\r\n");  /* sudden modec */
     445    full_write1_str("\r\n");  /* sudden modec */
    431446}
    432447
     
    441456        return;
    442457
    443     if ((G.telflags ^= UF_SGA) & UF_SGA) /* toggle */
    444         putiac2(DO, TELOPT_SGA);
     458    G.telflags ^= UF_SGA; /* toggle */
     459    if (G.telflags & UF_SGA)
     460        put_iac2(DO, TELOPT_SGA);
    445461    else
    446         putiac2(DONT, TELOPT_SGA);
     462        put_iac2(DONT, TELOPT_SGA);
    447463}
    448464
     
    451467{
    452468    /* Tell server we will (or won't) do TTYPE */
    453 
    454469    if (G.ttype)
    455         putiac2(WILL, TELOPT_TTYPE);
     470        put_iac2(WILL, TELOPT_TTYPE);
    456471    else
    457         putiac2(WONT, TELOPT_TTYPE);
     472        put_iac2(WONT, TELOPT_TTYPE);
    458473}
    459474#endif
     
    463478{
    464479    /* Tell server we will (or will not) do AUTOLOGIN */
    465 
    466480    if (G.autologin)
    467         putiac2(WILL, TELOPT_NEW_ENVIRON);
     481        put_iac2(WILL, TELOPT_NEW_ENVIRON);
    468482    else
    469         putiac2(WONT, TELOPT_NEW_ENVIRON);
     483        put_iac2(WONT, TELOPT_NEW_ENVIRON);
    470484}
    471485#endif
     
    475489{
    476490    /* Tell server we will do NAWS */
    477     putiac2(WILL, TELOPT_NAWS);
     491    put_iac2(WILL, TELOPT_NAWS);
    478492}
    479493#endif
     
    497511    case TELOPT_NAWS:
    498512        to_naws();
    499         putiac_naws(c, G.win_width, G.win_height);
     513        put_iac_naws(c, G.win_width, G.win_height);
    500514        break;
    501515#endif
     
    507521
    508522/* subnegotiation -- ignore all (except TTYPE,NAWS) */
    509 static int subneg(byte c)
     523static void subneg(byte c)
    510524{
    511525    switch (G.telstate) {
     
    515529#if ENABLE_FEATURE_TELNET_TTYPE
    516530        else
    517         if (c == TELOPT_TTYPE)
    518             putiac_subopt(TELOPT_TTYPE, G.ttype);
     531        if (c == TELOPT_TTYPE && G.ttype)
     532            put_iac_subopt(TELOPT_TTYPE, G.ttype);
    519533#endif
    520534#if ENABLE_FEATURE_TELNET_AUTOLOGIN
    521535        else
    522         if (c == TELOPT_NEW_ENVIRON)
    523             putiac_subopt_autologin();
     536        if (c == TELOPT_NEW_ENVIRON && G.autologin)
     537            put_iac_subopt_autologin();
    524538#endif
    525539        break;
    526540    case TS_SUB2:
    527         if (c == SE)
    528             return TRUE;
     541        if (c == SE) {
     542            G.telstate = TS_COPY;
     543            return;
     544        }
    529545        G.telstate = TS_SUB1;
    530         /* break; */
    531     }
    532     return FALSE;
    533 }
    534 
    535 static void fgotsig(int sig)
    536 {
    537     G.gotsig = sig;
    538 }
    539 
     546        break;
     547    }
     548}
    540549
    541550static void rawmode(void)
     
    551560}
    552561
    553 int telnet_main(int argc, char** argv);
    554 int telnet_main(int argc, char** argv)
     562int telnet_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     563int telnet_main(int argc UNUSED_PARAM, char **argv)
    555564{
    556565    char *host;
    557566    int port;
    558567    int len;
    559 #ifdef USE_POLL
    560568    struct pollfd ufds[2];
    561 #else
    562     fd_set readfds;
    563     int maxfd;
    564 #endif
    565569
    566570    INIT_G();
     
    579583        cfmakeraw(&G.termios_raw);
    580584    }
    581 
    582     if (argc < 2)
    583         bb_show_usage();
    584585
    585586#if ENABLE_FEATURE_TELNET_AUTOLOGIN
     
    597598        bb_show_usage();
    598599
    599     G.netfd = create_and_connect_stream_or_die(host, port);
    600 
    601     setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
    602 
    603     signal(SIGINT, fgotsig);
    604 
    605 #ifdef USE_POLL
    606     ufds[0].fd = 0; ufds[1].fd = G.netfd;
    607     ufds[0].events = ufds[1].events = POLLIN;
    608 #else
    609     FD_ZERO(&readfds);
    610     FD_SET(0, &readfds);
    611     FD_SET(G.netfd, &readfds);
    612     maxfd = G.netfd + 1;
    613 #endif
     600    xmove_fd(create_and_connect_stream_or_die(host, port), netfd);
     601
     602    setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
     603
     604    signal(SIGINT, record_signo);
     605
     606    ufds[0].fd = STDIN_FILENO;
     607    ufds[0].events = POLLIN;
     608    ufds[1].fd = netfd;
     609    ufds[1].events = POLLIN;
    614610
    615611    while (1) {
    616 #ifndef USE_POLL
    617         fd_set rfds = readfds;
    618 
    619         switch (select(maxfd, &rfds, NULL, NULL, NULL))
    620 #else
    621         switch (poll(ufds, 2, -1))
    622 #endif
    623         {
    624         case 0:
    625             /* timeout */
    626         case -1:
     612        if (poll(ufds, 2, -1) < 0) {
    627613            /* error, ignore and/or log something, bay go to loop */
    628             if (G.gotsig)
    629                 conescape();
     614            if (bb_got_signal)
     615                con_escape();
    630616            else
    631617                sleep(1);
    632             break;
    633         default:
    634 
    635 #ifdef USE_POLL
    636             if (ufds[0].revents) /* well, should check POLLIN, but ... */
    637 #else
    638             if (FD_ISSET(0, &rfds))
    639 #endif
    640             {
    641                 len = read(0, G.buf, DATABUFSIZE);
    642                 if (len <= 0)
    643                     doexit(0);
    644                 TRACE(0, ("Read con: %d\n", len));
    645                 handlenetoutput(len);
     618            continue;
     619        }
     620
     621// FIXME: reads can block. Need full bidirectional buffering.
     622
     623        if (ufds[0].revents) {
     624            len = safe_read(STDIN_FILENO, G.buf, DATABUFSIZE);
     625            if (len <= 0)
     626                doexit(EXIT_SUCCESS);
     627            TRACE(0, ("Read con: %d\n", len));
     628            handle_net_output(len);
     629        }
     630
     631        if (ufds[1].revents) {
     632            len = safe_read(netfd, G.buf, DATABUFSIZE);
     633            if (len <= 0) {
     634                full_write1_str("Connection closed by foreign host\r\n");
     635                doexit(EXIT_FAILURE);
    646636            }
    647 
    648 #ifdef USE_POLL
    649             if (ufds[1].revents) /* well, should check POLLIN, but ... */
    650 #else
    651             if (FD_ISSET(G.netfd, &rfds))
    652 #endif
    653             {
    654                 len = read(G.netfd, G.buf, DATABUFSIZE);
    655                 if (len <= 0) {
    656                     write_str(1, "Connection closed by foreign host\r\n");
    657                     doexit(1);
    658                 }
    659                 TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len));
    660                 handlenetinput(len);
    661             }
    662         }
    663     }
    664 }
     637            TRACE(0, ("Read netfd (%d): %d\n", netfd, len));
     638            handle_net_input(len);
     639        }
     640    } /* while (1) */
     641}
Note: See TracChangeset for help on using the changeset viewer.