Advertisement
Guest User

Untitled

a guest
Jan 14th, 2014
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.24 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <netdb.h>
  7. #include <string.h>
  8. #include <signal.h>
  9. #include <assert.h>
  10. #include <syslog.h>
  11. #include <sys/types.h>
  12. #include <sys/select.h>
  13. #include <sys/file.h>
  14. #include <sys/ioctl.h>
  15. #include <sys/param.h>
  16. #include <sys/socket.h>
  17. #include <sys/stat.h>
  18. #include <sys/time.h>
  19. #include <sys/wait.h>
  20. #include <netinet/in.h>
  21. #include <arpa/ftp.h>
  22. #include <arpa/inet.h>
  23. #include <arpa/telnet.h>
  24. #define BUF_SIZE 4096
  25.  
  26. extern int sys_nerr, errno;
  27.  
  28.     char client_hostname[64];
  29.  
  30.  
  31.     void set_nonblock(int fd)
  32.     {
  33.         int fl;
  34.         int x;
  35.         x = fcntl(fd, F_GETFL, &fl);
  36.         if (x < 0) {
  37.         exit(1);
  38.         }
  39.         fl |= O_NONBLOCK;
  40.         x = fcntl(fd, F_SETFL, &fl);
  41.         if (x < 0) {
  42.         exit(1);
  43.         }
  44.     }
  45.  
  46.  
  47.     int serwer_gniazdo(char *addr, int port)
  48.     {
  49.         int addrlen, s, on = 1, x;
  50.         static struct sockaddr_in client_addr;
  51.  
  52.         s = socket(AF_INET, SOCK_STREAM, 0);
  53.         if (s < 0)
  54.         perror("socket"), exit(1);
  55.  
  56.         addrlen = sizeof(client_addr);
  57.         memset(&client_addr, '\0', addrlen);
  58.         client_addr.sin_family = AF_INET;
  59.         client_addr.sin_addr.s_addr = inet_addr(addr);
  60.         client_addr.sin_port = htons(port);
  61.         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, 4);
  62.         x = bind(s, (struct sockaddr *) &client_addr, addrlen);
  63.         if (x < 0)
  64.         perror("bind"), exit(1);
  65.  
  66.         x = listen(s, 5);
  67.         if (x < 0)
  68.         perror("listen"), exit(1);
  69.  
  70.         return s;
  71.     }
  72.  
  73.     int otworz_host(char *host, int port)
  74.     {
  75.         struct sockaddr_in rem_addr;
  76.         int len, s, x;
  77.         struct hostent *H;
  78.         int on = 1;
  79.  
  80.         H = gethostbyname(host);
  81.         if (!H)
  82.         return (-2);
  83.  
  84.         len = sizeof(rem_addr);
  85.  
  86.         s = socket(AF_INET, SOCK_STREAM, 0);
  87.         if (s < 0)
  88.         return s;
  89.  
  90.         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, 4);
  91.  
  92.         len = sizeof(rem_addr);
  93.         memset(&rem_addr, '\0', len);
  94.         rem_addr.sin_family = AF_INET;
  95.         memcpy(&rem_addr.sin_addr, H->h_addr, H->h_length);
  96.         rem_addr.sin_port = htons(port);
  97.         x = connect(s, (struct sockaddr *) &rem_addr, len);
  98.         if (x < 0) {
  99.         close(s);
  100.         return x;
  101.         }
  102.         set_nonblock(s);
  103.         return s;
  104.     }
  105.  
  106.     int sock_addr_info(struct sockaddr_in addr, int len, char *fqdn)
  107.     {
  108.         struct hostent *hostinfo;
  109.  
  110.         hostinfo = gethostbyaddr((char *) &addr.sin_addr.s_addr, len, AF_INET);
  111.         if (!hostinfo) {
  112.         sprintf(fqdn, "%s", inet_ntoa(addr.sin_addr));
  113.         return 0;
  114.         }
  115.         if (hostinfo && fqdn)
  116.         sprintf(fqdn, "%s [%s]", hostinfo->h_name, inet_ntoa(addr.sin_addr));
  117.         return 0;
  118.     }
  119.  
  120.  
  121.     int czekaj_na_polaczenie(int s)
  122.     {
  123.        int newsock;
  124.     static struct sockaddr_in peer;
  125.     socklen_t len;
  126.     len = sizeof(struct sockaddr);
  127.     newsock = accept(s, (struct sockaddr *) &peer, &len);
  128.         if (newsock < 0) {
  129.         if (errno != EINTR)
  130.             perror("accept");
  131.         }
  132.         sock_addr_info(peer, len, client_hostname);
  133.         set_nonblock(newsock);
  134.         return (newsock);
  135.     }
  136.  
  137.     int zapis(int fd, char *buf, int *len)
  138.     {
  139.         int x = write(fd, buf, *len);
  140.         if (x < 0)
  141.             return x;
  142.         if (x == 0)
  143.             return x;
  144.         if (x != *len)
  145.             memmove(buf, buf+x, (*len)-x);
  146.         *len -= x;
  147.         return x;
  148.     }
  149.  
  150.     void klient(int cfd, int sfd)
  151.     {
  152.         int maxfd;
  153.         char *sbuf;
  154.         char *cbuf;
  155.         int x, n;
  156.         int cbo = 0;
  157.         int sbo = 0;
  158.         fd_set R;
  159.  
  160.         sbuf = (char *)malloc(BUF_SIZE);
  161.         cbuf = (char *)malloc(BUF_SIZE);
  162.         maxfd = cfd > sfd ? cfd : sfd;
  163.         maxfd++;
  164.  
  165.        while (1)
  166.        {
  167.         struct timeval to;
  168.         if (cbo)
  169.             {
  170.             if (zapis(sfd, cbuf, &cbo) < 0 && errno != EWOULDBLOCK) {
  171.                     exit(1);
  172.             }
  173.         }
  174.         if (sbo) {
  175.             if (zapis(cfd, sbuf, &sbo) < 0 && errno != EWOULDBLOCK) {
  176.                     exit(1);
  177.             }
  178.         }
  179.        
  180.         FD_ZERO(&R);
  181.         if (cbo < BUF_SIZE)
  182.             FD_SET(cfd, &R);
  183.         if (sbo < BUF_SIZE)
  184.             FD_SET(sfd, &R);
  185.  
  186.         to.tv_sec = 0;
  187.         to.tv_usec = 1000;
  188.         x = select(maxfd+1, &R, 0, 0, &to);
  189.         if (x > 0) {
  190.             if (FD_ISSET(cfd, &R)) {
  191.             n = read(cfd, cbuf+cbo, BUF_SIZE-cbo);
  192.             if (n > 0) {
  193.                 cbo += n;
  194.             } else {
  195.                 close(cfd);
  196.                 close(sfd);
  197.                 _exit(0);
  198.             }
  199.             }
  200.             if (FD_ISSET(sfd, &R)) {
  201.             n = read(sfd, sbuf+sbo, BUF_SIZE-sbo);
  202.             if (n > 0) {
  203.                 sbo += n;
  204.             } else {
  205.                 close(sfd);
  206.                 close(cfd);
  207.                 _exit(0);
  208.             }
  209.             }
  210.         } else if (x < 0 && errno != EINTR) {
  211.             close(sfd);
  212.             close(cfd);
  213.             _exit(0);
  214.         }
  215.         }
  216.     }
  217.  
  218.  
  219.     int main(int argc, char *argv[])
  220.     {
  221.         char *localaddr = (char *)"127.0.0.1";
  222.         int localport = atoi(argv[1]);
  223.         char *remoteaddr = (char *)(argv[2]);
  224.         int remoteport = atoi(argv[3]);
  225.         int client, server;
  226.         int master_sock;
  227.  
  228.         if (4 != argc)
  229.         {
  230.             fprintf(stderr, "usage: %s port host port\n", argv[0]);
  231.             exit(1);
  232.         }
  233.  
  234.         assert(localaddr);
  235.         assert(localport > 0);
  236.         assert(remoteaddr);
  237.         assert(remoteport > 0);
  238.  
  239.         master_sock = serwer_gniazdo(localaddr, localport);
  240.        
  241.         for (;;)
  242.         {
  243.             if ((client = czekaj_na_polaczenie(master_sock)) < 0)
  244.                 continue;
  245.             if ((server = otworz_host(remoteaddr, remoteport)) < 0)
  246.                 continue;
  247.             if (!fork()) {
  248.                 klient(client, server);
  249.             }
  250.  
  251.        
  252.             close(client);
  253.             close(server);        
  254.         }
  255.  
  256.         printf("Koniec programu");
  257.  
  258.         return 0;
  259.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement