Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/nc.c

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

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 29  int nc_main(int argc, char **argv) Line 29  int nc_main(int argc, char **argv)
29   int sfd = sfd; /* for gcc */   int sfd = sfd; /* for gcc */
30   int cfd = 0;   int cfd = 0;
31   unsigned lport = 0;   unsigned lport = 0;
32   SKIP_NC_SERVER(const) unsigned do_listen = 0;   IF_NOT_NC_SERVER(const) unsigned do_listen = 0;
33   SKIP_NC_EXTRA (const) unsigned wsecs = 0;   IF_NOT_NC_EXTRA (const) unsigned wsecs = 0;
34   SKIP_NC_EXTRA (const) unsigned delay = 0;   IF_NOT_NC_EXTRA (const) unsigned delay = 0;
35   SKIP_NC_EXTRA (const int execparam = 0;)   IF_NOT_NC_EXTRA (const int execparam = 0;)
36   USE_NC_EXTRA  (char **execparam = NULL;)   IF_NC_EXTRA     (char **execparam = NULL;)
  len_and_sockaddr *lsa;  
37   fd_set readfds, testfds;   fd_set readfds, testfds;
38   int opt; /* must be signed (getopt returns -1) */   int opt; /* must be signed (getopt returns -1) */
39    
# Line 42  int nc_main(int argc, char **argv) Line 41  int nc_main(int argc, char **argv)
41   /* getopt32 is _almost_ usable:   /* getopt32 is _almost_ usable:
42   ** it cannot handle "... -e prog -prog-opt" */   ** it cannot handle "... -e prog -prog-opt" */
43   while ((opt = getopt(argc, argv,   while ((opt = getopt(argc, argv,
44          "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0          "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0
45   ) {   ) {
46   if (ENABLE_NC_SERVER && opt=='l')   if (ENABLE_NC_SERVER && opt == 'l')
47   USE_NC_SERVER(do_listen++);   IF_NC_SERVER(do_listen++);
48   else if (ENABLE_NC_SERVER && opt=='p')   else if (ENABLE_NC_SERVER && opt == 'p')
49   USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));   IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
50   else if (ENABLE_NC_EXTRA && opt=='w')   else if (ENABLE_NC_EXTRA && opt == 'w')
51   USE_NC_EXTRA( wsecs = xatou(optarg));   IF_NC_EXTRA( wsecs = xatou(optarg));
52   else if (ENABLE_NC_EXTRA && opt=='i')   else if (ENABLE_NC_EXTRA && opt == 'i')
53   USE_NC_EXTRA( delay = xatou(optarg));   IF_NC_EXTRA( delay = xatou(optarg));
54   else if (ENABLE_NC_EXTRA && opt=='f')   else if (ENABLE_NC_EXTRA && opt == 'f')
55   USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR));   IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
56   else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) {   else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) {
57   /* We cannot just 'break'. We should let getopt finish.   /* We cannot just 'break'. We should let getopt finish.
58   ** Or else we won't be able to find where   ** Or else we won't be able to find where
59   ** 'host' and 'port' params are   ** 'host' and 'port' params are
60   ** (think "nc -w 60 host port -e prog"). */   ** (think "nc -w 60 host port -e prog"). */
61   USE_NC_EXTRA(   IF_NC_EXTRA(
62   char **p;   char **p;
63   // +2: one for progname (optarg) and one for NULL   // +2: one for progname (optarg) and one for NULL
64   execparam = xzalloc(sizeof(char*) * (argc - optind + 2));   execparam = xzalloc(sizeof(char*) * (argc - optind + 2));
# Line 80  int nc_main(int argc, char **argv) Line 79  int nc_main(int argc, char **argv)
79   argc -= optind;   argc -= optind;
80   // -l and -f don't mix   // -l and -f don't mix
81   if (do_listen && cfd) bb_show_usage();   if (do_listen && cfd) bb_show_usage();
82   // Listen or file modes need zero arguments, client mode needs 2   // File mode needs need zero arguments, listen mode needs zero or one,
83   if (do_listen || cfd) {   // client mode needs one or two
84     if (cfd) {
85   if (argc) bb_show_usage();   if (argc) bb_show_usage();
86     } else if (do_listen) {
87     if (argc > 1) bb_show_usage();
88   } else {   } else {
89   if (!argc || argc > 2) bb_show_usage();   if (!argc || argc > 2) bb_show_usage();
90   }   }
# Line 99  int nc_main(int argc, char **argv) Line 101  int nc_main(int argc, char **argv)
101    
102   if (!cfd) {   if (!cfd) {
103   if (do_listen) {   if (do_listen) {
104   /* create_and_bind_stream_or_die(NULL, lport)   sfd = create_and_bind_stream_or_die(argv[0], lport);
  * would've work wonderfully, but we need  
  * to know lsa */  
  sfd = xsocket_stream(&lsa);  
  if (lport)  
  set_nport(lsa, htons(lport));  
  setsockopt_reuseaddr(sfd);  
  xbind(sfd, &lsa->u.sa, lsa->len);  
105   xlisten(sfd, do_listen); /* can be > 1 */   xlisten(sfd, do_listen); /* can be > 1 */
106    #if 0  /* nc-1.10 does not do this (without -v) */
107   /* If we didn't specify a port number,   /* If we didn't specify a port number,
108   * query and print it after listen() */   * query and print it after listen() */
109   if (!lport) {   if (!lport) {
110   socklen_t addrlen = lsa->len;   len_and_sockaddr lsa;
111   getsockname(sfd, &lsa->u.sa, &addrlen);   lsa.len = LSA_SIZEOF_SA;
112   lport = get_nport(&lsa->u.sa);   getsockname(sfd, &lsa.u.sa, &lsa.len);
113     lport = get_nport(&lsa.u.sa);
114   fdprintf(2, "%d\n", ntohs(lport));   fdprintf(2, "%d\n", ntohs(lport));
115   }   }
116    #endif
117   close_on_exec_on(sfd);   close_on_exec_on(sfd);
118   accept_again:   accept_again:
119   cfd = accept(sfd, NULL, 0);   cfd = accept(sfd, NULL, 0);
# Line 131  int nc_main(int argc, char **argv) Line 129  int nc_main(int argc, char **argv)
129    
130   if (wsecs) {   if (wsecs) {
131   alarm(0);   alarm(0);
132   /* Non-ignored siganls revert to SIG_DFL on exec anyway */   /* Non-ignored signals revert to SIG_DFL on exec anyway */
133   /*signal(SIGALRM, SIG_DFL);*/   /*signal(SIGALRM, SIG_DFL);*/
134   }   }
135    
136   /* -e given? */   /* -e given? */
137   if (execparam) {   if (execparam) {
138   signal(SIGCHLD, SIG_IGN);   pid_t pid;
139   // With more than one -l, repeatedly act as server.   /* With more than one -l, repeatedly act as server */
140   if (do_listen > 1 && vfork()) {   if (do_listen > 1 && (pid = vfork()) != 0) {
141   /* parent */   /* parent or error */
142   // This is a bit weird as cleanup goes, since we wind up with no   if (pid < 0)
143   // stdin/stdout/stderr.  But it's small and shouldn't hurt anything.   bb_perror_msg_and_die("vfork");
144   // We check for cfd == 0 above.   /* prevent zombies */
145   logmode = LOGMODE_NONE;   signal(SIGCHLD, SIG_IGN);
146   close(0);   close(cfd);
  close(1);  
  close(2);  
147   goto accept_again;   goto accept_again;
148   }   }
149   /* child (or main thread if no multiple -l) */   /* child, or main thread if only one -l */
150   xmove_fd(cfd, 0);   xmove_fd(cfd, 0);
151   xdup2(0, 1);   xdup2(0, 1);
152   xdup2(0, 2);   xdup2(0, 2);
153   USE_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)   IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
154   /* Don't print stuff or it will go over the wire.... */   /* Don't print stuff or it will go over the wire... */
155   _exit(127);   _exit(127);
156   }   }
157    
158   // Select loop copying stdin to cfd, and cfd to stdout.   /* Select loop copying stdin to cfd, and cfd to stdout */
159    
160   FD_ZERO(&readfds);   FD_ZERO(&readfds);
161   FD_SET(cfd, &readfds);   FD_SET(cfd, &readfds);
# Line 172  int nc_main(int argc, char **argv) Line 168  int nc_main(int argc, char **argv)
168    
169   testfds = readfds;   testfds = readfds;
170    
171   if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)   if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0)
172   bb_perror_msg_and_die("select");   bb_perror_msg_and_die("select");
173    
174  #define iobuf bb_common_bufsiz1  #define iobuf bb_common_bufsiz1
175   for (fd = 0; fd < FD_SETSIZE; fd++) {   fd = STDIN_FILENO;
176     while (1) {
177   if (FD_ISSET(fd, &testfds)) {   if (FD_ISSET(fd, &testfds)) {
178   nread = safe_read(fd, iobuf, sizeof(iobuf));   nread = safe_read(fd, iobuf, sizeof(iobuf));
179   if (fd == cfd) {   if (fd == cfd) {
# Line 184  int nc_main(int argc, char **argv) Line 181  int nc_main(int argc, char **argv)
181   exit(EXIT_SUCCESS);   exit(EXIT_SUCCESS);
182   ofd = STDOUT_FILENO;   ofd = STDOUT_FILENO;
183   } else {   } else {
184   if (nread<1) {   if (nread < 1) {
185   // Close outgoing half-connection so they get EOF, but   /* Close outgoing half-connection so they get EOF,
186   // leave incoming alone so we can see response.   * but leave incoming alone so we can see response */
187   shutdown(cfd, 1);   shutdown(cfd, 1);
188   FD_CLR(STDIN_FILENO, &readfds);   FD_CLR(STDIN_FILENO, &readfds);
189   }   }
190   ofd = cfd;   ofd = cfd;
191   }   }
192   xwrite(ofd, iobuf, nread);   xwrite(ofd, iobuf, nread);
193   if (delay > 0) sleep(delay);   if (delay > 0)
194     sleep(delay);
195   }   }
196     if (fd == cfd)
197     break;
198     fd = cfd;
199   }   }
200   }   }
201  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984