masqmail-0.2
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 +}