masqmail

diff src/libident/id_open.c @ 0:08114f7dcc23

this is masqmail-0.2.21 from oliver kurth
author meillo@marmaro.de
date Fri, 26 Sep 2008 17:05:23 +0200
parents
children 26e34ae9a3e3
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/libident/id_open.c	Fri Sep 26 17:05:23 2008 +0200
     1.3 @@ -0,0 +1,167 @@
     1.4 +/*
     1.5 +** id_open.c                 Establish/initiate a connection to an IDENT server
     1.6 +**
     1.7 +** Author: Peter Eriksson <pen@lysator.liu.se>
     1.8 +** Fixes: Pär Emanuelsson <pell@lysator.liu.se>
     1.9 +*/
    1.10 +
    1.11 +#ifdef NeXT3
    1.12 +#  include <libc.h>
    1.13 +#endif
    1.14 +
    1.15 +#include <stdio.h>
    1.16 +#include <errno.h>
    1.17 +#include <fcntl.h>
    1.18 +
    1.19 +#ifdef HAVE_ANSIHEADERS
    1.20 +#  include <stdlib.h>
    1.21 +#  include <string.h>
    1.22 +#  include <unistd.h>
    1.23 +#  if !defined(__sgi) && !defined(VMS)
    1.24 +#    define bzero(p,l)     memset(p, 0, l)
    1.25 +#  endif
    1.26 +#endif
    1.27 +
    1.28 +#include <sys/types.h>
    1.29 +#include <sys/socket.h>
    1.30 +#include <sys/wait.h>
    1.31 +#include <sys/time.h>
    1.32 +#include <sys/file.h>
    1.33 +
    1.34 +#define IN_LIBIDENT_SRC
    1.35 +#include "ident.h"
    1.36 +
    1.37 +#include <arpa/inet.h>
    1.38 +
    1.39 +#ifdef _AIX
    1.40 +#  include <sys/select.h>
    1.41 +#endif
    1.42 +
    1.43 +
    1.44 +/*
    1.45 +ident_t *id_open __P3(struct in_addr *, laddr,
    1.46 +		      struct in_addr *, faddr,
    1.47 +		      struct timeval *, timeout)
    1.48 +*/
    1.49 +
    1.50 +ident_t *id_open __P((	__STRUCT_IN_ADDR_P laddr,
    1.51 +			__STRUCT_IN_ADDR_P faddr,
    1.52 +			__STRUCT_TIMEVAL_P timeout))
    1.53 +{
    1.54 +    ident_t *id;
    1.55 +    int res, tmperrno;
    1.56 +    struct sockaddr_in sin_laddr, sin_faddr;
    1.57 +    fd_set rs, ws, es;
    1.58 +#ifndef OLD_SETSOCKOPT
    1.59 +    int on = 1;
    1.60 +    struct linger linger;
    1.61 +#endif
    1.62 +    
    1.63 +    if ((id = (ident_t *) malloc(sizeof(*id))) == 0)
    1.64 +	return 0;
    1.65 +    
    1.66 +    if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    1.67 +    {
    1.68 +	free(id);
    1.69 +	return 0;
    1.70 +    }
    1.71 +    
    1.72 +    if (timeout)
    1.73 +    {
    1.74 +	if ((res = fcntl(id->fd, F_GETFL, 0)) < 0)
    1.75 +	    goto ERROR;
    1.76 +
    1.77 +#ifndef VMS
    1.78 +	if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0)
    1.79 +	    goto ERROR;
    1.80 +#endif
    1.81 +    }
    1.82 +
    1.83 +    /* We silently ignore errors if we can't change LINGER */
    1.84 +#ifdef OLD_SETSOCKOPT
    1.85 +    /* Old style setsockopt() */
    1.86 +    (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER);
    1.87 +    (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR);
    1.88 +#else
    1.89 +    /* New style setsockopt() */
    1.90 +    linger.l_onoff = 0;
    1.91 +    linger.l_linger = 0;
    1.92 +    
    1.93 +    (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
    1.94 +    (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on));
    1.95 +#endif
    1.96 +    
    1.97 +    id->buf[0] = '\0';
    1.98 +    
    1.99 +    bzero((char *)&sin_laddr, sizeof(sin_laddr));
   1.100 +    sin_laddr.sin_family = AF_INET;
   1.101 +    sin_laddr.sin_addr = *laddr;
   1.102 +    sin_laddr.sin_port = 0;
   1.103 +    
   1.104 +    if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0)
   1.105 +    {
   1.106 +#ifdef DEBUG
   1.107 +	perror("libident: bind");
   1.108 +#endif
   1.109 +	goto ERROR;
   1.110 +    }
   1.111 +    
   1.112 +    bzero((char *)&sin_faddr, sizeof(sin_faddr));
   1.113 +    sin_faddr.sin_family = AF_INET;
   1.114 +    sin_faddr.sin_addr = *faddr;
   1.115 +    sin_faddr.sin_port = htons(IDPORT);
   1.116 +
   1.117 +    errno = 0;
   1.118 +    res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr));
   1.119 +    if (res < 0 && errno != EINPROGRESS)
   1.120 +    {
   1.121 +#ifdef DEBUG
   1.122 +	perror("libident: connect");
   1.123 +#endif
   1.124 +	goto ERROR;
   1.125 +    }
   1.126 +
   1.127 +    if (timeout)
   1.128 +    {
   1.129 +	FD_ZERO(&rs);
   1.130 +	FD_ZERO(&ws);
   1.131 +	FD_ZERO(&es);
   1.132 +	
   1.133 +	FD_SET(id->fd, &rs);
   1.134 +	FD_SET(id->fd, &ws);
   1.135 +	FD_SET(id->fd, &es);
   1.136 +
   1.137 +#ifdef __hpux
   1.138 +	if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0)
   1.139 +#else
   1.140 +	if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0)
   1.141 +#endif
   1.142 +	{
   1.143 +#ifdef DEBUG
   1.144 +	    perror("libident: select");
   1.145 +#endif
   1.146 +	    goto ERROR;
   1.147 +	}
   1.148 +	
   1.149 +	if (res == 0)
   1.150 +	{
   1.151 +	    errno = ETIMEDOUT;
   1.152 +	    goto ERROR;
   1.153 +	}
   1.154 +	
   1.155 +	if (FD_ISSET(id->fd, &es))
   1.156 +	    goto ERROR;
   1.157 +	
   1.158 +	if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws))
   1.159 +	    goto ERROR;
   1.160 +    }
   1.161 +    
   1.162 +    return id;
   1.163 +    
   1.164 +  ERROR:
   1.165 +    tmperrno = errno;		/* Save, so close() won't erase it */
   1.166 +    close(id->fd);
   1.167 +    free(id);
   1.168 +    errno = tmperrno;
   1.169 +    return 0;
   1.170 +}