[comp.unix.questions] And speaking of IPC...

koreth@ssyx.ucsc.edu (Steven Grimm) (12/24/87)

I've received a number of requests for this sort of thing, so there are
probably a lot of people out on the net who would like it.  It's a set of
black-box socket routines (AF_INET only, sorry!) that should save someone
lots of headaches when writing socket stuff.  Documentation is in the
file.  (Maybe this should go to comp.sources.unix, but it's short and
comp.sources.unix takes forever to post things...)

+New! Improved! Now 100% Artificial-+-+-----------------------------------+
|#   #  @@@  ****  &&&&& $$$$$ %   %| |Steven Grimm                       |
|#  #  @   @ *   * &       $   %   %+-+ ARPA: koreth@ssyx.ucsc.edu        |
|###   @   @ ****  &&&&    $   %%%%%| | UUCP: ...!ucbvax!ucscc!ssyx!koreth|
|#  #  @   @ * *   &       $   %   %+-+     ______________________________|
|#   #  @@@  *  ** &&&&&   $   %   %| |     |"Let's see what's out there."|
+-----with NutraSour(TM)!  No natural colors or preservatives!------------+

--------------- (cut here) ----------------

/*
** SOCKET.C
**
** Written by Steven Grimm (koreth@ssyx.ucsc.edu) on 11-26-87 (Thanksgiving)
** Please distribute widely, but leave my name here.
**
** Various black-box routines for socket manipulation, so I don't have to
** remember all the structure elements.
** Of course, I still have to remember how to call these routines.
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

extern int errno;

/*
** serversock()
**
** Creates an internet socket, binds it to an address, and prepares it for
** subsequent accept() calls by calling listen().
**
** Input: port number desired, or 0 for a random one
** Output: file descriptor of socket, or a negative error
*/
int serversock(port)
int port;
{
	int	sock, x;
	struct	sockaddr_in server;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return -errno;

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(port);

	x = bind(sock, &server, sizeof(server));
	if (x < 0)
	{
		close(sock);
		return -errno;
	}

	listen(sock, 5);

	return sock;
}

/*
** portnum()
**
** Returns the internet port number for a socket.
**
** Input: file descriptor of socket
** Output: inet port number
*/
int portnum(fd)
int fd;
{
	int	length, err;
	struct	sockaddr_in address;

	length = sizeof(address);
	err = getsockname(fd, &address, &length);
	if (err < 0)
		return -errno;

	return ntohs(address.sin_port);
}

/*
** clientsock()
**
** Returns a connected client socket.
**
** Input: host name and port number to connect to
** Output: file descriptor of CONNECTED socket, or a negative error (-9999
**         if the hostname was bad).
*/
int clientsock(host, port)
char *host;
int port;
{
	int	sock;
	struct	sockaddr_in server;
	struct	hostent *hp, *gethostbyname();

	hp = gethostbyname(host);
	if (hp == NULL)
		return -9999;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return -errno;

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
	server.sin_port = htons(port);

	if (connect(sock, &server, sizeof(server)) < 0)
	{
		close(sock);
		return -errno;
	}

	return sock;
}