123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #include "libbb.h"
- #include "common_bufsiz.h"
- #if ENABLE_NC_110_COMPAT
- # include "nc_bloaty.c"
- #else
- static void timeout(int signum UNUSED_PARAM)
- {
- bb_error_msg_and_die("timed out");
- }
- int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int nc_main(int argc, char **argv)
- {
-
- int sfd = sfd;
- int cfd = 0;
- unsigned lport = 0;
- IF_NOT_NC_SERVER(const) unsigned do_listen = 0;
- IF_NOT_NC_EXTRA (const) unsigned wsecs = 0;
- IF_NOT_NC_EXTRA (const) unsigned delay = 0;
- IF_NOT_NC_EXTRA (const int execparam = 0;)
- IF_NC_EXTRA (char **execparam = NULL;)
- struct pollfd pfds[2];
- int opt;
- if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) {
-
- while ((opt = getopt(argc, argv,
- "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0
- ) {
- if (ENABLE_NC_SERVER && opt == 'l')
- IF_NC_SERVER(do_listen++);
- else if (ENABLE_NC_SERVER && opt == 'p')
- IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
- else if (ENABLE_NC_EXTRA && opt == 'w')
- IF_NC_EXTRA( wsecs = xatou(optarg));
- else if (ENABLE_NC_EXTRA && opt == 'i')
- IF_NC_EXTRA( delay = xatou(optarg));
- else if (ENABLE_NC_EXTRA && opt == 'f')
- IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
- else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) {
-
- IF_NC_EXTRA(
- char **p;
-
- execparam = xzalloc(sizeof(char*) * (argc - optind + 2));
- p = execparam;
- *p++ = optarg;
- while (optind < argc) {
- *p++ = argv[optind++];
- }
- )
-
- } else bb_show_usage();
- }
- argv += optind;
- argc -= optind;
-
- if (do_listen && cfd) bb_show_usage();
-
-
- if (cfd) {
- if (argc) bb_show_usage();
- } else if (do_listen) {
- if (argc > 1) bb_show_usage();
- } else {
- if (!argc || argc > 2) bb_show_usage();
- }
- } else {
- if (argc != 3) bb_show_usage();
- argc--;
- argv++;
- }
- if (wsecs) {
- signal(SIGALRM, timeout);
- alarm(wsecs);
- }
- if (!cfd) {
- if (do_listen) {
- sfd = create_and_bind_stream_or_die(argv[0], lport);
- xlisten(sfd, do_listen);
- #if 0
-
- if (!lport) {
- len_and_sockaddr lsa;
- lsa.len = LSA_SIZEOF_SA;
- getsockname(sfd, &lsa.u.sa, &lsa.len);
- lport = get_nport(&lsa.u.sa);
- fdprintf(2, "%d\n", ntohs(lport));
- }
- #endif
- close_on_exec_on(sfd);
- accept_again:
- cfd = accept(sfd, NULL, 0);
- if (cfd < 0)
- bb_perror_msg_and_die("accept");
- if (!execparam)
- close(sfd);
- } else {
- cfd = create_and_connect_stream_or_die(argv[0],
- argv[1] ? bb_lookup_port(argv[1], "tcp", 0) : 0);
- }
- }
- if (wsecs) {
- alarm(0);
-
-
- }
-
- if (execparam) {
- pid_t pid;
-
- if (do_listen > 1 && (pid = xvfork()) != 0) {
-
-
- signal(SIGCHLD, SIG_IGN);
- close(cfd);
- goto accept_again;
- }
-
- xmove_fd(cfd, 0);
- xdup2(0, 1);
-
- IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
- IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);)
- }
-
- pfds[0].fd = STDIN_FILENO;
- pfds[0].events = POLLIN;
- pfds[1].fd = cfd;
- pfds[1].events = POLLIN;
- #define iobuf bb_common_bufsiz1
- setup_common_bufsiz();
- for (;;) {
- int fdidx;
- int ofd;
- int nread;
- if (safe_poll(pfds, 2, -1) < 0)
- bb_perror_msg_and_die("poll");
- fdidx = 0;
- while (1) {
- if (pfds[fdidx].revents) {
- nread = safe_read(pfds[fdidx].fd, iobuf, COMMON_BUFSIZE);
- if (fdidx != 0) {
- if (nread < 1)
- exit(EXIT_SUCCESS);
- ofd = STDOUT_FILENO;
- } else {
- if (nread < 1) {
-
- shutdown(cfd, SHUT_WR);
- pfds[0].fd = -1;
- }
- ofd = cfd;
- }
- xwrite(ofd, iobuf, nread);
- if (delay > 0)
- sleep(delay);
- }
- if (fdidx == 1)
- break;
- fdidx++;
- }
- }
- }
- #endif
|