/[LeafOK_CVS]/lbbs/src/bbs_net.c
ViewVC logotype

Diff of /lbbs/src/bbs_net.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.53 by sysadm, Wed Jun 18 05:11:19 2025 UTC Revision 1.62 by sysadm, Wed Oct 8 03:34:52 2025 UTC
# Line 16  Line 16 
16    
17  #include "bbs.h"  #include "bbs.h"
18  #include "common.h"  #include "common.h"
 #include "log.h"  
19  #include "io.h"  #include "io.h"
20  #include "screen.h"  #include "log.h"
 #include "menu.h"  
21  #include "login.h"  #include "login.h"
22  #include <stdio.h>  #include "menu.h"
23  #include <stdarg.h>  #include "screen.h"
24  #include <errno.h>  #include <errno.h>
 #include <string.h>  
 #include <stdlib.h>  
25  #include <fcntl.h>  #include <fcntl.h>
26    #include <netdb.h>
27    #include <stdarg.h>
28    #include <stdio.h>
29    #include <stdlib.h>
30    #include <string.h>
31  #include <time.h>  #include <time.h>
32  #include <unistd.h>  #include <unistd.h>
 #include <netdb.h>  
 #include <sys/select.h>  
 #include <sys/ioctl.h>  
 #include <sys/socket.h>  
 #include <sys/epoll.h>  
 #include <netinet/in.h>  
 #include <netinet/ip.h>  
33  #include <arpa/inet.h>  #include <arpa/inet.h>
34    #include <iconv.h>
35  #include <libssh/libssh.h>  #include <libssh/libssh.h>
36  #include <libssh/server.h>  #include <libssh/server.h>
37  #include <libssh/callbacks.h>  #include <libssh/callbacks.h>
38    #include <netinet/in.h>
39    #include <netinet/ip.h>
40    #include <sys/select.h>
41    #include <sys/ioctl.h>
42    #include <sys/socket.h>
43    #include <sys/epoll.h>
44    
45  #define MENU_CONF_DELIM " \t\r\n"  #define MENU_CONF_DELIM " \t\r\n"
46    
# Line 47  Line 48 
48  #define MAXSTATION 26 * 2  #define MAXSTATION 26 * 2
49  #define STATION_PER_LINE 4  #define STATION_PER_LINE 4
50    
51    #define BBS_NET_DEFAULT_CHARSET "UTF-8"
52    
53  struct _bbsnet_conf  struct _bbsnet_conf
54  {  {
55          char host1[20];          char host1[20];
56          char host2[40];          char host2[40];
57          char ip[40];          char ip[40];
58          in_port_t port;          in_port_t port;
59            char charset[20];
60  } bbsnet_conf[MAXSTATION];  } bbsnet_conf[MAXSTATION];
61    
62  MENU_SET bbsnet_menu;  MENU_SET bbsnet_menu;
# Line 63  int load_bbsnet_conf(const char *file_co Line 67  int load_bbsnet_conf(const char *file_co
67          MENU *p_menu;          MENU *p_menu;
68          MENU_ITEM *p_menu_item;          MENU_ITEM *p_menu_item;
69          MENU_ITEM_ID menu_item_id;          MENU_ITEM_ID menu_item_id;
70          char t[256], *t1, *t2, *t3, *t4, *saveptr;          char t[256], *t1, *t2, *t3, *t4, *t5, *saveptr;
71    
72          fp = fopen(file_config, "r");          fp = fopen(file_config, "r");
73          if (fp == NULL)          if (fp == NULL)
# Line 101  int load_bbsnet_conf(const char *file_co Line 105  int load_bbsnet_conf(const char *file_co
105                  t2 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);                  t2 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);
106                  t3 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);                  t3 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);
107                  t4 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);                  t4 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);
108                    t5 = strtok_r(NULL, MENU_CONF_DELIM, &saveptr);
109    
110                  if (t1 == NULL || t2 == NULL || t3 == NULL || t4 == NULL || t[0] == '#' || t[0] == '*')                  if (t1 == NULL || t2 == NULL || t3 == NULL || t4 == NULL || t5 == NULL || t[0] == '#' || t[0] == '*')
111                  {                  {
112                          continue;                          continue;
113                  }                  }
# Line 114  int load_bbsnet_conf(const char *file_co Line 119  int load_bbsnet_conf(const char *file_co
119                  strncpy(bbsnet_conf[menu_item_id].ip, t3, sizeof(bbsnet_conf[menu_item_id].ip) - 1);                  strncpy(bbsnet_conf[menu_item_id].ip, t3, sizeof(bbsnet_conf[menu_item_id].ip) - 1);
120                  bbsnet_conf[menu_item_id].ip[sizeof(bbsnet_conf[menu_item_id].ip) - 1] = '\0';                  bbsnet_conf[menu_item_id].ip[sizeof(bbsnet_conf[menu_item_id].ip) - 1] = '\0';
121                  bbsnet_conf[menu_item_id].port = (in_port_t)(t4 ? atoi(t4) : 23);                  bbsnet_conf[menu_item_id].port = (in_port_t)(t4 ? atoi(t4) : 23);
122                    strncpy(bbsnet_conf[menu_item_id].charset, t5, sizeof(bbsnet_conf[menu_item_id].charset) - 1);
123                    bbsnet_conf[menu_item_id].charset[sizeof(bbsnet_conf[menu_item_id].charset) - 1] = '\0';
124    
125                  p_menu_item = get_menu_item_by_id(&bbsnet_menu, menu_item_id);                  p_menu_item = get_menu_item_by_id(&bbsnet_menu, menu_item_id);
126                  if (p_menu_item == NULL)                  if (p_menu_item == NULL)
# Line 188  void process_bar(int n, int len) Line 195  void process_bar(int n, int len)
195          iflush();          iflush();
196  }  }
197    
198    int bbsnet_io_buf_conv(iconv_t cd, char *p_buf, int *p_buf_len, int *p_buf_offset, char *p_conv, size_t conv_size, int *p_conv_len)
199    {
200            char *in_buf;
201            char *out_buf;
202            size_t in_bytes;
203            size_t out_bytes;
204            int ret;
205    
206            in_buf = p_buf + *p_buf_offset;
207            in_bytes = (size_t)(*p_buf_len - *p_buf_offset);
208            out_buf = p_conv + *p_conv_len;
209            out_bytes = conv_size - (size_t)(*p_conv_len);
210    
211            while (in_bytes > 0)
212            {
213                    ret = (int)iconv(cd, &in_buf, &in_bytes, &out_buf, &out_bytes);
214                    if (ret == -1)
215                    {
216                            if (errno == EINVAL) // Incomplete
217                            {
218    #ifdef _DEBUG
219                                    log_error("iconv(inbytes=%d, outbytes=%d) error: EINVAL\n", in_bytes, out_bytes);
220    #endif
221                                    *p_buf_len = (int)(p_buf + *p_buf_len - in_buf);
222                                    *p_buf_offset = 0;
223                                    *p_conv_len = (int)(conv_size - out_bytes);
224                                    memmove(p_buf, in_buf, (size_t)(*p_buf_len));
225    
226                                    break;
227                            }
228                            else if (errno == E2BIG)
229                            {
230                                    log_error("iconv(inbytes=%d, outbytes=%d) error: E2BIG\n", in_bytes, out_bytes);
231                                    return -1;
232                            }
233                            else if (errno == EILSEQ)
234                            {
235                                    if (in_bytes > out_bytes || out_bytes <= 0)
236                                    {
237                                            log_error("iconv(inbytes=%d, outbytes=%d) error: EILSEQ and E2BIG\n", in_bytes, out_bytes);
238                                            return -2;
239                                    }
240    
241                                    *out_buf = *in_buf;
242                                    in_buf++;
243                                    out_buf++;
244                                    in_bytes--;
245                                    out_bytes--;
246    
247                                    continue;
248                            }
249                    }
250                    else
251                    {
252                            *p_buf_len = 0;
253                            *p_buf_offset = 0;
254                            *p_conv_len = (int)(conv_size - out_bytes);
255    
256                            break;
257                    }
258            }
259    
260            return 0;
261    }
262    
263  int bbsnet_connect(int n)  int bbsnet_connect(int n)
264  {  {
265          int sock, ret, loop, error;          int sock, ret, loop, error;
# Line 203  int bbsnet_connect(int n) Line 275  int bbsnet_connect(int n)
275          int output_buf_len = 0;          int output_buf_len = 0;
276          int input_buf_offset = 0;          int input_buf_offset = 0;
277          int output_buf_offset = 0;          int output_buf_offset = 0;
278            iconv_t input_cd = NULL;
279            char input_conv[LINE_BUFFER_LEN * 2];
280            char output_conv[LINE_BUFFER_LEN * 2];
281            int input_conv_len = 0;
282            int output_conv_len = 0;
283            int input_conv_offset = 0;
284            int output_conv_offset = 0;
285            iconv_t output_cd = NULL;
286          struct epoll_event ev, events[MAX_EVENTS];          struct epoll_event ev, events[MAX_EVENTS];
287          int nfds, epollfd;          int nfds, epollfd;
288          int stdin_read_wait = 0;          int stdin_read_wait = 0;
# Line 213  int bbsnet_connect(int n) Line 293  int bbsnet_connect(int n)
293          int tos;          int tos;
294          char remote_addr[IP_ADDR_LEN];          char remote_addr[IP_ADDR_LEN];
295          int remote_port;          int remote_port;
296          time_t t_used;          time_t t_used = time(NULL);
297          struct tm *tm_used;          struct tm *tm_used;
298          int ch;          int ch;
299    
# Line 225  int bbsnet_connect(int n) Line 305  int bbsnet_connect(int n)
305          clearscr();          clearscr();
306    
307          moveto(0, 0);          moveto(0, 0);
308          prints("\033[1;32m正在测试往 %s (%s) 的连接,请稍候... \033[m\r\n",          prints("\033[1;32m姝e湪娴嬭瘯寰 %s (%s) 鐨勮繛鎺ワ紝璇风◢鍊... \033[m\r\n",
309                     bbsnet_conf[n].host1, bbsnet_conf[n].ip);                     bbsnet_conf[n].host1, bbsnet_conf[n].ip);
310          iflush();          iflush();
311    
# Line 233  int bbsnet_connect(int n) Line 313  int bbsnet_connect(int n)
313    
314          if (p_host == NULL)          if (p_host == NULL)
315          {          {
316                  prints("\033[1;31m查找主机名失败!\033[m\r\n");                  prints("\033[1;31m鏌ユ壘涓绘満鍚嶅け璐ワ紒\033[m\r\n");
317                  press_any_key();                  press_any_key();
318                  return -1;                  return -1;
319          }          }
# Line 242  int bbsnet_connect(int n) Line 322  int bbsnet_connect(int n)
322    
323          if (sock < 0)          if (sock < 0)
324          {          {
325                  prints("\033[1;31m无法创建socket!\033[m\r\n");                  prints("\033[1;31m鏃犳硶鍒涘缓socket锛乗033[m\r\n");
326                  press_any_key();                  press_any_key();
327                  return -1;                  return -1;
328          }          }
# Line 267  int bbsnet_connect(int n) Line 347  int bbsnet_connect(int n)
347          remote_addr[sizeof(remote_addr) - 1] = '\0';          remote_addr[sizeof(remote_addr) - 1] = '\0';
348          remote_port = ntohs(sin.sin_port);          remote_port = ntohs(sin.sin_port);
349    
350          prints("\033[1;32m穿梭进度条提示您当前已使用的时间,按\033[1;33mCtrl+C\033[1;32m中断。\033[m\r\n");          prints("\033[1;32m绌挎杩涘害鏉℃彁绀烘偍褰撳墠宸蹭娇鐢ㄧ殑鏃堕棿锛屾寜\033[1;33mCtrl+C\033[1;32m涓柇銆俓033[m\r\n");
351          process_bar(0, MAX_PROCESS_BAR_LEN);          process_bar(0, MAX_PROCESS_BAR_LEN);
352    
353          // Set socket as non-blocking          // Set socket as non-blocking
# Line 287  int bbsnet_connect(int n) Line 367  int bbsnet_connect(int n)
367                  return -1;                  return -1;
368          }          }
369    
370          ev.events = EPOLLOUT;          ev.events = EPOLLOUT | EPOLLET;
371          ev.data.fd = sock;          ev.data.fd = sock;
372          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1)          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1)
373          {          {
# Line 295  int bbsnet_connect(int n) Line 375  int bbsnet_connect(int n)
375                  goto cleanup;                  goto cleanup;
376          }          }
377    
378          ev.events = EPOLLIN;          ev.events = EPOLLIN | EPOLLET;
379          ev.data.fd = STDIN_FILENO;          ev.data.fd = STDIN_FILENO;
380          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1)          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1)
381          {          {
# Line 322  int bbsnet_connect(int n) Line 402  int bbsnet_connect(int n)
402                          {                          {
403                                  log_error("connect(socket) error (%d)\n", errno);                                  log_error("connect(socket) error (%d)\n", errno);
404    
405                                  prints("\033[1;31m连接失败!\033[m\r\n");                                  prints("\033[1;31m杩炴帴澶辫触锛乗033[m\r\n");
406                                  press_any_key();                                  press_any_key();
407    
408                                  goto cleanup;                                  goto cleanup;
# Line 380  int bbsnet_connect(int n) Line 460  int bbsnet_connect(int n)
460          }          }
461          if (!sock_connected)          if (!sock_connected)
462          {          {
463                  prints("\033[1;31m连接失败!\033[m\r\n");                  prints("\033[1;31m杩炴帴澶辫触锛乗033[m\r\n");
464                  press_any_key();                  press_any_key();
465    
466                  goto cleanup;                  goto cleanup;
# Line 392  int bbsnet_connect(int n) Line 472  int bbsnet_connect(int n)
472                  log_error("setsockopt IP_TOS=%d error (%d)\n", tos, errno);                  log_error("setsockopt IP_TOS=%d error (%d)\n", tos, errno);
473          }          }
474    
475          prints("\033[1;31m连接成功!\033[m\r\n");          prints("\033[1;31m杩炴帴鎴愬姛锛乗033[m\r\n");
476          iflush();          iflush();
477          log_common("BBSNET connect to %s:%d\n", remote_addr, remote_port);          log_common("BBSNET connect to %s:%d\n", remote_addr, remote_port);
478    
479            input_cd = iconv_open(bbsnet_conf[n].charset, BBS_NET_DEFAULT_CHARSET);
480            if (input_cd == (iconv_t)(-1))
481            {
482                    log_error("iconv_open(%s->%s) error: %d\n", BBS_NET_DEFAULT_CHARSET, bbsnet_conf[n].charset, errno);
483                    goto cleanup;
484            }
485            output_cd = iconv_open(BBS_NET_DEFAULT_CHARSET, bbsnet_conf[n].charset);
486            if (input_cd == (iconv_t)(-1))
487            {
488                    log_error("iconv_open(%s->%s) error: %d\n", bbsnet_conf[n].charset, BBS_NET_DEFAULT_CHARSET, errno);
489                    iconv_close(input_cd);
490                    goto cleanup;
491            }
492    
493          ev.events = EPOLLIN | EPOLLOUT | EPOLLET;          ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
494          ev.data.fd = sock;          ev.data.fd = sock;
495          if (epoll_ctl(epollfd, EPOLL_CTL_MOD, sock, &ev) == -1)          if (epoll_ctl(epollfd, EPOLL_CTL_MOD, sock, &ev) == -1)
# Line 404  int bbsnet_connect(int n) Line 498  int bbsnet_connect(int n)
498                  goto cleanup;                  goto cleanup;
499          }          }
500    
501          ev.events = EPOLLOUT;          ev.events = EPOLLOUT | EPOLLET;
502          ev.data.fd = STDOUT_FILENO;          ev.data.fd = STDOUT_FILENO;
503          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDOUT_FILENO, &ev) == -1)          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDOUT_FILENO, &ev) == -1)
504          {          {
# Line 441  int bbsnet_connect(int n) Line 535  int bbsnet_connect(int n)
535                          {                          {
536                                  break;                                  break;
537                          }                          }
                         continue;  
538                  }                  }
539    
540                  for (int i = 0; i < nfds; i++)                  for (int i = 0; i < nfds; i++)
541                  {                  {
542                          if (events[i].data.fd == STDIN_FILENO || stdin_read_wait)                          if (events[i].data.fd == STDIN_FILENO)
543                          {                          {
544                                  stdin_read_wait = 1;                                  stdin_read_wait = 1;
545                                  while (input_buf_len < sizeof(input_buf) && !SYS_server_exit)                          }
546    
547                            if (events[i].data.fd == sock)
548                            {
549                                    if (events[i].events & EPOLLIN)
550                                  {                                  {
551                                          if (SSH_v2)                                          sock_read_wait = 1;
552                                    }
553                                    if (events[i].events & EPOLLOUT)
554                                    {
555                                            sock_write_wait = 1;
556                                    }
557                            }
558    
559                            if (events[i].data.fd == STDOUT_FILENO)
560                            {
561                                    stdout_write_wait = 1;
562                            }
563                    }
564    
565                    if (stdin_read_wait)
566                    {
567                            while (input_buf_len < sizeof(input_buf) && !SYS_server_exit)
568                            {
569                                    if (SSH_v2)
570                                    {
571                                            ret = ssh_channel_read_nonblocking(SSH_channel, input_buf + input_buf_len, sizeof(input_buf) - (uint32_t)input_buf_len, 0);
572                                            if (ret == SSH_ERROR)
573                                          {                                          {
574                                                  ret = ssh_channel_read_nonblocking(SSH_channel, input_buf + input_buf_len, sizeof(input_buf) - (uint32_t)input_buf_len, 0);                                                  log_error("ssh_channel_read_nonblocking() error: %s\n", ssh_get_error(SSH_session));
575                                                  if (ret == SSH_ERROR)                                                  loop = 0;
576                                                  {                                                  break;
                                                         log_error("ssh_channel_read_nonblocking() error: %s\n", ssh_get_error(SSH_session));  
                                                         loop = 0;  
                                                         break;  
                                                 }  
                                                 else if (ret == SSH_EOF)  
                                                 {  
                                                         stdin_read_wait = 0;  
                                                         loop = 0;  
                                                         break;  
                                                 }  
                                                 else if (ret == 0)  
                                                 {  
                                                         stdin_read_wait = 0;  
                                                         break; // Check whether channel is still open  
                                                 }  
577                                          }                                          }
578                                          else                                          else if (ret == SSH_EOF)
579                                          {                                          {
580                                                  ret = (int)read(STDIN_FILENO, input_buf + input_buf_len, sizeof(input_buf) - (size_t)input_buf_len);                                                  stdin_read_wait = 0;
581                                                    loop = 0;
582                                                    break;
583                                          }                                          }
584                                          if (ret < 0)                                          else if (ret == 0)
585                                          {                                          {
586                                                  if (errno == EAGAIN || errno == EWOULDBLOCK)                                                  stdin_read_wait = 0;
587                                                  {                                                  break; // Check whether channel is still open
                                                         stdin_read_wait = 0;  
                                                         break;  
                                                 }  
                                                 else if (errno == EINTR)  
                                                 {  
                                                         continue;  
                                                 }  
                                                 else  
                                                 {  
                                                         log_error("read(STDIN) error (%d)\n", errno);  
                                                         loop = 0;  
                                                         break;  
                                                 }  
588                                          }                                          }
589                                          else if (ret == 0) // broken pipe                                  }
590                                    else
591                                    {
592                                            ret = (int)read(STDIN_FILENO, input_buf + input_buf_len, sizeof(input_buf) - (size_t)input_buf_len);
593                                    }
594                                    if (ret < 0)
595                                    {
596                                            if (errno == EAGAIN || errno == EWOULDBLOCK)
597                                          {                                          {
                                                 log_common("read(STDIN) EOF\n");  
598                                                  stdin_read_wait = 0;                                                  stdin_read_wait = 0;
                                                 loop = 0;  
599                                                  break;                                                  break;
600                                          }                                          }
601                                          else                                          else if (errno == EINTR)
602                                          {                                          {
                                                 input_buf_len += ret;  
                                                 BBS_last_access_tm = time(NULL);  
603                                                  continue;                                                  continue;
604                                          }                                          }
605                                            else
606                                            {
607                                                    log_error("read(STDIN) error (%d)\n", errno);
608                                                    loop = 0;
609                                                    break;
610                                            }
611                                    }
612                                    else if (ret == 0) // broken pipe
613                                    {
614    #ifdef _DEBUG
615                                            log_error("read(STDIN) EOF\n");
616    #endif
617                                            stdin_read_wait = 0;
618                                            loop = 0;
619                                            break;
620                                    }
621                                    else
622                                    {
623                                            input_buf_len += ret;
624                                            BBS_last_access_tm = time(NULL);
625    
626                                            // Refresh current action while user input
627                                            if (user_online_update("BBS_NET") < 0)
628                                            {
629                                                    log_error("user_online_update(BBS_NET) error\n");
630                                            }
631    
632                                            continue;
633                                    }
634                            }
635                    }
636    
637                    if (sock_write_wait)
638                    {
639                            if (input_buf_offset < input_buf_len)
640                            {
641                                    ret = bbsnet_io_buf_conv(input_cd, input_buf, &input_buf_len, &input_buf_offset, input_conv, sizeof(input_conv), &input_conv_len);
642                                    if (ret < 0)
643                                    {
644                                            log_error("bbsnet_io_buf_conv(input, %d, %d, %d) error\n", input_buf_len, input_buf_offset, input_conv_len);
645                                  }                                  }
646                          }                          }
647    
648                          if (events[i].data.fd == sock || sock_write_wait) // EPOLLOUT                          while (input_conv_offset < input_conv_len && !SYS_server_exit)
649                          {                          {
650                                  sock_write_wait = 1;                                  ret = (int)write(sock, input_conv + input_conv_offset, (size_t)(input_conv_len - input_conv_offset));
651                                  while (input_buf_offset < input_buf_len && !SYS_server_exit)                                  if (ret < 0)
652                                  {                                  {
653                                          ret = (int)write(sock, input_buf + input_buf_offset, (size_t)(input_buf_len - input_buf_offset));                                          if (errno == EAGAIN || errno == EWOULDBLOCK)
                                         if (ret < 0)  
654                                          {                                          {
655                                                  if (errno == EAGAIN || errno == EWOULDBLOCK)                                                  sock_write_wait = 0;
656                                                  {                                                  break;
                                                         sock_write_wait = 0;  
                                                         break;  
                                                 }  
                                                 else if (errno == EINTR)  
                                                 {  
                                                         continue;  
                                                 }  
                                                 else  
                                                 {  
                                                         log_error("write(socket) error (%d)\n", errno);  
                                                         loop = 0;  
                                                         break;  
                                                 }  
657                                          }                                          }
658                                          else if (ret == 0) // broken pipe                                          else if (errno == EINTR)
659                                          {                                          {
660                                                  log_common("write(socket) EOF\n");                                                  continue;
661                                                  sock_write_wait = 0;                                          }
662                                            else
663                                            {
664                                                    log_error("write(socket) error (%d)\n", errno);
665                                                  loop = 0;                                                  loop = 0;
666                                                  break;                                                  break;
667                                          }                                          }
668                                          else                                  }
669                                    else if (ret == 0) // broken pipe
670                                    {
671    #ifdef _DEBUG
672                                            log_error("write(socket) EOF\n");
673    #endif
674                                            sock_write_wait = 0;
675                                            loop = 0;
676                                            break;
677                                    }
678                                    else
679                                    {
680                                            input_conv_offset += ret;
681                                            if (input_conv_offset >= input_conv_len) // Output buffer complete
682                                          {                                          {
683                                                  input_buf_offset += ret;                                                  input_conv_offset = 0;
684                                                  if (input_buf_offset >= input_buf_len) // Output buffer complete                                                  input_conv_len = 0;
685                                                  {                                                  break;
                                                         input_buf_offset = 0;  
                                                         input_buf_len = 0;  
                                                         break;  
                                                 }  
                                                 continue;  
686                                          }                                          }
687                                            continue;
688                                  }                                  }
689                          }                          }
690                    }
691    
692                          if (events[i].data.fd == sock || sock_read_wait) // EPOLLIN                  if (sock_read_wait)
693                    {
694                            while (output_buf_len < sizeof(output_buf) && !SYS_server_exit)
695                          {                          {
696                                  sock_read_wait = 1;                                  ret = (int)read(sock, output_buf + output_buf_len, sizeof(output_buf) - (size_t)output_buf_len);
697                                  while (output_buf_len < sizeof(output_buf) && !SYS_server_exit)                                  if (ret < 0)
698                                  {                                  {
699                                          ret = (int)read(sock, output_buf + output_buf_len, sizeof(output_buf) - (size_t)output_buf_len);                                          if (errno == EAGAIN || errno == EWOULDBLOCK)
                                         if (ret < 0)  
700                                          {                                          {
                                                 if (errno == EAGAIN || errno == EWOULDBLOCK)  
                                                 {  
                                                         sock_read_wait = 0;  
                                                         break;  
                                                 }  
                                                 else if (errno == EINTR)  
                                                 {  
                                                         continue;  
                                                 }  
                                                 else  
                                                 {  
                                                         log_error("read(socket) error (%d)\n", errno);  
                                                         loop = 0;  
                                                         break;  
                                                 }  
                                         }  
                                         else if (ret == 0) // broken pipe  
                                         {  
 #ifdef _DEBUG  
                                                 log_error("read(socket) EOF\n");  
 #endif  
701                                                  sock_read_wait = 0;                                                  sock_read_wait = 0;
                                                 loop = 0;  
702                                                  break;                                                  break;
703                                          }                                          }
704                                          else                                          else if (errno == EINTR)
705                                          {                                          {
                                                 output_buf_len += ret;  
706                                                  continue;                                                  continue;
707                                          }                                          }
708                                            else
709                                            {
710                                                    log_error("read(socket) error (%d)\n", errno);
711                                                    loop = 0;
712                                                    break;
713                                            }
714                                    }
715                                    else if (ret == 0) // broken pipe
716                                    {
717    #ifdef _DEBUG
718                                            log_error("read(socket) EOF\n");
719    #endif
720                                            sock_read_wait = 0;
721                                            loop = 0;
722                                            break;
723                                    }
724                                    else
725                                    {
726                                            output_buf_len += ret;
727                                            continue;
728                                  }                                  }
729                          }                          }
730                    }
731    
732                          if (events[i].data.fd == STDOUT_FILENO || stdout_write_wait)                  if (stdout_write_wait)
733                    {
734                            if (output_buf_offset < output_buf_len)
735                          {                          {
736                                  stdout_write_wait = 1;                                  ret = bbsnet_io_buf_conv(output_cd, output_buf, &output_buf_len, &output_buf_offset, output_conv, sizeof(output_conv), &output_conv_len);
737                                  while (output_buf_offset < output_buf_len && !SYS_server_exit)                                  if (ret < 0)
738                                  {                                  {
739                                          if (SSH_v2)                                          log_error("bbsnet_io_buf_conv(output, %d, %d, %d) error\n", output_buf_len, output_buf_offset, output_conv_len);
740                                    }
741                            }
742    
743                            while (output_conv_offset < output_conv_len && !SYS_server_exit)
744                            {
745                                    if (SSH_v2)
746                                    {
747                                            ret = ssh_channel_write(SSH_channel, output_conv + output_conv_offset, (uint32_t)(output_conv_len - output_conv_offset));
748                                            if (ret == SSH_ERROR)
749                                          {                                          {
750                                                  ret = ssh_channel_write(SSH_channel, output_buf + output_buf_offset, (uint32_t)(output_buf_len - output_buf_offset));                                                  log_error("ssh_channel_write() error: %s\n", ssh_get_error(SSH_session));
751                                                  if (ret == SSH_ERROR)                                                  loop = 0;
752                                                  {                                                  break;
                                                         log_error("ssh_channel_write() error: %s\n", ssh_get_error(SSH_session));  
                                                         loop = 0;  
                                                         break;  
                                                 }  
753                                          }                                          }
754                                          else                                  }
755                                    else
756                                    {
757                                            ret = (int)write(STDOUT_FILENO, output_conv + output_conv_offset, (size_t)(output_conv_len - output_conv_offset));
758                                    }
759                                    if (ret < 0)
760                                    {
761                                            if (errno == EAGAIN || errno == EWOULDBLOCK)
762                                          {                                          {
763                                                  ret = (int)write(STDOUT_FILENO, output_buf + output_buf_offset, (size_t)(output_buf_len - output_buf_offset));                                                  stdout_write_wait = 0;
764                                                    break;
765                                          }                                          }
766                                          if (ret < 0)                                          else if (errno == EINTR)
767                                          {                                          {
768                                                  if (errno == EAGAIN || errno == EWOULDBLOCK)                                                  continue;
                                                 {  
                                                         stdout_write_wait = 0;  
                                                         break;  
                                                 }  
                                                 else if (errno == EINTR)  
                                                 {  
                                                         continue;  
                                                 }  
                                                 else  
                                                 {  
                                                         log_error("write(STDOUT) error (%d)\n", errno);  
                                                         loop = 0;  
                                                         break;  
                                                 }  
769                                          }                                          }
770                                          else if (ret == 0) // broken pipe                                          else
771                                          {                                          {
772  #ifdef _DEBUG                                                  log_error("write(STDOUT) error (%d)\n", errno);
                                                 log_error("write(STDOUT) EOF\n");  
 #endif  
                                                 stdout_write_wait = 0;  
773                                                  loop = 0;                                                  loop = 0;
774                                                  break;                                                  break;
775                                          }                                          }
776                                          else                                  }
777                                    else if (ret == 0) // broken pipe
778                                    {
779    #ifdef _DEBUG
780                                            log_error("write(STDOUT) EOF\n");
781    #endif
782                                            stdout_write_wait = 0;
783                                            loop = 0;
784                                            break;
785                                    }
786                                    else
787                                    {
788                                            output_conv_offset += ret;
789                                            if (output_conv_offset >= output_conv_len) // Output buffer complete
790                                          {                                          {
791                                                  output_buf_offset += ret;                                                  output_conv_offset = 0;
792                                                  if (output_buf_offset >= output_buf_len) // Output buffer complete                                                  output_conv_len = 0;
793                                                  {                                                  break;
                                                         output_buf_offset = 0;  
                                                         output_buf_len = 0;  
                                                         break;  
                                                 }  
                                                 continue;  
794                                          }                                          }
795                                            continue;
796                                  }                                  }
797                          }                          }
798                  }                  }
799          }          }
800    
801            iconv_close(input_cd);
802            iconv_close(output_cd);
803    
804  cleanup:  cleanup:
805          if (close(epollfd) < 0)          if (close(epollfd) < 0)
806          {          {
# Line 704  bbsnet_refresh() Line 847  bbsnet_refresh()
847          moveto(22, 0);          moveto(22, 0);
848          prints(" ----------------------------------------------------------------------------- ");          prints(" ----------------------------------------------------------------------------- ");
849          moveto(23, 0);          moveto(23, 0);
850          prints(" [\x1b[1;32mCtrl+C\x1b[m]退出");          prints(" [\x1b[1;32mCtrl+C\x1b[m]閫鍑");
851    
852          iflush();          iflush();
853    
# Line 717  int bbsnet_selchange() Line 860  int bbsnet_selchange()
860    
861          moveto(20, 0);          moveto(20, 0);
862          clrtoeol();          clrtoeol();
863          prints("|\x1b[1m单位:\x1b[1;33m%-18s\x1b[m  站名:\x1b[1;33m%s\x1b[m",          prints("|\x1b[1m鍗曚綅:\x1b[1;33m%-18s\x1b[m  绔欏悕:\x1b[1;33m%s\x1b[m",
864                     bbsnet_conf[i].host2, bbsnet_conf[i].host1);                     bbsnet_conf[i].host2, bbsnet_conf[i].host1);
865          moveto(20, 79);          moveto(20, 79);
866          prints("|");          prints("|");
867          moveto(21, 0);          moveto(21, 0);
868          clrtoeol();          clrtoeol();
869          prints("|\x1b[1m连往:\x1b[1;33m%-20s", bbsnet_conf[i].ip);          prints("|\x1b[1m杩炲線:\x1b[1;33m%-20s", bbsnet_conf[i].ip);
870          if (bbsnet_conf[i].port != 23)          if (bbsnet_conf[i].port != 23)
871          {          {
872                  prints("  %d", bbsnet_conf[i].port);                  prints("  %d", bbsnet_conf[i].port);


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1