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 >
Wrap
C/C++ Source or Header
|
1998-05-11
|
4KB
|
194 lines
/*
network.c : Network stuff
Copyright (C) 1998 Timo Sirainen
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <glib.h>
/* Connect to socket */
int net_connect(char *server, int port)
{
struct sockaddr_in sin;
struct hostent *hp;
int opt, fh;
g_return_val_if_fail(server != NULL, -1);
memset(&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = inet_addr(server); /* it's ip address? */
if (sin.sin_addr.s_addr == -1)
{
/* it's host name? */
hp = gethostbyname(server);
if (hp == NULL) return -1;
memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
fh = socket(AF_INET, SOCK_STREAM, 0);
if (fh == -1) return -1;
opt = 1;
setsockopt(fh, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
setsockopt(fh, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
if (connect(fh, (struct sockaddr *)&sin, sizeof (struct sockaddr)) < 0)
{
close(fh);
return -1;
}
fcntl(fh, F_SETFL, O_NONBLOCK);
return fh;
}
/* Disconnect socket */
void net_disconnect(int fh)
{
close(fh);
}
/* Listen for connections on a socket */
int net_listen(char *ownaddr, int *port)
{
struct sockaddr_in sin;
int opt, len, fh;
memset(&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = inet_addr(ownaddr);
sin.sin_port = htons(*port);
sin.sin_family = AF_INET;
fh = socket(AF_INET, SOCK_STREAM, 0);
if (fh == -1) return -1;
opt = 1;
setsockopt(fh, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
setsockopt(fh, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
if (bind(fh, (struct sockaddr *) &sin, sizeof(sin)) < 0)
{
close(fh);
return -1;
}
len = sizeof(sin);
if (getsockname(fh, (struct sockaddr *) &sin, &len) != 0)
{
close(fh);
return -1;
}
*port = ntohs(sin.sin_port);
if (listen(fh, 1) < 0)
{
close(fh);
return -1;
}
fcntl(fh, F_SETFL, O_NONBLOCK);
return fh;
}
/* Accept a connection on a socket */
int net_accept(int handle, char *addr, int *port)
{
struct sockaddr_in saddr;
int addrlen, ret;
addrlen = sizeof(saddr);
ret = accept(handle, (struct sockaddr *) &saddr, &addrlen);
if (ret >= 0)
{
strcpy(addr, inet_ntoa(saddr.sin_addr));
*port = ntohs(saddr.sin_port);
fcntl(ret, F_SETFL, O_NONBLOCK);
}
return ret;
}
/* Read data from socket */
int net_receive(int fh, char *buf, int len)
{
int n;
n = recv(fh, buf, len, 0);
if (n == 0) return -1;
if (n == -1 && errno == EWOULDBLOCK) return 0;
return n;
}
/* Transmit data */
int net_transmit(int fh, char *data, int len)
{
int n, sent = 0;
do
{
n = send(fh, data+sent, len-sent, 0);
if (n == 0) return -1;
if (n == -1)
{
if (errno == EWOULDBLOCK || errno == EAGAIN) continue;
return -1;
}
sent += n;
}
while (sent != len);
return sent;
}
/* Get socket address/port */
int net_getsockname(int handle, char *addr, int *port)
{
struct sockaddr_in sock;
int len;
if (getsockname(handle, (struct sockaddr *) &sock, &len) == -1)
return 0;
strcpy(addr, inet_ntoa(sock.sin_addr));
if (port != NULL) *port = sock.sin_port;
return 1;
}