/*
* Copyright (C) 2005 Roy Keene
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
/*
* Network related functions
*/
#include "compat.h"
#include "net.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <stdarg.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
/* Do things required for network access. */
static int net_init(void) {
#ifdef _USE_WIN32_
static int net_init_called = 0;
WSADATA wsaData;
if (net_init_called) {
return(0);
}
if (WSAStartup(MAKEWORD(2, 0), &wsaData)!=0) {
return(-1);
}
if (wsaData.wVersion!=MAKEWORD(2, 0)) {
/* Cleanup Winsock stuff */
WSACleanup();
return(-1);
}
net_init_called = 1;
#endif
return(0);
}
/*
* Create a listening port on tcp port PORT
*/
int net_listen(const int port) {
struct sockaddr_in localname;
int sockFd;
net_init();
sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
localname.sin_family = AF_INET;
localname.sin_port = htons(port);
localname.sin_addr.s_addr = INADDR_ANY;
if (sockFd < 0) {
return(-1);
}
if (bind(sockFd, (struct sockaddr *) &localname, sizeof(localname)) < 0) {
return(-1);
}
if (listen(sockFd, 1024) < 0) {
return(-1);
}
return(sockFd);
}
int net_connect_tcp(const char *host, const int port) {
int sockid;
struct hostent *hostinfo;
struct sockaddr_in sock;
net_init();
#ifdef HAVE_INET_ATON
if (!inet_aton(host,&sock.sin_addr)) {
#else
#ifdef HAVE_INET_ADDR
if ( (sock.sin_addr.s_addr=inet_addr(host) )==-1) {
#else
{
#endif
#endif
if ((hostinfo=gethostbyname(host))==NULL) return(-EPERM);
memcpy(&sock.sin_addr.s_addr,hostinfo->h_addr_list[0],hostinfo->h_length);
}
sock.sin_family=AF_INET;
sock.sin_port=htons(port);
if ((sockid=socket(AF_INET, SOCK_STREAM, 0))<0) {
return(-EIO);
}
if (connect(sockid, (struct sockaddr *) &sock, sizeof(sock))<0) {
close(sockid);
return(-EIO);
}
return(sockid);
}
int net_close(const int sockid) {
shutdown(sockid, SHUT_RDWR);
return(close(sockid));
}
syntax highlighted by Code2HTML, v. 0.9.1