masqmail

annotate src/libident/id_parse.c @ 281:ea5f86e0a81c

modes are now enforced exclusive Other MTAs (exim, postfix) are more relaxing, but as combinations of exclusive modes are senseless we behave more obvious if we fail early. This makes understanding the behavior easier too.
author markus schnalke <meillo@marmaro.de>
date Tue, 07 Dec 2010 14:04:56 -0300
parents 08114f7dcc23
children
rev   line source
meillo@0 1 /*
meillo@0 2 ** id_parse.c Receive and parse a reply from an IDENT server
meillo@0 3 **
meillo@0 4 ** Author: Peter Eriksson <pen@lysator.liu.se>
meillo@0 5 ** Fiddling: 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 <string.h>
meillo@0 14 #include <errno.h>
meillo@0 15 #include <ctype.h>
meillo@0 16
meillo@0 17 #ifdef HAVE_ANSIHEADERS
meillo@0 18 # include <stdlib.h>
meillo@0 19 # include <string.h>
meillo@0 20 # include <unistd.h>
meillo@0 21 #endif
meillo@0 22
meillo@0 23 #include <sys/types.h>
meillo@0 24 #include <sys/wait.h>
meillo@0 25 #include <sys/time.h>
meillo@0 26
meillo@0 27 #ifdef _AIX
meillo@0 28 # include <sys/select.h>
meillo@0 29 #endif
meillo@0 30
meillo@0 31 #ifdef _AIX
meillo@0 32 # include <sys/select.h>
meillo@0 33 #endif
meillo@0 34 #ifdef VMS
meillo@10 35 # include <sys/socket.h> /* for fd_set */
meillo@0 36 #endif
meillo@0 37 #define IN_LIBIDENT_SRC
meillo@0 38 #include "ident.h"
meillo@0 39
meillo@0 40
meillo@0 41 /*
meillo@10 42 int
meillo@10 43 id_parse __P7(ident_t *, id,
meillo@10 44 struct timeval *, timeout,
meillo@10 45 int *, lport,
meillo@10 46 int *, fport,
meillo@10 47 char **, identifier,
meillo@10 48 char **, opsys,
meillo@10 49 char **, charset)
meillo@0 50 */
meillo@0 51
meillo@10 52 int
meillo@10 53 id_parse __P((ident_t * id,
meillo@10 54 __STRUCT_TIMEVAL_P timeout,
meillo@10 55 int *lport,
meillo@10 56 int *fport,
meillo@10 57 char **identifier,
meillo@10 58 char **opsys,
meillo@10 59 char **charset))
meillo@0 60 {
meillo@10 61 char c, *cp, *tmp_charset;
meillo@10 62 fd_set rs;
meillo@10 63 int pos, res = 0, lp, fp;
meillo@10 64
meillo@10 65 errno = 0;
meillo@10 66
meillo@10 67 tmp_charset = 0;
meillo@10 68
meillo@10 69 if (!id)
meillo@10 70 return -1;
meillo@10 71 if (lport)
meillo@10 72 *lport = 0;
meillo@10 73 if (fport)
meillo@10 74 *fport = 0;
meillo@10 75 if (identifier)
meillo@10 76 *identifier = 0;
meillo@10 77 if (opsys)
meillo@10 78 *opsys = 0;
meillo@10 79 if (charset)
meillo@10 80 *charset = 0;
meillo@10 81
meillo@10 82 pos = strlen(id->buf);
meillo@10 83
meillo@10 84 if (timeout) {
meillo@10 85 FD_ZERO(&rs);
meillo@10 86 FD_SET(id->fd, &rs);
meillo@0 87
meillo@0 88 #ifdef __hpux
meillo@10 89 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) 0, (int *) 0, timeout)) < 0)
meillo@0 90 #else
meillo@10 91 if ((res = select(FD_SETSIZE, &rs, (fd_set *) 0, (fd_set *) 0, timeout)) < 0)
meillo@0 92 #endif
meillo@10 93 return -1;
meillo@10 94
meillo@10 95 if (res == 0) {
meillo@10 96 errno = ETIMEDOUT;
meillo@10 97 return -1;
meillo@10 98 }
meillo@0 99 }
meillo@10 100
meillo@10 101 /* Every octal value is allowed except 0, \n and \r */
meillo@10 102 while (pos < sizeof(id->buf)
meillo@10 103 && (res = read(id->fd, id->buf + pos, 1)) == 1
meillo@10 104 && id->buf[pos] != '\n' && id->buf[pos] != '\r')
meillo@10 105 pos++;
meillo@10 106
meillo@10 107 if (res < 0)
meillo@10 108 return -1;
meillo@10 109
meillo@10 110 if (res == 0) {
meillo@10 111 errno = ENOTCONN;
meillo@10 112 return -1;
meillo@0 113 }
meillo@10 114
meillo@10 115 if (id->buf[pos] != '\n' && id->buf[pos] != '\r')
meillo@10 116 return 0; /* Not properly terminated string */
meillo@10 117
meillo@10 118 id->buf[pos++] = '\0';
meillo@10 119
meillo@10 120 /*
meillo@10 121 ** Get first field (<lport> , <fport>)
meillo@10 122 */
meillo@10 123 cp = id_strtok(id->buf, ":", &c);
meillo@0 124 if (!cp)
meillo@10 125 return -2;
meillo@10 126
meillo@10 127 if (sscanf(cp, " %d , %d", &lp, &fp) != 2) {
meillo@10 128 if (identifier) {
meillo@10 129 *identifier = id_strdup(cp);
meillo@10 130 if (*identifier == NULL)
meillo@10 131 return -4;
meillo@10 132 }
meillo@10 133 return -2;
meillo@0 134 }
meillo@10 135
meillo@10 136 if (lport)
meillo@10 137 *lport = lp;
meillo@10 138 if (fport)
meillo@10 139 *fport = fp;
meillo@10 140
meillo@0 141 /*
meillo@10 142 ** Get second field (USERID or ERROR)
meillo@10 143 */
meillo@10 144 cp = id_strtok((char *) 0, ":", &c);
meillo@0 145 if (!cp)
meillo@10 146 return -2;
meillo@10 147
meillo@10 148 if (strcmp(cp, "ERROR") == 0) {
meillo@10 149 cp = id_strtok((char *) 0, "\n\r", &c);
meillo@10 150 if (!cp)
meillo@10 151 return -2;
meillo@10 152
meillo@10 153 if (identifier) {
meillo@10 154 *identifier = id_strdup(cp);
meillo@10 155 if (*identifier == NULL)
meillo@10 156 return -4;
meillo@10 157 }
meillo@10 158
meillo@10 159 return 2;
meillo@10 160 } else if (strcmp(cp, "USERID") == 0) {
meillo@10 161 /*
meillo@10 162 ** Get first subfield of third field <opsys>
meillo@10 163 */
meillo@10 164 cp = id_strtok((char *) 0, ",:", &c);
meillo@10 165 if (!cp)
meillo@10 166 return -2;
meillo@10 167
meillo@10 168 if (opsys) {
meillo@10 169 *opsys = id_strdup(cp);
meillo@10 170 if (*opsys == NULL)
meillo@10 171 return -4;
meillo@10 172 }
meillo@10 173
meillo@10 174 /*
meillo@10 175 ** We have a second subfield (<charset>)
meillo@10 176 */
meillo@10 177 if (c == ',') {
meillo@10 178 cp = id_strtok((char *) 0, ":", &c);
meillo@10 179 if (!cp)
meillo@10 180 return -2;
meillo@10 181
meillo@10 182 tmp_charset = cp;
meillo@10 183 if (charset) {
meillo@10 184 *charset = id_strdup(cp);
meillo@10 185 if (*charset == NULL)
meillo@10 186 return -4;
meillo@10 187 }
meillo@10 188
meillo@10 189 /*
meillo@10 190 ** We have even more subfields - ignore them
meillo@10 191 */
meillo@10 192 if (c == ',')
meillo@10 193 id_strtok((char *) 0, ":", &c);
meillo@10 194 }
meillo@10 195
meillo@10 196 if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0)
meillo@10 197 cp = id_strtok((char *) 0, (char *) 0, &c);
meillo@10 198 else
meillo@10 199 cp = id_strtok((char *) 0, "\n\r", &c);
meillo@10 200
meillo@10 201 if (identifier) {
meillo@10 202 *identifier = id_strdup(cp);
meillo@10 203 if (*identifier == NULL)
meillo@10 204 return -4;
meillo@10 205 }
meillo@10 206 return 1;
meillo@10 207 } else {
meillo@10 208 if (identifier) {
meillo@10 209 *identifier = id_strdup(cp);
meillo@10 210 if (*identifier == NULL)
meillo@10 211 return -4;
meillo@10 212 }
meillo@10 213 return -3;
meillo@0 214 }
meillo@0 215 }