contrib/newshound/socket.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- alrmbrk
- atoport
- atoaddr
- make_connection
- sock_write
- sock_gets
- sock_puts
/* This code was developed by Vic Metcalfe (vic@brutus.tlug.org) */
/* The source has no copyright and was taken from the unix-socket-faq. */
#include "conf.h"
void alrmbrk()
/* [<][>][^][v][top][bottom][index][help] */
{
done = 1;
}
int atoport(char *service, char *proto)
/* [<][>][^][v][top][bottom][index][help] */
{
int port;
long int lport;
struct servent *serv;
char *errpos;
/* First try to read it from /etc/services */
serv = getservbyname(service, proto);
if (serv != NULL)
port = serv->s_port;
else
{ /* Not in services, maybe a number? */
lport = strtol(service,&errpos,0);
if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) )
return -1; /* Invalid port address */
port = htons(lport);
}
return port;
}
struct in_addr *atoaddr(char *address)
/* [<][>][^][v][top][bottom][index][help] */
{
struct hostent *host;
static struct in_addr saddr;
/* First try it as aaa.bbb.ccc.ddd. */
saddr.s_addr = inet_addr(address);
if (saddr.s_addr != -1)
{
return &saddr;
}
host = gethostbyname(address);
if (host != NULL)
{
return (struct in_addr *) *host->h_addr_list;
}
return NULL;
}
int make_connection(char *service, int type, char *netaddress)
/* [<][>][^][v][top][bottom][index][help] */
{
/* First convert service from a string, to a number... */
int port = -1;
struct in_addr *addr;
int sock, connected;
struct sockaddr_in address;
if (type == SOCK_STREAM)
port = atoport(service, "tcp");
if (type == SOCK_DGRAM)
port = atoport(service, "udp");
if (port == -1)
{
fprintf(stderr,"make_connection: Invalid socket type.\n");
return -1;
}
addr = atoaddr(netaddress);
if (addr == NULL)
{
fprintf(stderr,"make_connection: Invalid network address.\n");
return -1;
}
memset((char *) &address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = (port);
address.sin_addr.s_addr = addr->s_addr;
sock = socket(AF_INET, type, 0);
if (debug>=1)
printf("Connecting to %s on port %d.\n",inet_ntoa(*addr),htons(port));
if (type == SOCK_STREAM)
{
connected = connect(sock, (struct sockaddr *) &address,
sizeof(address));
if (connected < 0)
{
perror("connect");
return -1;
}
return sock;
}
/* Otherwise, must be for udp, so bind to address. */
if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0)
{
perror("bind");
return -1;
}
return sock;
}
int sock_write(int sockfd, const char *buf, size_t count)
/* [<][>][^][v][top][bottom][index][help] */
{
size_t bytes_sent = 0;
int this_write;
while (bytes_sent < count)
{
do
this_write = write(sockfd, buf, count - bytes_sent);
while ( (this_write < 0) && (errno == EINTR) );
if (this_write <= 0)
return this_write;
bytes_sent += this_write;
buf += this_write;
}
return count;
}
int sock_gets(int sockfd, char *str, size_t count) {
/* [<][>][^][v][top][bottom][index][help] */
int bytes_read;
int total_count = 0;
char *current_position;
char last_read = 0;
done = 0;
current_position = str;
signal(SIGALRM, alrmbrk);
while ((last_read != 10) && (done != 1)){
alarm(60);
bytes_read = read(sockfd, &last_read, 1);
if (bytes_read <= 0) {
/* The other side may have closed unexpectedly */
return -1; /* Is this effective on other platforms than linux? */
}
if ( (total_count < count) && (last_read != 10) && (last_read !=13) ) {
current_position[0] = last_read;
current_position++;
total_count++;
}
}
if (count > 0)
current_position[0] = 0;
return total_count;
}
int sock_puts(int sockfd, const char *str) {
/* [<][>][^][v][top][bottom][index][help] */
return sock_write(sockfd, str, strlen(str));
}