home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / yagirc-0.51.tar.gz / yagirc-0.51.tar / yagirc-0.51 / network.c < prev    next >
C/C++ Source or Header  |  1998-05-11  |  4KB  |  194 lines

  1. /*
  2.  
  3.  network.c : Network stuff
  4.  
  5.     Copyright (C) 1998 Timo Sirainen
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <errno.h>
  25.  
  26. #include <netdb.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29. #include <sys/types.h>
  30. #include <sys/signal.h>
  31. #include <sys/param.h>
  32. #include <sys/socket.h>
  33. #include <netinet/in.h>
  34. #include <arpa/inet.h>
  35.  
  36. #include <sys/time.h>
  37. #include <sys/socket.h>
  38. #include <sys/ioctl.h>
  39.  
  40. #include <glib.h>
  41.  
  42. /* Connect to socket */
  43. int net_connect(char *server, int port)
  44. {
  45.     struct sockaddr_in sin;
  46.     struct hostent *hp;
  47.     int opt, fh;
  48.  
  49.     g_return_val_if_fail(server != NULL, -1);
  50.  
  51.     memset(&sin, 0, sizeof(sin));
  52.     sin.sin_addr.s_addr = inet_addr(server); /* it's ip address? */
  53.     if (sin.sin_addr.s_addr == -1)
  54.     {
  55.         /* it's host name? */
  56.         hp = gethostbyname(server);
  57.         if (hp == NULL) return -1;
  58.  
  59.         memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
  60.     }
  61.     sin.sin_family = AF_INET;
  62.     sin.sin_port = htons(port);
  63.  
  64.     fh = socket(AF_INET, SOCK_STREAM, 0);
  65.     if (fh == -1) return -1;
  66.  
  67.     opt = 1;
  68.     setsockopt(fh, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
  69.     setsockopt(fh, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
  70.  
  71.     if (connect(fh, (struct sockaddr *)&sin, sizeof (struct sockaddr)) < 0)
  72.     {
  73.         close(fh);
  74.         return -1;
  75.     }
  76.  
  77.     fcntl(fh, F_SETFL, O_NONBLOCK);
  78.  
  79.     return fh;
  80. }
  81.  
  82. /* Disconnect socket */
  83. void net_disconnect(int fh)
  84. {
  85.     close(fh);
  86. }
  87.  
  88. /* Listen for connections on a socket */
  89. int net_listen(char *ownaddr, int *port)
  90. {
  91.     struct sockaddr_in sin;
  92.     int opt, len, fh;
  93.  
  94.     memset(&sin, 0, sizeof(sin));
  95.     sin.sin_addr.s_addr = inet_addr(ownaddr);
  96.     sin.sin_port = htons(*port);
  97.     sin.sin_family = AF_INET;
  98.  
  99.     fh = socket(AF_INET, SOCK_STREAM, 0);
  100.     if (fh == -1) return -1;
  101.  
  102.     opt = 1;
  103.     setsockopt(fh, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
  104.     setsockopt(fh, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
  105.  
  106.     if (bind(fh, (struct sockaddr *) &sin, sizeof(sin)) < 0)
  107.     {
  108.         close(fh);
  109.         return -1;
  110.     }
  111.  
  112.     len = sizeof(sin);
  113.     if (getsockname(fh, (struct sockaddr *) &sin, &len) != 0)
  114.     {
  115.         close(fh);
  116.         return -1;
  117.     }
  118.     *port = ntohs(sin.sin_port);
  119.  
  120.     if (listen(fh, 1) < 0)
  121.     {
  122.         close(fh);
  123.         return -1;
  124.     }
  125.  
  126.     fcntl(fh, F_SETFL, O_NONBLOCK);
  127.  
  128.     return fh;
  129. }
  130.  
  131. /* Accept a connection on a socket */
  132. int net_accept(int handle, char *addr, int *port)
  133. {
  134.     struct sockaddr_in saddr;
  135.     int addrlen, ret;
  136.  
  137.     addrlen = sizeof(saddr);
  138.     ret = accept(handle, (struct sockaddr *) &saddr, &addrlen);
  139.     if (ret >= 0)
  140.     {
  141.         strcpy(addr, inet_ntoa(saddr.sin_addr));
  142.         *port = ntohs(saddr.sin_port);
  143.         fcntl(ret, F_SETFL, O_NONBLOCK);
  144.     }
  145.     return ret;
  146. }
  147.  
  148. /* Read data from socket */
  149. int net_receive(int fh, char *buf, int len)
  150. {
  151.     int n;
  152.  
  153.     n = recv(fh, buf, len, 0);
  154.     if (n == 0) return -1;
  155.     if (n == -1 && errno == EWOULDBLOCK) return 0;
  156.     return n;
  157. }
  158.  
  159. /* Transmit data */
  160. int net_transmit(int fh, char *data, int len)
  161. {
  162.     int n, sent = 0;
  163.  
  164.     do
  165.     {
  166.         n = send(fh, data+sent, len-sent, 0);
  167.         if (n == 0) return -1;
  168.         if (n == -1)
  169.         {
  170.             if (errno == EWOULDBLOCK || errno == EAGAIN) continue;
  171.             return -1;
  172.         }
  173.         sent += n;
  174.     }
  175.     while (sent != len);
  176.  
  177.     return sent;
  178. }
  179.  
  180. /* Get socket address/port */
  181. int net_getsockname(int handle, char *addr, int *port)
  182. {
  183.     struct sockaddr_in sock;
  184.     int len;
  185.  
  186.     if (getsockname(handle, (struct sockaddr *) &sock, &len) == -1)
  187.         return 0;
  188.  
  189.     strcpy(addr, inet_ntoa(sock.sin_addr));
  190.     if (port != NULL) *port = sock.sin_port;
  191.  
  192.     return 1;
  193. }
  194.