masqmail

annotate src/libident/id_open.c @ 1:af25f5c39d90

added diff from debian (masqmail-0.2.21-4)
author meillo@marmaro.de
date Fri, 26 Sep 2008 20:56:23 +0200
parents
children 26e34ae9a3e3
rev   line source
meillo@0 1 /*
meillo@0 2 ** id_open.c Establish/initiate a connection to an IDENT server
meillo@0 3 **
meillo@0 4 ** Author: Peter Eriksson <pen@lysator.liu.se>
meillo@0 5 ** Fixes: Pär Emanuelsson <pell@lysator.liu.se>
meillo@0 6 */
meillo@0 7
meillo@0 8 #ifdef NeXT3
meillo@0 9 # include <libc.h>
meillo@0 10 #endif
meillo@0 11
meillo@0 12 #include <stdio.h>
meillo@0 13 #include <errno.h>
meillo@0 14 #include <fcntl.h>
meillo@0 15
meillo@0 16 #ifdef HAVE_ANSIHEADERS
meillo@0 17 # include <stdlib.h>
meillo@0 18 # include <string.h>
meillo@0 19 # include <unistd.h>
meillo@0 20 # if !defined(__sgi) && !defined(VMS)
meillo@0 21 # define bzero(p,l) memset(p, 0, l)
meillo@0 22 # endif
meillo@0 23 #endif
meillo@0 24
meillo@0 25 #include <sys/types.h>
meillo@0 26 #include <sys/socket.h>
meillo@0 27 #include <sys/wait.h>
meillo@0 28 #include <sys/time.h>
meillo@0 29 #include <sys/file.h>
meillo@0 30
meillo@0 31 #define IN_LIBIDENT_SRC
meillo@0 32 #include "ident.h"
meillo@0 33
meillo@0 34 #include <arpa/inet.h>
meillo@0 35
meillo@0 36 #ifdef _AIX
meillo@0 37 # include <sys/select.h>
meillo@0 38 #endif
meillo@0 39
meillo@0 40
meillo@0 41 /*
meillo@0 42 ident_t *id_open __P3(struct in_addr *, laddr,
meillo@0 43 struct in_addr *, faddr,
meillo@0 44 struct timeval *, timeout)
meillo@0 45 */
meillo@0 46
meillo@0 47 ident_t *id_open __P(( __STRUCT_IN_ADDR_P laddr,
meillo@0 48 __STRUCT_IN_ADDR_P faddr,
meillo@0 49 __STRUCT_TIMEVAL_P timeout))
meillo@0 50 {
meillo@0 51 ident_t *id;
meillo@0 52 int res, tmperrno;
meillo@0 53 struct sockaddr_in sin_laddr, sin_faddr;
meillo@0 54 fd_set rs, ws, es;
meillo@0 55 #ifndef OLD_SETSOCKOPT
meillo@0 56 int on = 1;
meillo@0 57 struct linger linger;
meillo@0 58 #endif
meillo@0 59
meillo@0 60 if ((id = (ident_t *) malloc(sizeof(*id))) == 0)
meillo@0 61 return 0;
meillo@0 62
meillo@0 63 if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
meillo@0 64 {
meillo@0 65 free(id);
meillo@0 66 return 0;
meillo@0 67 }
meillo@0 68
meillo@0 69 if (timeout)
meillo@0 70 {
meillo@0 71 if ((res = fcntl(id->fd, F_GETFL, 0)) < 0)
meillo@0 72 goto ERROR;
meillo@0 73
meillo@0 74 #ifndef VMS
meillo@0 75 if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0)
meillo@0 76 goto ERROR;
meillo@0 77 #endif
meillo@0 78 }
meillo@0 79
meillo@0 80 /* We silently ignore errors if we can't change LINGER */
meillo@0 81 #ifdef OLD_SETSOCKOPT
meillo@0 82 /* Old style setsockopt() */
meillo@0 83 (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER);
meillo@0 84 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR);
meillo@0 85 #else
meillo@0 86 /* New style setsockopt() */
meillo@0 87 linger.l_onoff = 0;
meillo@0 88 linger.l_linger = 0;
meillo@0 89
meillo@0 90 (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
meillo@0 91 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on));
meillo@0 92 #endif
meillo@0 93
meillo@0 94 id->buf[0] = '\0';
meillo@0 95
meillo@0 96 bzero((char *)&sin_laddr, sizeof(sin_laddr));
meillo@0 97 sin_laddr.sin_family = AF_INET;
meillo@0 98 sin_laddr.sin_addr = *laddr;
meillo@0 99 sin_laddr.sin_port = 0;
meillo@0 100
meillo@0 101 if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0)
meillo@0 102 {
meillo@0 103 #ifdef DEBUG
meillo@0 104 perror("libident: bind");
meillo@0 105 #endif
meillo@0 106 goto ERROR;
meillo@0 107 }
meillo@0 108
meillo@0 109 bzero((char *)&sin_faddr, sizeof(sin_faddr));
meillo@0 110 sin_faddr.sin_family = AF_INET;
meillo@0 111 sin_faddr.sin_addr = *faddr;
meillo@0 112 sin_faddr.sin_port = htons(IDPORT);
meillo@0 113
meillo@0 114 errno = 0;
meillo@0 115 res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr));
meillo@0 116 if (res < 0 && errno != EINPROGRESS)
meillo@0 117 {
meillo@0 118 #ifdef DEBUG
meillo@0 119 perror("libident: connect");
meillo@0 120 #endif
meillo@0 121 goto ERROR;
meillo@0 122 }
meillo@0 123
meillo@0 124 if (timeout)
meillo@0 125 {
meillo@0 126 FD_ZERO(&rs);
meillo@0 127 FD_ZERO(&ws);
meillo@0 128 FD_ZERO(&es);
meillo@0 129
meillo@0 130 FD_SET(id->fd, &rs);
meillo@0 131 FD_SET(id->fd, &ws);
meillo@0 132 FD_SET(id->fd, &es);
meillo@0 133
meillo@0 134 #ifdef __hpux
meillo@0 135 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0)
meillo@0 136 #else
meillo@0 137 if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0)
meillo@0 138 #endif
meillo@0 139 {
meillo@0 140 #ifdef DEBUG
meillo@0 141 perror("libident: select");
meillo@0 142 #endif
meillo@0 143 goto ERROR;
meillo@0 144 }
meillo@0 145
meillo@0 146 if (res == 0)
meillo@0 147 {
meillo@0 148 errno = ETIMEDOUT;
meillo@0 149 goto ERROR;
meillo@0 150 }
meillo@0 151
meillo@0 152 if (FD_ISSET(id->fd, &es))
meillo@0 153 goto ERROR;
meillo@0 154
meillo@0 155 if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws))
meillo@0 156 goto ERROR;
meillo@0 157 }
meillo@0 158
meillo@0 159 return id;
meillo@0 160
meillo@0 161 ERROR:
meillo@0 162 tmperrno = errno; /* Save, so close() won't erase it */
meillo@0 163 close(id->fd);
meillo@0 164 free(id);
meillo@0 165 errno = tmperrno;
meillo@0 166 return 0;
meillo@0 167 }