Logo Search packages:      
Sourcecode: pbbuttonsd version File versions

tcp.c

/*
 * ---------------------------------------------------------------------------
 * $Id: tcp.c,v 1.3 2003/11/12 18:25:05 matthiasgrimm Exp $
 * ---------------------------------------------------------------------------
 * Revision 1.1.1.1  2001/12/07 11:31:48  sleemburg
 * Initial CVS import of the unreleased pmud-0.8 to apmud (new project name
 * because of a name clash at sourceforge.net).
 *
 * Revision 1.3  1999/01/12 08:29:17  stephan
 * in tcp_open, close the socket if the connection fails.
 *
 * Revision 1.2  1998/09/15 07:13:31  stephan
 * win32 modifications by Job de Haas (job@dsl.nl)
 *
 * Revision 1.1  1998/04/02 12:54:49  stephan
 * Initial revision
 *
 * ---------------------------------------------------------------------------
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#ifdef WITH_PMUD

#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#ifdef WIN32
#include <winsock.h>
#include <io.h>

#define open       _open
#define close     _close
#else
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif


#if defined( __STDC__ ) || defined( WIN32 )
#include <stdarg.h>
#else
#include <varargs.h>
#endif

#define FATAL(error)    { errno = error; return (-1); }

/*
 * ---------------------------------------------------------------------------
 * public interface
 * ---------------------------------------------------------------------------
 */
int tcp_open(char *, char *, unsigned short);
int tcp_bind(unsigned short);
void tcp_listen(int);
int tcp_read(int, const char *, size_t);
int tcp_write(int, const char *, size_t);
#ifdef __STDC__
int tcp_printf(int, char *, ...);
#else
int tcp_printf();
#endif

#ifdef SOCKS
#define connect         Rconnect 
#define getsockname     Rgetsockname 
#define bind            Rbind 
#define accept          Raccept
#define listen          Rlisten 
#define select          Rselect
#endif

#ifdef WIN32
int first = 1;
#endif


int tcp_open(char *host, char *service, unsigned short port)
{
      struct sockaddr_in server;
      struct hostent *hostinfo;
      struct servent *servinfo;
#ifdef WIN32
      SOCKET sock_fd; 
      int iResult;
 
      if(first)
      {
            /* Start the WSA */
            WSADATA wsadata;
            iResult= WSAStartup( MAKEWORD( 1, 1 ), &wsadata );
            if( iResult != 0 )
                  FATAL( iResult );

            first = 0;
      }
#else
      int sock_fd; 
#endif

      /* use localhost if none specified */
      if(! host || ! *host)
            host = "localhost";

      /* check arguments */
      if( (!service || !*service ) && port <= 0)
#ifdef WIN32
            FATAL(WSAEDESTADDRREQ)
#else
            FATAL(EDESTADDRREQ)
#endif

      /* initialise the server information */
      memset((char *) &server, 0, sizeof(server));
      server.sin_family      = AF_INET;
      server.sin_port = htons(port);

      /* try to get the server specification, if fail then use port */
      if( service && *service )
      {
            servinfo = getservbyname(service, "tcp");
            if(servinfo)
                  server.sin_port = servinfo->s_port;
      }

      /* try to get the address of the host */
      server.sin_addr.s_addr = inet_addr(host);
      if( server.sin_addr.s_addr == INADDR_NONE )
      {
            hostinfo = gethostbyname(host);
            if(!hostinfo)
#ifdef WIN32
                  FATAL(WSAEADDRNOTAVAIL)
#else
                  FATAL(EADDRNOTAVAIL)
#endif

            memcpy(     (char *) &server.sin_addr,    hostinfo->h_addr, 
                  hostinfo->h_length
                  );
      }

      /* create socket */
      sock_fd = socket(AF_INET, SOCK_STREAM, 0);
      if( sock_fd < 0 )
            FATAL(errno)


      /* connect to the server */
      if(connect(sock_fd, (struct sockaddr *) &server, sizeof(server)) < 0)
      {
            close(sock_fd);
            FATAL(errno)
      }

      return(sock_fd);
} 

int tcp_bind(unsigned short port)
{
      int fd;
      struct sockaddr_in server;

      fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      if(fd < 0)
            return fd;

      memset((char*)&server, 0, sizeof(server));
      server.sin_family = AF_INET;
      server.sin_addr.s_addr = htonl(INADDR_ANY);
      server.sin_port = htons(port);

      if(bind(fd, (struct sockaddr*) &server, sizeof(server)) < 0)
      {
            close(fd);
            return -1;
      }
      return fd;
}

void tcp_listen(int fd)
{
      if(fd>=0)
            listen(fd, 5);
}

int tcp_accept(int fd)
{
      return accept(fd, (struct sockaddr*)0, (int*)0);
}

int tcp_close(int fd)
{

#ifdef WIN32
      if (!first) 
      {
            int iResult = WSACleanup();
            if(iResult != 0)
                  FATAL(iResult)
      }
#endif

      return close(fd);
}

char *tcp_identify(int fd)
{
      struct sockaddr_in client;
      int len = sizeof(client);
      char *inetaddr;
      struct hostent *remote;
      struct in_addr *remaddr;
      register int i;
      int match;

      if(getpeername(fd, (struct sockaddr*) &client, &len))
            return (char*)0;

      if(client.sin_family != AF_INET)
            return 0;
      
      inetaddr = inet_ntoa(client.sin_addr);
      if(inetaddr <= (char*)0)
            return (char*)0;

      remote=gethostbyaddr((char *)&client.sin_addr, sizeof(client.sin_addr),
                        (int)client.sin_family);
      if(!remote)
            return (char*)0;

      for(match=i=0; remote->h_addr_list[i]; i++)
      {
            remaddr = (struct in_addr*) remote->h_addr_list[i];

            if(remaddr->s_addr == client.sin_addr.s_addr)
                  match++;
      }
      return match ? remote->h_name : (char*)0;
}

int tcp_write(int fildes, const char *buffer, size_t nbytes)
{
      register char *data;
      register size_t right;
      register size_t left;

      for(data=(char *)buffer, left=nbytes;;)

            if((right=send(fildes, data, left, 0)) < 0) {
                  return right;
            } else
            {
                  left -= right;
                  data += right;

                  /* if right == 0 then EOF, return #bytes written */
                  if(right == 0 || left == 0) 
                        return nbytes - left;
            }
      /*NOTREACHED*/
}

int tcp_read(int fildes, const char *buffer, size_t nbytes)
{
      register char *data;
      register size_t right;
      register size_t left;

      for(data=(char *)buffer, left=nbytes;;)

            if((right=recv(fildes, data, left, 0)) < 0) {
                  return right;
            } else
            {
                  left -= right;
                  data += right;

                  /* if right == 0 then EOF, return #bytes already read */
                  if(right == 0 || left == 0) 
                        return nbytes - left;
            }
      /*NOTREACHED*/
}

/*VARARGS*/
int
#if defined( __STDC__ ) || defined( WIN32 )
tcp_printf(int sock, char *fmt, ...)
#else
tcp_printf(sock, fmt, va_alist)
      int sock;
      char *fmt;
      va_dcl
#endif
{
      va_list ap;
      static char buf[2*BUFSIZ];
#if defined( __STDC__ ) || defined( WIN32 )
      va_start(ap, fmt);
#else
      va_start(ap);
#endif
      vsprintf(buf, fmt, ap);
      va_end(ap);
      return tcp_write(sock, buf, strlen(buf));
}
#endif /* WITH_PMUD */

Generated by  Doxygen 1.6.0   Back to index