fsck_minix.c lost fat.
[oweals/busybox.git] / mnc.c
diff --git a/mnc.c b/mnc.c
index 9d59977daebb8b40d57e0ac059c157e6134ba5b0..54cfdc602d7c7f87cd807f78801f55307d5df0a9 100644 (file)
--- a/mnc.c
+++ b/mnc.c
@@ -1,11 +1,14 @@
+/* vi: set sw=4 ts=4: */
 /*  mnc: mini-netcat - built from the ground up for LRP
     Copyright (C) 1998  Charles P. Wright
 
     0.0.1   6K      It works.
     0.0.2   5K      Smaller and you can also check the exit condition if you wish.
-
+    0.0.3          Uses select()       
 
     19980918 Busy Boxed! Dave Cinege
+    19990512 Uses Select. Charles P. Wright
+    19990513 Fixes stdin stupidity and uses buffers.  Charles P. Wright
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include <sys/time.h>
 #include <sys/ioctl.h>
 
-const char mnc_usage[] = 
-"mini-netcat 0.0.1 -- Open pipe to IP:port\n"
-"\tmnc [IP] [port]\n";
+#define BUFSIZE 100
+
+static const char mnc_usage[] =
+
+       "mnc [IP] [port]\n\n" "mini-netcat opens a pipe to IP:port\n";
 
-int
-mnc_main(struct FileInfo * i, int argc, char **argv)
+int mnc_main(int argc, char **argv)
 {
-        int sfd;
-        int result;
-        int len;
-        int pid;
-        char ch;
-        
-        struct sockaddr_in address;
-        struct hostent *hostinfo;
-
-#ifdef SELECT
-        fd_set readfds, testfds;
-#endif
-
-        sfd = socket(AF_INET, SOCK_STREAM, 0);
-
-        hostinfo = (struct hostent *) gethostbyname(argv[1]);
-
-        if (!hostinfo)
-        {
-                exit(1);
-        }
-
-        address.sin_family = AF_INET;
-        address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
-        address.sin_port = htons(atoi(argv[2]));
-
-        len = sizeof(address);
-
-        result = connect(sfd, (struct sockaddr *)&address, len);
-
-        if (result < 0) 
-        {
-                exit(2);
-        }
-
-#ifdef SELECT
-        FD_ZERO(&readfds);
-        FD_SET(sfd, &readfds);
-        FD_SET(fileno(stdin), &readfds);
-
-        while(1)
-        {
-                int fd;
-                int nread;
-
-                testfds = readfds;
-
-                result = select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) 0);
-
-                if(result < 1) 
-                {
-                        exit(3);
-                }
-
-                for(fd = 0; fd < FD_SETSIZE; fd++)
-                {
-                        if(FD_ISSET(fd,&testfds))
-                        {
-                                ioctl(fd, FIONREAD, &nread);
-
-                                if (nread == 0)
-                                        exit(0);
-
-                                if(fd == sfd)
-                                {
-                                        read(sfd, &ch, 1);
-                                        write(fileno(stdout), &ch, 1);
-                                }
-                                else
-                                {
-                                        read(fileno(stdin), &ch, 1);
-                                        write(sfd, &ch, 1);
-                                }
-                        }
-                }
-        }
-#else
-        pid = fork();
-
-        if (!pid)
-        {
-                int retval;
-                retval = 1;
-                while(retval == 1)
-                {
-                        retval = read(fileno(stdin), &ch, 1);
-                        write(sfd, &ch, 1);
-                }
-        }
-        else
-        {
-                int retval;
-                retval = 1;
-                while(retval == 1)
-                {
-                        retval = read(sfd, &ch, 1);
-                        write(fileno(stdout), &ch, 1);
-                }
-        }
-
-        exit(0);
-#endif
+       int sfd;
+       int result;
+       int len;
+       char ch[BUFSIZE];
+
+       struct sockaddr_in address;
+       struct hostent *hostinfo;
+
+       fd_set readfds, testfds;
+
+       if (argc <= 1 || **(argv + 1) == '-') {
+               usage(mnc_usage);
+       }
+       argc--;
+       argv++;
+
+       sfd = socket(AF_INET, SOCK_STREAM, 0);
+
+       hostinfo = (struct hostent *) gethostbyname(*argv);
+
+       if (!hostinfo) {
+               exit(1);
+       }
+
+       address.sin_family = AF_INET;
+       address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
+       address.sin_port = htons(atoi(*(++argv)));
+
+       len = sizeof(address);
+
+       result = connect(sfd, (struct sockaddr *) &address, len);
+
+       if (result < 0) {
+               exit(2);
+       }
+
+       FD_ZERO(&readfds);
+       FD_SET(sfd, &readfds);
+       FD_SET(fileno(stdin), &readfds);
+
+       while (1) {
+               int fd;
+               int ofd;
+               int nread;
+
+               testfds = readfds;
+
+               result =
+                       select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL,
+                                  (struct timeval *) 0);
+
+               if (result < 1) {
+                       exit(3);
+               }
+
+               for (fd = 0; fd < FD_SETSIZE; fd++) {
+                       if (FD_ISSET(fd, &testfds)) {
+                               int trn = 0;
+                               int rn;
+
+                               ioctl(fd, FIONREAD, &nread);
+
+                               if (fd == sfd) {
+                                       if (nread == 0)
+                                               exit(0);
+                                       ofd = fileno(stdout);
+                               } else {
+                                       ofd = sfd;
+                               }
+
+
+
+                               do {
+                                       rn = (BUFSIZE < nread - trn) ? BUFSIZE : nread - trn;
+                                       trn += rn;
+                                       read(fd, ch, rn);
+                                       write(ofd, ch, rn);
+                               }
+                               while (trn < nread);
+                       }
+               }
+       }
 }